@qwen-code/qwen-code 0.18.1 → 0.18.3-preview.0

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 (74) hide show
  1. package/README.md +2 -1
  2. package/bundled/qc-helper/docs/common-workflow.md +4 -4
  3. package/bundled/qc-helper/docs/configuration/model-providers.md +1 -1
  4. package/bundled/qc-helper/docs/configuration/settings.md +77 -77
  5. package/bundled/qc-helper/docs/features/channels/feishu.md +16 -0
  6. package/bundled/qc-helper/docs/features/mcp.md +1 -1
  7. package/bundled/qc-helper/docs/features/sub-agents.md +3 -3
  8. package/bundled/qc-helper/docs/qwen-serve.md +24 -12
  9. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +30 -30
  10. package/bundled/review/SKILL.md +10 -4
  11. package/bundled/simplify/SKILL.md +1 -1
  12. package/chunks/{agent-XT7NHZ5H.js → agent-X42UKL4M.js} +5 -5
  13. package/chunks/{agent-headless-LNRE63ZL.js → agent-headless-7FQ7NX6G.js} +5 -5
  14. package/chunks/{anthropicContentGenerator-DCI26OQF.js → anthropicContentGenerator-KLBHYGH6.js} +1 -1
  15. package/chunks/{askUserQuestion-ITYUTWLR.js → askUserQuestion-QPZXR3UO.js} +1 -1
  16. package/chunks/{chunk-BXYRCW2C.js → chunk-3U2ZIZDP.js} +10 -5
  17. package/chunks/{chunk-XZTNBSMW.js → chunk-6X6PTTH3.js} +1 -1
  18. package/chunks/{chunk-7KPZFE5A.js → chunk-C64WAJOC.js} +1 -1
  19. package/chunks/{chunk-WJ3SND6W.js → chunk-JHSQY3J5.js} +2 -2
  20. package/chunks/{chunk-3NRO6NHX.js → chunk-MN5RAXVB.js} +3 -3
  21. package/chunks/{chunk-RON7LFNH.js → chunk-P5CE42XM.js} +6 -6
  22. package/chunks/{chunk-Y7KMDUEP.js → chunk-QP4R5FTG.js} +1 -1
  23. package/chunks/{chunk-QILTEBWS.js → chunk-RTTAC5VW.js} +1 -1
  24. package/chunks/{chunk-IS7UA4W3.js → chunk-U62OHNQR.js} +4 -4
  25. package/chunks/{chunk-6T7Y7USE.js → chunk-VFW7VM7A.js} +1354 -1028
  26. package/chunks/{chunk-HQUWWSSP.js → chunk-VIEIRAK3.js} +1 -1
  27. package/chunks/{chunk-HED55F43.js → chunk-VU6A2OBJ.js} +15 -5
  28. package/chunks/{chunk-DHZREJTG.js → chunk-YJDVHAGL.js} +1 -1
  29. package/chunks/{chunk-A2ZIEEGJ.js → chunk-ZNUMXPNK.js} +592 -43
  30. package/chunks/{computer-use-4YX3JGBV.js → computer-use-WHPP33BI.js} +5 -5
  31. package/chunks/{contextCommand-KS2H7MW5.js → contextCommand-WP7BU7IY.js} +7 -7
  32. package/chunks/{cron-create-CAPUKK7I.js → cron-create-DQKRQMCP.js} +1 -1
  33. package/chunks/{cron-delete-G3KAR26Q.js → cron-delete-DOFPHFTI.js} +1 -1
  34. package/chunks/{cron-list-ZA4ZIUS5.js → cron-list-RCVOO3CB.js} +1 -1
  35. package/chunks/{dist-VEGFONCF.js → dist-2UCAYOX7.js} +2 -2
  36. package/chunks/{dist-X4EXN7W6.js → dist-33LHH26D.js} +1 -1
  37. package/chunks/{dist-YLS6NI7H.js → dist-KF43SZZV.js} +1 -1
  38. package/chunks/{dist-7YWFWOCJ.js → dist-UH7CYT7F.js} +2 -2
  39. package/chunks/{edit-2ARPEO4B.js → edit-V22UFE4F.js} +7 -9
  40. package/chunks/{enter-worktree-IXNXNAW5.js → enter-worktree-HYS5U3QO.js} +5 -5
  41. package/chunks/{enterPlanMode-TAKAGAYP.js → enterPlanMode-UR2KPB4Y.js} +5 -5
  42. package/chunks/{exit-worktree-LHTRV7ML.js → exit-worktree-JNIUZIZ3.js} +5 -5
  43. package/chunks/{exitPlanMode-MK5UAITL.js → exitPlanMode-NJY3Y6XQ.js} +11 -9
  44. package/chunks/{geminiContentGenerator-HFJIGO77.js → geminiContentGenerator-SDUMCYHD.js} +1 -1
  45. package/chunks/{glob-I2USLUSC.js → glob-Z6UYFZCH.js} +5 -5
  46. package/chunks/{grep-WBIF7THR.js → grep-WHWDB2HD.js} +5 -5
  47. package/chunks/{ls-2R5RHLX5.js → ls-TRD77UTS.js} +1 -1
  48. package/chunks/{lsp-XKH6ZIAN.js → lsp-2VFWQPZS.js} +1 -1
  49. package/chunks/{monitor-WU7UFATU.js → monitor-F4V4YEE4.js} +5 -5
  50. package/chunks/{notebook-edit-KUHYPXEM.js → notebook-edit-P45433KC.js} +6 -6
  51. package/chunks/{openaiContentGenerator-5PLHYJQL.js → openaiContentGenerator-DRXB5MSN.js} +5 -5
  52. package/chunks/{qwenContentGenerator-TSKW73KY.js → qwenContentGenerator-3XZMXLHX.js} +7 -7
  53. package/chunks/{read-file-VIPF2PS6.js → read-file-WQPROSSJ.js} +3 -3
  54. package/chunks/{ripGrep-XLIZTYE7.js → ripGrep-EAE7GW6T.js} +5 -5
  55. package/chunks/{scheduler-O66SLJGU.js → scheduler-WCMRRLYM.js} +5 -5
  56. package/chunks/{send-message-CTME7DXD.js → send-message-QZOC5GA2.js} +1 -1
  57. package/chunks/{serve-BWOLYT62.js → serve-BVDNMP5D.js} +709 -26
  58. package/chunks/{shell-XE7UYKOO.js → shell-W4LWEOQL.js} +5 -5
  59. package/chunks/{skill-RZWM6XMC.js → skill-VTJI4OPM.js} +3 -3
  60. package/chunks/{src-L5P7K4MH.js → src-E42UOH5I.js} +11 -5
  61. package/chunks/{syntheticOutput-ZJGSU7OQ.js → syntheticOutput-WJSUK4SZ.js} +2 -2
  62. package/chunks/{task-create-EE6JEM7G.js → task-create-GGSC27HO.js} +2 -2
  63. package/chunks/{task-list-EESYAC65.js → task-list-EDHHHSK4.js} +1 -1
  64. package/chunks/{task-stop-XZVCFFYY.js → task-stop-WR5PDVZY.js} +1 -1
  65. package/chunks/{task-update-EIO4HNE3.js → task-update-UR7NUHBV.js} +2 -2
  66. package/chunks/{team-create-R2H7Y3SG.js → team-create-OAGMFFDJ.js} +5 -5
  67. package/chunks/{team-delete-A7LXPGV7.js → team-delete-FC33URJK.js} +1 -1
  68. package/chunks/{todoWrite-VRKSGAWM.js → todoWrite-GO2ME7ZV.js} +1 -1
  69. package/chunks/{tool-search-USSQMTMS.js → tool-search-XZPD5EPI.js} +3 -3
  70. package/chunks/{web-fetch-GHAZUA54.js → web-fetch-NLLATYIL.js} +2 -2
  71. package/chunks/{workflow-5LNNLNUR.js → workflow-AIC3XOX5.js} +249 -24
  72. package/chunks/{write-file-2I7HP24C.js → write-file-6GIRRW43.js} +6 -6
  73. package/cli.js +1320 -536
  74. package/package.json +2 -2
package/cli.js CHANGED
@@ -7,13 +7,13 @@ import {
7
7
  clearAccount,
8
8
  loadAccount,
9
9
  saveAccount
10
- } from "./chunks/chunk-Y7KMDUEP.js";
10
+ } from "./chunks/chunk-QP4R5FTG.js";
11
11
  import {
12
12
  AcpBridge,
13
13
  PairingStore,
14
14
  SessionRouter,
15
15
  resolvePath
16
- } from "./chunks/chunk-HED55F43.js";
16
+ } from "./chunks/chunk-VU6A2OBJ.js";
17
17
  import {
18
18
  ACP_PREFLIGHT_KINDS,
19
19
  CORRUPTED_SUFFIX,
@@ -23,6 +23,7 @@ import {
23
23
  ENV_CORRUPTED_PATH,
24
24
  ENV_WAS_RECOVERED,
25
25
  IDLE_HOOK_EVENTS,
26
+ MID_TURN_QUEUE_DRAIN_METHOD,
26
27
  NOT_CURRENTLY_GENERATING_CANCEL_MESSAGE,
27
28
  OUTPUT_LANGUAGE_AUTO,
28
29
  SERVE_CONTROL_EXT_METHODS,
@@ -91,7 +92,7 @@ import {
91
92
  updateOutputLanguageFile,
92
93
  validateCustomTheme,
93
94
  writeOutputLanguageAndRegisterPath
94
- } from "./chunks/chunk-BXYRCW2C.js";
95
+ } from "./chunks/chunk-3U2ZIZDP.js";
95
96
  import {
96
97
  AgentSideConnection,
97
98
  PROTOCOL_VERSION,
@@ -104,7 +105,7 @@ import {
104
105
  formatContextUsageText,
105
106
  isTerminalGoalStatusKind,
106
107
  require_react
107
- } from "./chunks/chunk-IS7UA4W3.js";
108
+ } from "./chunks/chunk-U62OHNQR.js";
108
109
  import {
109
110
  SUPPORTED_LANGUAGES,
110
111
  clearScreen,
@@ -117,7 +118,7 @@ import {
117
118
  ta,
118
119
  writeStderrLine,
119
120
  writeStdoutLine
120
- } from "./chunks/chunk-XZTNBSMW.js";
121
+ } from "./chunks/chunk-6X6PTTH3.js";
121
122
  import {
122
123
  noteInteraction
123
124
  } from "./chunks/chunk-MRO43B25.js";
@@ -137,6 +138,7 @@ import {
137
138
  DISPLAY_MODE,
138
139
  EXTENSIONS_CONFIG_FILENAME,
139
140
  ExtensionManager,
141
+ FORK_SUBAGENT_TYPE,
140
142
  FileDiscoveryService,
141
143
  FileSearchFactory,
142
144
  GitWorktreeService,
@@ -340,13 +342,13 @@ import {
340
342
  writeRuntimeStatus,
341
343
  writeWorktreeSession,
342
344
  writeWorktreeSessionMarker
343
- } from "./chunks/chunk-6T7Y7USE.js";
345
+ } from "./chunks/chunk-VFW7VM7A.js";
344
346
  import {
345
347
  external_exports
346
348
  } from "./chunks/chunk-K5PGHDBN.js";
347
349
  import {
348
350
  runSideQuery
349
- } from "./chunks/chunk-HQUWWSSP.js";
351
+ } from "./chunks/chunk-VIEIRAK3.js";
350
352
  import "./chunks/chunk-O4PICXES.js";
351
353
  import "./chunks/chunk-TW522KN6.js";
352
354
  import "./chunks/chunk-BJ5HQ23U.js";
@@ -416,7 +418,7 @@ import {
416
418
  stripRuntimeSnapshotPrefix,
417
419
  uiTelemetryService,
418
420
  withInteractionSpan
419
- } from "./chunks/chunk-RON7LFNH.js";
421
+ } from "./chunks/chunk-P5CE42XM.js";
420
422
  import "./chunks/chunk-3PJXIDKI.js";
421
423
  import "./chunks/chunk-UWCTAVOD.js";
