aico-cli 0.1.6 → 0.1.8

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.
@@ -0,0 +1,117 @@
1
+ import { existsSync } from 'node:fs';
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';
5
+ import 'ansis';
6
+ import 'inquirer';
7
+ import 'tinyexec';
8
+ import 'node:os';
9
+ import 'node:child_process';
10
+ import 'node:util';
11
+ import 'child_process';
12
+ import 'util';
13
+ import 'ora';
14
+ import 'dayjs';
15
+ import 'node:path';
16
+ import 'node:url';
17
+
18
+ async function checkAllFeatures(context) {
19
+ const results = {};
20
+ results.config = await checkConfigFeature();
21
+ results.claudeCode = await checkClaudeCodeFeature();
22
+ results.workflow = await checkWorkflowFeature();
23
+ results.statusBar = await checkStatusBarFeature();
24
+ results.aiPersonality = await checkAiPersonalityFeature();
25
+ return results;
26
+ }
27
+ async function checkConfigFeature() {
28
+ try {
29
+ const settingsExists = existsSync(SETTINGS_FILE);
30
+ if (!settingsExists) {
31
+ return { isInstalled: false, details: "settings.json \u4E0D\u5B58\u5728" };
32
+ }
33
+ const settings = await readJsonConfig(SETTINGS_FILE);
34
+ const hasBaseUrl = !!settings?.env?.ANTHROPIC_BASE_URL;
35
+ return {
36
+ isInstalled: hasBaseUrl,
37
+ details: hasBaseUrl ? "API \u914D\u7F6E\u6B63\u5E38" : "\u7F3A\u5C11 ANTHROPIC_BASE_URL \u914D\u7F6E"
38
+ };
39
+ } catch (error) {
40
+ return {
41
+ isInstalled: false,
42
+ details: `\u914D\u7F6E\u68C0\u67E5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`
43
+ };
44
+ }
45
+ }
46
+ async function checkClaudeCodeFeature() {
47
+ try {
48
+ const installed = await isClaudeCodeInstalled();
49
+ return {
50
+ isInstalled: installed,
51
+ details: installed ? "Claude Code \u5DF2\u5B89\u88C5" : "Claude Code \u672A\u5B89\u88C5"
52
+ };
53
+ } catch (error) {
54
+ return {
55
+ isInstalled: false,
56
+ details: `Claude Code \u68C0\u67E5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`
57
+ };
58
+ }
59
+ }
60
+ async function checkWorkflowFeature() {
61
+ try {
62
+ const workflowDir = join(CLAUDE_DIR, "agents");
63
+ const workflowExists = existsSync(workflowDir);
64
+ if (!workflowExists) {
65
+ return { isInstalled: false, details: "\u5DE5\u4F5C\u6D41\u76EE\u5F55\u4E0D\u5B58\u5728" };
66
+ }
67
+ const hasWorkflowFiles = existsSync(join(workflowDir, "aico")) || existsSync(join(workflowDir, "commands"));
68
+ return {
69
+ isInstalled: hasWorkflowFiles,
70
+ details: hasWorkflowFiles ? "\u5DE5\u4F5C\u6D41\u6587\u4EF6\u5DF2\u5B89\u88C5" : "\u5DE5\u4F5C\u6D41\u76EE\u5F55\u4E3A\u7A7A"
71
+ };
72
+ } catch (error) {
73
+ return {
74
+ isInstalled: false,
75
+ details: `\u5DE5\u4F5C\u6D41\u68C0\u67E5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`
76
+ };
77
+ }
78
+ }
79
+ async function checkStatusBarFeature() {
80
+ try {
81
+ const statusBarDir = join(CLAUDE_DIR, "ccline");
82
+ const statusBarExists = existsSync(statusBarDir);
83
+ return {
84
+ isInstalled: statusBarExists,
85
+ details: statusBarExists ? "\u72B6\u6001\u680F\u5DF2\u914D\u7F6E" : "\u72B6\u6001\u680F\u672A\u914D\u7F6E"
86
+ };
87
+ } catch (error) {
88
+ return {
89
+ isInstalled: false,
90
+ details: `\u72B6\u6001\u680F\u68C0\u67E5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`
91
+ };
92
+ }
93
+ }
94
+ async function checkAiPersonalityFeature() {
95
+ try {
96
+ const requiredFiles = [
97
+ "personality.md",
98
+ "base.md",
99
+ "language.md",
100
+ "CLAUDE.md"
101
+ ];
102
+ const missingFiles = requiredFiles.filter(
103
+ (file) => !existsSync(join(CLAUDE_DIR, file))
104
+ );
105
+ return {
106
+ isInstalled: missingFiles.length === 0,
107
+ details: missingFiles.length === 0 ? "AI \u4E2A\u6027\u6587\u4EF6\u5B8C\u6574" : `\u7F3A\u5931\u6587\u4EF6: ${missingFiles.join(", ")}`
108
+ };
109
+ } catch (error) {
110
+ return {
111
+ isInstalled: false,
112
+ details: `AI \u4E2A\u6027\u6587\u4EF6\u68C0\u67E5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`
113
+ };
114
+ }
115
+ }
116
+
117
+ export { checkAllFeatures };
@@ -2,18 +2,18 @@ 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, readFileSync, writeFileSync, statSync, readdirSync } from 'node:fs';
5
+ import { existsSync, copyFileSync, mkdirSync, readdirSync, rmSync, unlinkSync, readFileSync, writeFileSync, statSync } 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';
9
9
  import { promisify } from 'util';
