From 5a54c1b536fe228c29754ed20be81149d51be4da Mon Sep 17 00:00:00 2001 From: "Kai (Tam Nhu) Tran" <61256810+kaitranntt@users.noreply.github.com> Date: Mon, 18 May 2026 09:45:20 -0400 Subject: [PATCH] fix(codex): pass ccsx resume through to native codex Closes #1287 --- CHANGELOG.md | 4 ++++ docs/codebase-summary.md | 1 + docs/project-roadmap.md | 3 ++- docs/system-architecture/target-adapters.md | 1 + src/dispatcher/cli-argument-parser.ts | 17 +++++++++++----- src/dispatcher/target-executor.ts | 6 +++--- .../targets/codex-runtime-integration.test.ts | 20 +++++++++++++++++++ 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17ba3f7d..c00be0b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ * **docker:** `ghcr.io/kaitranntt/ccs-dashboard:latest` Docker image is deprecated — migrate to `ghcr.io/kaitranntt/ccs:latest` (CCS + CLIProxy). The legacy image continues publishing for 2 more releases and emits a startup warning. See [#1251](https://github.com/kaitranntt/ccs/issues/1251). +### Bug Fixes + +* **codex:** Pass `ccsx resume` through to native Codex instead of treating `resume` as a CCS profile. + ## [7.79.1](https://github.com/kaitranntt/ccs/compare/v7.79.0...v7.79.1) (2026-05-14) ### Hotfixes diff --git a/docs/codebase-summary.md b/docs/codebase-summary.md index e9fe2bb3..275c559f 100644 --- a/docs/codebase-summary.md +++ b/docs/codebase-summary.md @@ -273,6 +273,7 @@ src/ ### Native Codex Runtime Target - Dedicated runtime entrypoints: `ccs-codex` and `ccsx` resolve through `src/bin/codex-runtime.ts`, while `ccsxp` resolves through `src/bin/ccsxp-runtime.ts`; all three set `CCS_INTERNAL_ENTRY_TARGET=codex` before delegating to `src/targets/target-resolver.ts`. +- Native Codex passthrough: `ccsx --help`, `ccsx --version`, and `ccsx resume ...` short-circuit before CCS profile detection, so Codex diagnostics and session resume behavior stay aligned with the upstream Codex CLI. CCS-owned `ccsx auth` remains the managed Codex profile namespace. - Provider shortcut behavior: `ccsxp` strips user-supplied `--target` overrides and prepends `--config model_provider="cliproxy"` so it behaves like native Codex plus the CLIProxy provider recipe. The stricter CCS-managed bridge remains available explicitly through `ccs codex --target codex`. It pins `CODEX_HOME` to native `~/.codex` by default so inherited launcher state does not send history/config writes to a nonstandard Codex root; `CCSXP_CODEX_HOME` is the explicit override. On launch, CCS repairs the native `[model_providers.cliproxy]` stanza in `config.toml`, preserves a valid custom `base_url`, reads that provider's configured `env_key` (default `CLIPROXY_API_KEY`), and injects the effective CLIProxy auth token into that key for the child Codex process. - Implicit Codex launches such as `ccs --target codex` and `ccsxp` use native Codex default mode even when the CCS default profile is a Claude account. Explicit unsupported profiles such as `ccs work --target codex` still fail fast with native-vs-pool guidance. - `argv[0]` alias mapping still exists in `src/targets/target-resolver.ts` for same-binary/custom alias scenarios, but the built-in npm bins above do not depend on that map at runtime. diff --git a/docs/project-roadmap.md b/docs/project-roadmap.md index 3d7bf32f..8d909d8f 100644 --- a/docs/project-roadmap.md +++ b/docs/project-roadmap.md @@ -1,6 +1,6 @@ # CCS Project Roadmap -Last Updated: 2026-05-09 +Last Updated: 2026-05-18 Forward-looking roadmap documenting current priorities, GitHub issues, and future feature plans. @@ -41,6 +41,7 @@ All major modularization work is complete. The codebase evolved from monolithic ### Recent Fixes +- **2026-05-18**: **#1287** `ccsx resume` now passes through to the native Codex `resume` subcommand before CCS profile detection, preserving Codex session continuation while keeping `ccsx auth` on the managed Codex profile namespace. - **2026-05-09**: **#1199** Existing Claude auth accounts now have dashboard-visible Shared Resources controls separate from History Sync. Accounts exposes a dedicated Resources action for `shared` vs `profile-local`, `/shared` now inventories commands, skills, agents, plugins, and `settings.json`, plugin directories without docs show factual directory contents, and shared settings content is inspectable read-only through the localhost-gated shared-content API. - **2026-05-07**: **#760** Codex GPT fast mode is now a first-class CLIProxy model tuning suffix. CCS accepts `gpt-5.4-fast`, `gpt-5.4-high-fast`, and equivalent canonicalized forms in raw env configs, CLI variant creation, and the dashboard model picker; runtime requests now send the base upstream model with `reasoning.effort` plus `service_tier: "priority"` instead of leaking the suffixed alias to CLIProxy upstream routing. - **2026-05-07**: **#1103** GitHub Copilot is now treated as a deprecated compatibility bridge. The dashboard moves Copilot out of the active Identity & Access section and into Deprecated, quick setup no longer offers `ghcp` for new onboarding, CLI/help/config copy marks Copilot as deprecated, and existing `ccs copilot` / `ghcp` compatibility paths remain available for current setups. diff --git a/docs/system-architecture/target-adapters.md b/docs/system-architecture/target-adapters.md index 228ed888..929a6ffb 100644 --- a/docs/system-architecture/target-adapters.md +++ b/docs/system-architecture/target-adapters.md @@ -515,6 +515,7 @@ ccs-codex ccsx → dist/bin/codex-runtime.js → CCS_INTERNAL_ENTRY_TARGET=codex +→ passes native Codex diagnostics and `resume` through before CCS profile detection ccsxp → dist/bin/ccsxp-runtime.js diff --git a/src/dispatcher/cli-argument-parser.ts b/src/dispatcher/cli-argument-parser.ts index 2a11a199..dcb8c72c 100644 --- a/src/dispatcher/cli-argument-parser.ts +++ b/src/dispatcher/cli-argument-parser.ts @@ -43,7 +43,7 @@ export interface DispatcherBootstrap { * - setGlobalConfigDir (--config-dir flag) * - Cloud-sync warnings * - Completion short-circuit via tryHandleRootCommand - * - Codex native passthrough via execNativeCodexFlagCommand + * - Codex native passthrough via execNativeCodexCommand * * Adapter registration (registerTarget calls) stays in main() because it is * singleton wiring with no dependency on the parsed args. @@ -141,9 +141,9 @@ export async function bootstrapAndParseEarlyCli(rawArgs: string[]): Promise { + if (process.platform === 'win32') return; + + const result = runCodexAlias(['resume', '--help'], { + ...process.env, + CI: '1', + NO_COLOR: '1', + CCS_HOME: tmpHome, + CODEX_HOME: path.join(tmpHome, '.codex'), + CCS_CODEX_PATH: fakeCodexPath, + CCS_TEST_CODEX_ARGS_OUT: codexArgsLogPath, + CCS_TEST_CODEX_HELP: 'Resume a previous interactive session', + }); + + expect(result.status).toBe(0); + expect(result.stdout).toContain('Resume a previous interactive session'); + expect(result.stderr).not.toContain('Profile not found: resume'); + expect(readLoggedCodexCalls(codexArgsLogPath)).toEqual([['resume', '--help']]); + }); + it('strips nested Codex session env from passthrough launches while keeping CODEX_HOME', () => { if (process.platform === 'win32') return;