Commit Graph
240 Commits
Author SHA1 Message Date
walker1211andGitHub 35b6210cd2 fix: support Claude subcommands and background sessions
Squash merge PR #1240.\n\nValidated locally from the PR head because trusted-author GitHub CI was skipped for this fork PR:\n- bun run validate\n- bun run build:all\n- bun run test:all\n- CCS_E2E_SKIP_BUILD=1 bun run test:e2e
2026-05-14 10:18:23 -04:00
Kai (Tam Nhu) TranandGitHub 9c5d4976c5 fix(windows): pin cmd shell for wrapper launches (#1229) 2026-05-12 18:13:13 -04:00
Tam Nhu Tran c2b00b7ad6 feat(dispatcher): pass through Claude subcommands without interactive-session args
Closes #1218.

When the user invokes `ccs <profile> agents` (and other Claude subcommands
like `mcp`, `doctor`, `plugin`, ...), CCS was unconditionally injecting
session-only Claude flags (`--append-system-prompt`, `--disallowedTools`,
`--settings`, official-channels plugin specs) and forwarding the
`DISABLE_TELEMETRY=1` env var from profile settings. Each of those
either errored out the subcommand (`error: unknown option
'--append-system-prompt'`) or silently flipped Claude into
non-interactive list mode, so the new `claude agents` agent view never
opened under CCS.

Add a small `claude-subcommand-detector` that recognizes the documented
Claude subcommand set after skipping known value-taking flags, then have
the three steering-prompt injectors (websearch, image-analysis, browser),
the cliproxy and settings launchers, and the official-channels plan
short-circuit when a subcommand invocation is detected. Also strip
`DISABLE_TELEMETRY` from the spawned env only for subcommand
invocations — upstream Claude Code uses that var as a kill switch for
the subcommand TUIs, and the user's telemetry preference still applies
to every normal interactive session.

Verified end-to-end against `ccs glm agents` and `ccs ck agents`: the
agent view opens correctly, no `unknown option` error, and all 1938
existing tests pass.
2026-05-12 16:35:37 -04:00
d6b705e6a9 fix(dispatcher): re-inject anthropic auth env for anthropic-compatible api profiles (#1181)
* 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>
2026-05-04 20:22:13 -04:00
Tam Nhu Tran b6a49eeab7 fix(config/loader): break runtime cycle from normalizers to channels-runtime
The normalizers extraction in #1168 introduced a circular module-load
chain that crashed the built CLI:

  ccs.js -> errors -> services/logging -> log-config -> config-loader-facade
   -> unified-config-loader -> loader/normalizers -> channels/official-channels-runtime
   -> utils/claude-detector -> utils/shell-executor -> utils/websearch-manager
   -> utils/websearch/hook-env -> utils/websearch/trace
   -> services/logging (mid-load - createLogger undefined) -> CRASH

normalizers only needed three pure helpers from official-channels-runtime
(isOfficialChannelId, normalizeOfficialChannelIds, resolveLegacyDiscord
Selection) but pulled in the whole file's claude-detector / shell-
executor / websearch chain.

Fix: extract those three helpers + OFFICIAL_CHANNEL_IDS into a leaf
module src/channels/official-channels-ids.ts with no runtime deps.
Update normalizers.ts and config-getters.ts to import from the leaf.
official-channels-runtime.ts re-exports from the leaf for callers that
still want the bundled API.

Also revert the over-eager facade-import migration in
src/utils/config-manager.ts (it was importing from config-loader-facade
which re-exports from itself, creating a direct cycle).

Verified: dist/ccs.js boots cleanly (--version returns); test:all
1828/1828 pass; typecheck/lint/format clean.

Refs #1135
2026-05-03 12:20:32 -04:00
Tam Nhu Tran 4f6e61739c refactor(config): adopt config-loader-facade across the codebase
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
2026-05-03 01:42:53 -04:00
Tam Nhu Tran b8ed36e370 fix: round 3 red-team — test false-positive, dead code,
edge-case coverage

- Fix false-positive test: use CCSError with recoverable=false
  instead of plain Error (never exercised recoverable check)
- Remove redundant retryableCheck ?? defaultRetryableCheck
  (destructuring already defaults)
- Add test: retryAfter > maxDelayMs (server directive wins)
- Add test: baseDelayMs=0 produces immediate retries
- Add test: onRetry not called when maxRetries=0
2026-04-30 15:16:07 -04:00
Tam Nhu Tran 18e865ea36 fix: round 2 red-team fixes — onRetry safety, validation, barrel
- retry-strategy: wrap onRetry in try/catch to prevent
  callback errors from aborting retries
- retry-strategy: validate baseDelayMs >= 0
- retry-strategy: update JSDoc to clarify
  retryAfter/maxDelayMs interaction
- errors/index.ts: add ValidationError to barrel
- Tests: onRetry throw test, negative baseDelayMs test
2026-04-30 14:59:44 -04:00
Tam Nhu Tran 9bb1bdbad9 fix: address red-team review findings — cache aliasing, jitter cap, cause shadowing
- config-loader-facade: use structuredClone() to prevent cache aliasing
- retry-strategy: re-cap delay after jitter to enforce maxDelayMs boundary
- retry-strategy: wire retryAfter from RetryableError into delay computation
- retry-strategy: guard against negative maxRetries
- error-types: rename RetryableError.cause to originalError to avoid shadowing Error.cause
- Tests updated for all fixes
2026-04-30 14:37:28 -04:00
Tam Nhu Tran d089ab06c2 refactor(errors): add RetryableError and retry-strategy utility
Extract retryable error class and reusable withRetry wrapper from
scattered retry logic in glmt-proxy and binary/downloader.
2026-04-30 13:46:33 -04:00
Tam Nhu Tran c3c8cb7a82 fix(cliproxy): exclude colocated tests from tsconfig and eslint
- Add src/**/__tests__/** to tsconfig.json exclude list
- Add ignores pattern for __tests__ in eslint.config.mjs
- Fix ui/src/lib/api-client.ts import path for provider-entitlement-types
- Remove stale build artifacts from ui/src/lib/ and tests/mocks/
2026-04-29 17:18:23 -04:00
Tam Nhu Tran 1c72b4b8d5 refactor(cliproxy): flatten module structure and colocate tests (#1135)
- Split types.ts (331 LOC) into 4 concern-based files under types/:
  platform-types, binary-types, provider-types, config-types
- Preserve backward compat via barrel re-export (types.ts → types/index)
- Reorganize 53 root-level files into 8 subdirectories:
  accounts/, ai-providers/, auth/, binary/, config/, executor/,
  management/, proxy/, quota/, routing/, services/, sync/
- Reduce src/cliproxy/ root from 65 to 8 files (target: ≤10)
- Colocate 87 unit tests from tests/unit/cliproxy/ into
  src/cliproxy/*/__tests__/ (13 colocated test directories)
- Update import paths across 40+ consumer files
- Add TDD backward-compat test for types split

Refs #1135
2026-04-29 17:06:39 -04:00
Tam Nhu Tran 47fbe8bb3a fix(proxy): clean up temp launch settings 2026-04-28 11:59:37 -04:00
Tam Nhu Tran 3dcf150978 fix(proxy): preserve settings-profile launches for openai bridge 2026-04-28 11:42:56 -04:00
Tam Nhu Tran 5ff0370c1c chore: merge origin/dev into pr-1061 fix branch 2026-04-22 22:38:20 -04:00
Tam Nhu Tran c24033dc6b fix(browser): preserve opt-in browser settings and env isolation 2026-04-22 22:35:02 -04:00
Tam Nhu Tran f78c30ac50 fix(runtime): isolate nested Anthropic env across delegation paths 2026-04-22 22:09:08 -04:00
Wooseong Kim 1fd2fb83fb fix(runtime): strip reintroduced Anthropic routing env
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
2026-04-22 14:08:37 +09:00
Wooseong Kim 9ae85b82c1 fix(runtime): strip inherited Anthropic routing env selectively 2026-04-22 14:08:37 +09:00
walker1211andClaude Opus 4.7 4cf826efa2 fix(image-analysis): clear runtime env on native-read fallback
Avoid carrying runtime API credentials and endpoint fields into native Read fallback launches.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 01:36:11 +08:00
walker1211andClaude Opus 4.7 63082d4aed fix(image-analysis): clear runtime env on native-read fallback
Avoid carrying runtime API credentials and endpoint fields into native Read fallback launches.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 01:25:32 +08:00
Tam Nhu Tran 6604357b22 fix(browser): default browser tooling to manual opt-in 2026-04-20 21:15:31 -04:00
Tam Nhu Tran 039ed63a39 fix(browser): harden runtime policy edge cases 2026-04-20 21:01:19 -04:00
Tam Nhu Tran 7d02f55f9f feat(browser): add explicit runtime policy controls 2026-04-20 21:01:19 -04:00
Tam Nhu Tran f36c4a6e32 fix: keep browser setup config-only 2026-04-19 22:07:58 -04:00
Tam Nhu Tran 7ad8bbf0a1 feat: add browser setup flow for Claude attach 2026-04-19 22:00:16 -04:00
Tam Nhu Tran ccdd0b6e8e fix(windows): align escaped wrapper shell handling
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.
2026-04-19 14:27:27 -04:00
Tam Nhu Tran a945b0b104 fix(targets): use cmd.exe for escaped Windows wrapper launches
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.
2026-04-19 14:09:12 -04:00
Tam Nhu Tran b52503300b fix(browser): bootstrap managed attach profile setup 2026-04-18 17:18:14 -04:00
Tam Nhu Tran 41bf5075e0 hotfix(browser): avoid aborting launch on missing managed profile
- skip managed Claude browser attach when the default CCS browser profile
  directory has not been created yet
- keep explicit env override flows failing fast so real misconfiguration still
  surfaces clearly
- add regression coverage for default and settings-profile launches
2026-04-16 22:59:43 -04:00
Tam Nhu Tran 8a17410f96 fix(browser): address platform and port review 2026-04-16 18:49:24 -04:00
Tam Nhu Tran 4e30c9b080 feat(cli): add browser automation commands 2026-04-16 18:49:24 -04:00
Tam Nhu Tran 3b5941c60b feat(cursor): split legacy bridge from cliproxy provider 2026-04-15 17:04:37 -04:00
Tam Nhu Tran 33f57d3cac hotfix: stop auto-enabling stale Chrome DevTools reuse 2026-04-13 12:02:22 -04:00
github-actions[bot] d2e10ed576 chore(sync): merge main into dev after release [skip ci]
# Conflicts:
#	package.json
2026-04-13 13:53:45 +00:00
Tam Nhu Tran 31c464a3c5 chore: merge dev into pr-976 branch 2026-04-13 09:40:10 -04:00
Tam Nhu Tran a68bc46caf fix(test): isolate chrome reuse home env expectations 2026-04-13 08:41:19 -04:00
Tam Nhu Tran 7fc39f7c03 fix(cli): match managed prompt files by exact path 2026-04-13 08:39:59 -04:00
Yehor Baklanov 45c231a717 feat(cli): add --append-system-prompt-file support 2026-04-13 06:37:19 +00:00
Wooseong Kim a76265a7c0 fix(image-analysis): wrap defaultDeps in arrow functions to fix circular dep capture
Direct function references in defaultDeps (checkRemoteProxy, fetchRemoteAuthStatus,
getAuthStatus, getProxyTarget, initializeAccounts) are captured at module load time.
Due to circular dependencies in the module graph, auth-handler.js may not have
finished initializing when this module is first evaluated, causing these references
to be captured as undefined.

Wrapping each reference in an arrow function defers evaluation to call time,
by which point all modules are fully initialized.

isCliproxyRunning was already wrapped correctly; this patch applies the same
pattern consistently to all deps.

Fixes #973
2026-04-13 15:05:22 +09:00
walkerandClaude Opus 4.6 eb8149e8fa feat(browser): 接入 CCS browser MCP 与最小交互闭环
新增 browser MCP 安装、Chrome 复用与运行时接线,
实现 navigate、click、type、take_screenshot 四个 phase-1 工具并补齐相关单测。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 11:19:16 +08:00
Tam Nhu Tran 8d8f4469b6 fix(websearch): reject blank searxng status urls 2026-04-12 14:46:56 -04:00
Tam Nhu Tran 54791b5cca Merge remote-tracking branch 'origin/dev' into kai/fix/958-searxng-pr-review 2026-04-12 06:32:27 -04:00
Tam Nhu Tran 8b553c35c1 fix(websearch): harden searxng url handling 2026-04-12 06:31:20 -04:00
Tam Nhu Tran 898e7a6321 hotfix: detect bun-owned installs through symlinked ccs path 2026-04-12 01:33:48 -04:00
Tam Nhu Tran 5f8e66ec1e hotfix: detect bun-owned installs through symlinked ccs path 2026-04-12 01:22:15 -04:00
buiducnhat 36d828f99c feat(websearch): add url property to WebSearchProviderConfig interface 2026-04-11 19:35:41 +07:00
buiducnhat eec8c8b4a3 feat(websearch): add SearXNG provider support and configuration
- 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.
2026-04-11 16:43:59 +07:00
Tam Nhu Tran 94bcad2d1a fix(update): align no-update dependency injection 2026-04-10 23:06:37 -04:00
Tam Nhu Tran a4496ff1d9 fix(update): harden install verification flow 2026-04-10 22:44:46 -04:00