aico-cli 0.5.0 → 2.0.25
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/bin/cli/README.md +43 -0
- package/bin/cli/cli.js +3780 -0
- package/bin/cli/package.json +32 -0
- package/bin/cli/sdk-tools.d.ts +275 -0
- package/bin/cli/sdk.d.ts +446 -0
- package/bin/cli/sdk.mjs +14840 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/annotations-23.0.0.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/claude-code-jetbrains-plugin-0.1.11-beta-searchableOptions.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/claude-code-jetbrains-plugin-0.1.11-beta.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/config-1.4.3.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/jansi-2.4.1.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlin-logging-jvm-7.0.0.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlin-reflect-2.0.21.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlin-sdk-jvm-0.4.0.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlin-stdlib-2.1.20.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlinx-coroutines-core-jvm-1.9.0.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlinx-coroutines-slf4j-1.9.0.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlinx-io-bytestring-jvm-0.5.4.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlinx-io-core-jvm-0.5.4.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlinx-serialization-core-jvm-1.8.1.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlinx-serialization-json-jvm-1.8.1.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-client-cio-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-client-core-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-events-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-http-cio-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-http-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-io-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-network-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-network-tls-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-serialization-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-server-cio-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-server-core-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-server-sse-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-server-websockets-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-sse-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-utils-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-websocket-serialization-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-websockets-jvm-3.0.2.jar +0 -0
- package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/slf4j-api-2.0.16.jar +0 -0
- package/bin/cli/vendor/ripgrep/COPYING +3 -0
- package/bin/cli/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/bin/cli/vendor/ripgrep/arm64-darwin/ripgrep.node +0 -0
- package/bin/cli/vendor/ripgrep/arm64-linux/rg +0 -0
- package/bin/cli/vendor/ripgrep/arm64-linux/ripgrep.node +0 -0
- package/bin/cli/vendor/ripgrep/x64-darwin/rg +0 -0
- package/bin/cli/vendor/ripgrep/x64-darwin/ripgrep.node +0 -0
- package/bin/cli/vendor/ripgrep/x64-linux/rg +0 -0
- package/bin/cli/vendor/ripgrep/x64-linux/ripgrep.node +0 -0
- package/bin/cli/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/bin/cli/vendor/ripgrep/x64-win32/ripgrep.node +0 -0
- package/bin/cli/yoga.wasm +0 -0
- package/dist/chunks/run-command.mjs +1 -0
- package/dist/chunks/simple-config.mjs +60 -15
- package/dist/cli.mjs +202 -64
- package/dist/index.mjs +3 -52
- package/package.json +2 -1
- package/templates/agents/base/panel-experts.md +244 -0
- package/templates/agents/code/python/345/274/200/345/217/221/344/270/223/345/256/266.md +49 -0
- package/templates/agents/code//345/256/211/345/205/250/346/274/217/346/264/236/350/257/206/345/210/253/344/270/223/345/256/266.md +51 -0
- package/templates/agents/code//346/200/247/350/203/275/345/210/206/346/236/220/344/270/223/345/256/266.md +49 -0
- package/templates/agents/code//346/212/200/346/234/257/346/226/207/346/241/243/345/267/245/347/250/213/345/270/210.md +49 -0
- package/templates/agents/code//346/240/271/346/234/254/345/216/237/345/233/240/345/210/206/346/236/220/345/270/210.md +49 -0
- package/templates/agents/code//347/263/273/347/273/237/346/236/266/346/236/204/345/270/210.md +232 -0
- package/templates/agents/code//350/264/250/351/207/217/350/257/204/344/274/260/345/267/245/347/250/213/345/270/210.md +49 -0
- package/templates/commands/base//344/270/223/345/256/266/347/273/204/345/210/206/346/236/220/346/231/272/350/203/275/344/275/223.md +82 -0
- package/templates/cursor.md +87 -0
- package/templates/hooks/claude-code-hooks.json +0 -9
- package/templates/hooks/notify.ps1 +110 -24
- package/templates/hooks/scripts/Stop/powershell/session-summary.ps1 +108 -78
- package/templates/hooks/scripts/UserPromptSubmit/powershell/input-notifier.ps1 +67 -39
- package/templates/personality.md +1 -1
- package/templates/settings.json +3 -15
|
Binary file
|
package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/claude-code-jetbrains-plugin-0.1.11-beta.jar
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlinx-serialization-core-jvm-1.8.1.jar
ADDED
|
Binary file
|
package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/kotlinx-serialization-json-jvm-1.8.1.jar
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bin/cli/vendor/claude-code-jetbrains-plugin/lib/ktor-websocket-serialization-jvm-3.0.2.jar
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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.
|
|
16
|
+
const version = "2.0.25";
|
|
17
17
|
|
|
18
18
|
function displayBanner(subtitle) {
|
|
19
19
|
const defaultSubtitle = "\u4E00\u952E\u914D\u7F6E\u4F60\u7684\u5F00\u53D1\u73AF\u5883";
|
|
@@ -3267,26 +3267,26 @@ const MCP_SERVICES = [
|
|
|
3267
3267
|
}
|
|
3268
3268
|
},
|
|
3269
3269
|
{
|
|
3270
|
-
id: "
|
|
3271
|
-
name: "
|
|
3272
|
-
description: "
|
|
3270
|
+
id: "chrome-devtools",
|
|
3271
|
+
name: "Chrome DevTools",
|
|
3272
|
+
description: "Chrome \u5F00\u53D1\u8005\u5DE5\u5177 MCP \u670D\u52A1",
|
|
3273
3273
|
requiresApiKey: false,
|
|
3274
3274
|
config: {
|
|
3275
3275
|
type: "stdio",
|
|
3276
3276
|
command: "npx",
|
|
3277
|
-
args: ["-
|
|
3277
|
+
args: ["chrome-devtools-mcp@latest"],
|
|
3278
3278
|
env: {}
|
|
3279
3279
|
}
|
|
3280
3280
|
},
|
|
3281
3281
|
{
|
|
3282
|
-
id: "
|
|
3283
|
-
name: "
|
|
3284
|
-
description: "
|
|
3282
|
+
id: "sequential-thinking",
|
|
3283
|
+
name: "Sequential Thinking",
|
|
3284
|
+
description: "\u987A\u5E8F\u601D\u8003 MCP \u670D\u52A1",
|
|
3285
3285
|
requiresApiKey: false,
|
|
3286
3286
|
config: {
|
|
3287
3287
|
type: "stdio",
|
|
3288
3288
|
command: "npx",
|
|
3289
|
-
args: ["
|
|
3289
|
+
args: ["-y", "sequential-thinking-mcp@latest"],
|
|
3290
3290
|
env: {}
|
|
3291
3291
|
}
|
|
3292
3292
|
}
|
|
@@ -5284,7 +5284,8 @@ class InstallationComposer {
|
|
|
5284
5284
|
}
|
|
5285
5285
|
/**
|
|
5286
5286
|
* 公司配置安装
|
|
5287
|
-
*
|
|
5287
|
+
* 包含:固定API配置 + CCometixLine + MCP + Workflow
|
|
5288
|
+
* Claude Code 由 startClaudeCodeEditor 函数自动安装
|
|
5288
5289
|
* 公司配置不需要安装 CCR
|
|
5289
5290
|
*/
|
|
5290
5291
|
async installCompanySetup(options = {}) {
|
|
@@ -5310,7 +5311,6 @@ class InstallationComposer {
|
|
|
5310
5311
|
const configType = configCheckResult?.data?.configType;
|
|
5311
5312
|
if (configType === "none" || options.force) {
|
|
5312
5313
|
const companySteps = [
|
|
5313
|
-
INSTALLER_NAMES.CLAUDE_CODE,
|
|
5314
5314
|
INSTALLER_NAMES.CONFIG,
|
|
5315
5315
|
INSTALLER_NAMES.CCOMETIX_LINE,
|
|
5316
5316
|
INSTALLER_NAMES.MCP
|
|
@@ -5323,7 +5323,6 @@ class InstallationComposer {
|
|
|
5323
5323
|
} else {
|
|
5324
5324
|
console.log(ansis.yellow(`\u26A0 \u68C0\u6D4B\u5230${configType === "company" ? "\u516C\u53F8" : "\u4E2A\u4EBA"}\u914D\u7F6E\uFF0C\u5C06\u5F3A\u5236\u6267\u884C\u5B8C\u6574\u516C\u53F8\u914D\u7F6E`));
|
|
5325
5325
|
const companySteps = [
|
|
5326
|
-
INSTALLER_NAMES.CLAUDE_CODE,
|
|
5327
5326
|
INSTALLER_NAMES.CONFIG,
|
|
5328
5327
|
INSTALLER_NAMES.CCOMETIX_LINE,
|
|
5329
5328
|
INSTALLER_NAMES.MCP
|
|
@@ -5337,12 +5336,12 @@ class InstallationComposer {
|
|
|
5337
5336
|
}
|
|
5338
5337
|
/**
|
|
5339
5338
|
* 个人配置安装
|
|
5340
|
-
* 包含:
|
|
5339
|
+
* 包含:CCR + 配置备份应用 + CCometixLine + MCP + Workflow
|
|
5340
|
+
* Claude Code 由 startClaudeCodeEditor 函数自动安装
|
|
5341
5341
|
*/
|
|
5342
5342
|
async installPersonalSetup(options = {}) {
|
|
5343
5343
|
console.log(ansis.cyan("\n\u{1F464} \u5F00\u59CB\u4E2A\u4EBA\u914D\u7F6E\u5B89\u88C5...\n"));
|
|
5344
5344
|
const installationSteps = [
|
|
5345
|
-
INSTALLER_NAMES.CLAUDE_CODE,
|
|
5346
5345
|
INSTALLER_NAMES.CCR,
|
|
5347
5346
|
INSTALLER_NAMES.CONFIG,
|
|
5348
5347
|
INSTALLER_NAMES.CCOMETIX_LINE,
|
|
@@ -5492,6 +5491,52 @@ const init$1 = {
|
|
|
5492
5491
|
init: init
|
|
5493
5492
|
};
|
|
5494
5493
|
|
|
5494
|
+
async function isClaudeCodeInstalled() {
|
|
5495
|
+
return await commandExists("claude");
|
|
5496
|
+
}
|
|
5497
|
+
async function installClaudeCode(lang) {
|
|
5498
|
+
getTranslation(lang);
|
|
5499
|
+
if (isTermux()) {
|
|
5500
|
+
console.log(ansis.yellow(`\u2139 ${messages.installation.termuxDetected}`));
|
|
5501
|
+
const termuxPrefix = getTermuxPrefix();
|
|
5502
|
+
console.log(ansis.gray(messages.installation.termuxPathInfo.replace("{path}", termuxPrefix)));
|
|
5503
|
+
console.log(ansis.gray(`Node.js: ${termuxPrefix}/bin/node`));
|
|
5504
|
+
console.log(ansis.gray(`npm: ${termuxPrefix}/bin/npm`));
|
|
5505
|
+
}
|
|
5506
|
+
console.log(messages.installation.installing);
|
|
5507
|
+
try {
|
|
5508
|
+
await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
|
|
5509
|
+
console.log(`\u2714 ${messages.installation.installSuccess}`);
|
|
5510
|
+
if (isTermux()) {
|
|
5511
|
+
console.log(ansis.gray(`
|
|
5512
|
+
Claude Code installed to: ${getTermuxPrefix()}/bin/claude`));
|
|
5513
|
+
}
|
|
5514
|
+
} catch (error) {
|
|
5515
|
+
console.error(`\u2716 ${messages.installation.installFailed}`);
|
|
5516
|
+
if (isTermux()) {
|
|
5517
|
+
console.error(ansis.yellow(`
|
|
5518
|
+
${messages.installation.termuxInstallHint}
|
|
5519
|
+
`));
|
|
5520
|
+
}
|
|
5521
|
+
throw error;
|
|
5522
|
+
}
|
|
5523
|
+
}
|
|
5524
|
+
async function installClaudeCodeSilently() {
|
|
5525
|
+
const installed = await isClaudeCodeInstalled();
|
|
5526
|
+
if (installed) {
|
|
5527
|
+
console.log(ansis.green("\u2714 \u5DF2\u5B89\u88C5 Claude Code"));
|
|
5528
|
+
return;
|
|
5529
|
+
}
|
|
5530
|
+
console.log("\u6B63\u5728\u5B89\u88C5 Claude Code...");
|
|
5531
|
+
try {
|
|
5532
|
+
await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
|
|
5533
|
+
console.log(ansis.green("\u2714 Claude Code \u5B89\u88C5\u6210\u529F"));
|
|
5534
|
+
} catch (error) {
|
|
5535
|
+
console.error(ansis.red("\u2716 Claude Code \u5B89\u88C5\u5931\u8D25"));
|
|
5536
|
+
throw error;
|
|
5537
|
+
}
|
|
5538
|
+
}
|
|
5539
|
+
|
|
5495
5540
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5496
5541
|
function getTemplateSettings() {
|
|
5497
5542
|
const templatePath = join(__dirname, "../../templates/settings.json");
|
|
@@ -5570,4 +5615,4 @@ async function openSettingsJson() {
|
|
|
5570
5615
|
}
|
|
5571
5616
|
}
|
|
5572
5617
|
|
|
5573
|
-
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, ConfigCheckerInstaller as V, updateAicoConfig as W, version as X, InstallationComposer as Y, readAicoConfig as Z, init$1 as _,
|
|
5618
|
+
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, ConfigCheckerInstaller as V, updateAicoConfig as W, version as X, InstallationComposer as Y, readAicoConfig as Z, init$1 as _, 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, 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 };
|
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 { N as createEscapablePrompt, O as displayBannerWithInfo,
|
|
4
|
+
import { N as createEscapablePrompt, l as isClaudeCodeInstalled, n as installClaudeCode, O as displayBannerWithInfo, i as init, P as executeWithEscapeSupport, Q as handleExitPromptError, R as handleGeneralError, T as EscapeKeyPressed, U as displayBanner, V as ConfigCheckerInstaller, W as updateAicoConfig, X as version, Y as InstallationComposer, Z 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 { EventEmitter } from 'node:events';
|
|
@@ -13,6 +13,7 @@ import 'node:path';
|
|
|
13
13
|
import { exec } from 'child_process';
|
|
14
14
|
import { promisify } from 'util';
|
|
15
15
|
import { promisify as promisify$1 } from 'node:util';
|
|
16
|
+
import path from 'path';
|
|
16
17
|
import 'ora';
|
|
17
18
|
import 'dayjs';
|
|
18
19
|
import 'node:url';
|
|
@@ -175,10 +176,7 @@ class ProcessManager extends EventEmitter {
|
|
|
175
176
|
unregisterProcess(pid) {
|
|
176
177
|
const info = this.processes.get(pid);
|
|
177
178
|
if (info) {
|
|
178
|
-
this.log(`\u6CE8\u9500\u8FDB\u7A0B: ${info.name} (PID: ${pid})`, "info");
|
|
179
179
|
this.processes.delete(pid);
|
|
180
|
-
} else {
|
|
181
|
-
this.log(`\u5C1D\u8BD5\u6CE8\u9500\u4E0D\u5B58\u5728\u7684\u8FDB\u7A0B (PID: ${pid})`, "warning");
|
|
182
180
|
}
|
|
183
181
|
}
|
|
184
182
|
/**
|
|
@@ -201,60 +199,83 @@ class ProcessManager extends EventEmitter {
|
|
|
201
199
|
this.log("\u7528\u6237\u8BF7\u6C42\u5F3A\u5236\u5173\u95ED\uFF0C\u7ACB\u5373\u7EC8\u6B62\u6240\u6709\u8FDB\u7A0B...", "warning");
|
|
202
200
|
};
|
|
203
201
|
process.once("SIGINT", forceShutdownHandler);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
202
|
+
try {
|
|
203
|
+
let runningProcesses = Array.from(this.processes.values()).filter((p) => p.status === "running");
|
|
204
|
+
if (runningProcesses.length > 0) {
|
|
205
|
+
for (const info of runningProcesses) {
|
|
206
|
+
try {
|
|
207
|
+
info.process.kill("SIGTERM");
|
|
208
|
+
info.status = "killed";
|
|
209
|
+
} catch (error) {
|
|
210
|
+
this.log(`\u65E0\u6CD5\u7EC8\u6B62\u8FDB\u7A0B ${info.name} (PID: ${info.pid}): ${error}`, "error");
|
|
211
|
+
}
|
|
213
212
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
213
|
+
const maxWaitTime = 1e3;
|
|
214
|
+
const checkInterval = 100;
|
|
215
|
+
let waitedTime = 0;
|
|
216
|
+
while (waitedTime < maxWaitTime && !forceShutdownRequested) {
|
|
217
|
+
await new Promise((resolve) => setTimeout(resolve, checkInterval));
|
|
218
|
+
waitedTime += checkInterval;
|
|
219
|
+
runningProcesses = Array.from(this.processes.values()).filter((p) => p.status === "running");
|
|
220
|
+
if (runningProcesses.length === 0) {
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
224
223
|
}
|
|
225
224
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
225
|
+
process.removeListener("SIGINT", forceShutdownHandler);
|
|
226
|
+
runningProcesses = Array.from(this.processes.values()).filter((p) => p.status === "running");
|
|
227
|
+
if (runningProcesses.length > 0) {
|
|
228
|
+
this.log(`\u5F3A\u5236\u7EC8\u6B62 ${runningProcesses.length} \u4E2A\u4ECD\u5728\u8FD0\u884C\u7684\u8FDB\u7A0B...`, "warning");
|
|
229
|
+
for (const info of runningProcesses) {
|
|
230
|
+
try {
|
|
231
|
+
info.process.kill("SIGKILL");
|
|
232
|
+
this.log(`\u5F3A\u5236\u7EC8\u6B62\u8FDB\u7A0B ${info.name} (PID: ${info.pid})`, "warning");
|
|
233
|
+
} catch (error) {
|
|
234
|
+
this.log(`\u65E0\u6CD5\u5F3A\u5236\u7EC8\u6B62\u8FDB\u7A0B ${info.name} (PID: ${info.pid}): ${error}`, "error");
|
|
235
|
+
}
|
|
237
236
|
}
|
|
238
237
|
}
|
|
238
|
+
const totalTime = Date.now() - firstSignalTime;
|
|
239
|
+
this.log(`\u5173\u95ED\u5B8C\u6210\uFF0C\u8017\u65F6 ${totalTime}ms`, "success");
|
|
240
|
+
} catch (error) {
|
|
241
|
+
this.log(`\u5173\u95ED\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF: ${error}`, "error");
|
|
242
|
+
} finally {
|
|
243
|
+
this.cleanup();
|
|
244
|
+
setTimeout(() => {
|
|
245
|
+
process.exit(0);
|
|
246
|
+
}, 100);
|
|
239
247
|
}
|
|
240
|
-
const totalTime = Date.now() - firstSignalTime;
|
|
241
|
-
this.log(`\u5173\u95ED\u5B8C\u6210\uFF0C\u8017\u65F6 ${totalTime}ms`, "success");
|
|
242
|
-
this.cleanup();
|
|
243
|
-
process.exit(0);
|
|
244
248
|
}
|
|
245
249
|
/**
|
|
246
250
|
* 清理所有进程
|
|
247
251
|
*/
|
|
248
252
|
cleanup() {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
253
|
+
try {
|
|
254
|
+
let cleanedCount = 0;
|
|
255
|
+
for (const [pid, info] of this.processes) {
|
|
256
|
+
if (info.status === "running") {
|
|
257
|
+
try {
|
|
258
|
+
if (info.process.kill("SIGTERM")) {
|
|
259
|
+
this.log(`\u5DF2\u53D1\u9001 SIGTERM \u4FE1\u53F7\u7ED9\u8FDB\u7A0B ${info.name} (PID: ${pid})`, "info");
|
|
260
|
+
cleanedCount++;
|
|
261
|
+
}
|
|
262
|
+
} catch (error) {
|
|
263
|
+
this.log(`\u53D1\u9001 SIGTERM \u4FE1\u53F7\u7ED9\u8FDB\u7A0B ${info.name} (PID: ${pid}) \u5931\u8D25: ${error}`, "warning");
|
|
264
|
+
try {
|
|
265
|
+
if (info.process.kill("SIGKILL")) {
|
|
266
|
+
this.log(`\u5DF2\u53D1\u9001 SIGKILL \u4FE1\u53F7\u7ED9\u8FDB\u7A0B ${info.name} (PID: ${pid})`, "warning");
|
|
267
|
+
cleanedCount++;
|
|
268
|
+
}
|
|
269
|
+
} catch (killError) {
|
|
270
|
+
this.log(`\u53D1\u9001 SIGKILL \u4FE1\u53F7\u7ED9\u8FDB\u7A0B ${info.name} (PID: ${pid}) \u5931\u8D25: ${killError}`, "error");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
254
273
|
}
|
|
255
274
|
}
|
|
275
|
+
this.processes.clear();
|
|
276
|
+
} catch (error) {
|
|
277
|
+
this.log(`\u8FDB\u7A0B\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF: ${error}`, "error");
|
|
256
278
|
}
|
|
257
|
-
this.processes.clear();
|
|
258
279
|
}
|
|
259
280
|
/**
|
|
260
281
|
* 获取当前运行的进程数量
|
|
@@ -531,6 +552,81 @@ promisify$1(exec$1);
|
|
|
531
552
|
|
|
532
553
|
promisify$1(exec$1);
|
|
533
554
|
|
|
555
|
+
async function checkLocalClaudeCode() {
|
|
556
|
+
try {
|
|
557
|
+
const fs = await import('fs');
|
|
558
|
+
const localClaudePath = path.resolve(process.cwd(), "bin/cli/cli.js");
|
|
559
|
+
if (fs.existsSync(localClaudePath)) {
|
|
560
|
+
const stats = fs.statSync(localClaudePath);
|
|
561
|
+
return {
|
|
562
|
+
exists: true,
|
|
563
|
+
path: localClaudePath,
|
|
564
|
+
size: stats.size
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
return {
|
|
568
|
+
exists: false,
|
|
569
|
+
path: localClaudePath
|
|
570
|
+
};
|
|
571
|
+
} catch (error) {
|
|
572
|
+
return {
|
|
573
|
+
exists: false,
|
|
574
|
+
path: path.resolve(process.cwd(), "bin/cli/cli.js"),
|
|
575
|
+
error: error instanceof Error ? error.message : String(error)
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
async function checkGlobalClaudeCode() {
|
|
580
|
+
try {
|
|
581
|
+
const isWindows = process.platform === "win32";
|
|
582
|
+
const command = isWindows ? "claude.cmd" : "claude";
|
|
583
|
+
const { spawnSync } = await import('child_process');
|
|
584
|
+
const whichCommand = isWindows ? "where" : "which";
|
|
585
|
+
const result = spawnSync(whichCommand, [command], {
|
|
586
|
+
stdio: "pipe",
|
|
587
|
+
timeout: 5e3
|
|
588
|
+
// 5秒超时
|
|
589
|
+
});
|
|
590
|
+
if (result.status === 0 && result.stdout) {
|
|
591
|
+
const output = result.stdout.toString().trim();
|
|
592
|
+
return {
|
|
593
|
+
installed: true,
|
|
594
|
+
command: output.split("\n")[0]
|
|
595
|
+
// 返回第一个匹配的路径
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
return {
|
|
599
|
+
installed: false,
|
|
600
|
+
error: result.stderr?.toString() || "\u547D\u4EE4\u672A\u627E\u5230"
|
|
601
|
+
};
|
|
602
|
+
} catch (error) {
|
|
603
|
+
return {
|
|
604
|
+
installed: false,
|
|
605
|
+
error: error instanceof Error ? error.message : String(error)
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async function performHealthCheck() {
|
|
610
|
+
const localCheck = await checkLocalClaudeCode();
|
|
611
|
+
if (localCheck.exists) {
|
|
612
|
+
console.log(ansis.green(`\u2705 \u68C0\u6D4B\u5230\u7F16\u8F91\u5668`));
|
|
613
|
+
} else {
|
|
614
|
+
console.log(ansis.yellow(`\u26A0\uFE0F \u6CA1\u6709\u68C0\u6D4B\u5230\u7F16\u8F91\u5668: ${localCheck.path}`));
|
|
615
|
+
if (localCheck.error) {
|
|
616
|
+
console.log(ansis.gray(` \u9519\u8BEF\u8BE6\u60C5: ${localCheck.error}`));
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
const globalCheck = await checkGlobalClaudeCode();
|
|
620
|
+
if (globalCheck.installed) {
|
|
621
|
+
console.log(ansis.green(`\u{1F680} \u542F\u52A8\u7F16\u8F91\u5668`));
|
|
622
|
+
} else {
|
|
623
|
+
console.log(ansis.yellow("\u26A0\uFE0F \u5168\u5C40 Claude Code \u672A\u5B89\u88C5"));
|
|
624
|
+
if (globalCheck.error) {
|
|
625
|
+
console.log(ansis.gray(` \u9519\u8BEF\u8BE6\u60C5: ${globalCheck.error}`));
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
534
630
|
async function tryStartClaude(command, args, options) {
|
|
535
631
|
process.platform === "win32";
|
|
536
632
|
const spawnOptions = {
|
|
@@ -545,6 +641,7 @@ async function tryStartClaude(command, args, options) {
|
|
|
545
641
|
async function startClaudeCodeEditor(_lang) {
|
|
546
642
|
try {
|
|
547
643
|
console.log(ansis.cyan("\u{1F680} \u6B63\u5728\u542F\u52A8\u4EE3\u7801\u7F16\u8F91\u5668..."));
|
|
644
|
+
await performHealthCheck();
|
|
548
645
|
const isWindows = process.platform === "win32";
|
|
549
646
|
const spawnOptions = {
|
|
550
647
|
stdio: "inherit",
|
|
@@ -555,56 +652,97 @@ async function startClaudeCodeEditor(_lang) {
|
|
|
555
652
|
// 禁用shell模式,避免进程泄漏(Windows和Unix都适用)
|
|
556
653
|
};
|
|
557
654
|
try {
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
await tryStartClaude(command, args, spawnOptions);
|
|
562
|
-
} else {
|
|
563
|
-
await tryStartClaude(command, args, spawnOptions);
|
|
655
|
+
const localCheck = await checkLocalClaudeCode();
|
|
656
|
+
if (!localCheck.exists) {
|
|
657
|
+
throw new Error(`\u672C\u5730 aico\u8FD0\u884C\u547D\u4EE4 \u6587\u4EF6\u4E0D\u5B58\u5728: ${localCheck.path}${localCheck.error ? ` (${localCheck.error})` : ""}`);
|
|
564
658
|
}
|
|
659
|
+
const command = isWindows ? "node.exe" : "node";
|
|
660
|
+
const args = [localCheck.path];
|
|
661
|
+
await tryStartClaude(command, args, spawnOptions);
|
|
565
662
|
return;
|
|
566
|
-
} catch (
|
|
567
|
-
|
|
568
|
-
|
|
663
|
+
} catch (localError) {
|
|
664
|
+
console.log(ansis.yellow("\u{1F4A1} \u5C1D\u8BD5\u81EA\u52A8\u5B89\u88C5\u5E76\u542F\u52A8..."));
|
|
665
|
+
try {
|
|
666
|
+
const installed = await isClaudeCodeInstalled();
|
|
667
|
+
if (!installed) {
|
|
668
|
+
console.log(ansis.cyan("\u{1F4E6} \u68C0\u6D4B\u5230 Claude Code \u672A\u5B89\u88C5\uFF0C\u6B63\u5728\u81EA\u52A8\u5B89\u88C5..."));
|
|
669
|
+
await installClaudeCode(_lang || "zh-CN");
|
|
670
|
+
console.log(ansis.green("\u2705 Claude Code \u5B89\u88C5\u5B8C\u6210"));
|
|
671
|
+
}
|
|
672
|
+
const command = isWindows ? "claude.cmd" : "claude";
|
|
673
|
+
const args = [];
|
|
674
|
+
console.log(ansis.gray(`\u{1F527} \u4F7F\u7528\u5168\u5C40\u547D\u4EE4: ${command}`));
|
|
675
|
+
if (isWindows) {
|
|
676
|
+
await tryStartClaude(command, args, spawnOptions);
|
|
677
|
+
} else {
|
|
678
|
+
await tryStartClaude(command, args, spawnOptions);
|
|
679
|
+
}
|
|
680
|
+
return;
|
|
681
|
+
} catch (installError) {
|
|
682
|
+
console.log(ansis.yellow("\u26A0\uFE0F \u5B89\u88C5\u540E\u542F\u52A8\u5931\u8D25: "), ansis.gray(installError.message));
|
|
683
|
+
console.log(ansis.yellow("\u{1F4A1} \u5C1D\u8BD5\u4F7F\u7528 npx \u542F\u52A8..."));
|
|
569
684
|
try {
|
|
570
685
|
const npxArgs = ["@anthropic-ai/claude-code"];
|
|
686
|
+
console.log(ansis.gray(`\u{1F527} \u4F7F\u7528 npx \u547D\u4EE4: npx ${npxArgs.join(" ")}`));
|
|
571
687
|
if (isWindows) {
|
|
572
688
|
await tryStartClaude("npx.cmd", npxArgs, spawnOptions);
|
|
573
689
|
} else {
|
|
574
690
|
await tryStartClaude("npx", npxArgs, spawnOptions);
|
|
575
691
|
}
|
|
576
692
|
return;
|
|
577
|
-
} catch (
|
|
578
|
-
|
|
693
|
+
} catch (npxError) {
|
|
694
|
+
console.log(ansis.yellow("\u26A0\uFE0F npx \u542F\u52A8\u4E5F\u5931\u8D25: "), ansis.gray(npxError.message));
|
|
695
|
+
throw new Error(`\u6240\u6709\u542F\u52A8\u65B9\u5F0F\u5747\u5931\u8D25:
|
|
696
|
+
- \u672C\u5730\u542F\u52A8: ${localError.message}
|
|
697
|
+
- \u5168\u5C40\u542F\u52A8: ${installError.message || "\u8DF3\u8FC7"}
|
|
698
|
+
- npx\u542F\u52A8: ${npxError.message}`);
|
|
579
699
|
}
|
|
580
|
-
} else {
|
|
581
|
-
throw firstError;
|
|
582
700
|
}
|
|
583
701
|
}
|
|
584
702
|
} catch (error) {
|
|
585
703
|
console.error(ansis.red("\u274C \u542F\u52A8\u4EE3\u7801\u7F16\u8F91\u5668\u5931\u8D25:"));
|
|
586
704
|
const isWindows = process.platform === "win32";
|
|
705
|
+
console.error(ansis.yellow("\u{1F4CB} \u8BE6\u7EC6\u8BCA\u65AD\u4FE1\u606F:"));
|
|
706
|
+
console.error(ansis.gray(` \u9519\u8BEF\u7C7B\u578B: ${error.name || "Unknown"}`));
|
|
707
|
+
console.error(ansis.gray(` \u9519\u8BEF\u4EE3\u7801: ${error.code || "\u65E0"}`));
|
|
708
|
+
console.error(ansis.gray(` \u9519\u8BEF\u6D88\u606F: ${error.message || error}`));
|
|
709
|
+
console.error(ansis.gray(` \u5F53\u524D\u76EE\u5F55: ${process.cwd()}`));
|
|
710
|
+
console.error(ansis.gray(` \u64CD\u4F5C\u7CFB\u7EDF: ${process.platform}`));
|
|
711
|
+
console.error(ansis.gray(` Node.js \u7248\u672C: ${process.version}`));
|
|
712
|
+
console.error(ansis.gray(` \u5185\u5B58\u4F7F\u7528: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB`));
|
|
587
713
|
if (error.code === "ENOENT" || error.message?.includes("command not found") || error.message?.includes("ENOENT")) {
|
|
588
|
-
console.error(ansis.yellow("\u{1F4A1} \
|
|
589
|
-
console.error(ansis.gray("
|
|
714
|
+
console.error(ansis.yellow("\u{1F4A1} \u53EF\u80FD\u7684\u539F\u56E0:"));
|
|
715
|
+
console.error(ansis.gray(" 1. \u672C\u5730 Claude Code \u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u8DEF\u5F84\u9519\u8BEF"));
|
|
716
|
+
console.error(ansis.gray(" 2. \u81EA\u52A8\u5B89\u88C5 Claude Code \u5931\u8D25"));
|
|
717
|
+
console.error(ansis.gray(" 3. Node.js \u73AF\u5883\u95EE\u9898"));
|
|
718
|
+
console.error(ansis.gray(" 4. PATH \u73AF\u5883\u53D8\u91CF\u914D\u7F6E\u95EE\u9898"));
|
|
719
|
+
console.error(ansis.yellow("\u{1F4A1} \u89E3\u51B3\u65B9\u6848:"));
|
|
720
|
+
console.error(ansis.gray(" - \u786E\u4FDD\u9879\u76EE\u5DF2\u6B63\u786E\u6784\u5EFA\uFF0Cbin/cli/cli.js \u6587\u4EF6\u5B58\u5728"));
|
|
721
|
+
console.error(ansis.gray(" - \u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\uFF0C\u786E\u4FDD\u53EF\u4EE5\u8BBF\u95EE npm \u4ED3\u5E93"));
|
|
722
|
+
console.error(ansis.gray(" - \u624B\u52A8\u5B89\u88C5: npm install -g @anthropic-ai/claude-code"));
|
|
723
|
+
console.error(ansis.gray(" - \u68C0\u67E5 Node.js \u548C npm \u7248\u672C\u517C\u5BB9\u6027"));
|
|
590
724
|
if (isWindows) {
|
|
591
725
|
console.error(ansis.yellow("\u{1F4A1} Windows \u7528\u6237\u989D\u5916\u63D0\u793A:"));
|
|
592
726
|
console.error(ansis.gray(" 1. \u91CD\u542F\u547D\u4EE4\u884C\u7A97\u53E3\u4EE5\u5237\u65B0 PATH \u73AF\u5883\u53D8\u91CF"));
|
|
593
727
|
console.error(ansis.gray(" 2. \u786E\u8BA4 npm \u5168\u5C40\u5B89\u88C5\u8DEF\u5F84\u5728 PATH \u4E2D"));
|
|
594
728
|
console.error(ansis.gray(" 3. \u5C1D\u8BD5\u4F7F\u7528 npx.cmd @anthropic-ai/claude-code --dangerously-skip-permissions"));
|
|
595
729
|
console.error(ansis.gray(" 4. \u68C0\u67E5\u662F\u5426\u5B89\u88C5\u4E86 Node.js \u548C npm"));
|
|
730
|
+
console.error(ansis.gray(" 5. \u5C1D\u8BD5\u4EE5\u7BA1\u7406\u5458\u6743\u9650\u8FD0\u884C"));
|
|
596
731
|
}
|
|
597
732
|
} else if (error.message?.includes("spawn") || error.message?.includes("\u8FDB\u7A0B")) {
|
|
598
733
|
console.error(ansis.yellow("\u{1F4A1} \u8FDB\u7A0B\u542F\u52A8\u5931\u8D25\uFF0C\u53EF\u80FD\u662F\u8FDB\u7A0B\u7BA1\u7406\u95EE\u9898:"));
|
|
599
734
|
console.error(ansis.gray(" 1. \u68C0\u67E5\u7CFB\u7EDF\u662F\u5426\u6709\u8DB3\u591F\u7684\u8D44\u6E90"));
|
|
600
735
|
console.error(ansis.gray(" 2. \u5C1D\u8BD5\u5173\u95ED\u5176\u4ED6\u5E94\u7528\u7A0B\u5E8F\u91CA\u653E\u5185\u5B58"));
|
|
736
|
+
console.error(ansis.gray(" 3. \u68C0\u67E5\u8FDB\u7A0B\u7BA1\u7406\u5668\u72B6\u6001"));
|
|
601
737
|
if (isWindows) {
|
|
602
|
-
console.error(ansis.gray("
|
|
603
|
-
console.error(ansis.gray("
|
|
738
|
+
console.error(ansis.gray(" 4. Windows\u7528\u6237: \u5C1D\u8BD5\u4EE5\u7BA1\u7406\u5458\u6743\u9650\u8FD0\u884C"));
|
|
739
|
+
console.error(ansis.gray(" 5. Windows\u7528\u6237: \u68C0\u67E5\u9632\u75C5\u6BD2\u8F6F\u4EF6\u662F\u5426\u963B\u6B62\u4E86\u8FDB\u7A0B\u542F\u52A8"));
|
|
604
740
|
}
|
|
605
741
|
} else {
|
|
606
|
-
console.error(ansis.
|
|
607
|
-
console.error(ansis.gray(
|
|
742
|
+
console.error(ansis.yellow("\u{1F4A1} \u672A\u77E5\u9519\u8BEF\u7C7B\u578B\uFF0C\u8BF7\u68C0\u67E5\u4EE5\u4E0B\u5185\u5BB9:"));
|
|
743
|
+
console.error(ansis.gray(" 1. \u67E5\u770B\u5B8C\u6574\u7684\u9519\u8BEF\u5806\u6808\u4FE1\u606F"));
|
|
744
|
+
console.error(ansis.gray(" 2. \u68C0\u67E5\u7CFB\u7EDF\u65E5\u5FD7"));
|
|
745
|
+
console.error(ansis.gray(" 3. \u5C1D\u8BD5\u91CD\u542F\u7CFB\u7EDF"));
|
|
608
746
|
}
|
|
609
747
|
try {
|
|
610
748
|
const processCount = processManager.getProcessCount();
|
|
@@ -639,7 +777,7 @@ function createDefaultContext() {
|
|
|
639
777
|
};
|
|
640
778
|
}
|
|
641
779
|
async function launchCodeEditor() {
|
|
642
|
-
return startClaudeCodeEditor();
|
|
780
|
+
return startClaudeCodeEditor("zh-CN");
|
|
643
781
|
}
|
|
644
782
|
async function launchCUI() {
|
|
645
783
|
try {
|