mirror of
https://github.com/coleam00/Archon
synced 2026-04-21 13:37:41 +00:00
fix: move CLAUDECODE warning into stripCwdEnv, remove dead useGlobalAuth logic
Review findings addressed: 1. CLAUDECODE warning was dead code — the boot import deleted CLAUDECODE from process.env before the warning check in cli.ts/server/index.ts could fire. Moved the warning into stripCwdEnv() itself, emitted BEFORE the deletion. Removed duplicate warning code from both entry points. 2. useGlobalAuth token stripping removed (intentional, not regression) — the old code stripped CLAUDE_CODE_OAUTH_TOKEN and CLAUDE_API_KEY when useGlobalAuth=true. Per design discussion: the user controls ~/.archon/.env and all keys they set are intentional. If they want global auth, they just don't set tokens. Simplified buildSubprocessEnv to log auth mode for diagnostics only, no filtering. 3. Docs "no override needed" corrected — cli.md and configuration.md now reflect the actual code (override: true).
This commit is contained in:
parent
c1eb071308
commit
76b49b5b3a
6 changed files with 33 additions and 75 deletions
|
|
@ -30,7 +30,7 @@ bun run cli version
|
|||
## Startup Behavior
|
||||
|
||||
1. `@archon/paths/strip-cwd-env-boot` (first import) removes all Bun-auto-loaded CWD `.env` keys from `process.env`
|
||||
2. Loads `~/.archon/.env` (no `override` needed — CWD keys are already stripped)
|
||||
2. Loads `~/.archon/.env` with `override: true` (Archon config wins over shell-inherited vars)
|
||||
3. Smart Claude auth default: if no `CLAUDE_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN`, sets `CLAUDE_USE_GLOBAL_AUTH=true`
|
||||
4. Imports all commands AFTER dotenv setup
|
||||
|
||||
|
|
|
|||
|
|
@ -30,16 +30,8 @@ if (existsSync(globalEnvPath)) {
|
|||
}
|
||||
}
|
||||
|
||||
// Warn when running inside a Claude Code session — nested sessions can deadlock.
|
||||
if (process.env.CLAUDECODE === '1' && !process.env.ARCHON_SUPPRESS_NESTED_CLAUDE_WARNING) {
|
||||
process.stderr.write(
|
||||
'\u26a0 Detected CLAUDECODE=1 — you appear to be running `archon` from inside a Claude Code session.\n' +
|
||||
' If workflows hang silently at dag_node_started, this is a known class of issue.\n' +
|
||||
' Workaround: run `archon serve` from a regular shell and use the web UI or HTTP API.\n' +
|
||||
' Suppress: set ARCHON_SUPPRESS_NESTED_CLAUDE_WARNING=1\n' +
|
||||
' Details: https://github.com/coleam00/Archon/issues/1067\n'
|
||||
);
|
||||
}
|
||||
// CLAUDECODE=1 warning is emitted inside stripCwdEnv() (boot import above)
|
||||
// BEFORE the marker is deleted from process.env. No duplicate warning here.
|
||||
|
||||
// Smart defaults for Claude auth
|
||||
// If no explicit tokens, default to global auth from `claude /login`
|
||||
|
|
|
|||
|
|
@ -82,66 +82,30 @@ function normalizeClaudeUsage(usage?: {
|
|||
}
|
||||
|
||||
/**
|
||||
* Build environment for Claude subprocess
|
||||
* Build environment for Claude subprocess.
|
||||
*
|
||||
* Auth behavior:
|
||||
* - CLAUDE_USE_GLOBAL_AUTH=true: Filter tokens, use global auth from `claude /login`
|
||||
* - CLAUDE_USE_GLOBAL_AUTH=false: Pass tokens through explicitly
|
||||
* - Not set: Auto-detect — use explicit tokens if present, otherwise fall back to global auth
|
||||
* process.env is already clean at this point:
|
||||
* - stripCwdEnv() at entry point removed CWD .env keys + CLAUDECODE markers
|
||||
* - ~/.archon/.env loaded with override:true as the trusted source
|
||||
*
|
||||
* Auth mode is determined by the SDK based on what tokens are present:
|
||||
* - Tokens in env → SDK uses them (explicit auth)
|
||||
* - No tokens → SDK uses `claude /login` credentials (global auth)
|
||||
* - User controls this by what they put in ~/.archon/.env
|
||||
*
|
||||
* We log the detected mode for diagnostics but don't filter — the user's
|
||||
* config is trusted. See coleam00/Archon#1067 for design rationale.
|
||||
*/
|
||||
function buildSubprocessEnv(): NodeJS.ProcessEnv {
|
||||
const globalAuthSetting = process.env.CLAUDE_USE_GLOBAL_AUTH?.toLowerCase();
|
||||
|
||||
// Check for empty token values (common misconfiguration)
|
||||
const tokenVars = ['CLAUDE_CODE_OAUTH_TOKEN', 'CLAUDE_API_KEY'] as const;
|
||||
const emptyTokens = tokenVars.filter(v => process.env[v] === '');
|
||||
if (emptyTokens.length > 0) {
|
||||
getLog().warn({ emptyTokens }, 'empty_token_values');
|
||||
}
|
||||
|
||||
// Warn if user has the legacy variable but not the new ones
|
||||
if (
|
||||
process.env.ANTHROPIC_API_KEY &&
|
||||
!process.env.CLAUDE_CODE_OAUTH_TOKEN &&
|
||||
!process.env.CLAUDE_API_KEY
|
||||
) {
|
||||
getLog().warn(
|
||||
{ hint: 'Use CLAUDE_API_KEY or CLAUDE_CODE_OAUTH_TOKEN instead' },
|
||||
'deprecated_anthropic_api_key_ignored'
|
||||
);
|
||||
}
|
||||
|
||||
const hasExplicitTokens = Boolean(
|
||||
process.env.CLAUDE_CODE_OAUTH_TOKEN ?? process.env.CLAUDE_API_KEY
|
||||
);
|
||||
const authMode = hasExplicitTokens ? 'explicit' : 'global';
|
||||
getLog().info(
|
||||
{ authMode },
|
||||
authMode === 'global' ? 'using_global_auth' : 'using_explicit_tokens'
|
||||
);
|
||||
|
||||
// Determine whether to use global auth
|
||||
let useGlobalAuth: boolean;
|
||||
if (globalAuthSetting === 'true') {
|
||||
useGlobalAuth = true;
|
||||
getLog().info({ authMode: 'global' }, 'using_global_auth');
|
||||
} else if (globalAuthSetting === 'false') {
|
||||
useGlobalAuth = false;
|
||||
getLog().info({ authMode: 'explicit' }, 'using_explicit_tokens');
|
||||
} else if (globalAuthSetting !== undefined) {
|
||||
// Unrecognized value - warn and fall back to auto-detect
|
||||
getLog().warn({ value: globalAuthSetting }, 'unrecognized_global_auth_setting');
|
||||
useGlobalAuth = !hasExplicitTokens;
|
||||
} else {
|
||||
// Not set - auto-detect: use tokens if present, otherwise global auth
|
||||
useGlobalAuth = !hasExplicitTokens;
|
||||
if (hasExplicitTokens) {
|
||||
getLog().info({ authMode: 'explicit', autoDetected: true }, 'using_explicit_tokens');
|
||||
} else {
|
||||
getLog().info({ authMode: 'global', autoDetected: true }, 'using_global_auth');
|
||||
}
|
||||
}
|
||||
|
||||
// process.env is already clean — stripCwdEnv() at entry point removed CWD
|
||||
// .env keys and CLAUDECODE markers. Everything remaining is user-trusted
|
||||
// (shell env + ~/.archon/.env). Pass it through as-is.
|
||||
const envKeyCount = Object.keys(process.env).length;
|
||||
getLog().debug({ envKeyCount, useGlobalAuth, hasExplicitTokens }, 'subprocess_env_prepared');
|
||||
return { ...process.env };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ Infrastructure configuration (database URL, platform tokens) is stored in `.env`
|
|||
|
||||
| Component | Location | Purpose |
|
||||
|-----------|----------|---------|
|
||||
| **CLI** | `~/.archon/.env` | Global infrastructure config; CWD .env keys stripped before loading (no `override` needed) |
|
||||
| **CLI** | `~/.archon/.env` | Global infrastructure config; CWD .env keys stripped first, then loaded with `override: true` (Archon config wins over shell-inherited vars) |
|
||||
| **Server (dev)** | `<archon-repo>/.env` + `~/.archon/.env` | Repo `.env` for platform tokens; `~/.archon/.env` loaded with `override: true` |
|
||||
| **Server (binary)** | `~/.archon/.env` | Single source of truth (repo `.env` path is not available in compiled binaries) |
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,16 @@ export function stripCwdEnv(cwd: string = process.cwd()): void {
|
|||
// --- Pass 2: Nested Claude Code session markers ---
|
||||
// Pattern-matched (not hardcoded) so new CLAUDE_CODE_* markers added by
|
||||
// future Claude Code versions are automatically handled.
|
||||
// Emit warning BEFORE deleting — downstream code won't see CLAUDECODE=1.
|
||||
if (process.env.CLAUDECODE === '1' && !process.env.ARCHON_SUPPRESS_NESTED_CLAUDE_WARNING) {
|
||||
process.stderr.write(
|
||||
'\u26a0 Detected CLAUDECODE=1 \u2014 running inside a Claude Code session.\n' +
|
||||
' If workflows hang silently, this is a known class of issue.\n' +
|
||||
' Workaround: run `archon serve` from a regular shell.\n' +
|
||||
' Suppress: set ARCHON_SUPPRESS_NESTED_CLAUDE_WARNING=1\n' +
|
||||
' Details: https://github.com/coleam00/Archon/issues/1067\n'
|
||||
);
|
||||
}
|
||||
if (process.env.CLAUDECODE) {
|
||||
Reflect.deleteProperty(process.env, 'CLAUDECODE');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,16 +40,8 @@ if (existsSync(globalEnvPath)) {
|
|||
}
|
||||
}
|
||||
|
||||
// Warn when running inside a Claude Code session — nested sessions can deadlock.
|
||||
if (process.env.CLAUDECODE === '1' && !process.env.ARCHON_SUPPRESS_NESTED_CLAUDE_WARNING) {
|
||||
process.stderr.write(
|
||||
'\u26a0 Detected CLAUDECODE=1 — server started from inside a Claude Code session.\n' +
|
||||
' If AI queries hang silently, this is a known class of issue.\n' +
|
||||
' Workaround: start the server from a regular (non-Claude-Code) shell.\n' +
|
||||
' Suppress: set ARCHON_SUPPRESS_NESTED_CLAUDE_WARNING=1\n' +
|
||||
' Details: https://github.com/coleam00/Archon/issues/1067\n'
|
||||
);
|
||||
}
|
||||
// CLAUDECODE=1 warning is emitted inside stripCwdEnv() (boot import above)
|
||||
// BEFORE the marker is deleted from process.env. No duplicate warning here.
|
||||
|
||||
// Smart default: use Claude Code's built-in OAuth if no explicit credentials
|
||||
if (
|
||||
|
|
|
|||
Loading…
Reference in a new issue