422
424
  import {
@@ -430,13 +432,13 @@ import {
430
432
  isAnyAutoMemPath
431
433
  } from "./chunks/chunk-IQHSD7K5.js";
432
434
  import "./chunks/chunk-LYRSMKLS.js";
433
- import "./chunks/chunk-QILTEBWS.js";
435
+ import "./chunks/chunk-RTTAC5VW.js";
434
436
  import {
435
437
  SchemaValidator,
436
438
  ToolConfirmationOutcome,
437
439
  ToolDisplayNames,
438
440
  ToolNames
439
- } from "./chunks/chunk-A2ZIEEGJ.js";
441
+ } from "./chunks/chunk-ZNUMXPNK.js";
440
442
  import {
441
443
  clearCachedCredentialFile,
442
444
  openBrowserSecurely,
@@ -11232,7 +11234,7 @@ var require_supports_color = __commonJS({
11232
11234
  "node_modules/chalk/node_modules/supports-color/index.js"(exports, module) {
11233
11235
  "use strict";
11234
11236
  init_esbuild_shims();
11235
- var os33 = __require("os");
11237
+ var os32 = __require("os");
11236
11238
  var tty4 = __require("tty");
11237
11239
  var hasFlag3 = require_has_flag();
11238
11240
  var { env: env5 } = process;
@@ -11281,7 +11283,7 @@ var require_supports_color = __commonJS({
11281
11283
  return min;
11282
11284
  }
11283
11285
  if (process.platform === "win32") {
11284
- const osRelease = os33.release().split(".");
11286
+ const osRelease = os32.release().split(".");
11285
11287
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
11286
11288
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
11287
11289
  }
@@ -32580,7 +32582,7 @@ var require_supports_color2 = __commonJS({
32580
32582
  "node_modules/ink-link/node_modules/supports-color/index.js"(exports, module) {
32581
32583
  "use strict";
32582
32584
  init_esbuild_shims();
32583
- var os33 = __require("os");
32585
+ var os32 = __require("os");
32584
32586
  var tty4 = __require("tty");
32585
32587
  var hasFlag3 = require_has_flag();
32586
32588
  var { env: env5 } = process;
@@ -32629,7 +32631,7 @@ var require_supports_color2 = __commonJS({
32629
32631
  return min;
32630
32632
  }
32631
32633
  if (process.platform === "win32") {
32632
- const osRelease = os33.release().split(".");
32634
+ const osRelease = os32.release().split(".");
32633
32635
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
32634
32636
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
32635
32637
  }
@@ -36808,9 +36810,9 @@ var require_defaults = __commonJS({
36808
36810
  "node_modules/@pnpm/npm-conf/lib/defaults.js"(exports) {
36809
36811
  "use strict";
36810
36812
  init_esbuild_shims();
36811
- var os33 = __require("os");
36813
+ var os32 = __require("os");
36812
36814
  var path60 = __require("path");
36813
- var temp = os33.tmpdir();
36815
+ var temp = os32.tmpdir();
36814
36816
  var uidOrPid = process.getuid ? process.getuid() : process.pid;
36815
36817
  var hasUnicode = /* @__PURE__ */ __name(() => true, "hasUnicode");
36816
36818
  var isWindows4 = process.platform === "win32";
@@ -36821,7 +36823,7 @@ var require_defaults = __commonJS({
36821
36823
  var umask = {
36822
36824
  fromString: /* @__PURE__ */ __name(() => process.umask(), "fromString")
36823
36825
  };
36824
- var home = os33.homedir();
36826
+ var home = os32.homedir();
36825
36827
  if (home) {
36826
36828
  process.env.HOME = home;
36827
36829
  } else {
@@ -49241,7 +49243,7 @@ var measure_element_default = measureElement;
49241
49243
  // packages/cli/src/gemini.tsx
49242
49244
  var import_react233 = __toESM(require_react(), 1);
49243
49245
  import dns from "node:dns";
49244
- import os32 from "node:os";
49246
+ import os31 from "node:os";
49245
49247
  import path59, { basename as basename13 } from "node:path";
49246
49248
  import v83 from "node:v8";
49247
49249
 
@@ -56776,10 +56778,10 @@ function ensureBuiltins() {
56776
56778
  if (!builtinsPromise) {
56777
56779
  builtinsPromise = (async () => {
56778
56780
  const [telegram, weixin, dingtalk, feishu] = await Promise.all([
56779
- import("./chunks/dist-YLS6NI7H.js"),
56780
- import("./chunks/dist-VEGFONCF.js"),
56781
- import("./chunks/dist-7YWFWOCJ.js"),
56782
- import("./chunks/dist-X4EXN7W6.js")
56781
+ import("./chunks/dist-KF43SZZV.js"),
56782
+ import("./chunks/dist-2UCAYOX7.js"),
56783
+ import("./chunks/dist-UH7CYT7F.js"),
56784
+ import("./chunks/dist-33LHH26D.js")
56783
56785
  ]);
56784
56786
  for (const mod of [telegram, weixin, dingtalk, feishu]) {
56785
56787
  registry.set(mod.plugin.channelType, mod.plugin);
@@ -59187,7 +59189,7 @@ var serveCommand = {
59187
59189
  process.exit(1);
59188
59190
  }
59189
59191
  }
59190
- const { runQwenServe } = await import("./chunks/serve-BWOLYT62.js");
59192
+ const { runQwenServe } = await import("./chunks/serve-BVDNMP5D.js");
59191
59193
  try {
59192
59194
  await runQwenServe({
59193
59195
  port: argv.port,
@@ -59226,6 +59228,432 @@ var serveCommand = {
59226
59228
  }, "handler")
59227
59229
  };
59228
59230
 
59231
+ // packages/cli/src/commands/sessions.ts
59232
+ init_esbuild_shims();
59233
+
59234
+ // packages/cli/src/commands/sessions/list.ts
59235
+ init_esbuild_shims();
59236
+
59237
+ // packages/cli/node_modules/string-width/index.js
59238
+ init_esbuild_shims();
59239
+ var import_emoji_regex = __toESM(require_emoji_regex(), 1);
59240
+ var segmenter4 = new Intl.Segmenter();
59241
+ var defaultIgnorableCodePointRegex = new RegExp("^\\p{Default_Ignorable_Code_Point}$", "u");
59242
+ function stringWidth2(string, options = {}) {
59243
+ if (typeof string !== "string" || string.length === 0) {
59244
+ return 0;
59245
+ }
59246
+ const {
59247
+ ambiguousIsNarrow = true,
59248
+ countAnsiEscapeCodes = false
59249
+ } = options;
59250
+ if (!countAnsiEscapeCodes) {
59251
+ string = stripAnsi(string);
59252
+ }
59253
+ if (string.length === 0) {
59254
+ return 0;
59255
+ }
59256
+ let width = 0;
59257
+ const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
59258
+ for (const { segment: character } of segmenter4.segment(string)) {
59259
+ const codePoint = character.codePointAt(0);
59260
+ if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
59261
+ continue;
59262
+ }
59263
+ if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) {
59264
+ continue;
59265
+ }
59266
+ if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) {
59267
+ continue;
59268
+ }
59269
+ if (codePoint >= 55296 && codePoint <= 57343) {
59270
+ continue;
59271
+ }
59272
+ if (codePoint >= 65024 && codePoint <= 65039) {
59273
+ continue;
59274
+ }
59275
+ if (defaultIgnorableCodePointRegex.test(character)) {
59276
+ continue;
59277
+ }
59278
+ if ((0, import_emoji_regex.default)().test(character)) {
59279
+ width += 2;
59280
+ continue;
59281
+ }
59282
+ width += eastAsianWidth(codePoint, eastAsianWidthOptions);
59283
+ }
59284
+ return width;
59285
+ }
59286
+ __name(stringWidth2, "stringWidth");
59287
+
59288
+ // packages/cli/src/ui/utils/textUtils.ts
59289
+ init_esbuild_shims();
59290
+ init_ansi_regex();
59291
+ import { stripVTControlCharacters } from "node:util";
59292
+ var getAsciiArtWidth = /* @__PURE__ */ __name((asciiArt) => {
59293
+ if (!asciiArt) {
59294
+ return 0;
59295
+ }
59296
+ const lines = asciiArt.split("\n");
59297
+ return Math.max(...lines.map((line) => getCachedStringWidth(line)));
59298
+ }, "getAsciiArtWidth");
59299
+ var codePointsCache = /* @__PURE__ */ new Map();
59300
+ var MAX_STRING_LENGTH_TO_CACHE = 1e3;
59301
+ function toCodePoints(str) {
59302
+ let isAscii = true;
59303
+ for (let i = 0; i < str.length; i++) {
59304
+ if (str.charCodeAt(i) > 127) {
59305
+ isAscii = false;
59306
+ break;
59307
+ }
59308
+ }
59309
+ if (isAscii) {
59310
+ return str.split("");
59311
+ }
59312
+ if (str.length <= MAX_STRING_LENGTH_TO_CACHE) {
59313
+ const cached = codePointsCache.get(str);
59314
+ if (cached) {
59315
+ return cached;
59316
+ }
59317
+ }
59318
+ const result = Array.from(str);
59319
+ if (str.length <= MAX_STRING_LENGTH_TO_CACHE) {
59320
+ codePointsCache.set(str, result);
59321
+ }
59322
+ return result;
59323
+ }
59324
+ __name(toCodePoints, "toCodePoints");
59325
+ function cpLen(str) {
59326
+ return toCodePoints(str).length;
59327
+ }
59328
+ __name(cpLen, "cpLen");
59329
+ function cpSlice(str, start, end) {
59330
+ const arr = toCodePoints(str).slice(start, end);
59331
+ return arr.join("");
59332
+ }
59333
+ __name(cpSlice, "cpSlice");
59334
+ function stripUnsafeCharacters(str) {
59335
+ const strippedAnsi = stripAnsi(str);
59336
+ const strippedVT = stripVTControlCharacters(strippedAnsi);
59337
+ return toCodePoints(strippedVT).filter((char) => {
59338
+ const code = char.codePointAt(0);
59339
+ if (code === void 0) return false;
59340
+ if (code === 9 || code === 10 || code === 13) return true;
59341
+ if (code >= 0 && code <= 31) return false;
59342
+ if (code >= 128 && code <= 159) return false;
59343
+ return true;
59344
+ }).join("");
59345
+ }
59346
+ __name(stripUnsafeCharacters, "stripUnsafeCharacters");
59347
+ var stringWidthCache = /* @__PURE__ */ new Map();
59348
+ var getCachedStringWidth = /* @__PURE__ */ __name((str) => {
59349
+ if (/^[\x20-\x7E]*$/.test(str)) {
59350
+ return str.length;
59351
+ }
59352
+ if (stringWidthCache.has(str)) {
59353
+ return stringWidthCache.get(str);
59354
+ }
59355
+ const width = stringWidth2(str);
59356
+ stringWidthCache.set(str, width);
59357
+ return width;
59358
+ }, "getCachedStringWidth");
59359
+ var regex = ansiRegex();
59360
+ function escapeAnsiCtrlCodes(obj) {
59361
+ if (typeof obj === "string") {
59362
+ if (obj.search(regex) === -1) {
59363
+ return obj;
59364
+ }
59365
+ regex.lastIndex = 0;
59366
+ return obj.replace(
59367
+ regex,
59368
+ (match) => JSON.stringify(match).slice(1, -1)
59369
+ );
59370
+ }
59371
+ if (obj === null || typeof obj !== "object") {
59372
+ return obj;
59373
+ }
59374
+ if (Array.isArray(obj)) {
59375
+ let newArr = null;
59376
+ for (let i = 0; i < obj.length; i++) {
59377
+ const value = obj[i];
59378
+ const escapedValue = escapeAnsiCtrlCodes(value);
59379
+ if (escapedValue !== value) {
59380
+ if (newArr === null) {
59381
+ newArr = [...obj];
59382
+ }
59383
+ newArr[i] = escapedValue;
59384
+ }
59385
+ }
59386
+ return newArr !== null ? newArr : obj;
59387
+ }
59388
+ let newObj = null;
59389
+ const keys = Object.keys(obj);
59390
+ for (const key of keys) {
59391
+ const value = obj[key];
59392
+ const escapedValue = escapeAnsiCtrlCodes(value);
59393
+ if (escapedValue !== value) {
59394
+ if (newObj === null) {
59395
+ newObj = { ...obj };
59396
+ }
59397
+ newObj[key] = escapedValue;
59398
+ }
59399
+ }
59400
+ return newObj !== null ? newObj : obj;
59401
+ }
59402
+ __name(escapeAnsiCtrlCodes, "escapeAnsiCtrlCodes");
59403
+ var SENSITIVE_PATTERNS = [
59404
+ // API keys with common prefixes
59405
+ {
59406
+ pattern: /(sk-[a-zA-Z0-9]{20,})/g,
59407
+ replacement: "sk-***REDACTED***"
59408
+ },
59409
+ {
59410
+ pattern: /(api[_-]?key[_-]?[=:]\s*)[a-zA-Z0-9_-]{20,}/gi,
59411
+ replacement: "$1***REDACTED***"
59412
+ },
59413
+ // Bearer tokens
59414
+ {
59415
+ pattern: /(Bearer\s+)[a-zA-Z0-9._-]+/gi,
59416
+ replacement: "$1***REDACTED***"
59417
+ },
59418
+ // Generic tokens
59419
+ {
59420
+ pattern: /(token[_-]?[=:]\s*)[a-zA-Z0-9._-]{10,}/gi,
59421
+ replacement: "$1***REDACTED***"
59422
+ },
59423
+ // Passwords in connection strings or assignments
59424
+ {
59425
+ pattern: /(password[_-]?[=:]\s*)[^\s]+/gi,
59426
+ replacement: "$1***REDACTED***"
59427
+ },
59428
+ {
59429
+ pattern: /(pwd[_-]?[=:]\s*)[^\s]+/gi,
59430
+ replacement: "$1***REDACTED***"
59431
+ },
59432
+ // AWS keys
59433
+ {
59434
+ pattern: /(AKIA[A-Z0-9]{16})/g,
59435
+ replacement: "***REDACTED***"
59436
+ },
59437
+ // Generic secret patterns
59438
+ {
59439
+ pattern: /(secret[_-]?[=:]\s*)[a-zA-Z0-9._-]{10,}/gi,
59440
+ replacement: "$1***REDACTED***"
59441
+ }
59442
+ ];
59443
+ function sanitizeSensitiveText(text, maxLength = 200) {
59444
+ let result = text;
59445
+ for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
59446
+ result = result.replace(pattern, replacement);
59447
+ }
59448
+ if (result.length > maxLength) {
59449
+ if (maxLength <= 3) {
59450
+ return result.slice(0, maxLength);
59451
+ }
59452
+ return result.slice(0, maxLength - 3) + "...";
59453
+ }
59454
+ return result;
59455
+ }
59456
+ __name(sanitizeSensitiveText, "sanitizeSensitiveText");
59457
+ var FILENAME_CONTROL_CHARS_REGEX = /[\x00-\x1f\x7f-\x9f]/g;
59458
+ function escapeFilenameControlChar(ch) {
59459
+ switch (ch) {
59460
+ case "\b":
59461
+ return "\\b";
59462
+ case " ":
59463
+ return "\\t";
59464
+ case "\n":
59465
+ return "\\n";
59466
+ case "\f":
59467
+ return "\\f";
59468
+ case "\r":
59469
+ return "\\r";
59470
+ default: {
59471
+ const code = ch.charCodeAt(0);
59472
+ return `\\u${code.toString(16).padStart(4, "0")}`;
59473
+ }
59474
+ }
59475
+ }
59476
+ __name(escapeFilenameControlChar, "escapeFilenameControlChar");
59477
+ function sanitizeFilenameForDisplay(name) {
59478
+ return escapeAnsiCtrlCodes(name).replace(
59479
+ FILENAME_CONTROL_CHARS_REGEX,
59480
+ escapeFilenameControlChar
59481
+ );
59482
+ }
59483
+ __name(sanitizeFilenameForDisplay, "sanitizeFilenameForDisplay");
59484
+
59485
+ // packages/cli/src/commands/sessions/common.ts
59486
+ init_esbuild_shims();
59487
+ function initSessionService() {
59488
+ const settings = loadSettings();
59489
+ Storage.setRuntimeBaseDir(
59490
+ settings.merged.advanced?.runtimeOutputDir,
59491
+ process.cwd()
59492
+ );
59493
+ return new SessionService(process.cwd());
59494
+ }
59495
+ __name(initSessionService, "initSessionService");
59496
+
59497
+ // packages/cli/src/commands/sessions/list.ts
59498
+ var SESSION_COL = 38;
59499
+ var TIME_COL = 16;
59500
+ var TITLE_COL = 24;
59501
+ var BRANCH_COL = 12;
59502
+ function formatTime(iso) {
59503
+ const d = new Date(iso);
59504
+ if (isNaN(d.getTime())) return iso;
59505
+ const pad2 = /* @__PURE__ */ __name((n) => String(n).padStart(2, "0"), "pad");
59506
+ return `${d.getUTCFullYear()}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())} ${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())}`;
59507
+ }
59508
+ __name(formatTime, "formatTime");
59509
+ function sanitize(value) {
59510
+ const stripped = value.replace(/[\r\n\t]/g, "");
59511
+ const escaped = escapeAnsiCtrlCodes(stripped);
59512
+ return escaped.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/g, "");
59513
+ }
59514
+ __name(sanitize, "sanitize");
59515
+ function padDisplay(str, width) {
59516
+ const currentWidth = stringWidth2(str);
59517
+ if (currentWidth >= width) return str;
59518
+ return str + " ".repeat(width - currentWidth);
59519
+ }
59520
+ __name(padDisplay, "padDisplay");
59521
+ function truncate(str, maxLen) {
59522
+ const width = stringWidth2(str);
59523
+ if (width <= maxLen) return str;
59524
+ const suffix = maxLen > 3 ? "..." : "";
59525
+ const target = maxLen - stringWidth2(suffix);
59526
+ let result = "";
59527
+ let w = 0;
59528
+ for (const char of str) {
59529
+ w += stringWidth2(char);
59530
+ if (w > target) break;
59531
+ result += char;
59532
+ }
59533
+ return result + suffix;
59534
+ }
59535
+ __name(truncate, "truncate");
59536
+ function outputHuman(items) {
59537
+ if (items.length === 0) {
59538
+ writeStdoutLine("No sessions found.");
59539
+ return;
59540
+ }
59541
+ const termWidth = process.stdout.columns ?? 80;
59542
+ const PROMPT_COL = Math.max(
59543
+ 20,
59544
+ termWidth - SESSION_COL - TIME_COL - TITLE_COL - BRANCH_COL - 4
59545
+ );
59546
+ const header = padDisplay("SESSION ID", SESSION_COL) + " " + padDisplay("STARTED", TIME_COL) + " " + padDisplay("TITLE", TITLE_COL) + " " + padDisplay("BRANCH", BRANCH_COL) + " PROMPT";
59547
+ writeStdoutLine(header);
59548
+ for (const item of items) {
59549
+ const sessionId = truncate(
59550
+ sanitize(String(item.sessionId ?? "")),
59551
+ SESSION_COL
59552
+ );
59553
+ const time = truncate(sanitize(formatTime(item.startTime)), TIME_COL);
59554
+ const sanitizedPrompt = sanitize(item.prompt ?? "");
59555
+ const title = truncate(
59556
+ item.customTitle != null ? sanitize(item.customTitle) : sanitizedPrompt,
59557
+ TITLE_COL
59558
+ );
59559
+ const branch = truncate(
59560
+ item.gitBranch != null ? sanitize(item.gitBranch) : "-",
59561
+ BRANCH_COL
59562
+ );
59563
+ const prompt = truncate(sanitizedPrompt, PROMPT_COL);
59564
+ writeStdoutLine(
59565
+ `${padDisplay(sessionId, SESSION_COL)} ${padDisplay(time, TIME_COL)} ${padDisplay(title, TITLE_COL)} ${padDisplay(branch, BRANCH_COL)} ${prompt}`
59566
+ );
59567
+ }
59568
+ }
59569
+ __name(outputHuman, "outputHuman");
59570
+ function toJsonItem(item) {
59571
+ return {
59572
+ sessionId: item.sessionId,
59573
+ startTime: item.startTime,
59574
+ mtime: item.mtime,
59575
+ prompt: item.prompt,
59576
+ gitBranch: item.gitBranch ?? null,
59577
+ customTitle: item.customTitle ?? null,
59578
+ titleSource: item.titleSource ?? null,
59579
+ filePath: item.filePath,
59580
+ cwd: item.cwd
59581
+ };
59582
+ }
59583
+ __name(toJsonItem, "toJsonItem");
59584
+ function formatError2(err) {
59585
+ return err instanceof Error ? err.message : String(err);
59586
+ }
59587
+ __name(formatError2, "formatError");
59588
+ async function handleList2(argv) {
59589
+ let svc;
59590
+ try {
59591
+ svc = initSessionService();
59592
+ } catch (err) {
59593
+ writeStderrLine(
59594
+ `Error: failed to initialize session service: ${formatError2(err)}`
59595
+ );
59596
+ process.exit(1);
59597
+ return;
59598
+ }
59599
+ let result;
59600
+ try {
59601
+ result = await svc.listSessions({
59602
+ size: argv.limit ?? 20
59603
+ });
59604
+ } catch (err) {
59605
+ writeStderrLine(`Error: failed to list sessions: ${formatError2(err)}`);
59606
+ process.exit(1);
59607
+ return;
59608
+ }
59609
+ if (argv.json) {
59610
+ for (const item of result.items) {
59611
+ writeStdoutLine(JSON.stringify(toJsonItem(item)));
59612
+ }
59613
+ if (result.items.length > 0 && result.hasMore) {
59614
+ writeStderrLine(
59615
+ `Note: ${result.items.length} sessions shown, more available. Use --limit to show more.`
59616
+ );
59617
+ }
59618
+ } else {
59619
+ outputHuman(result.items);
59620
+ if (result.items.length > 0 && result.hasMore) {
59621
+ writeStdoutLine(
59622
+ `Showing ${result.items.length} sessions. Use --limit to show more.`
59623
+ );
59624
+ }
59625
+ }
59626
+ }
59627
+ __name(handleList2, "handleList");
59628
+ var listCommand4 = {
59629
+ command: "list",
59630
+ describe: "List sessions",
59631
+ builder: /* @__PURE__ */ __name((yargs) => yargs.option("json", {
59632
+ type: "boolean",
59633
+ describe: "Output as JSON Lines",
59634
+ default: false
59635
+ }).option("limit", {
59636
+ type: "number",
59637
+ describe: "Maximum number of sessions to show",
59638
+ default: 20,
59639
+ coerce: /* @__PURE__ */ __name((v) => Number.isInteger(v) && v > 0 ? v : 20, "coerce")
59640
+ }), "builder"),
59641
+ handler: /* @__PURE__ */ __name(async (argv) => {
59642
+ await handleList2(argv);
59643
+ }, "handler")
59644
+ };
59645
+
59646
+ // packages/cli/src/commands/sessions.ts
59647
+ var sessionsCommand = {
59648
+ command: "sessions",
59649
+ describe: "Manage Qwen Code sessions",
59650
+ builder: /* @__PURE__ */ __name((yargs) => yargs.command(listCommand4).demandCommand(1, "You need at least one command before continuing.").version(false), "builder"),
59651
+ // demandCommand(1) ensures a subcommand is always required;
59652
+ // yargs automatically shows help when none is provided.
59653
+ handler: /* @__PURE__ */ __name(() => {
59654
+ }, "handler")
59655
+ };
59656
+
59229
59657
  // packages/cli/src/utils/runBudget.ts
59230
59658
  init_esbuild_shims();
59231
59659
  var SECOND = 1e3;
@@ -59931,11 +60359,11 @@ async function parseArguments() {
59931
60359
  }
59932
60360
  return true;
59933
60361
  })
59934
- ).command(mcpCommand).command(extensionsCommand).command(authCommand).command(hooksCommand).command(channelCommand).command(reviewCommand).command(serveCommand);
60362
+ ).command(mcpCommand).command(extensionsCommand).command(authCommand).command(hooksCommand).command(channelCommand).command(reviewCommand).command(serveCommand).command(sessionsCommand);
59935
60363
  yargsInstance.version(await getCliVersion()).alias("v", "version").help().alias("h", "help").strict().demandCommand(0, 0);
59936
60364
  yargsInstance.wrap(yargsInstance.terminalWidth());
59937
60365
  const result = await yargsInstance.parse();
59938
- if (result._.length > 0 && (result._[0] === "mcp" || result._[0] === "extensions" || result._[0] === "auth" || result._[0] === "hooks" || result._[0] === "channel" || result._[0] === "review")) {
60366
+ if (result._.length > 0 && (result._[0] === "mcp" || result._[0] === "extensions" || result._[0] === "auth" || result._[0] === "hooks" || result._[0] === "channel" || result._[0] === "review" || result._[0] === "sessions")) {
59939
60367
  process.exit(0);
59940
60368
  }
59941
60369
  const queryArg = result.query;
@@ -64477,258 +64905,6 @@ var aboutCommand = {
64477
64905
 
64478
64906
  // packages/cli/src/ui/commands/tasksCommand.ts
64479
64907
  init_esbuild_shims();
64480
-
64481
- // packages/cli/src/ui/utils/textUtils.ts
64482
- init_esbuild_shims();
64483
- init_ansi_regex();
64484
- import { stripVTControlCharacters } from "node:util";
64485
-
64486
- // packages/cli/node_modules/string-width/index.js
64487
- init_esbuild_shims();
64488
- var import_emoji_regex = __toESM(require_emoji_regex(), 1);
64489
- var segmenter4 = new Intl.Segmenter();
64490
- var defaultIgnorableCodePointRegex = new RegExp("^\\p{Default_Ignorable_Code_Point}$", "u");
64491
- function stringWidth2(string, options = {}) {
64492
- if (typeof string !== "string" || string.length === 0) {
64493
- return 0;
64494
- }
64495
- const {
64496
- ambiguousIsNarrow = true,
64497
- countAnsiEscapeCodes = false
64498
- } = options;
64499
- if (!countAnsiEscapeCodes) {
64500
- string = stripAnsi(string);
64501
- }
64502
- if (string.length === 0) {
64503
- return 0;
64504
- }
64505
- let width = 0;
64506
- const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
64507
- for (const { segment: character } of segmenter4.segment(string)) {
64508
- const codePoint = character.codePointAt(0);
64509
- if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
64510
- continue;
64511
- }
64512
- if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) {
64513
- continue;
64514
- }
64515
- if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) {
64516
- continue;
64517
- }
64518
- if (codePoint >= 55296 && codePoint <= 57343) {
64519
- continue;
64520
- }
64521
- if (codePoint >= 65024 && codePoint <= 65039) {
64522
- continue;
64523
- }
64524
- if (defaultIgnorableCodePointRegex.test(character)) {
64525
- continue;
64526
- }
64527
- if ((0, import_emoji_regex.default)().test(character)) {
64528
- width += 2;
64529
- continue;
64530
- }
64531
- width += eastAsianWidth(codePoint, eastAsianWidthOptions);
64532
- }
64533
- return width;
64534
- }
64535
- __name(stringWidth2, "stringWidth");
64536
-
64537
- // packages/cli/src/ui/utils/textUtils.ts
64538
- var getAsciiArtWidth = /* @__PURE__ */ __name((asciiArt) => {
64539
- if (!asciiArt) {
64540
- return 0;
64541
- }
64542
- const lines = asciiArt.split("\n");
64543
- return Math.max(...lines.map((line) => getCachedStringWidth(line)));
64544
- }, "getAsciiArtWidth");
64545
- var codePointsCache = /* @__PURE__ */ new Map();
64546
- var MAX_STRING_LENGTH_TO_CACHE = 1e3;
64547
- function toCodePoints(str) {
64548
- let isAscii = true;
64549
- for (let i = 0; i < str.length; i++) {
64550
- if (str.charCodeAt(i) > 127) {
64551
- isAscii = false;
64552
- break;
64553
- }
64554
- }
64555
- if (isAscii) {
64556
- return str.split("");
64557
- }
64558
- if (str.length <= MAX_STRING_LENGTH_TO_CACHE) {
64559
- const cached = codePointsCache.get(str);
64560
- if (cached) {
64561
- return cached;
64562
- }
64563
- }
64564
- const result = Array.from(str);
64565
- if (str.length <= MAX_STRING_LENGTH_TO_CACHE) {
64566
- codePointsCache.set(str, result);
64567
- }
64568
- return result;
64569
- }
64570
- __name(toCodePoints, "toCodePoints");
64571
- function cpLen(str) {
64572
- return toCodePoints(str).length;
64573
- }
64574
- __name(cpLen, "cpLen");
64575
- function cpSlice(str, start, end) {
64576
- const arr = toCodePoints(str).slice(start, end);
64577
- return arr.join("");
64578
- }
64579
- __name(cpSlice, "cpSlice");
64580
- function stripUnsafeCharacters(str) {
64581
- const strippedAnsi = stripAnsi(str);
64582
- const strippedVT = stripVTControlCharacters(strippedAnsi);
64583
- return toCodePoints(strippedVT).filter((char) => {
64584
- const code = char.codePointAt(0);
64585
- if (code === void 0) return false;
64586
- if (code === 9 || code === 10 || code === 13) return true;
64587
- if (code >= 0 && code <= 31) return false;
64588
- if (code >= 128 && code <= 159) return false;
64589
- return true;
64590
- }).join("");
64591
- }
64592
- __name(stripUnsafeCharacters, "stripUnsafeCharacters");
64593
- var stringWidthCache = /* @__PURE__ */ new Map();
64594
- var getCachedStringWidth = /* @__PURE__ */ __name((str) => {
64595
- if (/^[\x20-\x7E]*$/.test(str)) {
64596
- return str.length;
64597
- }
64598
- if (stringWidthCache.has(str)) {
64599
- return stringWidthCache.get(str);
64600
- }
64601
- const width = stringWidth2(str);
64602
- stringWidthCache.set(str, width);
64603
- return width;
64604
- }, "getCachedStringWidth");
64605
- var regex = ansiRegex();
64606
- function escapeAnsiCtrlCodes(obj) {
64607
- if (typeof obj === "string") {
64608
- if (obj.search(regex) === -1) {
64609
- return obj;
64610
- }
64611
- regex.lastIndex = 0;
64612
- return obj.replace(
64613
- regex,
64614
- (match) => JSON.stringify(match).slice(1, -1)
64615
- );
64616
- }
64617
- if (obj === null || typeof obj !== "object") {
64618
- return obj;
64619
- }
64620
- if (Array.isArray(obj)) {
64621
- let newArr = null;
64622
- for (let i = 0; i < obj.length; i++) {
64623
- const value = obj[i];
64624
- const escapedValue = escapeAnsiCtrlCodes(value);
64625
- if (escapedValue !== value) {
64626
- if (newArr === null) {
64627
- newArr = [...obj];
64628
- }
64629
- newArr[i] = escapedValue;
64630
- }
64631
- }
64632
- return newArr !== null ? newArr : obj;
64633
- }
64634
- let newObj = null;
64635
- const keys = Object.keys(obj);
64636
- for (const key of keys) {
64637
- const value = obj[key];
64638
- const escapedValue = escapeAnsiCtrlCodes(value);
64639
- if (escapedValue !== value) {
64640
- if (newObj === null) {
64641
- newObj = { ...obj };
64642
- }
64643
- newObj[key] = escapedValue;
64644
- }
64645
- }
64646
- return newObj !== null ? newObj : obj;
64647
- }
64648
- __name(escapeAnsiCtrlCodes, "escapeAnsiCtrlCodes");
64649
- var SENSITIVE_PATTERNS = [
64650
- // API keys with common prefixes
64651
- {
64652
- pattern: /(sk-[a-zA-Z0-9]{20,})/g,
64653
- replacement: "sk-***REDACTED***"
64654
- },
64655
- {
64656
- pattern: /(api[_-]?key[_-]?[=:]\s*)[a-zA-Z0-9_-]{20,}/gi,
64657
- replacement: "$1***REDACTED***"
64658
- },
64659
- // Bearer tokens
64660
- {
64661
- pattern: /(Bearer\s+)[a-zA-Z0-9._-]+/gi,
64662
- replacement: "$1***REDACTED***"
64663
- },
64664
- // Generic tokens
64665
- {
64666
- pattern: /(token[_-]?[=:]\s*)[a-zA-Z0-9._-]{10,}/gi,
64667
- replacement: "$1***REDACTED***"
64668
- },
64669
- // Passwords in connection strings or assignments
64670
- {
64671
- pattern: /(password[_-]?[=:]\s*)[^\s]+/gi,
64672
- replacement: "$1***REDACTED***"
64673
- },
64674
- {
64675
- pattern: /(pwd[_-]?[=:]\s*)[^\s]+/gi,
64676
- replacement: "$1***REDACTED***"
64677
- },
64678
- // AWS keys
64679
- {
64680
- pattern: /(AKIA[A-Z0-9]{16})/g,
64681
- replacement: "***REDACTED***"
64682
- },
64683
- // Generic secret patterns
64684
- {
64685
- pattern: /(secret[_-]?[=:]\s*)[a-zA-Z0-9._-]{10,}/gi,
64686
- replacement: "$1***REDACTED***"
64687
- }
64688
- ];
64689
- function sanitizeSensitiveText(text, maxLength = 200) {
64690
- let result = text;
64691
- for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
64692
- result = result.replace(pattern, replacement);
64693
- }
64694
- if (result.length > maxLength) {
64695
- if (maxLength <= 3) {
64696
- return result.slice(0, maxLength);
64697
- }
64698
- return result.slice(0, maxLength - 3) + "...";
64699
- }
64700
- return result;
64701
- }
64702
- __name(sanitizeSensitiveText, "sanitizeSensitiveText");
64703
- var FILENAME_CONTROL_CHARS_REGEX = /[\x00-\x1f\x7f-\x9f]/g;
64704
- function escapeFilenameControlChar(ch) {
64705
- switch (ch) {
64706
- case "\b":
64707
- return "\\b";
64708
- case " ":
64709
- return "\\t";
64710
- case "\n":
64711
- return "\\n";
64712
- case "\f":
64713
- return "\\f";
64714
- case "\r":
64715
- return "\\r";
64716
- default: {
64717
- const code = ch.charCodeAt(0);
64718
- return `\\u${code.toString(16).padStart(4, "0")}`;
64719
- }
64720
- }
64721
- }
64722
- __name(escapeFilenameControlChar, "escapeFilenameControlChar");
64723
- function sanitizeFilenameForDisplay(name) {
64724
- return escapeAnsiCtrlCodes(name).replace(
64725
- FILENAME_CONTROL_CHARS_REGEX,
64726
- escapeFilenameControlChar
64727
- );
64728
- }
64729
- __name(sanitizeFilenameForDisplay, "sanitizeFilenameForDisplay");
64730
-
64731
- // packages/cli/src/ui/commands/tasksCommand.ts
64732
64908
  function statusLabel(entry) {
64733
64909
  switch (entry.kind) {
64734
64910
  case "agent": {
@@ -64928,6 +65104,147 @@ var tasksCommand = {
64928
65104
  }, "action")
64929
65105
  };
64930
65106
 
65107
+ // packages/cli/src/ui/commands/workflowsCommand.ts
65108
+ init_esbuild_shims();
65109
+ function rowLine(entry, now) {
65110
+ const endTime = entry.endTime ?? now;
65111
+ const runtime = formatDuration(endTime - entry.startTime, {
65112
+ hideTrailingZeros: true
65113
+ });
65114
+ const label = entry.meta?.name ?? entry.runId;
65115
+ const phase = entry.currentPhase ? ` \xB7 ${entry.currentPhase}` : "";
65116
+ const counts = entry.agentsDispatched > 0 ? ` \xB7 ${entry.agentsCompleted}/${entry.agentsDispatched} agents` : "";
65117
+ const phaseCount = entry.phases.length > 0 ? ` \xB7 ${entry.phases.length} ${entry.phases.length === 1 ? "phase" : "phases"}` : "";
65118
+ const errorTail = entry.status === "failed" && entry.error ? ` \u2014 ${entry.error.slice(0, 80)}` : "";
65119
+ return ` ${entry.runId.padEnd(20)} ${entry.status.padEnd(10)} ${runtime.padStart(8)} ${label}${phase}${counts}${phaseCount}${errorTail}`;
65120
+ }
65121
+ __name(rowLine, "rowLine");
65122
+ function detailLines(entry, now) {
65123
+ const lines = [];
65124
+ const endTime = entry.endTime ?? now;
65125
+ const runtime = formatDuration(endTime - entry.startTime, {
65126
+ hideTrailingZeros: true
65127
+ });
65128
+ lines.push(`Workflow ${entry.runId}`);
65129
+ if (entry.meta?.name) {
65130
+ lines.push(` name : ${entry.meta.name}`);
65131
+ }
65132
+ if (entry.meta?.description) {
65133
+ lines.push(` description : ${entry.meta.description}`);
65134
+ }
65135
+ if (entry.meta?.whenToUse) {
65136
+ lines.push(` whenToUse : ${entry.meta.whenToUse}`);
65137
+ }
65138
+ lines.push(` status : ${entry.status}`);
65139
+ lines.push(` runtime : ${runtime}`);
65140
+ if (entry.currentPhase) {
65141
+ lines.push(` currentPhase: ${entry.currentPhase}`);
65142
+ }
65143
+ lines.push(
65144
+ ` agents : ${entry.agentsCompleted}/${entry.agentsDispatched}`
65145
+ );
65146
+ if (entry.error) {
65147
+ lines.push(` error : ${entry.error}`);
65148
+ }
65149
+ if (entry.phases.length > 0) {
65150
+ lines.push("");
65151
+ lines.push(` Phases (${entry.phases.length})`);
65152
+ for (const phase of entry.phases) {
65153
+ lines.push(` \xB7 ${phase}`);
65154
+ }
65155
+ }
65156
+ if (entry.recentLogs.length > 0) {
65157
+ lines.push("");
65158
+ lines.push(` Logs (last ${entry.recentLogs.length})`);
65159
+ for (const line of entry.recentLogs) {
65160
+ lines.push(` ${line}`);
65161
+ }
65162
+ }
65163
+ return lines;
65164
+ }
65165
+ __name(detailLines, "detailLines");
65166
+ var workflowsCommand = {
65167
+ name: "workflows",
65168
+ get description() {
65169
+ return t(
65170
+ "List active and completed workflow runs (text dump \u2014 interactive dialog opens via the footer pill)"
65171
+ );
65172
+ },
65173
+ get argumentHint() {
65174
+ return t("[runId]");
65175
+ },
65176
+ kind: "built-in" /* BUILT_IN */,
65177
+ // Same triple-mode coverage as `/tasks`: the dialog is richer in
65178
+ // interactive mode but headless / acp consumers need the text dump
65179
+ // as their only inspection path.
65180
+ supportedModes: ["interactive", "non_interactive", "acp"],
65181
+ action: /* @__PURE__ */ __name(async (context, args) => {
65182
+ const { config } = context.services;
65183
+ if (!config) {
65184
+ return {
65185
+ type: "message",
65186
+ messageType: "error",
65187
+ content: "Config not available."
65188
+ };
65189
+ }
65190
+ const registry2 = config.getWorkflowRunRegistry();
65191
+ const allEntries = registry2.list();
65192
+ const trimmedArgs = (args ?? "").trim();
65193
+ if (trimmedArgs.length > 0) {
65194
+ const target = registry2.get(trimmedArgs);
65195
+ if (!target) {
65196
+ return {
65197
+ type: "message",
65198
+ messageType: "error",
65199
+ content: `Unknown workflow runId: ${trimmedArgs}`
65200
+ };
65201
+ }
65202
+ return {
65203
+ type: "message",
65204
+ messageType: "info",
65205
+ content: detailLines(target, Date.now()).join("\n")
65206
+ };
65207
+ }
65208
+ if (allEntries.length === 0) {
65209
+ return {
65210
+ type: "message",
65211
+ messageType: "info",
65212
+ content: "No workflow runs recorded yet."
65213
+ };
65214
+ }
65215
+ const now = Date.now();
65216
+ const running = allEntries.filter((e) => e.status === "running").sort((a, b) => a.startTime - b.startTime);
65217
+ const terminal = allEntries.filter((e) => e.status !== "running").sort((a, b) => (b.endTime ?? 0) - (a.endTime ?? 0));
65218
+ const lines = [];
65219
+ if (context.executionMode === "interactive") {
65220
+ lines.push(
65221
+ t(
65222
+ "Tip: use `/workflows <runId>` for the per-run detail view (name, description, phase tree, recent logs)."
65223
+ ),
65224
+ ""
65225
+ );
65226
+ }
65227
+ lines.push(
65228
+ `Workflow runs (${allEntries.length} total \xB7 ${running.length} running)`,
65229
+ ""
65230
+ );
65231
+ if (running.length > 0) {
65232
+ lines.push("Active");
65233
+ for (const entry of running) lines.push(rowLine(entry, now));
65234
+ lines.push("");
65235
+ }
65236
+ if (terminal.length > 0) {
65237
+ lines.push("Recent");
65238
+ for (const entry of terminal) lines.push(rowLine(entry, now));
65239
+ }
65240
+ return {
65241
+ type: "message",
65242
+ messageType: "info",
65243
+ content: lines.join("\n")
65244
+ };
65245
+ }, "action")
65246
+ };
65247
+
64931
65248
  // packages/cli/src/ui/commands/agentsCommand.ts
64932
65249
  init_esbuild_shims();
64933
65250
  var agentsCommand = {
@@ -67500,13 +67817,18 @@ init_esbuild_shims();
67500
67817
  // packages/cli/src/ui/utils/backgroundWorkUtils.ts
67501
67818
  init_esbuild_shims();
67502
67819
  function hasBlockingBackgroundWork(config) {
67503
- return config.getBackgroundTaskRegistry().hasUnfinalizedTasks() || config.getMonitorRegistry().getRunning().length > 0 || config.getBackgroundShellRegistry().hasRunningEntries();
67820
+ return config.getBackgroundTaskRegistry().hasUnfinalizedTasks() || config.getMonitorRegistry().getRunning().length > 0 || config.getBackgroundShellRegistry().hasRunningEntries() || // R7 (wenshao): the WorkflowRunRegistry is a 4th sibling that the
67821
+ // earlier P4b commit forgot to wire here. Without this OR clause,
67822
+ // /clear and session-resume happily ran while a workflow was
67823
+ // mid-run, orphaning the dispatch loop.
67824
+ config.getWorkflowRunRegistry().hasRunningEntries();
67504
67825
  }
67505
67826
  __name(hasBlockingBackgroundWork, "hasBlockingBackgroundWork");
67506
67827
  function resetBackgroundStateForSessionSwitch(config) {
67507
67828
  config.getBackgroundTaskRegistry().reset();
67508
67829
  config.getMonitorRegistry().reset();
67509
67830
  config.getBackgroundShellRegistry().reset();
67831
+ config.getWorkflowRunRegistry().reset();
67510
67832
  }
67511
67833
  __name(resetBackgroundStateForSessionSwitch, "resetBackgroundStateForSessionSwitch");
67512
67834
 
@@ -69783,7 +70105,6 @@ __name(rollbackStandaloneUpdate, "rollbackStandaloneUpdate");
69783
70105
  // packages/cli/src/utils/installationInfo.ts
69784
70106
  init_esbuild_shims();
69785
70107
  import * as fs16 from "node:fs";
69786
- import * as os14 from "node:os";
69787
70108
  import * as path18 from "node:path";
69788
70109
  import * as childProcess from "node:child_process";
69789
70110
  var debugLogger14 = createDebugLogger("INSTALLATION_INFO");
@@ -69896,27 +70217,11 @@ function getInstallationInfo(projectRoot, isAutoUpdateEnabled) {
69896
70217
  npmPrefixWritable = true;
69897
70218
  } catch {
69898
70219
  }
69899
- if (!npmPrefixWritable && isAutoUpdateEnabled) {
69900
- const installRoot = process.env["HOME"] || os14.homedir();
69901
- if (!installRoot || installRoot === "/") {
69902
- return {
69903
- packageManager: "npm" /* NPM */,
69904
- isGlobal: true,
69905
- updateMessage: "Update requires sudo. Run: sudo npm install -g @qwen-code/qwen-code@latest"
69906
- };
69907
- }
69908
- const fallbackStandaloneDir = path18.join(
69909
- installRoot,
69910
- ".local",
69911
- "lib",
69912
- "qwen-code"
69913
- );
70220
+ if (!npmPrefixWritable) {
69914
70221
  return {
69915
70222
  packageManager: "npm" /* NPM */,
69916
70223
  isGlobal: true,
69917
- isStandalone: true,
69918
- standaloneDir: fallbackStandaloneDir,
69919
- updateMessage: "npm install requires sudo. Migrating to standalone installer for automatic updates."
70224
+ updateMessage: "Update requires sudo. Please run: sudo npm install -g @qwen-code/qwen-code@latest"
69920
70225
  };
69921
70226
  }
69922
70227
  const updateCommand2 = "npm install -g @qwen-code/qwen-code@latest";
@@ -71729,7 +72034,7 @@ async function extractMetadata(conversation, config) {
71729
72034
  const gitBranch = firstRecord?.gitBranch;
71730
72035
  let gitRepo;
71731
72036
  if (cwd5) {
71732
- const { getGitRepoName } = await import("./chunks/src-L5P7K4MH.js");
72037
+ const { getGitRepoName } = await import("./chunks/src-E42UOH5I.js");
71733
72038
  gitRepo = getGitRepoName(cwd5);
71734
72039
  }
71735
72040
  let model;
@@ -72995,6 +73300,7 @@ var forkCommand = {
72995
73300
  const params = {
72996
73301
  description: deriveForkDescription(directive),
72997
73302
  prompt: directive,
73303
+ subagent_type: FORK_SUBAGENT_TYPE,
72998
73304
  run_in_background: true
72999
73305
  };
73000
73306
  let result;
@@ -73924,7 +74230,7 @@ function formatHookSource(source) {
73924
74230
  }
73925
74231
  }
73926
74232
  __name(formatHookSource, "formatHookSource");
73927
- var listCommand4 = {
74233
+ var listCommand5 = {
73928
74234
  name: "list",
73929
74235
  get description() {
73930
74236
  return t("List all configured hooks");
@@ -74047,7 +74353,7 @@ var hooksCommand2 = {
74047
74353
  dialog: "hooks"
74048
74354
  };
74049
74355
  }
74050
- const result = await listCommand4.action?.(context, args);
74356
+ const result = await listCommand5.action?.(context, args);
74051
74357
  return result ?? { type: "message", messageType: "info", content: "" };
74052
74358
  }, "action")
74053
74359
  };
@@ -74344,7 +74650,7 @@ init_esbuild_shims();
74344
74650
  init_esbuild_shims();
74345
74651
  var import_strip_json_comments4 = __toESM(require_strip_json_comments(), 1);
74346
74652
  import * as fs18 from "node:fs";
74347
- import * as os15 from "node:os";
74653
+ import * as os14 from "node:os";
74348
74654
  import * as path21 from "node:path";
74349
74655
  function isRecord(value) {
74350
74656
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -74430,11 +74736,11 @@ function getClaudeProjectSettings(projects, cwd5) {
74430
74736
  return void 0;
74431
74737
  }
74432
74738
  __name(getClaudeProjectSettings, "getClaudeProjectSettings");
74433
- function getClaudeCodeConfigPath(homeDir = os15.homedir()) {
74739
+ function getClaudeCodeConfigPath(homeDir = os14.homedir()) {
74434
74740
  return path21.join(homeDir, ".claude.json");
74435
74741
  }
74436
74742
  __name(getClaudeCodeConfigPath, "getClaudeCodeConfigPath");
74437
- function getClaudeDesktopConfigPath(homeDir = os15.homedir(), platform5 = process.platform, env5 = process.env) {
74743
+ function getClaudeDesktopConfigPath(homeDir = os14.homedir(), platform5 = process.platform, env5 = process.env) {
74438
74744
  if (platform5 === "win32") {
74439
74745
  const appData = env5["APPDATA"] ?? path21.win32.join(homeDir, "AppData", "Roaming");
74440
74746
  return path21.win32.join(appData, "Claude", "claude_desktop_config.json");
@@ -74600,7 +74906,7 @@ function loadClaudeDesktopMcpServers(homeDir, platform5, env5) {
74600
74906
  }
74601
74907
  __name(loadClaudeDesktopMcpServers, "loadClaudeDesktopMcpServers");
74602
74908
  function loadClaudeMcpSources(options) {
74603
- const homeDir = options.homeDir ?? os15.homedir();
74909
+ const homeDir = options.homeDir ?? os14.homedir();
74604
74910
  const cwd5 = options.cwd ?? process.cwd();
74605
74911
  const platform5 = options.platform ?? process.platform;
74606
74912
  const env5 = options.env ?? process.env;
@@ -76863,7 +77169,7 @@ init_esbuild_shims();
76863
77169
  // packages/cli/src/ui/utils/terminalSetup.ts
76864
77170
  init_esbuild_shims();
76865
77171
  import { promises as fs21 } from "node:fs";
76866
- import * as os16 from "node:os";
77172
+ import * as os15 from "node:os";
76867
77173
  import * as path26 from "node:path";
76868
77174
  import { exec as exec3 } from "node:child_process";
76869
77175
  import { promisify } from "node:util";
@@ -76982,7 +77288,7 @@ async function detectTerminal2() {
76982
77288
  if (termProgram === "vscode" || process.env["VSCODE_GIT_IPC_HANDLE"]) {
76983
77289
  return "vscode";
76984
77290
  }
76985
- if (os16.platform() !== "win32") {
77291
+ if (os15.platform() !== "win32") {
76986
77292
  try {
76987
77293
  const { stdout } = await execAsync("ps -o comm= -p $PPID");
76988
77294
  const parentName = stdout.trim();
@@ -77012,10 +77318,10 @@ async function backupFile(filePath) {
77012
77318
  }
77013
77319
  __name(backupFile, "backupFile");
77014
77320
  function getVSCodeStyleConfigDir(appName) {
77015
- const platform5 = os16.platform();
77321
+ const platform5 = os15.platform();
77016
77322
  if (platform5 === "darwin") {
77017
77323
  return path26.join(
77018
- os16.homedir(),
77324
+ os15.homedir(),
77019
77325
  "Library",
77020
77326
  "Application Support",
77021
77327
  appName,
@@ -77027,7 +77333,7 @@ function getVSCodeStyleConfigDir(appName) {
77027
77333
  }
77028
77334
  return path26.join(process.env["APPDATA"], appName, "User");
77029
77335
  } else {
77030
- return path26.join(os16.homedir(), ".config", appName, "User");
77336
+ return path26.join(os15.homedir(), ".config", appName, "User");
77031
77337
  }
77032
77338
  }
77033
77339
  __name(getVSCodeStyleConfigDir, "getVSCodeStyleConfigDir");
@@ -79279,6 +79585,12 @@ var BuiltinCommandLoader = class {
79279
79585
  aboutCommand,
79280
79586
  agentsCommand,
79281
79587
  tasksCommand,
79588
+ // Gated behind isWorkflowsEnabled — feature flag honors
79589
+ // QWEN_CODE_ENABLE_WORKFLOWS (opt-in) and QWEN_CODE_DISABLE_WORKFLOWS
79590
+ // (kill switch). When the flag is off the command vanishes entirely
79591
+ // from typeahead and help, matching the established convention for
79592
+ // experimental builtins.
79593
+ this.config?.isWorkflowsEnabled() ? workflowsCommand : null,
79282
79594
  arenaCommand,
79283
79595
  approvalModeCommand,
79284
79596
  authCommand2,
@@ -82903,6 +83215,10 @@ ${text}
82903
83215
  if (options.captureMonitorNotifications !== false) {
82904
83216
  monitorRegistry.setNotificationCallback(
82905
83217
  (displayText, modelText, meta) => {
83218
+ if (meta.status === "running" && typeof monitorRegistry.get === "function") {
83219
+ const entry = monitorRegistry.get(meta.monitorId);
83220
+ if (!entry || entry.status !== "running") return;
83221
+ }
82906
83222
  const queueItem = {
82907
83223
  displayText,
82908
83224
  modelText,
@@ -83189,10 +83505,25 @@ ${text}
83189
83505
  if (pendingTeammateMessages.length > 0) {
83190
83506
  continue;
83191
83507
  }
83192
- const drainOneItem = /* @__PURE__ */ __name(async () => {
83508
+ const drainBatch = /* @__PURE__ */ __name(async () => {
83193
83509
  if (localQueue.length === 0) return;
83194
- const item = localQueue.shift();
83195
- emitNotificationToSdk(item);
83510
+ const targetType = localQueue[0].sendMessageType;
83511
+ let splitIdx = targetType === "cron" /* Cron */ ? 1 : 0;
83512
+ if (splitIdx === 0) {
83513
+ while (splitIdx < localQueue.length && localQueue[splitIdx].sendMessageType === targetType) {
83514
+ splitIdx++;
83515
+ }
83516
+ }
83517
+ const batch = localQueue.splice(0, splitIdx);
83518
+ if (batch.length === 0) return;
83519
+ for (const queueItem of batch) {
83520
+ emitNotificationToSdk(queueItem);
83521
+ }
83522
+ const item = {
83523
+ displayText: batch.map((i) => i.displayText).join("; "),
83524
+ modelText: batch.map((i) => i.modelText).join("\n\n"),
83525
+ sendMessageType: targetType
83526
+ };
83196
83527
  turnCount++;
83197
83528
  if (config.getMaxSessionTurns() >= 0 && turnCount > config.getMaxSessionTurns()) {
83198
83529
  await handleMaxTurnsExceededError(config);
@@ -83260,14 +83591,14 @@ ${text}
83260
83591
  break;
83261
83592
  }
83262
83593
  }
83263
- }, "drainOneItem");
83594
+ }, "drainBatch");
83264
83595
  let drainPromise = null;
83265
83596
  const drainLocalQueue = /* @__PURE__ */ __name(() => {
83266
83597
  if (drainPromise) return drainPromise;
83267
83598
  const p = (async () => {
83268
83599
  while (localQueue.length > 0) {
83269
83600
  if (structuredSubmission !== void 0) return;
83270
- await drainOneItem();
83601
+ await drainBatch();
83271
83602
  }
83272
83603
  })();
83273
83604
  drainPromise = p;
@@ -83902,7 +84233,7 @@ var SystemController = class extends BaseController {
83902
84233
  throw new Error("Request aborted");
83903
84234
  }
83904
84235
  try {
83905
- const mod = await import("./chunks/contextCommand-KS2H7MW5.js");
84236
+ const mod = await import("./chunks/contextCommand-WP7BU7IY.js");
83906
84237
  if (signal.aborted) {
83907
84238
  throw new Error("Request aborted");
83908
84239
  }
@@ -85303,6 +85634,10 @@ var Session = class {
85303
85634
  if (this.isShuttingDown || this.abortController.signal.aborted) {
85304
85635
  return;
85305
85636
  }
85637
+ if (meta.status === "running" && typeof registry2.get === "function") {
85638
+ const entry = registry2.get(meta.monitorId);
85639
+ if (!entry || entry.status !== "running") return;
85640
+ }
85306
85641
  this.enqueueMonitorNotification({
85307
85642
  displayText,
85308
85643
  modelText,
@@ -85507,25 +85842,29 @@ var Session = class {
85507
85842
  debugLogger33.error("[Session] Query execution error:", error);
85508
85843
  }
85509
85844
  }
85510
- async processMonitorNotification(notification) {
85845
+ async processMonitorNotificationBatch(batch) {
85511
85846
  await this.waitForInitialization();
85512
- this.outputAdapter.emitUserMessage([{ text: notification.displayText }]);
85513
- this.outputAdapter.emitSystemMessage(
85514
- "task_notification",
85515
- notification.sdkNotification
85516
- );
85847
+ for (const item of batch) {
85848
+ this.outputAdapter.emitUserMessage([{ text: item.displayText }]);
85849
+ this.outputAdapter.emitSystemMessage(
85850
+ "task_notification",
85851
+ item.sdkNotification
85852
+ );
85853
+ }
85854
+ const combinedModelText = batch.map((n) => n.modelText).join("\n\n");
85855
+ const combinedDisplayText = batch.map((n) => n.displayText).join("; ");
85517
85856
  const promptId = this.getNextPromptId();
85518
85857
  await runNonInteractive(
85519
85858
  this.config,
85520
85859
  this.settings,
85521
- notification.modelText,
85860
+ combinedModelText,
85522
85861
  promptId,
85523
85862
  {
85524
85863
  abortController: this.abortController,
85525
85864
  adapter: this.outputAdapter,
85526
85865
  controlService: this.controlService ?? void 0,
85527
85866
  sendMessageType: "notification" /* Notification */,
85528
- notificationDisplayText: notification.displayText,
85867
+ notificationDisplayText: combinedDisplayText,
85529
85868
  captureMonitorNotifications: false,
85530
85869
  captureMonitorRegistrations: false
85531
85870
  }
@@ -85551,15 +85890,15 @@ var Session = class {
85551
85890
  this.outputAdapter.emitSystemMessage("task_started", started);
85552
85891
  continue;
85553
85892
  }
85554
- const notification = this.monitorQueue.shift();
85555
- if (!notification) {
85893
+ if (this.monitorQueue.length === 0) {
85556
85894
  continue;
85557
85895
  }
85896
+ const batch = this.monitorQueue.splice(0);
85558
85897
  try {
85559
- await this.processMonitorNotification(notification);
85898
+ await this.processMonitorNotificationBatch(batch);
85560
85899
  } catch (error) {
85561
85900
  debugLogger33.error(
85562
- "[Session] Error processing monitor notification:",
85901
+ "[Session] Error processing monitor notification batch:",
85563
85902
  error
85564
85903
  );
85565
85904
  this.emitErrorResult(error);
@@ -87745,6 +88084,22 @@ __name(loadLowlight, "loadLowlight");
87745
88084
  // packages/cli/src/ui/utils/CodeColorizer.tsx
87746
88085
  var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
87747
88086
  var debugLogger37 = createDebugLogger("CODE_COLORIZER");
88087
+ var STRUCTURAL_BOX_RE = /[│├└┌┐┘┬┴┼]/;
88088
+ var CJK_RE = /[\u4E00-\u9FFF\u3400-\u4DBF]/g;
88089
+ function looksLikeDiagramOrArt(line) {
88090
+ const trimmed = line.trim();
88091
+ if (trimmed.length === 0) return false;
88092
+ if (STRUCTURAL_BOX_RE.test(trimmed)) {
88093
+ return true;
88094
+ }
88095
+ const cjkMatches = trimmed.match(CJK_RE) || [];
88096
+ const totalChars = trimmed.replace(/\s/g, "").length;
88097
+ if (totalChars > 0 && cjkMatches.length / totalChars > 0.3) {
88098
+ return true;
88099
+ }
88100
+ return false;
88101
+ }
88102
+ __name(looksLikeDiagramOrArt, "looksLikeDiagramOrArt");
87748
88103
  function renderHastNode(node, theme2, inheritedColor) {
87749
88104
  if (node.type === "text") {
87750
88105
  const color2 = inheritedColor || theme2.defaultColor;
@@ -87790,6 +88145,9 @@ function highlightAndRenderLine(line, language, theme2, lowlight) {
87790
88145
  if (!lowlight) {
87791
88146
  return line;
87792
88147
  }
88148
+ if (!language && looksLikeDiagramOrArt(line)) {
88149
+ return line;
88150
+ }
87793
88151
  try {
87794
88152
  const getHighlightedLine = /* @__PURE__ */ __name(() => !language || !lowlight.registered(language) ? lowlight.highlightAuto(line) : lowlight.highlight(language, line), "getHighlightedLine");
87795
88153
  const renderedNode = renderHastNode(getHighlightedLine(), theme2, void 0);
@@ -90749,7 +91107,7 @@ __name(renderMermaidVisual, "renderMermaidVisual");
90749
91107
  init_esbuild_shims();
90750
91108
  import crypto2 from "node:crypto";
90751
91109
  import fs27 from "node:fs";
90752
- import os17 from "node:os";
91110
+ import os16 from "node:os";
90753
91111
  import path35 from "node:path";
90754
91112
  import { spawn as spawn4, spawnSync } from "node:child_process";
90755
91113
  var CACHE_LIMIT = 40;
@@ -91313,7 +91671,7 @@ function isExecutable(filePath) {
91313
91671
  __name(isExecutable, "isExecutable");
91314
91672
  async function renderPngWithMmdcAsync(source, mmdc, env5, signal) {
91315
91673
  const tempDir = await fs27.promises.mkdtemp(
91316
- path35.join(os17.tmpdir(), "qwen-mermaid-")
91674
+ path35.join(os16.tmpdir(), "qwen-mermaid-")
91317
91675
  );
91318
91676
  const inputPath = path35.join(tempDir, "diagram.mmd");
91319
91677
  const outputPath = path35.join(tempDir, "diagram.png");
@@ -91410,7 +91768,7 @@ function getMermaidCellAspectRatio(env5) {
91410
91768
  __name(getMermaidCellAspectRatio, "getMermaidCellAspectRatio");
91411
91769
  async function renderPngWithChafaAsync(png, widthCells, rows, chafa, env5, signal) {
91412
91770
  const tempDir = await fs27.promises.mkdtemp(
91413
- path35.join(os17.tmpdir(), "qwen-mermaid-")
91771
+ path35.join(os16.tmpdir(), "qwen-mermaid-")
91414
91772
  );
91415
91773
  const imagePath = path35.join(tempDir, "diagram.png");
91416
91774
  try {
@@ -92639,39 +92997,143 @@ var AssistantMessageContent = /* @__PURE__ */ __name(({
92639
92997
  sourceCopyIndexOffsets
92640
92998
  }
92641
92999
  ), "AssistantMessageContent");
93000
+ var MAX_STREAMING_THINKING_VISUAL_LINES = 4;
93001
+ function wrapToVisualLines(text, width) {
93002
+ if (width <= 0) {
93003
+ return [""];
93004
+ }
93005
+ const visualLines = [];
93006
+ for (const logicalLine of text.split("\n")) {
93007
+ if (logicalLine === "") {
93008
+ visualLines.push("");
93009
+ continue;
93010
+ }
93011
+ let currentLine = "";
93012
+ let currentWidth = 0;
93013
+ for (const char of logicalLine) {
93014
+ const charWidth = getCachedStringWidth(char);
93015
+ if (currentWidth + charWidth > width && currentWidth > 0) {
93016
+ visualLines.push(currentLine);
93017
+ currentLine = "";
93018
+ currentWidth = 0;
93019
+ }
93020
+ currentLine += char;
93021
+ currentWidth += charWidth;
93022
+ }
93023
+ if (currentLine) {
93024
+ visualLines.push(currentLine);
93025
+ }
93026
+ }
93027
+ if (visualLines.length === 0) {
93028
+ visualLines.push("");
93029
+ }
93030
+ return visualLines;
93031
+ }
93032
+ __name(wrapToVisualLines, "wrapToVisualLines");
93033
+ function tailVisualLines(text, width, maxLines) {
93034
+ const charBudget = maxLines * width * 2;
93035
+ let sliceStart = Math.max(0, text.length - charBudget);
93036
+ if (sliceStart > 0) {
93037
+ const nl = text.indexOf("\n", sliceStart);
93038
+ if (nl !== -1 && nl < text.length - 1) {
93039
+ sliceStart = nl + 1;
93040
+ }
93041
+ }
93042
+ const lines = wrapToVisualLines(text.slice(sliceStart), width);
93043
+ return lines.slice(-maxLines).join("\n");
93044
+ }
93045
+ __name(tailVisualLines, "tailVisualLines");
93046
+ function formatDuration2(ms) {
93047
+ const totalSeconds = Math.round(ms / 1e3);
93048
+ if (totalSeconds < 60) {
93049
+ return `${totalSeconds}s`;
93050
+ }
93051
+ const minutes = Math.floor(totalSeconds / 60);
93052
+ const seconds = totalSeconds % 60;
93053
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
93054
+ }
93055
+ __name(formatDuration2, "formatDuration");
92642
93056
  var ThinkMessage = /* @__PURE__ */ __name(({
92643
93057
  text,
92644
93058
  isPending,
93059
+ expanded = false,
92645
93060
  availableTerminalHeight,
92646
- contentWidth
92647
- }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
92648
- PrefixedMarkdownMessage,
92649
- {
92650
- text,
92651
- prefix: "\u2726",
92652
- prefixColor: theme.text.secondary,
92653
- isPending,
92654
- availableTerminalHeight,
92655
- contentWidth,
92656
- textColor: theme.text.secondary
93061
+ contentWidth,
93062
+ durationMs
93063
+ }) => {
93064
+ const durationSuffix = durationMs != null ? ` ${formatDuration2(durationMs)}` : "";
93065
+ if (!isPending && !expanded) {
93066
+ const label = durationMs != null ? `${t("Thought for")} ${formatDuration2(durationMs)}` : t("Thinking");
93067
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { dimColor: true, italic: true, children: label });
93068
+ }
93069
+ if (isPending) {
93070
+ const innerWidth = Math.max(contentWidth - 2, 20);
93071
+ const maxLines = availableTerminalHeight != null ? Math.max(
93072
+ 1,
93073
+ Math.min(
93074
+ MAX_STREAMING_THINKING_VISUAL_LINES,
93075
+ Math.floor(availableTerminalHeight / 3)
93076
+ )
93077
+ ) : MAX_STREAMING_THINKING_VISUAL_LINES;
93078
+ const display = tailVisualLines(text, innerWidth, maxLines);
93079
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", children: [
93080
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Text, { dimColor: true, italic: true, children: [
93081
+ "\u27E1 ",
93082
+ t("Thinking"),
93083
+ "\u2026",
93084
+ durationSuffix
93085
+ ] }),
93086
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Box_default, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { dimColor: true, wrap: "truncate", children: display }) })
93087
+ ] });
92657
93088
  }
92658
- ), "ThinkMessage");
93089
+ const expandedLabel = durationMs != null ? `${t("Thought for")} ${formatDuration2(durationMs)}` : `${t("Thinking")}\u2026`;
93090
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", children: [
93091
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { dimColor: true, italic: true, children: expandedLabel }),
93092
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Box_default, { paddingLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
93093
+ MarkdownDisplay,
93094
+ {
93095
+ text,
93096
+ isPending: false,
93097
+ availableTerminalHeight,
93098
+ contentWidth: contentWidth - 2,
93099
+ textColor: theme.text.secondary
93100
+ }
93101
+ ) })
93102
+ ] });
93103
+ }, "ThinkMessage");
92659
93104
  var ThinkMessageContent = /* @__PURE__ */ __name(({
92660
93105
  text,
92661
93106
  isPending,
93107
+ expanded = false,
92662
93108
  availableTerminalHeight,
92663
93109
  contentWidth
92664
- }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
92665
- ContinuationMarkdownMessage,
92666
- {
92667
- text,
92668
- isPending,
92669
- availableTerminalHeight,
92670
- contentWidth,
92671
- basePrefix: "\u2726",
92672
- textColor: theme.text.secondary
93110
+ }) => {
93111
+ if (!isPending && !expanded) {
93112
+ return null;
93113
+ }
93114
+ if (isPending) {
93115
+ const innerWidth = Math.max(contentWidth - 2, 20);
93116
+ const maxLines = availableTerminalHeight != null ? Math.max(
93117
+ 1,
93118
+ Math.min(
93119
+ MAX_STREAMING_THINKING_VISUAL_LINES,
93120
+ Math.floor(availableTerminalHeight / 3)
93121
+ )
93122
+ ) : MAX_STREAMING_THINKING_VISUAL_LINES;
93123
+ const display = tailVisualLines(text, innerWidth, maxLines);
93124
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Box_default, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { dimColor: true, wrap: "truncate", children: display }) });
92673
93125
  }
92674
- ), "ThinkMessageContent");
93126
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Box_default, { paddingLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
93127
+ MarkdownDisplay,
93128
+ {
93129
+ text,
93130
+ isPending: false,
93131
+ availableTerminalHeight,
93132
+ contentWidth: contentWidth - 2,
93133
+ textColor: theme.text.secondary
93134
+ }
93135
+ ) });
93136
+ }, "ThinkMessageContent");
92675
93137
 
92676
93138
  // packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
92677
93139
  init_esbuild_shims();
@@ -93093,7 +93555,7 @@ init_esbuild_shims();
93093
93555
  var import_react58 = __toESM(require_react(), 1);
93094
93556
  import { spawnSync as spawnSync2 } from "node:child_process";
93095
93557
  import fs28 from "node:fs";
93096
- import os18 from "node:os";
93558
+ import os17 from "node:os";
93097
93559
  import pathMod from "node:path";
93098
93560
 
93099
93561
  // packages/cli/src/ui/components/shared/vim-buffer-actions.ts
@@ -95445,7 +95907,7 @@ function useTextBuffer({
95445
95907
  let tmpDir;
95446
95908
  let filePath;
95447
95909
  try {
95448
- tmpDir = fs28.mkdtempSync(pathMod.join(os18.tmpdir(), "qwen-edit-"));
95910
+ tmpDir = fs28.mkdtempSync(pathMod.join(os17.tmpdir(), "qwen-edit-"));
95449
95911
  filePath = pathMod.join(tmpDir, "buffer.txt");
95450
95912
  } catch (err) {
95451
95913
  debugLogger39.error(
@@ -101189,20 +101651,23 @@ var HistoryItemDisplayComponent = /* @__PURE__ */ __name(({
101189
101651
  sourceCopyIndexOffsets
101190
101652
  }
101191
101653
  ),
101192
- !compactMode && itemForDisplay.type === "gemini_thought" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
101654
+ itemForDisplay.type === "gemini_thought" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
101193
101655
  ThinkMessage,
101194
101656
  {
101195
101657
  text: itemForDisplay.text.trimEnd(),
101196
101658
  isPending,
101659
+ expanded: false,
101197
101660
  availableTerminalHeight: availableTerminalHeightGemini ?? availableTerminalHeight,
101198
- contentWidth
101661
+ contentWidth,
101662
+ durationMs: itemForDisplay.durationMs
101199
101663
  }
101200
101664
  ),
101201
- !compactMode && itemForDisplay.type === "gemini_thought_content" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
101665
+ itemForDisplay.type === "gemini_thought_content" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
101202
101666
  ThinkMessageContent,
101203
101667
  {
101204
101668
  text: itemForDisplay.text.trimEnd(),
101205
101669
  isPending,
101670
+ expanded: false,
101206
101671
  availableTerminalHeight: availableTerminalHeightGemini ?? availableTerminalHeight,
101207
101672
  contentWidth
101208
101673
  }
@@ -105930,12 +106395,12 @@ __name(StatusLineDialog, "StatusLineDialog");
105930
106395
  init_esbuild_shims();
105931
106396
  var import_react100 = __toESM(require_react(), 1);
105932
106397
  var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
105933
- function formatTime(seconds) {
106398
+ function formatTime2(seconds) {
105934
106399
  const minutes = Math.floor(seconds / 60);
105935
106400
  const remainingSeconds = seconds % 60;
105936
106401
  return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
105937
106402
  }
105938
- __name(formatTime, "formatTime");
106403
+ __name(formatTime2, "formatTime");
105939
106404
  function QwenOAuthProgress({
105940
106405
  onTimeout,
105941
106406
  onCancel,
@@ -106032,7 +106497,7 @@ function QwenOAuthProgress({
106032
106497
  /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(Text, { children: [
106033
106498
  t("Time remaining:"),
106034
106499
  " ",
106035
- formatTime(timeRemaining)
106500
+ formatTime2(timeRemaining)
106036
106501
  ] })
106037
106502
  ] }),
106038
106503
  /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(Text, { color: theme.text.secondary, children: t("Esc to cancel") }) })
@@ -106060,7 +106525,7 @@ function QwenOAuthProgress({
106060
106525
  /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(Text, { children: [
106061
106526
  t("Time remaining:"),
106062
106527
  " ",
106063
- formatTime(timeRemaining)
106528
+ formatTime2(timeRemaining)
106064
106529
  ] })
106065
106530
  ] }),
106066
106531
  /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(Text, { color: theme.text.secondary, children: t("Esc to cancel") }) })
@@ -107983,7 +108448,7 @@ __name(TrustDialog, "TrustDialog");
107983
108448
  init_esbuild_shims();
107984
108449
  var import_react108 = __toESM(require_react(), 1);
107985
108450
  import * as fs31 from "node:fs";
107986
- import * as os19 from "node:os";
108451
+ import * as os18 from "node:os";
107987
108452
  import * as nodePath2 from "node:path";
107988
108453
  var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1);
107989
108454
  function getPermScopeItems() {
@@ -108098,7 +108563,7 @@ function PermissionsDialog({
108098
108563
  const dirCompletions = (0, import_react108.useMemo)(() => {
108099
108564
  const trimmed = newDirInput.trim();
108100
108565
  if (!trimmed) return [];
108101
- const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os19.homedir()) : trimmed;
108566
+ const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os18.homedir()) : trimmed;
108102
108567
  const endsWithSep = expanded.endsWith("/") || expanded.endsWith(nodePath2.sep);
108103
108568
  const searchDir = endsWithSep ? expanded : nodePath2.dirname(expanded);
108104
108569
  const prefix = endsWithSep ? "" : nodePath2.basename(expanded);
@@ -108172,7 +108637,7 @@ function PermissionsDialog({
108172
108637
  const handleAddDirSubmit = (0, import_react108.useCallback)(() => {
108173
108638
  const trimmed = newDirInput.trim();
108174
108639
  if (!trimmed) return;
108175
- const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os19.homedir()) : trimmed;
108640
+ const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os18.homedir()) : trimmed;
108176
108641
  const absoluteExpanded = nodePath2.isAbsolute(expanded) ? expanded : nodePath2.resolve(expanded);
108177
108642
  if (!fs31.existsSync(absoluteExpanded)) {
108178
108643
  setDirInputError(t("Directory does not exist."));
@@ -108840,7 +109305,9 @@ function ModelDialog({
108840
109305
  const availableModelEntries = (0, import_react109.useMemo)(() => {
108841
109306
  const allModels = config ? config.getAllConfiguredModels() : [];
108842
109307
  const runtimeModels = allModels.filter((m) => m.isRuntimeModel);
108843
- const registryModels = allModels.filter((m) => !m.isRuntimeModel);
109308
+ const registryModels = allModels.filter(
109309
+ (m) => !m.isRuntimeModel && (m.authType !== "qwen-oauth" /* QWEN_OAUTH */ || authType === "qwen-oauth" /* QWEN_OAUTH */)
109310
+ );
108844
109311
  const modelsByAuthTypeMap = /* @__PURE__ */ new Map();
108845
109312
  for (const model of registryModels) {
108846
109313
  const authType2 = model.authType;
@@ -108875,7 +109342,7 @@ function ModelDialog({
108875
109342
  }
108876
109343
  }
108877
109344
  return result;
108878
- }, [config]);
109345
+ }, [authType, config]);
108879
109346
  const MODEL_OPTIONS = (0, import_react109.useMemo)(
108880
109347
  () => availableModelEntries.map(
108881
109348
  ({ authType: t2, model, isRuntime, snapshotId }) => {
@@ -109747,11 +110214,11 @@ var import_react113 = __toESM(require_react(), 1);
109747
110214
  var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1);
109748
110215
  var STATUS_REFRESH_INTERVAL_MS = 2e3;
109749
110216
  var IN_PROCESS_REFRESH_INTERVAL_MS = 1e3;
109750
- function truncate(str, maxLen) {
110217
+ function truncate2(str, maxLen) {
109751
110218
  if (str.length <= maxLen) return str;
109752
110219
  return str.slice(0, maxLen - 1) + "\u2026";
109753
110220
  }
109754
- __name(truncate, "truncate");
110221
+ __name(truncate2, "truncate");
109755
110222
  function pad(str, len, align2 = "left") {
109756
110223
  if (str.length >= len) return str.slice(0, len);
109757
110224
  const padding = " ".repeat(len - str.length);
@@ -109878,7 +110345,7 @@ function ArenaStatusDialog({
109878
110345
  const successfulToolCalls = live?.successfulToolCalls ?? agent.stats.successfulToolCalls;
109879
110346
  const failedToolCalls = live?.failedToolCalls ?? agent.stats.failedToolCalls;
109880
110347
  return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Box_default, { flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(Box_default, { children: [
109881
- /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Box_default, { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Text, { color: theme.text.primary, children: truncate(label, MAX_MODEL_NAME_LENGTH) }) }),
110348
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Box_default, { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Text, { color: theme.text.primary, children: truncate2(label, MAX_MODEL_NAME_LENGTH) }) }),
109882
110349
  /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Box_default, { width: colStatus, justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Text, { color: color2, children: statusText }) }),
109883
110350
  /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Box_default, { width: colTime, justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Text, { color: theme.text.primary, children: pad(formatDuration(elapsed), colTime - 1, "right") }) }),
109884
110351
  /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Box_default, { width: colTokens, justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Text, { color: theme.text.primary, children: pad(totalTokens.toLocaleString(), colTokens - 1, "right") }) }),
@@ -112378,11 +112845,11 @@ function sortSkills(skills) {
112378
112845
  );
112379
112846
  }
112380
112847
  __name(sortSkills, "sortSkills");
112381
- function truncate2(text, max) {
112848
+ function truncate3(text, max) {
112382
112849
  if (text.length <= max) return text;
112383
112850
  return `${text.slice(0, Math.max(0, max - 1))}\u2026`;
112384
112851
  }
112385
- __name(truncate2, "truncate");
112852
+ __name(truncate3, "truncate");
112386
112853
  function SkillsManagerDialog({
112387
112854
  settings,
112388
112855
  config,
@@ -112473,7 +112940,7 @@ function SkillsManagerDialog({
112473
112940
  () => filteredUnlocked.map((s) => ({
112474
112941
  key: s.name,
112475
112942
  value: { name: s.name, description: s.description, level: s.level },
112476
- label: `${truncate2(s.name, NAME_COLUMN).padEnd(NAME_COLUMN)} ${truncate2(
112943
+ label: `${truncate3(s.name, NAME_COLUMN).padEnd(NAME_COLUMN)} ${truncate3(
112477
112944
  s.description,
112478
112945
  80
112479
112946
  )} (${levelLabel(s.level)})`
@@ -112718,8 +113185,8 @@ function SkillsManagerDialog({
112718
113185
  filteredLocked.map((s) => {
112719
113186
  const scopeName = higher.scopeOf(s.name) ?? t("higher scope");
112720
113187
  return /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(Text, { dimColor: true, wrap: "truncate", children: t(" {{name}} {{description}} [locked: {{scope}}]", {
112721
- name: truncate2(s.name, NAME_COLUMN).padEnd(NAME_COLUMN),
112722
- description: truncate2(s.description, 60),
113188
+ name: truncate3(s.name, NAME_COLUMN).padEnd(NAME_COLUMN),
113189
+ description: truncate3(s.description, 60),
112723
113190
  scope: scopeName
112724
113191
  }) }, s.name);
112725
113192
  })
@@ -117862,7 +118329,7 @@ function convertToHistoryItems(conversation, config) {
117862
118329
  }
117863
118330
  case "assistant": {
117864
118331
  const parts = record.message?.parts;
117865
- const thoughtText = !config || !config.getContentGenerator().useSummarizedThinking() ? extractThoughtTextFromParts(parts) : "";
118332
+ const thoughtText = !config ? extractThoughtTextFromParts(parts) : "";
117866
118333
  const text = extractTextFromParts(parts);
117867
118334
  const functionCalls = extractFunctionCalls(parts);
117868
118335
  if (thoughtText) {
@@ -119339,7 +119806,7 @@ __name(emptyMessage, "emptyMessage");
119339
119806
  init_esbuild_shims();
119340
119807
  var import_react146 = __toESM(require_react(), 1);
119341
119808
  import fs32 from "node:fs/promises";
119342
- import os20 from "node:os";
119809
+ import os19 from "node:os";
119343
119810
  import path39 from "node:path";
119344
119811
  import { spawnSync as spawnSync4 } from "node:child_process";
119345
119812
  var import_jsx_runtime144 = __toESM(require_jsx_runtime(), 1);
@@ -119391,7 +119858,7 @@ async function ensureFileExists(filePath) {
119391
119858
  }
119392
119859
  __name(ensureFileExists, "ensureFileExists");
119393
119860
  function formatDisplayPath(filePath) {
119394
- const home = os20.homedir();
119861
+ const home = os19.homedir();
119395
119862
  if (filePath.startsWith(home)) {
119396
119863
  return `~${filePath.slice(home.length)}`;
119397
119864
  }
@@ -119726,6 +120193,8 @@ function entryId(entry) {
119726
120193
  return entry.shellId;
119727
120194
  case "monitor":
119728
120195
  return entry.monitorId;
120196
+ case "workflow":
120197
+ return entry.runId;
119729
120198
  case "dream":
119730
120199
  return entry.dreamId;
119731
120200
  default: {
@@ -119744,6 +120213,7 @@ function useBackgroundTaskView(config) {
119744
120213
  const agentRegistry = config.getBackgroundTaskRegistry();
119745
120214
  const shellRegistry = config.getBackgroundShellRegistry();
119746
120215
  const monitorRegistry = config.getMonitorRegistry();
120216
+ const workflowRegistry = config.getWorkflowRunRegistry();
119747
120217
  const memoryManager = config.getMemoryManager();
119748
120218
  const projectRoot = config.getProjectRoot();
119749
120219
  let lastDreamSig = "";
@@ -119752,6 +120222,7 @@ function useBackgroundTaskView(config) {
119752
120222
  const agentEntries = [...agentRegistry.getAll()];
119753
120223
  const shellEntries = [...shellRegistry.getAll()];
119754
120224
  const monitorEntries = [...monitorRegistry.getAll()];
120225
+ const workflowEntries = [...workflowRegistry.list()];
119755
120226
  const allDreams = dreamSnapshot ?? memoryManager.listTasksByType("dream", projectRoot);
119756
120227
  const runningDreams = allDreams.filter((t2) => t2.status === "running");
119757
120228
  const terminalDreams = allDreams.filter(
@@ -119784,6 +120255,7 @@ function useBackgroundTaskView(config) {
119784
120255
  ...agentEntries,
119785
120256
  ...shellEntries,
119786
120257
  ...monitorEntries,
120258
+ ...workflowEntries,
119787
120259
  ...dreamEntries
119788
120260
  ].sort((a, b) => {
119789
120261
  const aActive = isActive(a);
@@ -119800,6 +120272,7 @@ function useBackgroundTaskView(config) {
119800
120272
  agentRegistry.setStatusChangeCallback(refreshFromRegistry);
119801
120273
  shellRegistry.setStatusChangeCallback(refreshFromRegistry);
119802
120274
  monitorRegistry.setStatusChangeCallback(refreshFromRegistry);
120275
+ workflowRegistry.setStatusChangeCallback(refreshFromRegistry);
119803
120276
  agentRegistry.setApprovalChangeCallback(refreshFromRegistry);
119804
120277
  const memoryListener = /* @__PURE__ */ __name(() => {
119805
120278
  const dreams = memoryManager.listTasksByType("dream", projectRoot);
@@ -119814,6 +120287,7 @@ function useBackgroundTaskView(config) {
119814
120287
  agentRegistry.setStatusChangeCallback(void 0);
119815
120288
  shellRegistry.setStatusChangeCallback(void 0);
119816
120289
  monitorRegistry.setStatusChangeCallback(void 0);
120290
+ workflowRegistry.setStatusChangeCallback(void 0);
119817
120291
  agentRegistry.setApprovalChangeCallback(void 0);
119818
120292
  unsubscribeMemory();
119819
120293
  };
@@ -119948,6 +120422,9 @@ function BackgroundTaskViewProvider({
119948
120422
  }
119949
120423
  break;
119950
120424
  }
120425
+ case "workflow":
120426
+ config.getWorkflowRunRegistry().cancel(target.runId, Date.now());
120427
+ break;
119951
120428
  default: {
119952
120429
  const _exhaustive = target;
119953
120430
  throw new Error(
@@ -120124,6 +120601,12 @@ function rowLabel(entry) {
120124
120601
  return `${SHELL_ROW_PREFIX} ${entry.command}`;
120125
120602
  case "monitor":
120126
120603
  return `[monitor] ${entry.description}`;
120604
+ case "workflow": {
120605
+ const label = entry.meta?.name ?? entry.runId;
120606
+ const phase = entry.currentPhase ? ` \xB7 ${entry.currentPhase}` : "";
120607
+ const counts = entry.agentsDispatched > 0 ? ` (${entry.agentsCompleted}/${entry.agentsDispatched})` : "";
120608
+ return `[workflow] ${label}${phase}${counts}`;
120609
+ }
120127
120610
  case "dream":
120128
120611
  return formatDreamRowLabel(entry);
120129
120612
  default: {
@@ -120238,6 +120721,15 @@ var DetailBody = /* @__PURE__ */ __name(({ entry, maxHeight, maxWidth }) => {
120238
120721
  maxWidth
120239
120722
  }
120240
120723
  );
120724
+ case "workflow":
120725
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
120726
+ WorkflowDetailBody,
120727
+ {
120728
+ entry,
120729
+ maxHeight,
120730
+ maxWidth
120731
+ }
120732
+ );
120241
120733
  case "dream":
120242
120734
  return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
120243
120735
  DreamDetailBody,
@@ -120496,6 +120988,69 @@ var MonitorDetailBody = /* @__PURE__ */ __name(({ entry, maxHeight, maxWidth })
120496
120988
  }
120497
120989
  );
120498
120990
  }, "MonitorDetailBody");
120991
+ var MAX_VISIBLE_PHASES = 20;
120992
+ var MAX_VISIBLE_LOG_LINES = 10;
120993
+ var WorkflowDetailBody = /* @__PURE__ */ __name(({ entry, maxHeight, maxWidth }) => {
120994
+ const title = `${t("Workflow")} \u203A ${entry.meta?.name ?? entry.runId}`;
120995
+ const terminal = terminalStatusPresentation(entry.status);
120996
+ const dimSubtitleParts = [elapsedFor(entry)];
120997
+ if (entry.agentsDispatched > 0) {
120998
+ dimSubtitleParts.push(
120999
+ `${entry.agentsCompleted}/${entry.agentsDispatched} ${t("agents")}`
121000
+ );
121001
+ }
121002
+ dimSubtitleParts.push(
121003
+ `${entry.phases.length} ${entry.phases.length === 1 ? t("phase") : t("phases")}`
121004
+ );
121005
+ const phaseOverflow = Math.max(0, entry.phases.length - MAX_VISIBLE_PHASES);
121006
+ const visiblePhases = entry.phases.slice(-MAX_VISIBLE_PHASES);
121007
+ const logOverflow = Math.max(
121008
+ 0,
121009
+ entry.recentLogs.length - MAX_VISIBLE_LOG_LINES
121010
+ );
121011
+ const visibleLogs = entry.recentLogs.slice(-MAX_VISIBLE_LOG_LINES);
121012
+ const hasError = Boolean(entry.error);
121013
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(
121014
+ MaxSizedBox,
121015
+ {
121016
+ maxHeight,
121017
+ maxWidth,
121018
+ overflowDirection: "bottom",
121019
+ children: [
121020
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { bold: true, color: theme.text.accent, children: title }) }),
121021
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(Box_default, { children: [
121022
+ terminal && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { color: terminal.color, children: `${terminal.icon} ${statusVerb(entry.status)} \xB7 ` }),
121023
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { color: theme.text.secondary, children: dimSubtitleParts.join(" \xB7 ") })
121024
+ ] }),
121025
+ entry.meta?.description && /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_react149.Fragment, { children: [
121026
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, {}),
121027
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { wrap: "wrap", children: entry.meta.description }) })
121028
+ ] }),
121029
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, {}),
121030
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { bold: true, dimColor: true, children: t("Phases") }) }),
121031
+ entry.phases.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { dimColor: true, children: t("(no phase recorded yet)") }) }) : /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_react149.Fragment, { children: [
121032
+ phaseOverflow > 0 && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { dimColor: true, children: `+${phaseOverflow} ${t("more above")}` }) }),
121033
+ visiblePhases.map((phaseTitle, i) => {
121034
+ const isCurrent = entry.status === "running" && i === visiblePhases.length - 1 && entry.currentPhase === phaseTitle;
121035
+ const marker = isCurrent ? "\u25B8" : "\xB7";
121036
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { color: isCurrent ? theme.status.success : void 0, children: ` ${marker} ${phaseTitle}` }) }, `${phaseTitle}-${i}`);
121037
+ })
121038
+ ] }),
121039
+ entry.recentLogs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_react149.Fragment, { children: [
121040
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, {}),
121041
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { bold: true, dimColor: true, children: t("Logs") }) }),
121042
+ logOverflow > 0 && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { dimColor: true, children: `+${logOverflow} ${t("more above")}` }) }),
121043
+ visibleLogs.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { wrap: "truncate-end", dimColor: true, children: line }) }, `log-${i}`))
121044
+ ] }),
121045
+ hasError && /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_react149.Fragment, { children: [
121046
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, {}),
121047
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { bold: true, color: theme.status.error, children: t("Error") }) }),
121048
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { color: theme.status.error, wrap: "wrap", children: entry.error }) })
121049
+ ] })
121050
+ ]
121051
+ }
121052
+ );
121053
+ }, "WorkflowDetailBody");
120499
121054
  var BackgroundTasksDialog = /* @__PURE__ */ __name(({
120500
121055
  availableTerminalHeight,
120501
121056
  terminalWidth
@@ -121318,7 +121873,6 @@ var LoadingIndicator = /* @__PURE__ */ __name(({
121318
121873
  currentLoadingPhrase,
121319
121874
  elapsedTime,
121320
121875
  rightContent,
121321
- thought,
121322
121876
  candidatesTokens,
121323
121877
  streamingCharsRef,
121324
121878
  isStreaming,
@@ -121335,7 +121889,7 @@ var LoadingIndicator = /* @__PURE__ */ __name(({
121335
121889
  if (streamingState === "idle" /* Idle */) {
121336
121890
  return null;
121337
121891
  }
121338
- const primaryText = thought?.subject || currentLoadingPhrase;
121892
+ const primaryText = currentLoadingPhrase;
121339
121893
  const streamingTokens = streamingCharsRef ? Math.round(animatedChars / 4) : 0;
121340
121894
  const outputTokens = (candidatesTokens ?? 0) + streamingTokens;
121341
121895
  const showTokens = !isNarrow && outputTokens > 0;
@@ -121457,6 +122011,10 @@ var PrepareLabel = import_react152.default.memo(_PrepareLabel);
121457
122011
  // packages/cli/src/ui/components/SuggestionsDisplay.tsx
121458
122012
  var import_jsx_runtime150 = __toESM(require_jsx_runtime(), 1);
121459
122013
  var MAX_SUGGESTIONS_TO_SHOW = 8;
122014
+ function normalizeDescription(description) {
122015
+ return description.replace(/\s+/g, " ").trim();
122016
+ }
122017
+ __name(normalizeDescription, "normalizeDescription");
121460
122018
  function SuggestionsDisplay({
121461
122019
  suggestions,
121462
122020
  activeIndex,
@@ -121533,7 +122091,7 @@ function SuggestionsDisplay({
121533
122091
  flexGrow: 1,
121534
122092
  flexShrink: 1,
121535
122093
  paddingLeft: 2,
121536
- children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Text, { color: textColor, wrap: "wrap", children: suggestion.description })
122094
+ children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Text, { color: textColor, wrap: "truncate-end", children: normalizeDescription(suggestion.description) })
121537
122095
  }
121538
122096
  ),
121539
122097
  isActive && isLong && /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Text, { color: Colors.Gray, children: isExpanded ? " \u2190 " : " \u2192 " }) })
@@ -125056,6 +125614,7 @@ var KIND_NAMES = {
125056
125614
  agent: { singular: "local agent", plural: "local agents" },
125057
125615
  shell: { singular: "shell", plural: "shells" },
125058
125616
  monitor: { singular: "monitor", plural: "monitors" },
125617
+ workflow: { singular: "workflow", plural: "workflows" },
125059
125618
  dream: { singular: "dream", plural: "dreams" }
125060
125619
  };
125061
125620
  function hasPendingApproval(entries) {
@@ -125080,12 +125639,13 @@ function getPillLabel(entries) {
125080
125639
  }
125081
125640
  __name(getPillLabel, "getPillLabel");
125082
125641
  function groupAndFormat(entries) {
125083
- const counts = { agent: 0, shell: 0, monitor: 0, dream: 0 };
125642
+ const counts = { agent: 0, shell: 0, monitor: 0, workflow: 0, dream: 0 };
125084
125643
  for (const e of entries) counts[e.kind]++;
125085
125644
  const parts = [];
125086
125645
  if (counts.shell > 0) parts.push(formatCount("shell", counts.shell));
125087
125646
  if (counts.agent > 0) parts.push(formatCount("agent", counts.agent));
125088
125647
  if (counts.monitor > 0) parts.push(formatCount("monitor", counts.monitor));
125648
+ if (counts.workflow > 0) parts.push(formatCount("workflow", counts.workflow));
125089
125649
  if (counts.dream > 0) parts.push(formatCount("dream", counts.dream));
125090
125650
  return parts.join(", ");
125091
125651
  }
@@ -125994,7 +126554,6 @@ var Composer = /* @__PURE__ */ __name(() => {
125994
126554
  !uiState.embeddedShellFocused && !suppressBottomLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime164.jsx)(
125995
126555
  LoadingIndicator,
125996
126556
  {
125997
- thought: uiState.streamingState === "waiting_for_confirmation" /* WaitingForConfirmation */ || config.getAccessibility()?.enableLoadingPhrases === false ? void 0 : uiState.thought,
125998
126557
  currentLoadingPhrase: config.getAccessibility()?.enableLoadingPhrases === false ? void 0 : uiState.currentLoadingPhrase,
125999
126558
  elapsedTime: uiState.elapsedTime,
126000
126559
  candidatesTokens: agentTokens,
@@ -127444,12 +128003,12 @@ import process38 from "node:process";
127444
128003
  init_esbuild_shims();
127445
128004
  var import_react184 = __toESM(require_react(), 1);
127446
128005
  import process25 from "node:process";
127447
- import os21 from "node:os";
128006
+ import os20 from "node:os";
127448
128007
  import v82 from "v8";
127449
128008
  var debugLogger61 = createDebugLogger("MEMORY_MONITOR");
127450
128009
  var MEMORY_WARNING_THRESHOLD = Math.min(
127451
128010
  7 * 1024 * 1024 * 1024,
127452
- Math.floor(os21.totalmem() * 0.85)
128011
+ Math.floor(os20.totalmem() * 0.85)
127453
128012
  );
127454
128013
  var MEMORY_UI_COMPACT_THRESHOLD = /* @__PURE__ */ __name(() => Math.floor(v82.getHeapStatistics().heap_size_limit * 0.65), "MEMORY_UI_COMPACT_THRESHOLD");
127455
128014
  var MEMORY_CHECK_INTERVAL = 60 * 1e3;
@@ -129161,7 +129720,7 @@ init_esbuild_shims();
129161
129720
  var import_react198 = __toESM(require_react(), 1);
129162
129721
  import crypto4 from "node:crypto";
129163
129722
  import path42 from "node:path";
129164
- import os22 from "node:os";
129723
+ import os21 from "node:os";
129165
129724
  import fs36 from "node:fs";
129166
129725
  var OUTPUT_UPDATE_INTERVAL_MS = 1e3;
129167
129726
  var MAX_OUTPUT_LENGTH = 1e4;
@@ -129199,14 +129758,14 @@ var useShellCommandProcessor = /* @__PURE__ */ __name((addItemToHistory, setPend
129199
129758
  { type: "user_shell", text: rawQuery },
129200
129759
  userMessageTimestamp
129201
129760
  );
129202
- const isWindows4 = os22.platform() === "win32";
129761
+ const isWindows4 = os21.platform() === "win32";
129203
129762
  const targetDir = config.getTargetDir();
129204
129763
  let commandToExecute = rawQuery;
129205
129764
  let pwdFilePath;
129206
129765
  if (!isWindows4) {
129207
129766
  let command2 = rawQuery.trim();
129208
129767
  const pwdFileName = `shell_pwd_${crypto4.randomBytes(6).toString("hex")}.tmp`;
129209
- pwdFilePath = path42.join(os22.tmpdir(), pwdFileName);
129768
+ pwdFilePath = path42.join(os21.tmpdir(), pwdFileName);
129210
129769
  if (!command2.endsWith(";") && !command2.endsWith("&")) {
129211
129770
  command2 += ";";
129212
129771
  }
@@ -129882,6 +130441,8 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
129882
130441
  }, [history]);
129883
130442
  const summaryAbortRefsRef = (0, import_react202.useRef)(/* @__PURE__ */ new Set());
129884
130443
  const [pendingHistoryItem, pendingHistoryItemRef, setPendingHistoryItem] = useStateAndRef(null);
130444
+ const [pendingThoughtItem, pendingThoughtItemRef, setPendingThoughtItem] = useStateAndRef(null);
130445
+ const thoughtStartTimeRef = (0, import_react202.useRef)(null);
129885
130446
  const [
129886
130447
  pendingRetryErrorItem,
129887
130448
  pendingRetryErrorItemRef,
@@ -130294,7 +130855,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130294
130855
  [setThought]
130295
130856
  );
130296
130857
  const handleThoughtEvent = (0, import_react202.useCallback)(
130297
- (eventValue, currentThoughtBuffer, userMessageTimestamp) => {
130858
+ (eventValue, currentThoughtBuffer) => {
130298
130859
  if (turnCancelledRef.current) {
130299
130860
  return "";
130300
130861
  }
@@ -130302,56 +130863,41 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130302
130863
  if (!thoughtText) {
130303
130864
  return currentThoughtBuffer;
130304
130865
  }
130305
- let newThoughtBuffer = currentThoughtBuffer + thoughtText;
130306
- if (debugLogger66.isEnabled()) {
130307
- debugLogger66.debug(
130308
- `[THOUGHT_BUFFER] Buffer growing: current=${currentThoughtBuffer.length}, incoming=${thoughtText.length}, total=${newThoughtBuffer.length}`
130309
- );
130866
+ const newThoughtBuffer = currentThoughtBuffer + thoughtText;
130867
+ if (newThoughtBuffer.trim().length === 0) {
130868
+ return newThoughtBuffer;
130310
130869
  }
130311
- const pendingType = pendingHistoryItemRef.current?.type;
130312
- const isPendingThought = pendingType === "gemini_thought" || pendingType === "gemini_thought_content";
130313
- let thoughtToMerge = eventValue;
130314
- if (!isPendingThought) {
130315
- if (newThoughtBuffer.trim().length === 0) {
130316
- return newThoughtBuffer;
130317
- }
130318
- if (pendingHistoryItemRef.current) {
130319
- addItem(pendingHistoryItemRef.current, userMessageTimestamp);
130320
- }
130321
- newThoughtBuffer = stripLeadingBlankLines(newThoughtBuffer);
130322
- thoughtToMerge = {
130323
- ...eventValue,
130324
- description: newThoughtBuffer
130325
- };
130326
- setPendingHistoryItem({ type: "gemini_thought", text: "" });
130870
+ const startingNewThought = currentThoughtBuffer.trim().length === 0;
130871
+ const description = startingNewThought ? stripLeadingBlankLines(newThoughtBuffer) : thoughtText;
130872
+ if (startingNewThought) {
130873
+ thoughtStartTimeRef.current = Date.now();
130327
130874
  }
130328
- const splitPoint = findLastSafeSplitPoint(newThoughtBuffer);
130329
- const nextPendingType = isPendingThought && pendingType === "gemini_thought_content" ? "gemini_thought_content" : "gemini_thought";
130330
- if (splitPoint === newThoughtBuffer.length) {
130331
- setPendingHistoryItem({
130332
- type: nextPendingType,
130333
- text: newThoughtBuffer
130334
- });
130335
- } else {
130336
- const beforeText = newThoughtBuffer.substring(0, splitPoint);
130337
- const afterText = newThoughtBuffer.substring(splitPoint);
130338
- addItem(
130339
- {
130340
- type: nextPendingType,
130341
- text: beforeText
130342
- },
130343
- userMessageTimestamp
130344
- );
130345
- setPendingHistoryItem({
130346
- type: "gemini_thought_content",
130347
- text: afterText
130348
- });
130349
- newThoughtBuffer = afterText;
130875
+ mergeThought({
130876
+ ...eventValue,
130877
+ description
130878
+ });
130879
+ setPendingThoughtItem({
130880
+ type: "gemini_thought",
130881
+ text: stripLeadingBlankLines(newThoughtBuffer),
130882
+ durationMs: thoughtStartTimeRef.current ? Date.now() - thoughtStartTimeRef.current : 0
130883
+ });
130884
+ return startingNewThought ? description : newThoughtBuffer;
130885
+ },
130886
+ [mergeThought, setPendingThoughtItem]
130887
+ );
130888
+ const commitPendingThought = (0, import_react202.useCallback)(
130889
+ (userMessageTimestamp) => {
130890
+ if (pendingThoughtItemRef.current) {
130891
+ const item = { ...pendingThoughtItemRef.current };
130892
+ if (item.type === "gemini_thought" && thoughtStartTimeRef.current) {
130893
+ item.durationMs = Date.now() - thoughtStartTimeRef.current;
130894
+ }
130895
+ addItem(item, userMessageTimestamp);
130350
130896
  }
130351
- mergeThought(thoughtToMerge);
130352
- return newThoughtBuffer;
130897
+ setPendingThoughtItem(null);
130898
+ thoughtStartTimeRef.current = null;
130353
130899
  },
130354
- [addItem, pendingHistoryItemRef, setPendingHistoryItem, mergeThought]
130900
+ [addItem, pendingThoughtItemRef, setPendingThoughtItem]
130355
130901
  );
130356
130902
  const handleUserCancelledEvent = (0, import_react202.useCallback)(
130357
130903
  (userMessageTimestamp) => {
@@ -130359,6 +130905,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130359
130905
  return;
130360
130906
  }
130361
130907
  lastPromptErroredRef.current = false;
130908
+ commitPendingThought(userMessageTimestamp);
130362
130909
  if (pendingHistoryItemRef.current) {
130363
130910
  if (pendingHistoryItemRef.current.type === "tool_group") {
130364
130911
  const updatedTools = pendingHistoryItemRef.current.tools.map(
@@ -130384,6 +130931,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130384
130931
  },
130385
130932
  [
130386
130933
  addItem,
130934
+ commitPendingThought,
130387
130935
  pendingHistoryItemRef,
130388
130936
  setPendingHistoryItem,
130389
130937
  setThought,
@@ -130393,6 +130941,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130393
130941
  const handleErrorEvent = (0, import_react202.useCallback)(
130394
130942
  (eventValue, userMessageTimestamp) => {
130395
130943
  lastPromptErroredRef.current = true;
130944
+ commitPendingThought(userMessageTimestamp);
130396
130945
  if (pendingHistoryItemRef.current) {
130397
130946
  addItem(pendingHistoryItemRef.current, userMessageTimestamp);
130398
130947
  setPendingHistoryItem(null);
@@ -130423,6 +130972,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130423
130972
  },
130424
130973
  [
130425
130974
  addItem,
130975
+ commitPendingThought,
130426
130976
  pendingHistoryItemRef,
130427
130977
  setPendingHistoryItem,
130428
130978
  setPendingRetryErrorItem,
@@ -130673,11 +131223,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130673
131223
  description: `${mergedThought.description ?? ""}${queuedThought.value.description ?? ""}`
130674
131224
  };
130675
131225
  }
130676
- thoughtBuffer = handleThoughtEvent(
130677
- mergedThought,
130678
- thoughtBuffer,
130679
- userMessageTimestamp
130680
- );
131226
+ thoughtBuffer = handleThoughtEvent(mergedThought, thoughtBuffer);
130681
131227
  }
130682
131228
  }, "flushBufferedStreamEvents");
130683
131229
  const scheduleBufferedStreamFlush = /* @__PURE__ */ __name(() => {
@@ -130704,11 +131250,20 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130704
131250
  }
130705
131251
  break;
130706
131252
  case "content" /* Content */:
131253
+ if (pendingThoughtItemRef.current || bufferedEvents.some((e) => e.kind === "thought")) {
131254
+ flushBufferedStreamEvents();
131255
+ commitPendingThought(userMessageTimestamp);
131256
+ thoughtBuffer = "";
131257
+ }
131258
+ setThought((prev) => prev ? null : prev);
130707
131259
  bufferedEvents.push({ kind: "content", value: event.value });
130708
131260
  scheduleBufferedStreamFlush();
130709
131261
  break;
130710
131262
  case "tool_call_request" /* ToolCallRequest */:
130711
131263
  flushBufferedStreamEvents();
131264
+ commitPendingThought(userMessageTimestamp);
131265
+ thoughtBuffer = "";
131266
+ setThought((prev) => prev ? null : prev);
130712
131267
  toolCallRequests.push(event.value);
130713
131268
  try {
130714
131269
  const argsJson = JSON.stringify(event.value.args);
@@ -130743,6 +131298,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130743
131298
  break;
130744
131299
  case "finished" /* Finished */:
130745
131300
  flushBufferedStreamEvents();
131301
+ commitPendingThought(userMessageTimestamp);
130746
131302
  handleFinishedEvent(
130747
131303
  event,
130748
131304
  userMessageTimestamp
@@ -130753,6 +131309,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130753
131309
  }
130754
131310
  geminiMessageBuffer = "";
130755
131311
  thoughtBuffer = "";
131312
+ setThought(null);
130756
131313
  break;
130757
131314
  case "citation" /* Citation */:
130758
131315
  flushBufferedStreamEvents();
@@ -130768,8 +131325,10 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130768
131325
  if (pendingHistoryItemRef.current) {
130769
131326
  setPendingHistoryItem(null);
130770
131327
  }
130771
- geminiMessageBuffer = "";
131328
+ commitPendingThought(userMessageTimestamp);
130772
131329
  thoughtBuffer = "";
131330
+ setThought(null);
131331
+ geminiMessageBuffer = "";
130773
131332
  } else {
130774
131333
  flushBufferedStreamEvents();
130775
131334
  }
@@ -130816,6 +131375,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130816
131375
  }
130817
131376
  } finally {
130818
131377
  flushBufferedStreamEvents();
131378
+ commitPendingThought(userMessageTimestamp);
130819
131379
  discardBufferedStreamEvents();
130820
131380
  flushBufferedStreamEventsRef.current.delete(flushBufferedStreamEvents);
130821
131381
  }
@@ -130839,7 +131399,9 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130839
131399
  startRetryCountdown,
130840
131400
  clearRetryCountdown,
130841
131401
  setThought,
131402
+ commitPendingThought,
130842
131403
  pendingHistoryItemRef,
131404
+ pendingThoughtItemRef,
130843
131405
  setPendingHistoryItem,
130844
131406
  handleUserPromptSubmitBlockedEvent,
130845
131407
  handleStopHookLoopEvent,
@@ -130926,6 +131488,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130926
131488
  );
130927
131489
  }
130928
131490
  setThought(null);
131491
+ setPendingThoughtItem(null);
130929
131492
  }
130930
131493
  if (submitType === "retry" /* Retry */) {
130931
131494
  logUserRetry(config, new UserRetryEvent(prompt_id));
@@ -131047,6 +131610,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
131047
131610
  pendingRetryCountdownItemRef,
131048
131611
  pendingRetryErrorItemRef,
131049
131612
  setPendingRetryErrorItem,
131613
+ setPendingThoughtItem,
131050
131614
  dualOutput
131051
131615
  ]
131052
131616
  );
@@ -131289,12 +131853,15 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
131289
131853
  );
131290
131854
  const pendingHistoryItems = (0, import_react202.useMemo)(
131291
131855
  () => [
131856
+ // Reasoning renders above the streaming answer.
131857
+ pendingThoughtItem,
131292
131858
  pendingHistoryItem,
131293
131859
  pendingRetryErrorItem,
131294
131860
  pendingRetryCountdownItem,
131295
131861
  pendingToolCallGroupDisplay
131296
131862
  ].filter((i) => i !== void 0 && i !== null),
131297
131863
  [
131864
+ pendingThoughtItem,
131298
131865
  pendingHistoryItem,
131299
131866
  pendingRetryErrorItem,
131300
131867
  pendingRetryCountdownItem,
@@ -131439,7 +132006,11 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
131439
132006
  }, [config]);
131440
132007
  (0, import_react202.useEffect)(() => {
131441
132008
  const registry2 = config.getMonitorRegistry();
131442
- registry2.setNotificationCallback((displayText, modelText) => {
132009
+ registry2.setNotificationCallback((displayText, modelText, meta) => {
132010
+ if (meta.status === "running" && typeof registry2.get === "function") {
132011
+ const entry = registry2.get(meta.monitorId);
132012
+ if (!entry || entry.status !== "running") return;
132013
+ }
131443
132014
  notificationQueueRef.current.push({
131444
132015
  displayText,
131445
132016
  modelText,
@@ -131453,13 +132024,32 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
131453
132024
  }, [config]);
131454
132025
  (0, import_react202.useEffect)(() => {
131455
132026
  if (streamingState === "idle" /* Idle */ && !isSubmittingQueryRef.current && notificationQueueRef.current.length > 0) {
131456
- const item = notificationQueueRef.current.shift();
131457
- addItem(
131458
- { type: "notification", text: item.displayText },
131459
- Date.now()
131460
- );
131461
- submitQuery(item.modelText, item.sendMessageType, void 0, {
131462
- notificationDisplayText: item.displayText
132027
+ const queue = notificationQueueRef.current;
132028
+ const targetType = queue[0].sendMessageType;
132029
+ if (targetType === "cron" /* Cron */) {
132030
+ const item = queue.shift();
132031
+ addItem(
132032
+ { type: "notification", text: item.displayText },
132033
+ Date.now()
132034
+ );
132035
+ submitQuery(item.modelText, item.sendMessageType, void 0, {
132036
+ notificationDisplayText: item.displayText
132037
+ });
132038
+ return;
132039
+ }
132040
+ let splitIdx = 0;
132041
+ while (splitIdx < queue.length && queue[splitIdx].sendMessageType === targetType) {
132042
+ splitIdx++;
132043
+ }
132044
+ const batch = queue.splice(0, splitIdx);
132045
+ const now = Date.now();
132046
+ for (const item of batch) {
132047
+ addItem({ type: "notification", text: item.displayText }, now);
132048
+ }
132049
+ const combinedModelText = batch.map((e) => e.modelText).join("\n\n");
132050
+ const combinedDisplayText = batch.map((e) => e.displayText).join("; ");
132051
+ submitQuery(combinedModelText, targetType, void 0, {
132052
+ notificationDisplayText: combinedDisplayText
131463
132053
  });
131464
132054
  }
131465
132055
  }, [streamingState, submitQuery, notificationTrigger, addItem]);
@@ -133706,13 +134296,13 @@ import { format as format3 } from "node:util";
133706
134296
  init_esbuild_shims();
133707
134297
  var import_graceful_fs = __toESM(require_graceful_fs(), 1);
133708
134298
  import path49 from "node:path";
133709
- import os25 from "node:os";
134299
+ import os24 from "node:os";
133710
134300
 
133711
134301
  // node_modules/xdg-basedir/index.js
133712
134302
  init_esbuild_shims();
133713
- import os23 from "os";
134303
+ import os22 from "os";
133714
134304
  import path46 from "path";
133715
- var homeDirectory = os23.homedir();
134305
+ var homeDirectory = os22.homedir();
133716
134306
  var { env: env3 } = process;
133717
134307
  var xdgData = env3.XDG_DATA_HOME || (homeDirectory ? path46.join(homeDirectory, ".local", "share") : void 0);
133718
134308
  var xdgConfig = env3.XDG_CONFIG_HOME || (homeDirectory ? path46.join(homeDirectory, ".config") : void 0);
@@ -133947,14 +134537,14 @@ var dist_default6 = FS;
133947
134537
 
133948
134538
  // node_modules/atomically/dist/constants.js
133949
134539
  init_esbuild_shims();
133950
- import os24 from "node:os";
134540
+ import os23 from "node:os";
133951
134541
  import process30 from "node:process";
133952
134542
  var DEFAULT_ENCODING = "utf8";
133953
134543
  var DEFAULT_FILE_MODE = 438;
133954
134544
  var DEFAULT_FOLDER_MODE = 511;
133955
134545
  var DEFAULT_WRITE_OPTIONS = {};
133956
- var DEFAULT_USER_UID = os24.userInfo().uid;
133957
- var DEFAULT_USER_GID = os24.userInfo().gid;
134546
+ var DEFAULT_USER_UID = os23.userInfo().uid;
134547
+ var DEFAULT_USER_GID = os23.userInfo().gid;
133958
134548
  var DEFAULT_TIMEOUT_SYNC = 1e3;
133959
134549
  var IS_POSIX = !!process30.getuid;
133960
134550
  var IS_USER_ROOT2 = process30.getuid ? !process30.getuid() : false;
@@ -134407,7 +134997,7 @@ __name(hasProperty, "hasProperty");
134407
134997
  // node_modules/configstore/index.js
134408
134998
  function getConfigDirectory(id, globalConfigPath) {
134409
134999
  const pathPrefix = globalConfigPath ? path49.join(id, "config.json") : path49.join("configstore", `${id}.json`);
134410
- const configDirectory = xdgConfig ?? import_graceful_fs.default.mkdtempSync(import_graceful_fs.default.realpathSync(os25.tmpdir()) + path49.sep);
135000
+ const configDirectory = xdgConfig ?? import_graceful_fs.default.mkdtempSync(import_graceful_fs.default.realpathSync(os24.tmpdir()) + path49.sep);
134411
135001
  return path49.join(configDirectory, pathPrefix);
134412
135002
  }
134413
135003
  __name(getConfigDirectory, "getConfigDirectory");
@@ -134686,7 +135276,7 @@ var ansi_styles_default5 = ansiStyles5;
134686
135276
  // node_modules/update-notifier/node_modules/chalk/source/vendor/supports-color/index.js
134687
135277
  init_esbuild_shims();
134688
135278
  import process33 from "node:process";
134689
- import os26 from "node:os";
135279
+ import os25 from "node:os";
134690
135280
  import tty3 from "node:tty";
134691
135281
  function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process33.argv) {
134692
135282
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
@@ -134754,7 +135344,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
134754
135344
  return min;
134755
135345
  }
134756
135346
  if (process33.platform === "win32") {
134757
- const osRelease = os26.release().split(".");
135347
+ const osRelease = os25.release().split(".");
134758
135348
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
134759
135349
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
134760
135350
  }
@@ -135751,7 +136341,7 @@ init_esbuild_shims();
135751
136341
  var import_ini = __toESM(require_ini3(), 1);
135752
136342
  import process35 from "node:process";
135753
136343
  import path50 from "node:path";
135754
- import os27 from "node:os";
136344
+ import os26 from "node:os";
135755
136345
  import fs41 from "node:fs";
135756
136346
  var isWindows3 = process35.platform === "win32";
135757
136347
  var readRc = /* @__PURE__ */ __name((filePath) => {
@@ -135786,7 +136376,7 @@ var getNpmPrefix = /* @__PURE__ */ __name(() => {
135786
136376
  if (envPrefix) {
135787
136377
  return envPrefix;
135788
136378
  }
135789
- const homePrefix = readRc(path50.join(os27.homedir(), ".npmrc"));
136379
+ const homePrefix = readRc(path50.join(os26.homedir(), ".npmrc"));
135790
136380
  if (homePrefix) {
135791
136381
  return homePrefix;
135792
136382
  }
@@ -135817,11 +136407,11 @@ var getYarnPrefix = /* @__PURE__ */ __name(() => {
135817
136407
  if (windowsPrefix) {
135818
136408
  return windowsPrefix;
135819
136409
  }
135820
- const configPrefix = path50.join(os27.homedir(), ".config/yarn");
136410
+ const configPrefix = path50.join(os26.homedir(), ".config/yarn");
135821
136411
  if (fs41.existsSync(configPrefix)) {
135822
136412
  return configPrefix;
135823
136413
  }
135824
- const homePrefix = path50.join(os27.homedir(), ".yarn-config");
136414
+ const homePrefix = path50.join(os26.homedir(), ".yarn-config");
135825
136415
  if (fs41.existsSync(homePrefix)) {
135826
136416
  return homePrefix;
135827
136417
  }
@@ -136954,7 +137544,7 @@ import { spawn as spawn6 } from "node:child_process";
136954
137544
  var spawnWrapper = spawn6;
136955
137545
 
136956
137546
  // packages/cli/src/utils/handleAutoUpdate.ts
136957
- import os28 from "node:os";
137547
+ import os27 from "node:os";
136958
137548
  var UPDATE_SUCCESS_MESSAGE = "Update successful! Please restart Qwen Code to use the new version. Switching model providers before restarting may not work correctly.";
136959
137549
  var UPDATE_FAILED_MESSAGE = "Automatic update failed. Please try updating manually.";
136960
137550
  function handleAutoUpdate(info, settings, projectRoot, spawnFn = spawnWrapper) {
@@ -136993,7 +137583,7 @@ ${installationInfo.updateMessage}`;
136993
137583
  "@latest",
136994
137584
  isNightly ? "@nightly" : `@${info.update.latest}`
136995
137585
  );
136996
- const isWindows4 = os28.platform() === "win32";
137586
+ const isWindows4 = os27.platform() === "win32";
136997
137587
  const shell = isWindows4 ? "cmd.exe" : "bash";
136998
137588
  const shellArgs = isWindows4 ? ["/c", updateCommand2] : ["-c", updateCommand2];
136999
137589
  const updateProcess = spawnFn(shell, shellArgs, { stdio: "pipe" });
@@ -138251,6 +138841,10 @@ function dedupeNewestFirst(messages) {
138251
138841
  return result;
138252
138842
  }
138253
138843
  __name(dedupeNewestFirst, "dedupeNewestFirst");
138844
+ function mergeStartupWarnings(currentWarnings, nextWarnings) {
138845
+ return [.../* @__PURE__ */ new Set([...currentWarnings, ...nextWarnings])];
138846
+ }
138847
+ __name(mergeStartupWarnings, "mergeStartupWarnings");
138254
138848
  var SHELL_WIDTH_FRACTION = 0.89;
138255
138849
  var SHELL_HEIGHT_PADDING = 10;
138256
138850
  var AppContainer = /* @__PURE__ */ __name((props) => {
@@ -138383,6 +138977,9 @@ var AppContainer = /* @__PURE__ */ __name((props) => {
138383
138977
  computeWindowTitle(basename11(config.getTargetDir()))
138384
138978
  );
138385
138979
  const lastTitleRef = (0, import_react230.useRef)(null);
138980
+ const [startupWarnings, setStartupWarnings] = (0, import_react230.useState)(
138981
+ () => props.startupWarnings || []
138982
+ );
138386
138983
  const staticExtraHeight = 3;
138387
138984
  (0, import_react230.useEffect)(() => {
138388
138985
  void loadLowlight().catch((err) => {
@@ -138395,6 +138992,9 @@ var AppContainer = /* @__PURE__ */ __name((props) => {
138395
138992
  (async () => {
138396
138993
  profileCheckpoint("config_initialize_start");
138397
138994
  await config.initialize();
138995
+ setStartupWarnings(
138996
+ (currentWarnings) => mergeStartupWarnings(currentWarnings, config.getWarnings())
138997
+ );
138398
138998
  profileCheckpoint("config_initialize_end");
138399
138999
  setConfigInitialized(true);
138400
139000
  profileCheckpoint("input_enabled");
@@ -140693,7 +141293,7 @@ ${migrationResult.failedFiles.map((f) => ` \u2022 ${f.file}: ${f.error}`).join(
140693
141293
  {
140694
141294
  value: {
140695
141295
  version: props.version,
140696
- startupWarnings: props.startupWarnings || []
141296
+ startupWarnings
140697
141297
  },
140698
141298
  children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(CompactModeProvider, { value: compactModeValue, children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(RenderModeProvider, { value: renderModeValue, children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(TerminalOutputProvider, { value: writeRaw, children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(ShellFocusContext.Provider, { value: isFocused, children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(App2, {}) }) }) }) })
140699
141299
  }
@@ -140830,7 +141430,7 @@ __name(relaunchAppInChildProcess, "relaunchAppInChildProcess");
140830
141430
  init_esbuild_shims();
140831
141431
  var import_shell_quote = __toESM(require_shell_quote(), 1);
140832
141432
  import { exec as exec7, execSync as execSync5, spawn as spawn8 } from "node:child_process";
140833
- import os29 from "node:os";
141433
+ import os28 from "node:os";
140834
141434
  import path56 from "node:path";
140835
141435
  import fs46 from "node:fs";
140836
141436
  import { fileURLToPath as fileURLToPath4 } from "node:url";
@@ -140838,7 +141438,7 @@ import { promisify as promisify3 } from "node:util";
140838
141438
  import { randomBytes } from "node:crypto";
140839
141439
  var execAsync2 = promisify3(exec7);
140840
141440
  function getContainerPath(hostPath) {
140841
- if (os29.platform() !== "win32") {
141441
+ if (os28.platform() !== "win32") {
140842
141442
  return hostPath;
140843
141443
  }
140844
141444
  const withForwardSlashes = hostPath.replace(/\\/g, "/");
@@ -140875,7 +141475,7 @@ async function shouldUseCurrentUserInSandbox() {
140875
141475
  if (envVar === "0" || envVar === "false") {
140876
141476
  return false;
140877
141477
  }
140878
- if (os29.platform() === "linux") {
141478
+ if (os28.platform() === "linux") {
140879
141479
  const debugEnv = [process.env["DEBUG"], process.env["DEBUG_MODE"]].some(
140880
141480
  (v) => v === "true" || v === "1"
140881
141481
  );
@@ -140900,7 +141500,7 @@ function ports() {
140900
141500
  }
140901
141501
  __name(ports, "ports");
140902
141502
  function entrypoint(workdir, cliArgs) {
140903
- const isWindows4 = os29.platform() === "win32";
141503
+ const isWindows4 = os28.platform() === "win32";
140904
141504
  const containerWorkdir = getContainerPath(workdir);
140905
141505
  const shellCmds = [];
140906
141506
  const pathSeparator = isWindows4 ? ";" : ":";
@@ -140983,9 +141583,9 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
140983
141583
  "-D",
140984
141584
  `TARGET_DIR=${fs46.realpathSync(process.cwd())}`,
140985
141585
  "-D",
140986
- `TMP_DIR=${fs46.realpathSync(os29.tmpdir())}`,
141586
+ `TMP_DIR=${fs46.realpathSync(os28.tmpdir())}`,
140987
141587
  "-D",
140988
- `HOME_DIR=${fs46.realpathSync(os29.homedir())}`,
141588
+ `HOME_DIR=${fs46.realpathSync(os28.homedir())}`,
140989
141589
  "-D",
140990
141590
  `CACHE_DIR=${fs46.realpathSync(execSync5(`getconf DARWIN_USER_CACHE_DIR`).toString().trim())}`,
140991
141591
  "-D",
@@ -141181,8 +141781,8 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141181
141781
  if (!runtimeSameAsUserSettings) {
141182
141782
  args.push("--env", `QWEN_RUNTIME_DIR=${runtimeBaseDirContainerPath}`);
141183
141783
  }
141184
- args.push("--volume", `${os29.tmpdir()}:${getContainerPath(os29.tmpdir())}`);
141185
- const gcloudConfigDir = path56.join(os29.homedir(), ".config", "gcloud");
141784
+ args.push("--volume", `${os28.tmpdir()}:${getContainerPath(os28.tmpdir())}`);
141785
+ const gcloudConfigDir = path56.join(os28.homedir(), ".config", "gcloud");
141186
141786
  if (fs46.existsSync(gcloudConfigDir)) {
141187
141787
  args.push(
141188
141788
  "--volume",
@@ -141393,7 +141993,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141393
141993
  }
141394
141994
  args.push("--env", `SANDBOX=${containerName}`);
141395
141995
  if (config.command === "podman") {
141396
- const emptyAuthFilePath = path56.join(os29.tmpdir(), "empty_auth.json");
141996
+ const emptyAuthFilePath = path56.join(os28.tmpdir(), "empty_auth.json");
141397
141997
  fs46.writeFileSync(emptyAuthFilePath, "{}", "utf-8");
141398
141998
  args.push("--authfile", emptyAuthFilePath);
141399
141999
  }
@@ -141405,7 +142005,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141405
142005
  const uid = execSync5("id -u").toString().trim();
141406
142006
  const gid = execSync5("id -g").toString().trim();
141407
142007
  const username = "qwen";
141408
- const homeDir = getContainerPath(os29.homedir());
142008
+ const homeDir = getContainerPath(os28.homedir());
141409
142009
  const setupUserCommands = [
141410
142010
  // Use -f with groupadd to avoid errors if the group already exists.
141411
142011
  `groupadd -f -g ${gid} ${username}`,
@@ -141417,7 +142017,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141417
142017
  const suCommand = `su -p ${username} -c '${escapedOriginalCommand}'`;
141418
142018
  finalEntrypoint[2] = `${setupUserCommands} && ${suCommand}`;
141419
142019
  userFlag = `--user ${uid}:${gid}`;
141420
- args.push("--env", `HOME=${os29.homedir()}`);
142020
+ args.push("--env", `HOME=${os28.homedir()}`);
141421
142021
  } else if (isIntegrationTest) {
141422
142022
  args.push("--user", "root");
141423
142023
  userFlag = "--user root";
@@ -141428,7 +142028,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141428
142028
  let sandboxProcess = void 0;
141429
142029
  if (proxyCommand) {
141430
142030
  const proxyContainerCommand = `${config.command} run --rm --init ${userFlag} --name ${SANDBOX_PROXY_NAME} --network ${SANDBOX_PROXY_NAME} -p 8877:8877 -v ${process.cwd()}:${workdir} --workdir ${workdir} ${image2} ${proxyCommand}`;
141431
- const isWindows4 = os29.platform() === "win32";
142031
+ const isWindows4 = os28.platform() === "win32";
141432
142032
  const proxyShell = isWindows4 ? "cmd.exe" : "bash";
141433
142033
  const proxyShellArgs = isWindows4 ? ["/c", proxyContainerCommand] : ["-c", proxyContainerCommand];
141434
142034
  proxyProcess = spawn8(proxyShell, proxyShellArgs, {
@@ -141594,9 +142194,9 @@ __name(ensureSandboxImageIsPresent, "ensureSandboxImageIsPresent");
141594
142194
  // packages/cli/src/utils/startupWarnings.ts
141595
142195
  init_esbuild_shims();
141596
142196
  import fs47 from "node:fs/promises";
141597
- import os30 from "node:os";
142197
+ import os29 from "node:os";
141598
142198
  import { join as pathJoin } from "node:path";
141599
- var warningsFilePath = pathJoin(os30.tmpdir(), "qwen-code-warnings.txt");
142199
+ var warningsFilePath = pathJoin(os29.tmpdir(), "qwen-code-warnings.txt");
141600
142200
  async function getStartupWarnings() {
141601
142201
  try {
141602
142202
  await fs47.access(warningsFilePath);
@@ -141620,7 +142220,7 @@ __name(getStartupWarnings, "getStartupWarnings");
141620
142220
  // packages/cli/src/utils/userStartupWarnings.ts
141621
142221
  init_esbuild_shims();
141622
142222
  import fs48 from "node:fs/promises";
141623
- import * as os31 from "node:os";
142223
+ import * as os30 from "node:os";
141624
142224
  import path57 from "node:path";
141625
142225
  var homeDirectoryCheck = {
141626
142226
  id: "home-directory",
@@ -141628,7 +142228,7 @@ var homeDirectoryCheck = {
141628
142228
  try {
141629
142229
  const [workspaceRealPath, homeRealPath] = await Promise.all([
141630
142230
  fs48.realpath(options.workspaceRoot),
141631
- fs48.realpath(os31.homedir())
142231
+ fs48.realpath(os30.homedir())
141632
142232
  ]);
141633
142233
  if (workspaceRealPath === homeRealPath) {
141634
142234
  return "You are running Qwen Code in your home directory. It is recommended to run in a project-specific directory.";
@@ -143148,9 +143748,10 @@ __name(toPermissionOptions, "toPermissionOptions");
143148
143748
  // packages/cli/src/acp-integration/session/SubAgentTracker.ts
143149
143749
  var debugLogger75 = createDebugLogger("ACP_SUBAGENT_TRACKER");
143150
143750
  var SubAgentTracker = class {
143151
- constructor(ctx, client, parentToolCallId, subagentType) {
143751
+ constructor(ctx, client, parentToolCallId, subagentType, onAskUserQuestionCancel) {
143152
143752
  this.ctx = ctx;
143153
143753
  this.client = client;
143754
+ this.onAskUserQuestionCancel = onAskUserQuestionCancel;
143154
143755
  this.toolCallEmitter = new ToolCallEmitter(ctx);
143155
143756
  this.messageEmitter = new MessageEmitter(ctx);
143156
143757
  this.subagentMeta = { parentToolCallId, subagentType };
@@ -143280,12 +143881,25 @@ var SubAgentTracker = class {
143280
143881
  await event.respond(outcome, {
143281
143882
  answers: "answers" in output ? output.answers : void 0
143282
143883
  });
143884
+ if (outcome === "cancel" /* Cancel */ && event.name === ToolNames.ASK_USER_QUESTION) {
143885
+ this.onAskUserQuestionCancel?.();
143886
+ }
143283
143887
  } catch (error) {
143284
143888
  debugLogger75.error(
143285
143889
  `Permission request failed for subagent tool ${event.name}:`,
143286
143890
  error
143287
143891
  );
143288
- await event.respond("cancel" /* Cancel */);
143892
+ if (event.name === ToolNames.ASK_USER_QUESTION) {
143893
+ this.onAskUserQuestionCancel?.();
143894
+ }
143895
+ try {
143896
+ await event.respond("cancel" /* Cancel */);
143897
+ } catch (respondError) {
143898
+ debugLogger75.error(
143899
+ `Failed to cancel subagent tool ${event.name} after permission request failure:`,
143900
+ respondError
143901
+ );
143902
+ }
143289
143903
  }
143290
143904
  };
143291
143905
  }
@@ -143651,7 +144265,7 @@ function maskApiKeyForDisplay(apiKey) {
143651
144265
  return `${trimmed.slice(0, 3)}...${trimmed.slice(-4)}`;
143652
144266
  }
143653
144267
  __name(maskApiKeyForDisplay, "maskApiKeyForDisplay");
143654
- var MID_TURN_QUEUE_DRAIN_METHOD = "craft/drainMidTurnQueue";
144268
+ var ASK_USER_QUESTION_CANCEL_SKIP_MESSAGE = "Skipped because ask_user_question was cancelled before the user answered; user input is required before continuing.";
143655
144269
  var MID_TURN_QUEUE_DRAIN_TIMEOUT_MS = 2e3;
143656
144270
  var MID_TURN_QUEUE_DRAIN_MAX_TIMEOUT_STRIKES = 3;
143657
144271
  var MidTurnDrainTimeoutError = class extends Error {
@@ -144450,15 +145064,21 @@ ${this.pendingWorktreeNotice}
144450
145064
  );
144451
145065
  }
144452
145066
  if (functionCalls.length > 0) {
144453
- const toolResponseParts = await this.runToolCalls(
145067
+ const toolRun = await this.runToolCalls(
144454
145068
  pendingSend.signal,
144455
145069
  promptId,
144456
145070
  functionCalls
144457
145071
  );
145072
+ if (toolRun.stopAfterUserQuestionCancel) {
145073
+ await this.#preserveCancelledAskUserQuestionToolRun(
145074
+ toolRun
145075
+ );
145076
+ return { stopReason: "end_turn" };
145077
+ }
144458
145078
  nextMessage = {
144459
145079
  role: "user",
144460
145080
  parts: [
144461
- ...toolResponseParts,
145081
+ ...toolRun.parts,
144462
145082
  ...await this.#drainMidTurnUserMessages()
144463
145083
  ]
144464
145084
  };
@@ -144636,15 +145256,19 @@ ${this.pendingWorktreeNotice}
144636
145256
  );
144637
145257
  }
144638
145258
  if (functionCalls.length > 0) {
144639
- const toolResponseParts = await this.runToolCalls(
145259
+ const toolRun = await this.runToolCalls(
144640
145260
  pendingSend.signal,
144641
145261
  promptId,
144642
145262
  functionCalls
144643
145263
  );
145264
+ if (toolRun.stopAfterUserQuestionCancel) {
145265
+ await this.#preserveCancelledAskUserQuestionToolRun(toolRun);
145266
+ return { stopReason: "end_turn" };
145267
+ }
144644
145268
  nextMessage = {
144645
145269
  role: "user",
144646
145270
  parts: [
144647
- ...toolResponseParts,
145271
+ ...toolRun.parts,
144648
145272
  ...await this.#drainMidTurnUserMessages()
144649
145273
  ]
144650
145274
  };
@@ -144768,6 +145392,16 @@ ${this.pendingWorktreeNotice}
144768
145392
  });
144769
145393
  }
144770
145394
  }
145395
+ async #preserveCancelledAskUserQuestionToolRun(toolRun) {
145396
+ this.#preserveUnsentMessageHistory(
145397
+ {
145398
+ role: "user",
145399
+ parts: [...toolRun.parts, ...await this.#drainMidTurnUserMessages()]
145400
+ },
145401
+ true
145402
+ );
145403
+ await this.messageRewriter?.waitForPendingRewrites();
145404
+ }
144771
145405
  #recordCompressionTokenCount(info) {
144772
145406
  this.#syncPromptTokenCountWithCurrentChat();
144773
145407
  const tokenCount = this.#extractCompressionTokenCount(info);
@@ -145047,15 +145681,21 @@ ${this.pendingWorktreeNotice}
145047
145681
  );
145048
145682
  }
145049
145683
  if (functionCalls.length > 0) {
145050
- const toolResponseParts = await this.runToolCalls(
145684
+ const toolRun = await this.runToolCalls(
145051
145685
  ac.signal,
145052
145686
  promptId,
145053
145687
  functionCalls
145054
145688
  );
145689
+ if (toolRun.stopAfterUserQuestionCancel) {
145690
+ await this.#preserveCancelledAskUserQuestionToolRun(
145691
+ toolRun
145692
+ );
145693
+ return;
145694
+ }
145055
145695
  nextMessage = {
145056
145696
  role: "user",
145057
145697
  parts: [
145058
- ...toolResponseParts,
145698
+ ...toolRun.parts,
145059
145699
  ...await this.#drainMidTurnUserMessages()
145060
145700
  ]
145061
145701
  };
@@ -145171,7 +145811,10 @@ ${this.pendingWorktreeNotice}
145171
145811
  break;
145172
145812
  }
145173
145813
  const item = this.notificationQueue.shift();
145174
- await this.#executeBackgroundNotificationPrompt(item);
145814
+ await sessionIdContext.run(
145815
+ this.config.getSessionId(),
145816
+ () => this.#executeBackgroundNotificationPromptInner(item)
145817
+ );
145175
145818
  }
145176
145819
  } finally {
145177
145820
  this.notificationProcessing = false;
@@ -145183,12 +145826,6 @@ ${this.pendingWorktreeNotice}
145183
145826
  }
145184
145827
  }
145185
145828
  }
145186
- async #executeBackgroundNotificationPrompt(item) {
145187
- return sessionIdContext.run(
145188
- this.config.getSessionId(),
145189
- () => this.#executeBackgroundNotificationPromptInner(item)
145190
- );
145191
- }
145192
145829
  async #executeBackgroundNotificationPromptInner(item) {
145193
145830
  return Storage.runWithRuntimeBaseDir(
145194
145831
  this.runtimeBaseDir,
@@ -145279,15 +145916,20 @@ ${this.pendingWorktreeNotice}
145279
145916
  );
145280
145917
  }
145281
145918
  if (functionCalls.length > 0) {
145282
- const toolResponseParts = await this.runToolCalls(
145919
+ const toolRun = await this.runToolCalls(
145283
145920
  ac.signal,
145284
145921
  promptId,
145285
145922
  functionCalls
145286
145923
  );
145924
+ if (toolRun.stopAfterUserQuestionCancel) {
145925
+ await this.#preserveCancelledAskUserQuestionToolRun(toolRun);
145926
+ await this.#emitBackgroundNotificationEndTurn("end_turn");
145927
+ return;
145928
+ }
145287
145929
  nextMessage = {
145288
145930
  role: "user",
145289
145931
  parts: [
145290
- ...toolResponseParts,
145932
+ ...toolRun.parts,
145291
145933
  ...await this.#drainMidTurnUserMessages()
145292
145934
  ]
145293
145935
  };
@@ -145524,8 +146166,9 @@ ${this.pendingWorktreeNotice}
145524
146166
  * on. Response-part ordering matches the original `functionCalls` order.
145525
146167
  */
145526
146168
  async runToolCalls(abortSignal, promptId, functionCalls) {
146169
+ const dedupedFunctionCalls = dedupeToolCallsById(functionCalls);
145527
146170
  const batches = [];
145528
- for (const fc of dedupeToolCallsById(functionCalls)) {
146171
+ for (const fc of dedupedFunctionCalls) {
145529
146172
  const isAgent = fc.name === ToolNames.AGENT;
145530
146173
  const last = batches[batches.length - 1];
145531
146174
  if (isAgent && last?.concurrent) {
@@ -145534,7 +146177,45 @@ ${this.pendingWorktreeNotice}
145534
146177
  batches.push({ concurrent: isAgent, calls: [fc] });
145535
146178
  }
145536
146179
  }
145537
- const runBounded = /* @__PURE__ */ __name(async (calls) => {
146180
+ let skippedToolCallCounter = 0;
146181
+ const recordSkippedToolCall = /* @__PURE__ */ __name(async (fc) => {
146182
+ const toolName = fc.name ?? "unknown_tool";
146183
+ const callId = fc.id ?? `${toolName}-skip-${++skippedToolCallCounter}`;
146184
+ const part = {
146185
+ functionResponse: {
146186
+ id: callId,
146187
+ name: toolName,
146188
+ response: { error: ASK_USER_QUESTION_CANCEL_SKIP_MESSAGE }
146189
+ }
146190
+ };
146191
+ const error = new Error(ASK_USER_QUESTION_CANCEL_SKIP_MESSAGE);
146192
+ try {
146193
+ this.config.getChatRecordingService()?.recordToolResult([part], {
146194
+ callId,
146195
+ status: "error",
146196
+ resultDisplay: void 0,
146197
+ error,
146198
+ errorType: void 0
146199
+ });
146200
+ await this.toolCallEmitter.emitStart({
146201
+ callId,
146202
+ toolName,
146203
+ args: fc.args ?? {},
146204
+ status: "pending"
146205
+ });
146206
+ await this.toolCallEmitter.emitError(callId, toolName, error);
146207
+ } catch (recordError) {
146208
+ debugLogger78.error("Failed to record skipped tool call:", recordError);
146209
+ }
146210
+ return part;
146211
+ }, "recordSkippedToolCall");
146212
+ const appendSkippedAfter = /* @__PURE__ */ __name(async (parts2, fc) => {
146213
+ const startIndex = dedupedFunctionCalls.indexOf(fc) + 1;
146214
+ for (const remainingCall of dedupedFunctionCalls.slice(startIndex)) {
146215
+ parts2.push(await recordSkippedToolCall(remainingCall));
146216
+ }
146217
+ }, "appendSkippedAfter");
146218
+ const runBounded = /* @__PURE__ */ __name(async (calls, runAbortSignal, onStopAfterUserQuestionCancel, shouldSkipUnstarted) => {
145538
146219
  const parsed = parseInt(
145539
146220
  process.env["QWEN_CODE_MAX_TOOL_CONCURRENCY"] || "",
145540
146221
  10
@@ -145544,7 +146225,19 @@ ${this.pendingWorktreeNotice}
145544
146225
  const executing = /* @__PURE__ */ new Set();
145545
146226
  for (let i = 0; i < calls.length; i++) {
145546
146227
  const idx = i;
145547
- const p = this.runTool(abortSignal, promptId, calls[idx]).then((r) => {
146228
+ if (runAbortSignal.aborted && shouldSkipUnstarted?.()) {
146229
+ results[idx] = {
146230
+ parts: [await recordSkippedToolCall(calls[idx])],
146231
+ stopAfterUserQuestionCancel: false
146232
+ };
146233
+ continue;
146234
+ }
146235
+ const p = this.runTool(
146236
+ runAbortSignal,
146237
+ promptId,
146238
+ calls[idx],
146239
+ onStopAfterUserQuestionCancel
146240
+ ).then((r) => {
145548
146241
  results[idx] = r;
145549
146242
  }).finally(() => {
145550
146243
  executing.delete(p);
@@ -145560,16 +146253,54 @@ ${this.pendingWorktreeNotice}
145560
146253
  const parts = [];
145561
146254
  for (const batch of batches) {
145562
146255
  if (batch.concurrent && batch.calls.length > 1) {
145563
- const results = await runBounded(batch.calls);
145564
- for (const r of results) parts.push(...r);
146256
+ const batchAbortController = new AbortController();
146257
+ let batchStopAfterUserQuestionCancel = false;
146258
+ const propagateAbort = /* @__PURE__ */ __name(() => {
146259
+ batchAbortController.abort(abortSignal.reason);
146260
+ }, "propagateAbort");
146261
+ if (abortSignal.aborted) {
146262
+ propagateAbort();
146263
+ } else {
146264
+ abortSignal.addEventListener("abort", propagateAbort, {
146265
+ once: true
146266
+ });
146267
+ }
146268
+ const stopBatchAfterUserQuestionCancel = /* @__PURE__ */ __name(() => {
146269
+ batchStopAfterUserQuestionCancel = true;
146270
+ batchAbortController.abort(USER_CANCEL_ABORT_REASON);
146271
+ }, "stopBatchAfterUserQuestionCancel");
146272
+ let results;
146273
+ try {
146274
+ results = await runBounded(
146275
+ batch.calls,
146276
+ batchAbortController.signal,
146277
+ stopBatchAfterUserQuestionCancel,
146278
+ () => batchStopAfterUserQuestionCancel
146279
+ );
146280
+ } finally {
146281
+ abortSignal.removeEventListener("abort", propagateAbort);
146282
+ }
146283
+ let shouldStop = false;
146284
+ for (const r of results) {
146285
+ parts.push(...r.parts);
146286
+ shouldStop ||= r.stopAfterUserQuestionCancel;
146287
+ }
146288
+ if (shouldStop) {
146289
+ await appendSkippedAfter(parts, batch.calls[batch.calls.length - 1]);
146290
+ return { parts, stopAfterUserQuestionCancel: true };
146291
+ }
145565
146292
  } else {
145566
146293
  for (const fc of batch.calls) {
145567
146294
  const r = await this.runTool(abortSignal, promptId, fc);
145568
- parts.push(...r);
146295
+ parts.push(...r.parts);
146296
+ if (r.stopAfterUserQuestionCancel) {
146297
+ await appendSkippedAfter(parts, fc);
146298
+ return { parts, stopAfterUserQuestionCancel: true };
146299
+ }
145569
146300
  }
145570
146301
  }
145571
146302
  }
145572
- return parts;
146303
+ return { parts, stopAfterUserQuestionCancel: false };
145573
146304
  }
145574
146305
  /**
145575
146306
  * Assemble the per-turn system reminders the model needs to see at the
@@ -145601,11 +146332,15 @@ ${this.pendingWorktreeNotice}
145601
146332
  }
145602
146333
  return reminders;
145603
146334
  }
145604
- async runTool(abortSignal, promptId, fc) {
146335
+ async runTool(abortSignal, promptId, fc, onStopAfterUserQuestionCancel) {
145605
146336
  const callId = fc.id ?? `${fc.name}-${Date.now()}`;
145606
146337
  let args = fc.args ?? {};
145607
146338
  const startTime = Date.now();
145608
146339
  let spanError;
146340
+ let activeToolAbortSignal = abortSignal;
146341
+ let nestedAskUserQuestionCancelled = false;
146342
+ let agentToolAbortController;
146343
+ let removeAgentToolAbortPropagation;
145609
146344
  const errorResponse = /* @__PURE__ */ __name((error) => {
145610
146345
  const durationMs = Date.now() - startTime;
145611
146346
  logToolCall(this.config, {
@@ -145616,7 +146351,7 @@ ${this.pendingWorktreeNotice}
145616
146351
  function_args: args,
145617
146352
  duration_ms: durationMs,
145618
146353
  // An aborted signal means the call was cancelled, not a genuine error.
145619
- status: abortSignal.aborted ? "cancelled" : "error",
146354
+ status: activeToolAbortSignal.aborted ? "cancelled" : "error",
145620
146355
  success: false,
145621
146356
  error: error.message,
145622
146357
  tool_type: typeof tool !== "undefined" && tool instanceof DiscoveredMCPTool ? "mcp" : "native"
@@ -145631,8 +146366,9 @@ ${this.pendingWorktreeNotice}
145631
146366
  }
145632
146367
  ];
145633
146368
  }, "errorResponse");
145634
- const earlyErrorResponse = /* @__PURE__ */ __name(async (error, toolName2 = fc.name ?? "unknown_tool") => {
146369
+ const earlyErrorResponse = /* @__PURE__ */ __name(async (error, toolName2 = fc.name ?? "unknown_tool", opts) => {
145635
146370
  spanError = error.message;
146371
+ removeAgentToolAbortPropagation?.();
145636
146372
  if (toolName2 !== ToolNames.TODO_WRITE) {
145637
146373
  await this.toolCallEmitter.emitError(callId, toolName2, error);
145638
146374
  }
@@ -145644,7 +146380,10 @@ ${this.pendingWorktreeNotice}
145644
146380
  error,
145645
146381
  errorType: void 0
145646
146382
  });
145647
- return errorParts;
146383
+ return {
146384
+ parts: errorParts,
146385
+ stopAfterUserQuestionCancel: opts?.stopAfterUserQuestionCancel ?? false
146386
+ };
145648
146387
  }, "earlyErrorResponse");
145649
146388
  if (!fc.name) {
145650
146389
  return earlyErrorResponse(new Error("Missing function name"));
@@ -145679,6 +146418,23 @@ ${this.pendingWorktreeNotice}
145679
146418
  const isAgentTool = tool.name === ToolNames.AGENT;
145680
146419
  const isExitPlanModeTool = tool.name === ToolNames.EXIT_PLAN_MODE;
145681
146420
  const isEnterPlanModeTool = tool.name === ToolNames.ENTER_PLAN_MODE;
146421
+ if (isAgentTool) {
146422
+ agentToolAbortController = new AbortController();
146423
+ activeToolAbortSignal = agentToolAbortController.signal;
146424
+ const propagateAbort = /* @__PURE__ */ __name(() => {
146425
+ agentToolAbortController?.abort(abortSignal.reason);
146426
+ }, "propagateAbort");
146427
+ if (abortSignal.aborted) {
146428
+ propagateAbort();
146429
+ } else {
146430
+ abortSignal.addEventListener("abort", propagateAbort, {
146431
+ once: true
146432
+ });
146433
+ removeAgentToolAbortPropagation = /* @__PURE__ */ __name(() => {
146434
+ abortSignal.removeEventListener("abort", propagateAbort);
146435
+ }, "removeAgentToolAbortPropagation");
146436
+ }
146437
+ }
145682
146438
  let subAgentCleanupFunctions = [];
145683
146439
  const toolUseId = generateToolUseId();
145684
146440
  const approvalMode = this.config.getApprovalMode();
@@ -145692,11 +146448,16 @@ ${this.pendingWorktreeNotice}
145692
146448
  this,
145693
146449
  this.client,
145694
146450
  parentToolCallId,
145695
- subagentType
146451
+ subagentType,
146452
+ () => {
146453
+ nestedAskUserQuestionCancelled = true;
146454
+ agentToolAbortController?.abort(USER_CANCEL_ABORT_REASON);
146455
+ onStopAfterUserQuestionCancel?.();
146456
+ }
145696
146457
  );
145697
146458
  subAgentCleanupFunctions = subSubAgentTracker.setup(
145698
146459
  taskEventEmitter,
145699
- abortSignal
146460
+ activeToolAbortSignal
145700
146461
  );
145701
146462
  }
145702
146463
  const isAskUserQuestionTool = toolName === ToolNames.ASK_USER_QUESTION;
@@ -145914,9 +146675,15 @@ ${this.pendingWorktreeNotice}
145914
146675
  }
145915
146676
  switch (outcome) {
145916
146677
  case "cancel" /* Cancel */:
146678
+ if (toolName === ToolNames.ASK_USER_QUESTION) {
146679
+ onStopAfterUserQuestionCancel?.();
146680
+ }
145917
146681
  return earlyErrorResponse(
145918
146682
  new Error(`Tool "${toolName}" was canceled by the user.`),
145919
- toolName
146683
+ toolName,
146684
+ {
146685
+ stopAfterUserQuestionCancel: toolName === ToolNames.ASK_USER_QUESTION
146686
+ }
145920
146687
  );
145921
146688
  case "proceed_once" /* ProceedOnce */:
145922
146689
  case "proceed_always" /* ProceedAlways */:
@@ -145953,7 +146720,7 @@ ${this.pendingWorktreeNotice}
145953
146720
  args,
145954
146721
  toolUseId,
145955
146722
  permissionMode,
145956
- abortSignal
146723
+ activeToolAbortSignal
145957
146724
  );
145958
146725
  if (!preHookResult.shouldProceed) {
145959
146726
  const blockReason = preHookResult.blockReason || "Blocked by PreToolUse hook";
@@ -145976,11 +146743,11 @@ ${this.pendingWorktreeNotice}
145976
146743
  `Qwen Code is executing tool ${toolName}`
145977
146744
  );
145978
146745
  try {
145979
- toolResult = await invocation.execute(abortSignal);
146746
+ toolResult = await invocation.execute(activeToolAbortSignal);
145980
146747
  } finally {
145981
146748
  sleepInhibitorHandle.release();
145982
146749
  }
145983
- const aborted2 = abortSignal.aborted;
146750
+ const aborted2 = activeToolAbortSignal.aborted;
145984
146751
  endToolExecutionSpan(execSpan, {
145985
146752
  success: !toolResult.error && !aborted2,
145986
146753
  error: aborted2 ? "tool_cancelled" : toolResult.error ? "tool_error" : void 0,
@@ -145989,12 +146756,13 @@ ${this.pendingWorktreeNotice}
145989
146756
  } catch (execError) {
145990
146757
  endToolExecutionSpan(execSpan, {
145991
146758
  success: false,
145992
- error: abortSignal.aborted ? "tool_cancelled" : "tool_exception",
145993
- cancelled: abortSignal.aborted
146759
+ error: activeToolAbortSignal.aborted ? "tool_cancelled" : "tool_exception",
146760
+ cancelled: activeToolAbortSignal.aborted
145994
146761
  });
145995
146762
  throw execError;
145996
146763
  }
145997
146764
  subAgentCleanupFunctions.forEach((cleanup) => cleanup());
146765
+ removeAgentToolAbortPropagation?.();
145998
146766
  if ((isEnterPlanModeTool || isExitPlanModeTool) && !didRequestPermission && !toolResult.error && this.config.getApprovalMode() !== approvalMode) {
145999
146767
  await this.sendUpdate({
146000
146768
  sessionUpdate: "current_mode_update",
@@ -146006,7 +146774,10 @@ ${this.pendingWorktreeNotice}
146006
146774
  callId,
146007
146775
  toolResult.llmContent
146008
146776
  );
146009
- if (hooksEnabledForTool && messageBusForTool && !toolResult.error) {
146777
+ const aborted = activeToolAbortSignal.aborted;
146778
+ const status = aborted ? "cancelled" : toolResult.error ? "error" : "success";
146779
+ const succeeded = status === "success";
146780
+ if (hooksEnabledForTool && messageBusForTool && !toolResult.error && !aborted && !nestedAskUserQuestionCancelled) {
146010
146781
  const toolResponse = {
146011
146782
  llmContent: toolResult.llmContent,
146012
146783
  returnDisplay: toolResult.returnDisplay
@@ -146018,7 +146789,7 @@ ${this.pendingWorktreeNotice}
146018
146789
  toolResponse,
146019
146790
  toolUseId,
146020
146791
  permissionMode,
146021
- abortSignal
146792
+ activeToolAbortSignal
146022
146793
  );
146023
146794
  if (postHookResult.shouldStop) {
146024
146795
  const stopMessage = postHookResult.stopReason || "Execution stopped by PostToolUse hook";
@@ -146031,17 +146802,17 @@ ${this.pendingWorktreeNotice}
146031
146802
  const contextPart = { text: postHookResult.additionalContext };
146032
146803
  responseParts.push(contextPart);
146033
146804
  }
146034
- } else if (hooksEnabledForTool && messageBusForTool && toolResult.error) {
146805
+ } else if (hooksEnabledForTool && messageBusForTool && (toolResult.error || aborted)) {
146806
+ const isInterrupt = aborted;
146035
146807
  const failureHookResult = await firePostToolUseFailureHook(
146036
146808
  messageBusForTool,
146037
146809
  toolUseId,
146038
146810
  toolName,
146039
146811
  args,
146040
- toolResult.error.message,
146041
- false,
146042
- // not an interrupt
146812
+ toolResult.error?.message ?? "Tool execution was cancelled",
146813
+ isInterrupt,
146043
146814
  permissionMode,
146044
- abortSignal
146815
+ activeToolAbortSignal
146045
146816
  );
146046
146817
  if (failureHookResult.additionalContext) {
146047
146818
  debugLogger78.debug(
@@ -146049,9 +146820,6 @@ ${this.pendingWorktreeNotice}
146049
146820
  );
146050
146821
  }
146051
146822
  }
146052
- const aborted = abortSignal.aborted;
146053
- const status = aborted ? "cancelled" : toolResult.error ? "error" : "success";
146054
- const succeeded = status === "success";
146055
146823
  if (isTodoWriteTool) {
146056
146824
  const todos = this.planEmitter.extractTodos(
146057
146825
  toolResult.returnDisplay,
@@ -146099,14 +146867,18 @@ ${this.pendingWorktreeNotice}
146099
146867
  } else if (aborted) {
146100
146868
  spanError = "Tool execution was cancelled";
146101
146869
  }
146102
- return responseParts;
146870
+ return {
146871
+ parts: responseParts,
146872
+ stopAfterUserQuestionCancel: nestedAskUserQuestionCancelled
146873
+ };
146103
146874
  } catch (e) {
146104
146875
  subAgentCleanupFunctions.forEach((cleanup) => cleanup());
146876
+ removeAgentToolAbortPropagation?.();
146105
146877
  const error = e instanceof Error ? e : new Error(String(e));
146106
146878
  spanError = error.message;
146107
146879
  const hooksEnabledForError = !this.config.getDisableAllHooks?.();
146108
146880
  const messageBusForError = this.config.getMessageBus?.();
146109
- const isInterrupt = abortSignal.aborted;
146881
+ const isInterrupt = activeToolAbortSignal.aborted;
146110
146882
  if (hooksEnabledForError && messageBusForError) {
146111
146883
  const failureHookResult = await firePostToolUseFailureHook(
146112
146884
  messageBusForError,
@@ -146116,7 +146888,7 @@ ${this.pendingWorktreeNotice}
146116
146888
  error.message,
146117
146889
  isInterrupt,
146118
146890
  String(approvalMode),
146119
- abortSignal
146891
+ activeToolAbortSignal
146120
146892
  );
146121
146893
  if (failureHookResult.additionalContext) {
146122
146894
  debugLogger78.debug(
@@ -146138,12 +146910,15 @@ ${this.pendingWorktreeNotice}
146138
146910
  callId,
146139
146911
  // A throw caused by abort (e.g. AbortError) is a cancellation, not
146140
146912
  // a genuine tool error — keep it consistent with the success path.
146141
- status: abortSignal.aborted ? "cancelled" : "error",
146913
+ status: activeToolAbortSignal.aborted ? "cancelled" : "error",
146142
146914
  resultDisplay: void 0,
146143
146915
  error,
146144
146916
  errorType: void 0
146145
146917
  });
146146
- return errorResponse(error);
146918
+ return {
146919
+ parts: errorResponse(error),
146920
+ stopAfterUserQuestionCancel: nestedAskUserQuestionCancelled
146921
+ };
146147
146922
  }
146148
146923
  });
146149
146924
  } finally {
@@ -148190,7 +148965,7 @@ var QwenAgent = class {
148190
148965
  async initialize(args) {
148191
148966
  this.clientCapabilities = args.clientCapabilities;
148192
148967
  const authMethods = buildAuthMethods();
148193
- const version = "0.18.1";
148968
+ const version = "0.18.3-preview.0";
148194
148969
  return {
148195
148970
  protocolVersion: PROTOCOL_VERSION,
148196
148971
  agentInfo: {
@@ -151547,7 +152322,10 @@ ${outputText}
151547
152322
  settings,
151548
152323
  argvForSession,
151549
152324
  cwd5,
151550
- [],
152325
+ // ACP sessions do not provide an extension override. Passing [] is a
152326
+ // truthy override and prevents default/argv extension commands from
152327
+ // loading, so leave it unset to preserve normal CLI behavior.
152328
+ void 0,
151551
152329
  // Pass separated hooks for proper source attribution
151552
152330
  {
151553
152331
  userHooks: this.settings.getUserHooks(),
@@ -151773,7 +152551,7 @@ function validateDnsResolutionOrder(order) {
151773
152551
  }
151774
152552
  __name(validateDnsResolutionOrder, "validateDnsResolutionOrder");
151775
152553
  function getNodeMemoryArgs(isDebugMode3) {
151776
- const totalMemoryMB = os32.totalmem() / (1024 * 1024);
152554
+ const totalMemoryMB = os31.totalmem() / (1024 * 1024);
151777
152555
  const heapStats = v83.getHeapStatistics();
151778
152556
  const currentMaxOldSpaceSizeMb = Math.floor(
151779
152557
  heapStats.heap_size_limit / 1024 / 1024
@@ -152275,7 +153053,7 @@ ${finalArgs[promptIndex + 1]}`;
152275
153053
  process.exit(0);
152276
153054
  }
152277
153055
  if (config.isInteractive()) {
152278
- void import("./chunks/scheduler-O66SLJGU.js").then((m) => m.startBackgroundHousekeeping(config, settings)).catch((err) => {
153056
+ void import("./chunks/scheduler-WCMRRLYM.js").then((m) => m.startBackgroundHousekeeping(config, settings)).catch((err) => {
152279
153057
  debugLogger80.warn("failed to start background housekeeping:", err);
152280
153058
  });
152281
153059
  }
@@ -152295,6 +153073,7 @@ ${finalArgs[promptIndex + 1]}`;
152295
153073
  ] : []
152296
153074
  ])
152297
153075
  ];
153076
+ const emittedStartupWarnings = new Set(startupWarnings);
152298
153077
  for (const warning of startupWarnings) {
152299
153078
  writeStderrLine(warning);
152300
153079
  }
@@ -152339,6 +153118,11 @@ ${finalArgs[promptIndex + 1]}`;
152339
153118
  if (inputFormat !== "stream-json" /* STREAM_JSON */) {
152340
153119
  profileCheckpoint("config_initialize_start");
152341
153120
  await config.initialize();
153121
+ for (const warning of config.getWarnings()) {
153122
+ if (emittedStartupWarnings.has(warning)) continue;
153123
+ emittedStartupWarnings.add(warning);
153124
+ writeStderrLine(warning);
153125
+ }
152342
153126
  profileCheckpoint("config_initialize_end");
152343
153127
  await config.waitForMcpReady();
152344
153128
  const failedMcpServers = typeof config.getFailedMcpServerNames === "function" ? config.getFailedMcpServerNames() : [];