10
10
  import ora from 'ora';
11
- import dayjs from 'dayjs';
11
+ import 'dayjs';
12
12
  import { join as join$1 } from 'node:path';
13
13
  import { join, dirname } from 'pathe';
14
14
  import { fileURLToPath } from 'node:url';
15
15
 
16
- const version = "0.1.6";
16
+ const version = "0.1.8";
17
17
 
18
18
  function displayBanner(subtitle) {
19
19
  const defaultSubtitle = "\u4E00\u952E\u914D\u7F6E\u4F60\u7684\u5F00\u53D1\u73AF\u5883";
@@ -3417,6 +3417,32 @@ function copyDir(src, dest, options = {}) {
3417
3417
  }
3418
3418
  }
3419
3419
  }
3420
+ function removeFile(path) {
3421
+ try {
3422
+ if (exists(path) && isFile(path)) {
3423
+ unlinkSync(path);
3424
+ }
3425
+ } catch (error) {
3426
+ throw new FileSystemError(
3427
+ `Failed to remove file: ${path}`,
3428
+ path,
3429
+ error
3430
+ );
3431
+ }
3432
+ }
3433
+ function removeDir(path) {
3434
+ try {
3435
+ if (exists(path) && isDirectory(path)) {
3436
+ rmSync(path, { recursive: true, force: true });
3437
+ }
3438
+ } catch (error) {
3439
+ throw new FileSystemError(
3440
+ `Failed to remove directory: ${path}`,
3441
+ path,
3442
+ error
3443
+ );
3444
+ }
3445
+ }
3420
3446
 
