aico-cli 2.0.36 → 2.0.37

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.
@@ -14,7 +14,7 @@ import { join, dirname, basename } from 'pathe';
14
14
  import { fileURLToPath } from 'node:url';
15
15
  import { EventEmitter } from 'node:events';
16
16
 
17
- const version = "2.0.36";
17
+ const version = "2.0.37";
18
18
 
19
19
  function displayBanner(subtitle) {
20
20
  const defaultSubtitle = "\u4E00\u952E\u914D\u7F6E\u4F60\u7684\u5F00\u53D1\u73AF\u5883";
@@ -3217,6 +3217,34 @@ const CLAUDE_MD_FILE = join(CLAUDE_DIR, "CLAUDE.md");
3217
3217
  const ClAUDE_CONFIG_FILE = join(homedir(), ".claude.json");
3218
3218
  const LEGACY_AICO_CONFIG_FILE = join(homedir(), ".aico.json");
3219
3219
  const AICO_CONFIG_FILE = join(CLAUDE_DIR, ".aico-config.json");
3220
+ const TARGET_CONFIGS = {
3221
+ claude: {
3222
+ dirName: ".claude",
3223
+ mainConfigFile: "CLAUDE.md",
3224
+ settingsFile: "settings.json"
3225
+ // 无需重命名
3226
+ },
3227
+ codebuddy: {
3228
+ dirName: ".codebuddy",
3229
+ mainConfigFile: "CODEBUDDY.md",
3230
+ settingsFile: "settings.json",
3231
+ fileRenames: {
3232
+ "CLAUDE.md": "CODEBUDDY.md"
3233
+ }
3234
+ }
3235
+ };
3236
+ function getTargetDir(target = "claude") {
3237
+ return join(homedir(), TARGET_CONFIGS[target].dirName);
3238
+ }
3239
+ function getTargetSettingsFile(target = "claude") {
3240
+ return join(getTargetDir(target), TARGET_CONFIGS[target].settingsFile);
3241
+ }
3242
+ function getTargetMainConfigFile(target = "claude") {
3243
+ return join(getTargetDir(target), TARGET_CONFIGS[target].mainConfigFile);
3244
+ }
3245
+ function getTargetAicoConfigFile(target = "claude") {
3246
+ return join(getTargetDir(target), ".aico-config.json");
3247
+ }
3220
3248
  const SUPPORTED_LANGS = ["zh-CN"];
3221
3249
  const LANG_LABELS = {
3222
3250
  "zh-CN": "\u7B80\u4F53\u4E2D\u6587"
@@ -3753,18 +3781,19 @@ function updateAicoConfig(updates) {
3753
3781
  writeAicoConfig(newConfig);
3754
3782
  }
3755
3783
 
3756
- function getMcpConfigPath() {
3757
- return ClAUDE_CONFIG_FILE;
3784
+ function getMcpConfigPath(target = "claude") {
3785
+ const configFileName = target === "claude" ? ".claude.json" : `.${target}.json`;
3786
+ return join(homedir(), configFileName);
3758
3787
  }
3759
- function readMcpConfig() {
3760
- return readJsonConfig(ClAUDE_CONFIG_FILE);
3788
+ function readMcpConfig(target = "claude") {
3789
+ return readJsonConfig(getMcpConfigPath(target));
3761
3790
  }
3762
- function writeMcpConfig(config) {
3763
- writeJsonConfig(ClAUDE_CONFIG_FILE, config);
3791
+ function writeMcpConfig(config, target = "claude") {
3792
+ writeJsonConfig(getMcpConfigPath(target), config);
3764
3793
  }
3765
- function backupMcpConfig() {
3766
- const backupBaseDir = join(CLAUDE_DIR, "backup");
3767
- return backupJsonConfig(ClAUDE_CONFIG_FILE, backupBaseDir);
3794
+ function backupMcpConfig(target = "claude") {
3795
+ const backupBaseDir = join(getTargetDir(target), "backup");
3796
+ return backupJsonConfig(getMcpConfigPath(target), backupBaseDir);
3768
3797
  }
3769
3798
  function mergeMcpServers(existing, newServers) {
3770
3799
  const config = existing || { mcpServers: {} };
@@ -3811,9 +3840,9 @@ function fixWindowsMcpConfig(config) {
3811
3840
  }
3812
3841
  return fixed;
3813
3842
  }
3814
- function updateClaudeConfigEnv(envVars) {
3843
+ function updateClaudeConfigEnv(envVars, target = "claude") {
3815
3844
  try {
3816
- let config = readMcpConfig();
3845
+ let config = readMcpConfig(target);
3817
3846
  if (!config) {
3818
3847
  config = { mcpServers: {} };
3819
3848
  }
@@ -3821,15 +3850,15 @@ function updateClaudeConfigEnv(envVars) {
3821
3850
  config.env = {};
3822
3851
  }
3823
3852
  Object.assign(config.env, envVars);
3824
- writeMcpConfig(config);
3853
+ writeMcpConfig(config, target);
3825
3854
  } catch (error) {
3826
- console.error("Failed to update Claude config env", error);
3855
+ console.error("Failed to update config env", error);
3827
3856
  throw error;
3828
3857
  }
3829
3858
  }
3830
- function addCompletedOnboarding() {
3859
+ function addCompletedOnboarding(target = "claude") {
3831
3860
  try {
3832
- let config = readMcpConfig();
3861
+ let config = readMcpConfig(target);
3833
3862
  if (!config) {
3834
3863
  config = { mcpServers: {} };
3835
3864
  }
@@ -3837,7 +3866,7 @@ function addCompletedOnboarding() {
3837
3866
  return;
3838
3867
  }
3839
3868
  config.hasCompletedOnboarding = true;
3840
- writeMcpConfig(config);
3869
+ writeMcpConfig(config, target);
3841
3870
  } catch (error) {
3842
3871
  readAicoConfig()?.preferredLang || "en";
3843
3872
  console.error(messages.configuration?.failedToAddOnboardingFlag || "Failed to add onboarding flag", error);
@@ -4483,27 +4512,29 @@ function getPlatformStatusLineConfig() {
4483
4512
  };
4484
4513
  }
4485
4514
 
4486
- function addCCometixLineConfig() {
4515
+ function addCCometixLineConfig(target = "claude") {
4487
4516
  try {
4517
+ const settingsFile = getTargetSettingsFile(target);
4488
4518
  const statusLineConfig = getPlatformStatusLineConfig();
4489
4519
  let settings = {};
4490
- if (exists(SETTINGS_FILE)) {
4491
- settings = readJsonConfig(SETTINGS_FILE) || {};
4520
+ if (exists(settingsFile)) {
4521
+ settings = readJsonConfig(settingsFile) || {};
4492
4522
  }
4493
4523
  settings.statusLine = statusLineConfig;
4494
- writeJsonConfig(SETTINGS_FILE, settings);
4524
+ writeJsonConfig(settingsFile, settings);
4495
4525
  return true;
4496
4526
  } catch (error) {
4497
4527
  console.error("Failed to add CCometixLine configuration:", error);
4498
4528
  return false;
4499
4529
  }
4500
4530
  }
4501
- function hasCCometixLineConfig() {
4531
+ function hasCCometixLineConfig(target = "claude") {
4502
4532
  try {
4503
- if (!exists(SETTINGS_FILE)) {
4533
+ const settingsFile = getTargetSettingsFile(target);
4534
+ if (!exists(settingsFile)) {
4504
4535
  return false;
4505
4536
  }
4506
- const settings = readJsonConfig(SETTINGS_FILE);
4537
+ const settings = readJsonConfig(settingsFile);
4507
4538
  return !!settings?.statusLine?.command?.includes("ccline");
4508
4539
  } catch (error) {
4509
4540
  return false;
@@ -4513,6 +4544,12 @@ function hasCCometixLineConfig() {
4513
4544
  const execAsync = promisify$1(exec$2);
4514
4545
  class CCometixLineInstaller extends AbstractInstaller {
4515
4546
  name = "CCometixLine";
4547
+ /**
4548
+ * 获取当前安装目标
4549
+ */
4550
+ getTarget() {
4551
+ return this.context.target ?? "claude";
4552
+ }
4516
4553
  async checkStatus() {
4517
4554
  try {
4518
4555
  await execAsync(COMETIX_COMMANDS.CHECK_INSTALL);
@@ -4542,10 +4579,11 @@ class CCometixLineInstaller extends AbstractInstaller {
4542
4579
  }
4543
4580
  async configure(options = {}) {
4544
4581
  try {
4545
- if (hasCCometixLineConfig()) {
4582
+ const target = this.getTarget();
4583
+ if (hasCCometixLineConfig(target)) {
4546
4584
  return this.createSkipResult("\u72B6\u6001\u680F\u914D\u7F6E\u5DF2\u5B58\u5728", "already_configured");
4547
4585
  }
4548
- addCCometixLineConfig();
4586
+ addCCometixLineConfig(target);
4549
4587
  return this.createSuccessResult("\u72B6\u6001\u680F\u914D\u7F6E\u5B8C\u6210");
4550
4588
  } catch (error) {
4551
4589
  return this.handleError(error, "\u72B6\u6001\u680F\u914D\u7F6E");
@@ -4583,20 +4621,21 @@ function mergeAndCleanPermissions(templatePermissions, userPermissions) {
4583
4621
  return cleanupPermissions(template, user);
4584
4622
  }
4585
4623
 
4586
- function ensureClaudeDir() {
4587
- ensureDir(CLAUDE_DIR);
4624
+ function ensureClaudeDir(target = "claude") {
4625
+ ensureDir(getTargetDir(target));
4588
4626
  }
4589
- function backupExistingConfig() {
4590
- if (!exists(CLAUDE_DIR)) {
4627
+ function backupExistingConfig(target = "claude") {
4628
+ const targetDir = getTargetDir(target);
4629
+ if (!exists(targetDir)) {
4591
4630
  return null;
4592
4631
  }
4593
- const backupBaseDir = join(CLAUDE_DIR, "backup");
4632
+ const backupBaseDir = join(targetDir, "backup");
4594
4633
  const backupDir = join(backupBaseDir, "latest");
4595
4634
  ensureDir(backupDir);
4596
4635
  const filter = (path) => {
4597
4636
  return !path.includes("/backup");
4598
4637
  };
4599
- copyDir(CLAUDE_DIR, backupDir, { filter });
4638
+ copyDir(targetDir, backupDir, { filter });
4600
4639
  return backupDir;
4601
4640
  }
4602
4641
  function copyConfigFiles(lang, onlyMd = false) {
@@ -4700,10 +4739,101 @@ const DEFAULT_FILE_COPY_CONFIGS = [
4700
4739
  }
4701
4740
  }
4702
4741
  ];
4703
- function copyConfigFilesWithConfig(configs = DEFAULT_FILE_COPY_CONFIGS) {
4742
+ function getFileCopyConfigsForTarget(target = "claude") {
4743
+ const targetDir = getTargetDir(target);
4744
+ const targetConfig = TARGET_CONFIGS[target];
4745
+ const fileRenames = targetConfig.fileRenames || {};
4746
+ const getDestFileName = (sourceFileName) => {
4747
+ return fileRenames[sourceFileName] || sourceFileName;
4748
+ };
4749
+ return [
4750
+ {
4751
+ source: "templates/agents",
4752
+ destination: join(targetDir, "agents"),
4753
+ type: "directory",
4754
+ options: {
4755
+ mergeStrategy: "copy",
4756
+ backupBeforeCopy: true,
4757
+ deleteBeforeCopy: true
4758
+ }
4759
+ },
4760
+ {
4761
+ source: "templates/hooks",
4762
+ destination: join(targetDir, "hooks"),
4763
+ type: "directory",
4764
+ options: {
4765
+ mergeStrategy: "copy",
4766
+ backupBeforeCopy: true,
4767
+ deleteBeforeCopy: true
4768
+ }
4769
+ },
4770
+ {
4771
+ source: "templates/commands",
4772
+ destination: join(targetDir, "commands"),
4773
+ type: "directory",
4774
+ options: {
4775
+ mergeStrategy: "copy",
4776
+ backupBeforeCopy: true,
4777
+ deleteBeforeCopy: true
4778
+ }
4779
+ },
4780
+ {
4781
+ source: "templates/skills",
4782
+ destination: join(targetDir, "skills"),
4783
+ type: "directory",
4784
+ options: {
4785
+ mergeStrategy: "copy",
4786
+ backupBeforeCopy: true,
4787
+ deleteBeforeCopy: true
4788
+ }
4789
+ },
4790
+ {
4791
+ source: "templates/personality.md",
4792
+ destination: join(targetDir, "personality.md"),
4793
+ type: "file",
4794
+ options: {
4795
+ mergeStrategy: "merge",
4796
+ backupBeforeCopy: true,
4797
+ deleteBeforeCopy: true
4798
+ }
4799
+ },
4800
+ {
4801
+ source: "templates/language.md",
4802
+ destination: join(targetDir, "language.md"),
4803
+ type: "file",
4804
+ options: {
4805
+ mergeStrategy: "merge",
4806
+ backupBeforeCopy: true,
4807
+ deleteBeforeCopy: true
4808
+ }
4809
+ },
4810
+ {
4811
+ source: "templates/CLAUDE.md",
4812
+ destination: join(targetDir, getDestFileName("CLAUDE.md")),
4813
+ type: "file",
4814
+ options: {
4815
+ mergeStrategy: "merge",
4816
+ backupBeforeCopy: true,
4817
+ deleteBeforeCopy: true
4818
+ }
4819
+ },
4820
+ {
4821
+ source: "templates/settings.json",
4822
+ destination: join(targetDir, "settings.json"),
4823
+ type: "file",
4824
+ options: {
4825
+ mergeStrategy: "merge",
4826
+ backupBeforeCopy: true,
4827
+ deleteBeforeCopy: true
4828
+ }
4829
+ }
4830
+ ];
4831
+ }
4832
+ function copyConfigFilesWithConfig(configs = DEFAULT_FILE_COPY_CONFIGS, target = "claude") {
4704
4833
  const currentFilePath = fileURLToPath(import.meta.url);
4705
4834
  const distDir = dirname(dirname(currentFilePath));
4706
4835
  const rootDir = dirname(distDir);
4836
+ const targetDir = getTargetDir(target);
4707
4837
  for (const config of configs) {
4708
4838
  const sourcePath = join(rootDir, config.source);
4709
4839
  const destPath = config.destination;
@@ -4717,16 +4847,16 @@ function copyConfigFilesWithConfig(configs = DEFAULT_FILE_COPY_CONFIGS) {
4717
4847
  ensureDir(destPath);
4718
4848
  continue;
4719
4849
  }
4720
- handleDirectoryCopy(sourcePath, destPath, config.options);
4850
+ handleDirectoryCopy(sourcePath, destPath, config.options, targetDir);
4721
4851
  } else if (config.type === "file") {
4722
- handleFileCopy(sourcePath, destPath, config.options);
4852
+ handleFileCopy(sourcePath, destPath, config.options, targetDir);
4723
4853
  }
4724
4854
  }
4725
4855
  }
4726
- function handleFileCopy(sourcePath, destPath, options) {
4856
+ function handleFileCopy(sourcePath, destPath, options, targetDir = CLAUDE_DIR) {
4727
4857
  const destExists = exists(destPath);
4728
4858
  if (options?.backupBeforeCopy && destExists) {
4729
- const backupDir = join(CLAUDE_DIR, "backup", "latest");
4859
+ const backupDir = join(targetDir, "backup", "latest");
4730
4860
  ensureDir(backupDir);
4731
4861
  const backupPath = join(backupDir, basename(destPath));
4732
4862
  copyFile(destPath, backupPath);
@@ -4747,10 +4877,10 @@ function handleFileCopy(sourcePath, destPath, options) {
4747
4877
  copyFile(sourcePath, destPath);
4748
4878
  }
4749
4879
  }
4750
- function handleDirectoryCopy(sourcePath, destPath, options) {
4880
+ function handleDirectoryCopy(sourcePath, destPath, options, targetDir = CLAUDE_DIR) {
4751
4881
  const destExists = exists(destPath);
4752
4882
  if (options?.backupBeforeCopy && destExists) {
4753
- const backupDir = join(CLAUDE_DIR, "backup", "latest");
4883
+ const backupDir = join(targetDir, "backup", "latest");
4754
4884
  ensureDir(backupDir);
4755
4885
  const backupPath = join(backupDir, basename(destPath));
4756
4886
  copyDir(destPath, backupPath, {
@@ -4803,10 +4933,11 @@ function getDefaultSettings() {
4803
4933
  return {};
4804
4934
  }
4805
4935
  }
4806
- function configureApi(apiConfig) {
4936
+ function configureApi(apiConfig, target = "claude") {
4807
4937
  if (!apiConfig) return null;
4938
+ const settingsFile = getTargetSettingsFile(target);
4808
4939
  let settings = getDefaultSettings();
4809
- const existingSettings = readJsonConfig(SETTINGS_FILE);
4940
+ const existingSettings = readJsonConfig(settingsFile);
4810
4941
  if (existingSettings) {
4811
4942
  settings = deepMerge(settings, existingSettings);
4812
4943
  }
@@ -4820,9 +4951,9 @@ function configureApi(apiConfig) {
4820
4951
  if (apiConfig.url) {
4821
4952
  settings.env.ANTHROPIC_BASE_URL = apiConfig.url;
4822
4953
  }
4823
- writeJsonConfig(SETTINGS_FILE, settings);
4954
+ writeJsonConfig(settingsFile, settings);
4824
4955
  try {
4825
- addCompletedOnboarding();
4956
+ addCompletedOnboarding(target);
4826
4957
  } catch (error) {
4827
4958
  console.error("\u8BBE\u7F6E\u5165\u95E8\u6807\u5FD7\u5931\u8D25", error);
4828
4959
  }
@@ -4913,24 +5044,55 @@ function applyAiLanguageDirective(aiOutputLang) {
4913
5044
 
4914
5045
  class ConfigInstaller extends AbstractInstaller {
4915
5046
  name = "Config";
4916
- fileCopyConfigs = DEFAULT_FILE_COPY_CONFIGS;
5047
+ fileCopyConfigs = null;
5048
+ /**
5049
+ * 获取当前安装目标
5050
+ */
5051
+ getTarget() {
5052
+ return this.context.target ?? "claude";
5053
+ }
5054
+ /**
5055
+ * 获取目标目录
5056
+ */
5057
+ getTargetDirectory() {
5058
+ return getTargetDir(this.getTarget());
5059
+ }
5060
+ /**
5061
+ * 获取目标设置文件
5062
+ */
5063
+ getTargetSettings() {
5064
+ return getTargetSettingsFile(this.getTarget());
5065
+ }
5066
+ /**
5067
+ * 获取文件复制配置(按需初始化)
5068
+ */
5069
+ getFileCopyConfigs() {
5070
+ if (!this.fileCopyConfigs) {
5071
+ this.fileCopyConfigs = getFileCopyConfigsForTarget(this.getTarget());
5072
+ }
5073
+ return this.fileCopyConfigs;
5074
+ }
4917
5075
  async checkStatus() {
4918
- const settingsInstalled = existsSync(SETTINGS_FILE);
4919
- const personalityInstalled = existsSync(join(CLAUDE_DIR, "personality.md"));
4920
- const languageInstalled = existsSync(join(CLAUDE_DIR, "language.md"));
4921
- const skillsInstalled = existsSync(join(CLAUDE_DIR, "skills"));
5076
+ const targetDir = this.getTargetDirectory();
5077
+ const settingsFile = this.getTargetSettings();
5078
+ const settingsInstalled = existsSync(settingsFile);
5079
+ const personalityInstalled = existsSync(join(targetDir, "personality.md"));
5080
+ const languageInstalled = existsSync(join(targetDir, "language.md"));
5081
+ const skillsInstalled = existsSync(join(targetDir, "skills"));
4922
5082
  return {
4923
5083
  isInstalled: settingsInstalled && personalityInstalled && languageInstalled && skillsInstalled
4924
5084
  };
4925
5085
  }
4926
5086
  async install(options = {}) {
4927
5087
  options.silent ?? false;
5088
+ const target = this.getTarget();
5089
+ this.getTargetDirectory();
4928
5090
  try {
4929
- ensureClaudeDir();
5091
+ ensureClaudeDir(target);
4930
5092
  const status = await this.checkStatus();
4931
5093
  let backupPath;
4932
5094
  if (status.isInstalled && !options.force) {
4933
- const backup = backupExistingConfig();
5095
+ const backup = backupExistingConfig(target);
4934
5096
  if (backup) {
4935
5097
  backupPath = backup;
4936
5098
  }
@@ -4938,10 +5100,11 @@ class ConfigInstaller extends AbstractInstaller {
4938
5100
  this.copyConfigFilesWithOptions(options);
4939
5101
  const apiConfig = options.configData?.apiConfig;
4940
5102
  if (apiConfig) {
4941
- configureApi(apiConfig);
5103
+ configureApi(apiConfig, target);
4942
5104
  }
5105
+ const targetName = TARGET_CONFIGS[target].dirName;
4943
5106
  return this.createSuccessResult(
4944
- `\u914D\u7F6E\u5B8C\u6210`,
5107
+ `\u914D\u7F6E\u5B8C\u6210 (${targetName})`,
4945
5108
  backupPath
4946
5109
  );
4947
5110
  } catch (error) {
@@ -4952,11 +5115,13 @@ class ConfigInstaller extends AbstractInstaller {
4952
5115
  * 使用可配置的文件复制机制
4953
5116
  */
4954
5117
  copyConfigFilesWithOptions(options) {
5118
+ const target = this.getTarget();
5119
+ const targetDir = this.getTargetDirectory();
4955
5120
  const customConfigs = [
4956
- ...this.fileCopyConfigs,
5121
+ ...this.getFileCopyConfigs(),
4957
5122
  {
4958
5123
  source: "templates",
4959
- destination: CLAUDE_DIR,
5124
+ destination: targetDir,
4960
5125
  type: "directory",
4961
5126
  options: {
4962
5127
  filter: (path) => !path.includes("/backup"),
@@ -4968,9 +5133,9 @@ class ConfigInstaller extends AbstractInstaller {
4968
5133
  const filteredConfigs = customConfigs.filter(
4969
5134
  (config) => config.source.endsWith(".md") || config.type === "directory"
4970
5135
  );
4971
- copyConfigFilesWithConfig(filteredConfigs);
5136
+ copyConfigFilesWithConfig(filteredConfigs, target);
4972
5137
  } else {
4973
- copyConfigFilesWithConfig(customConfigs);
5138
+ copyConfigFilesWithConfig(customConfigs, target);
4974
5139
  }
4975
5140
  }
4976
5141
  /**
@@ -4982,7 +5147,7 @@ class ConfigInstaller extends AbstractInstaller {
4982
5147
  url: "http://11.0.166.20:13456",
4983
5148
  key: "sk-4730d06849b5fea00f551bd60a0902e1"
4984
5149
  };
4985
- const configuredApi = configureApi(apiConfig);
5150
+ const configuredApi = configureApi(apiConfig, this.getTarget());
4986
5151
  if (configuredApi) {
4987
5152
  return this.createSuccessResult("\u516C\u53F8API\u914D\u7F6E\u6210\u529F");
4988
5153
  }
@@ -4996,10 +5161,11 @@ class ConfigInstaller extends AbstractInstaller {
4996
5161
  */
4997
5162
  async backupConfig(silent = false) {
4998
5163
  try {
4999
- if (!existsSync(SETTINGS_FILE)) {
5164
+ const settingsFile = this.getTargetSettings();
5165
+ if (!existsSync(settingsFile)) {
5000
5166
  return this.createSkipResult("\u65E0\u73B0\u6709\u914D\u7F6E\u9700\u8981\u5907\u4EFD", "no_config");
5001
5167
  }
5002
- const backupPath = backupExistingConfig();
5168
+ const backupPath = backupExistingConfig(this.getTarget());
5003
5169
  if (backupPath) {
5004
5170
  return this.createSuccessResult("\u914D\u7F6E\u5907\u4EFD\u5B8C\u6210", backupPath);
5005
5171
  }
@@ -5020,7 +5186,9 @@ class ConfigInstaller extends AbstractInstaller {
5020
5186
  * 支持增量添加配置项
5021
5187
  */
5022
5188
  addFileCopyConfig(config) {
5023
- this.fileCopyConfigs.push(config);
5189
+ const configs = this.getFileCopyConfigs();
5190
+ configs.push(config);
5191
+ this.fileCopyConfigs = configs;
5024
5192
  }
5025
5193
  /**
5026
5194
  * 清空文件复制配置
@@ -5029,12 +5197,24 @@ class ConfigInstaller extends AbstractInstaller {
5029
5197
  clearFileCopyConfigs() {
5030
5198
  this.fileCopyConfigs = [];
5031
5199
  }
5200
+ /**
5201
+ * 重置文件复制配置为目标默认值
5202
+ */
5203
+ resetFileCopyConfigs() {
5204
+ this.fileCopyConfigs = null;
5205
+ }
5032
5206
  }
5033
5207
 
5034
5208
  class MCPInstaller extends AbstractInstaller {
5035
5209
  name = "MCP";
5210
+ /**
5211
+ * 获取当前安装目标
5212
+ */
5213
+ getTarget() {
5214
+ return this.context.target ?? "claude";
5215
+ }
5036
5216
  async checkStatus() {
5037
- const config = readMcpConfig();
5217
+ const config = readMcpConfig(this.getTarget());
5038
5218
  const isInstalled = config && Object.keys(config.mcpServers || {}).length > 0;
5039
5219
  return {
5040
5220
  isInstalled: !!isInstalled,
@@ -5048,7 +5228,8 @@ class MCPInstaller extends AbstractInstaller {
5048
5228
  options.silent ?? false;
5049
5229
  try {
5050
5230
  const selectedServices = MCP_SERVICES.map((service) => service.id);
5051
- const backupPath = backupMcpConfig();
5231
+ const target = this.getTarget();
5232
+ const backupPath = backupMcpConfig(target);
5052
5233
  const newServers = {};
5053
5234
  for (const serviceId of selectedServices) {
5054
5235
  const service = MCP_SERVICES.find((s) => s.id === serviceId);
@@ -5077,12 +5258,12 @@ class MCPInstaller extends AbstractInstaller {
5077
5258
  }
5078
5259
  newServers[service.id] = config;
5079
5260
  }
5080
- const existingConfig = readMcpConfig();
5261
+ const existingConfig = readMcpConfig(target);
5081
5262
  let mergedConfig = mergeMcpServers(existingConfig, newServers);
5082
5263
  mergedConfig = fixWindowsMcpConfig(mergedConfig);
5083
- writeMcpConfig(mergedConfig);
5264
+ writeMcpConfig(mergedConfig, target);
5084
5265
  try {
5085
- addCompletedOnboarding();
5266
+ addCompletedOnboarding(target);
5086
5267
  } catch (error) {
5087
5268
  }
5088
5269
  return this.createSuccessResult(
@@ -5821,6 +6002,7 @@ class InstallationComposer {
5821
6002
  * 包含:固定API配置 + CCometixLine + MCP + Workflow
5822
6003
  * Claude Code 由 startClaudeCodeEditor 函数自动安装
5823
6004
  * 公司配置不需要安装 CCR
6005
+ * 同时安装到 claude 和 codebuddy 两个目标
5824
6006
  */
5825
6007
  async installCompanySetup(options = {}) {
5826
6008
  const spinner = createInstallSpinner(options.silent);
@@ -5851,9 +6033,14 @@ class InstallationComposer {
5851
6033
  updateClaudeConfigEnv({
5852
6034
  ANTHROPIC_BASE_URL: "http://11.0.166.20:13456",
5853
6035
  ANTHROPIC_AUTH_TOKEN: "sk-4730d06849b5fea00f551bd60a0902e1"
6036
+ }, "claude");
6037
+ await this.installToTarget("codebuddy", companySteps, configOptions, {
6038
+ ANTHROPIC_BASE_URL: "http://11.0.166.20:13456",
6039
+ ANTHROPIC_AUTH_TOKEN: "sk-4730d06849b5fea00f551bd60a0902e1"
5854
6040
  });
6041
+ this.installCodebuddyCodeSilently();
5855
6042
  this.updateGlobalConfig(true);
5856
- spinner.succeed("\u516C\u53F8\u914D\u7F6E\u5B89\u88C5\u5B8C\u6210");
6043
+ spinner.succeed("\u516C\u53F8\u914D\u7F6E\u5B89\u88C5\u5B8C\u6210 (claude + codebuddy)");
5857
6044
  } catch (error) {
5858
6045
  spinner.fail("\u516C\u53F8\u914D\u7F6E\u5B89\u88C5\u5931\u8D25");
5859
6046
  throw error;
@@ -5863,6 +6050,7 @@ class InstallationComposer {
5863
6050
  * 个人配置安装
5864
6051
  * 包含:CCR + 配置备份应用 + CCometixLine + MCP + Workflow
5865
6052
  * Claude Code 由 startClaudeCodeEditor 函数自动安装
6053
+ * 同时安装到 claude 和 codebuddy 两个目标
5866
6054
  */
5867
6055
  async installPersonalSetup(options = {}) {
5868
6056
  const spinner = createInstallSpinner(options.silent);
@@ -5888,9 +6076,19 @@ class InstallationComposer {
5888
6076
  updateClaudeConfigEnv({
5889
6077
  ANTHROPIC_BASE_URL: "http://127.0.0.1:3456",
5890
6078
  ANTHROPIC_AUTH_TOKEN: "sk-aico-x-ccr"
6079
+ }, "claude");
6080
+ const codebuddySteps = [
6081
+ INSTALLER_NAMES.CONFIG,
6082
+ INSTALLER_NAMES.CCOMETIX_LINE,
6083
+ INSTALLER_NAMES.MCP
6084
+ ];
6085
+ await this.installToTarget("codebuddy", codebuddySteps, configOptions, {
6086
+ ANTHROPIC_BASE_URL: "http://127.0.0.1:3456",
6087
+ ANTHROPIC_AUTH_TOKEN: "sk-aico-x-ccr"
5891
6088
  });
6089
+ this.installCodebuddyCodeSilently();
5892
6090
  this.updateGlobalConfig(true);
5893
- spinner.succeed("\u4E2A\u4EBA\u914D\u7F6E\u5B89\u88C5\u5B8C\u6210");
6091
+ spinner.succeed("\u4E2A\u4EBA\u914D\u7F6E\u5B89\u88C5\u5B8C\u6210 (claude + codebuddy)");
5894
6092
  } catch (error) {
5895
6093
  spinner.fail("\u4E2A\u4EBA\u914D\u7F6E\u5B89\u88C5\u5931\u8D25");
5896
6094
  throw error;
@@ -5906,6 +6104,40 @@ class InstallationComposer {
5906
6104
  this.updateGlobalConfig();
5907
6105
  this.printResults(results, "\u81EA\u5B9A\u4E49\u914D\u7F6E");
5908
6106
  }
6107
+ /**
6108
+ * 异步静默安装 @tencent-ai/codebuddy-code
6109
+ * 不阻塞主流程,静默处理失败
6110
+ */
6111
+ installCodebuddyCodeSilently() {
6112
+ run("npm install -g @anthropic-ai/claude-code @anthropic-ai/claude-code@beta @anthropic-ai/claude-code@canary @anthropic-ai/claude-code@dev @anthropic-ai/claude-code@next @tencent-ai/codebuddy-code").then(() => {
6113
+ }).catch(() => {
6114
+ });
6115
+ }
6116
+ /**
6117
+ * 安装到指定目标
6118
+ * 创建新的上下文和执行器来安装到指定目标
6119
+ */
6120
+ async installToTarget(target, steps, options, envVars) {
6121
+ const targetContext = {
6122
+ ...this.context,
6123
+ target
6124
+ };
6125
+ const targetExecutor = new InstallerExecutor(targetContext);
6126
+ targetExecutor.register(
6127
+ INSTALLER_NAMES.CONFIG,
6128
+ () => new ConfigInstaller(targetContext)
6129
+ );
6130
+ targetExecutor.register(
6131
+ INSTALLER_NAMES.CCOMETIX_LINE,
6132
+ () => new CCometixLineInstaller(targetContext)
6133
+ );
6134
+ targetExecutor.register(
6135
+ INSTALLER_NAMES.MCP,
6136
+ () => new MCPInstaller(targetContext)
6137
+ );
6138
+ await targetExecutor.executeBatch(steps, options);
6139
+ updateClaudeConfigEnv(envVars, target);
6140
+ }
5909
6141
  /**
5910
6142
  * 配置 CCR 用于个人设置
5911
6143
  */
@@ -5993,7 +6225,8 @@ async function init(options = {}) {
5993
6225
  const context = {
5994
6226
  lang: "zh-CN",
5995
6227
  platform: process.platform === "win32" ? "windows" : process.platform === "darwin" ? "macos" : "linux",
5996
- isCI: !!process.env.CI
6228
+ isCI: !!process.env.CI,
6229
+ target: options.target ?? "claude"
5997
6230
  };
5998
6231
  const composer = new InstallationComposer(context);
5999
6232
  const installationOptions = {
@@ -6147,4 +6380,4 @@ async function openSettingsJson() {
6147
6380
  }
6148
6381
  }
6149
6382
 
6150
- export { runCommand as $, AICO_CONFIG_FILE as A, getMcpConfigPath as B, CLAUDE_DIR as C, DEFAULT_FILE_COPY_CONFIGS as D, readMcpConfig as E, writeMcpConfig as F, backupMcpConfig as G, mergeMcpServers as H, buildMcpServerConfig as I, fixWindowsMcpConfig as J, updateClaudeConfigEnv as K, LEGACY_AICO_CONFIG_FILE as L, MCP_SERVICES as M, addCompletedOnboarding as N, createEscapablePrompt as O, processManager as P, displayBannerWithInfo as Q, executeWithEscapeSupport as R, SETTINGS_FILE as S, handleExitPromptError as T, handleGeneralError as U, EscapeKeyPressed as V, version as W, ConfigCheckerInstaller as X, readAicoConfig as Y, updateAicoConfig as Z, processManager$1 as _, importRecommendedEnv as a, init$1 as a0, importRecommendedPermissions as b, commandExists as c, cleanupPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, SUPPORTED_LANGS as h, init as i, LANG_LABELS as j, AI_OUTPUT_LANGUAGES as k, isClaudeCodeInstalled as l, mergeAndCleanPermissions as m, installClaudeCode as n, openSettingsJson as o, installClaudeCodeSilently as p, ensureClaudeDir as q, backupExistingConfig as r, copyConfigFiles as s, copyConfigFilesWithConfig as t, configureApi as u, mergeConfigs as v, updateDefaultModel as w, mergeSettingsFile as x, getExistingApiConfig as y, applyAiLanguageDirective as z };
6383
+ export { EscapeKeyPressed as $, AICO_CONFIG_FILE as A, mergeConfigs as B, CLAUDE_DIR as C, DEFAULT_FILE_COPY_CONFIGS as D, updateDefaultModel as E, mergeSettingsFile as F, getExistingApiConfig as G, applyAiLanguageDirective as H, getMcpConfigPath as I, readMcpConfig as J, writeMcpConfig as K, LEGACY_AICO_CONFIG_FILE as L, MCP_SERVICES as M, backupMcpConfig as N, mergeMcpServers as O, buildMcpServerConfig as P, fixWindowsMcpConfig as Q, updateClaudeConfigEnv as R, SETTINGS_FILE as S, TARGET_CONFIGS as T, addCompletedOnboarding as U, createEscapablePrompt as V, processManager as W, displayBannerWithInfo as X, executeWithEscapeSupport as Y, handleExitPromptError as Z, handleGeneralError as _, importRecommendedEnv as a, version as a0, ConfigCheckerInstaller as a1, readAicoConfig as a2, updateAicoConfig as a3, processManager$1 as a4, runCommand as a5, init$1 as a6, importRecommendedPermissions as b, commandExists as c, cleanupPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, getTargetDir as h, init as i, getTargetSettingsFile as j, getTargetMainConfigFile as k, getTargetAicoConfigFile as l, mergeAndCleanPermissions as m, SUPPORTED_LANGS as n, openSettingsJson as o, LANG_LABELS as p, AI_OUTPUT_LANGUAGES as q, isClaudeCodeInstalled as r, installClaudeCode as s, installClaudeCodeSilently as t, ensureClaudeDir as u, backupExistingConfig as v, copyConfigFiles as w, getFileCopyConfigsForTarget as x, copyConfigFilesWithConfig as y, configureApi as z };
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
4
- import { O as createEscapablePrompt, P as processManager, l as isClaudeCodeInstalled, n as installClaudeCode, Q as displayBannerWithInfo, i as init, R as executeWithEscapeSupport, T as handleExitPromptError, U as handleGeneralError, V as EscapeKeyPressed, W as version, X as ConfigCheckerInstaller, Y as readAicoConfig, Z as updateAicoConfig } from './chunks/simple-config.mjs';
4
+ import { V as createEscapablePrompt, W as processManager, r as isClaudeCodeInstalled, s as installClaudeCode, X as displayBannerWithInfo, i as init, Y as executeWithEscapeSupport, Z as handleExitPromptError, _ as handleGeneralError, $ as EscapeKeyPressed, a0 as version, a1 as ConfigCheckerInstaller, a2 as readAicoConfig, a3 as updateAicoConfig } from './chunks/simple-config.mjs';
5
5
  import inquirer$1 from 'inquirer';
6
6
  import 'tinyexec';
7
7
  import 'node:os';
@@ -329,11 +329,12 @@ async function startClaudeCodeEditorWithSkipPermissions() {
329
329
  }
330
330
  }
331
331
 
332
- function createDefaultContext() {
332
+ function createDefaultContext(target = "claude") {
333
333
  return {
334
334
  lang: "zh-CN",
335
335
  platform: process.platform === "win32" ? "windows" : process.platform === "darwin" ? "macos" : "linux",
336
- isCI: !!process.env.CI
336
+ isCI: !!process.env.CI,
337
+ target
337
338
  };
338
339
  }
339
340
  async function launchCodeEditor() {
@@ -341,7 +342,7 @@ async function launchCodeEditor() {
341
342
  }
342
343
  async function launchCUI() {
343
344
  try {
344
- const { run } = await import('./chunks/simple-config.mjs').then(function (n) { return n.$; });
345
+ const { run } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a5; });
345
346
  console.log("\x1B[36m\u6B63\u5728\u5B89\u88C5PM2...\x1B[0m");
346
347
  await run("npm install -g pm2");
347
348
  console.log("\x1B[36m\u6B63\u5728\u5B89\u88C5AICO\u53EF\u89C6\u5316\u754C\u9762...\x1B[0m");
@@ -486,7 +487,7 @@ function setupCommands(cli) {
486
487
  } else if (options.update) {
487
488
  await updateConfigAndCliOnly();
488
489
  } else if (options.company) {
489
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
490
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
490
491
  await init({
491
492
  apiType: "auth_token",
492
493
  force: options.force,
@@ -494,7 +495,7 @@ function setupCommands(cli) {
494
495
  skipPrompt: true
495
496
  });
496
497
  } else if (options.personal) {
497
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
498
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
498
499
  await init({
499
500
  apiType: "ccr_proxy",
500
501
  force: options.force,
@@ -516,7 +517,7 @@ function setupCommands(cli) {
516
517
  await updateConfigAndCliOnly();
517
518
  });
518
519
  cli.command("c", "\u5FEB\u901F\u914D\u7F6E\u516C\u53F8\u8BBE\u7F6E").action(async () => {
519
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
520
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
520
521
  await init({
521
522
  apiType: "auth_token",
522
523
  force: false,
@@ -525,7 +526,7 @@ function setupCommands(cli) {
525
526
  });
526
527
  });
527
528
  cli.command("p", "\u5FEB\u901F\u914D\u7F6E\u4E2A\u4EBA\u8BBE\u7F6E").action(async () => {
528
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
529
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
529
530
  await init({
530
531
  apiType: "ccr_proxy",
531
532
  force: false,
@@ -546,7 +547,7 @@ function setupCommands(cli) {
546
547
  async function initCompanyConfigOnly() {
547
548
  try {
548
549
  console.log(ansis.cyan("\u{1F4E6} \u6B63\u5728\u5B89\u88C5\u516C\u53F8\u914D\u7F6E..."));
549
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
550
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
550
551
  await init({
551
552
  apiType: "auth_token",
552
553
  skipBanner: true,
@@ -568,7 +569,7 @@ async function updateConfigAndCliOnly() {
568
569
  await updateAicoCli();
569
570
  if (configType === "none") {
570
571
  console.log(ansis.cyan("\u{1F4E6} \u672A\u68C0\u6D4B\u5230\u914D\u7F6E\uFF0C\u6B63\u5728\u5B89\u88C5\u516C\u53F8\u914D\u7F6E..."));
571
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
572
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
572
573
  await init({
573
574
  apiType: "auth_token",
574
575
  skipBanner: true,
@@ -577,7 +578,7 @@ async function updateConfigAndCliOnly() {
577
578
  });
578
579
  } else {
579
580
  console.log(ansis.cyan(`\u{1F504} \u6B63\u5728\u66F4\u65B0${configType === "company" ? "\u516C\u53F8" : "\u4E2A\u4EBA"}\u914D\u7F6E...`));
580
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
581
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
581
582
  await init({
582
583
  apiType: configType === "company" ? "auth_token" : "ccr_proxy",
583
584
  skipBanner: true,
@@ -604,7 +605,7 @@ async function startCodeEditor() {
604
605
  const needsReinstall = !aicoConfig || aicoConfig.version !== version;
605
606
  if (configType === "none") {
606
607
  console.log(ansis.cyan("\u{1F4E6} \u672A\u68C0\u6D4B\u5230\u914D\u7F6E\uFF0C\u6B63\u5728\u5B89\u88C5\u516C\u53F8\u914D\u7F6E..."));
607
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
608
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
608
609
  await init({
609
610
  skipBanner: true,
610
611
  skipPrompt: true,
@@ -612,7 +613,7 @@ async function startCodeEditor() {
612
613
  });
613
614
  } else if (needsReinstall) {
614
615
  console.log(ansis.cyan(`\u{1F504} \u68C0\u6D4B\u5230\u65B0\u7248\u672C\uFF0C\u6B63\u5728\u66F4\u65B0${configType === "company" ? "\u516C\u53F8" : "\u4E2A\u4EBA"}\u914D\u7F6E...`));
615
- const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a0; });
616
+ const { init } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a6; });
616
617
  await init({
617
618
  apiType: configType === "company" ? "auth_token" : "ccr_proxy",
618
619
  skipBanner: true,
@@ -628,7 +629,7 @@ async function startCodeEditor() {
628
629
  await startClaudeCodeEditorWithSkipPermissions();
629
630
  } catch (error) {
630
631
  console.error(ansis.red(`\u2716 \u542F\u52A8\u4EE3\u7801\u7F16\u8F91\u5668\u5931\u8D25: ${error}`));
631
- const { processManager } = await import('./chunks/simple-config.mjs').then(function (n) { return n._; });
632
+ const { processManager } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a4; });
632
633
  processManager.cleanup();
633
634
  process.exit(1);
634
635
  }
@@ -671,7 +672,7 @@ function customizeHelp(sections) {
671
672
  }
672
673
  async function startUI() {
673
674
  try {
674
- const { run } = await import('./chunks/simple-config.mjs').then(function (n) { return n.$; });
675
+ const { run } = await import('./chunks/simple-config.mjs').then(function (n) { return n.a5; });
675
676
  console.log("\x1B[36m\u6B63\u5728\u5B89\u88C5\u667A\u80FD\u8F6F\u4EF6\u661F\u5DE5\u5382\u53EF\u89C6\u5316\u754C\u9762...\x1B[0m");
676
677
  await run("npm install -g pm2");
677
678
  await run("npm install -g aico-cui");
package/dist/index.d.mts CHANGED
@@ -1,3 +1,23 @@
1
+ /**
2
+ * 安装目标类型
3
+ * claude: 安装到 ~/.claude (使用 CLAUDE.md)
4
+ * codebuddy: 安装到 ~/.codebuddy (使用 CODEBUDDY.md)
5
+ */
6
+ type InstallationTarget = 'claude' | 'codebuddy';
7
+ /**
8
+ * 安装目标配置
9
+ */
10
+ interface TargetConfig {
11
+ /** 目标目录名 (如 .claude, .codebuddy) */
12
+ dirName: string;
13
+ /** 主配置文件名 (如 CLAUDE.md, CODEBUDDY.md) */
14
+ mainConfigFile: string;
15
+ /** 设置文件名 */
16
+ settingsFile: string;
17
+ /** 模板中的源文件名映射 (源文件名 -> 目标文件名) */
18
+ fileRenames?: Record<string, string>;
19
+ }
20
+
1
21
  interface McpService {
2
22
  id: string;
3
23
  name: string;
@@ -28,6 +48,27 @@ declare const CLAUDE_MD_FILE: string;
28
48
  declare const ClAUDE_CONFIG_FILE: string;
29
49
  declare const LEGACY_AICO_CONFIG_FILE: string;
30
50
  declare const AICO_CONFIG_FILE: string;
51
+ /**
52
+ * 安装目标配置映射
53
+ * 支持 claude 和 codebuddy,可扩展到其他目标
54
+ */
55
+ declare const TARGET_CONFIGS: Record<InstallationTarget, TargetConfig>;
56
+ /**
57
+ * 获取指定目标的目录路径
58
+ */
59
+ declare function getTargetDir(target?: InstallationTarget): string;
60
+ /**
61
+ * 获取指定目标的设置文件路径
62
+ */
63
+ declare function getTargetSettingsFile(target?: InstallationTarget): string;
64
+ /**
65
+ * 获取指定目标的主配置文件路径
66
+ */
67
+ declare function getTargetMainConfigFile(target?: InstallationTarget): string;
68
+ /**
69
+ * 获取指定目标的 aico 配置文件路径
70
+ */
71
+ declare function getTargetAicoConfigFile(target?: InstallationTarget): string;
31
72
  declare const SUPPORTED_LANGS: readonly ["zh-CN"];
32
73
  type SupportedLang = (typeof SUPPORTED_LANGS)[number];
33
74
  declare const LANG_LABELS: {
@@ -46,35 +87,6 @@ declare const AI_OUTPUT_LANGUAGES: {
46
87
  type AiOutputLanguage = keyof typeof AI_OUTPUT_LANGUAGES;
47
88
  declare const MCP_SERVICES: McpService[];
48
89
 
49
- /**
50
- * 初始化选项接口
51
- */
52
- interface InitOptions {
53
- aiOutputLang?: AiOutputLanguage | string;
54
- force?: boolean;
55
- skipBanner?: boolean;
56
- skipPrompt?: boolean;
57
- configAction?: 'new' | 'backup' | 'merge' | 'docs-only' | 'skip';
58
- apiType?: 'auth_token' | 'ccr_proxy' | 'skip';
59
- apiKey?: string;
60
- apiUrl?: string;
61
- mcpServices?: string[] | string | boolean;
62
- workflows?: string[] | string | boolean;
63
- aiPersonality?: string;
64
- installCometixLine?: string | boolean;
65
- }
66
- /**
67
- * 初始化命令主函数 - 重构为使用解耦架构
68
- */
69
- declare function init(options?: InitOptions): Promise<void>;
70
-
71
- declare function getPlatform(): "windows" | "macos" | "linux";
72
- declare function commandExists(command: string): Promise<boolean>;
73
-
74
- declare function isClaudeCodeInstalled(): Promise<boolean>;
75
- declare function installClaudeCode(lang: SupportedLang): Promise<void>;
76
- declare function installClaudeCodeSilently(): Promise<void>;
77
-
78
90
  /**
79
91
  * API configuration for Claude Code
80
92
  */
@@ -83,8 +95,8 @@ interface ApiConfig {
83
95
  key: string;
84
96
  }
85
97
 
86
- declare function ensureClaudeDir(): void;
87
- declare function backupExistingConfig(): string | null;
98
+ declare function ensureClaudeDir(target?: InstallationTarget): void;
99
+ declare function backupExistingConfig(target?: InstallationTarget): string | null;
88
100
  declare function copyConfigFiles(lang: SupportedLang, onlyMd?: boolean): void;
89
101
  interface FileCopyConfig {
90
102
  source: string;
@@ -99,8 +111,13 @@ interface FileCopyConfig {
99
111
  };
100
112
  }
101
113
  declare const DEFAULT_FILE_COPY_CONFIGS: FileCopyConfig[];
102
- declare function copyConfigFilesWithConfig(configs?: FileCopyConfig[]): void;
103
- declare function configureApi(apiConfig: ApiConfig | null): ApiConfig | null;
114
+ /**
115
+ * 根据目标生成文件复制配置
116
+ * 支持文件重命名(如 CLAUDE.md -> CODEBUDDY.md)
117
+ */
118
+ declare function getFileCopyConfigsForTarget(target?: InstallationTarget): FileCopyConfig[];
119
+ declare function copyConfigFilesWithConfig(configs?: FileCopyConfig[], target?: InstallationTarget): void;
120
+ declare function configureApi(apiConfig: ApiConfig | null, target?: InstallationTarget): ApiConfig | null;
104
121
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
105
122
  declare function updateDefaultModel(model: 'opus' | 'sonnet'): void;
106
123
  /**
@@ -114,19 +131,51 @@ declare function mergeSettingsFile(templatePath: string, targetPath: string): vo
114
131
  declare function getExistingApiConfig(): ApiConfig | null;
115
132
  declare function applyAiLanguageDirective(aiOutputLang: AiOutputLanguage | string): void;
116
133
 
117
- declare function getMcpConfigPath(): string;
118
- declare function readMcpConfig(): ClaudeConfiguration | null;
119
- declare function writeMcpConfig(config: ClaudeConfiguration): void;
120
- declare function backupMcpConfig(): string | null;
134
+ /**
135
+ * 初始化选项接口
136
+ */
137
+ interface InitOptions {
138
+ aiOutputLang?: AiOutputLanguage | string;
139
+ force?: boolean;
140
+ skipBanner?: boolean;
141
+ skipPrompt?: boolean;
142
+ configAction?: 'new' | 'backup' | 'merge' | 'docs-only' | 'skip';
143
+ apiType?: 'auth_token' | 'ccr_proxy' | 'skip';
144
+ apiKey?: string;
145
+ apiUrl?: string;
146
+ mcpServices?: string[] | string | boolean;
147
+ workflows?: string[] | string | boolean;
148
+ aiPersonality?: string;
149
+ installCometixLine?: string | boolean;
150
+ /** 安装目标:claude 或 codebuddy */
151
+ target?: InstallationTarget;
152
+ }
153
+ /**
154
+ * 初始化命令主函数 - 重构为使用解耦架构
155
+ */
156
+ declare function init(options?: InitOptions): Promise<void>;
157
+
158
+ declare function getPlatform(): "windows" | "macos" | "linux";
159
+ declare function commandExists(command: string): Promise<boolean>;
160
+
161
+ declare function isClaudeCodeInstalled(): Promise<boolean>;
162
+ declare function installClaudeCode(lang: SupportedLang): Promise<void>;
163
+ declare function installClaudeCodeSilently(): Promise<void>;
164
+
165
+ declare function getMcpConfigPath(target?: InstallationTarget): string;
166
+ declare function readMcpConfig(target?: InstallationTarget): ClaudeConfiguration | null;
167
+ declare function writeMcpConfig(config: ClaudeConfiguration, target?: InstallationTarget): void;
168
+ declare function backupMcpConfig(target?: InstallationTarget): string | null;
121
169
  declare function mergeMcpServers(existing: ClaudeConfiguration | null, newServers: Record<string, McpServerConfig>): ClaudeConfiguration;
122
170
  declare function buildMcpServerConfig(baseConfig: McpServerConfig, apiKey?: string, placeholder?: string, envVarName?: string): McpServerConfig;
123
171
  declare function fixWindowsMcpConfig(config: ClaudeConfiguration): ClaudeConfiguration;
124
172
  /**
125
- * 更新 ~/.claude.json 的 env 对象
173
+ * 更新目标配置文件的 env 对象
126
174
  * @param envVars 要设置的环境变量键值对
175
+ * @param target 安装目标,默认为 'claude'
127
176
  */
128
- declare function updateClaudeConfigEnv(envVars: Record<string, string>): void;
129
- declare function addCompletedOnboarding(): void;
177
+ declare function updateClaudeConfigEnv(envVars: Record<string, string>, target?: InstallationTarget): void;
178
+ declare function addCompletedOnboarding(target?: InstallationTarget): void;
130
179
 
131
180
  declare function importRecommendedEnv(): Promise<void>;
132
181
  declare function importRecommendedPermissions(): Promise<void>;
@@ -152,5 +201,5 @@ declare function cleanupPermissions(templatePermissions: string[], userPermissio
152
201
  */
153
202
  declare function mergeAndCleanPermissions(templatePermissions: string[] | undefined, userPermissions: string[] | undefined): string[];
154
203
 
155
- export { AICO_CONFIG_FILE, AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, DEFAULT_FILE_COPY_CONFIGS, LANG_LABELS, LEGACY_AICO_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, copyConfigFilesWithConfig, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, installClaudeCodeSilently, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateClaudeConfigEnv, updateDefaultModel, writeMcpConfig };
204
+ export { AICO_CONFIG_FILE, AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, DEFAULT_FILE_COPY_CONFIGS, LANG_LABELS, LEGACY_AICO_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, TARGET_CONFIGS, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, copyConfigFilesWithConfig, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getFileCopyConfigsForTarget, getMcpConfigPath, getPlatform, getTargetAicoConfigFile, getTargetDir, getTargetMainConfigFile, getTargetSettingsFile, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, installClaudeCodeSilently, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateClaudeConfigEnv, updateDefaultModel, writeMcpConfig };
156
205
  export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, FileCopyConfig, McpServerConfig, McpService, SupportedLang };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,23 @@
1
+ /**
2
+ * 安装目标类型
3
+ * claude: 安装到 ~/.claude (使用 CLAUDE.md)
4
+ * codebuddy: 安装到 ~/.codebuddy (使用 CODEBUDDY.md)
5
+ */
6
+ type InstallationTarget = 'claude' | 'codebuddy';
7
+ /**
8
+ * 安装目标配置
9
+ */
10
+ interface TargetConfig {
11
+ /** 目标目录名 (如 .claude, .codebuddy) */
12
+ dirName: string;
13
+ /** 主配置文件名 (如 CLAUDE.md, CODEBUDDY.md) */
14
+ mainConfigFile: string;
15
+ /** 设置文件名 */
16
+ settingsFile: string;
17
+ /** 模板中的源文件名映射 (源文件名 -> 目标文件名) */
18
+ fileRenames?: Record<string, string>;
19
+ }
20
+
1
21
  interface McpService {
2
22
  id: string;
3
23
  name: string;
@@ -28,6 +48,27 @@ declare const CLAUDE_MD_FILE: string;
28
48
  declare const ClAUDE_CONFIG_FILE: string;
29
49
  declare const LEGACY_AICO_CONFIG_FILE: string;
30
50
  declare const AICO_CONFIG_FILE: string;
51
+ /**
52
+ * 安装目标配置映射
53
+ * 支持 claude 和 codebuddy,可扩展到其他目标
54
+ */
55
+ declare const TARGET_CONFIGS: Record<InstallationTarget, TargetConfig>;
56
+ /**
57
+ * 获取指定目标的目录路径
58
+ */
59
+ declare function getTargetDir(target?: InstallationTarget): string;
60
+ /**
61
+ * 获取指定目标的设置文件路径
62
+ */
63
+ declare function getTargetSettingsFile(target?: InstallationTarget): string;
64
+ /**
65
+ * 获取指定目标的主配置文件路径
66
+ */
67
+ declare function getTargetMainConfigFile(target?: InstallationTarget): string;
68
+ /**
69
+ * 获取指定目标的 aico 配置文件路径
70
+ */
71
+ declare function getTargetAicoConfigFile(target?: InstallationTarget): string;
31
72
  declare const SUPPORTED_LANGS: readonly ["zh-CN"];
32
73
  type SupportedLang = (typeof SUPPORTED_LANGS)[number];
33
74
  declare const LANG_LABELS: {
@@ -46,35 +87,6 @@ declare const AI_OUTPUT_LANGUAGES: {
46
87
  type AiOutputLanguage = keyof typeof AI_OUTPUT_LANGUAGES;
47
88
  declare const MCP_SERVICES: McpService[];
48
89
 
49
- /**
50
- * 初始化选项接口
51
- */
52
- interface InitOptions {
53
- aiOutputLang?: AiOutputLanguage | string;
54
- force?: boolean;
55
- skipBanner?: boolean;
56
- skipPrompt?: boolean;
57
- configAction?: 'new' | 'backup' | 'merge' | 'docs-only' | 'skip';
58
- apiType?: 'auth_token' | 'ccr_proxy' | 'skip';
59
- apiKey?: string;
60
- apiUrl?: string;
61
- mcpServices?: string[] | string | boolean;
62
- workflows?: string[] | string | boolean;
63
- aiPersonality?: string;
64
- installCometixLine?: string | boolean;
65
- }
66
- /**
67
- * 初始化命令主函数 - 重构为使用解耦架构
68
- */
69
- declare function init(options?: InitOptions): Promise<void>;
70
-
71
- declare function getPlatform(): "windows" | "macos" | "linux";
72
- declare function commandExists(command: string): Promise<boolean>;
73
-
74
- declare function isClaudeCodeInstalled(): Promise<boolean>;
75
- declare function installClaudeCode(lang: SupportedLang): Promise<void>;
76
- declare function installClaudeCodeSilently(): Promise<void>;
77
-
78
90
  /**
79
91
  * API configuration for Claude Code
80
92
  */
@@ -83,8 +95,8 @@ interface ApiConfig {
83
95
  key: string;
84
96
  }
85
97
 
86
- declare function ensureClaudeDir(): void;
87
- declare function backupExistingConfig(): string | null;
98
+ declare function ensureClaudeDir(target?: InstallationTarget): void;
99
+ declare function backupExistingConfig(target?: InstallationTarget): string | null;
88
100
  declare function copyConfigFiles(lang: SupportedLang, onlyMd?: boolean): void;
89
101
  interface FileCopyConfig {
90
102
  source: string;
@@ -99,8 +111,13 @@ interface FileCopyConfig {
99
111
  };
100
112
  }
101
113
  declare const DEFAULT_FILE_COPY_CONFIGS: FileCopyConfig[];
102
- declare function copyConfigFilesWithConfig(configs?: FileCopyConfig[]): void;
103
- declare function configureApi(apiConfig: ApiConfig | null): ApiConfig | null;
114
+ /**
115
+ * 根据目标生成文件复制配置
116
+ * 支持文件重命名(如 CLAUDE.md -> CODEBUDDY.md)
117
+ */
118
+ declare function getFileCopyConfigsForTarget(target?: InstallationTarget): FileCopyConfig[];
119
+ declare function copyConfigFilesWithConfig(configs?: FileCopyConfig[], target?: InstallationTarget): void;
120
+ declare function configureApi(apiConfig: ApiConfig | null, target?: InstallationTarget): ApiConfig | null;
104
121
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
105
122
  declare function updateDefaultModel(model: 'opus' | 'sonnet'): void;
106
123
  /**
@@ -114,19 +131,51 @@ declare function mergeSettingsFile(templatePath: string, targetPath: string): vo
114
131
  declare function getExistingApiConfig(): ApiConfig | null;
115
132
  declare function applyAiLanguageDirective(aiOutputLang: AiOutputLanguage | string): void;
116
133
 
117
- declare function getMcpConfigPath(): string;
118
- declare function readMcpConfig(): ClaudeConfiguration | null;
119
- declare function writeMcpConfig(config: ClaudeConfiguration): void;
120
- declare function backupMcpConfig(): string | null;
134
+ /**
135
+ * 初始化选项接口
136
+ */
137
+ interface InitOptions {
138
+ aiOutputLang?: AiOutputLanguage | string;
139
+ force?: boolean;
140
+ skipBanner?: boolean;
141
+ skipPrompt?: boolean;
142
+ configAction?: 'new' | 'backup' | 'merge' | 'docs-only' | 'skip';
143
+ apiType?: 'auth_token' | 'ccr_proxy' | 'skip';
144
+ apiKey?: string;
145
+ apiUrl?: string;
146
+ mcpServices?: string[] | string | boolean;
147
+ workflows?: string[] | string | boolean;
148
+ aiPersonality?: string;
149
+ installCometixLine?: string | boolean;
150
+ /** 安装目标:claude 或 codebuddy */
151
+ target?: InstallationTarget;
152
+ }
153
+ /**
154
+ * 初始化命令主函数 - 重构为使用解耦架构
155
+ */
156
+ declare function init(options?: InitOptions): Promise<void>;
157
+
158
+ declare function getPlatform(): "windows" | "macos" | "linux";
159
+ declare function commandExists(command: string): Promise<boolean>;
160
+
161
+ declare function isClaudeCodeInstalled(): Promise<boolean>;
162
+ declare function installClaudeCode(lang: SupportedLang): Promise<void>;
163
+ declare function installClaudeCodeSilently(): Promise<void>;
164
+
165
+ declare function getMcpConfigPath(target?: InstallationTarget): string;
166
+ declare function readMcpConfig(target?: InstallationTarget): ClaudeConfiguration | null;
167
+ declare function writeMcpConfig(config: ClaudeConfiguration, target?: InstallationTarget): void;
168
+ declare function backupMcpConfig(target?: InstallationTarget): string | null;
121
169
  declare function mergeMcpServers(existing: ClaudeConfiguration | null, newServers: Record<string, McpServerConfig>): ClaudeConfiguration;
122
170
  declare function buildMcpServerConfig(baseConfig: McpServerConfig, apiKey?: string, placeholder?: string, envVarName?: string): McpServerConfig;
123
171
  declare function fixWindowsMcpConfig(config: ClaudeConfiguration): ClaudeConfiguration;
124
172
  /**
125
- * 更新 ~/.claude.json 的 env 对象
173
+ * 更新目标配置文件的 env 对象
126
174
  * @param envVars 要设置的环境变量键值对
175
+ * @param target 安装目标,默认为 'claude'
127
176
  */
128
- declare function updateClaudeConfigEnv(envVars: Record<string, string>): void;
129
- declare function addCompletedOnboarding(): void;
177
+ declare function updateClaudeConfigEnv(envVars: Record<string, string>, target?: InstallationTarget): void;
178
+ declare function addCompletedOnboarding(target?: InstallationTarget): void;
130
179
 
131
180
  declare function importRecommendedEnv(): Promise<void>;
132
181
  declare function importRecommendedPermissions(): Promise<void>;
@@ -152,5 +201,5 @@ declare function cleanupPermissions(templatePermissions: string[], userPermissio
152
201
  */
153
202
  declare function mergeAndCleanPermissions(templatePermissions: string[] | undefined, userPermissions: string[] | undefined): string[];
154
203
 
155
- export { AICO_CONFIG_FILE, AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, DEFAULT_FILE_COPY_CONFIGS, LANG_LABELS, LEGACY_AICO_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, copyConfigFilesWithConfig, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, installClaudeCodeSilently, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateClaudeConfigEnv, updateDefaultModel, writeMcpConfig };
204
+ export { AICO_CONFIG_FILE, AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, DEFAULT_FILE_COPY_CONFIGS, LANG_LABELS, LEGACY_AICO_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, TARGET_CONFIGS, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, copyConfigFilesWithConfig, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getFileCopyConfigsForTarget, getMcpConfigPath, getPlatform, getTargetAicoConfigFile, getTargetDir, getTargetMainConfigFile, getTargetSettingsFile, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, installClaudeCodeSilently, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateClaudeConfigEnv, updateDefaultModel, writeMcpConfig };
156
205
  export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, FileCopyConfig, McpServerConfig, McpService, SupportedLang };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AICO_CONFIG_FILE, k as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, D as DEFAULT_FILE_COPY_CONFIGS, j as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, N as addCompletedOnboarding, z as applyAiLanguageDirective, r as backupExistingConfig, G as backupMcpConfig, I as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, u as configureApi, s as copyConfigFiles, t as copyConfigFilesWithConfig, q as ensureClaudeDir, J as fixWindowsMcpConfig, y as getExistingApiConfig, B as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, n as installClaudeCode, p as installClaudeCodeSilently, l as isClaudeCodeInstalled, m as mergeAndCleanPermissions, v as mergeConfigs, H as mergeMcpServers, x as mergeSettingsFile, o as openSettingsJson, E as readMcpConfig, K as updateClaudeConfigEnv, w as updateDefaultModel, F as writeMcpConfig } from './chunks/simple-config.mjs';
1
+ export { A as AICO_CONFIG_FILE, q as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, D as DEFAULT_FILE_COPY_CONFIGS, p as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, n as SUPPORTED_LANGS, T as TARGET_CONFIGS, U as addCompletedOnboarding, H as applyAiLanguageDirective, v as backupExistingConfig, N as backupMcpConfig, P as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, z as configureApi, w as copyConfigFiles, y as copyConfigFilesWithConfig, u as ensureClaudeDir, Q as fixWindowsMcpConfig, G as getExistingApiConfig, x as getFileCopyConfigsForTarget, I as getMcpConfigPath, g as getPlatform, l as getTargetAicoConfigFile, h as getTargetDir, k as getTargetMainConfigFile, j as getTargetSettingsFile, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, s as installClaudeCode, t as installClaudeCodeSilently, r as isClaudeCodeInstalled, m as mergeAndCleanPermissions, B as mergeConfigs, O as mergeMcpServers, F as mergeSettingsFile, o as openSettingsJson, J as readMcpConfig, R as updateClaudeConfigEnv, E as updateDefaultModel, K as writeMcpConfig } from './chunks/simple-config.mjs';
2
2
  import 'ansis';
3
3
  import 'inquirer';
4
4
  import 'tinyexec';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aico-cli",
3
- "version": "2.0.36",
3
+ "version": "2.0.37",
4
4
  "packageManager": "pnpm@9.15.9",
5
5
  "description": "AI CLI",
6
6
  "repository": {