fix(custom-model): pre-approve the injected API key in the isolated Claude config dir

The CLAUDE_CONFIG_DIR isolation from the previous commit fixed the cosmetic
auth warning but introduced a real regression: an otherwise-empty config
directory has none of a real profile's prior custom-API-key approvals, so
Claude Code stops at an interactive 'Detected a custom API key - use it?'
prompt on every single launch. Confirmed live. With nobody at a TTY to
answer, the prompt's own default ('No') silently refuses the very key this
feature just injected, which looks like the endpoint being ignored.

Adds apiKeyTrustFile to the env-kind customModelInjection capability shape
({relPath, shape: 'claude-api-key-responses'}), set on claude's entry to
{relPath: '.claude.json', shape: 'claude-api-key-responses'}. The apply step
merges customApiKeyResponses.approved: [apiKey] into
<isolatedConfigDir>/.claude.json - the exact field a real answered prompt
itself writes to (confirmed against a real ~/.claude.json after answering by
hand once), so this answers the prompt in advance rather than bypassing it.
Merges onto whatever the CLI already wrote into that file on an earlier
launch in the same isolated directory rather than overwriting it; a missing
or corrupt file is treated as empty rather than failing the apply.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RqZeHrRS6DYcGcGX2p9EwG
This commit is contained in:
Devvyn
2026-09-16 13:08:07 +08:00
co-authored by Claude Sonnet 5
parent 0e8b1981af
commit 97464bfa27
9 changed files with 192 additions and 8 deletions
+7
View File
@@ -264,6 +264,13 @@ const CLAUDE: CliEntry = {
// never shares a directory with a stored claude.ai OAuth login — see the doc comment on
// customModelInjection in cli-registry/types.ts for the traded-off side effect.
configDirVar: 'CLAUDE_CONFIG_DIR',
// ⚠️ Required alongside configDirVar, not optional in practice: verified live that an
// isolated, otherwise-empty config directory makes claude stop at an interactive
// "Detected a custom API key — use it?" prompt on EVERY launch, defaulting to "No" with
// no one at the TTY to answer — silently refusing the very key this feature injected.
// Pre-seeding this file's customApiKeyResponses.approved list (verified against a real
// ~/.claude.json after answering the prompt once by hand) answers it in advance instead.
apiKeyTrustFile: { relPath: '.claude.json', shape: 'claude-api-key-responses' },
},
},
overlays: {