jinzd-ai-cli 0.4.317 → 0.4.319

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.
Files changed (35) hide show
  1. package/dist/{batch-OWVPYMTH.js → batch-CQ542WJF.js} +2 -2
  2. package/dist/{chunk-K2TKTYEH.js → chunk-2PAQOR2X.js} +9 -9
  3. package/dist/{chunk-LONB36SP.js → chunk-46OEMKQX.js} +0 -2
  4. package/dist/{chunk-HDHVWGDA.js → chunk-662ZJPJE.js} +1 -1
  5. package/dist/{chunk-X4GNEJNN.js → chunk-A7YZLLWN.js} +1 -1
  6. package/dist/{chunk-WJOINCVO.js → chunk-AC44E4CV.js} +28 -16
  7. package/dist/{chunk-DPWHBIK2.js → chunk-D6BLSFYD.js} +4 -4
  8. package/dist/{chunk-DOWBL4OI.js → chunk-DCQDFQDW.js} +1 -1
  9. package/dist/{chunk-6EM2TRG5.js → chunk-GP24X3KJ.js} +1 -1
  10. package/dist/{chunk-6VBW3L57.js → chunk-GVAAGBHX.js} +2 -1
  11. package/dist/{chunk-VZBBSBSN.js → chunk-KEOMNFBH.js} +1 -1
  12. package/dist/{chunk-2Z7SOAPR.js → chunk-N2MHUA4B.js} +5 -5
  13. package/dist/{chunk-HD7KVZLR.js → chunk-OQZIP4LU.js} +1 -1
  14. package/dist/{chunk-S73DO2G5.js → chunk-PGQ5OV3P.js} +1 -1
  15. package/dist/{chunk-VUZCU6BH.js → chunk-SZBSTSG4.js} +4 -4
  16. package/dist/{chunk-27RIJK3U.js → chunk-Y3SEC5EC.js} +28 -16
  17. package/dist/{chunk-LZJHXSR3.js → chunk-YHMQMP2I.js} +99 -62
  18. package/dist/{ci-ED4EZGRM.js → ci-HAPWBC37.js} +6 -6
  19. package/dist/{ci-format-2ORFD7KF.js → ci-format-NGWP4GTQ.js} +2 -2
  20. package/dist/{constants-N3AHLPRZ.js → constants-CPHZLOCQ.js} +1 -1
  21. package/dist/{constants-QX6K72OV.js → constants-GSUK6ILC.js} +1 -1
  22. package/dist/{doctor-cli-J6NQF6HS.js → doctor-cli-L6AK2GJ7.js} +6 -6
  23. package/dist/electron-server.js +110 -74
  24. package/dist/{hub-B6SI42VX.js → hub-TCZFG2ZG.js} +1 -1
  25. package/dist/index.js +21 -21
  26. package/dist/{persistent-memory-5VRVOD76.js → persistent-memory-E3UYP7RJ.js} +2 -2
  27. package/dist/{persistent-memory-6AEA7G2Q.js → persistent-memory-IPNMYXU4.js} +2 -2
  28. package/dist/{pr-D3A76PY6.js → pr-J5TSU5P6.js} +6 -6
  29. package/dist/{run-tests-J3N7IM4M.js → run-tests-FLGSE63O.js} +2 -2
  30. package/dist/{run-tests-UFL7ZB4U.js → run-tests-PDD4KUQL.js} +2 -2
  31. package/dist/{server-FBIKTICF.js → server-3C6IK3JE.js} +6 -6
  32. package/dist/{server-NOU4PXEC.js → server-XQ3IQUZ5.js} +16 -16
  33. package/dist/{task-orchestrator-KT6G2WSM.js → task-orchestrator-544JETWF.js} +6 -6
  34. package/dist/{usage-QV3RTJ7B.js → usage-MQTA7HHZ.js} +3 -3
  35. package/package.json +1 -1
@@ -55,7 +55,7 @@ import {
55
55
  touchMemoryReferences,
56
56
  updateMemoryApproval,
57
57
  updateMemoryEntry
58
- } from "./chunk-6EM2TRG5.js";
58
+ } from "./chunk-GP24X3KJ.js";
59
59
  import {
60
60
  DEFAULT_PATTERNS,
61
61
  redactJson,
@@ -77,10 +77,11 @@ import {
77
77
  decodeWindowsBuffer,
78
78
  killProcessTree,
79
79
  looksLikeGbkMojibake,
80
+ posixShell,
80
81
  recoverGbkMojibake,
81
82
  runTestsTool,
82
83
  shellInvocation
83
- } from "./chunk-WJOINCVO.js";
84
+ } from "./chunk-AC44E4CV.js";
84
85
  import {
85
86
  getCurrentSessionKey,
86
87
  getExecutionConfigDir,
@@ -122,7 +123,7 @@ import {
122
123
  SUBAGENT_MAX_ROUNDS_LIMIT,
123
124
  VERSION,
124
125
  buildUserIdentityPrompt
125
- } from "./chunk-DOWBL4OI.js";
126
+ } from "./chunk-DCQDFQDW.js";
126
127
 
127
128
  // src/web/access.ts
128
129
  import { randomBytes, timingSafeEqual } from "crypto";