3421
3447
  const messages = {
3422
3448
  // 菜单相关
@@ -3682,10 +3708,9 @@ function backupJsonConfig(path, backupDir) {
3682
3708
  if (!exists(path)) {
3683
3709
  return null;
3684
3710
  }
3685
- const timestamp = dayjs().format("YYYY-MM-DD_HH-mm-ss");
3686
3711
  const fileName = path.split("/").pop() || "config.json";
3687
3712
  const baseDir = backupDir || join(path, "..", "backup");
3688
- const backupPath = join(baseDir, `${fileName}.backup_${timestamp}`);
3713
+ const backupPath = join(baseDir, `${fileName}.backup`);
3689
3714
  try {
3690
3715
  ensureDir(baseDir);
3691
3716
  copyFile(path, backupPath);
@@ -4468,7 +4493,8 @@ class CCRInstaller extends AbstractInstaller {
4468
4493
  });
4469
4494
  ccrProcess.unref();
4470
4495
  this.log("CCR UI \u5DF2\u542F\u52A8", "success");
4471
- this.log("\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u8BBF\u95EE http://localhost:3456", "info");
4496
+ this.log("\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u8BBF\u95EE http://127.0.0.1:3456/ui/", "info");
4497
+ this.log("API\u5BC6\u94A5: sk-aico-x-ccr", "info");
4472
4498
  return this.createSuccessResult("CCR UI \u542F\u52A8\u6210\u529F");
4473
4499
  } catch (error) {
4474
4500
  return this.handleError(error, "CCR UI \u542F\u52A8");
@@ -4893,11 +4919,59 @@ class ConfigInstaller extends AbstractInstaller {
4893
4919
  copyFile(src, dest);
4894
4920
  }
4895
4921
  }
4896
- const agentsDir = join(sourceDir, "agents");
4897
- if (exists(agentsDir) && isDirectory(agentsDir)) {
4898
- const destAgentsDir = join(CLAUDE_DIR, "agents");
4899
- copyDir(agentsDir, destAgentsDir, { overwrite: true });
4922
+ await this.copyAgentsAndCommandsDirectories(sourceDir);
4923
+ }
4924
+ /**
4925
+ * 复制 agents commands 目录
4926
+ * 遵循先备份、再清空、最后复制的流程
4927
+ */
4928
+ async copyAgentsAndCommandsDirectories(sourceDir) {
4929
+ const directoriesToCopy = ["agents", "commands"];
4930
+ for (const dirName of directoriesToCopy) {
4931
+ const sourceSubDir = join(sourceDir, dirName);
4932
+ const destSubDir = join(CLAUDE_DIR, dirName);
4933
+ if (exists(sourceSubDir) && isDirectory(sourceSubDir)) {
4934
+ await this.backupDirectory(dirName, destSubDir);
4935
+ await this.cleanDirectory(destSubDir);
4936
+ copyDir(sourceSubDir, destSubDir, { overwrite: true });
4937
+ this.log(`\u5DF2\u590D\u5236 ${dirName} \u76EE\u5F55`, "success");
4938
+ }
4939
+ }
4940
+ }
4941
+ /**
4942
+ * 备份目录到 backup 文件夹
4943
+ */
4944
+ async backupDirectory(dirName, sourceDir) {
4945
+ if (!exists(sourceDir)) {
4946
+ return;
4900
4947
  }
4948
+ const backupBaseDir = join(CLAUDE_DIR, "backup");
4949
+ const backupDir = join(backupBaseDir, dirName);
4950
+ ensureDir(backupDir);
4951
+ copyDir(sourceDir, backupDir, { overwrite: true });
4952
+ this.log(`\u5DF2\u5907\u4EFD ${dirName} \u76EE\u5F55\u5230: ${backupDir}`, "info");
4953
+ }
4954
+ /**
4955
+ * 清空目录内容
4956
+ */
4957
+ async cleanDirectory(dirPath) {
4958
+ if (!exists(dirPath)) {
4959
+ ensureDir(dirPath);
4960
+ return;
4961
+ }
4962
+ const files = readDir(dirPath);
4963
+ if (files && files.length > 0) {
4964
+ for (const file of files) {
4965
+ const filePath = join(dirPath, file);
4966
+ if (isDirectory(filePath)) {
4967
+ await this.cleanDirectory(filePath);
4968
+ removeDir(filePath);
4969
+ } else {
4970
+ removeFile(filePath);
4971
+ }
4972
+ }
4973
+ }
4974
+ this.log(`\u5DF2\u6E05\u7A7A ${dirPath} \u76EE\u5F55`, "info");
4901
4975
  }
4902
4976
  }
4903
4977
 
