feat(#2149): set base claude-code env in managed settings
Add `baseClaudeEnv` (always-on) and extend `otelSettingsEnv` with the env vars from #2149: Always-on (every agent): - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 - CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1 - CLAUDE_CODE_RESUME_INTERRUPTED_TURN=1 (recovers MCP-flap mid-turn) - CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT=1 - CLAUDE_CODE_SYNC_PLUGIN_INSTALL=1 - CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX=hive+<agent> - DISABLE_AUTOUPDATER=1 / DISABLE_UPDATES=1 (nix owns packages) - DISABLE_INSTALL_GITHUB_APP_COMMAND=1 - DO_NOT_TRACK=1 - ENABLE_CLAUDEAI_MCP_SERVERS=0 (hive supplies its own) - FORCE_AUTOUPDATE_PLUGINS=1 OTEL-gated (when hyperhive.otel.enable): - CLAUDE_CODE_ENABLE_FEEDBACK_SURVEY_FOR_OTEL=1 - CLAUDE_CODE_OTEL_DIAG_STDERR=1 - OTEL_METRICS_INCLUDE_VERSION=1 Because baseClaudeEnv includes per-agent values (CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX = "hive+${userName}"), jq is now always run at build time — the OTEL-off branch that returned the static asset verbatim is removed.
This commit is contained in:
parent
32a02640c1
commit
04692871cf
1 changed files with 48 additions and 15 deletions
|
|
@ -37,8 +37,38 @@ let
|
|||
# (claude merges the `env` from the user settings on top of these
|
||||
# managed ones), so the token is read from disk at start and never
|
||||
# touches the store.
|
||||
# Base claude-code environment applied to every agent regardless of OTEL.
|
||||
# Shipped via the managed settings `env` block so claude and `hivectl
|
||||
# choom` both inherit them without a launch wrapper.
|
||||
baseClaudeEnv = {
|
||||
# Suppress analytics, survey pings, and other non-essential outbound
|
||||
# traffic — agents are headless and don't need any of that.
|
||||
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
|
||||
DO_NOT_TRACK = "1";
|
||||
# Disable claude's self-update machinery; package management is nix's job.
|
||||
DISABLE_AUTOUPDATER = "1";
|
||||
DISABLE_UPDATES = "1";
|
||||
# Keep plugin updates synchronized on install; prefer HTTPS for fetches.
|
||||
CLAUDE_CODE_PLUGIN_PREFER_HTTPS = "1";
|
||||
CLAUDE_CODE_SYNC_PLUGIN_INSTALL = "1";
|
||||
FORCE_AUTOUPDATE_PLUGINS = "1";
|
||||
# Suppress the "install GitHub app" prompt — not applicable in-hive.
|
||||
DISABLE_INSTALL_GITHUB_APP_COMMAND = "1";
|
||||
# Disable Anthropic's hosted claude.ai MCP servers; the hive supplies its own.
|
||||
ENABLE_CLAUDEAI_MCP_SERVERS = "0";
|
||||
# Resume an interrupted turn on reconnect (recovers from transient MCP flaps).
|
||||
CLAUDE_CODE_RESUME_INTERRUPTED_TURN = "1";
|
||||
# Use the simpler system prompt variant suited to headless operation.
|
||||
CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT = "1";
|
||||
# Tag remote-control sessions with the hive+agent name for identification.
|
||||
CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX = "hive+${userName}";
|
||||
};
|
||||
otelSettingsEnv = {
|
||||
CLAUDE_CODE_ENABLE_TELEMETRY = "1";
|
||||
# Attach feedback-survey data to the OTEL pipeline.
|
||||
CLAUDE_CODE_ENABLE_FEEDBACK_SURVEY_FOR_OTEL = "1";
|
||||
# Emit OTEL SDK diagnostics to stderr for easier log capture.
|
||||
CLAUDE_CODE_OTEL_DIAG_STDERR = "1";
|
||||
OTEL_METRICS_EXPORTER = "otlp";
|
||||
OTEL_LOGS_EXPORTER = "otlp";
|
||||
OTEL_TRACES_EXPORTER = "otlp";
|
||||
|
|
@ -51,6 +81,8 @@ let
|
|||
OTEL_RESOURCE_ATTRIBUTES =
|
||||
"service.name=hyperhive-agent,agent=${userName},hive=${hiveDisplayName},swarm=${swarmDisplayName}"
|
||||
+ lib.optionalString (otelCfg.extraResourceAttributes != "") ",${otelCfg.extraResourceAttributes}";
|
||||
# Include the Claude Code version label in emitted metrics.
|
||||
OTEL_METRICS_INCLUDE_VERSION = "1";
|
||||
}
|
||||
// lib.optionalAttrs (otelCfg.metricIntervalMs != null) {
|
||||
OTEL_METRIC_EXPORT_INTERVAL = toString otelCfg.metricIntervalMs;
|
||||
|
|
@ -1176,25 +1208,26 @@ in
|
|||
# deliberately NOT shipped here: effort is controlled live via the
|
||||
# `--effort` CLI flag (HIVE_DEFAULT_EFFORT / the per-agent UI slider),
|
||||
# which managed scope would otherwise override and lock.
|
||||
# Base hive-enforced settings, plus — when OTEL is enabled — an `env`
|
||||
# block so Claude Code exports telemetry natively from the settings
|
||||
# file it reads in every context (harness turn-loop AND `hivectl
|
||||
# choom`), with no launch wrapper. With OTEL off it's the shared
|
||||
# static asset verbatim; with OTEL on it's a per-agent merge (the
|
||||
# resource attributes carry the agent name) done at BUILD time via
|
||||
# `jq` — not eval-time `readFile`, which would be import-from-
|
||||
# derivation.
|
||||
# Hive-enforced settings merged with a per-agent `env` block at BUILD
|
||||
# time via `jq` (not eval-time `readFile`, which would be import-from-
|
||||
# derivation). The `env` block is always present: `baseClaudeEnv` sets
|
||||
# behaviour flags and the remote-control session prefix for every agent;
|
||||
# `otelSettingsEnv` is merged on top when OTEL is enabled. claude-code
|
||||
# auto-discovers this file in every context (harness turn-loop AND
|
||||
# `hivectl choom`) so no launch wrapper is needed.
|
||||
environment.etc."claude-code/managed-settings.json".source =
|
||||
let
|
||||
baseSettings = "${pkgs.hyperhive-assets}/share/hyperhive/prompts/claude-settings.json";
|
||||
# Merge base env (always) with OTEL env (when enabled). jq is always
|
||||
# run — `baseClaudeEnv` contains per-agent values (e.g.
|
||||
# CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX) that can't live in the
|
||||
# static store asset.
|
||||
allEnv = baseClaudeEnv // lib.optionalAttrs otelCfg.enable otelSettingsEnv;
|
||||
in
|
||||
if !otelCfg.enable then
|
||||
baseSettings
|
||||
else
|
||||
pkgs.runCommand "managed-settings.json" { nativeBuildInputs = [ pkgs.jq ]; } ''
|
||||
jq --argjson env ${lib.escapeShellArg (builtins.toJSON otelSettingsEnv)} \
|
||||
'. + { env: $env }' ${baseSettings} > "$out"
|
||||
'';
|
||||
pkgs.runCommand "managed-settings.json" { nativeBuildInputs = [ pkgs.jq ]; } ''
|
||||
jq --argjson env ${lib.escapeShellArg (builtins.toJSON allEnv)} \
|
||||
'. + { env: $env }' ${baseSettings} > "$out"
|
||||
'';
|
||||
|
||||
# Inject the OTEL auth header (a secret) into the agent's *user*
|
||||
# claude settings at runtime, keeping it out of the world-readable
|
||||
|
|
|
|||
Loading…
Reference in a new issue