@@ -994,8 +995,6 @@ var PRICING_TABLE = {
994
995
  // GLM-5V-Turbo(2026-04 视觉编程旗舰)官方直连 API 定价 $1.20 / $4.00。
995
996
  "glm-5v-turbo": { input: 1.2, output: 4 },
996
997
  "glm-5.1": { input: 0.95, output: 3.15 },
997
- "glm-5.1-reasoning": { input: 1.4, output: 4.4 },
998
- "glm-5.1-air": { input: 0.4, output: 1.2 },
999
998
  "glm-z1": { input: 0.5, output: 1.5 },
1000
999
  "glm-z1-air": { input: 0.2, output: 0.6 },
1001
1000
  "glm-z1-flash": { input: 0, output: 0 },
@@ -1393,7 +1392,8 @@ function getDangerLevel(toolName, args) {
1393
1392
  if (/\bgit\s+(?:clean\b|reset\s+--hard\b|push\b[^\n]*(?:--force\b|\s-f\b))/i.test(cmd)) return "destructive";
1394
1393
  if (/\brm\s+[^\n]*(?:-\w*[rRfF]\w*|--recursive|--force)\b/.test(cmd)) return "destructive";
1395
1394
  if (/\brm\s+\S/.test(cmd)) return "destructive";
1396
- if (/\brmdir\b|\bformat\b|\bmkfs\b|\bdd\s+if=|\bshred\b|\bfdisk\b|\bparted\b/.test(cmd)) return "destructive";
1395
+ if (/\brmdir\b|\bmkfs\b|\bdd\s+if=|\bshred\b|\bfdisk\b|\bparted\b/.test(cmd)) return "destructive";
1396
+ if (/(?:^|[;&|(\n]\s*)format(?:\.com)?\s+[A-Za-z]:/im.test(cmd)) return "destructive";
1397
1397
  if (/\bshutdown\b|\breboot\b|\bhalt\b|\bpoweroff\b/.test(cmd)) return "destructive";
1398
1398
  if (/\bkill\s+-9\b|\bkillall\b/.test(cmd)) return "destructive";
1399
1399
  if (/\bRemove-Item\b|\bri\s+\S/i.test(cmd)) return "destructive";
@@ -4340,10 +4340,10 @@ var ZHIPU_CONFIG = {
4340
4340
  { id: "glm-5.3-flash", displayName: "GLM-5.3 Flash (\u539F\u751F\u591A\u6A21\u6001, 1M, \u8F93\u5165\u7EA6\u4E3A 5.3 \u7684 1/10, \u59CB\u7EC8\u601D\u8003)", contextWindow: 1048576, supportsStreaming: true, supportsThinking: true },
4341
4341
  { id: "glm-5.2", displayName: "GLM-5.2 (2026-06 Flagship, 1M, Coding)", contextWindow: 1048576, supportsStreaming: true, supportsThinking: true },
4342
4342
  { id: "glm-5v-turbo", displayName: "GLM-5V-Turbo (Multimodal Vision + Coding)", contextWindow: 202752, supportsStreaming: true },
4343
- { id: "glm-5.1", displayName: "GLM-5.1 (2026 Flagship, 200K, Agent+Code)", contextWindow: 204800, supportsStreaming: true, supportsThinking: true },
4344
- { id: "glm-5.1-reasoning", displayName: "GLM-5.1 Reasoning (Deep Thinking)", contextWindow: 204800, supportsStreaming: true, supportsThinking: true },
4345
- { id: "glm-5.1-air", displayName: "GLM-5.1 Air (Lightweight 5.1)", contextWindow: 204800, supportsStreaming: true, supportsThinking: true },
4346
- { id: "glm-5", displayName: "GLM-5 (Flagship, Deep Thinking)", contextWindow: 131072, supportsStreaming: true, supportsThinking: true },
4343
+ // 2026-10-07 清理:移除 glm-5.1-reasoning / glm-5.1-air(官方模型总览与发布记录里**从未出现过**,
4344
+ // 当初取自第三方标注,同 v0.4.198 的 `glm-5.2[1m]`)与 glm-5 / glm-5.1(已被 glm-5.2 / 5.3 取代,
4345
+ // 要便宜有 glm-5.3-flash;glm-5 这里标的 128K 与官方 200K 也不符)。后两者端点仍可用,`/model` 照收,
4346
+ // pricing.ts 保留其费率供历史成本回算。
4347
4347
  { id: "glm-4.6", displayName: "GLM-4.6 (200K, \u4E2D\u6587\u5199\u4F5C\u63A8\u8350)", contextWindow: 204800, supportsStreaming: true }
4348
4348
  ]
4349
4349
  };
@@ -6084,7 +6084,7 @@ var undoStack = new UndoStack();
6084
6084
  import { spawn } from "child_process";
6085
6085
  import { platform } from "os";
6086
6086
  var IS_WINDOWS2 = platform() === "win32";
6087
- var SHELL = IS_WINDOWS2 ? "powershell.exe" : process.env["SHELL"] ?? "/bin/bash";
6087
+ var SHELL = IS_WINDOWS2 ? "powershell.exe" : posixShell();
6088
6088
  var pool = /* @__PURE__ */ new Map();
6089
6089
  var IDLE_EVICT_MS = 5 * 6e4;
6090
6090
  var evictionTimer = null;
@@ -6093,7 +6093,11 @@ function spawnShell(cwd) {
6093
6093
  const proc = spawn(SHELL, shellArgs, {
6094
6094
  cwd,
6095
6095
  windowsHide: true,
6096
- stdio: ["pipe", "pipe", "pipe"]
6096
+ stdio: ["pipe", "pipe", "pipe"],
6097
+ // POSIX: own process group, so a timeout / Ctrl+C can kill the whole tree
6098
+ // (killProcessTree with processGroup=true). Without it only the shell host
6099
+ // died and grandchildren were orphaned (2026-10-07 audit A-01).
6100
+ detached: !IS_WINDOWS2
6097
6101
  });
6098
6102
  proc.on("exit", () => {
6099
6103
  for (const [key, entry] of pool) {
@@ -6120,13 +6124,17 @@ function startEvictionTimer() {
6120
6124
  }
6121
6125
  }, 6e4).unref();
6122
6126
  }
6127
+ function stderrMarker(id) {
6128
+ return `AICLI_MARKER_ERR:${id}`;
6129
+ }
6123
6130
  function buildWrappedCommand(command, id, isWindows) {
6124
6131
  const markerStart = `AICLI_MARKER_START:${id}`;
6125
6132
  const markerEnd = `AICLI_MARKER_END:${id}`;
6126
6133
  if (!isWindows) {
6134
+ const quoted = `'${command.replace(/'/g, `'\\''`)}'`;
6127
6135
  return `echo "${markerStart}"
6128
- ${command}
6129
- echo "${markerEnd}:$?"`;
6136
+ eval ${quoted} </dev/null
6137
+ __aicli_rc=$?; echo "${stderrMarker(id)}" >&2; echo "${markerEnd}:$__aicli_rc"`;
6130
6138
  }
6131
6139
  const b64 = Buffer.from(command, "utf-8").toString("base64");
6132
6140
  const decoded = `[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${b64}'))`;
@@ -6158,32 +6166,46 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
6158
6166
  const markerStartPattern = `AICLI_MARKER_START:${id}`;
6159
6167
  const markerEndPattern = `AICLI_MARKER_END:${id}`;
6160
6168
  const proc = entry.proc;
6169
+ const errMarker = stderrMarker(id);
6170
+ const cleanStderr = (s) => {
6171
+ const i = s.indexOf(errMarker);
6172
+ return i < 0 ? s : s.slice(0, i);
6173
+ };
6174
+ const checkDone = () => {
6175
+ if (resolved) return;
6176
+ const parsed = extractPoolOutput(stdout, markerStartPattern, markerEndPattern);
6177
+ if (parsed.exitCode === null) return;
6178
+ if (!IS_WINDOWS2 && !stderr.includes(errMarker)) return;
6179
+ stdout = parsed.output;
6180
+ stderr = cleanStderr(stderr);
6181
+ resolved = true;
6182
+ cleanup();
6183
+ resolve13({ stdout, stderr, exitCode: parsed.exitCode, timedOut, aborted });
6184
+ };
6161
6185
  const onData = (chunk) => {
6162
6186
  stdout += IS_WINDOWS2 ? decodeWindowsBuffer(chunk) : chunk.toString("utf-8");
6163
- if (!resolved && stdout.includes(markerEndPattern)) {
6164
- const endLine = stdout.split("\n").find((l) => l.includes(markerEndPattern));
6165
- const exitCode = endLine ? parseEndMarker(endLine) : null;
6166
- stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
6167
- resolved = true;
6168
- cleanup();
6169
- resolve13({ stdout, stderr, exitCode, timedOut, aborted });
6170
- }
6187
+ checkDone();
6171
6188
  };
6172
6189
  const onErr = (chunk) => {
6173
6190
  stderr += IS_WINDOWS2 ? decodeWindowsBuffer(chunk) : chunk.toString("utf-8");
6191
+ checkDone();
6174
6192
  };
6175
6193
  const finishPoolFailure = (message, exitCode = null) => {
6176
6194
  if (resolved) return;
6177
6195
  resolved = true;
6178
- stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
6196
+ stdout = extractPoolOutput(stdout, markerStartPattern, markerEndPattern).output;
6197
+ stderr = cleanStderr(stderr);
6179
6198
  stderr += `${stderr ? "\n" : ""}[pool terminated] ${message}`;
6180
6199
  cleanup();
6181
6200
  pool.delete(sessionKey);
6182
- resolve13({ stdout, stderr, exitCode: exitCode === 0 ? null : exitCode, timedOut, aborted });
6201
+ resolve13({ stdout, stderr, exitCode, timedOut, aborted });
6183
6202
  };
6184
6203
  const onClose = (code, signal) => {
6185
6204
  const detail = signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`;
6186
- finishPoolFailure(`Shell exited before the completion marker (${detail}).`, code);
6205
+ finishPoolFailure(
6206
+ `The shell exited before the command finished (${detail}) \u2014 typically an explicit \`exit\`/\`exec\`, or \`set -e\` aborting on a failing command. Shell state (variables, options, functions) was reset; the next command runs in a fresh shell in the same directory.`,
6207
+ signal ? null : code
6208
+ );
6187
6209
  };
6188
6210
  const onStdinError = (err) => {
6189
6211
  finishPoolFailure(`Shell stdin failed: ${err.message}`);
@@ -6196,10 +6218,11 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
6196
6218
  if (resolved) return;
6197
6219
  timedOut = true;
6198
6220
  resolved = true;
6199
- stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
6221
+ stdout = extractPoolOutput(stdout, markerStartPattern, markerEndPattern).output;
6222
+ stderr = cleanStderr(stderr);
6200
6223
  cleanup();
6201
6224
  resolve13({ stdout, stderr, exitCode: null, timedOut, aborted });
6202
- killProcessTree(proc);
6225
+ killProcessTree(proc, true);
6203
6226
  pool.delete(sessionKey);
6204
6227
  }, timeout);
6205
6228
  const onAbort = () => {
@@ -6207,9 +6230,10 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
6207
6230
  aborted = true;
6208
6231
  resolved = true;
6209
6232
  cleanup();
6210
- stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
6233
+ stdout = extractPoolOutput(stdout, markerStartPattern, markerEndPattern).output;
6234
+ stderr = cleanStderr(stderr);
6211
6235
  resolve13({ stdout, stderr, exitCode: null, timedOut, aborted });
6212
- killProcessTree(proc);
6236
+ killProcessTree(proc, true);
6213
6237
  pool.delete(sessionKey);
6214
6238
  };
6215
6239
  if (abortSignal?.aborted) {
@@ -6241,36 +6265,18 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
6241
6265
  }
6242
6266
  });