@@ -5277,6 +5351,7 @@ class InstallationComposer {
5277
5351
  /**
5278
5352
  * 公司配置安装
5279
5353
  * 包含:Claude Code + 固定API配置 + CCometixLine + MCP + Workflow
5354
+ * 公司配置不需要安装 CCR
5280
5355
  */
5281
5356
  async installCompanySetup(options = {}) {
5282
5357
  console.log(ansis.cyan("\n\u{1F3E2} \u5F00\u59CB\u914D\u7F6E\u5B89\u88C5...\n"));
@@ -5330,7 +5405,7 @@ class InstallationComposer {
5330
5405
  }
5331
5406
  /**
5332
5407
  * 个人配置安装
5333
- * 包含:Claude Code + CCR + 配置备份应用 + CCometixLine + MCP
5408
+ * 包含:Claude Code + CCR + 配置备份应用 + CCometixLine + MCP + Workflow
5334
5409
  */
5335
5410
  async installPersonalSetup(options = {}) {
5336
5411
  console.log(ansis.cyan("\n\u{1F464} \u5F00\u59CB\u4E2A\u4EBA\u914D\u7F6E\u5B89\u88C5...\n"));
@@ -5339,7 +5414,8 @@ class InstallationComposer {
5339
5414
  INSTALLER_NAMES.CCR,
5340
5415
  INSTALLER_NAMES.CONFIG,
5341
5416
  INSTALLER_NAMES.CCOMETIX_LINE,
5342
- INSTALLER_NAMES.MCP
5417
+ INSTALLER_NAMES.MCP,
5418
+ INSTALLER_NAMES.WORKFLOW
5343
5419
  ];
5344
5420
  const configOptions = {
5345
5421
  ...options,
@@ -5586,4 +5662,4 @@ async function openSettingsJson() {
5586
5662
  }
5587
5663
  }
5588
5664
 
5589
- export { AICO_CONFIG_FILE as A, readMcpConfig as B, CLAUDE_DIR as C, writeMcpConfig as D, backupMcpConfig as E, mergeMcpServers as F, buildMcpServerConfig as G, fixWindowsMcpConfig as H, addCompletedOnboarding as I, createEscapablePrompt as J, displayBannerWithInfo as K, LEGACY_AICO_CONFIG_FILE as L, MCP_SERVICES as M, executeWithEscapeSupport as N, handleExitPromptError as O, handleGeneralError as P, EscapeKeyPressed as Q, displayBanner as R, SETTINGS_FILE as S, version as T, ConfigCheckerInstaller as U, init$1 as V, init as a, getPlatform as b, commandExists as c, importRecommendedEnv as d, importRecommendedPermissions as e, cleanupPermissions as f, getTermuxPrefix as g, mergeAndCleanPermissions as h, isTermux as i, CLAUDE_MD_FILE as j, ClAUDE_CONFIG_FILE as k, SUPPORTED_LANGS as l, messages as m, LANG_LABELS as n, openSettingsJson as o, AI_OUTPUT_LANGUAGES as p, ensureClaudeDir as q, backupExistingConfig as r, copyConfigFiles as s, configureApi as t, mergeConfigs as u, updateDefaultModel as v, mergeSettingsFile as w, getExistingApiConfig as x, applyAiLanguageDirective as y, getMcpConfigPath as z };
5665
+ 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, init$1 as W, 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 };
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 { J as createEscapablePrompt, K as displayBannerWithInfo, a as init, N as executeWithEscapeSupport, O as handleExitPromptError, P as handleGeneralError, Q as EscapeKeyPressed, R as displayBanner, T as version, U as ConfigCheckerInstaller } from './chunks/simple-config.mjs';
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 } from './chunks/simple-config.mjs';
5
5
  import inquirer$1 from 'inquirer';
6
- import { spawn, exec } from 'node:child_process';
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
11
  import 'node:url';
12
- import 'dayjs';
13
- import { promisify } from 'node:util';
14
- import 'child_process';
15
- import 'util';
16
- import 'ora';
17
12
  import 'node:path';
13
+ import { exec } from 'child_process';
14
+ import { promisify } from 'util';
15
+ import { promisify as promisify$1 } from 'node:util';
16
+ import 'ora';
17
+ import 'dayjs';
18
18
 
19
19
  const inquirer = {
20
20
  ...inquirer$1,
@@ -123,7 +123,9 @@ async function updateAicoCli() {
123
123
 
124
124
  promisify(exec);
125
125
 
126
- promisify(exec);
126
+ promisify$1(exec$1);
127
+
128
+ promisify$1(exec$1);
127
129
 
128
130
  async function tryStartClaude(command, args, options) {
129
131
  return new Promise((resolve, reject) => {
@@ -339,7 +341,7 @@ function setupCommands(cli) {
339
341
  } else if (options.update) {
340
342
  await update({});
341
343
  } else if (options.company) {
342
- const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.V; });
344
+ const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.W; });
343
345
  await init2({
344
346
  apiType: "auth_token",
345
347
  force: options.force,
@@ -347,7 +349,7 @@ function setupCommands(cli) {
347
349
  skipPrompt: true
348
350
  });
349
351
  } else if (options.personal) {
350
- const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.V; });
352
+ const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.W; });
351
353
  await init2({
352
354
  apiType: "ccr_proxy",
353
355
  force: options.force,
@@ -370,10 +372,17 @@ async function startCodeEditor() {
370
372
  const checker = new ConfigCheckerInstaller(context);
371
373
  const status = await checker.checkStatus();
372
374
  if (status.isInstalled) {
373
- console.log(ansis.green("\u2705 \u68C0\u6D4B\u5230\u5DF2\u6709\u914D\u7F6E\uFF0C\u76F4\u63A5\u542F\u52A8\u4EE3\u7801\u7F16\u8F91\u5668..."));
375
+ console.log(ansis.green("\u2705 \u68C0\u6D4B\u5230\u5DF2\u6709\u914D\u7F6E\uFF0C\u68C0\u67E5\u5404\u529F\u80FD\u6A21\u5757\u5B89\u88C5\u72B6\u6001..."));
376
+ const { checkAllFeatures } = await import('./chunks/feature-checker.mjs');
377
+ const featureStatus = await checkAllFeatures(context);
378
+ const missingFeatures = Object.entries(featureStatus).filter(([_, status2]) => !status2.isInstalled).map(([name, _]) => name);
379
+ if (missingFeatures.length > 0) {
380
+ console.log(ansis.yellow(`\u26A0\uFE0F \u53D1\u73B0\u672A\u5B89\u88C5\u7684\u529F\u80FD\u6A21\u5757: ${missingFeatures.join(", ")}`));
381
+ console.log(ansis.yellow(" \u8FD0\u884C `aico --init` \u6216 `aico --update` \u6765\u5B89\u88C5\u7F3A\u5931\u529F\u80FD"));
382
+ }
374
383
  } else {
375
384
  console.log(ansis.yellow("\u26A0\uFE0F \u672A\u68C0\u6D4B\u5230\u914D\u7F6E\uFF0C\u5C06\u5148\u6267\u884C\u521D\u59CB\u5316\u914D\u7F6E..."));
376
- const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.V; });
385
+ const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.W; });
377
386
  await init2({ skipBanner: true, skipPrompt: true });
