jinzd-ai-cli 0.4.91 → 0.4.92

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,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigManager
4
- } from "./chunk-US6MQO6W.js";
4
+ } from "./chunk-ING3NMVR.js";
5
5
  import "./chunk-2ZD3YTVM.js";
6
- import "./chunk-AKCXRW2Q.js";
6
+ import "./chunk-5IL2BHSD.js";
7
7
 
8
8
  // src/cli/batch.ts
9
9
  import Anthropic from "@anthropic-ai/sdk";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.91";
4
+ var VERSION = "0.4.92";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -6,7 +6,7 @@ import { platform } from "os";
6
6
  import chalk from "chalk";
7
7
 
8
8
  // src/core/constants.ts
9
- var VERSION = "0.4.91";
9
+ var VERSION = "0.4.92";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -23,7 +23,7 @@ import {
23
23
  } from "./chunk-6VRJGH25.js";
24
24
  import {
25
25
  runTestsTool
26
- } from "./chunk-IGNYJUZU.js";
26
+ } from "./chunk-KLSISB52.js";
27
27
  import {
28
28
  CONFIG_DIR_NAME,
29
29
  DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
@@ -31,7 +31,7 @@ import {
31
31
  SUBAGENT_ALLOWED_TOOLS,
32
32
  SUBAGENT_DEFAULT_MAX_ROUNDS,
33
33
  SUBAGENT_MAX_ROUNDS_LIMIT
34
- } from "./chunk-AKCXRW2Q.js";
34
+ } from "./chunk-5IL2BHSD.js";
35
35
 
36
36
  // src/tools/types.ts
37
37
  function isFileWriteTool(name) {
@@ -83,7 +83,7 @@ function schemaToJsonSchema(schema) {
83
83
  }
84
84
 
85
85
  // src/tools/builtin/bash.ts
86
- import { execSync } from "child_process";
86
+ import { spawn } from "child_process";
87
87
  import { existsSync as existsSync2, readdirSync, statSync } from "fs";
88
88
  import { platform } from "os";
89
89
  import { resolve } from "path";
@@ -203,6 +203,26 @@ var UndoStack = class {
203
203
  };
204
204
  var undoStack = new UndoStack();
205
205
 
206
+ // src/core/interrupt.ts
207
+ var controller = new AbortController();
208
+ var interrupted = false;
209
+ function currentAbortSignal() {
210
+ return controller.signal;
211
+ }
212
+ function isInterrupted() {
213
+ return interrupted;
214
+ }
215
+ function requestInterrupt() {
216
+ interrupted = true;
217
+ if (!controller.signal.aborted) {
218
+ controller.abort(new DOMException("User interrupted (Ctrl+C)", "AbortError"));
219
+ }
220
+ }
221
+ function resetInterrupt() {
222
+ controller = new AbortController();
223
+ interrupted = false;
224
+ }
225
+
206
226
  // src/tools/builtin/bash.ts
207
227
  var IS_WINDOWS = platform() === "win32";
208
228
  var SHELL = IS_WINDOWS ? "powershell.exe" : process.env["SHELL"] ?? "/bin/bash";
@@ -285,21 +305,40 @@ Important rules:
285
305
  parsedTargetsBefore.set(t, existsSync2(t));
286
306
  }
287
307
  try {
288
- const output = execSync(actualCommand, {
289
- timeout,
290
- encoding: IS_WINDOWS ? "buffer" : "utf-8",
291
- stdio: ["pipe", "pipe", "pipe"],
292
- cwd: effectiveCwd,
293
- shell: SHELL,
294
- env: {
295
- ...process.env,
296
- PYTHONUTF8: "1",
297
- PYTHONIOENCODING: "utf-8"
308
+ const { stdout, stderr, status, signal, timedOut, aborted } = await runShell(
309
+ actualCommand,
310
+ {
311
+ timeout,
312
+ cwd: effectiveCwd,
313
+ env: {
314
+ ...process.env,
315
+ PYTHONUTF8: "1",
316
+ PYTHONIOENCODING: "utf-8"
317
+ }
298
318
  }
299
- });
319
+ );
320
+ if (aborted) {
321
+ pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
322
+ throw new ToolError(
323
+ "bash",
324
+ `Command interrupted by user (Ctrl+C).
325
+
326
+ [The user pressed Ctrl+C while this command was running. Stop the current task, summarize what was done so far, and wait for the user's next instruction. Do NOT retry this command or continue with further tool calls unless explicitly asked.]`
327
+ );
328
+ }
329
+ if (status !== 0 || timedOut) {
330
+ throw {
331
+ status,
332
+ signal,
333
+ code: timedOut ? "ETIMEDOUT" : void 0,
334
+ stdout,
335
+ stderr,
336
+ message: timedOut ? "ETIMEDOUT" : `exit ${status}`
337
+ };
338
+ }
300
339
  updateCwdFromCommand(command, effectiveCwd);
301
340
  pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
302
- const result = IS_WINDOWS && Buffer.isBuffer(output) ? output.toString("utf-8") : output;
341
+ const result = IS_WINDOWS && Buffer.isBuffer(stdout) ? stdout.toString("utf-8") : stdout;
303
342
  return result || "(command completed with no output)";
304
343
  } catch (err) {
305
344
  pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
@@ -419,6 +458,84 @@ function pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, cwd) {
419
458
  }
420
459
  }
421
460
  }
