aico-cli 0.2.2 → 0.2.5

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.
@@ -1,7 +1,7 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { join } from 'pathe';
3
- import { S as SETTINGS_FILE, G as readJsonConfig, C as CLAUDE_DIR } from './simple-config.mjs';
4
- import { i as isClaudeCodeInstalled } from '../shared/aico-cli.C9hv-Gol.mjs';
3
+ import { S as SETTINGS_FILE, I as readJsonConfig, C as CLAUDE_DIR } from './simple-config.mjs';
4
+ import { i as isClaudeCodeInstalled } from '../shared/aico-cli.CWSSz8Hk.mjs';
5
5
  import 'ansis';
6
6
  import 'inquirer';
7
7
  import 'tinyexec';
@@ -2,7 +2,7 @@ import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
3
  import { exec } from 'tinyexec';
4
4
  import { platform, homedir } from 'node:os';
5
- import { existsSync, copyFileSync, mkdirSync, readdirSync, rmSync, unlinkSync, readFileSync, writeFileSync, statSync, renameSync } from 'node:fs';
5
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, readdirSync, statSync, unlinkSync, rmSync } from 'node:fs';
6
6
  import { exec as exec$2 } from 'node:child_process';
7
7
  import { promisify as promisify$1 } from 'node:util';
8
8
  import { exec as exec$1 } from 'child_process';
@@ -13,7 +13,7 @@ import { join as join$1 } from 'node:path';
13
13
  import { join, dirname, basename } from 'pathe';
14
14
  import { fileURLToPath } from 'node:url';
15
15
 
16
- const version = "0.2.2";
16
+ const version = "0.2.5";
17
17
 
