`ccs agents` exited with "Profile not found: agents" instead of opening
the Claude agent view. The first positional token was treated as a
profile name, so `detectProfileType` threw for any bare Claude subcommand
that is not also a profile. `ccs <profile> agents` (#1218) and
`ccs default agents` already worked; only the bare form was unrouted.
On the profile-not-found path, reroute documented Claude subcommands
(agents, mcp, plugin, project, setup-token, auto-mode, remote-control,
ultrareview, upgrade, install) through the default profile so they launch
`claude <subcommand>` — where the existing launcher already strips
interactive-session args. Gated to the claude target so codex/droid keep
their own subcommand routing, and only reached when no profile of that
name exists, so a real configured profile still wins. CCS commands that
shadow Claude subcommands (doctor, update, auth) are intercepted earlier
by the root-command router and are unaffected.
Closes#1404
PRs #1373/#1377 gated cursor daemon endpoints behind a token check, but
startDaemon() did not generate or expose a token. Health-check probing
during startup then 401'd against the new auth, so startDaemon waited 30s
then reported failure. Same for tests asserting /404 and validation
behavior — they couldn't reach the downstream logic past the 401 gate.
- Auto-generate a 32-byte hex token in startDaemon when caller did not
provide one
- Return daemonToken in startDaemon result so callers/tests can attach it
- Update integration tests to include x-ccs-cursor-token header
Red-team follow-up to #1341: the original fix only guarded --print but
Claude accepts -p as the short form, and CCS itself passes -p in
headless-executor.ts. Without this check the security bypass survived
via the short flag.
Added regression tests: ['-p', 'agents'], ['-p', 'doctor'], ['-p']
alone, and injector short-circuit verification for -p form.
- Add CCS_SQLITE_BIN env-var override; validated with fs.realpathSync so
symlinks are fully resolved before prefix check
- Reject any override whose realpath does not start under a trusted system
prefix (prevents PATH-hijack reintroduction from #1347)
- Add TRUSTED_PREFIX_UNIX covering /nix/store/, /opt/local/ (MacPorts),
/snap/, /run/current-system/ in addition to existing /usr/* and
/opt/homebrew/ entries
- Add TRUSTED_PREFIX_WINDOWS covering Program Files, System32, and the
Chocolatey managed bin dir (no canonical winget/Scoop path exists)
- Keep TRUSTED_SQLITE_PATHS_WINDOWS empty — Windows users set CCS_SQLITE_BIN
- Pass env as optional third param to querySqliteJson (backward compatible)
- Add 16-test suite covering env-var acceptance, /tmp rejection, symlink
traversal, NixOS paths, MacPorts, Windows fallback, and prefix safety
Red-team review of #1340 found that backgroundProbe / shouldKeepSessionProxiesAlive /
startKeepAliveWatcher and related types were never reachable: the sole caller
(claude-launcher.ts) passed no hasBackgroundWorkerUsingBaseUrl detector, so
backgroundProbe was always undefined and the keepalive branch never executed.
Remove the unreachable scaffold:
- Delete CLAUDE_BG_WORKER_ARGS, hasClaudeBackgroundWorkerUsingBaseUrl{,InProcessList},
shouldKeepSessionProxiesAlive, ShouldKeepSessionProxiesAliveOptions, and the
SessionProxyKeepAliveOptions interface from session-bridge.ts
- Remove the backgroundProbe/startKeepAliveWatcher block and keepalive exit branch
from setupCleanupHandlers; the function now always calls stopSessionResources on
Claude exit
- Remove backgroundKeepAliveBaseUrl wiring from claude-launcher.ts
- Remove the execFileSync import (was only used by the deleted ps-based detector)
- Update test file: remove tests for deleted exports, keep placeholder
A trusted bg-worker detector can be re-added in a future PR if the feature is
actually needed; the keepalive logic in shouldKeepSessionProxiesAlive can be
restored then.
* fix(dispatcher): treat --print as non-subcommand Claude session
* style: apply prettier formatting
* fix(dispatcher): correct return type in subcommand detector
getClaudeSubcommandName returns string | null; return false (boolean)
was invalid after dev refactored isClaudeSubcommandInvocation to
delegate to it. Change to return null to preserve the --print safety
fix intent.