378
387
  }
379
388
  await startClaudeCodeEditor();
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { c as commandExists, i as isTermux, m as messages, g as getTermuxPrefix } from './chunks/simple-config.mjs';
2
- export { A as AICO_CONFIG_FILE, p as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, j as CLAUDE_MD_FILE, k as ClAUDE_CONFIG_FILE, n as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, l as SUPPORTED_LANGS, I as addCompletedOnboarding, y as applyAiLanguageDirective, r as backupExistingConfig, E as backupMcpConfig, G as buildMcpServerConfig, f as cleanupPermissions, t as configureApi, s as copyConfigFiles, q as ensureClaudeDir, H as fixWindowsMcpConfig, x as getExistingApiConfig, z as getMcpConfigPath, b as getPlatform, d as importRecommendedEnv, e as importRecommendedPermissions, a as init, h as mergeAndCleanPermissions, u as mergeConfigs, F as mergeMcpServers, w as mergeSettingsFile, o as openSettingsJson, B as readMcpConfig, v as updateDefaultModel, D as writeMcpConfig } from './chunks/simple-config.mjs';
3
- import { exec } from 'tinyexec';
4
- import ansis from 'ansis';
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';
3
+ import 'ansis';
5
4
  import 'inquirer';
5
+ import 'tinyexec';
6
6
  import 'node:os';
7
7
  import 'node:fs';
8
8
  import 'node:child_process';
@@ -14,51 +14,3 @@ import 'dayjs';
14
14
  import 'node:path';
15
15
  import 'pathe';
16
16
  import 'node:url';