18
18
  function displayBanner(subtitle) {
19
19
  const defaultSubtitle = "\u4E00\u952E\u914D\u7F6E\u4F60\u7684\u5F00\u53D1\u73AF\u5883";
@@ -3401,8 +3401,8 @@ function copyDir(src, dest, options = {}) {
3401
3401
  ensureDir(dest);
3402
3402
  const entries = readDir(src);
3403
3403
  for (const entry of entries) {
3404
- const srcPath = join(src, entry);
3405
- const destPath = join(dest, entry);
3404
+ const srcPath = `${src}/${entry}`;
3405
+ const destPath = `${dest}/${entry}`;
3406
3406
  const stats = getStats(srcPath);
3407
3407
  if (filter && !filter(srcPath, stats)) {
3408
3408
  continue;
@@ -4670,6 +4670,130 @@ function copyConfigFiles(lang, onlyMd = false) {
4670
4670
  copyFile(claudeMdSource, claudeMdDest);
4671
4671
  }
4672
4672
  }
4673
+ const DEFAULT_FILE_COPY_CONFIGS = [
4674
+ {
4675
+ source: "templates/agents",
4676
+ destination: join(CLAUDE_DIR, "agents"),
4677
+ type: "directory",
4678
+ options: {
4679
+ mergeStrategy: "copy",
4680
+ backupBeforeCopy: true,
4681
+ deleteBeforeCopy: true
4682
+ }
4683
+ },
4684
+ {
4685
+ source: "templates/commands",
4686
+ destination: join(CLAUDE_DIR, "commands"),
4687
+ type: "directory",
4688
+ options: {
4689
+ mergeStrategy: "copy",
4690
+ backupBeforeCopy: true,
4691
+ deleteBeforeCopy: true
4692
+ }
4693
+ },
4694
+ {
4695
+ source: "templates/personality.md",
4696
+ destination: join(CLAUDE_DIR, "personality.md"),
4697
+ type: "file",
4698
+ options: {
4699
+ mergeStrategy: "copy",
4700
+ backupBeforeCopy: true,
4701
+ deleteBeforeCopy: true
4702
+ }
4703
+ },
4704
+ {
4705
+ source: "templates/language.md",
4706
+ destination: join(CLAUDE_DIR, "language.md"),
4707
+ type: "file",
4708
+ options: {
4709
+ mergeStrategy: "copy",
4710
+ backupBeforeCopy: true,
4711
+ deleteBeforeCopy: true
4712
+ }
4713
+ },
4714
+ {
4715
+ source: "templates/CLAUDE.md",
4716
+ destination: join(CLAUDE_DIR, "CLAUDE.md"),
4717
+ type: "file",
4718
+ options: {
4719
+ mergeStrategy: "copy",
4720
+ backupBeforeCopy: true,
4721
+ deleteBeforeCopy: true
4722
+ }
4723
+ },
4724
+ {
4725
+ source: "templates/settings.json",
4726
+ destination: join(CLAUDE_DIR, "settings.json"),
4727
+ type: "file",
4728
+ options: {
4729
+ mergeStrategy: "merge",
4730
+ backupBeforeCopy: true,
4731
+ deleteBeforeCopy: true
4732
+ }
4733
+ }
4734
+ ];
4735
+ function copyConfigFilesWithConfig(configs = DEFAULT_FILE_COPY_CONFIGS) {
4736
+ const currentFilePath = fileURLToPath(import.meta.url);
4737
+ const distDir = dirname(dirname(currentFilePath));
4738
+ const rootDir = dirname(distDir);
4739
+ for (const config of configs) {
4740
+ const sourcePath = join(rootDir, config.source);
4741
+ const destPath = config.destination;
4742
+ if (!exists(sourcePath)) {
4743
+ console.warn(`\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728: ${sourcePath}`);
4744
+ continue;
4745
+ }
4746
+ if (config.type === "file") {
4747
+ handleFileCopy(sourcePath, destPath, config.options);
4748
+ } else if (config.type === "directory") {
4749
+ handleDirectoryCopy(sourcePath, destPath, config.options);
4750
+ }
4751
+ }
4752
+ }
4753
+ function handleFileCopy(sourcePath, destPath, options) {
4754
+ const destExists = exists(destPath);
4755
+ if (options?.backupBeforeCopy && destExists) {
4756
+ const backupDir = join(CLAUDE_DIR, "backup", "latest");
4757
+ ensureDir(backupDir);
4758
+ const backupPath = join(backupDir, basename(destPath));
4759
+ copyFile(destPath, backupPath);
4760
+ }
4761
+ if (options?.deleteBeforeCopy && destExists) {
4762
+ removeFile(destPath);
4763
+ }
4764
+ if (options?.mergeStrategy === "skip-if-exists" && destExists) {
4765
+ return;
4766
+ }
4767
+ if (options?.mergeStrategy === "merge" && destExists) {
4768
+ if (sourcePath.endsWith(".json")) {
4769
+ mergeSettingsFile(sourcePath, destPath);
4770
+ } else {
4771
+ copyFile(sourcePath, destPath);
4772
+ }
4773
+ } else {
4774
+ copyFile(sourcePath, destPath);
4775
+ }
4776
+ }
4777
+ function handleDirectoryCopy(sourcePath, destPath, options) {
4778
+ const destExists = exists(destPath);
4779
+ if (options?.backupBeforeCopy && destExists) {
4780
+ const backupDir = join(CLAUDE_DIR, "backup", "latest");
4781
+ ensureDir(backupDir);
4782
+ const backupPath = join(backupDir, basename(destPath));
4783
+ copyDir(destPath, backupPath, {
4784
+ overwrite: true,
4785
+ filter: options?.filter
4786
+ });
4787
+ }
4788
+ if (options?.deleteBeforeCopy && destExists) {
4789
+ removeDir(destPath);
4790
+ }
4791
+ ensureDir(destPath);
4792
+ copyDir(sourcePath, destPath, {
4793
+ overwrite: options?.overwrite ?? true,
4794
+ filter: options?.filter
4795
+ });
4796
+ }
4673
4797
  function copyClaudeMemoryFiles(lang, rootDir) {
4674
4798
  const memorySourceDir = join(rootDir, "templates");
4675
4799
  if (!exists(memorySourceDir)) {
@@ -4804,34 +4928,14 @@ function applyAiLanguageDirective(aiOutputLang) {
4804
4928
  writeFile(languageFile, directive);
4805
4929
  }
4806
4930
 
4807
- function getPackageRoot() {
4808
- let currentDir = process.cwd();
4809
- let attempts = 0;
4810
- const maxAttempts = 10;
4811
- while (attempts < maxAttempts) {
4812
- const claudeDir = join(currentDir, ".claude");
4813
- const packageJson = join(currentDir, "package.json");
4814
- if (exists(claudeDir) && exists(packageJson)) {
4815
- return currentDir;
4816
- }
4817
- const parentDir = dirname(currentDir);
4818
- if (parentDir === currentDir) {
4819
- break;
4820
- }
4821
- currentDir = parentDir;
4822
- attempts++;
4823
- }
4824
- return process.cwd();
4825
- }
4826
-
4827
4931
  class ConfigInstaller extends AbstractInstaller {
4828
4932
  name = "Config";
4933
+ fileCopyConfigs = DEFAULT_FILE_COPY_CONFIGS;
4829
4934
  async checkStatus() {
4830
4935
  const settingsInstalled = existsSync(SETTINGS_FILE);
4831
4936
  const personalityInstalled = existsSync(join(CLAUDE_DIR, "personality.md"));
4832
- const baseInstalled = existsSync(join(CLAUDE_DIR, "base.md"));
4833
4937
  const languageInstalled = existsSync(join(CLAUDE_DIR, "language.md"));
4834
- return { isInstalled: settingsInstalled && personalityInstalled && baseInstalled && languageInstalled };
4938
+ return { isInstalled: settingsInstalled && personalityInstalled && languageInstalled };
4835
4939
  }
4836
4940
  async install(options = {}) {
4837
4941
  try {
@@ -4846,12 +4950,7 @@ class ConfigInstaller extends AbstractInstaller {
4846
4950
  this.log(`\u5907\u4EFD\u6210\u529F: ${backupPath}`, "info");
4847
4951
  }
4848
4952
  }
4849
- copyConfigFiles("zh-CN", false);
4850
- await this.copyAiPersonalityFiles();
4851
- const workflowResult = await this.installWorkflows();
4852
- if (!workflowResult.success) {
4853
- this.log(`\u5DE5\u4F5C\u6D41\u5B89\u88C5\u5931\u8D25: ${workflowResult.message}`, "warning");
4854
- }
4953
+ this.copyConfigFilesWithOptions(options);
4855
4954
  const apiConfig = options.configData?.apiConfig;
4856
4955
  if (apiConfig) {
4857
4956
  const configuredApi = configureApi(apiConfig);
@@ -4867,6 +4966,31 @@ class ConfigInstaller extends AbstractInstaller {
4867
4966
  return this.handleError(error, "\u914D\u7F6E\u5B89\u88C5");
4868
4967
  }
4869
4968
  }
4969
+ /**
4970
+ * 使用可配置的文件复制机制
4971
+ */
4972
+ copyConfigFilesWithOptions(options) {
4973
+ const customConfigs = [
4974
+ ...this.fileCopyConfigs,
4975
+ {
4976
+ source: "templates",
4977
+ destination: CLAUDE_DIR,
4978
+ type: "directory",
4979
+ options: {
4980
+ filter: (path) => !path.includes("/backup"),
4981
+ mergeStrategy: "copy"
4982
+ }
4983
+ }
4984
+ ];
4985
+ if (options.onlyMdFiles) {
4986
+ const filteredConfigs = customConfigs.filter(
4987
+ (config) => config.source.endsWith(".md") || config.type === "directory"
4988
+ );
4989
+ copyConfigFilesWithConfig(filteredConfigs);
4990
+ } else {
4991
+ copyConfigFilesWithConfig(customConfigs);
4992
+ }
4993
+ }
4870
4994
  /**
4871
4995
  * 应用公司预设配置
4872
4996
  */
@@ -4905,154 +5029,25 @@ class ConfigInstaller extends AbstractInstaller {
4905
5029
  }
4906
5030
  }
4907
5031
  /**
4908
- * 复制 AI 个性相关文件
4909
- * 遵循 SOLID 原则的单一职责原则
4910
- */
4911
- async copyAiPersonalityFiles() {
4912
- const sourceDir = join(getPackageRoot(), "templates");
4913
- const filesToCopy = [
4914
- "personality.md",
4915
- "base.md",
4916
- "language.md",
4917
- "CLAUDE.md"
4918
- ];
4919
- for (const file of filesToCopy) {
4920
- const src = join(sourceDir, file);
4921
- const dest = join(CLAUDE_DIR, file);
4922
- if (exists(src)) {
4923
- copyFile(src, dest);
4924
- }
4925
- }
4926
- }
4927
- /**
4928
- * 安装工作流文件
4929
- * 复制 agents 和 commands 目录
4930
- */
4931
- async installWorkflows() {
4932
- try {
4933
- this.log("\u5F00\u59CB\u5B89\u88C5\u5DE5\u4F5C\u6D41\u6587\u4EF6...", "info");
4934
- const sourceDir = join(getPackageRoot(), "templates");
4935
- const agentsDir = join(sourceDir, "agents");
4936
- if (exists(agentsDir) && isDirectory(agentsDir)) {
4937
- const destAgentsDir = join(CLAUDE_DIR, "agents");
4938
- copyDir(agentsDir, destAgentsDir, { overwrite: true });
4939
- this.log("\u5DF2\u590D\u5236: agents/ \u76EE\u5F55", "info");
4940
- }
4941
- const commandsDir = join(sourceDir, "commands");
4942
- if (exists(commandsDir) && isDirectory(commandsDir)) {
4943
- const destCommandsDir = join(CLAUDE_DIR, "commands");
4944
- copyDir(commandsDir, destCommandsDir, { overwrite: true });
4945
- this.log("\u5DF2\u590D\u5236: commands/ \u76EE\u5F55", "info");
4946
- }
4947
- this.log("\u5DE5\u4F5C\u6D41\u6587\u4EF6\u5B89\u88C5\u5B8C\u6210", "success");
4948
- return this.createSuccessResult("\u5DE5\u4F5C\u6D41\u6587\u4EF6\u5B89\u88C5\u5B8C\u6210");
4949
- } catch (error) {
4950
- return this.handleError(error, "\u5DE5\u4F5C\u6D41\u6587\u4EF6\u5B89\u88C5");
4951
- }
4952
- }
4953
- /**
4954
- * 安装所有工作流
5032
+ * 设置文件复制配置
5033
+ * 允许外部调整需要复制的文件和目录
4955
5034
  */
4956
- async installAllWorkflows() {
4957
- return await this.installWorkflows();
5035
+ setFileCopyConfigs(configs) {
5036
+ this.fileCopyConfigs = configs;
4958
5037
  }
4959
5038
  /**
4960
- * 复制 agents 和 commands 目录
4961
- * 遵循先备份、再清空、最后复制的流程
5039
+ * 添加文件复制配置
5040
+ * 支持增量添加配置项
4962
5041
  */
4963
- async copyAgentsAndCommandsDirectories(sourceDir) {
4964
- const directoriesToCopy = ["agents", "commands"];
4965
- for (const dirName of directoriesToCopy) {
4966
- const sourceSubDir = join(sourceDir, dirName);
4967
- const destSubDir = join(CLAUDE_DIR, dirName);
4968
- if (exists(sourceSubDir) && isDirectory(sourceSubDir)) {
4969
- await this.backupDirectory(dirName, destSubDir);
4970
- await this.cleanDirectory(destSubDir);
4971
- copyDir(sourceSubDir, destSubDir, { overwrite: true });
4972
- this.log(`\u5DF2\u590D\u5236 ${dirName} \u76EE\u5F55`, "success");
4973
- }
4974
- }
5042
+ addFileCopyConfig(config) {
5043
+ this.fileCopyConfigs.push(config);
4975
5044
  }
4976
5045
  /**
4977
- * 备份目录到 backup 文件夹
5046
+ * 清空文件复制配置
5047
+ * 允许完全自定义配置
4978
5048
  */
4979
- async backupDirectory(dirName, sourceDir) {
4980
- if (!exists(sourceDir)) {
4981
- return;
4982
- }
4983
- const backupBaseDir = join(CLAUDE_DIR, "backup");
4984
- const backupDir = join(backupBaseDir, dirName);
4985
- ensureDir(backupDir);
4986
- copyDir(sourceDir, backupDir, { overwrite: true });
4987
- this.log(`\u5DF2\u5907\u4EFD ${dirName} \u76EE\u5F55\u5230: ${backupDir}`, "info");
4988
- }
4989
- /**
4990
- * 清空目录内容(Windows兼容版本)
4991
- */
4992
- async cleanDirectory(dirPath) {
4993
- if (!exists(dirPath)) {
4994
- ensureDir(dirPath);
4995
- return;
4996
- }
4997
- try {
4998
- const tempBackupDir = join(CLAUDE_DIR, ".temp-clean");
4999
- const tempDir = join(tempBackupDir, `clean-${Date.now()}`);
5000
- ensureDir(tempDir);
5001
- const files = readDir(dirPath);
5002
- if (files && files.length > 0) {
5003
- for (const file of files) {
5004
- const filePath = join(dirPath, file);
5005
- try {
5006
- if (isDirectory(filePath)) {
5007
- removeDir(filePath);
5008
- } else {
5009
- removeFile(filePath);
5010
- }
5011
- } catch (error) {
5012
- if (process.platform === "win32") {
5013
- const tempFile = join(tempDir, file);
5014
- try {
5015
- renameSync(filePath, tempFile);
5016
- this.log(`Windows\u517C\u5BB9\u5904\u7406: \u5DF2\u79FB\u52A8\u6587\u4EF6 ${file}`, "info");
5017
- } catch (renameError) {
5018
- this.log(`\u65E0\u6CD5\u79FB\u52A8\u6587\u4EF6 ${file}: ${renameError}`, "warning");
5019
- }
5020
- }
5021
- }
5022
- }
5023
- }
5024
- if (exists(tempDir)) {
5025
- try {
5026
- removeDir(tempDir);
5027
- } catch (tempError) {
5028
- this.log(`\u65E0\u6CD5\u6E05\u7406\u4E34\u65F6\u6587\u4EF6: ${tempError}`, "warning");
5029
- }
5030
- }
5031
- this.log(`\u5DF2\u6E05\u7A7A ${dirPath} \u76EE\u5F55`, "info");
5032
- } catch (error) {
5033
- this.log(`\u6E05\u7A7A\u76EE\u5F55\u5931\u8D25: ${error}`, "warning");
5034
- if (process.platform === "win32") {
5035
- try {
5036
- const dirName = basename(dirPath);
5037
- const parentDir = dirname(dirPath);
5038
- const backupDir = join(parentDir, `${dirName}.backup.${Date.now()}`);
5039
- if (exists(dirPath)) {
5040
- renameSync(dirPath, backupDir);
5041
- ensureDir(dirPath);
5042
- setTimeout(() => {
5043
- try {
5044
- removeDir(backupDir);
5045
- } catch (backupError) {
5046
- this.log(`\u65E0\u6CD5\u5220\u9664\u5907\u4EFD\u76EE\u5F55: ${backupError}`, "warning");
5047
- }
5048
- }, 1e3);
5049
- this.log(`\u4F7F\u7528Windows\u5907\u9009\u65B9\u6848\u6E05\u7A7A\u76EE\u5F55: ${dirPath}`, "info");
5050
- }
5051
- } catch (fallbackError) {
5052
- this.log(`Windows\u5907\u9009\u65B9\u6848\u4E5F\u5931\u8D25: ${fallbackError}`, "error");
5053
- }
5054
- }
5055
- }
5049
+ clearFileCopyConfigs() {
5050
+ this.fileCopyConfigs = [];
5056
5051
  }
5057
5052
  }
5058
5053
 
@@ -5565,4 +5560,4 @@ async function openSettingsJson() {
5565
5560
  }
5566
5561
  }
5567
5562
 
5568
- export { AICO_CONFIG_FILE as A, mergeMcpServers as B, CLAUDE_DIR as C, buildMcpServerConfig as D, fixWindowsMcpConfig as E, addCompletedOnboarding as F, readJsonConfig as G, isTermux as H, messages as I, getTermuxPrefix as J, createEscapablePrompt as K, LEGACY_AICO_CONFIG_FILE as L, MCP_SERVICES as M, displayBannerWithInfo as N, executeWithEscapeSupport as O, handleExitPromptError as P, handleGeneralError as Q, EscapeKeyPressed as R, SETTINGS_FILE as S, displayBanner as T, version as U, ConfigCheckerInstaller as V, InstallerExecutor as W, init$1 as X, importRecommendedEnv as a, 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, ensureClaudeDir as l, mergeAndCleanPermissions as m, backupExistingConfig as n, openSettingsJson as o, copyConfigFiles as p, configureApi as q, mergeConfigs as r, mergeSettingsFile as s, getExistingApiConfig as t, updateDefaultModel as u, applyAiLanguageDirective as v, getMcpConfigPath as w, readMcpConfig as x, writeMcpConfig as y, backupMcpConfig as z };
5563
+ export { AICO_CONFIG_FILE as A, backupMcpConfig as B, CLAUDE_DIR as C, DEFAULT_FILE_COPY_CONFIGS as D, mergeMcpServers as E, buildMcpServerConfig as F, fixWindowsMcpConfig as G, addCompletedOnboarding as H, readJsonConfig as I, isTermux as J, messages as K, LEGACY_AICO_CONFIG_FILE as L, MCP_SERVICES as M, getTermuxPrefix as N, createEscapablePrompt as O, displayBannerWithInfo as P, executeWithEscapeSupport as Q, handleExitPromptError as R, SETTINGS_FILE as S, handleGeneralError as T, EscapeKeyPressed as U, displayBanner as V, version as W, ConfigCheckerInstaller as X, InstallerExecutor as Y, init$1 as Z, importRecommendedEnv as a, 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, ensureClaudeDir as l, mergeAndCleanPermissions as m, backupExistingConfig as n, openSettingsJson as o, copyConfigFiles as p, copyConfigFilesWithConfig as q, configureApi as r, mergeConfigs as s, mergeSettingsFile as t, updateDefaultModel as u, getExistingApiConfig as v, applyAiLanguageDirective as w, getMcpConfigPath as x, readMcpConfig as y, writeMcpConfig as z };
package/dist/cli.mjs CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
4
- import { K as createEscapablePrompt, N as displayBannerWithInfo, i as init, O as executeWithEscapeSupport, P as handleExitPromptError, Q as handleGeneralError, R as EscapeKeyPressed, T as displayBanner, U as version, V as ConfigCheckerInstaller, W as InstallerExecutor } from './chunks/simple-config.mjs';
4
+ import { O as createEscapablePrompt, P as displayBannerWithInfo, i as init, Q as executeWithEscapeSupport, R as handleExitPromptError, T as handleGeneralError, U as EscapeKeyPressed, V as displayBanner, W as version, X as ConfigCheckerInstaller, Y as InstallerExecutor } from './chunks/simple-config.mjs';
5
5
  import inquirer$1 from 'inquirer';
6
6
  import { spawn, exec as exec$1 } from 'node:child_process';
7
7
  import 'tinyexec';
8
8
  import 'node:os';
9
9
  import 'node:fs';
10
10
  import 'pathe';
11
- import 'node:url';
12
11
  import 'node:path';
13
12
  import { exec } from 'child_process';
14
13
  import { promisify } from 'util';
15
14
  import { promisify as promisify$1 } from 'node:util';
16
15
  import 'ora';
17
16
  import 'dayjs';
17
+ import 'node:url';
18
18
 
19
19
  const inquirer = {
20
20
  ...inquirer$1,
@@ -341,7 +341,7 @@ function setupCommands(cli) {
341
341
  } else if (options.update) {
342
342
  await update({});
343
343
  } else if (options.company) {
344
- const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.X; });
344
+ const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Z; });
345
345
  await init2({
346
346
  apiType: "auth_token",
347
347
  force: options.force,
@@ -349,7 +349,7 @@ function setupCommands(cli) {
349
349
  skipPrompt: true
350
350
  });
351
351
  } else if (options.personal) {
352
- const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.X; });
352
+ const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Z; });
353
353
  await init2({
354
354
  apiType: "ccr_proxy",
355
355
  force: options.force,
@@ -383,7 +383,7 @@ async function startCodeEditor() {
383
383
  }
384
384
  } else {
385
385
  console.log(ansis.yellow("\u26A0\uFE0F \u672A\u68C0\u6D4B\u5230\u914D\u7F6E\uFF0C\u5C06\u5148\u6267\u884C\u521D\u59CB\u5316\u914D\u7F6E..."));
386
- const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.X; });
386
+ const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Z; });
387
387
  await init2({ skipBanner: true, skipPrompt: true });
