* 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>
Issue #1161. Sweeps 127 files to import from
src/config/config-loader-facade.ts instead of unified-config-loader or
utils/config-manager directly.
WRITE callers (32 files): replaced raw saveUnifiedConfig /
mutateUnifiedConfig / updateUnifiedConfig calls with the facade's
cache-coherent wrappers saveConfig / mutateConfig / updateConfig. This
fixes a latent stale-cache window where direct writes through the
underlying loader bypassed the facade's memoization.
READ callers (95 files): mechanical import-path migration only —
function names unchanged because the facade re-exports them. No
behavior change.
Also updated:
- tests/unit/utils/browser/browser-setup.test.ts (DI interface rename)
- src/management/checks/image-analysis-check.ts (dynamic import rename)
- src/web-server/health-service.ts (dynamic require rename)
- src/ccs.ts (path prefix fix from sweep script)
After sweep: zero raw write callers remain outside src/config/. Direct
imports of config-manager remain only for symbols not in the facade
(getConfigPath, getCcsDirSource, etc). Behavior unchanged; full suite
passes 1824/1824.
Out of scope: switching loadOrCreateUnifiedConfig() callers to
getCachedConfig() — needs per-callsite cache-safety analysis. Tracked
as follow-up.
Refs #1161
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
Use ComSpec-aware shell selection for escaped wrapper launches.
Apply it to the remaining Windows Claude launch paths.
Rewrite the Codex exec regression test to use scoped spies so the full suite stays isolated.
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)
- Updated websearch.md to include SearXNG in the configuration guide.
- Implemented SearXNG JSON API integration in websearch-transformer.cjs.
- Enhanced unified-config-loader.ts to support SearXNG settings.
- Defined SearXNG configuration types in unified-config-types.ts.
- Updated hook-env.ts to manage SearXNG environment variables.
- Modified status.ts to include SearXNG in web search provider checks.
- Added SearXNG routes and validation in websearch-routes.ts.
- Implemented SearXNG provider tests in websearch-transformer.test.ts.
- Updated readiness tests to account for SearXNG in status.test.ts.
- Enhanced websearch routes tests to validate SearXNG settings.
- Added SearXNG configuration fields in the UI settings.
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)