@ai-config-plaza/acp-cli 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,8 +34,8 @@ yarn global add @ai-config-plaza/acp-cli
34
34
 
35
35
  ```bash
36
36
  # 克隆仓库
37
- git clone https://github.com/AIConfigPlaza/acp-cli.git
38
- cd acp-cli
37
+ git clone https://github.com/AIConfigPlaza/acp.git
38
+ cd acp/cli
39
39
 
40
40
  # 安装依赖
41
41
  pnpm install
@@ -189,7 +189,7 @@ acp locale
189
189
  ### 项目结构
190
190
 
191
191
  ```
192
- acp-cli/
192
+ acp/cli/
193
193
  ├── bin/ # 可执行文件入口
194
194
  │ └── acp.js
195
195
  ├── src/
@@ -263,7 +263,7 @@ ACP CLI 连接到 ACP 平台的后端 API 服务:
263
263
 
264
264
  遇到问题?请提交 Issue:
265
265
 
266
- - GitHub Issues: https://github.com/AIConfigPlaza/acp-cli/issues
266
+ - GitHub Issues: https://github.com/AIConfigPlaza/acp/issues
267
267
 
268
268
  ## 📄 许可证
269
269
 
package/bin/acp.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  /**
4
4
  * ACP CLI 入口文件
package/dist/index.js CHANGED
@@ -674,22 +674,26 @@ var IDE_PATH_MAPPINGS = {
674
674
  vscode: {
675
675
  prompts: ".github/prompts",
676
676
  agents: "AGENTS.md",
677
- mcp: ".vscode/mcp.json"
677
+ mcp: ".vscode/mcp.json",
678
+ skills: ".github/skills"
678
679
  },
679
680
  cursor: {
680
681
  prompts: ".cursor/commands",
681
682
  agents: "AGENTS.md",
682
- mcp: ".cursor/mcp.json"
683
+ mcp: ".cursor/mcp.json",
684
+ skills: ".cursor/skills"
683
685
  },
684
686
  codex: {
685
687
  prompts: "~/.codex/prompts",
686
688
  agents: "AGENTS.md",
687
- mcp: ".codex/config.toml"
689
+ mcp: ".codex/config.toml",
690
+ skills: ".codex/skills"
688
691
  },
689
692
  "claude-code": {
690
693
  prompts: ".claude/commands",
691
694
  agents: "AGENTS.md",
692
- mcp: ".mcp.json"
695
+ mcp: ".mcp.json",
696
+ skills: ".claude/skills"
693
697
  }
694
698
  };
695
699
  function getIdePathMapping(ide) {
@@ -722,6 +726,13 @@ async function applySolution(solution, options) {
722
726
  targetDir
723
727
  );
724
728
  }
729
+ if (solution.skills?.length) {
730
+ await applySkills(
731
+ solution.skills,
732
+ pathMapping.skills,
733
+ targetDir
734
+ );
735
+ }
725
736
  logger.success(`
726
737
  \u2728 \u89E3\u51B3\u65B9\u6848 ${chalk3.cyan(solution.name)} \u5E94\u7528\u6210\u529F\uFF01`);
727
738
  }
@@ -845,6 +856,72 @@ function convertMcpToToml(mcpServers) {
845
856
  }
846
857
  return tomlContent;
847
858
  }
859
+ async function applySkills(skills, skillsDir, targetDir) {
860
+ const fullSkillsDir = path3.join(targetDir, skillsDir);
861
+ logger.step(`\u5199\u5165 ${skills.length} \u4E2A Skill \u914D\u7F6E\u5230: ${chalk3.gray(skillsDir)}`);
862
+ await fs3.ensureDir(fullSkillsDir);
863
+ for (const skill of skills) {
864
+ const skillDirName = sanitizeSkillName(skill.name);
865
+ const skillDirPath = path3.join(fullSkillsDir, skillDirName);
866
+ logger.step(`\u5904\u7406 Skill: ${chalk3.cyan(skill.name)}`);
867
+ const dirExists = await fs3.pathExists(skillDirPath);
868
+ if (dirExists) {
869
+ const { overwrite } = await inquirer2.prompt([
870
+ {
871
+ type: "confirm",
872
+ name: "overwrite",
873
+ message: `Skill \u76EE\u5F55 ${chalk3.cyan(skillDirName)} \u5DF2\u5B58\u5728\uFF0C\u662F\u5426\u8986\u76D6?`,
874
+ default: true
875
+ }
876
+ ]);
877
+ if (!overwrite) {
878
+ logger.warning(`\u8DF3\u8FC7: ${skillDirName}`);
879
+ continue;
880
+ }
881
+ }
882
+ await fs3.ensureDir(skillDirPath);
883
+ const skillMdPath = path3.join(skillDirPath, "SKILL.md");
884
+ await fs3.writeFile(skillMdPath, skill.skillMarkdown, "utf-8");
885
+ logger.success(`\u5DF2\u5199\u5165: ${path3.join(skillsDir, skillDirName, "SKILL.md")}`);
886
+ if (skill.skillResources && skill.skillResources.length > 0) {
887
+ for (const resource of skill.skillResources) {
888
+ const safeRelativePath = sanitizePath(resource.relativePath);
889
+ const resourceFilePath = path3.join(skillDirPath, safeRelativePath);
890
+ const fileExists = await fs3.pathExists(resourceFilePath);
891
+ if (fileExists) {
892
+ const { overwrite } = await inquirer2.prompt([
893
+ {
894
+ type: "confirm",
895
+ name: "overwrite",
896
+ message: `\u6587\u4EF6 ${chalk3.cyan(path3.join(skillDirName, safeRelativePath))} \u5DF2\u5B58\u5728\uFF0C\u662F\u5426\u8986\u76D6?`,
897
+ default: true
898
+ }
899
+ ]);
900
+ if (!overwrite) {
901
+ logger.warning(`\u8DF3\u8FC7: ${path3.join(skillDirName, safeRelativePath)}`);
902
+ continue;
903
+ }
904
+ }
905
+ await fs3.ensureDir(path3.dirname(resourceFilePath));
906
+ await fs3.writeFile(resourceFilePath, resource.fileContent, "utf-8");
907
+ logger.success(`\u5DF2\u5199\u5165: ${path3.join(skillsDir, skillDirName, safeRelativePath)}`);
908
+ }
909
+ }
910
+ }
911
+ }
912
+ function sanitizeSkillName(name) {
913
+ return name.replace(/[<>:"/\\|?*]/g, "-").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
914
+ }
915
+ function sanitizePath(relativePath) {
916
+ let safePath = relativePath.replace(/\.\./g, "").replace(/^[/\\]+/, "").replace(/[/\\]+/g, path3.sep);
917
+ if (path3.isAbsolute(safePath)) {
918
+ safePath = path3.relative("/", safePath);
919
+ }
920
+ if (safePath.match(/^[A-Za-z]:/)) {
921
+ safePath = safePath.substring(2);
922
+ }
923
+ return safePath;
924
+ }
848
925
  function sanitizeFileName(name) {
849
926
  return name.replace(/[<>:"/\\|?*]/g, "-").replace(/\s+/g, "-").replace(/-+/g, "-").toLowerCase();
850
927
  }
@@ -939,7 +1016,7 @@ async function fetchAndSelectSolution() {
939
1016
  pageSize: PAGE_SIZE
940
1017
  });
941
1018
  const choices = paginatedResult.items.map((solution) => ({
942
- name: `${chalk4.cyan(solution.name)} - ${chalk4.gray(solution.description)}`,
1019
+ name: `${chalk4.cyan(solution.name)} ${chalk4.yellow(`@${solution.author.username}`)} - ${chalk4.gray(solution.description)}`,
943
1020
  value: solution.id,
944
1021
  short: solution.name
945
1022
  }));
@@ -1058,7 +1135,7 @@ var localeCommand = new Command3("locale").description("\u5207\u6362 CLI \u8BED\
1058
1135
  });
1059
1136
 
1060
1137
  // src/index.ts
1061
- var version = true ? "1.0.4" : "0.0.0-dev";
1138
+ var version = true ? "1.0.6" : "0.0.0-dev";
1062
1139
  async function main() {
1063
1140
  const program = new Command4();
1064
1141
  program.name("acp").description(
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/login.ts","../src/config/token.ts","../src/utils/logger.ts","../src/config/locale.ts","../src/i18n/zh-CN.ts","../src/i18n/en-US.ts","../src/i18n/index.ts","../src/commands/apply.ts","../src/api/client.ts","../src/utils/pagination.ts","../src/apply/writer.ts","../src/utils/ide-mapper.ts","../src/commands/locale.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Command } from 'commander'\r\nimport chalk from 'chalk'\r\nimport { loginCommand } from './commands/login.js'\r\nimport { applyCommand } from './commands/apply.js'\r\nimport { localeCommand } from './commands/locale.js'\r\nimport { handleError } from './utils/logger.js'\r\nimport { t } from './i18n/index.js'\r\n\r\n/**\r\n * ACP CLI 主入口\r\n */\r\n\r\n// 版本号在构建时注入\r\n// @ts-ignore - 构建时通过 tsup define 注入\r\nconst version = typeof __VERSION__ !== 'undefined' ? __VERSION__ : '0.0.0-dev'\r\n\r\nasync function main() {\r\n const program = new Command()\r\n\r\n program\r\n .name('acp')\r\n .description(\r\n chalk.gray(await t('cli.description'))\r\n )\r\n .version(version, '-v, --version', await t('cli.version'))\r\n .helpOption('-h, --help', await t('cli.help'))\r\n\r\n // 注册命令\r\n program.addCommand(loginCommand)\r\n program.addCommand(applyCommand)\r\n program.addCommand(localeCommand)\r\n\r\n // 自定义帮助显示\r\n program.on('--help', async () => {\r\n console.log(chalk.bold('\\n' + await t('cli.exampleTitle') + '\\n'))\r\n console.log(chalk.gray(' $ acp login'))\r\n console.log(chalk.gray(' $ acp apply'))\r\n console.log(chalk.gray(' $ acp apply --ide vscode --dir ./my-project'))\r\n console.log(chalk.gray(' $ acp locale'))\r\n console.log()\r\n })\r\n\r\n // 解析命令\r\n try {\r\n await program.parseAsync(process.argv)\r\n } catch (error) {\r\n await handleError(error)\r\n process.exit(1)\r\n }\r\n}\r\n\r\nmain()\r\n","import { Command } from 'commander'\r\nimport inquirer from 'inquirer'\r\nimport chalk from 'chalk'\r\nimport { saveToken, getToken, initDefaultConfig } from '../config/token.js'\r\nimport { logger } from '../utils/logger.js'\r\nimport { t } from '../i18n/index.js'\r\n\r\n/**\r\n * acp login 命令\r\n * 提示用户输入 CLI Token 并保存\r\n */\r\n\r\nexport const loginCommand = new Command('login')\r\n .description('登录 ACP CLI,保存访问令牌 / Login to ACP CLI and save access token')\r\n .action(async () => {\r\n try {\r\n logger.title(await t('login.title'))\r\n\r\n // 初始化默认配置(首次使用时)\r\n await initDefaultConfig()\r\n\r\n // 检查是否已有 token\r\n const existingToken = await getToken()\r\n if (existingToken) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: await t('login.alreadyLoggedIn'),\r\n default: false\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.info(await t('login.cancelled'))\r\n return\r\n }\r\n }\r\n\r\n // 提示输入 token\r\n const { token } = await inquirer.prompt([\r\n {\r\n type: 'password',\r\n name: 'token',\r\n message: await t('login.inputToken'),\r\n validate: async (input: string) => {\r\n if (!input.trim()) {\r\n return await t('login.tokenEmpty')\r\n }\r\n if (input.trim().length < 10) {\r\n return await t('login.tokenInvalid')\r\n }\r\n return true\r\n },\r\n mask: '*'\r\n }\r\n ])\r\n\r\n // 保存 token\r\n await saveToken(token)\r\n\r\n logger.success(await t('login.success'))\r\n console.log(chalk.gray('\\n' + await t('login.hint') + '\\n'))\r\n } catch (error) {\r\n if (error instanceof Error) {\r\n logger.error(`${await t('login.failed')}: ${error.message}`)\r\n }\r\n process.exit(1)\r\n }\r\n })\r\n","import fs from 'fs-extra'\r\nimport path from 'path'\r\nimport os from 'os'\r\n\r\n/**\r\n * Token 和 BASE_URL 配置管理\r\n * 优先级: 环境变量 > ~/.acp/ 配置文件\r\n */\r\n\r\nconst TOKEN_ENV_KEY = 'ACP_CLI_TOKEN'\r\nconst BASE_URL_ENV_KEY = 'ACP_CLI_BASE_URL'\r\nconst DEFAULT_BASE_URL = 'https://api.ai-config-plaza.com'\r\n\r\nconst CONFIG_DIR = path.join(os.homedir(), '.acp')\r\nconst TOKEN_FILE = path.join(CONFIG_DIR, 'token')\r\nconst BASE_URL_FILE = path.join(CONFIG_DIR, 'base-url')\r\n\r\n/**\r\n * 读取 CLI Token\r\n */\r\nexport async function getToken(): Promise<string | null> {\r\n // 1. 优先读取环境变量\r\n const envToken = process.env[TOKEN_ENV_KEY]\r\n if (envToken?.trim()) {\r\n return envToken.trim()\r\n }\r\n\r\n // 2. 读取本地配置文件\r\n try {\r\n if (await fs.pathExists(TOKEN_FILE)) {\r\n const token = await fs.readFile(TOKEN_FILE, 'utf-8')\r\n return token.trim() || null\r\n }\r\n } catch (error) {\r\n // 读取失败返回 null\r\n }\r\n\r\n return null\r\n}\r\n\r\n/**\r\n * 保存 CLI Token 到本地配置文件\r\n */\r\nexport async function saveToken(token: string): Promise<void> {\r\n if (!token?.trim()) {\r\n throw new Error('Token 不能为空')\r\n }\r\n\r\n // 确保配置目录存在\r\n await fs.ensureDir(CONFIG_DIR)\r\n\r\n // 写入 token 文件\r\n await fs.writeFile(TOKEN_FILE, token.trim(), 'utf-8')\r\n}\r\n\r\n/**\r\n * 删除本地 Token\r\n */\r\nexport async function removeToken(): Promise<void> {\r\n if (await fs.pathExists(TOKEN_FILE)) {\r\n await fs.remove(TOKEN_FILE)\r\n }\r\n}\r\n\r\n/**\r\n * 检查是否已登录\r\n */\r\nexport async function isLoggedIn(): Promise<boolean> {\r\n const token = await getToken()\r\n return token !== null && token.length > 0\r\n}\r\n\r\n/**\r\n * 读取 BASE_URL\r\n */\r\nexport async function getBaseUrl(): Promise<string> {\r\n // 1. 优先读取环境变量\r\n const envBaseUrl = process.env[BASE_URL_ENV_KEY]\r\n if (envBaseUrl?.trim()) {\r\n return envBaseUrl.trim()\r\n }\r\n\r\n // 2. 读取本地配置文件\r\n try {\r\n if (await fs.pathExists(BASE_URL_FILE)) {\r\n const baseUrl = await fs.readFile(BASE_URL_FILE, 'utf-8')\r\n if (baseUrl.trim()) {\r\n return baseUrl.trim()\r\n }\r\n }\r\n } catch (error) {\r\n // 读取失败,使用默认值\r\n }\r\n\r\n // 3. 返回默认值\r\n return DEFAULT_BASE_URL\r\n}\r\n\r\n/**\r\n * 保存 BASE_URL 到本地配置文件\r\n */\r\nexport async function saveBaseUrl(baseUrl: string): Promise<void> {\r\n if (!baseUrl?.trim()) {\r\n throw new Error('BASE_URL 不能为空')\r\n }\r\n\r\n // 验证 URL 格式\r\n try {\r\n new URL(baseUrl.trim())\r\n } catch {\r\n throw new Error('BASE_URL 格式不正确,请输入有效的 URL')\r\n }\r\n\r\n // 确保配置目录存在\r\n await fs.ensureDir(CONFIG_DIR)\r\n\r\n // 写入 base-url 文件\r\n await fs.writeFile(BASE_URL_FILE, baseUrl.trim(), 'utf-8')\r\n}\r\n\r\n/**\r\n * 删除本地 BASE_URL\r\n */\r\nexport async function removeBaseUrl(): Promise<void> {\r\n if (await fs.pathExists(BASE_URL_FILE)) {\r\n await fs.remove(BASE_URL_FILE)\r\n }\r\n}\r\n\r\n/**\r\n * 初始化默认配置(首次使用时)\r\n */\r\nexport async function initDefaultConfig(): Promise<void> {\r\n await fs.ensureDir(CONFIG_DIR)\r\n\r\n // 如果 BASE_URL 不存在,初始化默认值\r\n if (!(await fs.pathExists(BASE_URL_FILE))) {\r\n await saveBaseUrl(DEFAULT_BASE_URL)\r\n }\r\n}\r\n","import chalk from 'chalk'\r\nimport { t } from '../i18n/index.js'\r\n\r\n/**\r\n * 日志工具 - 提供统一的终端输出格式\r\n */\r\n\r\n// 使用 Unicode 符号代替 figures\r\nconst symbols = {\r\n info: 'ℹ',\r\n tick: '✓',\r\n warning: '⚠',\r\n cross: '✖',\r\n arrowRight: '→'\r\n}\r\n\r\nexport const logger = {\r\n /**\r\n * 普通信息\r\n */\r\n info: (message: string) => {\r\n console.log(chalk.blue(symbols.info) + ' ' + message)\r\n },\r\n\r\n /**\r\n * 成功信息\r\n */\r\n success: (message: string) => {\r\n console.log(chalk.green(symbols.tick) + ' ' + chalk.green(message))\r\n },\r\n\r\n /**\r\n * 警告信息\r\n */\r\n warning: (message: string) => {\r\n console.log(chalk.yellow(symbols.warning) + ' ' + chalk.yellow(message))\r\n },\r\n\r\n /**\r\n * 错误信息\r\n */\r\n error: (message: string) => {\r\n console.error(chalk.red(symbols.cross) + ' ' + chalk.red(message))\r\n },\r\n\r\n /**\r\n * 步骤信息\r\n */\r\n step: (message: string) => {\r\n console.log(chalk.cyan(symbols.arrowRight) + ' ' + chalk.gray(message))\r\n },\r\n\r\n /**\r\n * 标题\r\n */\r\n title: (message: string) => {\r\n console.log('\\n' + chalk.bold.underline(message) + '\\n')\r\n },\r\n\r\n /**\r\n * 普通文本(无图标)\r\n */\r\n log: (message: string) => {\r\n console.log(message)\r\n }\r\n}\r\n\r\n/**\r\n * 自定义 CLI 错误类\r\n */\r\nexport class CLIError extends Error {\r\n constructor(\r\n message: string,\r\n public code?: string,\r\n public suggestions?: string[]\r\n ) {\r\n super(message)\r\n this.name = 'CLIError'\r\n }\r\n}\r\n\r\n/**\r\n * 错误处理函数\r\n */\r\nexport async function handleError(error: unknown): Promise<void> {\r\n console.error()\r\n\r\n if (error instanceof CLIError) {\r\n logger.error(error.message)\r\n\r\n if (error.code) {\r\n const errorCodeText = await t('error.errorCode')\r\n console.log(chalk.gray(`${errorCodeText} ${error.code}`))\r\n }\r\n\r\n if (error.suggestions?.length) {\r\n const suggestionsText = await t('error.suggestions')\r\n console.log(chalk.yellow.bold(`\\n${suggestionsText}\\n`))\r\n error.suggestions.forEach((suggestion, index) => {\r\n console.log(chalk.gray(` ${index + 1}. ${suggestion}`))\r\n })\r\n }\r\n } else if (error instanceof Error) {\r\n logger.error(error.message)\r\n\r\n if (process.env.DEBUG) {\r\n console.log(chalk.gray('\\n' + error.stack))\r\n }\r\n } else {\r\n logger.error(await t('error.unknownError'))\r\n }\r\n\r\n const needHelpText = await t('error.needHelp')\r\n console.log(\r\n chalk.gray(`\\n${needHelpText} `) +\r\n chalk.blue.underline('https://github.com/AIConfigPlaza/acp-cli')\r\n )\r\n console.log()\r\n}\r\n","import fs from 'fs-extra'\r\nimport path from 'path'\r\nimport os from 'os'\r\n\r\n/**\r\n * 语言配置管理\r\n * 支持的语言: zh-CN (中文), en-US (英文)\r\n */\r\n\r\nexport type Locale = 'zh-CN' | 'en-US'\r\n\r\nconst LOCALE_ENV_KEY = 'ACP_CLI_LOCALE'\r\nconst DEFAULT_LOCALE: Locale = 'zh-CN'\r\n\r\nconst CONFIG_DIR = path.join(os.homedir(), '.acp')\r\nconst LOCALE_FILE = path.join(CONFIG_DIR, 'locale')\r\n\r\n/**\r\n * 读取当前语言配置\r\n */\r\nexport async function getLocale(): Promise<Locale> {\r\n // 1. 优先读取环境变量\r\n const envLocale = process.env[LOCALE_ENV_KEY]\r\n if (envLocale && isValidLocale(envLocale)) {\r\n return envLocale as Locale\r\n }\r\n\r\n // 2. 读取本地配置文件\r\n try {\r\n if (await fs.pathExists(LOCALE_FILE)) {\r\n const locale = (await fs.readFile(LOCALE_FILE, 'utf-8')).trim()\r\n if (isValidLocale(locale)) {\r\n return locale as Locale\r\n }\r\n }\r\n } catch (error) {\r\n // 读取失败使用默认值\r\n }\r\n\r\n // 3. 返回默认语言\r\n return DEFAULT_LOCALE\r\n}\r\n\r\n/**\r\n * 保存语言配置到本地文件\r\n */\r\nexport async function saveLocale(locale: Locale): Promise<void> {\r\n if (!isValidLocale(locale)) {\r\n throw new Error(`不支持的语言: ${locale}`)\r\n }\r\n\r\n // 确保配置目录存在\r\n await fs.ensureDir(CONFIG_DIR)\r\n\r\n // 保存语言配置\r\n await fs.writeFile(LOCALE_FILE, locale, 'utf-8')\r\n}\r\n\r\n/**\r\n * 验证语言代码是否有效\r\n */\r\nfunction isValidLocale(locale: string): boolean {\r\n return locale === 'zh-CN' || locale === 'en-US'\r\n}\r\n\r\n/**\r\n * 获取所有支持的语言列表\r\n */\r\nexport function getSupportedLocales(): Locale[] {\r\n return ['zh-CN', 'en-US']\r\n}\r\n\r\n/**\r\n * 获取语言显示名称\r\n */\r\nexport function getLocaleName(locale: Locale): string {\r\n const names: Record<Locale, string> = {\r\n 'zh-CN': '简体中文',\r\n 'en-US': 'English'\r\n }\r\n return names[locale]\r\n}\r\n","/**\r\n * 中文语言包\r\n */\r\n\r\nexport const zhCN = {\r\n // 通用\r\n common: {\r\n confirm: '确认',\r\n cancel: '取消',\r\n yes: '是',\r\n no: '否',\r\n success: '成功',\r\n failed: '失败',\r\n error: '错误',\r\n warning: '警告',\r\n info: '提示'\r\n },\r\n\r\n // CLI 主程序\r\n cli: {\r\n name: 'acp',\r\n description: 'AI-Config-Plaza CLI - 统一 AI 编程工具配置管理',\r\n version: '显示版本号',\r\n help: '显示帮助信息',\r\n exampleTitle: '示例:'\r\n },\r\n\r\n // login 命令\r\n login: {\r\n command: 'login',\r\n description: '登录 ACP CLI,保存访问令牌',\r\n title: '🔐 ACP CLI 登录',\r\n alreadyLoggedIn: '检测到已登录,是否重新登录?',\r\n cancelled: '已取消登录',\r\n inputToken: '请输入 CLI Token:',\r\n tokenEmpty: 'Token 不能为空',\r\n tokenInvalid: 'Token 格式不正确(至少 10 个字符)',\r\n success: '登录成功!Token 已保存到 ~/.acp/token',\r\n hint: '提示: 现在可以使用 acp apply 命令拉取配置',\r\n failed: '登录失败'\r\n },\r\n\r\n // apply 命令\r\n apply: {\r\n command: 'apply',\r\n description: '拉取并应用配置到本地项目',\r\n title: '🚀 ACP 配置应用',\r\n optionType: '资源类型 (solution|agent|prompt|mcp)',\r\n optionIde: 'AI IDE 类型 (vscode|cursor|codex|claude-code)',\r\n optionDir: '目标目录',\r\n notLoggedIn: '未登录,请先执行 acp login',\r\n loginFirst: '运行 acp login 命令登录',\r\n selectResourceType: '请选择资源类型:',\r\n resourceTypes: {\r\n solution: '解决方案 (Solution)',\r\n agent: 'Agent 配置 (暂不支持)',\r\n prompt: 'Prompt (暂不支持)',\r\n mcp: 'MCP 配置 (暂不支持)'\r\n },\r\n notSupported: '暂不支持独立应用 agent/prompt/mcp,请使用 solution 类型',\r\n noSelection: '未选择任何配置',\r\n selectIde: '请选择 AI IDE 类型:',\r\n applied: '配置已应用到:',\r\n searchPlaceholder: '搜索解决方案(输入名称或描述)',\r\n noResults: '没有找到解决方案',\r\n loadingMore: '加载更多...',\r\n noMore: '没有更多了',\r\n selected: '已选择',\r\n selectSolution: '请选择一个解决方案:',\r\n fetching: '正在获取解决方案列表...',\r\n fetchSuccess: '获取到 {count} 个解决方案',\r\n noSolutions: '暂无可用的解决方案',\r\n searchPrompt: '搜索解决方案 (按名称搜索,留空显示全部):',\r\n noMatch: '未找到匹配的解决方案',\r\n selectSolutionPage: '选择解决方案 (第 {current}/{total} 页):',\r\n nextPage: '>>> 下一页',\r\n prevPage: '<<< 上一页',\r\n cancel: '取消',\r\n fetchingDetail: '正在获取解决方案详情...',\r\n fetchDetailFailed: '获取解决方案失败',\r\n ideTypes: {\r\n vscode: 'VS Code',\r\n cursor: 'Cursor',\r\n codex: 'Codex',\r\n claudeCode: 'Claude Code'\r\n }\r\n },\r\n\r\n // locale 命令\r\n locale: {\r\n command: 'locale',\r\n description: '切换 CLI 语言',\r\n title: '🌐 语言设置',\r\n current: '当前语言',\r\n selectLanguage: '请选择语言:',\r\n success: '语言已切换为',\r\n failed: '语言切换失败',\r\n restartHint: '提示: 已生效,新命令将使用所选语言'\r\n },\r\n\r\n // 错误处理\r\n error: {\r\n errorCode: '错误代码:',\r\n suggestions: '💡 建议:',\r\n needHelp: '需要帮助? 访问:',\r\n unknownError: '未知错误'\r\n }\r\n}\r\n","/**\r\n * English Language Pack\r\n */\r\n\r\nexport const enUS = {\r\n // Common\r\n common: {\r\n confirm: 'Confirm',\r\n cancel: 'Cancel',\r\n yes: 'Yes',\r\n no: 'No',\r\n success: 'Success',\r\n failed: 'Failed',\r\n error: 'Error',\r\n warning: 'Warning',\r\n info: 'Info'\r\n },\r\n\r\n // CLI Main\r\n cli: {\r\n name: 'acp',\r\n description: 'AI-Config-Plaza CLI - Unified AI Programming Tool Configuration Management',\r\n version: 'Show version number',\r\n help: 'Show help information',\r\n exampleTitle: 'Examples:'\r\n },\r\n\r\n // login command\r\n login: {\r\n command: 'login',\r\n description: 'Login to ACP CLI and save access token',\r\n title: '🔐 ACP CLI Login',\r\n alreadyLoggedIn: 'Already logged in. Do you want to login again?',\r\n cancelled: 'Login cancelled',\r\n inputToken: 'Please enter CLI Token:',\r\n tokenEmpty: 'Token cannot be empty',\r\n tokenInvalid: 'Invalid token format (at least 10 characters)',\r\n success: 'Login successful! Token saved to ~/.acp/token',\r\n hint: 'Tip: You can now use acp apply command to fetch configurations',\r\n failed: 'Login failed'\r\n },\r\n\r\n // apply command\r\n apply: {\r\n command: 'apply',\r\n description: 'Fetch and apply configurations to local project',\r\n title: '🚀 ACP Configuration Apply',\r\n optionType: 'Resource type (solution|agent|prompt|mcp)',\r\n optionIde: 'AI IDE type (vscode|cursor|codex|claude-code)',\r\n optionDir: 'Target directory',\r\n notLoggedIn: 'Not logged in. Please run acp login first',\r\n loginFirst: 'Run acp login command to login',\r\n selectResourceType: 'Please select resource type:',\r\n resourceTypes: {\r\n solution: 'Solution',\r\n agent: 'Agent Configuration (Not supported yet)',\r\n prompt: 'Prompt (Not supported yet)',\r\n mcp: 'MCP Configuration (Not supported yet)'\r\n },\r\n notSupported: 'Standalone application of agent/prompt/mcp is not supported yet. Please use solution type',\r\n noSelection: 'No configuration selected',\r\n selectIde: 'Please select AI IDE type:',\r\n applied: 'Configuration applied to:',\r\n searchPlaceholder: 'Search solutions (enter name or description)',\r\n noResults: 'No solutions found',\r\n loadingMore: 'Loading more...',\r\n noMore: 'No more items',\r\n selected: 'Selected',\r\n selectSolution: 'Please select a solution:',\r\n fetching: 'Fetching solution list...',\r\n fetchSuccess: 'Fetched {count} solutions',\r\n noSolutions: 'No solutions available',\r\n searchPrompt: 'Search solutions (search by name, leave empty to show all):',\r\n noMatch: 'No matching solutions found',\r\n selectSolutionPage: 'Select solution (Page {current}/{total}):',\r\n nextPage: '>>> Next Page',\r\n prevPage: '<<< Previous Page',\r\n cancel: 'Cancel',\r\n fetchingDetail: 'Fetching solution details...',\r\n fetchDetailFailed: 'Failed to fetch solutions',\r\n ideTypes: {\r\n vscode: 'VS Code',\r\n cursor: 'Cursor',\r\n codex: 'Codex',\r\n claudeCode: 'Claude Code'\r\n }\r\n },\r\n\r\n // locale command\r\n locale: {\r\n command: 'locale',\r\n description: 'Switch CLI language',\r\n title: '🌐 Language Settings',\r\n current: 'Current Language',\r\n selectLanguage: 'Please select language:',\r\n success: 'Language switched to',\r\n failed: 'Failed to switch language',\r\n restartHint: 'Tip: Changes take effect immediately for new commands'\r\n },\r\n\r\n // Error handling\r\n error: {\r\n errorCode: 'Error Code:',\r\n suggestions: '💡 Suggestions:',\r\n needHelp: 'Need help? Visit:',\r\n unknownError: 'Unknown error'\r\n }\r\n}\r\n","import { getLocale, type Locale } from '../config/locale.js'\r\nimport { zhCN } from './zh-CN.js'\r\nimport { enUS } from './en-US.js'\r\n\r\n/**\r\n * 国际化工具 - 提供多语言支持\r\n */\r\n\r\n// 语言包映射\r\nconst messages: Record<Locale, typeof zhCN> = {\r\n 'zh-CN': zhCN,\r\n 'en-US': enUS\r\n}\r\n\r\n// 当前语言缓存\r\nlet currentLocale: Locale | null = null\r\nlet currentMessages: typeof zhCN | null = null\r\n\r\n/**\r\n * 初始化 i18n\r\n */\r\nasync function initI18n(): Promise<void> {\r\n if (!currentLocale) {\r\n currentLocale = await getLocale()\r\n currentMessages = messages[currentLocale]\r\n }\r\n}\r\n\r\n/**\r\n * 翻译函数 - 根据键路径获取翻译文本\r\n * @param key - 翻译键,支持点分隔的路径,如 'login.title'\r\n * @param params - 替换参数对象\r\n * @returns 翻译后的文本\r\n */\r\nexport async function t(key: string, params?: Record<string, string | number>): Promise<string> {\r\n await initI18n()\r\n\r\n // 通过点分隔的路径获取嵌套值\r\n const keys = key.split('.')\r\n let value: any = currentMessages\r\n\r\n for (const k of keys) {\r\n if (value && typeof value === 'object' && k in value) {\r\n value = value[k]\r\n } else {\r\n // 如果找不到翻译,返回 key 本身\r\n return key\r\n }\r\n }\r\n\r\n // 如果不是字符串,返回 key\r\n if (typeof value !== 'string') {\r\n return key\r\n }\r\n\r\n // 替换参数\r\n if (params) {\r\n return value.replace(/\\{(\\w+)\\}/g, (match, paramKey) => {\r\n return paramKey in params ? String(params[paramKey]) : match\r\n })\r\n }\r\n\r\n return value\r\n}\r\n\r\n/**\r\n * 同步翻译函数(需要先初始化)\r\n * @param key - 翻译键\r\n * @param params - 替换参数对象\r\n * @returns 翻译后的文本\r\n */\r\nexport function tSync(key: string, params?: Record<string, string | number>): string {\r\n if (!currentMessages) {\r\n // 如果未初始化,返回 key\r\n return key\r\n }\r\n\r\n const keys = key.split('.')\r\n let value: any = currentMessages\r\n\r\n for (const k of keys) {\r\n if (value && typeof value === 'object' && k in value) {\r\n value = value[k]\r\n } else {\r\n return key\r\n }\r\n }\r\n\r\n if (typeof value !== 'string') {\r\n return key\r\n }\r\n\r\n if (params) {\r\n return value.replace(/\\{(\\w+)\\}/g, (match, paramKey) => {\r\n return paramKey in params ? String(params[paramKey]) : match\r\n })\r\n }\r\n\r\n return value\r\n}\r\n\r\n/**\r\n * 获取当前语言\r\n */\r\nexport async function getCurrentLocale(): Promise<Locale> {\r\n await initI18n()\r\n return currentLocale!\r\n}\r\n\r\n/**\r\n * 重新加载语言配置(切换语言后调用)\r\n */\r\nexport async function reloadLocale(): Promise<void> {\r\n currentLocale = null\r\n currentMessages = null\r\n await initI18n()\r\n}\r\n\r\n/**\r\n * 获取完整的语言包(用于类型提示)\r\n */\r\nexport function getMessages() {\r\n return currentMessages || zhCN\r\n}\r\n","import { Command } from 'commander'\r\nimport inquirer from 'inquirer'\r\nimport chalk from 'chalk'\r\nimport ora from 'ora'\r\nimport { apiClient } from '../api/client.js'\r\nimport { logger, CLIError } from '../utils/logger.js'\r\nimport { isLoggedIn } from '../config/token.js'\r\nimport { type AiIdeType } from '../utils/ide-mapper.js'\r\nimport { searchByName, paginate } from '../utils/pagination.js'\r\nimport { applySolution } from '../apply/writer.js'\r\nimport type { Solution } from '../types/index.js'\r\nimport { t } from '../i18n/index.js'\r\n\r\n/**\r\n * acp apply 命令\r\n * 拉取并应用配置到本地项目\r\n */\r\n\r\ntype ResourceType = 'solution' | 'agent' | 'prompt' | 'mcp'\r\n\r\nexport const applyCommand = new Command('apply')\r\n .description('拉取并应用配置到本地项目 / Fetch and apply configurations to local project')\r\n .option('-t, --type <type>', '资源类型 (solution|agent|prompt|mcp) / Resource type', 'solution')\r\n .option('-i, --ide <ide>', 'AI IDE 类型 / AI IDE type (vscode|cursor|codex|claude-code)')\r\n .option('-d, --dir <path>', '目标目录 / Target directory', process.cwd())\r\n .action(async (options) => {\r\n try {\r\n // 检查登录状态\r\n if (!(await isLoggedIn())) {\r\n throw new CLIError(\r\n await t('apply.notLoggedIn'),\r\n 'NOT_LOGGED_IN',\r\n [await t('apply.loginFirst')]\r\n )\r\n }\r\n\r\n logger.title(await t('apply.title'))\r\n\r\n // 1. 选择资源类型\r\n const resourceType = await selectResourceType(options.type)\r\n\r\n // 2. 根据类型拉取并选择资源\r\n let selectedSolution: Solution | null = null\r\n\r\n if (resourceType === 'solution') {\r\n selectedSolution = await fetchAndSelectSolution()\r\n } else {\r\n throw new CLIError(await t('apply.notSupported'))\r\n }\r\n\r\n if (!selectedSolution) {\r\n logger.info(await t('apply.noSelection'))\r\n return\r\n }\r\n\r\n // 3. 选择 IDE 类型\r\n const ide = options.ide || (await selectIde())\r\n\r\n // 4. 应用配置\r\n await applySolution(selectedSolution, {\r\n ide: ide as AiIdeType,\r\n targetDir: options.dir\r\n })\r\n\r\n const appliedMsg = await t('apply.applied')\r\n console.log(chalk.gray(`\\n${appliedMsg} ${chalk.cyan(options.dir)}\\n`))\r\n } catch (error) {\r\n if (error instanceof Error) {\r\n logger.error(error.message)\r\n }\r\n process.exit(1)\r\n }\r\n })\r\n\r\n/**\r\n * 选择资源类型\r\n */\r\nasync function selectResourceType(defaultType?: string): Promise<ResourceType> {\r\n if (defaultType && ['solution', 'agent', 'prompt', 'mcp'].includes(defaultType)) {\r\n return defaultType as ResourceType\r\n }\r\n\r\n const { type } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'type',\r\n message: await t('apply.selectResourceType'),\r\n choices: [\r\n { name: chalk.cyan(await t('apply.resourceTypes.solution')), value: 'solution' },\r\n { name: chalk.gray(await t('apply.resourceTypes.agent')), value: 'agent', disabled: true },\r\n { name: chalk.gray(await t('apply.resourceTypes.prompt')), value: 'prompt', disabled: true },\r\n { name: chalk.gray(await t('apply.resourceTypes.mcp')), value: 'mcp', disabled: true }\r\n ],\r\n default: 'solution'\r\n }\r\n ])\r\n\r\n return type\r\n}\r\n\r\n/**\r\n * 拉取并选择解决方案\r\n */\r\nasync function fetchAndSelectSolution(): Promise<Solution | null> {\r\n const spinner = ora(await t('apply.fetching')).start()\r\n\r\n try {\r\n // 1. 拉取解决方案列表\r\n const response = await apiClient.getSolutions()\r\n spinner.stop()\r\n\r\n if (!response.data || response.data.length === 0) {\r\n logger.warning(await t('apply.noSolutions'))\r\n return null\r\n }\r\n\r\n logger.success(await t('apply.fetchSuccess', { count: response.data.length }))\r\n\r\n // 2. 搜索过滤\r\n const { searchQuery } = await inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'searchQuery',\r\n message: await t('apply.searchPrompt'),\r\n default: ''\r\n }\r\n ])\r\n\r\n let filteredSolutions = searchByName(response.data, searchQuery)\r\n\r\n if (filteredSolutions.length === 0) {\r\n logger.warning(await t('apply.noMatch'))\r\n return null\r\n }\r\n\r\n // 3. 分页显示\r\n const PAGE_SIZE = 20\r\n let currentPage = 1\r\n let selectedSolution: Solution | null = null\r\n\r\n while (!selectedSolution) {\r\n const paginatedResult = paginate(filteredSolutions, {\r\n page: currentPage,\r\n pageSize: PAGE_SIZE\r\n })\r\n\r\n // 构建选择列表\r\n const choices = paginatedResult.items.map((solution) => ({\r\n name: `${chalk.cyan(solution.name)} - ${chalk.gray(solution.description)}`,\r\n value: solution.id,\r\n short: solution.name\r\n }))\r\n\r\n // 添加分页控制选项\r\n if (paginatedResult.hasNext) {\r\n choices.push({\r\n name: chalk.yellow(await t('apply.nextPage')),\r\n value: '__NEXT_PAGE__',\r\n short: await t('apply.nextPage')\r\n })\r\n }\r\n\r\n if (paginatedResult.hasPrev) {\r\n choices.unshift({\r\n name: chalk.yellow(await t('apply.prevPage')),\r\n value: '__PREV_PAGE__',\r\n short: await t('apply.prevPage')\r\n })\r\n }\r\n\r\n choices.push({\r\n name: chalk.red(await t('apply.cancel')),\r\n value: '__CANCEL__',\r\n short: await t('apply.cancel')\r\n })\r\n\r\n const { selected } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'selected',\r\n message: await t('apply.selectSolutionPage', { \r\n current: currentPage, \r\n total: paginatedResult.totalPages \r\n }),\r\n choices,\r\n pageSize: 15\r\n }\r\n ])\r\n\r\n if (selected === '__CANCEL__') {\r\n return null\r\n } else if (selected === '__NEXT_PAGE__') {\r\n currentPage++\r\n } else if (selected === '__PREV_PAGE__') {\r\n currentPage--\r\n } else {\r\n // 获取详情\r\n const detailSpinner = ora(await t('apply.fetchingDetail')).start()\r\n const detailResponse = await apiClient.getSolutionById(selected)\r\n detailSpinner.stop()\r\n\r\n selectedSolution = detailResponse.data\r\n }\r\n }\r\n\r\n return selectedSolution\r\n } catch (error) {\r\n spinner.fail(await t('apply.fetchDetailFailed'))\r\n throw error\r\n }\r\n}\r\n\r\n/**\r\n * 选择 IDE 类型\r\n */\r\nasync function selectIde(): Promise<AiIdeType> {\r\n const { ide } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'ide',\r\n message: await t('apply.selectIde'),\r\n choices: [\r\n { name: chalk.cyan(await t('apply.ideTypes.vscode')), value: 'vscode' },\r\n { name: chalk.cyan(await t('apply.ideTypes.cursor')), value: 'cursor' },\r\n { name: chalk.cyan(await t('apply.ideTypes.codex')), value: 'codex' },\r\n { name: chalk.cyan(await t('apply.ideTypes.claudeCode')), value: 'claude-code' }\r\n ],\r\n default: 'vscode'\r\n }\r\n ])\r\n\r\n return ide\r\n}\r\n","import axios, { AxiosInstance, AxiosError } from 'axios'\r\nimport { getToken, getBaseUrl } from '../config/token.js'\r\nimport type {\r\n ApiResponse,\r\n Solution,\r\n AgentConfig,\r\n Prompt,\r\n McpConfig\r\n} from '../types/index.js'\r\n\r\n/**\r\n * API 客户端封装\r\n */\r\n\r\nclass ApiClient {\r\n private client: AxiosInstance\r\n private baseUrlPromise: Promise<string>\r\n\r\n constructor() {\r\n // 异步获取 BASE_URL\r\n this.baseUrlPromise = getBaseUrl()\r\n\r\n this.client = axios.create({\r\n timeout: 30000,\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n }\r\n })\r\n\r\n // 请求拦截器:自动添加 token 和 baseURL\r\n this.client.interceptors.request.use(async (config) => {\r\n // 设置 baseURL\r\n if (!config.baseURL) {\r\n config.baseURL = await this.baseUrlPromise\r\n }\r\n\r\n // 添加 token\r\n const token = await getToken()\r\n if (token) {\r\n config.headers['X-CLI-TOKEN'] = token\r\n }\r\n return config\r\n })\r\n\r\n // 响应拦截器:统一错误处理\r\n this.client.interceptors.response.use(\r\n (response) => response,\r\n (error: AxiosError) => {\r\n if (error.response) {\r\n const status = error.response.status\r\n const message = (error.response.data as any)?.message || error.message\r\n\r\n if (status === 401) {\r\n throw new Error('认证失败,请先执行 acp login 登录')\r\n } else if (status === 403) {\r\n throw new Error('权限不足,请检查 token 是否有效')\r\n } else if (status === 404) {\r\n throw new Error('请求的资源不存在')\r\n } else if (status >= 500) {\r\n throw new Error(`服务器错误 (${status}): ${message}`)\r\n } else {\r\n throw new Error(`请求失败 (${status}): ${message}`)\r\n }\r\n } else if (error.request) {\r\n throw new Error('网络错误,请检查网络连接')\r\n } else {\r\n throw new Error(`请求配置错误: ${error.message}`)\r\n }\r\n }\r\n )\r\n }\r\n\r\n /**\r\n * 获取解决方案列表\r\n */\r\n async getSolutions(aiTool?: string): Promise<ApiResponse<Solution[]>> {\r\n const params = aiTool ? { aiTool } : {}\r\n const response = await this.client.get<ApiResponse<Solution[]>>(\r\n '/api/cli/solutions',\r\n { params }\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取解决方案详情\r\n */\r\n async getSolutionById(id: string): Promise<ApiResponse<Solution>> {\r\n const response = await this.client.get<ApiResponse<Solution>>(\r\n `/api/cli/solutions/${id}`\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 Agent 配置列表\r\n */\r\n async getAgents(): Promise<ApiResponse<AgentConfig[]>> {\r\n const response = await this.client.get<ApiResponse<AgentConfig[]>>(\r\n '/api/cli/agents'\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 Agent 配置详情\r\n */\r\n async getAgentById(id: string): Promise<ApiResponse<AgentConfig>> {\r\n const response = await this.client.get<ApiResponse<AgentConfig>>(\r\n `/api/cli/agents/${id}`\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 Prompt 列表\r\n */\r\n async getPrompts(): Promise<ApiResponse<Prompt[]>> {\r\n const response = await this.client.get<ApiResponse<Prompt[]>>(\r\n '/api/cli/prompts'\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 Prompt 详情\r\n */\r\n async getPromptById(id: string): Promise<ApiResponse<Prompt>> {\r\n const response = await this.client.get<ApiResponse<Prompt>>(\r\n `/api/cli/prompts/${id}`\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 MCP 配置列表\r\n */\r\n async getMcps(): Promise<ApiResponse<McpConfig[]>> {\r\n const response = await this.client.get<ApiResponse<McpConfig[]>>(\r\n '/api/cli/mcps'\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 MCP 配置详情\r\n */\r\n async getMcpById(id: string): Promise<ApiResponse<McpConfig>> {\r\n const response = await this.client.get<ApiResponse<McpConfig>>(\r\n `/api/cli/mcps/${id}`\r\n )\r\n return response.data\r\n }\r\n}\r\n\r\n// 导出单例\r\nexport const apiClient = new ApiClient()\r\n","/**\r\n * 分页工具函数\r\n */\r\n\r\nexport interface PaginationOptions {\r\n page: number\r\n pageSize: number\r\n}\r\n\r\nexport interface PaginationResult<T> {\r\n items: T[]\r\n total: number\r\n page: number\r\n pageSize: number\r\n totalPages: number\r\n hasNext: boolean\r\n hasPrev: boolean\r\n}\r\n\r\n/**\r\n * 对数组进行分页\r\n */\r\nexport function paginate<T>(\r\n items: T[],\r\n options: PaginationOptions\r\n): PaginationResult<T> {\r\n const { page, pageSize } = options\r\n const total = items.length\r\n const totalPages = Math.ceil(total / pageSize)\r\n const startIndex = (page - 1) * pageSize\r\n const endIndex = startIndex + pageSize\r\n\r\n return {\r\n items: items.slice(startIndex, endIndex),\r\n total,\r\n page,\r\n pageSize,\r\n totalPages,\r\n hasNext: page < totalPages,\r\n hasPrev: page > 1\r\n }\r\n}\r\n\r\n/**\r\n * 按名称搜索(不区分大小写)\r\n */\r\nexport function searchByName<T extends { name: string }>(\r\n items: T[],\r\n query: string\r\n): T[] {\r\n if (!query.trim()) {\r\n return items\r\n }\r\n\r\n const lowerQuery = query.toLowerCase().trim()\r\n return items.filter((item) =>\r\n item.name.toLowerCase().includes(lowerQuery)\r\n )\r\n}\r\n","import fs from 'fs-extra'\r\nimport path from 'path'\r\nimport chalk from 'chalk'\r\nimport inquirer from 'inquirer'\r\nimport { logger } from '../utils/logger.js'\r\nimport { getIdePathMapping, type AiIdeType } from '../utils/ide-mapper.js'\r\nimport type { Solution, Prompt, McpConfig } from '../types/index.js'\r\n\r\n/**\r\n * 配置应用模块 - 将远程配置写入本地文件\r\n */\r\n\r\nexport interface ApplyOptions {\r\n ide: AiIdeType\r\n targetDir: string\r\n}\r\n\r\n/**\r\n * 应用解决方案配置\r\n */\r\nexport async function applySolution(\r\n solution: Solution,\r\n options: ApplyOptions\r\n): Promise<void> {\r\n const { ide, targetDir } = options\r\n const pathMapping = getIdePathMapping(ide)\r\n\r\n logger.title(`📦 应用解决方案: ${chalk.cyan(solution.name)}`)\r\n\r\n // 1. 应用 Agent 配置\r\n if (solution.agentConfig) {\r\n await applyAgentConfig(\r\n solution.agentConfig.content,\r\n pathMapping.agents,\r\n targetDir\r\n )\r\n }\r\n\r\n // 2. 应用 Prompts\r\n if (solution.customPrompts?.length) {\r\n await applyPrompts(\r\n solution.customPrompts,\r\n pathMapping.prompts,\r\n targetDir\r\n )\r\n }\r\n\r\n // 3. 应用 MCP 配置\r\n if (solution.mcpConfigs?.length) {\r\n await applyMcpConfigs(\r\n solution.mcpConfigs,\r\n pathMapping.mcp,\r\n targetDir\r\n )\r\n }\r\n\r\n logger.success(`\\n✨ 解决方案 ${chalk.cyan(solution.name)} 应用成功!`)\r\n}\r\n\r\n/**\r\n * 应用 Agent 配置\r\n */\r\nexport async function applyAgentConfig(\r\n content: string,\r\n relativePath: string,\r\n targetDir: string\r\n): Promise<void> {\r\n const filePath = path.join(targetDir, relativePath)\r\n\r\n logger.step(`写入 Agent 配置: ${chalk.gray(relativePath)}`)\r\n\r\n // 检查文件是否存在\r\n const exists = await fs.pathExists(filePath)\r\n if (exists) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: `文件 ${chalk.cyan(relativePath)} 已存在,是否覆盖?`,\r\n default: true\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.warning(`跳过: ${relativePath}`)\r\n return\r\n }\r\n }\r\n\r\n // 写入文件\r\n await fs.ensureDir(path.dirname(filePath))\r\n await fs.writeFile(filePath, content, 'utf-8')\r\n\r\n logger.success(`已写入: ${relativePath}`)\r\n}\r\n\r\n/**\r\n * 应用 Prompts\r\n */\r\nexport async function applyPrompts(\r\n prompts: Prompt[],\r\n promptsDir: string,\r\n targetDir: string\r\n): Promise<void> {\r\n const fullPromptsDir = path.join(targetDir, promptsDir)\r\n\r\n logger.step(`写入 ${prompts.length} 个 Prompt 配置到: ${chalk.gray(promptsDir)}`)\r\n\r\n // 确保目录存在\r\n await fs.ensureDir(fullPromptsDir)\r\n\r\n for (const prompt of prompts) {\r\n // 生成文件名(清理特殊字符)\r\n const fileName = sanitizeFileName(prompt.name) + '.prompt.md'\r\n const filePath = path.join(fullPromptsDir, fileName)\r\n\r\n // 检查是否存在\r\n const exists = await fs.pathExists(filePath)\r\n if (exists) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: `Prompt ${chalk.cyan(fileName)} 已存在,是否覆盖?`,\r\n default: true\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.warning(`跳过: ${fileName}`)\r\n continue\r\n }\r\n }\r\n\r\n // 写入内容\r\n await fs.writeFile(filePath, prompt.content, 'utf-8')\r\n logger.success(`已写入: ${path.join(promptsDir, fileName)}`)\r\n }\r\n}\r\n\r\n/**\r\n * 应用 MCP 配置\r\n */\r\nexport async function applyMcpConfigs(\r\n mcpConfigs: McpConfig[],\r\n mcpFile: string,\r\n targetDir: string\r\n): Promise<void> {\r\n const filePath = path.join(targetDir, mcpFile)\r\n\r\n logger.step(`写入 MCP 配置: ${chalk.gray(mcpFile)}`)\r\n\r\n // 构造 mcpServers 结构\r\n const mcpServers: Record<string, any> = {}\r\n\r\n for (const mcpConfig of mcpConfigs) {\r\n try {\r\n const config = JSON.parse(mcpConfig.configJson)\r\n // 使用 MCP 配置的名称作为 key\r\n mcpServers[mcpConfig.name] = config\r\n } catch (error) {\r\n logger.warning(`MCP 配置 ${mcpConfig.name} 格式错误,已跳过`)\r\n }\r\n }\r\n\r\n // 检查文件是否存在\r\n const exists = await fs.pathExists(filePath)\r\n if (exists) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: `文件 ${chalk.cyan(mcpFile)} 已存在,是否覆盖?`,\r\n default: true\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.warning(`跳过: ${mcpFile}`)\r\n return\r\n }\r\n }\r\n\r\n // 写入文件\r\n await fs.ensureDir(path.dirname(filePath))\r\n\r\n // 根据文件扩展名和路径决定输出格式\r\n if (mcpFile.endsWith('.toml')) {\r\n // Codex 使用 TOML 格式\r\n const tomlContent = convertMcpToToml(mcpServers)\r\n await fs.writeFile(filePath, tomlContent, 'utf-8')\r\n } else {\r\n // JSON 格式\r\n let mergedConfig: Record<string, any>\r\n \r\n // VS Code 使用 \"servers\",其他 IDE 使用 \"mcpServers\"\r\n if (mcpFile.includes('.vscode')) {\r\n mergedConfig = {\r\n servers: mcpServers\r\n }\r\n } else {\r\n mergedConfig = {\r\n mcpServers\r\n }\r\n }\r\n \r\n await fs.writeFile(filePath, JSON.stringify(mergedConfig, null, 2), 'utf-8')\r\n }\r\n\r\n logger.success(`已写入: ${mcpFile}`)\r\n}\r\n\r\n/**\r\n * 将 MCP 配置转换为 TOML 格式(用于 Codex)\r\n */\r\nfunction convertMcpToToml(mcpServers: Record<string, any>): string {\r\n let tomlContent = ''\r\n\r\n for (const [serverName, config] of Object.entries(mcpServers)) {\r\n tomlContent += `[mcp_servers.${serverName}]\\n`\r\n \r\n // 写入 command\r\n if (config.command) {\r\n tomlContent += `command = ${JSON.stringify(config.command)}\\n`\r\n }\r\n\r\n // 写入 args\r\n if (config.args && Array.isArray(config.args)) {\r\n const argsStr = config.args.map((arg: string) => JSON.stringify(arg)).join(', ')\r\n tomlContent += `args = [${argsStr}]\\n`\r\n }\r\n\r\n // 写入 env\r\n if (config.env && typeof config.env === 'object') {\r\n const envEntries = Object.entries(config.env)\r\n if (envEntries.length > 0) {\r\n const envStr = envEntries\r\n .map(([key, value]) => `${key} = ${JSON.stringify(value)}`)\r\n .join(', ')\r\n tomlContent += `env = { ${envStr} }\\n`\r\n }\r\n }\r\n\r\n tomlContent += '\\n'\r\n }\r\n\r\n return tomlContent\r\n}\r\n\r\n/**\r\n * 清理文件名中的特殊字符\r\n */\r\nfunction sanitizeFileName(name: string): string {\r\n return name\r\n .replace(/[<>:\"/\\\\|?*]/g, '-') // 替换非法字符\r\n .replace(/\\s+/g, '-') // 空格转连字符\r\n .replace(/-+/g, '-') // 多个连字符合并\r\n .toLowerCase()\r\n}\r\n","import type { AiIdeType, IdePathMapping } from '../types/index.js'\r\n\r\n// 重新导出类型\r\nexport type { AiIdeType, IdePathMapping }\r\n\r\n/**\r\n * AI IDE 路径映射配置\r\n * 定义不同 IDE 的配置文件输出路径\r\n */\r\n\r\nexport const IDE_PATH_MAPPINGS: Record<AiIdeType, IdePathMapping> = {\r\n vscode: {\r\n prompts: '.github/prompts',\r\n agents: 'AGENTS.md',\r\n mcp: '.vscode/mcp.json'\r\n },\r\n cursor: {\r\n prompts: '.cursor/commands',\r\n agents: 'AGENTS.md',\r\n mcp: '.cursor/mcp.json'\r\n },\r\n codex: {\r\n prompts: '~/.codex/prompts',\r\n agents: 'AGENTS.md',\r\n mcp: '.codex/config.toml'\r\n },\r\n 'claude-code': {\r\n prompts: '.claude/commands',\r\n agents: 'AGENTS.md',\r\n mcp: '.mcp.json'\r\n }\r\n}\r\n\r\n/**\r\n * 获取 IDE 路径映射\r\n */\r\nexport function getIdePathMapping(ide: AiIdeType): IdePathMapping {\r\n return IDE_PATH_MAPPINGS[ide]\r\n}\r\n\r\n/**\r\n * 获取所有支持的 IDE 列表\r\n */\r\nexport function getSupportedIdes(): AiIdeType[] {\r\n return Object.keys(IDE_PATH_MAPPINGS) as AiIdeType[]\r\n}\r\n\r\n/**\r\n * 验证 IDE 类型是否支持\r\n */\r\nexport function isValidIde(ide: string): ide is AiIdeType {\r\n return ide in IDE_PATH_MAPPINGS\r\n}\r\n","import { Command } from 'commander'\r\nimport inquirer from 'inquirer'\r\nimport chalk from 'chalk'\r\nimport { getLocale, saveLocale, getSupportedLocales, getLocaleName, type Locale } from '../config/locale.js'\r\nimport { t } from '../i18n/index.js'\r\nimport { logger } from '../utils/logger.js'\r\n\r\n/**\r\n * acp locale 命令\r\n * 切换 CLI 语言\r\n */\r\n\r\nexport const localeCommand = new Command('locale')\r\n .description('切换 CLI 语言 / Switch CLI language')\r\n .action(async () => {\r\n try {\r\n // 获取当前语言\r\n const currentLocale = await getLocale()\r\n \r\n // 显示标题\r\n const title = await t('locale.title')\r\n logger.title(title)\r\n\r\n // 显示当前语言\r\n const currentText = await t('locale.current')\r\n console.log(chalk.gray(`${currentText}: `) + chalk.cyan(getLocaleName(currentLocale)))\r\n console.log()\r\n\r\n // 选择新语言\r\n const supportedLocales = getSupportedLocales()\r\n const selectText = await t('locale.selectLanguage')\r\n \r\n const { newLocale } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'newLocale',\r\n message: selectText,\r\n choices: supportedLocales.map(locale => ({\r\n name: locale === currentLocale \r\n ? chalk.cyan(`${getLocaleName(locale)} (当前 / Current)`)\r\n : getLocaleName(locale),\r\n value: locale\r\n })),\r\n default: currentLocale\r\n }\r\n ])\r\n\r\n // 如果选择的是当前语言,则不做任何操作\r\n if (newLocale === currentLocale) {\r\n logger.info(`${await t('locale.current')}: ${getLocaleName(currentLocale)}`)\r\n return\r\n }\r\n\r\n // 保存新语言\r\n await saveLocale(newLocale as Locale)\r\n\r\n // 显示成功消息(使用新语言)\r\n // 注意:这里需要手动构造消息,因为 t() 函数还在使用旧语言缓存\r\n if (newLocale === 'zh-CN') {\r\n logger.success(`语言已切换为 ${getLocaleName(newLocale)}`)\r\n console.log(chalk.gray('\\n提示: 已生效,新命令将使用所选语言\\n'))\r\n } else {\r\n logger.success(`Language switched to ${getLocaleName(newLocale)}`)\r\n console.log(chalk.gray('\\nTip: Changes take effect immediately for new commands\\n'))\r\n }\r\n\r\n } catch (error) {\r\n if (error instanceof Error) {\r\n logger.error(`${await t('locale.failed')}: ${error.message}`)\r\n }\r\n process.exit(1)\r\n }\r\n })\r\n"],"mappings":"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","names":["Command","chalk","chalk","fs","path","os","CONFIG_DIR","chalk","Command","inquirer","chalk","fs","path","chalk","inquirer","chalk","path","fs","inquirer","Command","chalk","inquirer","Command","inquirer","chalk","Command","currentLocale","chalk","inquirer","Command","chalk"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/login.ts","../src/config/token.ts","../src/utils/logger.ts","../src/config/locale.ts","../src/i18n/zh-CN.ts","../src/i18n/en-US.ts","../src/i18n/index.ts","../src/commands/apply.ts","../src/api/client.ts","../src/utils/pagination.ts","../src/apply/writer.ts","../src/utils/ide-mapper.ts","../src/commands/locale.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Command } from 'commander'\r\nimport chalk from 'chalk'\r\nimport { loginCommand } from './commands/login.js'\r\nimport { applyCommand } from './commands/apply.js'\r\nimport { localeCommand } from './commands/locale.js'\r\nimport { handleError } from './utils/logger.js'\r\nimport { t } from './i18n/index.js'\r\n\r\n/**\r\n * ACP CLI 主入口\r\n */\r\n\r\n// 版本号在构建时注入\r\n// @ts-ignore - 构建时通过 tsup define 注入\r\nconst version = typeof __VERSION__ !== 'undefined' ? __VERSION__ : '0.0.0-dev'\r\n\r\nasync function main() {\r\n const program = new Command()\r\n\r\n program\r\n .name('acp')\r\n .description(\r\n chalk.gray(await t('cli.description'))\r\n )\r\n .version(version, '-v, --version', await t('cli.version'))\r\n .helpOption('-h, --help', await t('cli.help'))\r\n\r\n // 注册命令\r\n program.addCommand(loginCommand)\r\n program.addCommand(applyCommand)\r\n program.addCommand(localeCommand)\r\n\r\n // 自定义帮助显示\r\n program.on('--help', async () => {\r\n console.log(chalk.bold('\\n' + await t('cli.exampleTitle') + '\\n'))\r\n console.log(chalk.gray(' $ acp login'))\r\n console.log(chalk.gray(' $ acp apply'))\r\n console.log(chalk.gray(' $ acp apply --ide vscode --dir ./my-project'))\r\n console.log(chalk.gray(' $ acp locale'))\r\n console.log()\r\n })\r\n\r\n // 解析命令\r\n try {\r\n await program.parseAsync(process.argv)\r\n } catch (error) {\r\n await handleError(error)\r\n process.exit(1)\r\n }\r\n}\r\n\r\nmain()\r\n","import { Command } from 'commander'\r\nimport inquirer from 'inquirer'\r\nimport chalk from 'chalk'\r\nimport { saveToken, getToken, initDefaultConfig } from '../config/token.js'\r\nimport { logger } from '../utils/logger.js'\r\nimport { t } from '../i18n/index.js'\r\n\r\n/**\r\n * acp login 命令\r\n * 提示用户输入 CLI Token 并保存\r\n */\r\n\r\nexport const loginCommand = new Command('login')\r\n .description('登录 ACP CLI,保存访问令牌 / Login to ACP CLI and save access token')\r\n .action(async () => {\r\n try {\r\n logger.title(await t('login.title'))\r\n\r\n // 初始化默认配置(首次使用时)\r\n await initDefaultConfig()\r\n\r\n // 检查是否已有 token\r\n const existingToken = await getToken()\r\n if (existingToken) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: await t('login.alreadyLoggedIn'),\r\n default: false\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.info(await t('login.cancelled'))\r\n return\r\n }\r\n }\r\n\r\n // 提示输入 token\r\n const { token } = await inquirer.prompt([\r\n {\r\n type: 'password',\r\n name: 'token',\r\n message: await t('login.inputToken'),\r\n validate: async (input: string) => {\r\n if (!input.trim()) {\r\n return await t('login.tokenEmpty')\r\n }\r\n if (input.trim().length < 10) {\r\n return await t('login.tokenInvalid')\r\n }\r\n return true\r\n },\r\n mask: '*'\r\n }\r\n ])\r\n\r\n // 保存 token\r\n await saveToken(token)\r\n\r\n logger.success(await t('login.success'))\r\n console.log(chalk.gray('\\n' + await t('login.hint') + '\\n'))\r\n } catch (error) {\r\n if (error instanceof Error) {\r\n logger.error(`${await t('login.failed')}: ${error.message}`)\r\n }\r\n process.exit(1)\r\n }\r\n })\r\n","import fs from 'fs-extra'\r\nimport path from 'path'\r\nimport os from 'os'\r\n\r\n/**\r\n * Token 和 BASE_URL 配置管理\r\n * 优先级: 环境变量 > ~/.acp/ 配置文件\r\n */\r\n\r\nconst TOKEN_ENV_KEY = 'ACP_CLI_TOKEN'\r\nconst BASE_URL_ENV_KEY = 'ACP_CLI_BASE_URL'\r\nconst DEFAULT_BASE_URL = 'https://api.ai-config-plaza.com'\r\n\r\nconst CONFIG_DIR = path.join(os.homedir(), '.acp')\r\nconst TOKEN_FILE = path.join(CONFIG_DIR, 'token')\r\nconst BASE_URL_FILE = path.join(CONFIG_DIR, 'base-url')\r\n\r\n/**\r\n * 读取 CLI Token\r\n */\r\nexport async function getToken(): Promise<string | null> {\r\n // 1. 优先读取环境变量\r\n const envToken = process.env[TOKEN_ENV_KEY]\r\n if (envToken?.trim()) {\r\n return envToken.trim()\r\n }\r\n\r\n // 2. 读取本地配置文件\r\n try {\r\n if (await fs.pathExists(TOKEN_FILE)) {\r\n const token = await fs.readFile(TOKEN_FILE, 'utf-8')\r\n return token.trim() || null\r\n }\r\n } catch (error) {\r\n // 读取失败返回 null\r\n }\r\n\r\n return null\r\n}\r\n\r\n/**\r\n * 保存 CLI Token 到本地配置文件\r\n */\r\nexport async function saveToken(token: string): Promise<void> {\r\n if (!token?.trim()) {\r\n throw new Error('Token 不能为空')\r\n }\r\n\r\n // 确保配置目录存在\r\n await fs.ensureDir(CONFIG_DIR)\r\n\r\n // 写入 token 文件\r\n await fs.writeFile(TOKEN_FILE, token.trim(), 'utf-8')\r\n}\r\n\r\n/**\r\n * 删除本地 Token\r\n */\r\nexport async function removeToken(): Promise<void> {\r\n if (await fs.pathExists(TOKEN_FILE)) {\r\n await fs.remove(TOKEN_FILE)\r\n }\r\n}\r\n\r\n/**\r\n * 检查是否已登录\r\n */\r\nexport async function isLoggedIn(): Promise<boolean> {\r\n const token = await getToken()\r\n return token !== null && token.length > 0\r\n}\r\n\r\n/**\r\n * 读取 BASE_URL\r\n */\r\nexport async function getBaseUrl(): Promise<string> {\r\n // 1. 优先读取环境变量\r\n const envBaseUrl = process.env[BASE_URL_ENV_KEY]\r\n if (envBaseUrl?.trim()) {\r\n return envBaseUrl.trim()\r\n }\r\n\r\n // 2. 读取本地配置文件\r\n try {\r\n if (await fs.pathExists(BASE_URL_FILE)) {\r\n const baseUrl = await fs.readFile(BASE_URL_FILE, 'utf-8')\r\n if (baseUrl.trim()) {\r\n return baseUrl.trim()\r\n }\r\n }\r\n } catch (error) {\r\n // 读取失败,使用默认值\r\n }\r\n\r\n // 3. 返回默认值\r\n return DEFAULT_BASE_URL\r\n}\r\n\r\n/**\r\n * 保存 BASE_URL 到本地配置文件\r\n */\r\nexport async function saveBaseUrl(baseUrl: string): Promise<void> {\r\n if (!baseUrl?.trim()) {\r\n throw new Error('BASE_URL 不能为空')\r\n }\r\n\r\n // 验证 URL 格式\r\n try {\r\n new URL(baseUrl.trim())\r\n } catch {\r\n throw new Error('BASE_URL 格式不正确,请输入有效的 URL')\r\n }\r\n\r\n // 确保配置目录存在\r\n await fs.ensureDir(CONFIG_DIR)\r\n\r\n // 写入 base-url 文件\r\n await fs.writeFile(BASE_URL_FILE, baseUrl.trim(), 'utf-8')\r\n}\r\n\r\n/**\r\n * 删除本地 BASE_URL\r\n */\r\nexport async function removeBaseUrl(): Promise<void> {\r\n if (await fs.pathExists(BASE_URL_FILE)) {\r\n await fs.remove(BASE_URL_FILE)\r\n }\r\n}\r\n\r\n/**\r\n * 初始化默认配置(首次使用时)\r\n */\r\nexport async function initDefaultConfig(): Promise<void> {\r\n await fs.ensureDir(CONFIG_DIR)\r\n\r\n // 如果 BASE_URL 不存在,初始化默认值\r\n if (!(await fs.pathExists(BASE_URL_FILE))) {\r\n await saveBaseUrl(DEFAULT_BASE_URL)\r\n }\r\n}\r\n","import chalk from 'chalk'\r\nimport { t } from '../i18n/index.js'\r\n\r\n/**\r\n * 日志工具 - 提供统一的终端输出格式\r\n */\r\n\r\n// 使用 Unicode 符号代替 figures\r\nconst symbols = {\r\n info: 'ℹ',\r\n tick: '✓',\r\n warning: '⚠',\r\n cross: '✖',\r\n arrowRight: '→'\r\n}\r\n\r\nexport const logger = {\r\n /**\r\n * 普通信息\r\n */\r\n info: (message: string) => {\r\n console.log(chalk.blue(symbols.info) + ' ' + message)\r\n },\r\n\r\n /**\r\n * 成功信息\r\n */\r\n success: (message: string) => {\r\n console.log(chalk.green(symbols.tick) + ' ' + chalk.green(message))\r\n },\r\n\r\n /**\r\n * 警告信息\r\n */\r\n warning: (message: string) => {\r\n console.log(chalk.yellow(symbols.warning) + ' ' + chalk.yellow(message))\r\n },\r\n\r\n /**\r\n * 错误信息\r\n */\r\n error: (message: string) => {\r\n console.error(chalk.red(symbols.cross) + ' ' + chalk.red(message))\r\n },\r\n\r\n /**\r\n * 步骤信息\r\n */\r\n step: (message: string) => {\r\n console.log(chalk.cyan(symbols.arrowRight) + ' ' + chalk.gray(message))\r\n },\r\n\r\n /**\r\n * 标题\r\n */\r\n title: (message: string) => {\r\n console.log('\\n' + chalk.bold.underline(message) + '\\n')\r\n },\r\n\r\n /**\r\n * 普通文本(无图标)\r\n */\r\n log: (message: string) => {\r\n console.log(message)\r\n }\r\n}\r\n\r\n/**\r\n * 自定义 CLI 错误类\r\n */\r\nexport class CLIError extends Error {\r\n constructor(\r\n message: string,\r\n public code?: string,\r\n public suggestions?: string[]\r\n ) {\r\n super(message)\r\n this.name = 'CLIError'\r\n }\r\n}\r\n\r\n/**\r\n * 错误处理函数\r\n */\r\nexport async function handleError(error: unknown): Promise<void> {\r\n console.error()\r\n\r\n if (error instanceof CLIError) {\r\n logger.error(error.message)\r\n\r\n if (error.code) {\r\n const errorCodeText = await t('error.errorCode')\r\n console.log(chalk.gray(`${errorCodeText} ${error.code}`))\r\n }\r\n\r\n if (error.suggestions?.length) {\r\n const suggestionsText = await t('error.suggestions')\r\n console.log(chalk.yellow.bold(`\\n${suggestionsText}\\n`))\r\n error.suggestions.forEach((suggestion, index) => {\r\n console.log(chalk.gray(` ${index + 1}. ${suggestion}`))\r\n })\r\n }\r\n } else if (error instanceof Error) {\r\n logger.error(error.message)\r\n\r\n if (process.env.DEBUG) {\r\n console.log(chalk.gray('\\n' + error.stack))\r\n }\r\n } else {\r\n logger.error(await t('error.unknownError'))\r\n }\r\n\r\n const needHelpText = await t('error.needHelp')\r\n console.log(\r\n chalk.gray(`\\n${needHelpText} `) +\r\n chalk.blue.underline('https://github.com/AIConfigPlaza/acp-cli')\r\n )\r\n console.log()\r\n}\r\n","import fs from 'fs-extra'\r\nimport path from 'path'\r\nimport os from 'os'\r\n\r\n/**\r\n * 语言配置管理\r\n * 支持的语言: zh-CN (中文), en-US (英文)\r\n */\r\n\r\nexport type Locale = 'zh-CN' | 'en-US'\r\n\r\nconst LOCALE_ENV_KEY = 'ACP_CLI_LOCALE'\r\nconst DEFAULT_LOCALE: Locale = 'zh-CN'\r\n\r\nconst CONFIG_DIR = path.join(os.homedir(), '.acp')\r\nconst LOCALE_FILE = path.join(CONFIG_DIR, 'locale')\r\n\r\n/**\r\n * 读取当前语言配置\r\n */\r\nexport async function getLocale(): Promise<Locale> {\r\n // 1. 优先读取环境变量\r\n const envLocale = process.env[LOCALE_ENV_KEY]\r\n if (envLocale && isValidLocale(envLocale)) {\r\n return envLocale as Locale\r\n }\r\n\r\n // 2. 读取本地配置文件\r\n try {\r\n if (await fs.pathExists(LOCALE_FILE)) {\r\n const locale = (await fs.readFile(LOCALE_FILE, 'utf-8')).trim()\r\n if (isValidLocale(locale)) {\r\n return locale as Locale\r\n }\r\n }\r\n } catch (error) {\r\n // 读取失败使用默认值\r\n }\r\n\r\n // 3. 返回默认语言\r\n return DEFAULT_LOCALE\r\n}\r\n\r\n/**\r\n * 保存语言配置到本地文件\r\n */\r\nexport async function saveLocale(locale: Locale): Promise<void> {\r\n if (!isValidLocale(locale)) {\r\n throw new Error(`不支持的语言: ${locale}`)\r\n }\r\n\r\n // 确保配置目录存在\r\n await fs.ensureDir(CONFIG_DIR)\r\n\r\n // 保存语言配置\r\n await fs.writeFile(LOCALE_FILE, locale, 'utf-8')\r\n}\r\n\r\n/**\r\n * 验证语言代码是否有效\r\n */\r\nfunction isValidLocale(locale: string): boolean {\r\n return locale === 'zh-CN' || locale === 'en-US'\r\n}\r\n\r\n/**\r\n * 获取所有支持的语言列表\r\n */\r\nexport function getSupportedLocales(): Locale[] {\r\n return ['zh-CN', 'en-US']\r\n}\r\n\r\n/**\r\n * 获取语言显示名称\r\n */\r\nexport function getLocaleName(locale: Locale): string {\r\n const names: Record<Locale, string> = {\r\n 'zh-CN': '简体中文',\r\n 'en-US': 'English'\r\n }\r\n return names[locale]\r\n}\r\n","/**\r\n * 中文语言包\r\n */\r\n\r\nexport const zhCN = {\r\n // 通用\r\n common: {\r\n confirm: '确认',\r\n cancel: '取消',\r\n yes: '是',\r\n no: '否',\r\n success: '成功',\r\n failed: '失败',\r\n error: '错误',\r\n warning: '警告',\r\n info: '提示'\r\n },\r\n\r\n // CLI 主程序\r\n cli: {\r\n name: 'acp',\r\n description: 'AI-Config-Plaza CLI - 统一 AI 编程工具配置管理',\r\n version: '显示版本号',\r\n help: '显示帮助信息',\r\n exampleTitle: '示例:'\r\n },\r\n\r\n // login 命令\r\n login: {\r\n command: 'login',\r\n description: '登录 ACP CLI,保存访问令牌',\r\n title: '🔐 ACP CLI 登录',\r\n alreadyLoggedIn: '检测到已登录,是否重新登录?',\r\n cancelled: '已取消登录',\r\n inputToken: '请输入 CLI Token:',\r\n tokenEmpty: 'Token 不能为空',\r\n tokenInvalid: 'Token 格式不正确(至少 10 个字符)',\r\n success: '登录成功!Token 已保存到 ~/.acp/token',\r\n hint: '提示: 现在可以使用 acp apply 命令拉取配置',\r\n failed: '登录失败'\r\n },\r\n\r\n // apply 命令\r\n apply: {\r\n command: 'apply',\r\n description: '拉取并应用配置到本地项目',\r\n title: '🚀 ACP 配置应用',\r\n optionType: '资源类型 (solution|agent|prompt|mcp)',\r\n optionIde: 'AI IDE 类型 (vscode|cursor|codex|claude-code)',\r\n optionDir: '目标目录',\r\n notLoggedIn: '未登录,请先执行 acp login',\r\n loginFirst: '运行 acp login 命令登录',\r\n selectResourceType: '请选择资源类型:',\r\n resourceTypes: {\r\n solution: '解决方案 (Solution)',\r\n agent: 'Agent 配置 (暂不支持)',\r\n prompt: 'Prompt (暂不支持)',\r\n mcp: 'MCP 配置 (暂不支持)'\r\n },\r\n notSupported: '暂不支持独立应用 agent/prompt/mcp,请使用 solution 类型',\r\n noSelection: '未选择任何配置',\r\n selectIde: '请选择 AI IDE 类型:',\r\n applied: '配置已应用到:',\r\n searchPlaceholder: '搜索解决方案(输入名称或描述)',\r\n noResults: '没有找到解决方案',\r\n loadingMore: '加载更多...',\r\n noMore: '没有更多了',\r\n selected: '已选择',\r\n selectSolution: '请选择一个解决方案:',\r\n fetching: '正在获取解决方案列表...',\r\n fetchSuccess: '获取到 {count} 个解决方案',\r\n noSolutions: '暂无可用的解决方案',\r\n searchPrompt: '搜索解决方案 (按名称搜索,留空显示全部):',\r\n noMatch: '未找到匹配的解决方案',\r\n selectSolutionPage: '选择解决方案 (第 {current}/{total} 页):',\r\n nextPage: '>>> 下一页',\r\n prevPage: '<<< 上一页',\r\n cancel: '取消',\r\n fetchingDetail: '正在获取解决方案详情...',\r\n fetchDetailFailed: '获取解决方案失败',\r\n ideTypes: {\r\n vscode: 'VS Code',\r\n cursor: 'Cursor',\r\n codex: 'Codex',\r\n claudeCode: 'Claude Code'\r\n }\r\n },\r\n\r\n // locale 命令\r\n locale: {\r\n command: 'locale',\r\n description: '切换 CLI 语言',\r\n title: '🌐 语言设置',\r\n current: '当前语言',\r\n selectLanguage: '请选择语言:',\r\n success: '语言已切换为',\r\n failed: '语言切换失败',\r\n restartHint: '提示: 已生效,新命令将使用所选语言'\r\n },\r\n\r\n // 错误处理\r\n error: {\r\n errorCode: '错误代码:',\r\n suggestions: '💡 建议:',\r\n needHelp: '需要帮助? 访问:',\r\n unknownError: '未知错误'\r\n }\r\n}\r\n","/**\r\n * English Language Pack\r\n */\r\n\r\nexport const enUS = {\r\n // Common\r\n common: {\r\n confirm: 'Confirm',\r\n cancel: 'Cancel',\r\n yes: 'Yes',\r\n no: 'No',\r\n success: 'Success',\r\n failed: 'Failed',\r\n error: 'Error',\r\n warning: 'Warning',\r\n info: 'Info'\r\n },\r\n\r\n // CLI Main\r\n cli: {\r\n name: 'acp',\r\n description: 'AI-Config-Plaza CLI - Unified AI Programming Tool Configuration Management',\r\n version: 'Show version number',\r\n help: 'Show help information',\r\n exampleTitle: 'Examples:'\r\n },\r\n\r\n // login command\r\n login: {\r\n command: 'login',\r\n description: 'Login to ACP CLI and save access token',\r\n title: '🔐 ACP CLI Login',\r\n alreadyLoggedIn: 'Already logged in. Do you want to login again?',\r\n cancelled: 'Login cancelled',\r\n inputToken: 'Please enter CLI Token:',\r\n tokenEmpty: 'Token cannot be empty',\r\n tokenInvalid: 'Invalid token format (at least 10 characters)',\r\n success: 'Login successful! Token saved to ~/.acp/token',\r\n hint: 'Tip: You can now use acp apply command to fetch configurations',\r\n failed: 'Login failed'\r\n },\r\n\r\n // apply command\r\n apply: {\r\n command: 'apply',\r\n description: 'Fetch and apply configurations to local project',\r\n title: '🚀 ACP Configuration Apply',\r\n optionType: 'Resource type (solution|agent|prompt|mcp)',\r\n optionIde: 'AI IDE type (vscode|cursor|codex|claude-code)',\r\n optionDir: 'Target directory',\r\n notLoggedIn: 'Not logged in. Please run acp login first',\r\n loginFirst: 'Run acp login command to login',\r\n selectResourceType: 'Please select resource type:',\r\n resourceTypes: {\r\n solution: 'Solution',\r\n agent: 'Agent Configuration (Not supported yet)',\r\n prompt: 'Prompt (Not supported yet)',\r\n mcp: 'MCP Configuration (Not supported yet)'\r\n },\r\n notSupported: 'Standalone application of agent/prompt/mcp is not supported yet. Please use solution type',\r\n noSelection: 'No configuration selected',\r\n selectIde: 'Please select AI IDE type:',\r\n applied: 'Configuration applied to:',\r\n searchPlaceholder: 'Search solutions (enter name or description)',\r\n noResults: 'No solutions found',\r\n loadingMore: 'Loading more...',\r\n noMore: 'No more items',\r\n selected: 'Selected',\r\n selectSolution: 'Please select a solution:',\r\n fetching: 'Fetching solution list...',\r\n fetchSuccess: 'Fetched {count} solutions',\r\n noSolutions: 'No solutions available',\r\n searchPrompt: 'Search solutions (search by name, leave empty to show all):',\r\n noMatch: 'No matching solutions found',\r\n selectSolutionPage: 'Select solution (Page {current}/{total}):',\r\n nextPage: '>>> Next Page',\r\n prevPage: '<<< Previous Page',\r\n cancel: 'Cancel',\r\n fetchingDetail: 'Fetching solution details...',\r\n fetchDetailFailed: 'Failed to fetch solutions',\r\n ideTypes: {\r\n vscode: 'VS Code',\r\n cursor: 'Cursor',\r\n codex: 'Codex',\r\n claudeCode: 'Claude Code'\r\n }\r\n },\r\n\r\n // locale command\r\n locale: {\r\n command: 'locale',\r\n description: 'Switch CLI language',\r\n title: '🌐 Language Settings',\r\n current: 'Current Language',\r\n selectLanguage: 'Please select language:',\r\n success: 'Language switched to',\r\n failed: 'Failed to switch language',\r\n restartHint: 'Tip: Changes take effect immediately for new commands'\r\n },\r\n\r\n // Error handling\r\n error: {\r\n errorCode: 'Error Code:',\r\n suggestions: '💡 Suggestions:',\r\n needHelp: 'Need help? Visit:',\r\n unknownError: 'Unknown error'\r\n }\r\n}\r\n","import { getLocale, type Locale } from '../config/locale.js'\r\nimport { zhCN } from './zh-CN.js'\r\nimport { enUS } from './en-US.js'\r\n\r\n/**\r\n * 国际化工具 - 提供多语言支持\r\n */\r\n\r\n// 语言包映射\r\nconst messages: Record<Locale, typeof zhCN> = {\r\n 'zh-CN': zhCN,\r\n 'en-US': enUS\r\n}\r\n\r\n// 当前语言缓存\r\nlet currentLocale: Locale | null = null\r\nlet currentMessages: typeof zhCN | null = null\r\n\r\n/**\r\n * 初始化 i18n\r\n */\r\nasync function initI18n(): Promise<void> {\r\n if (!currentLocale) {\r\n currentLocale = await getLocale()\r\n currentMessages = messages[currentLocale]\r\n }\r\n}\r\n\r\n/**\r\n * 翻译函数 - 根据键路径获取翻译文本\r\n * @param key - 翻译键,支持点分隔的路径,如 'login.title'\r\n * @param params - 替换参数对象\r\n * @returns 翻译后的文本\r\n */\r\nexport async function t(key: string, params?: Record<string, string | number>): Promise<string> {\r\n await initI18n()\r\n\r\n // 通过点分隔的路径获取嵌套值\r\n const keys = key.split('.')\r\n let value: any = currentMessages\r\n\r\n for (const k of keys) {\r\n if (value && typeof value === 'object' && k in value) {\r\n value = value[k]\r\n } else {\r\n // 如果找不到翻译,返回 key 本身\r\n return key\r\n }\r\n }\r\n\r\n // 如果不是字符串,返回 key\r\n if (typeof value !== 'string') {\r\n return key\r\n }\r\n\r\n // 替换参数\r\n if (params) {\r\n return value.replace(/\\{(\\w+)\\}/g, (match, paramKey) => {\r\n return paramKey in params ? String(params[paramKey]) : match\r\n })\r\n }\r\n\r\n return value\r\n}\r\n\r\n/**\r\n * 同步翻译函数(需要先初始化)\r\n * @param key - 翻译键\r\n * @param params - 替换参数对象\r\n * @returns 翻译后的文本\r\n */\r\nexport function tSync(key: string, params?: Record<string, string | number>): string {\r\n if (!currentMessages) {\r\n // 如果未初始化,返回 key\r\n return key\r\n }\r\n\r\n const keys = key.split('.')\r\n let value: any = currentMessages\r\n\r\n for (const k of keys) {\r\n if (value && typeof value === 'object' && k in value) {\r\n value = value[k]\r\n } else {\r\n return key\r\n }\r\n }\r\n\r\n if (typeof value !== 'string') {\r\n return key\r\n }\r\n\r\n if (params) {\r\n return value.replace(/\\{(\\w+)\\}/g, (match, paramKey) => {\r\n return paramKey in params ? String(params[paramKey]) : match\r\n })\r\n }\r\n\r\n return value\r\n}\r\n\r\n/**\r\n * 获取当前语言\r\n */\r\nexport async function getCurrentLocale(): Promise<Locale> {\r\n await initI18n()\r\n return currentLocale!\r\n}\r\n\r\n/**\r\n * 重新加载语言配置(切换语言后调用)\r\n */\r\nexport async function reloadLocale(): Promise<void> {\r\n currentLocale = null\r\n currentMessages = null\r\n await initI18n()\r\n}\r\n\r\n/**\r\n * 获取完整的语言包(用于类型提示)\r\n */\r\nexport function getMessages() {\r\n return currentMessages || zhCN\r\n}\r\n","import { Command } from 'commander'\r\nimport inquirer from 'inquirer'\r\nimport chalk from 'chalk'\r\nimport ora from 'ora'\r\nimport { apiClient } from '../api/client.js'\r\nimport { logger, CLIError } from '../utils/logger.js'\r\nimport { isLoggedIn } from '../config/token.js'\r\nimport { type AiIdeType } from '../utils/ide-mapper.js'\r\nimport { searchByName, paginate } from '../utils/pagination.js'\r\nimport { applySolution } from '../apply/writer.js'\r\nimport type { Solution } from '../types/index.js'\r\nimport { t } from '../i18n/index.js'\r\n\r\n/**\r\n * acp apply 命令\r\n * 拉取并应用配置到本地项目\r\n */\r\n\r\ntype ResourceType = 'solution' | 'agent' | 'prompt' | 'mcp'\r\n\r\nexport const applyCommand = new Command('apply')\r\n .description('拉取并应用配置到本地项目 / Fetch and apply configurations to local project')\r\n .option('-t, --type <type>', '资源类型 (solution|agent|prompt|mcp) / Resource type', 'solution')\r\n .option('-i, --ide <ide>', 'AI IDE 类型 / AI IDE type (vscode|cursor|codex|claude-code)')\r\n .option('-d, --dir <path>', '目标目录 / Target directory', process.cwd())\r\n .action(async (options) => {\r\n try {\r\n // 检查登录状态\r\n if (!(await isLoggedIn())) {\r\n throw new CLIError(\r\n await t('apply.notLoggedIn'),\r\n 'NOT_LOGGED_IN',\r\n [await t('apply.loginFirst')]\r\n )\r\n }\r\n\r\n logger.title(await t('apply.title'))\r\n\r\n // 1. 选择资源类型\r\n const resourceType = await selectResourceType(options.type)\r\n\r\n // 2. 根据类型拉取并选择资源\r\n let selectedSolution: Solution | null = null\r\n\r\n if (resourceType === 'solution') {\r\n selectedSolution = await fetchAndSelectSolution()\r\n } else {\r\n throw new CLIError(await t('apply.notSupported'))\r\n }\r\n\r\n if (!selectedSolution) {\r\n logger.info(await t('apply.noSelection'))\r\n return\r\n }\r\n\r\n // 3. 选择 IDE 类型\r\n const ide = options.ide || (await selectIde())\r\n\r\n // 4. 应用配置\r\n await applySolution(selectedSolution, {\r\n ide: ide as AiIdeType,\r\n targetDir: options.dir\r\n })\r\n\r\n const appliedMsg = await t('apply.applied')\r\n console.log(chalk.gray(`\\n${appliedMsg} ${chalk.cyan(options.dir)}\\n`))\r\n } catch (error) {\r\n if (error instanceof Error) {\r\n logger.error(error.message)\r\n }\r\n process.exit(1)\r\n }\r\n })\r\n\r\n/**\r\n * 选择资源类型\r\n */\r\nasync function selectResourceType(defaultType?: string): Promise<ResourceType> {\r\n if (defaultType && ['solution', 'agent', 'prompt', 'mcp'].includes(defaultType)) {\r\n return defaultType as ResourceType\r\n }\r\n\r\n const { type } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'type',\r\n message: await t('apply.selectResourceType'),\r\n choices: [\r\n { name: chalk.cyan(await t('apply.resourceTypes.solution')), value: 'solution' },\r\n { name: chalk.gray(await t('apply.resourceTypes.agent')), value: 'agent', disabled: true },\r\n { name: chalk.gray(await t('apply.resourceTypes.prompt')), value: 'prompt', disabled: true },\r\n { name: chalk.gray(await t('apply.resourceTypes.mcp')), value: 'mcp', disabled: true }\r\n ],\r\n default: 'solution'\r\n }\r\n ])\r\n\r\n return type\r\n}\r\n\r\n/**\r\n * 拉取并选择解决方案\r\n */\r\nasync function fetchAndSelectSolution(): Promise<Solution | null> {\r\n const spinner = ora(await t('apply.fetching')).start()\r\n\r\n try {\r\n // 1. 拉取解决方案列表\r\n const response = await apiClient.getSolutions()\r\n spinner.stop()\r\n\r\n if (!response.data || response.data.length === 0) {\r\n logger.warning(await t('apply.noSolutions'))\r\n return null\r\n }\r\n\r\n logger.success(await t('apply.fetchSuccess', { count: response.data.length }))\r\n\r\n // 2. 搜索过滤\r\n const { searchQuery } = await inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'searchQuery',\r\n message: await t('apply.searchPrompt'),\r\n default: ''\r\n }\r\n ])\r\n\r\n let filteredSolutions = searchByName(response.data, searchQuery)\r\n\r\n if (filteredSolutions.length === 0) {\r\n logger.warning(await t('apply.noMatch'))\r\n return null\r\n }\r\n\r\n // 3. 分页显示\r\n const PAGE_SIZE = 20\r\n let currentPage = 1\r\n let selectedSolution: Solution | null = null\r\n\r\n while (!selectedSolution) {\r\n const paginatedResult = paginate(filteredSolutions, {\r\n page: currentPage,\r\n pageSize: PAGE_SIZE\r\n })\r\n\r\n // 构建选择列表\r\n const choices = paginatedResult.items.map((solution) => ({\r\n name: `${chalk.cyan(solution.name)} ${chalk.yellow(`@${solution.author.username}`)} - ${chalk.gray(solution.description)}`,\r\n value: solution.id,\r\n short: solution.name\r\n }))\r\n\r\n // 添加分页控制选项\r\n if (paginatedResult.hasNext) {\r\n choices.push({\r\n name: chalk.yellow(await t('apply.nextPage')),\r\n value: '__NEXT_PAGE__',\r\n short: await t('apply.nextPage')\r\n })\r\n }\r\n\r\n if (paginatedResult.hasPrev) {\r\n choices.unshift({\r\n name: chalk.yellow(await t('apply.prevPage')),\r\n value: '__PREV_PAGE__',\r\n short: await t('apply.prevPage')\r\n })\r\n }\r\n\r\n choices.push({\r\n name: chalk.red(await t('apply.cancel')),\r\n value: '__CANCEL__',\r\n short: await t('apply.cancel')\r\n })\r\n\r\n const { selected } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'selected',\r\n message: await t('apply.selectSolutionPage', { \r\n current: currentPage, \r\n total: paginatedResult.totalPages \r\n }),\r\n choices,\r\n pageSize: 15\r\n }\r\n ])\r\n\r\n if (selected === '__CANCEL__') {\r\n return null\r\n } else if (selected === '__NEXT_PAGE__') {\r\n currentPage++\r\n } else if (selected === '__PREV_PAGE__') {\r\n currentPage--\r\n } else {\r\n // 获取详情\r\n const detailSpinner = ora(await t('apply.fetchingDetail')).start()\r\n const detailResponse = await apiClient.getSolutionById(selected)\r\n detailSpinner.stop()\r\n\r\n selectedSolution = detailResponse.data\r\n }\r\n }\r\n\r\n return selectedSolution\r\n } catch (error) {\r\n spinner.fail(await t('apply.fetchDetailFailed'))\r\n throw error\r\n }\r\n}\r\n\r\n/**\r\n * 选择 IDE 类型\r\n */\r\nasync function selectIde(): Promise<AiIdeType> {\r\n const { ide } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'ide',\r\n message: await t('apply.selectIde'),\r\n choices: [\r\n { name: chalk.cyan(await t('apply.ideTypes.vscode')), value: 'vscode' },\r\n { name: chalk.cyan(await t('apply.ideTypes.cursor')), value: 'cursor' },\r\n { name: chalk.cyan(await t('apply.ideTypes.codex')), value: 'codex' },\r\n { name: chalk.cyan(await t('apply.ideTypes.claudeCode')), value: 'claude-code' }\r\n ],\r\n default: 'vscode'\r\n }\r\n ])\r\n\r\n return ide\r\n}\r\n","import axios, { AxiosInstance, AxiosError } from 'axios'\r\nimport { getToken, getBaseUrl } from '../config/token.js'\r\nimport type {\r\n ApiResponse,\r\n Solution,\r\n AgentConfig,\r\n Prompt,\r\n McpConfig\r\n} from '../types/index.js'\r\n\r\n/**\r\n * API 客户端封装\r\n */\r\n\r\nclass ApiClient {\r\n private client: AxiosInstance\r\n private baseUrlPromise: Promise<string>\r\n\r\n constructor() {\r\n // 异步获取 BASE_URL\r\n this.baseUrlPromise = getBaseUrl()\r\n\r\n this.client = axios.create({\r\n timeout: 30000,\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n }\r\n })\r\n\r\n // 请求拦截器:自动添加 token 和 baseURL\r\n this.client.interceptors.request.use(async (config) => {\r\n // 设置 baseURL\r\n if (!config.baseURL) {\r\n config.baseURL = await this.baseUrlPromise\r\n }\r\n\r\n // 添加 token\r\n const token = await getToken()\r\n if (token) {\r\n config.headers['X-CLI-TOKEN'] = token\r\n }\r\n return config\r\n })\r\n\r\n // 响应拦截器:统一错误处理\r\n this.client.interceptors.response.use(\r\n (response) => response,\r\n (error: AxiosError) => {\r\n if (error.response) {\r\n const status = error.response.status\r\n const message = (error.response.data as any)?.message || error.message\r\n\r\n if (status === 401) {\r\n throw new Error('认证失败,请先执行 acp login 登录')\r\n } else if (status === 403) {\r\n throw new Error('权限不足,请检查 token 是否有效')\r\n } else if (status === 404) {\r\n throw new Error('请求的资源不存在')\r\n } else if (status >= 500) {\r\n throw new Error(`服务器错误 (${status}): ${message}`)\r\n } else {\r\n throw new Error(`请求失败 (${status}): ${message}`)\r\n }\r\n } else if (error.request) {\r\n throw new Error('网络错误,请检查网络连接')\r\n } else {\r\n throw new Error(`请求配置错误: ${error.message}`)\r\n }\r\n }\r\n )\r\n }\r\n\r\n /**\r\n * 获取解决方案列表\r\n */\r\n async getSolutions(aiTool?: string): Promise<ApiResponse<Solution[]>> {\r\n const params = aiTool ? { aiTool } : {}\r\n const response = await this.client.get<ApiResponse<Solution[]>>(\r\n '/api/cli/solutions',\r\n { params }\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取解决方案详情\r\n */\r\n async getSolutionById(id: string): Promise<ApiResponse<Solution>> {\r\n const response = await this.client.get<ApiResponse<Solution>>(\r\n `/api/cli/solutions/${id}`\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 Agent 配置列表\r\n */\r\n async getAgents(): Promise<ApiResponse<AgentConfig[]>> {\r\n const response = await this.client.get<ApiResponse<AgentConfig[]>>(\r\n '/api/cli/agents'\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 Agent 配置详情\r\n */\r\n async getAgentById(id: string): Promise<ApiResponse<AgentConfig>> {\r\n const response = await this.client.get<ApiResponse<AgentConfig>>(\r\n `/api/cli/agents/${id}`\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 Prompt 列表\r\n */\r\n async getPrompts(): Promise<ApiResponse<Prompt[]>> {\r\n const response = await this.client.get<ApiResponse<Prompt[]>>(\r\n '/api/cli/prompts'\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 Prompt 详情\r\n */\r\n async getPromptById(id: string): Promise<ApiResponse<Prompt>> {\r\n const response = await this.client.get<ApiResponse<Prompt>>(\r\n `/api/cli/prompts/${id}`\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 MCP 配置列表\r\n */\r\n async getMcps(): Promise<ApiResponse<McpConfig[]>> {\r\n const response = await this.client.get<ApiResponse<McpConfig[]>>(\r\n '/api/cli/mcps'\r\n )\r\n return response.data\r\n }\r\n\r\n /**\r\n * 获取 MCP 配置详情\r\n */\r\n async getMcpById(id: string): Promise<ApiResponse<McpConfig>> {\r\n const response = await this.client.get<ApiResponse<McpConfig>>(\r\n `/api/cli/mcps/${id}`\r\n )\r\n return response.data\r\n }\r\n}\r\n\r\n// 导出单例\r\nexport const apiClient = new ApiClient()\r\n","/**\r\n * 分页工具函数\r\n */\r\n\r\nexport interface PaginationOptions {\r\n page: number\r\n pageSize: number\r\n}\r\n\r\nexport interface PaginationResult<T> {\r\n items: T[]\r\n total: number\r\n page: number\r\n pageSize: number\r\n totalPages: number\r\n hasNext: boolean\r\n hasPrev: boolean\r\n}\r\n\r\n/**\r\n * 对数组进行分页\r\n */\r\nexport function paginate<T>(\r\n items: T[],\r\n options: PaginationOptions\r\n): PaginationResult<T> {\r\n const { page, pageSize } = options\r\n const total = items.length\r\n const totalPages = Math.ceil(total / pageSize)\r\n const startIndex = (page - 1) * pageSize\r\n const endIndex = startIndex + pageSize\r\n\r\n return {\r\n items: items.slice(startIndex, endIndex),\r\n total,\r\n page,\r\n pageSize,\r\n totalPages,\r\n hasNext: page < totalPages,\r\n hasPrev: page > 1\r\n }\r\n}\r\n\r\n/**\r\n * 按名称搜索(不区分大小写)\r\n */\r\nexport function searchByName<T extends { name: string }>(\r\n items: T[],\r\n query: string\r\n): T[] {\r\n if (!query.trim()) {\r\n return items\r\n }\r\n\r\n const lowerQuery = query.toLowerCase().trim()\r\n return items.filter((item) =>\r\n item.name.toLowerCase().includes(lowerQuery)\r\n )\r\n}\r\n","import fs from 'fs-extra'\r\nimport path from 'path'\r\nimport chalk from 'chalk'\r\nimport inquirer from 'inquirer'\r\nimport { logger } from '../utils/logger.js'\r\nimport { getIdePathMapping, type AiIdeType } from '../utils/ide-mapper.js'\r\nimport type { Solution, Prompt, McpConfig, Skill } from '../types/index.js'\r\n\r\n/**\r\n * 配置应用模块 - 将远程配置写入本地文件\r\n */\r\n\r\nexport interface ApplyOptions {\r\n ide: AiIdeType\r\n targetDir: string\r\n}\r\n\r\n/**\r\n * 应用解决方案配置\r\n */\r\nexport async function applySolution(\r\n solution: Solution,\r\n options: ApplyOptions\r\n): Promise<void> {\r\n const { ide, targetDir } = options\r\n const pathMapping = getIdePathMapping(ide)\r\n\r\n logger.title(`📦 应用解决方案: ${chalk.cyan(solution.name)}`)\r\n\r\n // 1. 应用 Agent 配置\r\n if (solution.agentConfig) {\r\n await applyAgentConfig(\r\n solution.agentConfig.content,\r\n pathMapping.agents,\r\n targetDir\r\n )\r\n }\r\n\r\n // 2. 应用 Prompts\r\n if (solution.customPrompts?.length) {\r\n await applyPrompts(\r\n solution.customPrompts,\r\n pathMapping.prompts,\r\n targetDir\r\n )\r\n }\r\n\r\n // 3. 应用 MCP 配置\r\n if (solution.mcpConfigs?.length) {\r\n await applyMcpConfigs(\r\n solution.mcpConfigs,\r\n pathMapping.mcp,\r\n targetDir\r\n )\r\n }\r\n\r\n // 4. 应用 Skills\r\n if (solution.skills?.length) {\r\n await applySkills(\r\n solution.skills,\r\n pathMapping.skills,\r\n targetDir\r\n )\r\n }\r\n\r\n logger.success(`\\n✨ 解决方案 ${chalk.cyan(solution.name)} 应用成功!`)\r\n}\r\n\r\n/**\r\n * 应用 Agent 配置\r\n */\r\nexport async function applyAgentConfig(\r\n content: string,\r\n relativePath: string,\r\n targetDir: string\r\n): Promise<void> {\r\n const filePath = path.join(targetDir, relativePath)\r\n\r\n logger.step(`写入 Agent 配置: ${chalk.gray(relativePath)}`)\r\n\r\n // 检查文件是否存在\r\n const exists = await fs.pathExists(filePath)\r\n if (exists) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: `文件 ${chalk.cyan(relativePath)} 已存在,是否覆盖?`,\r\n default: true\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.warning(`跳过: ${relativePath}`)\r\n return\r\n }\r\n }\r\n\r\n // 写入文件\r\n await fs.ensureDir(path.dirname(filePath))\r\n await fs.writeFile(filePath, content, 'utf-8')\r\n\r\n logger.success(`已写入: ${relativePath}`)\r\n}\r\n\r\n/**\r\n * 应用 Prompts\r\n */\r\nexport async function applyPrompts(\r\n prompts: Prompt[],\r\n promptsDir: string,\r\n targetDir: string\r\n): Promise<void> {\r\n const fullPromptsDir = path.join(targetDir, promptsDir)\r\n\r\n logger.step(`写入 ${prompts.length} 个 Prompt 配置到: ${chalk.gray(promptsDir)}`)\r\n\r\n // 确保目录存在\r\n await fs.ensureDir(fullPromptsDir)\r\n\r\n for (const prompt of prompts) {\r\n // 生成文件名(清理特殊字符)\r\n const fileName = sanitizeFileName(prompt.name) + '.prompt.md'\r\n const filePath = path.join(fullPromptsDir, fileName)\r\n\r\n // 检查是否存在\r\n const exists = await fs.pathExists(filePath)\r\n if (exists) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: `Prompt ${chalk.cyan(fileName)} 已存在,是否覆盖?`,\r\n default: true\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.warning(`跳过: ${fileName}`)\r\n continue\r\n }\r\n }\r\n\r\n // 写入内容\r\n await fs.writeFile(filePath, prompt.content, 'utf-8')\r\n logger.success(`已写入: ${path.join(promptsDir, fileName)}`)\r\n }\r\n}\r\n\r\n/**\r\n * 应用 MCP 配置\r\n */\r\nexport async function applyMcpConfigs(\r\n mcpConfigs: McpConfig[],\r\n mcpFile: string,\r\n targetDir: string\r\n): Promise<void> {\r\n const filePath = path.join(targetDir, mcpFile)\r\n\r\n logger.step(`写入 MCP 配置: ${chalk.gray(mcpFile)}`)\r\n\r\n // 构造 mcpServers 结构\r\n const mcpServers: Record<string, any> = {}\r\n\r\n for (const mcpConfig of mcpConfigs) {\r\n try {\r\n const config = JSON.parse(mcpConfig.configJson)\r\n // 使用 MCP 配置的名称作为 key\r\n mcpServers[mcpConfig.name] = config\r\n } catch (error) {\r\n logger.warning(`MCP 配置 ${mcpConfig.name} 格式错误,已跳过`)\r\n }\r\n }\r\n\r\n // 检查文件是否存在\r\n const exists = await fs.pathExists(filePath)\r\n if (exists) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: `文件 ${chalk.cyan(mcpFile)} 已存在,是否覆盖?`,\r\n default: true\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.warning(`跳过: ${mcpFile}`)\r\n return\r\n }\r\n }\r\n\r\n // 写入文件\r\n await fs.ensureDir(path.dirname(filePath))\r\n\r\n // 根据文件扩展名和路径决定输出格式\r\n if (mcpFile.endsWith('.toml')) {\r\n // Codex 使用 TOML 格式\r\n const tomlContent = convertMcpToToml(mcpServers)\r\n await fs.writeFile(filePath, tomlContent, 'utf-8')\r\n } else {\r\n // JSON 格式\r\n let mergedConfig: Record<string, any>\r\n \r\n // VS Code 使用 \"servers\",其他 IDE 使用 \"mcpServers\"\r\n if (mcpFile.includes('.vscode')) {\r\n mergedConfig = {\r\n servers: mcpServers\r\n }\r\n } else {\r\n mergedConfig = {\r\n mcpServers\r\n }\r\n }\r\n \r\n await fs.writeFile(filePath, JSON.stringify(mergedConfig, null, 2), 'utf-8')\r\n }\r\n\r\n logger.success(`已写入: ${mcpFile}`)\r\n}\r\n\r\n/**\r\n * 将 MCP 配置转换为 TOML 格式(用于 Codex)\r\n */\r\nfunction convertMcpToToml(mcpServers: Record<string, any>): string {\r\n let tomlContent = ''\r\n\r\n for (const [serverName, config] of Object.entries(mcpServers)) {\r\n tomlContent += `[mcp_servers.${serverName}]\\n`\r\n \r\n // 写入 command\r\n if (config.command) {\r\n tomlContent += `command = ${JSON.stringify(config.command)}\\n`\r\n }\r\n\r\n // 写入 args\r\n if (config.args && Array.isArray(config.args)) {\r\n const argsStr = config.args.map((arg: string) => JSON.stringify(arg)).join(', ')\r\n tomlContent += `args = [${argsStr}]\\n`\r\n }\r\n\r\n // 写入 env\r\n if (config.env && typeof config.env === 'object') {\r\n const envEntries = Object.entries(config.env)\r\n if (envEntries.length > 0) {\r\n const envStr = envEntries\r\n .map(([key, value]) => `${key} = ${JSON.stringify(value)}`)\r\n .join(', ')\r\n tomlContent += `env = { ${envStr} }\\n`\r\n }\r\n }\r\n\r\n tomlContent += '\\n'\r\n }\r\n\r\n return tomlContent\r\n}\r\n\r\n/**\r\n * 应用 Skills\r\n */\r\nexport async function applySkills(\r\n skills: Skill[],\r\n skillsDir: string,\r\n targetDir: string\r\n): Promise<void> {\r\n const fullSkillsDir = path.join(targetDir, skillsDir)\r\n\r\n logger.step(`写入 ${skills.length} 个 Skill 配置到: ${chalk.gray(skillsDir)}`)\r\n\r\n // 确保目录存在\r\n await fs.ensureDir(fullSkillsDir)\r\n\r\n for (const skill of skills) {\r\n // 生成目录名(清理特殊字符)\r\n const skillDirName = sanitizeSkillName(skill.name)\r\n const skillDirPath = path.join(fullSkillsDir, skillDirName)\r\n\r\n logger.step(`处理 Skill: ${chalk.cyan(skill.name)}`)\r\n\r\n // 检查目录是否存在\r\n const dirExists = await fs.pathExists(skillDirPath)\r\n if (dirExists) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: `Skill 目录 ${chalk.cyan(skillDirName)} 已存在,是否覆盖?`,\r\n default: true\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.warning(`跳过: ${skillDirName}`)\r\n continue\r\n }\r\n }\r\n\r\n // 确保目录存在\r\n await fs.ensureDir(skillDirPath)\r\n\r\n // 1. 创建 SKILL.md 文件\r\n const skillMdPath = path.join(skillDirPath, 'SKILL.md')\r\n await fs.writeFile(skillMdPath, skill.skillMarkdown, 'utf-8')\r\n logger.success(`已写入: ${path.join(skillsDir, skillDirName, 'SKILL.md')}`)\r\n\r\n // 2. 处理 SkillResources\r\n if (skill.skillResources && skill.skillResources.length > 0) {\r\n for (const resource of skill.skillResources) {\r\n // 确保相对路径安全(防止路径遍历攻击)\r\n const safeRelativePath = sanitizePath(resource.relativePath)\r\n const resourceFilePath = path.join(skillDirPath, safeRelativePath)\r\n\r\n // 检查文件是否存在\r\n const fileExists = await fs.pathExists(resourceFilePath)\r\n if (fileExists) {\r\n const { overwrite } = await inquirer.prompt([\r\n {\r\n type: 'confirm',\r\n name: 'overwrite',\r\n message: `文件 ${chalk.cyan(path.join(skillDirName, safeRelativePath))} 已存在,是否覆盖?`,\r\n default: true\r\n }\r\n ])\r\n\r\n if (!overwrite) {\r\n logger.warning(`跳过: ${path.join(skillDirName, safeRelativePath)}`)\r\n continue\r\n }\r\n }\r\n\r\n // 确保父目录存在\r\n await fs.ensureDir(path.dirname(resourceFilePath))\r\n\r\n // 写入文件内容\r\n await fs.writeFile(resourceFilePath, resource.fileContent, 'utf-8')\r\n logger.success(`已写入: ${path.join(skillsDir, skillDirName, safeRelativePath)}`)\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 清理 skill 名称,用于创建目录名\r\n */\r\nfunction sanitizeSkillName(name: string): string {\r\n return name\r\n .replace(/[<>:\"/\\\\|?*]/g, '-') // 替换非法字符\r\n .replace(/\\s+/g, '-') // 空格转连字符\r\n .replace(/-+/g, '-') // 多个连字符合并\r\n .replace(/^-+|-+$/g, '') // 移除首尾连字符\r\n .toLowerCase()\r\n}\r\n\r\n/**\r\n * 清理路径,防止路径遍历攻击\r\n */\r\nfunction sanitizePath(relativePath: string): string {\r\n // 移除路径遍历攻击(如 ../, ..\\, 等)\r\n let safePath = relativePath\r\n .replace(/\\.\\./g, '') // 移除 ..\r\n .replace(/^[/\\\\]+/, '') // 移除开头的 / 或 \\\r\n .replace(/[/\\\\]+/g, path.sep) // 统一路径分隔符\r\n\r\n // 确保路径是相对路径,不包含绝对路径\r\n if (path.isAbsolute(safePath)) {\r\n safePath = path.relative('/', safePath)\r\n }\r\n\r\n // 移除 Windows 驱动器号(如 C:)\r\n if (safePath.match(/^[A-Za-z]:/)) {\r\n safePath = safePath.substring(2)\r\n }\r\n\r\n return safePath\r\n}\r\n\r\n/**\r\n * 清理文件名中的特殊字符\r\n */\r\nfunction sanitizeFileName(name: string): string {\r\n return name\r\n .replace(/[<>:\"/\\\\|?*]/g, '-') // 替换非法字符\r\n .replace(/\\s+/g, '-') // 空格转连字符\r\n .replace(/-+/g, '-') // 多个连字符合并\r\n .toLowerCase()\r\n}\r\n","import type { AiIdeType, IdePathMapping } from '../types/index.js'\r\n\r\n// 重新导出类型\r\nexport type { AiIdeType, IdePathMapping }\r\n\r\n/**\r\n * AI IDE 路径映射配置\r\n * 定义不同 IDE 的配置文件输出路径\r\n */\r\n\r\nexport const IDE_PATH_MAPPINGS: Record<AiIdeType, IdePathMapping> = {\r\n vscode: {\r\n prompts: '.github/prompts',\r\n agents: 'AGENTS.md',\r\n mcp: '.vscode/mcp.json',\r\n skills: '.github/skills'\r\n },\r\n cursor: {\r\n prompts: '.cursor/commands',\r\n agents: 'AGENTS.md',\r\n mcp: '.cursor/mcp.json',\r\n skills: '.cursor/skills'\r\n },\r\n codex: {\r\n prompts: '~/.codex/prompts',\r\n agents: 'AGENTS.md',\r\n mcp: '.codex/config.toml',\r\n skills: '.codex/skills'\r\n },\r\n 'claude-code': {\r\n prompts: '.claude/commands',\r\n agents: 'AGENTS.md',\r\n mcp: '.mcp.json',\r\n skills: '.claude/skills'\r\n }\r\n}\r\n\r\n/**\r\n * 获取 IDE 路径映射\r\n */\r\nexport function getIdePathMapping(ide: AiIdeType): IdePathMapping {\r\n return IDE_PATH_MAPPINGS[ide]\r\n}\r\n\r\n/**\r\n * 获取所有支持的 IDE 列表\r\n */\r\nexport function getSupportedIdes(): AiIdeType[] {\r\n return Object.keys(IDE_PATH_MAPPINGS) as AiIdeType[]\r\n}\r\n\r\n/**\r\n * 验证 IDE 类型是否支持\r\n */\r\nexport function isValidIde(ide: string): ide is AiIdeType {\r\n return ide in IDE_PATH_MAPPINGS\r\n}\r\n","import { Command } from 'commander'\r\nimport inquirer from 'inquirer'\r\nimport chalk from 'chalk'\r\nimport { getLocale, saveLocale, getSupportedLocales, getLocaleName, type Locale } from '../config/locale.js'\r\nimport { t } from '../i18n/index.js'\r\nimport { logger } from '../utils/logger.js'\r\n\r\n/**\r\n * acp locale 命令\r\n * 切换 CLI 语言\r\n */\r\n\r\nexport const localeCommand = new Command('locale')\r\n .description('切换 CLI 语言 / Switch CLI language')\r\n .action(async () => {\r\n try {\r\n // 获取当前语言\r\n const currentLocale = await getLocale()\r\n \r\n // 显示标题\r\n const title = await t('locale.title')\r\n logger.title(title)\r\n\r\n // 显示当前语言\r\n const currentText = await t('locale.current')\r\n console.log(chalk.gray(`${currentText}: `) + chalk.cyan(getLocaleName(currentLocale)))\r\n console.log()\r\n\r\n // 选择新语言\r\n const supportedLocales = getSupportedLocales()\r\n const selectText = await t('locale.selectLanguage')\r\n \r\n const { newLocale } = await inquirer.prompt([\r\n {\r\n type: 'list',\r\n name: 'newLocale',\r\n message: selectText,\r\n choices: supportedLocales.map(locale => ({\r\n name: locale === currentLocale \r\n ? chalk.cyan(`${getLocaleName(locale)} (当前 / Current)`)\r\n : getLocaleName(locale),\r\n value: locale\r\n })),\r\n default: currentLocale\r\n }\r\n ])\r\n\r\n // 如果选择的是当前语言,则不做任何操作\r\n if (newLocale === currentLocale) {\r\n logger.info(`${await t('locale.current')}: ${getLocaleName(currentLocale)}`)\r\n return\r\n }\r\n\r\n // 保存新语言\r\n await saveLocale(newLocale as Locale)\r\n\r\n // 显示成功消息(使用新语言)\r\n // 注意:这里需要手动构造消息,因为 t() 函数还在使用旧语言缓存\r\n if (newLocale === 'zh-CN') {\r\n logger.success(`语言已切换为 ${getLocaleName(newLocale)}`)\r\n console.log(chalk.gray('\\n提示: 已生效,新命令将使用所选语言\\n'))\r\n } else {\r\n logger.success(`Language switched to ${getLocaleName(newLocale)}`)\r\n console.log(chalk.gray('\\nTip: Changes take effect immediately for new commands\\n'))\r\n }\r\n\r\n } catch (error) {\r\n if (error instanceof Error) {\r\n logger.error(`${await t('locale.failed')}: ${error.message}`)\r\n }\r\n process.exit(1)\r\n }\r\n })\r\n"],"mappings":"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","names":["Command","chalk","chalk","fs","path","os","CONFIG_DIR","chalk","Command","inquirer","chalk","fs","path","chalk","inquirer","chalk","path","fs","inquirer","Command","chalk","inquirer","Command","inquirer","chalk","Command","currentLocale","chalk","inquirer","Command","chalk"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-config-plaza/acp-cli",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "AI-Config-Plaza CLI 工具 - 统一 AI 编程工具配置管理",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",