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
|
# (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
|
# managed ones), so the token is read from disk at start and never
|
||||||
# touches the store.
|
# 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 = {
|
otelSettingsEnv = {
|
||||||
CLAUDE_CODE_ENABLE_TELEMETRY = "1";
|
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_METRICS_EXPORTER = "otlp";
|
||||||
OTEL_LOGS_EXPORTER = "otlp";
|
OTEL_LOGS_EXPORTER = "otlp";
|
||||||
OTEL_TRACES_EXPORTER = "otlp";
|
OTEL_TRACES_EXPORTER = "otlp";
|
||||||
|
|
@ -51,6 +81,8 @@ let
|
||||||
OTEL_RESOURCE_ATTRIBUTES =
|
OTEL_RESOURCE_ATTRIBUTES =
|
||||||
"service.name=hyperhive-agent,agent=${userName},hive=${hiveDisplayName},swarm=${swarmDisplayName}"
|
"service.name=hyperhive-agent,agent=${userName},hive=${hiveDisplayName},swarm=${swarmDisplayName}"
|
||||||
+ lib.optionalString (otelCfg.extraResourceAttributes != "") ",${otelCfg.extraResourceAttributes}";
|
+ 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) {
|
// lib.optionalAttrs (otelCfg.metricIntervalMs != null) {
|
||||||
OTEL_METRIC_EXPORT_INTERVAL = toString otelCfg.metricIntervalMs;
|
OTEL_METRIC_EXPORT_INTERVAL = toString otelCfg.metricIntervalMs;
|
||||||
|
|
@ -1176,25 +1208,26 @@ in
|
||||||
# deliberately NOT shipped here: effort is controlled live via the
|
# deliberately NOT shipped here: effort is controlled live via the
|
||||||
# `--effort` CLI flag (HIVE_DEFAULT_EFFORT / the per-agent UI slider),
|
# `--effort` CLI flag (HIVE_DEFAULT_EFFORT / the per-agent UI slider),
|
||||||
# which managed scope would otherwise override and lock.
|
# which managed scope would otherwise override and lock.
|
||||||
# Base hive-enforced settings, plus — when OTEL is enabled — an `env`
|
# Hive-enforced settings merged with a per-agent `env` block at BUILD
|
||||||
# block so Claude Code exports telemetry natively from the settings
|
# time via `jq` (not eval-time `readFile`, which would be import-from-
|
||||||
# file it reads in every context (harness turn-loop AND `hivectl
|
# derivation). The `env` block is always present: `baseClaudeEnv` sets
|
||||||
# choom`), with no launch wrapper. With OTEL off it's the shared
|
# behaviour flags and the remote-control session prefix for every agent;
|
||||||
# static asset verbatim; with OTEL on it's a per-agent merge (the
|
# `otelSettingsEnv` is merged on top when OTEL is enabled. claude-code
|
||||||
# resource attributes carry the agent name) done at BUILD time via
|
# auto-discovers this file in every context (harness turn-loop AND
|
||||||
# `jq` — not eval-time `readFile`, which would be import-from-
|
# `hivectl choom`) so no launch wrapper is needed.
|
||||||
# derivation.
|
|
||||||
environment.etc."claude-code/managed-settings.json".source =
|
environment.etc."claude-code/managed-settings.json".source =
|
||||||
let
|
let
|
||||||
baseSettings = "${pkgs.hyperhive-assets}/share/hyperhive/prompts/claude-settings.json";
|
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
|
in
|
||||||
if !otelCfg.enable then
|
pkgs.runCommand "managed-settings.json" { nativeBuildInputs = [ pkgs.jq ]; } ''
|
||||||
baseSettings
|
jq --argjson env ${lib.escapeShellArg (builtins.toJSON allEnv)} \
|
||||||
else
|
'. + { env: $env }' ${baseSettings} > "$out"
|
||||||
pkgs.runCommand "managed-settings.json" { nativeBuildInputs = [ pkgs.jq ]; } ''
|
'';
|
||||||
jq --argjson env ${lib.escapeShellArg (builtins.toJSON otelSettingsEnv)} \
|
|
||||||
'. + { env: $env }' ${baseSettings} > "$out"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Inject the OTEL auth header (a secret) into the agent's *user*
|
# Inject the OTEL auth header (a secret) into the agent's *user*
|
||||||
# claude settings at runtime, keeping it out of the world-readable
|
# claude settings at runtime, keeping it out of the world-readable
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue