mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-15 20:20:09 +00:00
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<Disp
|
||||
return { args, isCompletionCommand, browserLaunchOverride: undefined, exitNow: true };
|
||||
}
|
||||
|
||||
if (shouldPassthroughNativeCodexFlagCommand(args)) {
|
||||
const { execNativeCodexFlagCommand } = await import('./target-executor');
|
||||
execNativeCodexFlagCommand(args);
|
||||
if (shouldPassthroughNativeCodexCommand(args)) {
|
||||
const { execNativeCodexCommand } = await import('./target-executor');
|
||||
execNativeCodexCommand(args);
|
||||
return { args, isCompletionCommand, browserLaunchOverride: undefined, exitNow: true };
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@ export const CODEX_RUNTIME_REASONING_LEVELS = new Set([
|
||||
]);
|
||||
|
||||
export const CODEX_NATIVE_PASSTHROUGH_FLAGS = new Set(['--help', '-h', '--version', '-v']);
|
||||
export const CODEX_NATIVE_PASSTHROUGH_SUBCOMMANDS = new Set(['resume']);
|
||||
|
||||
export const NATIVE_CLAUDE_EFFORT_LEVELS = ['low', 'medium', 'high', 'xhigh', 'max'] as const;
|
||||
|
||||
@@ -314,7 +315,7 @@ export function shouldNormalizeNativeClaudeEffort(
|
||||
|
||||
// ========== Native Codex Passthrough ==========
|
||||
|
||||
export function shouldPassthroughNativeCodexFlagCommand(args: string[]): boolean {
|
||||
export function shouldPassthroughNativeCodexCommand(args: string[]): boolean {
|
||||
return getNativeCodexPassthroughArgs(args) !== null;
|
||||
}
|
||||
|
||||
@@ -328,11 +329,17 @@ export function getNativeCodexPassthroughArgs(args: string[]): string[] | null {
|
||||
if (CODEX_NATIVE_PASSTHROUGH_FLAGS.has(firstArg)) {
|
||||
return targetArgs;
|
||||
}
|
||||
if (CODEX_NATIVE_PASSTHROUGH_SUBCOMMANDS.has(firstArg)) {
|
||||
return targetArgs;
|
||||
}
|
||||
|
||||
const secondArg = targetArgs[1] || '';
|
||||
if (firstArg === 'codex' && CODEX_NATIVE_PASSTHROUGH_FLAGS.has(secondArg)) {
|
||||
return targetArgs.slice(1);
|
||||
}
|
||||
if (firstArg === 'codex' && CODEX_NATIVE_PASSTHROUGH_SUBCOMMANDS.has(secondArg)) {
|
||||
return targetArgs.slice(1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* and top-level profile dispatcher (Phase E switch).
|
||||
*
|
||||
* Extracted from src/ccs.ts (lines 291-295, 394-426).
|
||||
* Handles direct execution of native Codex flag passthrough (--help, --version, etc.)
|
||||
* Handles direct execution of native Codex passthrough commands (--help, resume, etc.)
|
||||
* before the main profile dispatch loop runs.
|
||||
*
|
||||
* dispatchProfile() collapses the 6-branch switch in main() to a single call.
|
||||
@@ -29,9 +29,9 @@ export interface ProfileError extends Error {
|
||||
suggestions?: string[];
|
||||
}
|
||||
|
||||
// ========== Native Codex Flag Command Executor ==========
|
||||
// ========== Native Codex Command Executor ==========
|
||||
|
||||
export function execNativeCodexFlagCommand(args: string[]): void {
|
||||
export function execNativeCodexCommand(args: string[]): void {
|
||||
const adapter = getTarget('codex');
|
||||
if (!adapter) {
|
||||
console.error(fail('Target adapter not found for "codex"'));
|
||||
|
||||
@@ -498,6 +498,26 @@ process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
it('passes ccsx resume straight through to the native Codex binary', () => {
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user