461
+ function runShell(command, opts) {
462
+ return new Promise((resolvePromise) => {
463
+ const shellArgs = IS_WINDOWS ? ["-NoProfile", "-NonInteractive", "-Command", command] : ["-c", command];
464
+ const child = spawn(SHELL, shellArgs, {
465
+ cwd: opts.cwd,
466
+ env: opts.env,
467
+ windowsHide: true,
468
+ stdio: ["ignore", "pipe", "pipe"]
469
+ });
470
+ const stdoutChunks = [];
471
+ const stderrChunks = [];
472
+ let timedOut = false;
473
+ let aborted = false;
474
+ let settled = false;
475
+ child.stdout?.on("data", (chunk) => stdoutChunks.push(chunk));
476
+ child.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
477
+ const timeoutTimer = setTimeout(() => {
478
+ timedOut = true;
479
+ killChild(child);
480
+ }, opts.timeout);
481
+ const signal = currentAbortSignal();
482
+ const onAbort = () => {
483
+ aborted = true;
484
+ killChild(child);
485
+ };
486
+ if (signal.aborted) {
487
+ onAbort();
488
+ } else {
489
+ signal.addEventListener("abort", onAbort, { once: true });
490
+ }
491
+ const cleanup = () => {
492
+ clearTimeout(timeoutTimer);
493
+ signal.removeEventListener("abort", onAbort);
494
+ };
495
+ child.on("error", (err) => {
496
+ if (settled) return;
497
+ settled = true;
498
+ cleanup();
499
+ stderrChunks.push(Buffer.from(String(err.message ?? err)));
500
+ resolvePromise({
501
+ stdout: Buffer.concat(stdoutChunks),
502
+ stderr: Buffer.concat(stderrChunks),
503
+ status: null,
504
+ signal: null,
505
+ timedOut,
506
+ aborted
507
+ });
508
+ });
509
+ child.on("close", (code, sig) => {
510
+ if (settled) return;
511
+ settled = true;
512
+ cleanup();
513
+ resolvePromise({
514
+ stdout: Buffer.concat(stdoutChunks),
515
+ stderr: Buffer.concat(stderrChunks),
516
+ status: code,
517
+ signal: sig,
518
+ timedOut,
519
+ aborted
520
+ });
521
+ });
522
+ });
523
+ }
524
+ function killChild(child) {
525
+ if (child.killed || child.exitCode !== null) return;
526
+ try {
527
+ child.kill("SIGTERM");
528
+ } catch {
529
+ }
530
+ setTimeout(() => {
531
+ if (!child.killed && child.exitCode === null) {
532
+ try {
533
+ child.kill("SIGKILL");
534
+ } catch {
535
+ }
536
+ }
537
+ }, 500).unref();
538
+ }
422
539
  function updateCwdFromCommand(command, baseCwd) {
423
540
  const cdMatches = [...command.matchAll(/(?:^|[;&|])\s*cd\s+(['"]?)([^\s;&|'"]+)\1/g)];
424
541
  if (cdMatches.length === 0) return;
@@ -1012,7 +1129,7 @@ function simpleDiff(oldLines, newLines) {
1012
1129
  }
1013
1130
 
1014
1131
  // src/tools/hooks.ts
1015
- import { execSync as execSync2 } from "child_process";
1132
+ import { execSync } from "child_process";
1016
1133
  function shellEscape(value) {
1017
1134
  return "'" + value.replace(/'/g, "'\\''") + "'";
1018
1135
  }
@@ -1024,7 +1141,7 @@ function runHook(template, vars) {
1024
1141
  cmd = cmd.replace(/\{args\}/g, shellEscape(vars.args ?? ""));
1025
1142
  cmd = cmd.replace(/\{status\}/g, shellEscape(vars.status ?? ""));
1026
1143
  try {
1027
- execSync2(cmd, {
1144
+ execSync(cmd, {
1028
1145
  timeout: 5e3,
1029
1146
  stdio: ["pipe", "pipe", "pipe"],
1030
1147
  encoding: "utf-8"
@@ -1247,6 +1364,11 @@ var ToolExecutor = class {
1247
1364
  * 防止用户输入 "y"+Enter 被同时触发 once('line') 和主循环 on('line')。
1248
1365
  */
1249
1366
  confirming = false;
1367
+ /**
1368
+ * Tool 执行进行中标志(executeAll 的生命周期)。
1369
+ * repl.ts 的 SIGINT handler 在此为 true 时触发全局 interrupt(而不是退出程序)。
1370
+ */
1371
+ running = false;
1250
1372
  /** 在 confirm 期间用户输入的 slash 命令,由 repl.ts 主循环消费 */
1251
1373
  pendingSlashCommand = null;
1252
1374
  /** confirm() 的取消回调,由 SIGINT handler 调用 */
@@ -1381,25 +1503,30 @@ var ToolExecutor = class {
1381
1503
  }
1382
1504
  }
1383
1505
  async executeAll(calls) {
1384
- const phase = groupCallsByPhase(calls);
1385
- const results = new Array(calls.length);
1386
- const elapsed = await runSafePhases(phase, (c) => this.execute(c), results, "executor");
1387
- if (phase.safeParallel.length >= 2) {
1388
- console.log(theme.dim(` \u26A1 ${phase.safeParallel.length} tools executed in parallel (${elapsed}ms)`));
1389
- }
1390
- if (phase.fileWriteCalls.length === 1) {
1391
- const { idx, call } = phase.fileWriteCalls[0];
1392
- results[idx] = await this.execute(call);
1393
- } else if (phase.fileWriteCalls.length >= 2) {
1394
- const batchResults = await this.executeBatchFileWrites(phase.fileWriteCalls.map((f) => f.call));
1395
- for (let i = 0; i < phase.fileWriteCalls.length; i++) {
1396
- results[phase.fileWriteCalls[i].idx] = batchResults[i];
1506
+ this.running = true;
1507
+ try {
1508
+ const phase = groupCallsByPhase(calls);
1509
+ const results = new Array(calls.length);
1510
+ const elapsed = await runSafePhases(phase, (c) => this.execute(c), results, "executor");
1511
+ if (phase.safeParallel.length >= 2) {
1512
+ console.log(theme.dim(` \u26A1 ${phase.safeParallel.length} tools executed in parallel (${elapsed}ms)`));
1397
1513
  }
1514
+ if (phase.fileWriteCalls.length === 1) {
1515
+ const { idx, call } = phase.fileWriteCalls[0];
1516
+ results[idx] = await this.execute(call);
1517
+ } else if (phase.fileWriteCalls.length >= 2) {
1518
+ const batchResults = await this.executeBatchFileWrites(phase.fileWriteCalls.map((f) => f.call));
1519
+ for (let i = 0; i < phase.fileWriteCalls.length; i++) {
1520
+ results[phase.fileWriteCalls[i].idx] = batchResults[i];
1521
+ }
1522
+ }
1523
+ for (const { idx, call } of phase.otherCalls) {
1524
+ results[idx] = await this.execute(call);
1525
+ }
1526
+ return results;
1527
+ } finally {
1528
+ this.running = false;
1398
1529
  }
1399
- for (const { idx, call } of phase.otherCalls) {
1400
- results[idx] = await this.execute(call);
1401
- }
1402
- return results;
1403
1530
  }
1404
1531
  /**
1405
1532
  * 批量文件写入:展示所有文件的编号列表 + diff 预览,
@@ -2743,7 +2870,7 @@ function collectMatchingFiles(dirPath, rootPath, regex, results, maxResults) {
2743
2870
  }
2744
2871
 
2745
2872
  // src/tools/builtin/run-interactive.ts
2746
- import { spawn } from "child_process";
2873
+ import { spawn as spawn2 } from "child_process";
2747
2874
  import { platform as platform2 } from "os";
2748
2875
  var IS_WINDOWS2 = platform2() === "win32";
2749
2876
  var runInteractiveTool = {
@@ -2807,7 +2934,7 @@ var runInteractiveTool = {
2807
2934
  };
2808
2935
  const prefixWarnings = [argsTypeWarning, stdinTypeWarning].filter(Boolean).join("");
2809
2936
  return new Promise((resolve4) => {
2810
- const child = spawn(executable, cmdArgs.map(String), {
2937
+ const child = spawn2(executable, cmdArgs.map(String), {
2811
2938
  cwd: process.cwd(),
2812
2939
  env,
2813
2940
  stdio: ["pipe", "pipe", "pipe"]
@@ -2977,8 +3104,8 @@ var webFetchTool = {
2977
3104
  if (e.message.startsWith("Blocked:")) throw e;
2978
3105
  throw new NetworkError(`Invalid URL: "${url}"`);
2979
3106
  }
2980
- const controller = new AbortController();
2981
- const timeoutId = setTimeout(() => controller.abort(), 2e4);
3107
+ const controller2 = new AbortController();
3108
+ const timeoutId = setTimeout(() => controller2.abort(), 2e4);
2982
3109
  let rawHtml;
2983
3110
  let finalUrl;
2984
3111
  let contentType;
@@ -2998,7 +3125,7 @@ var webFetchTool = {
2998
3125
  }
2999
3126
  await resolveAndCheck(parsedHop.hostname);
3000
3127
  const r = await fetch(currentUrl, {
3001
- signal: controller.signal,
3128
+ signal: controller2.signal,
3002
3129
  headers: FETCH_HEADERS,
3003
3130
  redirect: "manual"
3004
3131
  // 手动控制重定向
@@ -3349,15 +3476,15 @@ var googleSearchTool = {
3349
3476
  url.searchParams.set("cx", cx);
3350
3477
  url.searchParams.set("q", query);
3351
3478
  url.searchParams.set("num", String(numResults));
3352
- const controller = new AbortController();
3353
- const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
3479
+ const controller2 = new AbortController();
3480
+ const timeout = setTimeout(() => controller2.abort(), REQUEST_TIMEOUT_MS);
3354
3481
  try {
3355
3482
  const response = await fetch(url.toString(), {
3356
3483
  method: "GET",
3357
3484
  headers: {
3358
3485
  "Accept": "application/json"
3359
3486
  },
3360
- signal: controller.signal
3487
+ signal: controller2.signal
3361
3488
  });
3362
3489
  if (!response.ok) {
3363
3490
  const errorBody = await response.text().catch(() => "");
@@ -3741,7 +3868,7 @@ var spawnAgentTool = {
3741
3868
  };
3742
3869
 
3743
3870
  // src/tools/builtin/task-manager.ts
3744
- import { spawn as spawn2 } from "child_process";
3871
+ import { spawn as spawn3 } from "child_process";
3745
3872
  import { randomUUID } from "crypto";
3746
3873
  import { platform as platform3 } from "os";
3747
3874
  var MAX_OUTPUT_CHARS = 1e4;
@@ -3766,7 +3893,7 @@ function createTask(command, description) {
3766
3893
  const isWin = platform3() === "win32";
3767
3894
  const shell = isWin ? "cmd" : "sh";
3768
3895
  const shellFlag = isWin ? "/c" : "-c";
3769
- const proc = spawn2(shell, [shellFlag, command], {
3896
+ const proc = spawn3(shell, [shellFlag, command], {
3770
3897
  stdio: ["ignore", "pipe", "pipe"],
3771
3898
  detached: false,
3772
3899
  env: { ...process.env, PYTHONUTF8: "1" }
@@ -4894,6 +5021,9 @@ export {
4894
5021
  theme,
4895
5022
  undoStack,
4896
5023
  renderDiff,
5024
+ isInterrupted,
5025
+ requestInterrupt,
5026
+ resetInterrupt,
4897
5027
  rlInternal,
4898
5028
  groupCallsByPhase,
4899
5029
  runSafePhases,
@@ -8,7 +8,7 @@ import {
8
8
  CONFIG_FILE_NAME,
9
9
  HISTORY_DIR_NAME,
10
10
  PLUGINS_DIR_NAME
11
- } from "./chunk-AKCXRW2Q.js";
11
+ } from "./chunk-5IL2BHSD.js";
12
12
 
13
13
  // src/config/config-manager.ts
14
14
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-AKCXRW2Q.js";
4
+ } from "./chunk-5IL2BHSD.js";
5
5
 
6
6
  // src/tools/builtin/run-tests.ts
7
7
  import { execSync } from "child_process";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  schemaToJsonSchema,
4
4
  truncateForPersist
5
- } from "./chunk-Z2V6EYPQ.js";
5
+ } from "./chunk-CNI26J5Z.js";
6
6
  import {
7
7
  AuthError,
8
8
  ProviderError,
@@ -21,7 +21,7 @@ import {
21
21
  MCP_PROTOCOL_VERSION,
22
22
  MCP_TOOL_PREFIX,
23
23
  VERSION
24
- } from "./chunk-AKCXRW2Q.js";
24
+ } from "./chunk-5IL2BHSD.js";
25
25
 
26
26
  // src/providers/claude.ts
27
27
  import Anthropic from "@anthropic-ai/sdk";
@@ -36,7 +36,7 @@ import {
36
36
  VERSION,
37
37
  buildUserIdentityPrompt,
38
38
  runTestsTool
39
- } from "./chunk-XQHCCV3A.js";
39
+ } from "./chunk-A4TUAW4J.js";
40
40
  import {
41
41
  hasSemanticIndex,
42
42
  semanticSearch
@@ -3304,7 +3304,7 @@ var SessionManager = class {
3304
3304
  };
3305
3305
 
3306
3306
  // src/tools/builtin/bash.ts
3307
- import { execSync } from "child_process";
3307
+ import { spawn } from "child_process";
3308
3308
  import { existsSync as existsSync4, readdirSync as readdirSync2, statSync } from "fs";
3309
3309
  import { platform } from "os";
3310
3310
  import { resolve } from "path";
@@ -3424,6 +3424,12 @@ var UndoStack = class {
3424
3424
  };
3425
3425
  var undoStack = new UndoStack();
3426
3426
 
3427
+ // src/core/interrupt.ts
3428
+ var controller = new AbortController();
3429
+ function currentAbortSignal() {
3430
+ return controller.signal;
3431
+ }
3432
+
3427
3433
  // src/tools/builtin/bash.ts
3428
3434
  var IS_WINDOWS = platform() === "win32";
3429
3435
  var SHELL = IS_WINDOWS ? "powershell.exe" : process.env["SHELL"] ?? "/bin/bash";
@@ -3506,21 +3512,40 @@ Important rules:
3506
3512
  parsedTargetsBefore.set(t, existsSync4(t));
3507
3513
  }
3508
3514
  try {
3509
- const output = execSync(actualCommand, {
3510
- timeout,
3511
- encoding: IS_WINDOWS ? "buffer" : "utf-8",
3512
- stdio: ["pipe", "pipe", "pipe"],
3513
- cwd: effectiveCwd,
3514
- shell: SHELL,
3515
- env: {
3516
- ...process.env,
3517
- PYTHONUTF8: "1",
3518
- PYTHONIOENCODING: "utf-8"
3515
+ const { stdout, stderr, status, signal, timedOut, aborted } = await runShell(
3516
+ actualCommand,
3517
+ {
3518
+ timeout,
3519
+ cwd: effectiveCwd,
3520
+ env: {
3521
+ ...process.env,
3522
+ PYTHONUTF8: "1",
3523
+ PYTHONIOENCODING: "utf-8"
3524
+ }
3519
3525
  }
3520
- });
3526
+ );
3527
+ if (aborted) {
3528
+ pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
3529
+ throw new ToolError(
3530
+ "bash",
3531
+ `Command interrupted by user (Ctrl+C).
3532
+
3533
+ [The user pressed Ctrl+C while this command was running. Stop the current task, summarize what was done so far, and wait for the user's next instruction. Do NOT retry this command or continue with further tool calls unless explicitly asked.]`
3534
+ );
3535
+ }
3536
+ if (status !== 0 || timedOut) {
3537
+ throw {
3538
+ status,
3539
+ signal,
3540
+ code: timedOut ? "ETIMEDOUT" : void 0,
3541
+ stdout,
3542
+ stderr,
3543
+ message: timedOut ? "ETIMEDOUT" : `exit ${status}`
3544
+ };
3545
+ }
3521
3546
  updateCwdFromCommand(command, effectiveCwd);
3522
3547
  pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
3523
- const result = IS_WINDOWS && Buffer.isBuffer(output) ? output.toString("utf-8") : output;
3548
+ const result = IS_WINDOWS && Buffer.isBuffer(stdout) ? stdout.toString("utf-8") : stdout;
3524
3549
  return result || "(command completed with no output)";
3525
3550
  } catch (err) {
3526
3551
  pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
@@ -3640,6 +3665,84 @@ function pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, cwd) {
3640
3665
  }
3641
3666
  }
3642
3667
  }
3668
+ function runShell(command, opts) {
3669
+ return new Promise((resolvePromise) => {
3670
+ const shellArgs = IS_WINDOWS ? ["-NoProfile", "-NonInteractive", "-Command", command] : ["-c", command];
3671
+ const child = spawn(SHELL, shellArgs, {
3672
+ cwd: opts.cwd,
3673
+ env: opts.env,
3674
+ windowsHide: true,
3675
+ stdio: ["ignore", "pipe", "pipe"]
3676
+ });
3677
+ const stdoutChunks = [];
3678
+ const stderrChunks = [];
3679
+ let timedOut = false;
3680
+ let aborted = false;
3681
+ let settled = false;
3682
+ child.stdout?.on("data", (chunk) => stdoutChunks.push(chunk));
3683
+ child.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
3684
+ const timeoutTimer = setTimeout(() => {
3685
+ timedOut = true;
3686
+ killChild(child);
3687
+ }, opts.timeout);
3688
+ const signal = currentAbortSignal();
3689
+ const onAbort = () => {
3690
+ aborted = true;
3691
+ killChild(child);
3692
+ };
3693
+ if (signal.aborted) {
3694
+ onAbort();
3695
+ } else {
3696
+ signal.addEventListener("abort", onAbort, { once: true });
3697
+ }
3698
+ const cleanup = () => {
3699
+ clearTimeout(timeoutTimer);
3700
+ signal.removeEventListener("abort", onAbort);
3701
+ };
3702
+ child.on("error", (err) => {
3703
+ if (settled) return;
3704
+ settled = true;
3705
+ cleanup();
3706
+ stderrChunks.push(Buffer.from(String(err.message ?? err)));
3707
+ resolvePromise({
3708
+ stdout: Buffer.concat(stdoutChunks),
3709
+ stderr: Buffer.concat(stderrChunks),
3710
+ status: null,
3711
+ signal: null,
3712
+ timedOut,
3713
+ aborted
3714
+ });
3715
+ });
3716
+ child.on("close", (code, sig) => {
3717
+ if (settled) return;
3718
+ settled = true;
3719
+ cleanup();
3720
+ resolvePromise({
3721
+ stdout: Buffer.concat(stdoutChunks),
3722
+ stderr: Buffer.concat(stderrChunks),
3723
+ status: code,
3724
+ signal: sig,
3725
+ timedOut,
3726
+ aborted
3727
+ });
3728
+ });
3729
+ });
3730
+ }
3731
+ function killChild(child) {
3732
+ if (child.killed || child.exitCode !== null) return;
3733
+ try {
3734
+ child.kill("SIGTERM");
3735
+ } catch {
3736
+ }
3737
+ setTimeout(() => {
3738
+ if (!child.killed && child.exitCode === null) {
3739
+ try {
3740
+ child.kill("SIGKILL");
3741
+ } catch {
3742
+ }
3743
+ }
3744
+ }, 500).unref();
3745
+ }
3643
3746
  function updateCwdFromCommand(command, baseCwd) {
3644
3747
  const cdMatches = [...command.matchAll(/(?:^|[;&|])\s*cd\s+(['"]?)([^\s;&|'"]+)\1/g)];
3645
3748
  if (cdMatches.length === 0) return;
@@ -4233,7 +4336,7 @@ function simpleDiff(oldLines, newLines) {
4233
4336
  }
4234
4337
 
4235
4338
  // src/tools/hooks.ts
4236
- import { execSync as execSync2 } from "child_process";
4339
+ import { execSync } from "child_process";
4237
4340
  function shellEscape(value) {
4238
4341
  return "'" + value.replace(/'/g, "'\\''") + "'";
4239
4342
  }
@@ -4245,7 +4348,7 @@ function runHook(template, vars) {
4245
4348
  cmd = cmd.replace(/\{args\}/g, shellEscape(vars.args ?? ""));
4246
4349
  cmd = cmd.replace(/\{status\}/g, shellEscape(vars.status ?? ""));
4247
4350
  try {
4248
- execSync2(cmd, {
4351
+ execSync(cmd, {
4249
4352
  timeout: 5e3,
4250
4353
  stdio: ["pipe", "pipe", "pipe"],
4251
4354
  encoding: "utf-8"
@@ -4429,6 +4532,11 @@ var ToolExecutor = class {
4429
4532
  * 防止用户输入 "y"+Enter 被同时触发 once('line') 和主循环 on('line')。
4430
4533
  */
4431
4534
  confirming = false;
4535
+ /**
4536
+ * Tool 执行进行中标志(executeAll 的生命周期)。
4537
+ * repl.ts 的 SIGINT handler 在此为 true 时触发全局 interrupt(而不是退出程序)。
4538
+ */
4539
+ running = false;
4432
4540
  /** 在 confirm 期间用户输入的 slash 命令,由 repl.ts 主循环消费 */
4433
4541
  pendingSlashCommand = null;
4434
4542
  /** confirm() 的取消回调,由 SIGINT handler 调用 */
@@ -4563,25 +4671,30 @@ var ToolExecutor = class {
4563
4671
  }
4564
4672
  }
4565
4673
  async executeAll(calls) {
4566
- const phase = groupCallsByPhase(calls);
4567
- const results = new Array(calls.length);
4568
- const elapsed = await runSafePhases(phase, (c) => this.execute(c), results, "executor");
4569
- if (phase.safeParallel.length >= 2) {
4570
- console.log(theme.dim(` \u26A1 ${phase.safeParallel.length} tools executed in parallel (${elapsed}ms)`));
4571
- }
4572
- if (phase.fileWriteCalls.length === 1) {
4573
- const { idx, call } = phase.fileWriteCalls[0];
4574
- results[idx] = await this.execute(call);
4575
- } else if (phase.fileWriteCalls.length >= 2) {
4576
- const batchResults = await this.executeBatchFileWrites(phase.fileWriteCalls.map((f) => f.call));
4577
- for (let i = 0; i < phase.fileWriteCalls.length; i++) {
4578
- results[phase.fileWriteCalls[i].idx] = batchResults[i];
4674
+ this.running = true;
4675
+ try {
4676
+ const phase = groupCallsByPhase(calls);
4677
+ const results = new Array(calls.length);
4678
+ const elapsed = await runSafePhases(phase, (c) => this.execute(c), results, "executor");
4679
+ if (phase.safeParallel.length >= 2) {
4680
+ console.log(theme.dim(` \u26A1 ${phase.safeParallel.length} tools executed in parallel (${elapsed}ms)`));
4579
4681
  }
4682
+ if (phase.fileWriteCalls.length === 1) {
4683
+ const { idx, call } = phase.fileWriteCalls[0];
4684
+ results[idx] = await this.execute(call);
4685
+ } else if (phase.fileWriteCalls.length >= 2) {
4686
+ const batchResults = await this.executeBatchFileWrites(phase.fileWriteCalls.map((f) => f.call));
4687
+ for (let i = 0; i < phase.fileWriteCalls.length; i++) {
4688
+ results[phase.fileWriteCalls[i].idx] = batchResults[i];
4689
+ }
4690
+ }
4691
+ for (const { idx, call } of phase.otherCalls) {
4692
+ results[idx] = await this.execute(call);
4693
+ }
4694
+ return results;
4695
+ } finally {
4696
+ this.running = false;
4580
4697
  }
4581
- for (const { idx, call } of phase.otherCalls) {
4582
- results[idx] = await this.execute(call);
4583
- }
4584
- return results;
4585
4698
  }
4586
4699
  /**
4587
4700
  * 批量文件写入:展示所有文件的编号列表 + diff 预览,
@@ -5925,7 +6038,7 @@ function collectMatchingFiles(dirPath, rootPath, regex, results, maxResults) {
5925
6038
  }
5926
6039
 
5927
6040
  // src/tools/builtin/run-interactive.ts
5928
- import { spawn } from "child_process";
6041
+ import { spawn as spawn2 } from "child_process";
5929
6042
  import { platform as platform2 } from "os";
5930
6043
  var IS_WINDOWS2 = platform2() === "win32";
5931
6044
  var runInteractiveTool = {
@@ -5989,7 +6102,7 @@ var runInteractiveTool = {
5989
6102
  };
5990
6103
  const prefixWarnings = [argsTypeWarning, stdinTypeWarning].filter(Boolean).join("");
5991
6104
  return new Promise((resolve6) => {
5992
- const child = spawn(executable, cmdArgs.map(String), {
6105
+ const child = spawn2(executable, cmdArgs.map(String), {
5993
6106
  cwd: process.cwd(),
5994
6107
  env,
5995
6108
  stdio: ["pipe", "pipe", "pipe"]
@@ -6159,8 +6272,8 @@ var webFetchTool = {
6159
6272
  if (e.message.startsWith("Blocked:")) throw e;
6160
6273
  throw new NetworkError(`Invalid URL: "${url}"`);
6161
6274
  }
6162
- const controller = new AbortController();
6163
- const timeoutId = setTimeout(() => controller.abort(), 2e4);
6275
+ const controller2 = new AbortController();
6276
+ const timeoutId = setTimeout(() => controller2.abort(), 2e4);
6164
6277
  let rawHtml;
6165
6278
  let finalUrl;
6166
6279
  let contentType;
@@ -6180,7 +6293,7 @@ var webFetchTool = {
6180
6293
  }
6181
6294
  await resolveAndCheck(parsedHop.hostname);
6182
6295
  const r = await fetch(currentUrl, {
6183
- signal: controller.signal,
6296
+ signal: controller2.signal,
6184
6297
  headers: FETCH_HEADERS,
6185
6298
  redirect: "manual"
6186
6299
  // 手动控制重定向
@@ -6531,15 +6644,15 @@ var googleSearchTool = {
6531
6644
  url.searchParams.set("cx", cx);
6532
6645
  url.searchParams.set("q", query);
6533
6646
  url.searchParams.set("num", String(numResults));
6534
- const controller = new AbortController();
6535
- const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
6647
+ const controller2 = new AbortController();
6648
+ const timeout = setTimeout(() => controller2.abort(), REQUEST_TIMEOUT_MS);
6536
6649
  try {
6537
6650
  const response = await fetch(url.toString(), {
6538
6651
  method: "GET",
6539
6652
  headers: {
6540
6653
  "Accept": "application/json"
6541
6654
  },
6542
- signal: controller.signal
6655
+ signal: controller2.signal
6543
6656
  });
6544
6657
  if (!response.ok) {
6545
6658
  const errorBody = await response.text().catch(() => "");
@@ -6923,7 +7036,7 @@ var spawnAgentTool = {
6923
7036
  };
6924
7037
 
6925
7038
  // src/tools/builtin/task-manager.ts
6926
- import { spawn as spawn2 } from "child_process";
7039
+ import { spawn as spawn3 } from "child_process";
6927
7040
  import { randomUUID } from "crypto";
6928
7041
  import { platform as platform3 } from "os";
6929
7042
  var MAX_OUTPUT_CHARS = 1e4;
@@ -6948,7 +7061,7 @@ function createTask(command, description) {
6948
7061
  const isWin = platform3() === "win32";
6949
7062
  const shell = isWin ? "cmd" : "sh";
6950
7063
  const shellFlag = isWin ? "/c" : "-c";
6951
- const proc = spawn2(shell, [shellFlag, command], {
7064
+ const proc = spawn3(shell, [shellFlag, command], {
6952
7065
  stdio: ["ignore", "pipe", "pipe"],
6953
7066
  detached: false,
6954
7067
  env: { ...process.env, PYTHONUTF8: "1" }
@@ -8070,7 +8183,7 @@ var ToolRegistry = class {
8070
8183
  };
8071
8184
 
8072
8185
  // src/mcp/client.ts
8073
- import { spawn as spawn3 } from "child_process";
8186
+ import { spawn as spawn4 } from "child_process";
8074
8187
  var McpClient = class {
8075
8188
  serverId;
8076
8189
  config;
@@ -8108,7 +8221,7 @@ var McpClient = class {
8108
8221
  async connect() {
8109
8222
  const timeout = this.config.timeout ?? MCP_CONNECT_TIMEOUT;
8110
8223
  try {
8111
- this.process = spawn3(this.config.command, this.config.args ?? [], {
8224
+ this.process = spawn4(this.config.command, this.config.args ?? [], {
8112
8225
  stdio: ["pipe", "pipe", "pipe"],
8113
8226
  env: { ...process.env, ...this.config.env },
8114
8227
  // Windows 上 npx 等是 .cmd 脚本,需要 shell 模式
@@ -9374,15 +9487,15 @@ function autoTrimSessionIfNeeded(session, sizeLimit = SESSION_SIZE_LIMIT) {
9374
9487
  // src/web/session-handler.ts
9375
9488
  import { existsSync as existsSync20, readFileSync as readFileSync13, appendFileSync as appendFileSync3, writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, readdirSync as readdirSync9, statSync as statSync8 } from "fs";
9376
9489
  import { join as join13, resolve as resolve4 } from "path";
9377
- import { execSync as execSync4 } from "child_process";
9490
+ import { execSync as execSync3 } from "child_process";
9378
9491
 
9379
9492
  // src/tools/git-context.ts
9380
- import { execSync as execSync3 } from "child_process";
9493
+ import { execSync as execSync2 } from "child_process";
9381
9494
  import { existsSync as existsSync19 } from "fs";
9382
9495
  import { join as join12 } from "path";
9383
9496
  function runGit2(cmd, cwd) {
9384
9497
  try {
9385
- return execSync3(`git ${cmd}`, {
9498
+ return execSync2(`git ${cmd}`, {
9386
9499
  cwd,
9387
9500
  encoding: "utf-8",
9388
9501
  stdio: ["pipe", "pipe", "pipe"],
@@ -11112,7 +11225,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
11112
11225
  let diff;
11113
11226
  try {
11114
11227
  const cmd = staged ? "git diff --staged" : "git diff";
11115
- diff = execSync4(cmd, { encoding: "utf-8", timeout: 1e4 }).trim();
11228
+ diff = execSync3(cmd, { encoding: "utf-8", timeout: 1e4 }).trim();
11116
11229
  } catch {
11117
11230
  this.send({ type: "error", message: "Failed to run git diff." });
11118
11231
  break;
@@ -11151,7 +11264,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
11151
11264
  let secDiff;
11152
11265
  try {
11153
11266
  const cmd = secStaged ? "git diff --staged" : "git diff";
11154
- secDiff = execSync4(cmd, { encoding: "utf-8", timeout: 1e4 }).trim();
11267
+ secDiff = execSync3(cmd, { encoding: "utf-8", timeout: 1e4 }).trim();
11155
11268
  } catch {
11156
11269
  this.send({ type: "error", message: "Failed to run git diff." });
11157
11270
  break;
@@ -11229,7 +11342,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
11229
11342
  case "test": {
11230
11343
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
11231
11344
  try {
11232
- const { executeTests } = await import("./run-tests-KHJ6YCPH.js");
11345
+ const { executeTests } = await import("./run-tests-4XJLQNUW.js");
11233
11346
  const argStr = args.join(" ").trim();
11234
11347
  let testArgs = {};
11235
11348
  if (argStr) {
@@ -385,7 +385,7 @@ ${content}`);
385
385
  }
386
386
  }
387
387
  async function runTaskMode(config, providers, configManager, topic) {
388
- const { TaskOrchestrator } = await import("./task-orchestrator-JB5TZNBK.js");
388
+ const { TaskOrchestrator } = await import("./task-orchestrator-IQTIXEOM.js");
389
389
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
390
390
  let interrupted = false;
391
391
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -30,10 +30,10 @@ import {
30
30
  saveDevState,
31
31
  sessionHasMeaningfulContent,
32
32
  setupProxy
33
- } from "./chunk-MYQANQ6F.js";
33
+ } from "./chunk-KPX72DTU.js";
34
34
  import {
35
35
  ConfigManager
36
- } from "./chunk-US6MQO6W.js";
36
+ } from "./chunk-ING3NMVR.js";
37
37
  import {
38
38
  ToolExecutor,
39
39
  ToolRegistry,
@@ -41,15 +41,18 @@ import {
41
41
  estimateTokens,
42
42
  googleSearchContext,
43
43
  initTheme,
44
+ isInterrupted,
44
45
  lastResponseStore,
45
46
  renderDiff,
47
+ requestInterrupt,
48
+ resetInterrupt,
46
49
  rlInternal,
47
50
  setContextWindow,
48
51
  setMaxOutputCap,
49
52
  spawnAgentContext,
50
53
  theme,
51
54
  undoStack
52
- } from "./chunk-Z2V6EYPQ.js";
55
+ } from "./chunk-CNI26J5Z.js";
53
56
  import "./chunk-2ZD3YTVM.js";
54
57
  import {
55
58
  fileCheckpoints
@@ -67,7 +70,7 @@ import "./chunk-KJLJPUY2.js";
67
70
  import "./chunk-6VRJGH25.js";
68
71
  import "./chunk-2DXY7UGF.js";
69
72
  import "./chunk-KHYD3WXE.js";
70
- import "./chunk-IGNYJUZU.js";
73
+ import "./chunk-KLSISB52.js";
71
74
  import {
72
75
  AGENTIC_BEHAVIOR_GUIDELINE,
73
76
  AUTHOR,
@@ -89,7 +92,7 @@ import {
89
92
  SKILLS_DIR_NAME,
90
93
  VERSION,
91
94
  buildUserIdentityPrompt
92
- } from "./chunk-AKCXRW2Q.js";
95
+ } from "./chunk-5IL2BHSD.js";
93
96
 
94
97
  // src/index.ts
95
98
  import { program } from "commander";
@@ -2609,7 +2612,7 @@ ${hint}` : "")
2609
2612
  usage: "/test [command|filter]",
2610
2613
  async execute(args, ctx) {
2611
2614
  try {
2612
- const { executeTests } = await import("./run-tests-MKBVRMBA.js");
2615
+ const { executeTests } = await import("./run-tests-JROEDZES.js");
2613
2616
  const argStr = args.join(" ").trim();
2614
2617
  let testArgs = {};
2615
2618
  if (argStr) {
@@ -5097,6 +5100,7 @@ Session '${this.resumeSessionId}' not found.
5097
5100
  this.rl.on("SIGINT", () => {
5098
5101
  if (this.streamAbortController) {
5099
5102
  this.streamAbortController.abort();
5103
+ requestInterrupt();
5100
5104
  return;
5101
5105
  }
5102
5106
  if (this.toolExecutor.confirming) {
@@ -5107,6 +5111,11 @@ Session '${this.resumeSessionId}' not found.
5107
5111
  askUserContext.cancelFn();
5108
5112
  return;
5109
5113
  }
5114
+ if (this.toolExecutor.running) {
5115
+ process.stdout.write(theme.warning("\n\u26A1 Ctrl+C \u2014 interrupting tool execution...\n"));
5116
+ requestInterrupt();
5117
+ return;
5118
+ }
5110
5119
  this.handleExit();
5111
5120
  });
5112
5121
  this.showPrompt();
@@ -5237,6 +5246,7 @@ Session '${this.resumeSessionId}' not found.
5237
5246
  `)
5238
5247
  );
5239
5248
  }
5249
+ resetInterrupt();
5240
5250
  const t0 = Date.now();
5241
5251
  try {
5242
5252
  const provider = this.providers.get(this.currentProvider);
@@ -6240,6 +6250,12 @@ ${systemPromptVolatile}` : systemPrompt;
6240
6250
  spawnAgentContext.configManager = this.config;
6241
6251
  ToolExecutor.currentMessageIndex = session.messages.length;
6242
6252
  const toolResults = await this.toolExecutor.executeAll(result.toolCalls);
6253
+ if (isInterrupted()) {
6254
+ spinner.stop();
6255
+ process.stdout.write(theme.warning("\n\u26A1 Interrupted by user (Ctrl+C) \u2014 agentic loop stopped.\n"));
6256
+ this.teardownInterjectionListener();
6257
+ return;
6258
+ }
6243
6259
  const thisRoundTools = result.toolCalls.map((tc) => tc.name);
6244
6260
  roundToolHistory.push({ round: round + 1, tools: thisRoundTools });
6245
6261
  const readFileCalls = result.toolCalls.filter((tc) => tc.name === "read_file");
@@ -6722,7 +6738,7 @@ program.command("web").description("Start Web UI server with browser-based chat
6722
6738
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
6723
6739
  process.exit(1);
6724
6740
  }
6725
- const { startWebServer } = await import("./server-J7BPHI7D.js");
6741
+ const { startWebServer } = await import("./server-WHTZFKVB.js");
6726
6742
  await startWebServer({ port, host: options.host });
6727
6743
  });
6728
6744
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
@@ -6845,7 +6861,7 @@ program.command("sessions").description("List recent conversation sessions").act
6845
6861
  });
6846
6862
  program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
6847
6863
  try {
6848
- const batch = await import("./batch-KZQHKPE5.js");
6864
+ const batch = await import("./batch-SK2YCZEY.js");
6849
6865
  switch (action) {
6850
6866
  case "submit":
6851
6867
  if (!arg) {
@@ -6888,7 +6904,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
6888
6904
  }
6889
6905
  });
6890
6906
  program.command("mcp-serve").description("Start an MCP server over STDIO, exposing aicli's built-in tools to Claude Desktop / Cursor / other MCP clients").option("--allow-destructive", "Allow bash / run_interactive / task_create (always destructive in MCP mode)").option("--allow-outside-cwd", "Allow tool path arguments to escape the sandbox root \u2014 disabled by default").option("--tools <list>", "Comma-separated whitelist of tools to expose (default: all eligible tools)").option("--cwd <path>", "Working directory AND sandbox root (default: current directory)").action(async (options) => {
6891
- const { startMcpServer } = await import("./server-B6U5GMZ7.js");
6907
+ const { startMcpServer } = await import("./server-DB4GMBDN.js");
6892
6908
  await startMcpServer({
6893
6909
  allowDestructive: !!options.allowDestructive,
6894
6910
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7015,7 +7031,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7015
7031
  }),
7016
7032
  config.get("customProviders")
7017
7033
  );
7018
- const { startHub } = await import("./hub-A66CLTFF.js");
7034
+ const { startHub } = await import("./hub-YRYUBSEQ.js");
7019
7035
  await startHub(
7020
7036
  {
7021
7037
  topic: topic ?? "",
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-XQHCCV3A.js";
4
+ } from "./chunk-A4TUAW4J.js";
5
5
  export {
6
6
  executeTests,
7
7
  runTestsTool
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-IGNYJUZU.js";
6
- import "./chunk-AKCXRW2Q.js";
5
+ } from "./chunk-KLSISB52.js";
6
+ import "./chunk-5IL2BHSD.js";
7
7
  export {
8
8
  executeTests,
9
9
  runTestsTool
@@ -3,7 +3,7 @@ import {
3
3
  ToolRegistry,
4
4
  getDangerLevel,
5
5
  schemaToJsonSchema
6
- } from "./chunk-Z2V6EYPQ.js";
6
+ } from "./chunk-CNI26J5Z.js";
7
7
  import "./chunk-2ZD3YTVM.js";
8
8
  import "./chunk-4BKXL7SM.js";
9
9
  import "./chunk-ANYYM4CF.js";
@@ -12,10 +12,10 @@ import "./chunk-KJLJPUY2.js";
12
12
  import "./chunk-6VRJGH25.js";
13
13
  import "./chunk-2DXY7UGF.js";
14
14
  import "./chunk-KHYD3WXE.js";
15
- import "./chunk-IGNYJUZU.js";
15
+ import "./chunk-KLSISB52.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-AKCXRW2Q.js";
18
+ } from "./chunk-5IL2BHSD.js";
19
19
 
20
20
  // src/mcp/server.ts
21
21
  import { createInterface } from "readline";
@@ -23,10 +23,10 @@ import {
23
23
  persistToolRound,
24
24
  rebuildExtraMessages,
25
25
  setupProxy
26
- } from "./chunk-MYQANQ6F.js";
26
+ } from "./chunk-KPX72DTU.js";
27
27
  import {
28
28
  ConfigManager
29
- } from "./chunk-US6MQO6W.js";
29
+ } from "./chunk-ING3NMVR.js";
30
30
  import {
31
31
  ToolExecutor,
32
32
  ToolRegistry,
@@ -44,7 +44,7 @@ import {
44
44
  spawnAgentContext,
45
45
  truncateOutput,
46
46
  undoStack
47
- } from "./chunk-Z2V6EYPQ.js";
47
+ } from "./chunk-CNI26J5Z.js";
48
48
  import "./chunk-2ZD3YTVM.js";
49
49
  import "./chunk-4BKXL7SM.js";
50
50
  import "./chunk-ANYYM4CF.js";
@@ -53,7 +53,7 @@ import "./chunk-KJLJPUY2.js";
53
53
  import "./chunk-6VRJGH25.js";
54
54
  import "./chunk-2DXY7UGF.js";
55
55
  import "./chunk-KHYD3WXE.js";
56
- import "./chunk-IGNYJUZU.js";
56
+ import "./chunk-KLSISB52.js";
57
57
  import {
58
58
  AGENTIC_BEHAVIOR_GUIDELINE,
59
59
  AUTHOR,
@@ -72,7 +72,7 @@ import {
72
72
  SKILLS_DIR_NAME,
73
73
  VERSION,
74
74
  buildUserIdentityPrompt
75
- } from "./chunk-AKCXRW2Q.js";
75
+ } from "./chunk-5IL2BHSD.js";
76
76
 
77
77
  // src/web/server.ts
78
78
  import express from "express";
@@ -2237,7 +2237,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
2237
2237
  case "test": {
2238
2238
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
2239
2239
  try {
2240
- const { executeTests } = await import("./run-tests-MKBVRMBA.js");
2240
+ const { executeTests } = await import("./run-tests-JROEDZES.js");
2241
2241
  const argStr = args.join(" ").trim();
2242
2242
  let testArgs = {};
2243
2243
  if (argStr) {
@@ -4,7 +4,7 @@ import {
4
4
  getDangerLevel,
5
5
  googleSearchContext,
6
6
  truncateOutput
7
- } from "./chunk-Z2V6EYPQ.js";
7
+ } from "./chunk-CNI26J5Z.js";
8
8
  import "./chunk-2ZD3YTVM.js";
9
9
  import "./chunk-4BKXL7SM.js";
10
10
  import "./chunk-ANYYM4CF.js";
@@ -13,10 +13,10 @@ import "./chunk-KJLJPUY2.js";
13
13
  import "./chunk-6VRJGH25.js";
14
14
  import "./chunk-2DXY7UGF.js";
15
15
  import "./chunk-KHYD3WXE.js";
16
- import "./chunk-IGNYJUZU.js";
16
+ import "./chunk-KLSISB52.js";
17
17
  import {
18
18
  SUBAGENT_ALLOWED_TOOLS
19
- } from "./chunk-AKCXRW2Q.js";
19
+ } from "./chunk-5IL2BHSD.js";
20
20
 
21
21
  // src/hub/task-orchestrator.ts
22
22
  import { createInterface } from "readline";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.91",
3
+ "version": "0.4.92",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",