mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 10:18:14 +00:00
1 parent
5a7c2202f4
commit
5a54c1b536
7 files changed
+43
-9
No files matched your search
@@ -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).
|
* **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)
|
## [7.79.1](https://github.com/kaitranntt/ccs/compare/v7.79.0...v7.79.1) (2026-05-14)
|
||||||
|
|
||||||
### Hotfixes
|
### Hotfixes
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ src/
|
|||||||
### Native Codex Runtime Target
|
### 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`.
|
- 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.
|
- 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.
|
- 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.
|
- `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
|
# 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.
|
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
|
### 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-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**: **#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.
|
- **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
|
ccsx
|
||||||
→ dist/bin/codex-runtime.js
|
→ dist/bin/codex-runtime.js
|
||||||
→ CCS_INTERNAL_ENTRY_TARGET=codex
|
→ CCS_INTERNAL_ENTRY_TARGET=codex
|
||||||
|
→ passes native Codex diagnostics and `resume` through before CCS profile detection
|
||||||
|
|
||||||
ccsxp
|
ccsxp
|
||||||
→ dist/bin/ccsxp-runtime.js
|
→ dist/bin/ccsxp-runtime.js
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export interface DispatcherBootstrap {
|
|||||||
* - setGlobalConfigDir (--config-dir flag)
|
* - setGlobalConfigDir (--config-dir flag)
|
||||||
* - Cloud-sync warnings
|
* - Cloud-sync warnings
|
||||||
* - Completion short-circuit via tryHandleRootCommand
|
* - 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
|
* Adapter registration (registerTarget calls) stays in main() because it is
|
||||||
* singleton wiring with no dependency on the parsed args.
|
* 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 };
|
return { args, isCompletionCommand, browserLaunchOverride: undefined, exitNow: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldPassthroughNativeCodexFlagCommand(args)) {
|
if (shouldPassthroughNativeCodexCommand(args)) {
|
||||||
const { execNativeCodexFlagCommand } = await import('./target-executor');
|
const { execNativeCodexCommand } = await import('./target-executor');
|
||||||
execNativeCodexFlagCommand(args);
|
execNativeCodexCommand(args);
|
||||||
return { args, isCompletionCommand, browserLaunchOverride: undefined, exitNow: true };
|
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_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;
|
export const NATIVE_CLAUDE_EFFORT_LEVELS = ['low', 'medium', 'high', 'xhigh', 'max'] as const;
|
||||||
|
|
||||||
@@ -314,7 +315,7 @@ export function shouldNormalizeNativeClaudeEffort(
|
|||||||
|
|
||||||
// ========== Native Codex Passthrough ==========
|
// ========== Native Codex Passthrough ==========
|
||||||
|
|
||||||
export function shouldPassthroughNativeCodexFlagCommand(args: string[]): boolean {
|
export function shouldPassthroughNativeCodexCommand(args: string[]): boolean {
|
||||||
return getNativeCodexPassthroughArgs(args) !== null;
|
return getNativeCodexPassthroughArgs(args) !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,11 +329,17 @@ export function getNativeCodexPassthroughArgs(args: string[]): string[] | null {
|
|||||||
if (CODEX_NATIVE_PASSTHROUGH_FLAGS.has(firstArg)) {
|
if (CODEX_NATIVE_PASSTHROUGH_FLAGS.has(firstArg)) {
|
||||||
return targetArgs;
|
return targetArgs;
|
||||||
}
|
}
|
||||||
|
if (CODEX_NATIVE_PASSTHROUGH_SUBCOMMANDS.has(firstArg)) {
|
||||||
|
return targetArgs;
|
||||||
|
}
|
||||||
|
|
||||||
const secondArg = targetArgs[1] || '';
|
const secondArg = targetArgs[1] || '';
|
||||||
if (firstArg === 'codex' && CODEX_NATIVE_PASSTHROUGH_FLAGS.has(secondArg)) {
|
if (firstArg === 'codex' && CODEX_NATIVE_PASSTHROUGH_FLAGS.has(secondArg)) {
|
||||||
return targetArgs.slice(1);
|
return targetArgs.slice(1);
|
||||||
}
|
}
|
||||||
|
if (firstArg === 'codex' && CODEX_NATIVE_PASSTHROUGH_SUBCOMMANDS.has(secondArg)) {
|
||||||
|
return targetArgs.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
* and top-level profile dispatcher (Phase E switch).
|
* and top-level profile dispatcher (Phase E switch).
|
||||||
*
|
*
|
||||||
* Extracted from src/ccs.ts (lines 291-295, 394-426).
|
* 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.
|
* before the main profile dispatch loop runs.
|
||||||
*
|
*
|
||||||
* dispatchProfile() collapses the 6-branch switch in main() to a single call.
|
* dispatchProfile() collapses the 6-branch switch in main() to a single call.
|
||||||
@@ -29,9 +29,9 @@ export interface ProfileError extends Error {
|
|||||||
suggestions?: string[];
|
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');
|
const adapter = getTarget('codex');
|
||||||
if (!adapter) {
|
if (!adapter) {
|
||||||
console.error(fail('Target adapter not found for "codex"'));
|
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', () => {
|
it('strips nested Codex session env from passthrough launches while keeping CODEX_HOME', () => {
|
||||||
if (process.platform === 'win32') return;
|
if (process.platform === 'win32') return;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user