From 160be319d0b1982c05dc2984673a81aa6ec245b5 Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Mon, 23 Mar 2026 13:44:32 -0400 Subject: [PATCH] feat: add explicit droid runtime alias surface --- README.md | 29 +++++--- docs/code-standards.md | 3 +- docs/codebase-summary.md | 2 +- docs/system-architecture/index.md | 9 ++- docs/system-architecture/target-adapters.md | 25 +++++-- package.json | 1 + src/commands/api-command/create-command.ts | 18 ++++- src/commands/cliproxy/variant-subcommand.ts | 28 +++++-- src/commands/help-command.ts | 16 ++-- src/targets/target-resolver.ts | 73 ++++++++++++++++--- .../targets/ccsd-alias-integration.test.ts | 11 +++ tests/unit/targets/target-resolver.test.ts | 34 +++++++++ .../provider-editor/provider-info-tab.tsx | 6 +- .../profiles/editor/info-section.tsx | 10 +-- .../profiles/profile-create-dialog.tsx | 24 ++++-- ui/src/lib/i18n.ts | 9 +-- ui/src/lib/support-updates-catalog.ts | 16 ++-- 17 files changed, 229 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index 828919e2..62012ab1 100644 --- a/README.md +++ b/README.md @@ -194,16 +194,25 @@ ccs api export glm --out ./glm.ccs-profile.json # Export for cross-device trans ccs api import ./glm.ccs-profile.json # Import exported profile bundle ``` -### Droid Alias (`argv[0]` pattern) +### Runtime Aliases (`argv[0]` pattern) -By default, invoking CCS as `ccsd` auto-selects the Droid target: +Built-in Droid runtime aliases: ```bash +ln -s "$(command -v ccs)" /usr/local/bin/ccs-droid ln -s "$(command -v ccs)" /usr/local/bin/ccsd -ccsd glm +ccs-droid glm # explicit alias +ccsd glm # legacy shortcut ``` -Need additional alias names? Set `CCS_DROID_ALIASES` as a comma-separated list (for example: `CCS_DROID_ALIASES=ccs-droid,mydroid`). +Need additional alias names? Use `CCS_TARGET_ALIASES` (preferred) or keep using +legacy `CCS_DROID_ALIASES`: + +```bash +CCS_TARGET_ALIASES='droid=mydroid,team-droid' +# Legacy fallback still supported: +CCS_DROID_ALIASES='mydroid,team-droid' +``` For Factory BYOK compatibility, CCS also stores a per-profile Droid provider hint (`CCS_DROID_PROVIDER`) using one of: @@ -217,9 +226,9 @@ which Droid treats as queued prompt text. CCS supports structural Droid command passthrough after profile selection: ```bash -ccsd codex exec --skip-permissions-unsafe "fix failing tests" -ccsd codex --skip-permissions-unsafe "fix failing tests" # auto-routed to: droid exec ... -ccsd codex -m custom:gpt-5.3-codex "fix failing tests" # short exec flags auto-routed too +ccs-droid codex exec --skip-permissions-unsafe "fix failing tests" +ccs-droid codex --skip-permissions-unsafe "fix failing tests" # auto-routed to: droid exec ... +ccs-droid codex -m custom:gpt-5.3-codex "fix failing tests" # short exec flags auto-routed too ``` If you pass exec-only flags without a prompt (for example `--skip-permissions-unsafe`), @@ -245,10 +254,10 @@ ccs cliproxy create mycodex --provider codex --target droid Built-in CLIProxy providers also work with Droid alias/target override: ```bash -ccsd codex -ccsd agy +ccs-droid codex +ccs-droid agy ccs codex --target droid -ccsd codex exec --auto high "triage this bug report" +ccs-droid codex exec --auto high "triage this bug report" ``` Dashboard parity: diff --git a/docs/code-standards.md b/docs/code-standards.md index 8d6182ba..60e41441 100644 --- a/docs/code-standards.md +++ b/docs/code-standards.md @@ -200,7 +200,8 @@ Resolves which adapter to use via `resolveTargetType()`: ↓ 2. Profile config: profileConfig.target field ↓ -3. argv[0] detection (busybox pattern): +3. argv[0] detection (runtime alias pattern): + - ccs-droid → droid - ccsd → droid - ccs → default ↓ diff --git a/docs/codebase-summary.md b/docs/codebase-summary.md index 17ae9fca..37049183 100644 --- a/docs/codebase-summary.md +++ b/docs/codebase-summary.md @@ -246,7 +246,7 @@ The targets module provides an extensible interface for dispatching profiles to 2. **Target Resolution** - Priority order: - `--target ` flag (CLI argument) - Per-profile `target` field (from config.yaml) - - `argv[0]` detection (busybox pattern: `ccsd` → droid) + - `argv[0]` detection (runtime alias pattern: `ccs-droid` / `ccsd` → droid) - Default: `claude` 3. **Implementations:** diff --git a/docs/system-architecture/index.md b/docs/system-architecture/index.md index 7de060eb..6c4e1647 100644 --- a/docs/system-architecture/index.md +++ b/docs/system-architecture/index.md @@ -86,11 +86,12 @@ Spawn Target Process - Spawns: `droid -m custom:ccs- ` - Model config includes baseUrl, apiKey, provider -**Binary alias pattern (busybox-style):** +**Runtime alias pattern (argv[0]-style):** ``` -ccs → Target: claude (default) -ccsd → Target: droid (auto-selected via argv[0]) +ccs → Target: claude (default) +ccs-droid → Target: droid (explicit alias) +ccsd → Target: droid (legacy shortcut) ``` For details on the adapter architecture, see [Target Adapters](./target-adapters.md). @@ -392,7 +393,7 @@ See [Provider Flows](./provider-flows.md) → Authentication Flow section. | +---> Creates symlink: ccs --> dist/ccs.js | - +---> Binary alias: ccsd → ccs (auto-selects droid target) + +---> Runtime aliases: ccs-droid / ccsd → ccs (auto-select droid target) | +---> First run creates: ~/.ccs/ ``` diff --git a/docs/system-architecture/target-adapters.md b/docs/system-architecture/target-adapters.md index c1944c6b..5d81005e 100644 --- a/docs/system-architecture/target-adapters.md +++ b/docs/system-architecture/target-adapters.md @@ -79,8 +79,9 @@ CCS resolves which adapter to use via priority-ordered checks: glm: target: droid -3. argv[0] detection (busybox pattern) — binary name mapping - └─ ccsd (symlink/batch file) → droid +3. argv[0] detection (runtime alias pattern) — binary name mapping + └─ ccs-droid (explicit alias) → droid + └─ ccsd (legacy shortcut) → droid └─ ccs (regular command) → default 4. Fallback: 'claude' — lowest priority @@ -351,22 +352,30 @@ ccs --target droid glm (credentials loaded from ~/.factory/settings.json) ``` -### Binary Alias Pattern +### Runtime Alias Pattern ```bash -# Create alias/symlink to auto-select droid target -# Built-in alias: ccsd +# Create aliases/symlinks to auto-select droid target +ln -s /path/to/ccs /path/to/ccs-droid ln -s /path/to/ccs /path/to/ccsd # Usage +ccs-droid glm +→ Target: droid (detected from argv[0]) +→ droid -m custom:ccs-glm "args..." + +# Legacy shortcut still works ccsd glm → Target: droid (detected from argv[0]) → droid -m custom:ccs-glm "args..." ``` -On Windows, `ccsd.cmd`, `ccsd.bat`, `ccsd.ps1`, and `ccsd.exe` wrappers are also recognized. +On Windows, `ccs-droid.cmd`, `ccsd.cmd`, `ccsd.bat`, `ccsd.ps1`, and `ccsd.exe` wrappers are also recognized. -Additional alias names can be configured at runtime via `CCS_DROID_ALIASES` (comma-separated). Example: `CCS_DROID_ALIASES=ccs-droid,mydroid`. +Additional alias names can be configured at runtime via `CCS_TARGET_ALIASES` +(preferred, `target=alias1,alias2;...`) or legacy `CCS_DROID_ALIASES` +(comma-separated). Example: +`CCS_TARGET_ALIASES=droid=mydroid,team-droid` --- @@ -612,7 +621,7 @@ ccs --target claude help ccs --target droid help # Test argv[0] detection -ccsd help +ccs-droid help ``` --- diff --git a/package.json b/package.json index c353c70a..ef687955 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "types": "dist/ccs.d.ts", "bin": { "ccs": "dist/ccs.js", + "ccs-droid": "dist/ccs.js", "ccsd": "dist/ccs.js" }, "files": [ diff --git a/src/commands/api-command/create-command.ts b/src/commands/api-command/create-command.ts index 0bcce273..dbd798a6 100644 --- a/src/commands/api-command/create-command.ts +++ b/src/commands/api-command/create-command.ts @@ -366,12 +366,18 @@ export async function handleApiCreateCommand(args: string[]): Promise { ` ${color(`ccs ${result.name} "your prompt"`, 'command')} ${dim('# uses droid by default')}` ); console.log( - ` ${color(`ccsd ${result.name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` + ` ${color(`ccs-droid ${result.name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` + ); + console.log( + ` ${color(`ccsd ${result.name} "your prompt"`, 'command')} ${dim('# legacy shortcut')}` ); } else { console.log(` ${color(`ccs ${result.name} "your prompt"`, 'command')}`); console.log( - ` ${color(`ccs ${result.name} --target droid "your prompt"`, 'command')} ${dim('# optional target override')}` + ` ${color(`ccs-droid ${result.name} "your prompt"`, 'command')} ${dim('# explicit one-off droid alias')}` + ); + console.log( + ` ${color(`ccs ${result.name} --target droid "your prompt"`, 'command')} ${dim('# target flag alternative')}` ); } console.log(''); @@ -447,8 +453,9 @@ export async function handleApiCreateCommand(args: string[]): Promise { ` ${color(`ccs ${name} "your prompt"`, 'command')} ${dim('# uses droid by default')}` ); console.log( - ` ${color(`ccsd ${name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` + ` ${color(`ccs-droid ${name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` ); + console.log(` ${color(`ccsd ${name} "your prompt"`, 'command')} ${dim('# legacy shortcut')}`); console.log( ` ${color(`ccs ${name} --target claude "your prompt"`, 'command')} ${dim('# override to Claude')}` ); @@ -457,7 +464,10 @@ export async function handleApiCreateCommand(args: string[]): Promise { ` ${color(`ccs ${name} "your prompt"`, 'command')} ${dim('# uses claude by default')}` ); console.log( - ` ${color(`ccs ${name} --target droid "your prompt"`, 'command')} ${dim('# run on droid for this call')}` + ` ${color(`ccs-droid ${name} "your prompt"`, 'command')} ${dim('# explicit one-off droid alias')}` + ); + console.log( + ` ${color(`ccs ${name} --target droid "your prompt"`, 'command')} ${dim('# target flag alternative')}` ); } console.log(''); diff --git a/src/commands/cliproxy/variant-subcommand.ts b/src/commands/cliproxy/variant-subcommand.ts index b3a00056..44d69d2b 100644 --- a/src/commands/cliproxy/variant-subcommand.ts +++ b/src/commands/cliproxy/variant-subcommand.ts @@ -290,7 +290,10 @@ export async function handleCreate( ` ${color(`ccs ${name} "your prompt"`, 'command')} ${dim('# uses droid by default')}` ); console.log( - ` ${color(`ccsd ${name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` + ` ${color(`ccs-droid ${name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` + ); + console.log( + ` ${color(`ccsd ${name} "your prompt"`, 'command')} ${dim('# legacy shortcut')}` ); console.log( ` ${color(`ccs ${name} --target claude "your prompt"`, 'command')} ${dim('# override to Claude')}` @@ -300,7 +303,10 @@ export async function handleCreate( ` ${color(`ccs ${name} "your prompt"`, 'command')} ${dim('# uses claude by default')}` ); console.log( - ` ${color(`ccs ${name} --target droid "your prompt"`, 'command')} ${dim('# run on droid for this call')}` + ` ${color(`ccs-droid ${name} "your prompt"`, 'command')} ${dim('# explicit one-off droid alias')}` + ); + console.log( + ` ${color(`ccs ${name} --target droid "your prompt"`, 'command')} ${dim('# target flag alternative')}` ); } console.log(''); @@ -452,8 +458,9 @@ export async function handleCreate( ` ${color(`ccs ${name} "your prompt"`, 'command')} ${dim('# uses droid by default')}` ); console.log( - ` ${color(`ccsd ${name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` + ` ${color(`ccs-droid ${name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` ); + console.log(` ${color(`ccsd ${name} "your prompt"`, 'command')} ${dim('# legacy shortcut')}`); console.log( ` ${color(`ccs ${name} --target claude "your prompt"`, 'command')} ${dim('# override to Claude')}` ); @@ -462,7 +469,10 @@ export async function handleCreate( ` ${color(`ccs ${name} "your prompt"`, 'command')} ${dim('# uses claude by default')}` ); console.log( - ` ${color(`ccs ${name} --target droid "your prompt"`, 'command')} ${dim('# run on droid for this call')}` + ` ${color(`ccs-droid ${name} "your prompt"`, 'command')} ${dim('# explicit one-off droid alias')}` + ); + console.log( + ` ${color(`ccs ${name} --target droid "your prompt"`, 'command')} ${dim('# target flag alternative')}` ); } console.log(''); @@ -697,7 +707,10 @@ export async function handleEdit( ` ${color(`ccs ${name} "your prompt"`, 'command')} ${dim('# uses droid by default')}` ); console.log( - ` ${color(`ccsd ${name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` + ` ${color(`ccs-droid ${name} "your prompt"`, 'command')} ${dim('# explicit droid alias')}` + ); + console.log( + ` ${color(`ccsd ${name} "your prompt"`, 'command')} ${dim('# legacy shortcut')}` ); console.log( ` ${color(`ccs ${name} --target claude "your prompt"`, 'command')} ${dim('# override to Claude')}` @@ -707,7 +720,10 @@ export async function handleEdit( ` ${color(`ccs ${name} "your prompt"`, 'command')} ${dim('# uses claude by default')}` ); console.log( - ` ${color(`ccs ${name} --target droid "your prompt"`, 'command')} ${dim('# run on droid for this call')}` + ` ${color(`ccs-droid ${name} "your prompt"`, 'command')} ${dim('# explicit one-off droid alias')}` + ); + console.log( + ` ${color(`ccs ${name} --target droid "your prompt"`, 'command')} ${dim('# target flag alternative')}` ); } console.log(''); diff --git a/src/commands/help-command.ts b/src/commands/help-command.ts index acb6adbe..0d8c0e26 100644 --- a/src/commands/help-command.ts +++ b/src/commands/help-command.ts @@ -355,22 +355,24 @@ Run ${color('ccs config', 'command')} for web dashboard`.trim(); // Aliases printSubSection('Aliases', [ - ['ccsd [args]', 'Shorthand for: ccs --target droid'], + ['ccs-droid [args]', 'Explicit Droid runtime alias'], + ['ccsd [args]', 'Legacy shortcut for: ccs-droid [args]'], ]); // Multi-target examples printSubSection('Multi-Target', [ ['ccs glm --target droid', 'Run GLM profile on Droid CLI'], - ['ccsd glm', 'Same as above (alias)'], - ['ccsd codex', 'Run built-in CLIProxy Codex profile on Droid'], - ['ccsd agy', 'Run built-in CLIProxy Antigravity profile on Droid'], + ['ccs-droid glm', 'Same as above (explicit alias)'], + ['ccsd glm', 'Legacy shortcut for ccs-droid'], + ['ccs-droid codex', 'Run built-in CLIProxy Codex profile on Droid'], + ['ccs-droid agy', 'Run built-in CLIProxy Antigravity profile on Droid'], [ - 'ccsd codex exec --skip-permissions-unsafe "fix failing tests"', + 'ccs-droid codex exec --skip-permissions-unsafe "fix failing tests"', 'Pass through Droid exec mode', ], - ['ccsd codex -m custom:gpt-5.3-codex "fix failing tests"', 'Auto-routes short exec flags'], + ['ccs-droid codex -m custom:gpt-5.3-codex "fix failing tests"', 'Auto-routes short exec flags'], [ - 'ccsd codex --skip-permissions-unsafe "fix failing tests"', + 'ccs-droid codex --skip-permissions-unsafe "fix failing tests"', 'Auto-routes to Droid exec when exec-only flags are detected', ], [ diff --git a/src/targets/target-resolver.ts b/src/targets/target-resolver.ts index b7a811f4..eced5f8a 100644 --- a/src/targets/target-resolver.ts +++ b/src/targets/target-resolver.ts @@ -12,27 +12,76 @@ import * as path from 'path'; import { TargetType } from './target-adapter'; /** - * Map of binary names to target types (busybox pattern). - * When CCS is invoked as `ccsd`, it auto-selects the droid target. + * Built-in argv[0] aliases for explicit runtime entrypoints. + * `ccs-droid` is the transparent alias; `ccsd` remains as a legacy shortcut. */ -const ARGV0_TARGET_MAP: Record = { +const BUILTIN_ARGV0_TARGET_MAP: Record = { + 'ccs-droid': 'droid', ccsd: 'droid', }; const ALIAS_NAME_REGEX = /^[a-z0-9._-]+$/; +const GENERIC_TARGET_ALIAS_ENV_VAR = 'CCS_TARGET_ALIASES'; +const LEGACY_TARGET_ALIAS_ENV_VARS: Partial> = { + droid: 'CCS_DROID_ALIASES', +}; -function buildArgv0TargetMap(): Record { - const map: Record = { ...ARGV0_TARGET_MAP }; - const envAliases = process.env['CCS_DROID_ALIASES']; - if (!envAliases) { - return map; +function addAliasToMap(map: Record, alias: string, target: TargetType): void { + const normalizedAlias = alias.trim().toLowerCase(); + if (!normalizedAlias || !ALIAS_NAME_REGEX.test(normalizedAlias)) { + return; } - for (const rawAlias of envAliases.split(',')) { - const alias = rawAlias.trim().toLowerCase(); - if (!alias || !ALIAS_NAME_REGEX.test(alias)) { + map[normalizedAlias] = target; +} + +function addAliasListToMap( + map: Record, + target: TargetType, + rawAliases: string +): void { + for (const rawAlias of rawAliases.split(',')) { + addAliasToMap(map, rawAlias, target); + } +} + +function parseGenericTargetAliasConfig(map: Record, rawConfig: string): void { + for (const rawEntry of rawConfig.split(';')) { + const entry = rawEntry.trim(); + if (!entry) { continue; } - map[alias] = 'droid'; + + const separatorIndex = entry.indexOf('='); + if (separatorIndex <= 0 || separatorIndex === entry.length - 1) { + continue; + } + + const rawTarget = entry.slice(0, separatorIndex).trim().toLowerCase(); + const rawAliases = entry.slice(separatorIndex + 1).trim(); + if (!rawAliases || !isValidTarget(rawTarget)) { + continue; + } + + addAliasListToMap(map, rawTarget, rawAliases); + } +} + +function buildArgv0TargetMap(): Record { + const map: Record = { ...BUILTIN_ARGV0_TARGET_MAP }; + const genericAliasConfig = process.env[GENERIC_TARGET_ALIAS_ENV_VAR]; + if (genericAliasConfig) { + parseGenericTargetAliasConfig(map, genericAliasConfig); + } + + for (const [target, envVar] of Object.entries(LEGACY_TARGET_ALIAS_ENV_VARS) as Array< + [TargetType, string] + >) { + const rawAliases = process.env[envVar]; + if (!rawAliases) { + continue; + } + + addAliasListToMap(map, target, rawAliases); } return map; diff --git a/tests/unit/targets/ccsd-alias-integration.test.ts b/tests/unit/targets/ccsd-alias-integration.test.ts index ebc4fd69..1c5c8f74 100644 --- a/tests/unit/targets/ccsd-alias-integration.test.ts +++ b/tests/unit/targets/ccsd-alias-integration.test.ts @@ -62,11 +62,22 @@ describe('ccsd alias integration', () => { expect(path.basename(argvPath)).toBe('ccsd'); }); + it('should preserve ccs-droid symlink basename in argv[1] under node', () => { + if (process.platform === 'win32') { + return; + } + + const argvPath = probeArgvPath('ccs-droid'); + expect(path.basename(argvPath)).toBe('ccs-droid'); + }); + it('should preserve extension-style alias basenames for wrapper compatibility', () => { const cmdArgvPath = probeArgvPathDirect('ccsd.cmd'); const ps1ArgvPath = probeArgvPathDirect('ccsd.ps1'); + const explicitCmdArgvPath = probeArgvPathDirect('ccs-droid.cmd'); expect(path.basename(cmdArgvPath)).toBe('ccsd.cmd'); expect(path.basename(ps1ArgvPath)).toBe('ccsd.ps1'); + expect(path.basename(explicitCmdArgvPath)).toBe('ccs-droid.cmd'); }); }); diff --git a/tests/unit/targets/target-resolver.test.ts b/tests/unit/targets/target-resolver.test.ts index 9841b9ce..7628ed63 100644 --- a/tests/unit/targets/target-resolver.test.ts +++ b/tests/unit/targets/target-resolver.test.ts @@ -7,6 +7,7 @@ import { resolveTargetType, stripTargetFlag } from '../../../src/targets/target- describe('resolveTargetType', () => { const originalArgv = process.argv; const originalDroidAliases = process.env.CCS_DROID_ALIASES; + const originalTargetAliases = process.env.CCS_TARGET_ALIASES; afterEach(() => { process.argv = originalArgv; @@ -15,6 +16,12 @@ describe('resolveTargetType', () => { } else { process.env.CCS_DROID_ALIASES = originalDroidAliases; } + + if (originalTargetAliases === undefined) { + delete process.env.CCS_TARGET_ALIASES; + } else { + process.env.CCS_TARGET_ALIASES = originalTargetAliases; + } }); it('should return claude as default', () => { @@ -52,6 +59,23 @@ describe('resolveTargetType', () => { expect(resolveTargetType([])).toBe('droid'); }); + it('should detect built-in ccs-droid argv[0] alias', () => { + process.argv = ['node', 'ccs-droid']; + expect(resolveTargetType([])).toBe('droid'); + }); + + it('should detect custom target aliases from CCS_TARGET_ALIASES', () => { + process.env.CCS_TARGET_ALIASES = 'droid=droidx,my-droid'; + process.argv = ['node', 'my-droid']; + expect(resolveTargetType([])).toBe('droid'); + }); + + it('should ignore unsupported targets in CCS_TARGET_ALIASES', () => { + process.env.CCS_TARGET_ALIASES = 'codex=ccsx;droid=ccs-droid-custom'; + process.argv = ['node', 'ccsx']; + expect(resolveTargetType([])).toBe('claude'); + }); + it('should detect custom argv[0] aliases from CCS_DROID_ALIASES', () => { process.env.CCS_DROID_ALIASES = 'droidx,my-droid'; process.argv = ['node', 'my-droid']; @@ -75,6 +99,11 @@ describe('resolveTargetType', () => { expect(resolveTargetType([])).toBe('droid'); }); + it('should strip .cmd extension on built-in explicit alias', () => { + process.argv = ['node', 'ccs-droid.cmd']; + expect(resolveTargetType([])).toBe('droid'); + }); + it('should strip .bat extension on Windows argv[0]', () => { process.argv = ['node', 'ccsd.bat']; expect(resolveTargetType([])).toBe('droid'); @@ -95,6 +124,11 @@ describe('resolveTargetType', () => { expect(resolveTargetType([])).toBe('droid'); }); + it('should handle full path argv[0] for ccs-droid', () => { + process.argv = ['node', '/usr/local/bin/ccs-droid']; + expect(resolveTargetType([])).toBe('droid'); + }); + it('should prioritize --target over argv[0]', () => { process.argv = ['node', 'ccsd']; expect(resolveTargetType(['--target', 'claude'])).toBe('claude'); diff --git a/ui/src/components/cliproxy/provider-editor/provider-info-tab.tsx b/ui/src/components/cliproxy/provider-editor/provider-info-tab.tsx index d2e7f4b8..8cb6835d 100644 --- a/ui/src/components/cliproxy/provider-editor/provider-info-tab.tsx +++ b/ui/src/components/cliproxy/provider-editor/provider-info-tab.tsx @@ -90,11 +90,7 @@ export function ProviderInfoTab({
- {isDroidTarget - ? `ccsd ${profileName} "prompt"` - : `ccs ${profileName} --target droid "prompt"`} + {`ccs-droid ${profileName} "prompt"`} diff --git a/ui/src/components/profiles/profile-create-dialog.tsx b/ui/src/components/profiles/profile-create-dialog.tsx index 09a63560..fe32c183 100644 --- a/ui/src/components/profiles/profile-create-dialog.tsx +++ b/ui/src/components/profiles/profile-create-dialog.tsx @@ -524,11 +524,25 @@ export function ProfileCreateDialog({

- Run with{' '} - - {targetValue === 'droid' ? 'ccsd' : 'ccs'} - {' '} - by default. You can still override each run with{' '} + {targetValue === 'droid' ? ( + <> + Preferred explicit alias:{' '} + ccs-droid. + + ) : ( + <> + Run with ccs by + default. + + )} + {targetValue === 'droid' ? ( + <> + {' '} + Legacy ccsd still + works for Droid. + + ) : null}{' '} + You can still override each run with{' '} --target.

diff --git a/ui/src/lib/i18n.ts b/ui/src/lib/i18n.ts index de2bdd5f..237be3e4 100644 --- a/ui/src/lib/i18n.ts +++ b/ui/src/lib/i18n.ts @@ -1451,10 +1451,8 @@ const resources = { openrouterModelsBadge: '{{modelCountLabel}} 个 OpenRouter 模型', runtimeProviderBadge: '运行时提供商设置', runtimeProviderTitle: '打开 AI Providers', - runtimeProviderDescription: - '先管理共享的提供商密钥和运行时连接器,再创建独立的 API 配置。', - runtimeProviderFeatureConnectors: - 'Gemini、Codex、Claude、Vertex 以及 OpenAI 兼容连接器', + runtimeProviderDescription: '先管理共享的提供商密钥和运行时连接器,再创建独立的 API 配置。', + runtimeProviderFeatureConnectors: 'Gemini、Codex、Claude、Vertex 以及 OpenAI 兼容连接器', runtimeProviderFeatureSecrets: '共享密钥与单个 API 配置分离存放', runtimeProviderFooter: '当多个配置需要共享同一提供商设置时最适合使用。', createOpenRouterProfile: '创建 OpenRouter 配置', @@ -3837,8 +3835,7 @@ const resources = { runtimeProviderTitle: 'AI Providers を開く', runtimeProviderDescription: '個別の API プロファイルを作成する前に、共有プロバイダーキーとランタイムコネクタを管理します。', - runtimeProviderFeatureConnectors: - 'Gemini、Codex、Claude、Vertex、OpenAI 互換コネクタ', + runtimeProviderFeatureConnectors: 'Gemini、Codex、Claude、Vertex、OpenAI 互換コネクタ', runtimeProviderFeatureSecrets: '共有シークレットを個別の API プロファイルから切り離して管理', runtimeProviderFooter: diff --git a/ui/src/lib/support-updates-catalog.ts b/ui/src/lib/support-updates-catalog.ts index aa9cee80..7a7097c1 100644 --- a/ui/src/lib/support-updates-catalog.ts +++ b/ui/src/lib/support-updates-catalog.ts @@ -68,7 +68,7 @@ export const SUPPORT_NOTICES: SupportNotice[] = [ highlights: [ 'Set default target to Droid when creating or editing API Profiles.', 'Set default target to Droid for CLIProxy variants, including Codex and Antigravity flows.', - 'Use ccsd alias or --target droid for one-off target overrides.', + 'Use ccs-droid as the explicit alias, with ccsd kept as the legacy shortcut.', ], actions: [ { @@ -88,11 +88,11 @@ export const SUPPORT_NOTICES: SupportNotice[] = [ path: '/cliproxy', }, { - id: 'copy-ccsd-command', - label: 'Run once with Droid alias', - description: 'Use ccsd to force Droid target with your current profile.', + id: 'copy-ccs-droid-command', + label: 'Run once with explicit Droid alias', + description: 'Use ccs-droid to force the Droid target with your current profile.', type: 'command', - command: 'ccsd glm', + command: 'ccs-droid glm', }, { id: 'copy-target-override', @@ -107,7 +107,7 @@ export const SUPPORT_NOTICES: SupportNotice[] = [ { label: 'CLIProxy', path: '/cliproxy' }, ], commands: [ - 'ccsd glm', + 'ccs-droid glm', 'ccs codex --target droid "your prompt"', 'ccs cliproxy create mycodex --provider codex --target droid', ], @@ -182,8 +182,8 @@ export const CLI_SUPPORT_ENTRIES: CliSupportEntry[] = [ { label: 'API Profiles', path: '/providers' }, { label: 'CLIProxy', path: '/cliproxy' }, ], - commands: ['ccsd glm', 'ccs km --target droid', 'ccs codex --target droid'], - notes: 'Use ccsd alias for automatic Droid target selection.', + commands: ['ccs-droid glm', 'ccs km --target droid', 'ccs codex --target droid'], + notes: 'Use ccs-droid as the explicit runtime alias. Legacy ccsd still works.', }, { id: 'codex-cliproxy',