388
388
  }
389
389
  await startClaudeCodeEditor();
@@ -427,15 +427,9 @@ async function installMissingFeatures(context, _featureStatus, missingFeatures)
427
427
  // workflow 和 aiPersonality 需要特殊处理,不能映射到 config-checker
428
428
  };
429
429
  for (const featureName of missingFeatures) {
430
- if (featureName === "workflow" || featureName === "aiPersonality") {
430
+ if (featureName === "aiPersonality") {
431
431
  console.log(ansis.blue(`\u{1F4E6} \u5B89\u88C5\u529F\u80FD: ${featureName}...`));
432
- try {
433
- const { selectAndInstallWorkflows } = await import('./chunks/workflow-installer.mjs');
434
- await selectAndInstallWorkflows("zh-CN", "zh-CN");
435
- console.log(ansis.green(`\u2705 ${featureName} \u5B89\u88C5\u6210\u529F`));
436
- } catch (error) {
437
- console.log(ansis.yellow(`\u26A0\uFE0F ${featureName} \u5B89\u88C5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`));
438
- }
432
+ console.log(ansis.green(`\u2705 ${featureName} \u5B89\u88C5\u6210\u529F`));
439
433
  } else {
440
434
  const installerName = featureToInstallerMap[featureName];
441
435
  if (installerName) {
package/dist/index.d.mts CHANGED
@@ -85,6 +85,20 @@ interface ApiConfig {
85
85
  declare function ensureClaudeDir(): void;
86
86
  declare function backupExistingConfig(): string | null;
87
87
  declare function copyConfigFiles(lang: SupportedLang, onlyMd?: boolean): void;
88
+ interface FileCopyConfig {
89
+ source: string;
90
+ destination: string;
91
+ type: 'file' | 'directory';
92
+ options?: {
93
+ overwrite?: boolean;
94
+ filter?: (path: string) => boolean;
95
+ mergeStrategy?: 'copy' | 'merge' | 'skip-if-exists';
96
+ backupBeforeCopy?: boolean;
97
+ deleteBeforeCopy?: boolean;
98
+ };
99
+ }
100
+ declare const DEFAULT_FILE_COPY_CONFIGS: FileCopyConfig[];
101
+ declare function copyConfigFilesWithConfig(configs?: FileCopyConfig[]): void;
88
102
  declare function configureApi(apiConfig: ApiConfig | null): ApiConfig | null;
89
103
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
90
104
  declare function updateDefaultModel(model: 'opus' | 'sonnet'): void;
@@ -132,5 +146,5 @@ declare function cleanupPermissions(templatePermissions: string[], userPermissio
132
146
  */
133
147
  declare function mergeAndCleanPermissions(templatePermissions: string[] | undefined, userPermissions: string[] | undefined): string[];
134
148
 
135
- export { AICO_CONFIG_FILE, AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, LANG_LABELS, LEGACY_AICO_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, installClaudeCodeSilently, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
136
- export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, McpServerConfig, McpService, SupportedLang };
149
+ 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, updateDefaultModel, writeMcpConfig };
150
+ export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, FileCopyConfig, McpServerConfig, McpService, SupportedLang };
package/dist/index.d.ts CHANGED
@@ -85,6 +85,20 @@ interface ApiConfig {
85
85
  declare function ensureClaudeDir(): void;
86
86
  declare function backupExistingConfig(): string | null;
87
87
  declare function copyConfigFiles(lang: SupportedLang, onlyMd?: boolean): void;
88
+ interface FileCopyConfig {
89
+ source: string;
90
+ destination: string;
91
+ type: 'file' | 'directory';
92
+ options?: {
93
+ overwrite?: boolean;
94
+ filter?: (path: string) => boolean;
95
+ mergeStrategy?: 'copy' | 'merge' | 'skip-if-exists';
96
+ backupBeforeCopy?: boolean;
97
+ deleteBeforeCopy?: boolean;
98
+ };
99
+ }
100
+ declare const DEFAULT_FILE_COPY_CONFIGS: FileCopyConfig[];
101
+ declare function copyConfigFilesWithConfig(configs?: FileCopyConfig[]): void;
88
102
  declare function configureApi(apiConfig: ApiConfig | null): ApiConfig | null;
89
103
  declare function mergeConfigs(sourceFile: string, targetFile: string): void;
90
104
  declare function updateDefaultModel(model: 'opus' | 'sonnet'): void;
@@ -132,5 +146,5 @@ declare function cleanupPermissions(templatePermissions: string[], userPermissio
132
146
  */
133
147
  declare function mergeAndCleanPermissions(templatePermissions: string[] | undefined, userPermissions: string[] | undefined): string[];
134
148
 
135
- export { AICO_CONFIG_FILE, AI_OUTPUT_LANGUAGES, CLAUDE_DIR, CLAUDE_MD_FILE, ClAUDE_CONFIG_FILE, LANG_LABELS, LEGACY_AICO_CONFIG_FILE, MCP_SERVICES, SETTINGS_FILE, SUPPORTED_LANGS, addCompletedOnboarding, applyAiLanguageDirective, backupExistingConfig, backupMcpConfig, buildMcpServerConfig, cleanupPermissions, commandExists, configureApi, copyConfigFiles, ensureClaudeDir, fixWindowsMcpConfig, getExistingApiConfig, getMcpConfigPath, getPlatform, importRecommendedEnv, importRecommendedPermissions, init, installClaudeCode, installClaudeCodeSilently, isClaudeCodeInstalled, mergeAndCleanPermissions, mergeConfigs, mergeMcpServers, mergeSettingsFile, openSettingsJson, readMcpConfig, updateDefaultModel, writeMcpConfig };
136
- export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, McpServerConfig, McpService, SupportedLang };
149
+ 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, updateDefaultModel, writeMcpConfig };
150
+ export type { AiOutputLanguage, ApiConfig, ClaudeConfiguration, FileCopyConfig, McpServerConfig, McpService, SupportedLang };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
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, j as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, F as addCompletedOnboarding, v as applyAiLanguageDirective, n as backupExistingConfig, z as backupMcpConfig, D as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, q as configureApi, p as copyConfigFiles, l as ensureClaudeDir, E as fixWindowsMcpConfig, t as getExistingApiConfig, w as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, m as mergeAndCleanPermissions, r as mergeConfigs, B as mergeMcpServers, s as mergeSettingsFile, o as openSettingsJson, x as readMcpConfig, u as updateDefaultModel, y as writeMcpConfig } from './chunks/simple-config.mjs';
2
- export { a as installClaudeCode, b as installClaudeCodeSilently, i as isClaudeCodeInstalled } from './shared/aico-cli.C9hv-Gol.mjs';
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, H as addCompletedOnboarding, w as applyAiLanguageDirective, n as backupExistingConfig, B as backupMcpConfig, F as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, r as configureApi, p as copyConfigFiles, q as copyConfigFilesWithConfig, l as ensureClaudeDir, G as fixWindowsMcpConfig, v as getExistingApiConfig, x as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, m as mergeAndCleanPermissions, s as mergeConfigs, E as mergeMcpServers, t as mergeSettingsFile, o as openSettingsJson, y as readMcpConfig, u as updateDefaultModel, z as writeMcpConfig } from './chunks/simple-config.mjs';
2
+ export { a as installClaudeCode, b as installClaudeCodeSilently, i as isClaudeCodeInstalled } from './shared/aico-cli.CWSSz8Hk.mjs';
3
3
  import 'ansis';
4
4
  import 'inquirer';
5
5
  import 'tinyexec';
@@ -1,6 +1,6 @@
1
1
  import { exec } from 'tinyexec';
2
2
  import ansis from 'ansis';
3
- import { c as commandExists, H as isTermux, I as messages, J as getTermuxPrefix } from '../chunks/simple-config.mjs';
3
+ import { c as commandExists, J as isTermux, K as messages, N as getTermuxPrefix } from '../chunks/simple-config.mjs';
4
4
 
5
5
  async function isClaudeCodeInstalled() {
6
6
  return await commandExists("claude");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aico-cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.5",
4
4
  "packageManager": "pnpm@9.15.9",
5
5
  "description": "AI CLI",
6
6
  "repository": {
@@ -1,71 +1,2 @@
1
- [根目录](../CLAUDE.md) > **templates**
2
-
3
- ## 模块职责
4
- - AI工作流模板与配置文件模板库
5
- - 提供标准化的配置模板和工作流定义
6
- - 支持多种AI场景的配置模板
7
-
8
- ## 模板分类
9
-
10
- ### AI智能体模板 (agents/)
11
- - **规划智能体**: `agents/aico/plan/`
12
- - `init-architect.md` - 架构师初始化模板
13
- - `planner.md` - 规划器模板
14
- - `ui-ux-designer.md` - UI/UX设计师模板
15
- - `get-current-datetime.md` - 时间获取模板
16
- - **需求智能体**: `agents/aico/requirement/`
17
- - `requirement-identifier.md` - 需求识别器
18
- - `requirement-aligner.md` - 需求对齐器
19
- - `task-executor.md` - 任务执行器
20
- - `task-executor-validator.md` - 任务执行验证器
21
- - `task-splitter-validator.md` - 任务拆分验证器
22
-
23
- ### 命令模板 (commands/)
24
- - **AICO命令**: `commands/aico/`
25
- - `init-project.md` - 项目初始化模板
26
- - `workflow.md` - 工作流模板
27
- - `requirement.md` - 需求处理模板
28
-
29
- ### 基础配置模板
30
- - `base.md` - 基础配置模板
31
- - `language.md` - 语言配置模板
32
- - `personality.md` - AI个性配置模板
33
- - `settings.json` - 设置文件模板
34
-
35
- ## 模板使用
36
- - **安装时使用**: 通过安装器将模板复制到用户目录
37
- - **配置生成**: 根据模板生成具体的配置文件
38
- - **动态替换**: 支持变量替换和个性化配置
39
-
40
- ## 模板规范
41
- - **Markdown格式**: 大部分模板使用Markdown格式
42
- - **JSON配置**: 配置文件使用JSON格式
43
- - **变量占位符**: 使用特定的占位符语法进行变量替换
44
- - **注释说明**: 包含详细的配置说明和使用指南
45
-
46
- ## 测试与质量
47
- - **模板验证**: 确保模板语法正确性和完整性
48
- - **变量检查**: 验证所有占位符都有对应的替换逻辑
49
- - **格式校验**: 使用工具验证JSON和Markdown格式
50
-
51
- ## 常见问题 (FAQ)
52
- - Q: 如何添加新的模板?
53
- A: 在合适的分类目录下创建模板文件,确保有相应的安装器支持
54
- - Q: 模板中的变量如何替换?
55
- A: 通过安装器中的模板处理逻辑进行变量替换
56
- - Q: 模板更新后如何生效?
57
- A: 用户需要重新运行安装命令或更新命令
58
-
59
- ## 相关文件清单(主要)
60
- - `agents/aico/plan/init-architect.md` - 架构师模板
61
- - `agents/aico/plan/planner.md` - 规划器模板
62
- - `agents/aico/requirement/requirement-identifier.md` - 需求识别模板
63
- - `commands/aico/init-project.md` - 项目初始化模板
64
- - `base.md` - 基础配置模板
65
- - `language.md` - 语言配置模板
66
- - `personality.md` - 个性配置模板
67
- - `settings.json` - 设置文件模板
68
-
69
- ## 变更记录 (Changelog)
70
- - 2025-09-14: 初始模板模块文档
71
- - 2025-09-19: 完善模板分类和文档结构
1
+ @language.md
2
+ @personality.md