17
-
18
- async function isClaudeCodeInstalled() {
19
- return await commandExists("claude");
20
- }
21
- async function installClaudeCode(lang) {
22
- getTranslation(lang);
23
- if (isTermux()) {
24
- console.log(ansis.yellow(`\u2139 ${messages.installation.termuxDetected}`));
25
- const termuxPrefix = getTermuxPrefix();
26
- console.log(ansis.gray(messages.installation.termuxPathInfo.replace("{path}", termuxPrefix)));
27
- console.log(ansis.gray(`Node.js: ${termuxPrefix}/bin/node`));
28
- console.log(ansis.gray(`npm: ${termuxPrefix}/bin/npm`));
29
- }
30
- console.log(messages.installation.installing);
31
- try {
32
- await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
33
- console.log(`\u2714 ${messages.installation.installSuccess}`);
34
- if (isTermux()) {
35
- console.log(ansis.gray(`
36
- Claude Code installed to: ${getTermuxPrefix()}/bin/claude`));
37
- }
38
- } catch (error) {
39
- console.error(`\u2716 ${messages.installation.installFailed}`);
40
- if (isTermux()) {
41
- console.error(ansis.yellow(`
42
- ${messages.installation.termuxInstallHint}
43
- `));
44
- }
45
- throw error;
46
- }
47
- }
48
- async function installClaudeCodeSilently() {
49
- const installed = await isClaudeCodeInstalled();
50
- if (installed) {
51
- console.log(ansis.green("\u2714 \u5DF2\u5B89\u88C5 Claude Code"));
52
- return;
53
- }
54
- console.log("\u6B63\u5728\u5B89\u88C5 Claude Code...");
55
- try {
56
- await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
57
- console.log(ansis.green("\u2714 Claude Code \u5B89\u88C5\u6210\u529F"));
58
- } catch (error) {
59
- console.error(ansis.red("\u2716 Claude Code \u5B89\u88C5\u5931\u8D25"));
60
- throw error;
61
- }
62
- }
63
-
64
- export { commandExists, installClaudeCode, installClaudeCodeSilently, isClaudeCodeInstalled };
@@ -0,0 +1,51 @@
1
+ import { exec } from 'tinyexec';
2
+ import ansis from 'ansis';
3
+ import { c as commandExists, H as isTermux, I as messages, J as getTermuxPrefix } from '../chunks/simple-config.mjs';
4
+
5
+ async function isClaudeCodeInstalled() {
6
+ return await commandExists("claude");
7
+ }
8
+ async function installClaudeCode(lang) {
9
+ getTranslation(lang);
10
+ if (isTermux()) {
11
+ console.log(ansis.yellow(`\u2139 ${messages.installation.termuxDetected}`));
12
+ const termuxPrefix = getTermuxPrefix();
13
+ console.log(ansis.gray(messages.installation.termuxPathInfo.replace("{path}", termuxPrefix)));
14
+ console.log(ansis.gray(`Node.js: ${termuxPrefix}/bin/node`));
15
+ console.log(ansis.gray(`npm: ${termuxPrefix}/bin/npm`));
16
+ }
17
+ console.log(messages.installation.installing);
18
+ try {
19
+ await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
20
+ console.log(`\u2714 ${messages.installation.installSuccess}`);
21
+ if (isTermux()) {
22
+ console.log(ansis.gray(`
23
+ Claude Code installed to: ${getTermuxPrefix()}/bin/claude`));
24
+ }
25
+ } catch (error) {
26
+ console.error(`\u2716 ${messages.installation.installFailed}`);
27
+ if (isTermux()) {
28
+ console.error(ansis.yellow(`
29
+ ${messages.installation.termuxInstallHint}
30
+ `));
31
+ }
32
+ throw error;
33
+ }
34
+ }
35
+ async function installClaudeCodeSilently() {
36
+ const installed = await isClaudeCodeInstalled();
37
+ if (installed) {
38
+ console.log(ansis.green("\u2714 \u5DF2\u5B89\u88C5 Claude Code"));
39
+ return;
40
+ }
41
+ console.log("\u6B63\u5728\u5B89\u88C5 Claude Code...");
42
+ try {
43
+ await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
44
+ console.log(ansis.green("\u2714 Claude Code \u5B89\u88C5\u6210\u529F"));
45
+ } catch (error) {
46
+ console.error(ansis.red("\u2716 Claude Code \u5B89\u88C5\u5931\u8D25"));
47
+ throw error;
48
+ }
49
+ }
50
+
51
+ export { installClaudeCode as a, installClaudeCodeSilently as b, isClaudeCodeInstalled as i };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aico-cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "packageManager": "pnpm@9.15.9",
5
5
  "description": "AI CLI",
6
6
  "repository": {