aico-cli 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/simple-config.mjs +4 -4
- package/dist/cli.mjs +32 -53
- package/dist/index.mjs +52 -4
- package/package.json +1 -1
- package/templates/personality.md +11 -10
- package/dist/chunks/feature-checker.mjs +0 -116
- package/dist/shared/aico-cli.CWSSz8Hk.mjs +0 -51
|
@@ -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.
|
|
16
|
+
const version = "0.2.9";
|
|
17
17
|
|
|
18
18
|
function displayBanner(subtitle) {
|
|
19
19
|
const defaultSubtitle = "\u4E00\u952E\u914D\u7F6E\u4F60\u7684\u5F00\u53D1\u73AF\u5883";
|
|
@@ -4959,7 +4959,7 @@ class ConfigInstaller extends AbstractInstaller {
|
|
|
4959
4959
|
}
|
|
4960
4960
|
}
|
|
4961
4961
|
return this.createSuccessResult(
|
|
4962
|
-
`\u914D\u7F6E\u5B8C\u6210
|
|
4962
|
+
`\u914D\u7F6E\u5B8C\u6210`,
|
|
4963
4963
|
backupPath
|
|
4964
4964
|
);
|
|
4965
4965
|
} catch (error) {
|
|
@@ -5072,7 +5072,7 @@ class MCPInstaller extends AbstractInstaller {
|
|
|
5072
5072
|
const selectedServices = MCP_SERVICES.map((service) => service.id);
|
|
5073
5073
|
const backupPath = backupMcpConfig();
|
|
5074
5074
|
if (backupPath) {
|
|
5075
|
-
this.log(`MCP \u914D\u7F6E\u5DF2\u5907\u4EFD
|
|
5075
|
+
this.log(`MCP \u914D\u7F6E\u5DF2\u5907\u4EFD`, "info");
|
|
5076
5076
|
}
|
|
5077
5077
|
const newServers = {};
|
|
5078
5078
|
for (const serviceId of selectedServices) {
|
|
@@ -5560,4 +5560,4 @@ async function openSettingsJson() {
|
|
|
5560
5560
|
}
|
|
5561
5561
|
}
|
|
5562
5562
|
|
|
5563
|
-
export { AICO_CONFIG_FILE as A,
|
|
5563
|
+
export { 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, addCompletedOnboarding as K, LEGACY_AICO_CONFIG_FILE as L, MCP_SERVICES as M, createEscapablePrompt as N, displayBannerWithInfo as O, executeWithEscapeSupport as P, handleExitPromptError as Q, handleGeneralError as R, SETTINGS_FILE as S, EscapeKeyPressed as T, displayBanner as U, version as V, ConfigCheckerInstaller as W, readAicoConfig as X, init$1 as Y, 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, copyConfigFilesWithConfig as t, configureApi as u, mergeConfigs as v, updateDefaultModel as w, mergeSettingsFile as x, getExistingApiConfig as y, applyAiLanguageDirective 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 {
|
|
4
|
+
import { N as createEscapablePrompt, O as displayBannerWithInfo, a as init, P as executeWithEscapeSupport, Q as handleExitPromptError, R as handleGeneralError, T as EscapeKeyPressed, U as displayBanner, V as version, W as ConfigCheckerInstaller, X as readAicoConfig } 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';
|
|
@@ -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.
|
|
344
|
+
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Y; });
|
|
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.
|
|
352
|
+
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Y; });
|
|
353
353
|
await init2({
|
|
354
354
|
apiType: "ccr_proxy",
|
|
355
355
|
force: options.force,
|
|
@@ -370,21 +370,37 @@ async function startCodeEditor() {
|
|
|
370
370
|
try {
|
|
371
371
|
const context = createDefaultContext();
|
|
372
372
|
const checker = new ConfigCheckerInstaller(context);
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
console.log(ansis.yellow(`\u26A0\uFE0F \
|
|
381
|
-
|
|
382
|
-
|
|
373
|
+
const configType = await checker.detectConfigType();
|
|
374
|
+
const aicoConfig = readAicoConfig();
|
|
375
|
+
const needsReinstall = !aicoConfig || aicoConfig.version !== version;
|
|
376
|
+
if (configType === "none" || needsReinstall) {
|
|
377
|
+
if (configType === "none") {
|
|
378
|
+
console.log(ansis.yellow("\u26A0\uFE0F \u672A\u68C0\u6D4B\u5230\u914D\u7F6E\uFF0C\u5C06\u6309\u516C\u53F8\u914D\u7F6E\u8FDB\u884C\u5B89\u88C5..."));
|
|
379
|
+
} else {
|
|
380
|
+
console.log(ansis.yellow(`\u26A0\uFE0F \u68C0\u6D4B\u5230\u65B0\u7248\u672C (\u5F53\u524D: ${version}, \u914D\u7F6E: ${aicoConfig?.version || "\u65E0"})\uFF0C\u5C06\u81EA\u52A8\u5347\u7EA7...`));
|
|
381
|
+
}
|
|
382
|
+
if (configType === "company") {
|
|
383
|
+
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Y; });
|
|
384
|
+
await init2({
|
|
385
|
+
apiType: "auth_token",
|
|
386
|
+
skipBanner: true,
|
|
387
|
+
skipPrompt: true,
|
|
388
|
+
force: true
|
|
389
|
+
});
|
|
390
|
+
} else if (configType === "personal") {
|
|
391
|
+
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Y; });
|
|
392
|
+
await init2({
|
|
393
|
+
apiType: "ccr_proxy",
|
|
394
|
+
skipBanner: true,
|
|
395
|
+
skipPrompt: true,
|
|
396
|
+
force: true
|
|
397
|
+
});
|
|
398
|
+
} else {
|
|
399
|
+
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Y; });
|
|
400
|
+
await init2({ skipBanner: true, skipPrompt: true });
|
|
383
401
|
}
|
|
384
402
|
} else {
|
|
385
|
-
console.log(ansis.
|
|
386
|
-
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Z; });
|
|
387
|
-
await init2({ skipBanner: true, skipPrompt: true });
|
|
403
|
+
console.log(ansis.green(`\u2705 \u68C0\u6D4B\u5230${configType === "company" ? "\u516C\u53F8" : "\u4E2A\u4EBA"}\u914D\u7F6E\uFF0C\u7248\u672C\u5339\u914D\uFF0C\u8DF3\u8FC7\u914D\u7F6E\u68C0\u67E5...`));
|
|
388
404
|
}
|
|
389
405
|
await startClaudeCodeEditor();
|
|
390
406
|
} catch (error) {
|
|
@@ -417,43 +433,6 @@ function customizeHelp(sections) {
|
|
|
417
433
|
});
|
|
418
434
|
return sections;
|
|
419
435
|
}
|
|
420
|
-
async function installMissingFeatures(context, _featureStatus, missingFeatures) {
|
|
421
|
-
try {
|
|
422
|
-
const executor = new InstallerExecutor(context);
|
|
423
|
-
const featureToInstallerMap = {
|
|
424
|
-
config: "config",
|
|
425
|
-
claudeCode: "claude-code",
|
|
426
|
-
statusBar: "ccometix-line"
|
|
427
|
-
// workflow 和 aiPersonality 需要特殊处理,不能映射到 config-checker
|
|
428
|
-
};
|
|
429
|
-
for (const featureName of missingFeatures) {
|
|
430
|
-
if (featureName === "aiPersonality") {
|
|
431
|
-
console.log(ansis.blue(`\u{1F4E6} \u5B89\u88C5\u529F\u80FD: ${featureName}...`));
|
|
432
|
-
console.log(ansis.green(`\u2705 ${featureName} \u5B89\u88C5\u6210\u529F`));
|
|
433
|
-
} else {
|
|
434
|
-
const installerName = featureToInstallerMap[featureName];
|
|
435
|
-
if (installerName) {
|
|
436
|
-
console.log(ansis.blue(`\u{1F4E6} \u5B89\u88C5\u529F\u80FD: ${featureName}...`));
|
|
437
|
-
const result = await executor.execute(installerName, {
|
|
438
|
-
skipPrompt: true,
|
|
439
|
-
silent: true
|
|
440
|
-
});
|
|
441
|
-
if (result.success) {
|
|
442
|
-
console.log(ansis.green(`\u2705 ${featureName} \u5B89\u88C5\u6210\u529F`));
|
|
443
|
-
} else {
|
|
444
|
-
console.log(ansis.yellow(`\u26A0\uFE0F ${featureName} \u5B89\u88C5\u5931\u8D25: ${result.message}`));
|
|
445
|
-
}
|
|
446
|
-
} else {
|
|
447
|
-
console.log(ansis.yellow(`\u26A0\uFE0F \u672A\u77E5\u529F\u80FD: ${featureName}\uFF0C\u8DF3\u8FC7\u5B89\u88C5`));
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
console.log(ansis.green("\u{1F389} \u7F3A\u5931\u529F\u80FD\u5B89\u88C5\u5B8C\u6210\uFF01"));
|
|
452
|
-
} catch (error) {
|
|
453
|
-
console.error(ansis.red(`\u2716 \u81EA\u52A8\u5B89\u88C5\u529F\u80FD\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`));
|
|
454
|
-
console.log(ansis.yellow("\u{1F4A1} \u8BF7\u624B\u52A8\u8FD0\u884C `aico --init` \u6765\u5B89\u88C5\u7F3A\u5931\u529F\u80FD"));
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
436
|
|
|
458
437
|
if (!Array.prototype.findLastIndex) {
|
|
459
438
|
Array.prototype.findLastIndex = function(predicate, thisArg) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
import '
|
|
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, D as DEFAULT_FILE_COPY_CONFIGS, n as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, l as SUPPORTED_LANGS, K as addCompletedOnboarding, z as applyAiLanguageDirective, r as backupExistingConfig, G as backupMcpConfig, I as buildMcpServerConfig, f as cleanupPermissions, u as configureApi, s as copyConfigFiles, t as copyConfigFilesWithConfig, q as ensureClaudeDir, J as fixWindowsMcpConfig, y as getExistingApiConfig, B as getMcpConfigPath, b as getPlatform, d as importRecommendedEnv, e as importRecommendedPermissions, a as init, h as mergeAndCleanPermissions, v as mergeConfigs, H as mergeMcpServers, x as mergeSettingsFile, o as openSettingsJson, E as readMcpConfig, w as updateDefaultModel, F as writeMcpConfig } from './chunks/simple-config.mjs';
|
|
3
|
+
import { exec } from 'tinyexec';
|
|
4
|
+
import ansis from 'ansis';
|
|
4
5
|
import 'inquirer';
|
|
5
|
-
import 'tinyexec';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'node:fs';
|
|
8
8
|
import 'node:child_process';
|
|
@@ -14,3 +14,51 @@ 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 };
|
package/package.json
CHANGED
package/templates/personality.md
CHANGED
|
@@ -29,7 +29,7 @@ description: 架构师级软件工程师,以工程卓越为信仰,为追求
|
|
|
29
29
|
影响范围:[详细说明]
|
|
30
30
|
风险评估:[潜在后果]
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
这里容易踩坑,请确认是否继续?[需要明确的"是"、"确认"、"继续"]
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
### 2. 命令执行标准
|
|
@@ -99,6 +99,7 @@ description: 架构师级软件工程师,以工程卓越为信仰,为追求
|
|
|
99
99
|
### 4. 问题解决流程
|
|
100
100
|
|
|
101
101
|
**操作准则:**
|
|
102
|
+
- 先复述用户的描述,确保理解无误
|
|
102
103
|
- 持续工作直到问题完全解决
|
|
103
104
|
- 基于事实分析,充分使用工具收集信息
|
|
104
105
|
- 操作前充分规划,理解现有代码再修改
|
|
@@ -107,9 +108,9 @@ description: 架构师级软件工程师,以工程卓越为信仰,为追求
|
|
|
107
108
|
### 5. 系统化分析流程
|
|
108
109
|
|
|
109
110
|
**TODO清单标准流程:**
|
|
110
|
-
1.
|
|
111
|
-
2.
|
|
112
|
-
3.
|
|
111
|
+
1. **需求分析**:明确用户需求的核心目标和约束条件,复述需求,确保理解无误
|
|
112
|
+
2. **环境评估**:分析当前工作环境和可用工具,尽量复用
|
|
113
|
+
3. **方案设计**:制定技术方案和实现策略,收集问题细节和影响范围
|
|
113
114
|
4. **风险评估**:识别潜在技术难点和解决方案
|
|
114
115
|
5. **执行验证**:按计划执行并验证结果
|
|
115
116
|
6. **总结反馈**:输出最终解决方案和优化建议
|
|
@@ -190,14 +191,14 @@ description: 架构师级软件工程师,以工程卓越为信仰,为追求
|
|
|
190
191
|
- "懂你的意思,考虑到可维护性,更好的做法是...这是我总结的经验"
|
|
191
192
|
|
|
192
193
|
**问题诊断:**
|
|
193
|
-
- "
|
|
194
|
-
- "
|
|
195
|
-
- "
|
|
194
|
+
- "这里容易踩坑,这个问题本质上是...我在多个项目中都验证过"
|
|
195
|
+
- "这里容易踩坑,你碰到的是经典的权衡取舍问题,咱们来权衡一下"
|
|
196
|
+
- "这里容易踩坑,需要从系统设计角度重新思考,我来帮你梳理"
|
|
196
197
|
|
|
197
198
|
**总结收尾:**
|
|
198
|
-
- "
|
|
199
|
-
- "
|
|
200
|
-
- "
|
|
199
|
+
- "我们来总结下,这个方案的优势在于...实际项目中验证过"
|
|
200
|
+
- "我们来总结下,实施时需要特别注意...这是我踩过的坑"
|
|
201
|
+
- "我们来总结下,这个方案不存在技术盲点,但我还是想提一个建议..."
|
|
201
202
|
|
|
202
203
|
## 响应特点
|
|
203
204
|
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { join } from 'pathe';
|
|
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
|
-
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
|
-
"language.md",
|
|
99
|
-
"CLAUDE.md"
|
|
100
|
-
];
|
|
101
|
-
const missingFiles = requiredFiles.filter(
|
|
102
|
-
(file) => !existsSync(join(CLAUDE_DIR, file))
|
|
103
|
-
);
|
|
104
|
-
return {
|
|
105
|
-
isInstalled: missingFiles.length === 0,
|
|
106
|
-
details: missingFiles.length === 0 ? "AI \u4E2A\u6027\u6587\u4EF6\u5B8C\u6574" : `\u7F3A\u5931\u6587\u4EF6: ${missingFiles.join(", ")}`
|
|
107
|
-
};
|
|
108
|
-
} catch (error) {
|
|
109
|
-
return {
|
|
110
|
-
isInstalled: false,
|
|
111
|
-
details: `AI \u4E2A\u6027\u6587\u4EF6\u68C0\u67E5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export { checkAllFeatures };
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { exec } from 'tinyexec';
|
|
2
|
-
import ansis from 'ansis';
|
|
3
|
-
import { c as commandExists, J as isTermux, K as messages, N 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 };
|