mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 22:16:41 +00:00
- add the huggingface preset and hf alias to the shared preset catalog - default the preset to Factory Droid because the documented path is generic chat completions - cover the CLI and dialog behavior with preset metadata and UI tests
149 lines
7.1 KiB
TypeScript
149 lines
7.1 KiB
TypeScript
import {
|
|
PROVIDER_PRESETS,
|
|
listCliproxyBridgeProviders,
|
|
getPresetAliases,
|
|
getPresetIds,
|
|
type ProviderPreset,
|
|
} from '../../api/services';
|
|
import { color, dim, fail, header, initUI, subheader } from '../../utils/ui';
|
|
import { sanitizeHelpText } from './shared';
|
|
|
|
type HelpWriter = (line: string) => void;
|
|
|
|
function renderPresetHelpLine(preset: ProviderPreset, idWidth: number): string {
|
|
const presetId = sanitizeHelpText(preset.id) || 'unknown';
|
|
const paddedId = presetId.padEnd(idWidth);
|
|
const presetName = sanitizeHelpText(preset.name) || 'Unknown preset';
|
|
const presetDescription = sanitizeHelpText(preset.description) || 'No description';
|
|
return ` ${color(paddedId, 'command')} ${presetName} - ${presetDescription}`;
|
|
}
|
|
|
|
export async function showApiCommandHelp(writeLine: HelpWriter = console.log): Promise<void> {
|
|
await initUI();
|
|
const presetIds = getPresetIds()
|
|
.map((id) => sanitizeHelpText(id))
|
|
.filter(Boolean);
|
|
const cliproxyProviderIds = listCliproxyBridgeProviders().map((provider) => provider.provider);
|
|
const presetAliases = getPresetAliases();
|
|
const presetIdWidth = Math.max(0, ...presetIds.map((id) => id.length)) + 2;
|
|
|
|
writeLine(header('CCS API Management'));
|
|
writeLine('');
|
|
writeLine(subheader('Usage'));
|
|
writeLine(` ${color('ccs api', 'command')} <command> [options]`);
|
|
writeLine('');
|
|
writeLine(subheader('Commands'));
|
|
writeLine(` ${color('create [name]', 'command')} Create new API profile (interactive)`);
|
|
writeLine(` ${color('list', 'command')} List all API profiles`);
|
|
writeLine(
|
|
` ${color('discover', 'command')} Discover orphan *.settings.json and register`
|
|
);
|
|
writeLine(` ${color('copy <src> <dest>', 'command')} Duplicate API profile settings + config`);
|
|
writeLine(
|
|
` ${color('export <name>', 'command')} Export profile bundle for cross-device transfer`
|
|
);
|
|
writeLine(` ${color('import <file>', 'command')} Import profile bundle and register profile`);
|
|
writeLine(` ${color('remove <name>', 'command')} Remove an API profile`);
|
|
writeLine('');
|
|
writeLine(subheader('Options'));
|
|
writeLine(
|
|
` ${color('--preset <id>', 'command')} Use provider preset (${presetIds.join(', ')})`
|
|
);
|
|
writeLine(
|
|
` ${color('--cliproxy-provider <id>', 'command')} Use routed CLIProxy provider (${cliproxyProviderIds.join(', ')})`
|
|
);
|
|
writeLine(` ${color('--base-url <url>', 'command')} API base URL (create)`);
|
|
writeLine(` ${color('--api-key <key>', 'command')} API key (create)`);
|
|
writeLine(` ${color('--model <model>', 'command')} Default model (create)`);
|
|
writeLine(
|
|
` ${color('--1m / --no-1m', 'command')} Write or clear [1m] on compatible Claude mappings`
|
|
);
|
|
writeLine(
|
|
` ${color('--target <cli>', 'command')} Default target: claude or droid (create)`
|
|
);
|
|
writeLine(` ${color('--register', 'command')} Register discovered orphan settings`);
|
|
writeLine(` ${color('--json', 'command')} JSON output for discover command`);
|
|
writeLine(` ${color('--out <file>', 'command')} Export bundle output path`);
|
|
writeLine(` ${color('--include-secrets', 'command')} Include token in export bundle`);
|
|
writeLine(` ${color('--name <name>', 'command')} Override profile name during import`);
|
|
writeLine(
|
|
` ${color('--force', 'command')} Overwrite existing or bypass validation (create/discover/copy/import)`
|
|
);
|
|
writeLine(` ${color('--yes, -y', 'command')} Skip confirmation prompts`);
|
|
writeLine('');
|
|
writeLine(subheader('Provider Presets'));
|
|
PROVIDER_PRESETS.forEach((preset) => writeLine(renderPresetHelpLine(preset, presetIdWidth)));
|
|
Object.entries(presetAliases).forEach(([alias, canonical]) => {
|
|
const safeAlias = sanitizeHelpText(alias);
|
|
const safeCanonical = sanitizeHelpText(canonical);
|
|
writeLine(` ${dim(`Legacy alias: --preset ${safeAlias} (auto-mapped to ${safeCanonical})`)}`);
|
|
});
|
|
writeLine('');
|
|
writeLine(subheader('Examples'));
|
|
writeLine(` ${dim('# Interactive wizard')}`);
|
|
writeLine(` ${color('ccs api create', 'command')}`);
|
|
writeLine('');
|
|
writeLine(` ${dim('# Quick setup with preset')}`);
|
|
writeLine(` ${color('ccs api create --preset anthropic', 'command')}`);
|
|
writeLine(
|
|
` ${color('ccs api create --preset anthropic --1m', 'command')} ${dim('# explicit Claude [1m] opt-in')}`
|
|
);
|
|
writeLine(` ${color('ccs api create --preset openrouter', 'command')}`);
|
|
writeLine(` ${color('ccs api create --preset alibaba-coding-plan', 'command')}`);
|
|
writeLine(` ${color('ccs api create --preset alibaba', 'command')} ${dim('# alias')}`);
|
|
writeLine(
|
|
` ${color('ccs api create hf-router --preset hf', 'command')} ${dim('# defaults to droid for generic chat completions')}`
|
|
);
|
|
writeLine(` ${color('ccs api create --preset glm', 'command')}`);
|
|
writeLine('');
|
|
writeLine(subheader('Claude Long Context'));
|
|
writeLine(` ${dim('Plain Claude model IDs stay on standard context by default.')}`);
|
|
writeLine(
|
|
` ${dim('Use --1m during create to append [1m] to compatible Claude mappings, or --no-1m to force plain IDs.')}`
|
|
);
|
|
writeLine(
|
|
` ${dim('CCS controls only the saved [1m] suffix. Provider pricing/entitlement stay upstream, and some accounts can still return 429 for long-context requests.')}`
|
|
);
|
|
writeLine('');
|
|
writeLine(` ${dim('# Create routed profile from existing CLIProxy provider config')}`);
|
|
writeLine(` ${color('ccs api create --cliproxy-provider gemini', 'command')}`);
|
|
writeLine(
|
|
` ${color('ccs api create gemini-droid --cliproxy-provider gemini --target droid', 'command')}`
|
|
);
|
|
writeLine(` ${color('ccs api create codex-api --cliproxy-provider codex', 'command')}`);
|
|
writeLine(
|
|
` ${color('ccs codex-api --target codex', 'command')} ${dim('# runtime-only native Codex launch')}`
|
|
);
|
|
writeLine('');
|
|
writeLine(` ${dim('# Create with name')}`);
|
|
writeLine(` ${color('ccs api create myapi', 'command')}`);
|
|
writeLine(` ${color('ccs api create mydroid --preset glm --target droid', 'command')}`);
|
|
writeLine('');
|
|
writeLine(` ${dim('# Remove API profile')}`);
|
|
writeLine(` ${color('ccs api remove myapi', 'command')}`);
|
|
writeLine('');
|
|
writeLine(` ${dim('# Discover and register orphan settings files')}`);
|
|
writeLine(` ${color('ccs api discover', 'command')}`);
|
|
writeLine(` ${color('ccs api discover --register', 'command')}`);
|
|
writeLine('');
|
|
writeLine(` ${dim('# Duplicate an existing API profile')}`);
|
|
writeLine(` ${color('ccs api copy glm glm-backup', 'command')}`);
|
|
writeLine('');
|
|
writeLine(` ${dim('# Export and import across devices')}`);
|
|
writeLine(` ${color('ccs api export glm --out ./glm.ccs-profile.json', 'command')}`);
|
|
writeLine(` ${color('ccs api import ./glm.ccs-profile.json', 'command')}`);
|
|
writeLine('');
|
|
writeLine(` ${dim('# Show all API profiles')}`);
|
|
writeLine(` ${color('ccs api list', 'command')}`);
|
|
writeLine('');
|
|
}
|
|
|
|
export async function showUnknownApiCommand(command: string): Promise<void> {
|
|
await initUI();
|
|
console.log(fail(`Unknown command: ${command}`));
|
|
console.log('');
|
|
console.log('Run for help:');
|
|
console.log(` ${color('ccs api --help', 'command')}`);
|
|
process.exit(1);
|
|
}
|