* fix(dispatcher): preserve anthropic auth env for settings profiles on non-proxy path
API profiles whose `ANTHROPIC_BASE_URL` is classified as `'anthropic'`
(anthropic.com, paths containing `/anthropic`, ollama.com) skip the
local OpenAI-compat proxy. The non-proxy launch path stripped
`ANTHROPIC_BASE_URL` / `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_API_KEY`
from the subprocess env without re-injecting them, so Claude Code
launched with no routing/auth in `process.env` and failed with
`Not logged in - Please run /login`. The `--settings` env block does
not satisfy Claude Code's auth check.
Pre-existing for `anthropic.com` and `/anthropic` profiles. Newly
broken in v7.77.0 for Ollama Cloud profiles - PR #1175 reclassified
`ollama.com` from `generic-chat-completion-api` to `anthropic`,
moving it from the proxy path onto this broken non-proxy path.
Fix by extending `stripAnthropicRoutingEnv` with an optional
`preserveFrom` parameter. Routing keys present in `preserveFrom`
survive the strip (with values from `preserveFrom`). Settings-type
profiles pass their own `settings.env` as the preserve source so
routing they explicitly supplied is kept while routing leaked from
the parent shell or `global.env` is dropped.
Wired into both call sites:
- `headless-executor.ts` (the `-p` headless executor)
- `settings-flow.ts` (the interactive flow, which then calls
`execClaude` - whose own `stripAnthropicRoutingEnv` pass on the
merged env now also takes `envVars` as the preserve source so the
caller-supplied routing is not stripped a second time before spawn)
Native Anthropic / Bedrock / Vertex profiles are unaffected (they
don't put routing keys in `settings.env`). The OpenAI-compat proxy
path is unaffected because `buildOpenAICompatProxyEnv` overrides
`BASE_URL` / `AUTH_TOKEN` with localhost values and explicitly deletes
`API_KEY` after this strip.
Replaces the Apr 21 defensive double-strip test (which was the
mechanism causing this regression on the interactive path) with a
test asserting the new contract: caller-supplied routing in `envVars`
survives, parent-process routing is still stripped.
* test: harden anthropic settings env preservation coverage
* fix: preserve explicit blank anthropic routing env
---------
Co-authored-by: Tam Nhu Tran <kaitran.ntt@gmail.com>
Prevent settings-profile Claude launches from reintroducing
routing/auth env after the final env merge.
- re-strip ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, and
ANTHROPIC_API_KEY after merging envVars
- preserve model-selection env such as ANTHROPIC_MODEL and
ANTHROPIC_DEFAULT_SONNET_MODEL
- add a regression test covering explicit settings-profile
overrides that try to reintroduce routing env
Verification:
- bun test tests/unit/utils/claudecode-env-stripping.test.ts
- bun run validate
Align Windows .cmd/.bat launch behavior with the Codex detector shell contract.
This keeps escaped -c overrides intact through wrapper execution.
Adds regression coverage for the Codex runtime path and the shared Windows shell launch path.
- Extract NEUTRAL_PROFILE_TYPE constant with JSDoc explaining why
CCS_PROFILE_TYPE must be neutralised in subprocess env blocks
- Replace 6 bare '' occurrences with the named constant (DRY)
- Group save/delete operations in beforeEach with section comments
Built [OnSteroids](https://onsteroids.ai)
When tests run inside a CCS-managed Claude session, host env vars
(CLAUDE_CONFIG_DIR, CCS_PROFILE_TYPE) leak into subprocess spawns
and fixture setup, causing 9 test failures:
- persist-command-handler: reads real symlinked settings.json instead
of temp fixture because CLAUDE_CONFIG_DIR overrides scoped CCS_HOME
- websearch-transformer: hook silently exits via shouldSkipHook()
because CCS_PROFILE_TYPE=account triggers native_account_profile skip
- claudecode-env-stripping: normalizeSharedPluginMetadataPaths receives
leaked CLAUDE_CONFIG_DIR instead of undefined for default profiles
Fix: clear CCS-managed env vars in beforeEach and neutralize
CCS_PROFILE_TYPE in subprocess env blocks.
Built [OnSteroids](https://onsteroids.ai)
- switch ccs-websearch MCP to stdio-first framing and keep legacy compatibility
- add cooldown persistence and bounded retries for provider failures
- surface cooldown status in readiness output and regression tests
- bind real spawn/spawnSync/execSync before module mocking
- avoid potential rebinding recursion or mock passthrough drift in CI
- keeps non-Claude process execution untouched during test mocks
- register child_process module mock in beforeAll instead of module load
- keep passthrough for non-Claude commands and restore after suite
- avoids cross-suite side effects that stalled cursor daemon CI tests
- mock only Claude command spawns and pass through real child_process for others
- add missing ChildProcess-compatible fields (pid/unref) on mock child
- stabilizes cursor daemon and ccsd alias tests in CI parallel execution