6243
6267
  }
6244
- function parseEndMarker(line) {
6245
- const idx = line.lastIndexOf(":");
6246
- if (idx < 0) return null;
6247
- const code = line.slice(idx + 1).trim();
6248
- return /^\d+$/.test(code) ? Number(code) : null;
6268
+ function extractPoolOutput(stdout, startMarker, endMarker) {
6269
+ const startMatch = new RegExp(`${escapeRegExp(startMarker)}\\r?\\n`).exec(stdout);
6270
+ const bodyStart = startMatch ? startMatch.index + startMatch[0].length : 0;
6271
+ const endMatch = new RegExp(`${escapeRegExp(endMarker)}:(\\d+)\\r?\\n`).exec(stdout.slice(bodyStart));
6272
+ const body = endMatch ? stdout.slice(bodyStart, bodyStart + endMatch.index) : stdout.slice(bodyStart);
6273
+ return {
6274
+ output: body.trim(),
6275
+ exitCode: endMatch ? Number(endMatch[1]) : null
6276
+ };
6249
6277
  }
6250
- function stripMarkerOutput(stdout, startMarker, endMarker) {
6251
- const lines = stdout.split("\n");
6252
- let capturing = false;
6253
- const out = [];
6254
- for (const line of lines) {
6255
- if (line.includes(startMarker)) {
6256
- capturing = true;
6257
- continue;
6258
- }
6259
- if (line.includes(endMarker)) {
6260
- capturing = false;
6261
- continue;
6262
- }
6263
- if (capturing) {
6264
- out.push(line);
6265
- }
6266
- }
6267
- if (!stdout.includes(endMarker) && out.length === 0) {
6268
- const startIdx = stdout.indexOf(startMarker);
6269
- if (startIdx >= 0) {
6270
- return stdout.slice(startIdx + startMarker.length).trimStart();
6271
- }
6272
- }
6273
- return out.join("\n").trim();
6278
+ function escapeRegExp(s) {
6279
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6274
6280
  }
6275
6281
  function cleanupPoolSession(sessionKey) {
6276
6282
  const entry = pool.get(sessionKey);
@@ -6284,7 +6290,7 @@ function cleanupPoolSession(sessionKey) {
6284
6290
 
6285
6291
  // src/tools/builtin/bash.ts
6286
6292
  var IS_WINDOWS3 = platform2() === "win32";
6287
- var SHELL2 = IS_WINDOWS3 ? "powershell.exe" : process.env["SHELL"] ?? "/bin/bash";
6293
+ var SHELL2 = IS_WINDOWS3 ? "powershell.exe" : posixShell();
6288
6294
  var cwdBySession = /* @__PURE__ */ new Map();
6289
6295
  function getCwd() {
6290
6296
  const key = getCurrentSessionKey();
@@ -6413,7 +6419,8 @@ Important rules:
6413
6419
  }
6414
6420
  if (timedOut) {
6415
6421
  pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
6416
- throw new ToolError("bash", formatTimeoutMessage(timeout, MAX_TIMEOUT, command));
6422
+ throw new ToolError("bash", formatTimeoutMessage(timeout, MAX_TIMEOUT, command, `${stdout}
6423
+ ${stderr}`));
6417
6424
  }
6418
6425
  if (status !== 0 || timedOut) {
6419
6426
  const poolStdout = (stdout ?? "").trim();
@@ -6432,7 +6439,12 @@ ${combined || formatFailureFallback(status)}
6432
6439
  }
6433
6440
  pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
6434
6441
  updateCwdFromCommand(command, effectiveCwd);
6435
- return annotateSuccessOutput(command, stdout) || emptyOutputResult(command, stderr ?? "");
6442
+ const out = annotateSuccessOutput(command, suppressBinaryOutput(stdout));
6443
+ const poolNote = /\[pool terminated\]/.test(stderr ?? "") ? `
6444
+
6445
+ ${(stderr ?? "").trim()}` : "";
6446
+ const body = out ? out + poolNote : emptyOutputResult(command, stderr ?? "");
6447
+ return body + backgroundJobNote(command);
6436
6448
  }
6437
6449
  try {
6438
6450
  const { stdout, stderr, status, signal, timedOut, aborted } = await runShell(
@@ -6469,17 +6481,18 @@ ${combined || formatFailureFallback(status)}
6469
6481
  updateCwdFromCommand(command, effectiveCwd);
6470
6482
  pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
6471
6483
  const result = Buffer.isBuffer(stdout) ? IS_WINDOWS3 ? decodeWindowsBuffer(stdout) : stdout.toString("utf-8") : String(stdout ?? "");
6472
- return annotateSuccessOutput(command, result) || emptyOutputResult(
6484
+ return (annotateSuccessOutput(command, suppressBinaryOutput(result)) || emptyOutputResult(
6473
6485
  command,
6474
6486
  Buffer.isBuffer(stderr) ? IS_WINDOWS3 ? decodeWindowsBuffer(stderr) : stderr.toString("utf-8") : String(stderr ?? "")
6475
- );
6487
+ )) + backgroundJobNote(command);
6476
6488
  } catch (err) {
6477
6489
  pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
6478
6490
  if (err && typeof err === "object") {
6479
6491
  const execErr = err;
6480
6492
  const isTimeout = execErr.code === "ETIMEDOUT" || execErr.status == null && execErr.signal === "SIGTERM" || /ETIMEDOUT/i.test(execErr.message ?? "");
6481
6493
  if (isTimeout) {
6482
- throw new ToolError("bash", formatTimeoutMessage(timeout, MAX_TIMEOUT, command));
6494
+ const captured = [execErr.stdout, execErr.stderr].map((b) => Buffer.isBuffer(b) ? IS_WINDOWS3 ? decodeWindowsBuffer(b) : b.toString("utf-8") : String(b ?? "")).join("\n");
6495
+ throw new ToolError("bash", formatTimeoutMessage(timeout, MAX_TIMEOUT, command, captured));
6483
6496
  }
6484
6497
  if ("status" in execErr && execErr.status !== void 0) {
6485
6498
  const stderr = IS_WINDOWS3 && Buffer.isBuffer(execErr.stderr) ? decodeWindowsBuffer(execErr.stderr).trim() : execErr.stderr?.toString().trim() ?? "";
@@ -6512,8 +6525,15 @@ function looksLikeTestCommand(command) {
6512
6525
  /(?:^|[;&|(\s])(?:go|cargo)\s+test\b/.test(command)
6513
6526
  );
6514
6527
  }
6515
- function formatTimeoutMessage(timeout, maxTimeout, command) {
6528
+ var TIMEOUT_CAPTURE_MAX = 2e3;
6529
+ function formatTimeoutMessage(timeout, maxTimeout, command, captured) {
6516
6530
  const seconds = Math.round(timeout / 1e3);
6531
+ const tail = (captured ?? "").trim();
6532
+ const capturedSection = tail ? [
6533
+ "Output captured before the timeout (last part \u2014 the cause is often here):",
6534
+ tail.length > TIMEOUT_CAPTURE_MAX ? "\u2026" + tail.slice(-TIMEOUT_CAPTURE_MAX) : tail,
6535
+ ""
6536
+ ] : [];
6517
6537
  const testRunnerHint = command !== void 0 && looksLikeTestCommand(command) ? [
6518
6538
  "This looks like a TEST run. Prefer the 'run_tests' tool instead of running the test runner through bash: it has a 5-minute timeout, auto-detects the framework, and returns a structured summary (no findstr/grep filtering needed).",
6519
6539
  ""
@@ -6521,6 +6541,7 @@ function formatTimeoutMessage(timeout, maxTimeout, command) {
6521
6541
  return [
6522
6542
  `Command timed out after ${seconds}s.`,
6523
6543
  "",
6544
+ ...capturedSection,
6524
6545
  ...testRunnerHint,
6525
6546
  "The previous command ran for longer than the timeout limit and was killed. This usually means it is scanning a large filesystem tree (recursive Get-ChildItem / find), compressing a big archive, or waiting on a network request.",
6526
6547
  "",
@@ -6693,6 +6714,19 @@ ${err}`;
6693
6714
  return detectPowerShellBackslashQuote(command) ? base + BACKSLASH_QUOTE_SILENT_WARNING : base;
6694
6715
  }
6695
6716
  var PS_TEXT_READ_CMDLET = /\b(?:Get-Content|gc|cat|type|Select-String|sls|Import-Csv)\b/i;
6717
+ function suppressBinaryOutput(stdout) {
6718
+ if (!stdout) return stdout;
6719
+ const sample = stdout.slice(0, 8e3);
6720
+ const replacement = (sample.match(/\uFFFD/g) ?? []).length;
6721
+ if (!sample.includes("\0") && !(sample.length >= 64 && replacement / sample.length > 0.3)) {
6722
+ return stdout;
6723
+ }
6724
+ return `[binary output suppressed: ${Buffer.byteLength(stdout, "utf-8")} bytes. Inspect it with a hex dump limited in size (e.g. \`xxd file | head -20\`), or use \`file\` to identify the type.]`;
6725
+ }
6726
+ function backgroundJobNote(command) {
6727
+ if (IS_WINDOWS3 || !/(?:^|\s)&(?![&>])/m.test(command)) return "";
6728
+ return "\n\n[Note: this command started a background job (`&`). It is not tracked by aicli \u2014 task_list/task_stop cannot see it and it keeps running after this session. For long-running processes (dev servers, watchers) prefer task_create.]";
6729
+ }
6696
6730
  function annotateSuccessOutput(command, stdout) {
6697
6731
  if (!IS_WINDOWS3 || !PS_TEXT_READ_CMDLET.test(command)) return stdout;
6698
6732
  if (!looksLikeGbkMojibake(stdout)) return stdout;
@@ -6870,7 +6904,9 @@ function runShell(command, opts) {
6870
6904
  cwd: opts.cwd,
6871
6905
  env: opts.env,
6872
6906
  windowsHide: true,
6873
- stdio: ["ignore", "pipe", "pipe"]
6907
+ stdio: ["ignore", "pipe", "pipe"],
6908
+ // POSIX: own process group so killChild can take the whole tree down (A-01).
6909
+ detached: !IS_WINDOWS3
6874
6910
  });
6875
6911
  const stdoutChunks = [];
6876
6912
  const stderrChunks = [];
@@ -6927,7 +6963,7 @@ function runShell(command, opts) {
6927
6963
  });
6928
6964
  }
6929
6965
  function killChild(child) {
6930
- killProcessTree(child);
6966
+ killProcessTree(child, true);
6931
6967
  }
6932
6968
  function updateCwdFromCommand(command, baseCwd) {
6933
6969
  const cdMatches = [...command.matchAll(/(?:^|[;&|])\s*cd\s+(['"]?)([^\s;&|'"]+)\1/g)];
@@ -17490,7 +17526,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
17490
17526
  Cost: ${formatCost(cost)}` : "";
17491
17527
  let memoryLine = "";
17492
17528
  try {
17493
- const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-6AEA7G2Q.js");
17529
+ const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-IPNMYXU4.js");
17494
17530
  const pending = countPendingMemories2(ctx.config.getConfigDir());
17495
17531
  if (pending > 0) memoryLine = `
17496
17532
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -18478,7 +18514,7 @@ async function handleTest(args, ctx) {
18478
18514
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
18479
18515
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
18480
18516
  }
18481
- const runTests = ctx.runTests ?? (await import("./run-tests-UFL7ZB4U.js")).executeTests;
18517
+ const runTests = ctx.runTests ?? (await import("./run-tests-PDD4KUQL.js")).executeTests;
18482
18518
  const report = await runTests(testArgs);
18483
18519
  ctx.send({ type: "info", message: report });
18484
18520
  } catch (err) {
@@ -18869,7 +18905,7 @@ async function handleMemory(args, ctx) {
18869
18905
  }
18870
18906
  if (intent.kind === "status") {
18871
18907
  const { getChatIndexStatus: getChatIndexStatus2 } = await import("./chat-index-RLVLQRRC.js");
18872
- const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-6AEA7G2Q.js");
18908
+ const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-IPNMYXU4.js");
18873
18909
  const memories = listMemoryEntries2(configDir, { includeExpired: true, includeRejected: true });
18874
18910
  const injected = formatMemoryForPrompt2(configDir, process.cwd(), ctx.config.get("memory")?.maxChars);
18875
18911
  const view = buildMemoryStatusView({
@@ -18892,7 +18928,7 @@ async function handleMemory(args, ctx) {
18892
18928
  return;
18893
18929
  }
18894
18930
  if (intent.kind === "recall") {
18895
- const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-6AEA7G2Q.js");
18931
+ const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-IPNMYXU4.js");
18896
18932
  const { searchChatMemory: searchChatMemory2 } = await import("./chat-index-RLVLQRRC.js");
18897
18933
  const persistentHits = searchPersistentMemories2(configDir, intent.query, process.cwd(), 3);
18898
18934
  if (persistentHits.length > 0) {
@@ -19013,7 +19049,7 @@ async function handleMemory(args, ctx) {
19013
19049
  ctx.handleMemoryManage(intent.action, args[1], intent.action === "expire" ? args[2] : void 0);
19014
19050
  } else if (intent.kind === "export") {
19015
19051
  if (args[1] === "md") {
19016
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-6AEA7G2Q.js");
19052
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-IPNMYXU4.js");
19017
19053
  ctx.send({
19018
19054
  type: "export_data",
19019
19055
  format: "md",
@@ -20018,7 +20054,7 @@ No tools match "${filter}".
20018
20054
  const { join: join26 } = await import("path");
20019
20055
  const { existsSync: existsSync32 } = await import("fs");
20020
20056
  const { getGitRoot: getGitRoot2 } = await import("./git-context-VNCA2GU7.js");
20021
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-N3AHLPRZ.js");
20057
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-CPHZLOCQ.js");
20022
20058
  const { approveProject, hashMcpFile } = await import("./project-trust-6CJB5ZMX.js");
20023
20059
  const cwd = process.cwd();
20024
20060
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -20937,7 +20973,7 @@ function createReviewCommands() {
20937
20973
  usage: "/test [command|filter]",
20938
20974
  async execute(args, ctx) {
20939
20975
  try {
20940
- const { executeTests } = await import("./run-tests-UFL7ZB4U.js");
20976
+ const { executeTests } = await import("./run-tests-PDD4KUQL.js");
20941
20977
  const argStr = args.join(" ").trim();
20942
20978
  let testArgs = {};
20943
20979
  if (argStr) {
@@ -158,7 +158,7 @@ ${content}`);
158
158
  }
159
159
  }
160
160
  async function runTaskMode(config, providers, configManager, topic) {
161
- const { TaskOrchestrator } = await import("./task-orchestrator-KT6G2WSM.js");
161
+ const { TaskOrchestrator } = await import("./task-orchestrator-544JETWF.js");
162
162
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
163
163
  let interrupted = false;
164
164
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -24,12 +24,12 @@ import {
24
24
  setupProxy,
25
25
  snapshotFile,
26
26
  stripRoutingTags
27
- } from "./chunk-K2TKTYEH.js";
27
+ } from "./chunk-2PAQOR2X.js";
28
28
  import {
29
29
  CostTracker,
30
30
  getPricing,
31
31
  setCostCurrency
32
- } from "./chunk-LONB36SP.js";
32
+ } from "./chunk-46OEMKQX.js";
33
33
  import {
34
34
  ToolExecutor,
35
35
  ToolRegistry,
@@ -47,7 +47,7 @@ import {
47
47
  setMaxOutputCap,
48
48
  spawnAgentContext,
49
49
  undoStack
50
- } from "./chunk-LZJHXSR3.js";
50
+ } from "./chunk-YHMQMP2I.js";
51
51
  import "./chunk-HLWUDRBO.js";
52
52
  import {
53
53
  NO_THINKING,
@@ -60,7 +60,7 @@ import {
60
60
  countPendingMemories,
61
61
  detectStaleLegacyMarkdownEdit,
62
62
  formatMemoryForPrompt
63
- } from "./chunk-S73DO2G5.js";
63
+ } from "./chunk-PGQ5OV3P.js";
64
64
  import "./chunk-RWRZVQCB.js";
65
65
  import "./chunk-B3MPYI4E.js";
66
66
  import "./chunk-M6HLYG33.js";
@@ -81,22 +81,22 @@ import {
81
81
  import {
82
82
  loadContextFiles,
83
83
  writeCrashLog
84
- } from "./chunk-DPWHBIK2.js";
84
+ } from "./chunk-D6BLSFYD.js";
85
85
  import {
86
86
  getActivePluginAssets,
87
87
  getPendingHookTrust,
88
88
  installFlushOnExit,
89
89
  mergePluginHooks,
90
90
  runLifecycleHooks
91
- } from "./chunk-HDHVWGDA.js";
91
+ } from "./chunk-662ZJPJE.js";
92
92
  import "./chunk-RS7SKYTS.js";
93
93
  import {
94
94
  ProviderRegistry,
95
95
  listBuiltInProviderMetadata
96
- } from "./chunk-2Z7SOAPR.js";
96
+ } from "./chunk-N2MHUA4B.js";
97
97
  import {
98
98
  ConfigManager
99
- } from "./chunk-VZBBSBSN.js";
99
+ } from "./chunk-KEOMNFBH.js";
100
100
  import {
101
101
  CONTENT_ONLY_STREAM_REMINDER,
102
102
  TEE_FINAL_USER_NUDGE,
@@ -114,7 +114,7 @@ import {
114
114
  runAgentLoop,
115
115
  stripToolCallReminder,
116
116
  teeStreamErrorSummary
117
- } from "./chunk-6VBW3L57.js";
117
+ } from "./chunk-GVAAGBHX.js";
118
118
  import {
119
119
  AuthError,
120
120
  ProviderError,
@@ -134,7 +134,7 @@ import {
134
134
  isInterrupted,
135
135
  requestInterrupt,
136
136
  resetInterrupt
137
- } from "./chunk-27RIJK3U.js";
137
+ } from "./chunk-Y3SEC5EC.js";
138
138
  import {
139
139
  AGENTIC_BEHAVIOR_GUIDELINE,
140
140
  AUTHOR,
@@ -152,7 +152,7 @@ import {
152
152
  SKILLS_DIR_NAME,
153
153
  VERSION,
154
154
  buildUserIdentityPrompt
155
- } from "./chunk-X4GNEJNN.js";
155
+ } from "./chunk-A7YZLLWN.js";
156
156
  import "./chunk-SXIJLSVF.js";
157
157
 
158
158
  // src/index.ts
@@ -2600,7 +2600,7 @@ Session '${this.resumeSessionId}' not found.
2600
2600
  /**
2601
2601
  * 从 config.modelParams 读取当前模型的推理参数(temperature / maxTokens / timeout / thinking)。
2602
2602
  * 用户可在 config.json 的 modelParams 字段按模型 ID 配置,例如:
2603
- * "modelParams": { "glm-5": { "temperature": 1.0, "maxTokens": 65536, "thinking": true } }
2603
+ * "modelParams": { "glm-5.3": { "temperature": 1.0, "maxTokens": 65536, "thinking": true } }
2604
2604
  */
2605
2605
  /** 运行时 thinking 模式覆盖:null=使用配置值,true/false=运行时覆盖 */
2606
2606
  runtimeThinking = null;
@@ -4107,7 +4107,7 @@ program.command("web").description("Start Web UI server with browser-based chat
4107
4107
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
4108
4108
  process.exit(1);
4109
4109
  }
4110
- const { startWebServer } = await import("./server-NOU4PXEC.js");
4110
+ const { startWebServer } = await import("./server-XQ3IQUZ5.js");
4111
4111
  await startWebServer({ port, host: options.host, externalOrigin: options.externalOrigin });
4112
4112
  });
4113
4113
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | logout-all <name> | migrate <name>)").action(async (action, username) => {
@@ -4274,11 +4274,11 @@ program.command("sessions").description("List recent conversation sessions").opt
4274
4274
  console.log(footer + "\n");
4275
4275
  });
4276
4276
  program.command("usage").description("Show token + cost usage grouped by provider/model (cross-session)").option("--days <n>", "Only the last N days (inclusive of today)").option("--month <ym>", "Only a specific month, format YYYY-MM (e.g. 2026-06)").option("--json", "Output as JSON (for scripting)").action(async (options) => {
4277
- const { runUsageCli } = await import("./usage-QV3RTJ7B.js");
4277
+ const { runUsageCli } = await import("./usage-MQTA7HHZ.js");
4278
4278
  await runUsageCli(options);
4279
4279
  });
4280
4280
  program.command("doctor").description("Health check: API keys, config, MCP, recent crashes, tool usage, disk usage").option("--json", "Output as JSON (for scripting)").option("--reset-stats", "Reset accumulated tool usage statistics").action(async (options) => {
4281
- const { runDoctorCli } = await import("./doctor-cli-J6NQF6HS.js");
4281
+ const { runDoctorCli } = await import("./doctor-cli-L6AK2GJ7.js");
4282
4282
  const argv = process.argv.slice(2);
4283
4283
  await runDoctorCli({
4284
4284
  json: !!options.json || argv.includes("--json"),
@@ -4287,7 +4287,7 @@ program.command("doctor").description("Health check: API keys, config, MCP, rece
4287
4287
  });
4288
4288
  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) => {
4289
4289
  try {
4290
- const batch = await import("./batch-OWVPYMTH.js");
4290
+ const batch = await import("./batch-CQ542WJF.js");
4291
4291
  switch (action) {
4292
4292
  case "submit":
4293
4293
  if (!arg) {
@@ -4330,7 +4330,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
4330
4330
  }
4331
4331
  });
4332
4332
  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) => {
4333
- const { startMcpServer } = await import("./server-FBIKTICF.js");
4333
+ const { startMcpServer } = await import("./server-3C6IK3JE.js");
4334
4334
  await startMcpServer({
4335
4335
  allowDestructive: !!options.allowDestructive,
4336
4336
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -4343,7 +4343,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4343
4343
  console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
4344
4344
  process.exit(1);
4345
4345
  }
4346
- const { runPrCli } = await import("./pr-D3A76PY6.js");
4346
+ const { runPrCli } = await import("./pr-J5TSU5P6.js");
4347
4347
  const result = await runPrCli({
4348
4348
  action,
4349
4349
  target,
@@ -4363,8 +4363,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
4363
4363
  process.exit(result.exitCode);
4364
4364
  });
4365
4365
  program.command("ci").description("Headless PR review (code + security) \u2014 reads git/gh diff, optionally posts to PR. Designed for GitHub Actions.").option("--pr <num>", "PR number or URL; diff fetched via gh pr diff <value>", (v) => /^#?\d+$/.test(v) ? parseInt(v.replace(/^#/, ""), 10) : v).option("--base <ref>", "Base ref for git diff <ref>...HEAD (ignored when --pr set)").option("--post", "Post review as a PR comment (requires gh CLI + GH_TOKEN, needs --pr)").option("--no-update", "Always create a new comment instead of updating the previous aicli review").option("--skip-code", "Skip the code review section").option("--skip-security", "Skip the security review section").option("--detailed", "Use the detailed code-review prompt").option("--max-diff <n>", "Max diff chars sent to the model (default 30000)", (v) => parseInt(v, 10)).option("--provider <id>", "Override provider (default: config.defaultProvider)").option("--model <id>", "Override model").option("--dry-run", "Print result to stdout instead of posting (overrides --post)").option("--json", "Output a structured JSON report").option("--markdown", "Output Markdown report (default)").option("--sarif", "Output SARIF 2.1.0 for code scanning artifacts").option("--fail-on-security-high", "Fail when the security review contains HIGH/CRITICAL findings (default)").option("--no-fail-on-security-high", "Do not fail on security HIGH/CRITICAL findings").option("--fail-on-test-failure", "Fail when the report mentions test failures (default)").option("--no-fail-on-test-failure", "Do not fail on test failure findings").option("--fail-on-lint-failure", "Fail when the report mentions lint/typecheck failures (default)").option("--no-fail-on-lint-failure", "Do not fail on lint/typecheck failure findings").action(async (options) => {
4366
- const { runCi } = await import("./ci-ED4EZGRM.js");
4367
- const { formatCiResult } = await import("./ci-format-2ORFD7KF.js");
4366
+ const { runCi } = await import("./ci-HAPWBC37.js");
4367
+ const { formatCiResult } = await import("./ci-format-NGWP4GTQ.js");
4368
4368
  const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
4369
4369
  if (formats > 1) {
4370
4370
  console.error("Choose only one output format: --json, --markdown, or --sarif.");
@@ -4523,7 +4523,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
4523
4523
  config.get("customProviders"),
4524
4524
  config.getConfigDir()
4525
4525
  );
4526
- const { startHub } = await import("./hub-B6SI42VX.js");
4526
+ const { startHub } = await import("./hub-TCZFG2ZG.js");
4527
4527
  await startHub(
4528
4528
  {
4529
4529
  topic: topic ?? "",
@@ -28,11 +28,11 @@ import {
28
28
  touchMemoryReferences,
29
29
  updateMemoryApproval,
30
30
  updateMemoryEntry
31
- } from "./chunk-S73DO2G5.js";
31
+ } from "./chunk-PGQ5OV3P.js";
32
32
  import "./chunk-3FEZSLGI.js";
33
33
  import "./chunk-HOSJZMQS.js";
34
34
  import "./chunk-BMLQPSHP.js";
35
- import "./chunk-X4GNEJNN.js";
35
+ import "./chunk-A7YZLLWN.js";
36
36
  export {
37
37
  addMemoryEntry,
38
38
  backupMemoryStore,
@@ -27,11 +27,11 @@ import {
27
27
  touchMemoryReferences,
28
28
  updateMemoryApproval,
29
29
  updateMemoryEntry
30
- } from "./chunk-6EM2TRG5.js";
30
+ } from "./chunk-GP24X3KJ.js";
31
31
  import "./chunk-FSC6KEWU.js";
32
32
  import "./chunk-2XMUCC42.js";
33
33
  import "./chunk-CGLYJRFA.js";
34
- import "./chunk-DOWBL4OI.js";
34
+ import "./chunk-DCQDFQDW.js";
35
35
  export {
36
36
  addMemoryEntry,
37
37
  backupMemoryStore,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  countSeverity,
4
4
  runCi
5
- } from "./chunk-VUZCU6BH.js";
6
- import "./chunk-HD7KVZLR.js";
5
+ } from "./chunk-SZBSTSG4.js";
6
+ import "./chunk-OQZIP4LU.js";
7
7
  import {
8
8
  buildReviewPrompt,
9
9
  buildSecurityReviewPrompt,
@@ -14,16 +14,16 @@ import {
14
14
  } from "./chunk-6YZEZFX5.js";
15
15
  import {
16
16
  ProviderRegistry
17
- } from "./chunk-2Z7SOAPR.js";
17
+ } from "./chunk-N2MHUA4B.js";
18
18
  import {
19
19
  ConfigManager
20
- } from "./chunk-VZBBSBSN.js";
21
- import "./chunk-6VBW3L57.js";
20
+ } from "./chunk-KEOMNFBH.js";
21
+ import "./chunk-GVAAGBHX.js";
22
22
  import "./chunk-TU3L3PW7.js";
23
23
  import "./chunk-BMLQPSHP.js";
24
24
  import {
25
25
  VERSION
26
- } from "./chunk-X4GNEJNN.js";
26
+ } from "./chunk-A7YZLLWN.js";
27
27
 
28
28
  // src/cli/pr.ts
29
29
  import { execFileSync } from "child_process";