Files
ccg-workflow/src/cli-setup.ts
T
li 53fcade330 feat: 新增 TypeScript CLI 安装系统,支持 npx 一键安装
- 重构为 TypeScript + unbuild 构建系统
- 新增交互式安装菜单(初始化/更新/卸载)
- 支持 npx ccg-workflow 直接运行
- 已发布至 npm: ccg-workflow@1.0.0
- 新增 Claude 角色提示词(6个专家角色)
- 更新命令模板支持三模型协作(Claude + Codex + Gemini)
- 更新 README 文档
2026-01-05 14:44:01 +08:00

110 lines
4.5 KiB
TypeScript

import type { CAC } from 'cac'
import type { CliOptions } from './types'
import ansis from 'ansis'
import { version } from '../package.json'
import { init } from './commands/init'
import { showMainMenu } from './commands/menu'
import { i18n, initI18n } from './i18n'
import { readCcgConfig } from './utils/config'
function customizeHelp(sections: any[]): any[] {
sections.unshift({
title: '',
body: ansis.cyan.bold(`CCG - Claude + Codex + Gemini v${version}`),
})
sections.push({
title: ansis.yellow(i18n.t('cli:help.commands')),
body: [
` ${ansis.cyan('ccg')} ${i18n.t('cli:help.commandDescriptions.showMenu')}`,
` ${ansis.cyan('ccg init')} | ${ansis.cyan('i')} ${i18n.t('cli:help.commandDescriptions.initConfig')}`,
'',
ansis.gray(` ${i18n.t('cli:help.shortcuts')}`),
` ${ansis.cyan('ccg i')} ${i18n.t('cli:help.shortcutDescriptions.quickInit')}`,
].join('\n'),
})
sections.push({
title: ansis.yellow(i18n.t('cli:help.options')),
body: [
` ${ansis.green('--lang, -l')} <lang> ${i18n.t('cli:help.optionDescriptions.displayLanguage')} (zh-CN, en)`,
` ${ansis.green('--force, -f')} ${i18n.t('cli:help.optionDescriptions.forceOverwrite')}`,
` ${ansis.green('--help, -h')} ${i18n.t('cli:help.optionDescriptions.displayHelp')}`,
` ${ansis.green('--version, -v')} ${i18n.t('cli:help.optionDescriptions.displayVersion')}`,
'',
ansis.gray(` ${i18n.t('cli:help.nonInteractiveMode')}`),
` ${ansis.green('--skip-prompt, -s')} ${i18n.t('cli:help.optionDescriptions.skipAllPrompts')}`,
` ${ansis.green('--frontend, -F')} <models> ${i18n.t('cli:help.optionDescriptions.frontendModels')}`,
` ${ansis.green('--backend, -B')} <models> ${i18n.t('cli:help.optionDescriptions.backendModels')}`,
` ${ansis.green('--mode, -m')} <mode> ${i18n.t('cli:help.optionDescriptions.collaborationMode')}`,
` ${ansis.green('--workflows, -w')} <list> ${i18n.t('cli:help.optionDescriptions.workflows')}`,
` ${ansis.green('--install-dir, -d')} <path> ${i18n.t('cli:help.optionDescriptions.installDir')}`,
].join('\n'),
})
sections.push({
title: ansis.yellow(i18n.t('cli:help.examples')),
body: [
ansis.gray(` # ${i18n.t('cli:help.exampleDescriptions.showInteractiveMenu')}`),
` ${ansis.cyan('npx ccg')}`,
'',
ansis.gray(` # ${i18n.t('cli:help.exampleDescriptions.runFullInitialization')}`),
` ${ansis.cyan('npx ccg init')}`,
` ${ansis.cyan('npx ccg i')}`,
'',
ansis.gray(` # ${i18n.t('cli:help.exampleDescriptions.customModels')}`),
` ${ansis.cyan('npx ccg i --frontend gemini,codex --backend codex,gemini')}`,
'',
ansis.gray(` # ${i18n.t('cli:help.exampleDescriptions.parallelMode')}`),
` ${ansis.cyan('npx ccg i --mode parallel')}`,
'',
].join('\n'),
})
return sections
}
export async function setupCommands(cli: CAC): Promise<void> {
try {
const config = await readCcgConfig()
const defaultLang = config?.general?.language || 'en'
await initI18n(defaultLang)
}
catch {
await initI18n('en')
}
// Default command - show menu
cli
.command('', 'Show interactive menu (default)')
.option('--lang, -l <lang>', 'Display language (zh-CN, en)')
.action(async (options: CliOptions) => {
if (options.lang) {
await initI18n(options.lang)
}
await showMainMenu()
})
// Init command
cli
.command('init', 'Initialize CCG multi-model collaboration system')
.alias('i')
.option('--lang, -l <lang>', 'Display language (zh-CN, en)')
.option('--force, -f', 'Force overwrite existing configuration')
.option('--skip-prompt, -s', 'Skip all interactive prompts (non-interactive mode)')
.option('--frontend, -F <models>', 'Frontend models (comma-separated: gemini,codex,claude)')
.option('--backend, -B <models>', 'Backend models (comma-separated: codex,gemini,claude)')
.option('--mode, -m <mode>', 'Collaboration mode (parallel, smart, sequential)')
.option('--workflows, -w <workflows>', 'Workflows to install (comma-separated or "all")')
.option('--install-dir, -d <path>', 'Installation directory (default: ~/.claude)')
.action(async (options: CliOptions) => {
if (options.lang) {
await initI18n(options.lang)
}
await init(options)
})
cli.help(sections => customizeHelp(sections))
cli.version(version)
}