diff --git a/README.md b/README.md index 47db2780..3bc3f421 100644 --- a/README.md +++ b/README.md @@ -197,13 +197,19 @@ ccs api import ./glm.ccs-profile.json # Import exported profile bundle ### Runtime Aliases (built-in bins / `argv[0]` pattern) -Built-in Droid runtime aliases are installed with the package: +Built-in Droid and native Codex runtime aliases are installed with the package: ```bash ccs-droid glm # explicit alias ccsd glm # legacy shortcut -ccs-codex # explicit Codex alias -ccsx # short Codex alias +ccs-codex # explicit native Codex alias +ccsx # short native Codex alias +``` + +CCS also ships an opinionated Codex provider shortcut: + +```bash +ccsxp # same as: ccs codex --target codex ``` Need additional alias names? First create the matching symlink or another launcher that @@ -255,8 +261,9 @@ Supported in v1: ```bash ccs --target codex # native Codex default session ccs-codex # explicit Codex alias -ccsx # short alias -ccs codex --target codex # built-in CLIProxy Codex on native Codex +ccsx # short native Codex alias +ccsxp # built-in CCS Codex provider on native Codex +ccs codex --target codex # explicit equivalent of ccsxp ccs api create codex-api --cliproxy-provider codex ccs codex-api --target codex # Codex bridge profile on native Codex ``` @@ -287,6 +294,42 @@ with `Use default`. CCS also keeps warning that transient runtime overrides such `codex -c key=value` and `CCS_CODEX_API_KEY` can change the effective runtime without persisting back into the user config file. +#### CLIProxy-backed native Codex + +There are two supported ways to use CLIProxy with native Codex: + +1. `ccsxp` or `ccs codex --target codex` + Uses the built-in CCS Codex provider route on native Codex. This path relies on transient + CCS-managed `-c` overrides and does **not** require changing your saved `model_provider`. + +2. Plain `codex` or a personal alias like `cxp` + Save CLIProxy as the native default provider in `~/.codex/config.toml` (or + `$CODEX_HOME/config.toml`), then export `CLIPROXY_API_KEY` in your shell. + +```toml +model_provider = "cliproxy" + +[model_providers.cliproxy] +base_url = "http://127.0.0.1:8317/api/provider/codex" +env_key = "CLIPROXY_API_KEY" +wire_api = "responses" +``` + +The top-level `model_provider = "cliproxy"` line is required. Defining only +`[model_providers.cliproxy]` is not enough for plain `codex` to pick it by default. + +```bash +export CLIPROXY_API_KEY="ccs-internal-managed" +ccsxp "your prompt" # CCS shortcut for the built-in provider route +codex "your prompt" # native Codex using your saved cliproxy default +``` + +Dashboard parity: `ccs config` -> `Compatible` -> `Codex CLI` + +- `Overview`: explains `ccsx` vs `ccsxp` +- `Top-level settings`: set **Default provider** to `cliproxy` +- `Model providers`: save `cliproxy` with `env_key = "CLIPROXY_API_KEY"` + ### Per-Profile Target Defaults You can pin a default target (`claude` or `droid`) per profile: diff --git a/src/commands/help-command.ts b/src/commands/help-command.ts index 0d76bd59..c1e878ba 100644 --- a/src/commands/help-command.ts +++ b/src/commands/help-command.ts @@ -407,6 +407,7 @@ Run ${color('ccs config', 'command')} for web dashboard`.trim(); ['ccsd [args]', 'Legacy shortcut for: ccs-droid [args]'], ['ccs-codex [args]', 'Explicit Codex runtime alias'], ['ccsx [args]', 'Short alias for: ccs-codex [args]'], + ['ccsxp [args]', 'Shortcut for: ccs codex --target codex [args]'], ], writeLine ); @@ -421,7 +422,8 @@ Run ${color('ccs config', 'command')} for web dashboard`.trim(); ['ccs --target codex', 'Open a native Codex session with your existing ~/.codex setup'], ['ccs-codex', 'Same as above (explicit Codex alias)'], ['ccsx', 'Short alias for ccs-codex'], - ['ccs codex --target codex', 'Run built-in CLIProxy Codex on native Codex CLI'], + ['ccsxp "your prompt"', 'Run built-in CLIProxy Codex on native Codex CLI'], + ['ccs codex --target codex', 'Explicit form of ccsxp'], [ 'ccs api create codex-api --cliproxy-provider codex', 'Create a routed API bridge that can also run on Codex', @@ -450,6 +452,20 @@ Run ${color('ccs config', 'command')} for web dashboard`.trim(); writeLine ); + printSubSection( + 'Codex + CLIProxy', + [ + ['ccsxp "your prompt"', 'Use the built-in CCS Codex provider shortcut on native Codex'], + ['ccs config', 'Open Compatible -> Codex CLI for native Codex setup and diagnostics'], + [ + 'Default provider', + 'Set to cliproxy if plain codex or a personal cxp alias should use CLIProxy', + ], + ['Model provider auth', 'Save cliproxy with env_key = "CLIPROXY_API_KEY"'], + ], + writeLine + ); + // Configuration printConfigSection( 'Configuration', diff --git a/src/targets/target-runtime-compatibility.ts b/src/targets/target-runtime-compatibility.ts index 65fd6024..9c9a83ca 100644 --- a/src/targets/target-runtime-compatibility.ts +++ b/src/targets/target-runtime-compatibility.ts @@ -65,7 +65,7 @@ export function evaluateTargetRuntimeCompatibility( if (input.cliproxyProvider !== 'codex') { return unsupported( `Codex CLI only supports CLIProxy provider "codex". This profile routes to "${input.cliproxyProvider || 'unknown'}".`, - 'Use: ccs codex --target codex, ccs-codex codex, or stay on Claude/Droid for other providers.' + 'Use: ccsxp, ccs codex --target codex, or stay on Claude/Droid for other providers.' ); } return { supported: true }; diff --git a/tests/unit/commands/help-command-parity.test.ts b/tests/unit/commands/help-command-parity.test.ts index 41619e6b..687fd2e5 100644 --- a/tests/unit/commands/help-command-parity.test.ts +++ b/tests/unit/commands/help-command-parity.test.ts @@ -106,8 +106,12 @@ describe('help command parity', () => { const rendered = stripAnsi(lines.join('\n')); expect(rendered.includes('ccs-codex [args]')).toBe(true); expect(rendered.includes('ccsx [args]')).toBe(true); + expect(rendered.includes('ccsxp [args]')).toBe(true); expect(rendered.includes('ccs --target codex')).toBe(true); + expect(rendered.includes('ccsxp "your prompt"')).toBe(true); expect(rendered.includes('ccs codex-api --target codex')).toBe(true); + expect(rendered.includes('Compatible -> Codex CLI')).toBe(true); + expect(rendered.includes('CLIPROXY_API_KEY')).toBe(true); expect(rendered.includes('codex (runtime-only)')).toBe(true); });