@qwen-code/qwen-code 0.18.1 → 0.18.3-nightly.20260618.bc3e0b405

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-ACIWYWX7.js} +5 -5
  13. package/chunks/{agent-headless-LNRE63ZL.js → agent-headless-3OQZEB2S.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-IS7UA4W3.js → chunk-753BG2JJ.js} +4 -4
  17. package/chunks/{chunk-RON7LFNH.js → chunk-BPJAFPPD.js} +6 -6
  18. package/chunks/{chunk-3NRO6NHX.js → chunk-MN5RAXVB.js} +3 -3
  19. package/chunks/{chunk-Y7KMDUEP.js → chunk-QP4R5FTG.js} +1 -1
  20. package/chunks/{chunk-6T7Y7USE.js → chunk-RMFCNRER.js} +124858 -123552
  21. package/chunks/{chunk-QILTEBWS.js → chunk-RTTAC5VW.js} +1 -1
  22. package/chunks/{chunk-XZTNBSMW.js → chunk-SWMGBYC2.js} +1 -1
  23. package/chunks/{chunk-WJ3SND6W.js → chunk-UIH54N5X.js} +2 -2
  24. package/chunks/{chunk-HQUWWSSP.js → chunk-VIEIRAK3.js} +1 -1
  25. package/chunks/{chunk-HED55F43.js → chunk-VU6A2OBJ.js} +15 -5
  26. package/chunks/{chunk-BXYRCW2C.js → chunk-XFUQS3BO.js} +10 -5
  27. package/chunks/{chunk-DHZREJTG.js → chunk-YJDVHAGL.js} +1 -1
  28. package/chunks/{chunk-A2ZIEEGJ.js → chunk-ZNUMXPNK.js} +592 -43
  29. package/chunks/{computer-use-4YX3JGBV.js → computer-use-Y3INMFGQ.js} +5 -5
  30. package/chunks/{contextCommand-KS2H7MW5.js → contextCommand-4AF56TE5.js} +7 -7
  31. package/chunks/{cron-create-CAPUKK7I.js → cron-create-DQKRQMCP.js} +1 -1
  32. package/chunks/{cron-delete-G3KAR26Q.js → cron-delete-DOFPHFTI.js} +1 -1
  33. package/chunks/{cron-list-ZA4ZIUS5.js → cron-list-RCVOO3CB.js} +1 -1
  34. package/chunks/{dist-VEGFONCF.js → dist-2UCAYOX7.js} +2 -2
  35. package/chunks/{dist-X4EXN7W6.js → dist-33LHH26D.js} +1 -1
  36. package/chunks/{dist-YLS6NI7H.js → dist-KF43SZZV.js} +1 -1
  37. package/chunks/{dist-7YWFWOCJ.js → dist-UH7CYT7F.js} +2 -2
  38. package/chunks/{edit-2ARPEO4B.js → edit-MO45GCL7.js} +8 -12
  39. package/chunks/{enter-worktree-IXNXNAW5.js → enter-worktree-Z3JI6PAT.js} +5 -5
  40. package/chunks/{enterPlanMode-TAKAGAYP.js → enterPlanMode-IK6VOFTA.js} +5 -5
  41. package/chunks/{exit-worktree-LHTRV7ML.js → exit-worktree-N7VFZX2L.js} +5 -5
  42. package/chunks/{exitPlanMode-MK5UAITL.js → exitPlanMode-I3KHESPG.js} +11 -9
  43. package/chunks/{geminiContentGenerator-HFJIGO77.js → geminiContentGenerator-SCL4XVAS.js} +1 -1
  44. package/chunks/{glob-I2USLUSC.js → glob-F2B2SE3K.js} +5 -5
  45. package/chunks/{grep-WBIF7THR.js → grep-4KQWN26D.js} +5 -5
  46. package/chunks/{ls-2R5RHLX5.js → ls-TRD77UTS.js} +1 -1
  47. package/chunks/{lsp-XKH6ZIAN.js → lsp-2VFWQPZS.js} +1 -1
  48. package/chunks/{monitor-WU7UFATU.js → monitor-JLANELR3.js} +5 -5
  49. package/chunks/{notebook-edit-KUHYPXEM.js → notebook-edit-HDRKPHHG.js} +6 -8
  50. package/chunks/{openaiContentGenerator-5PLHYJQL.js → openaiContentGenerator-BKTFJC2S.js} +5 -5
  51. package/chunks/{qwenContentGenerator-TSKW73KY.js → qwenContentGenerator-62BVT57E.js} +7 -7
  52. package/chunks/{read-file-VIPF2PS6.js → read-file-SFLRS3OC.js} +3 -3
  53. package/chunks/{ripGrep-XLIZTYE7.js → ripGrep-H2MU4MC3.js} +5 -5
  54. package/chunks/{scheduler-O66SLJGU.js → scheduler-2GZTWP5S.js} +5 -5
  55. package/chunks/{send-message-CTME7DXD.js → send-message-QZOC5GA2.js} +1 -1
  56. package/chunks/{serve-BWOLYT62.js → serve-SYMKDBDG.js} +709 -26
  57. package/chunks/{shell-XE7UYKOO.js → shell-U46KHTLY.js} +5 -5
  58. package/chunks/{skill-RZWM6XMC.js → skill-VQMJOXNY.js} +3 -3
  59. package/chunks/{src-L5P7K4MH.js → src-YBSBZZEL.js} +11 -5
  60. package/chunks/{syntheticOutput-ZJGSU7OQ.js → syntheticOutput-WJSUK4SZ.js} +2 -2
  61. package/chunks/{task-create-EE6JEM7G.js → task-create-GGSC27HO.js} +2 -2
  62. package/chunks/{task-list-EESYAC65.js → task-list-EDHHHSK4.js} +1 -1
  63. package/chunks/{task-stop-XZVCFFYY.js → task-stop-WR5PDVZY.js} +1 -1
  64. package/chunks/{task-update-EIO4HNE3.js → task-update-UR7NUHBV.js} +2 -2
  65. package/chunks/{team-create-R2H7Y3SG.js → team-create-OA3IGBCE.js} +5 -5
  66. package/chunks/{team-delete-A7LXPGV7.js → team-delete-FC33URJK.js} +1 -1
  67. package/chunks/{todoWrite-VRKSGAWM.js → todoWrite-GO2ME7ZV.js} +1 -1
  68. package/chunks/{tool-search-USSQMTMS.js → tool-search-A57VE2JF.js} +3 -3
  69. package/chunks/{web-fetch-GHAZUA54.js → web-fetch-NLLATYIL.js} +2 -2
  70. package/chunks/{workflow-5LNNLNUR.js → workflow-RWXT7YIU.js} +249 -24
  71. package/chunks/{write-file-2I7HP24C.js → write-file-46RW6BV4.js} +7 -9
  72. package/cli.js +1328 -542
  73. package/package.json +2 -2
  74. package/chunks/chunk-7KPZFE5A.js +0 -117
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-XFUQS3BO.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-753BG2JJ.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-SWMGBYC2.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-RMFCNRER.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-BPJAFPPD.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-SYMKDBDG.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-YBSBZZEL.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-4AF56TE5.js");
83906
84237
  if (signal.aborted) {
83907
84238
  throw new Error("Request aborted");
83908
84239
  }
@@ -84428,11 +84759,13 @@ var PermissionController = class extends BaseController {
84428
84759
  label: "Deny",
84429
84760
  description: "Block this file edit"
84430
84761
  },
84431
- {
84432
- type: "modify",
84433
- label: "Review Changes",
84434
- description: "Review the proposed changes before applying"
84435
- }
84762
+ ...details["hideModify"] === true ? [] : [
84763
+ {
84764
+ type: "modify",
84765
+ label: "Review Changes",
84766
+ description: "Review the proposed changes before applying"
84767
+ }
84768
+ ]
84436
84769
  ];
84437
84770
  case "plan":
84438
84771
  return [
@@ -85303,6 +85636,10 @@ var Session = class {
85303
85636
  if (this.isShuttingDown || this.abortController.signal.aborted) {
85304
85637
  return;
85305
85638
  }
85639
+ if (meta.status === "running" && typeof registry2.get === "function") {
85640
+ const entry = registry2.get(meta.monitorId);
85641
+ if (!entry || entry.status !== "running") return;
85642
+ }
85306
85643
  this.enqueueMonitorNotification({
85307
85644
  displayText,
85308
85645
  modelText,
@@ -85507,25 +85844,29 @@ var Session = class {
85507
85844
  debugLogger33.error("[Session] Query execution error:", error);
85508
85845
  }
85509
85846
  }
85510
- async processMonitorNotification(notification) {
85847
+ async processMonitorNotificationBatch(batch) {
85511
85848
  await this.waitForInitialization();
85512
- this.outputAdapter.emitUserMessage([{ text: notification.displayText }]);
85513
- this.outputAdapter.emitSystemMessage(
85514
- "task_notification",
85515
- notification.sdkNotification
85516
- );
85849
+ for (const item of batch) {
85850
+ this.outputAdapter.emitUserMessage([{ text: item.displayText }]);
85851
+ this.outputAdapter.emitSystemMessage(
85852
+ "task_notification",
85853
+ item.sdkNotification
85854
+ );
85855
+ }
85856
+ const combinedModelText = batch.map((n) => n.modelText).join("\n\n");
85857
+ const combinedDisplayText = batch.map((n) => n.displayText).join("; ");
85517
85858
  const promptId = this.getNextPromptId();
85518
85859
  await runNonInteractive(
85519
85860
  this.config,
85520
85861
  this.settings,
85521
- notification.modelText,
85862
+ combinedModelText,
85522
85863
  promptId,
85523
85864
  {
85524
85865
  abortController: this.abortController,
85525
85866
  adapter: this.outputAdapter,
85526
85867
  controlService: this.controlService ?? void 0,
85527
85868
  sendMessageType: "notification" /* Notification */,
85528
- notificationDisplayText: notification.displayText,
85869
+ notificationDisplayText: combinedDisplayText,
85529
85870
  captureMonitorNotifications: false,
85530
85871
  captureMonitorRegistrations: false
85531
85872
  }
@@ -85551,15 +85892,15 @@ var Session = class {
85551
85892
  this.outputAdapter.emitSystemMessage("task_started", started);
85552
85893
  continue;
85553
85894
  }
85554
- const notification = this.monitorQueue.shift();
85555
- if (!notification) {
85895
+ if (this.monitorQueue.length === 0) {
85556
85896
  continue;
85557
85897
  }
85898
+ const batch = this.monitorQueue.splice(0);
85558
85899
  try {
85559
- await this.processMonitorNotification(notification);
85900
+ await this.processMonitorNotificationBatch(batch);
85560
85901
  } catch (error) {
85561
85902
  debugLogger33.error(
85562
- "[Session] Error processing monitor notification:",
85903
+ "[Session] Error processing monitor notification batch:",
85563
85904
  error
85564
85905
  );
85565
85906
  this.emitErrorResult(error);
@@ -87745,6 +88086,22 @@ __name(loadLowlight, "loadLowlight");
87745
88086
  // packages/cli/src/ui/utils/CodeColorizer.tsx
87746
88087
  var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
87747
88088
  var debugLogger37 = createDebugLogger("CODE_COLORIZER");
88089
+ var STRUCTURAL_BOX_RE = /[│├└┌┐┘┬┴┼]/;
88090
+ var CJK_RE = /[\u4E00-\u9FFF\u3400-\u4DBF]/g;
88091
+ function looksLikeDiagramOrArt(line) {
88092
+ const trimmed = line.trim();
88093
+ if (trimmed.length === 0) return false;
88094
+ if (STRUCTURAL_BOX_RE.test(trimmed)) {
88095
+ return true;
88096
+ }
88097
+ const cjkMatches = trimmed.match(CJK_RE) || [];
88098
+ const totalChars = trimmed.replace(/\s/g, "").length;
88099
+ if (totalChars > 0 && cjkMatches.length / totalChars > 0.3) {
88100
+ return true;
88101
+ }
88102
+ return false;
88103
+ }
88104
+ __name(looksLikeDiagramOrArt, "looksLikeDiagramOrArt");
87748
88105
  function renderHastNode(node, theme2, inheritedColor) {
87749
88106
  if (node.type === "text") {
87750
88107
  const color2 = inheritedColor || theme2.defaultColor;
@@ -87790,6 +88147,9 @@ function highlightAndRenderLine(line, language, theme2, lowlight) {
87790
88147
  if (!lowlight) {
87791
88148
  return line;
87792
88149
  }
88150
+ if (!language && looksLikeDiagramOrArt(line)) {
88151
+ return line;
88152
+ }
87793
88153
  try {
87794
88154
  const getHighlightedLine = /* @__PURE__ */ __name(() => !language || !lowlight.registered(language) ? lowlight.highlightAuto(line) : lowlight.highlight(language, line), "getHighlightedLine");
87795
88155
  const renderedNode = renderHastNode(getHighlightedLine(), theme2, void 0);
@@ -90749,7 +91109,7 @@ __name(renderMermaidVisual, "renderMermaidVisual");
90749
91109
  init_esbuild_shims();
90750
91110
  import crypto2 from "node:crypto";
90751
91111
  import fs27 from "node:fs";
90752
- import os17 from "node:os";
91112
+ import os16 from "node:os";
90753
91113
  import path35 from "node:path";
90754
91114
  import { spawn as spawn4, spawnSync } from "node:child_process";
90755
91115
  var CACHE_LIMIT = 40;
@@ -91313,7 +91673,7 @@ function isExecutable(filePath) {
91313
91673
  __name(isExecutable, "isExecutable");
91314
91674
  async function renderPngWithMmdcAsync(source, mmdc, env5, signal) {
91315
91675
  const tempDir = await fs27.promises.mkdtemp(
91316
- path35.join(os17.tmpdir(), "qwen-mermaid-")
91676
+ path35.join(os16.tmpdir(), "qwen-mermaid-")
91317
91677
  );
91318
91678
  const inputPath = path35.join(tempDir, "diagram.mmd");
91319
91679
  const outputPath = path35.join(tempDir, "diagram.png");
@@ -91410,7 +91770,7 @@ function getMermaidCellAspectRatio(env5) {
91410
91770
  __name(getMermaidCellAspectRatio, "getMermaidCellAspectRatio");
91411
91771
  async function renderPngWithChafaAsync(png, widthCells, rows, chafa, env5, signal) {
91412
91772
  const tempDir = await fs27.promises.mkdtemp(
91413
- path35.join(os17.tmpdir(), "qwen-mermaid-")
91773
+ path35.join(os16.tmpdir(), "qwen-mermaid-")
91414
91774
  );
91415
91775
  const imagePath = path35.join(tempDir, "diagram.png");
91416
91776
  try {
@@ -92639,39 +92999,143 @@ var AssistantMessageContent = /* @__PURE__ */ __name(({
92639
92999
  sourceCopyIndexOffsets
92640
93000
  }
92641
93001
  ), "AssistantMessageContent");
93002
+ var MAX_STREAMING_THINKING_VISUAL_LINES = 4;
93003
+ function wrapToVisualLines(text, width) {
93004
+ if (width <= 0) {
93005
+ return [""];
93006
+ }
93007
+ const visualLines = [];
93008
+ for (const logicalLine of text.split("\n")) {
93009
+ if (logicalLine === "") {
93010
+ visualLines.push("");
93011
+ continue;
93012
+ }
93013
+ let currentLine = "";
93014
+ let currentWidth = 0;
93015
+ for (const char of logicalLine) {
93016
+ const charWidth = getCachedStringWidth(char);
93017
+ if (currentWidth + charWidth > width && currentWidth > 0) {
93018
+ visualLines.push(currentLine);
93019
+ currentLine = "";
93020
+ currentWidth = 0;
93021
+ }
93022
+ currentLine += char;
93023
+ currentWidth += charWidth;
93024
+ }
93025
+ if (currentLine) {
93026
+ visualLines.push(currentLine);
93027
+ }
93028
+ }
93029
+ if (visualLines.length === 0) {
93030
+ visualLines.push("");
93031
+ }
93032
+ return visualLines;
93033
+ }
93034
+ __name(wrapToVisualLines, "wrapToVisualLines");
93035
+ function tailVisualLines(text, width, maxLines) {
93036
+ const charBudget = maxLines * width * 2;
93037
+ let sliceStart = Math.max(0, text.length - charBudget);
93038
+ if (sliceStart > 0) {
93039
+ const nl = text.indexOf("\n", sliceStart);
93040
+ if (nl !== -1 && nl < text.length - 1) {
93041
+ sliceStart = nl + 1;
93042
+ }
93043
+ }
93044
+ const lines = wrapToVisualLines(text.slice(sliceStart), width);
93045
+ return lines.slice(-maxLines).join("\n");
93046
+ }
93047
+ __name(tailVisualLines, "tailVisualLines");
93048
+ function formatDuration2(ms) {
93049
+ const totalSeconds = Math.round(ms / 1e3);
93050
+ if (totalSeconds < 60) {
93051
+ return `${totalSeconds}s`;
93052
+ }
93053
+ const minutes = Math.floor(totalSeconds / 60);
93054
+ const seconds = totalSeconds % 60;
93055
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
93056
+ }
93057
+ __name(formatDuration2, "formatDuration");
92642
93058
  var ThinkMessage = /* @__PURE__ */ __name(({
92643
93059
  text,
92644
93060
  isPending,
93061
+ expanded = false,
92645
93062
  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
93063
+ contentWidth,
93064
+ durationMs
93065
+ }) => {
93066
+ const durationSuffix = durationMs != null ? ` ${formatDuration2(durationMs)}` : "";
93067
+ if (!isPending && !expanded) {
93068
+ const label = durationMs != null ? `${t("Thought for")} ${formatDuration2(durationMs)}` : t("Thinking");
93069
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { dimColor: true, italic: true, children: label });
93070
+ }
93071
+ if (isPending) {
93072
+ const innerWidth = Math.max(contentWidth - 2, 20);
93073
+ const maxLines = availableTerminalHeight != null ? Math.max(
93074
+ 1,
93075
+ Math.min(
93076
+ MAX_STREAMING_THINKING_VISUAL_LINES,
93077
+ Math.floor(availableTerminalHeight / 3)
93078
+ )
93079
+ ) : MAX_STREAMING_THINKING_VISUAL_LINES;
93080
+ const display = tailVisualLines(text, innerWidth, maxLines);
93081
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", children: [
93082
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Text, { dimColor: true, italic: true, children: [
93083
+ "\u27E1 ",
93084
+ t("Thinking"),
93085
+ "\u2026",
93086
+ durationSuffix
93087
+ ] }),
93088
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Box_default, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { dimColor: true, wrap: "truncate", children: display }) })
93089
+ ] });
92657
93090
  }
92658
- ), "ThinkMessage");
93091
+ const expandedLabel = durationMs != null ? `${t("Thought for")} ${formatDuration2(durationMs)}` : `${t("Thinking")}\u2026`;
93092
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Box_default, { flexDirection: "column", children: [
93093
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { dimColor: true, italic: true, children: expandedLabel }),
93094
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Box_default, { paddingLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
93095
+ MarkdownDisplay,
93096
+ {
93097
+ text,
93098
+ isPending: false,
93099
+ availableTerminalHeight,
93100
+ contentWidth: contentWidth - 2,
93101
+ textColor: theme.text.secondary
93102
+ }
93103
+ ) })
93104
+ ] });
93105
+ }, "ThinkMessage");
92659
93106
  var ThinkMessageContent = /* @__PURE__ */ __name(({
92660
93107
  text,
92661
93108
  isPending,
93109
+ expanded = false,
92662
93110
  availableTerminalHeight,
92663
93111
  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
93112
+ }) => {
93113
+ if (!isPending && !expanded) {
93114
+ return null;
93115
+ }
93116
+ if (isPending) {
93117
+ const innerWidth = Math.max(contentWidth - 2, 20);
93118
+ const maxLines = availableTerminalHeight != null ? Math.max(
93119
+ 1,
93120
+ Math.min(
93121
+ MAX_STREAMING_THINKING_VISUAL_LINES,
93122
+ Math.floor(availableTerminalHeight / 3)
93123
+ )
93124
+ ) : MAX_STREAMING_THINKING_VISUAL_LINES;
93125
+ const display = tailVisualLines(text, innerWidth, maxLines);
93126
+ 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
93127
  }
92674
- ), "ThinkMessageContent");
93128
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Box_default, { paddingLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
93129
+ MarkdownDisplay,
93130
+ {
93131
+ text,
93132
+ isPending: false,
93133
+ availableTerminalHeight,
93134
+ contentWidth: contentWidth - 2,
93135
+ textColor: theme.text.secondary
93136
+ }
93137
+ ) });
93138
+ }, "ThinkMessageContent");
92675
93139
 
92676
93140
  // packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
92677
93141
  init_esbuild_shims();
@@ -93093,7 +93557,7 @@ init_esbuild_shims();
93093
93557
  var import_react58 = __toESM(require_react(), 1);
93094
93558
  import { spawnSync as spawnSync2 } from "node:child_process";
93095
93559
  import fs28 from "node:fs";
93096
- import os18 from "node:os";
93560
+ import os17 from "node:os";
93097
93561
  import pathMod from "node:path";
93098
93562
 
93099
93563
  // packages/cli/src/ui/components/shared/vim-buffer-actions.ts
@@ -95445,7 +95909,7 @@ function useTextBuffer({
95445
95909
  let tmpDir;
95446
95910
  let filePath;
95447
95911
  try {
95448
- tmpDir = fs28.mkdtempSync(pathMod.join(os18.tmpdir(), "qwen-edit-"));
95912
+ tmpDir = fs28.mkdtempSync(pathMod.join(os17.tmpdir(), "qwen-edit-"));
95449
95913
  filePath = pathMod.join(tmpDir, "buffer.txt");
95450
95914
  } catch (err) {
95451
95915
  debugLogger39.error(
@@ -96430,7 +96894,7 @@ var ToolConfirmationMessage = /* @__PURE__ */ __name(({
96430
96894
  key: "Yes, allow always"
96431
96895
  });
96432
96896
  }
96433
- if ((!config.getIdeMode() || !isDiffingEnabled) && preferredEditor) {
96897
+ if (!confirmationDetails.hideModify && (!config.getIdeMode() || !isDiffingEnabled) && preferredEditor) {
96434
96898
  options.push({
96435
96899
  label: t("Modify with external editor"),
96436
96900
  value: "modify_with_editor" /* ModifyWithEditor */,
@@ -101189,20 +101653,23 @@ var HistoryItemDisplayComponent = /* @__PURE__ */ __name(({
101189
101653
  sourceCopyIndexOffsets
101190
101654
  }
101191
101655
  ),
101192
- !compactMode && itemForDisplay.type === "gemini_thought" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
101656
+ itemForDisplay.type === "gemini_thought" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
101193
101657
  ThinkMessage,
101194
101658
  {
101195
101659
  text: itemForDisplay.text.trimEnd(),
101196
101660
  isPending,
101661
+ expanded: false,
101197
101662
  availableTerminalHeight: availableTerminalHeightGemini ?? availableTerminalHeight,
101198
- contentWidth
101663
+ contentWidth,
101664
+ durationMs: itemForDisplay.durationMs
101199
101665
  }
101200
101666
  ),
101201
- !compactMode && itemForDisplay.type === "gemini_thought_content" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
101667
+ itemForDisplay.type === "gemini_thought_content" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
101202
101668
  ThinkMessageContent,
101203
101669
  {
101204
101670
  text: itemForDisplay.text.trimEnd(),
101205
101671
  isPending,
101672
+ expanded: false,
101206
101673
  availableTerminalHeight: availableTerminalHeightGemini ?? availableTerminalHeight,
101207
101674
  contentWidth
101208
101675
  }
@@ -105930,12 +106397,12 @@ __name(StatusLineDialog, "StatusLineDialog");
105930
106397
  init_esbuild_shims();
105931
106398
  var import_react100 = __toESM(require_react(), 1);
105932
106399
  var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
105933
- function formatTime(seconds) {
106400
+ function formatTime2(seconds) {
105934
106401
  const minutes = Math.floor(seconds / 60);
105935
106402
  const remainingSeconds = seconds % 60;
105936
106403
  return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
105937
106404
  }
105938
- __name(formatTime, "formatTime");
106405
+ __name(formatTime2, "formatTime");
105939
106406
  function QwenOAuthProgress({
105940
106407
  onTimeout,
105941
106408
  onCancel,
@@ -106032,7 +106499,7 @@ function QwenOAuthProgress({
106032
106499
  /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(Text, { children: [
106033
106500
  t("Time remaining:"),
106034
106501
  " ",
106035
- formatTime(timeRemaining)
106502
+ formatTime2(timeRemaining)
106036
106503
  ] })
106037
106504
  ] }),
106038
106505
  /* @__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 +106527,7 @@ function QwenOAuthProgress({
106060
106527
  /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(Text, { children: [
106061
106528
  t("Time remaining:"),
106062
106529
  " ",
106063
- formatTime(timeRemaining)
106530
+ formatTime2(timeRemaining)
106064
106531
  ] })
106065
106532
  ] }),
106066
106533
  /* @__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 +108450,7 @@ __name(TrustDialog, "TrustDialog");
107983
108450
  init_esbuild_shims();
107984
108451
  var import_react108 = __toESM(require_react(), 1);
107985
108452
  import * as fs31 from "node:fs";
107986
- import * as os19 from "node:os";
108453
+ import * as os18 from "node:os";
107987
108454
  import * as nodePath2 from "node:path";
107988
108455
  var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1);
107989
108456
  function getPermScopeItems() {
@@ -108098,7 +108565,7 @@ function PermissionsDialog({
108098
108565
  const dirCompletions = (0, import_react108.useMemo)(() => {
108099
108566
  const trimmed = newDirInput.trim();
108100
108567
  if (!trimmed) return [];
108101
- const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os19.homedir()) : trimmed;
108568
+ const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os18.homedir()) : trimmed;
108102
108569
  const endsWithSep = expanded.endsWith("/") || expanded.endsWith(nodePath2.sep);
108103
108570
  const searchDir = endsWithSep ? expanded : nodePath2.dirname(expanded);
108104
108571
  const prefix = endsWithSep ? "" : nodePath2.basename(expanded);
@@ -108172,7 +108639,7 @@ function PermissionsDialog({
108172
108639
  const handleAddDirSubmit = (0, import_react108.useCallback)(() => {
108173
108640
  const trimmed = newDirInput.trim();
108174
108641
  if (!trimmed) return;
108175
- const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os19.homedir()) : trimmed;
108642
+ const expanded = trimmed.startsWith("~") ? trimmed.replace(/^~/, os18.homedir()) : trimmed;
108176
108643
  const absoluteExpanded = nodePath2.isAbsolute(expanded) ? expanded : nodePath2.resolve(expanded);
108177
108644
  if (!fs31.existsSync(absoluteExpanded)) {
108178
108645
  setDirInputError(t("Directory does not exist."));
@@ -108840,7 +109307,9 @@ function ModelDialog({
108840
109307
  const availableModelEntries = (0, import_react109.useMemo)(() => {
108841
109308
  const allModels = config ? config.getAllConfiguredModels() : [];
108842
109309
  const runtimeModels = allModels.filter((m) => m.isRuntimeModel);
108843
- const registryModels = allModels.filter((m) => !m.isRuntimeModel);
109310
+ const registryModels = allModels.filter(
109311
+ (m) => !m.isRuntimeModel && (m.authType !== "qwen-oauth" /* QWEN_OAUTH */ || authType === "qwen-oauth" /* QWEN_OAUTH */)
109312
+ );
108844
109313
  const modelsByAuthTypeMap = /* @__PURE__ */ new Map();
108845
109314
  for (const model of registryModels) {
108846
109315
  const authType2 = model.authType;
@@ -108875,7 +109344,7 @@ function ModelDialog({
108875
109344
  }
108876
109345
  }
108877
109346
  return result;
108878
- }, [config]);
109347
+ }, [authType, config]);
108879
109348
  const MODEL_OPTIONS = (0, import_react109.useMemo)(
108880
109349
  () => availableModelEntries.map(
108881
109350
  ({ authType: t2, model, isRuntime, snapshotId }) => {
@@ -109747,11 +110216,11 @@ var import_react113 = __toESM(require_react(), 1);
109747
110216
  var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1);
109748
110217
  var STATUS_REFRESH_INTERVAL_MS = 2e3;
109749
110218
  var IN_PROCESS_REFRESH_INTERVAL_MS = 1e3;
109750
- function truncate(str, maxLen) {
110219
+ function truncate2(str, maxLen) {
109751
110220
  if (str.length <= maxLen) return str;
109752
110221
  return str.slice(0, maxLen - 1) + "\u2026";
109753
110222
  }
109754
- __name(truncate, "truncate");
110223
+ __name(truncate2, "truncate");
109755
110224
  function pad(str, len, align2 = "left") {
109756
110225
  if (str.length >= len) return str.slice(0, len);
109757
110226
  const padding = " ".repeat(len - str.length);
@@ -109878,7 +110347,7 @@ function ArenaStatusDialog({
109878
110347
  const successfulToolCalls = live?.successfulToolCalls ?? agent.stats.successfulToolCalls;
109879
110348
  const failedToolCalls = live?.failedToolCalls ?? agent.stats.failedToolCalls;
109880
110349
  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) }) }),
110350
+ /* @__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
110351
  /* @__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
110352
  /* @__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
110353
  /* @__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 +112847,11 @@ function sortSkills(skills) {
112378
112847
  );
112379
112848
  }
112380
112849
  __name(sortSkills, "sortSkills");
112381
- function truncate2(text, max) {
112850
+ function truncate3(text, max) {
112382
112851
  if (text.length <= max) return text;
112383
112852
  return `${text.slice(0, Math.max(0, max - 1))}\u2026`;
112384
112853
  }
112385
- __name(truncate2, "truncate");
112854
+ __name(truncate3, "truncate");
112386
112855
  function SkillsManagerDialog({
112387
112856
  settings,
112388
112857
  config,
@@ -112473,7 +112942,7 @@ function SkillsManagerDialog({
112473
112942
  () => filteredUnlocked.map((s) => ({
112474
112943
  key: s.name,
112475
112944
  value: { name: s.name, description: s.description, level: s.level },
112476
- label: `${truncate2(s.name, NAME_COLUMN).padEnd(NAME_COLUMN)} ${truncate2(
112945
+ label: `${truncate3(s.name, NAME_COLUMN).padEnd(NAME_COLUMN)} ${truncate3(
112477
112946
  s.description,
112478
112947
  80
112479
112948
  )} (${levelLabel(s.level)})`
@@ -112718,8 +113187,8 @@ function SkillsManagerDialog({
112718
113187
  filteredLocked.map((s) => {
112719
113188
  const scopeName = higher.scopeOf(s.name) ?? t("higher scope");
112720
113189
  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),
113190
+ name: truncate3(s.name, NAME_COLUMN).padEnd(NAME_COLUMN),
113191
+ description: truncate3(s.description, 60),
112723
113192
  scope: scopeName
112724
113193
  }) }, s.name);
112725
113194
  })
@@ -117862,7 +118331,7 @@ function convertToHistoryItems(conversation, config) {
117862
118331
  }
117863
118332
  case "assistant": {
117864
118333
  const parts = record.message?.parts;
117865
- const thoughtText = !config || !config.getContentGenerator().useSummarizedThinking() ? extractThoughtTextFromParts(parts) : "";
118334
+ const thoughtText = !config ? extractThoughtTextFromParts(parts) : "";
117866
118335
  const text = extractTextFromParts(parts);
117867
118336
  const functionCalls = extractFunctionCalls(parts);
117868
118337
  if (thoughtText) {
@@ -119339,7 +119808,7 @@ __name(emptyMessage, "emptyMessage");
119339
119808
  init_esbuild_shims();
119340
119809
  var import_react146 = __toESM(require_react(), 1);
119341
119810
  import fs32 from "node:fs/promises";
119342
- import os20 from "node:os";
119811
+ import os19 from "node:os";
119343
119812
  import path39 from "node:path";
119344
119813
  import { spawnSync as spawnSync4 } from "node:child_process";
119345
119814
  var import_jsx_runtime144 = __toESM(require_jsx_runtime(), 1);
@@ -119391,7 +119860,7 @@ async function ensureFileExists(filePath) {
119391
119860
  }
119392
119861
  __name(ensureFileExists, "ensureFileExists");
119393
119862
  function formatDisplayPath(filePath) {
119394
- const home = os20.homedir();
119863
+ const home = os19.homedir();
119395
119864
  if (filePath.startsWith(home)) {
119396
119865
  return `~${filePath.slice(home.length)}`;
119397
119866
  }
@@ -119726,6 +120195,8 @@ function entryId(entry) {
119726
120195
  return entry.shellId;
119727
120196
  case "monitor":
119728
120197
  return entry.monitorId;
120198
+ case "workflow":
120199
+ return entry.runId;
119729
120200
  case "dream":
119730
120201
  return entry.dreamId;
119731
120202
  default: {
@@ -119744,6 +120215,7 @@ function useBackgroundTaskView(config) {
119744
120215
  const agentRegistry = config.getBackgroundTaskRegistry();
119745
120216
  const shellRegistry = config.getBackgroundShellRegistry();
119746
120217
  const monitorRegistry = config.getMonitorRegistry();
120218
+ const workflowRegistry = config.getWorkflowRunRegistry();
119747
120219
  const memoryManager = config.getMemoryManager();
119748
120220
  const projectRoot = config.getProjectRoot();
119749
120221
  let lastDreamSig = "";
@@ -119752,6 +120224,7 @@ function useBackgroundTaskView(config) {
119752
120224
  const agentEntries = [...agentRegistry.getAll()];
119753
120225
  const shellEntries = [...shellRegistry.getAll()];
119754
120226
  const monitorEntries = [...monitorRegistry.getAll()];
120227
+ const workflowEntries = [...workflowRegistry.list()];
119755
120228
  const allDreams = dreamSnapshot ?? memoryManager.listTasksByType("dream", projectRoot);
119756
120229
  const runningDreams = allDreams.filter((t2) => t2.status === "running");
119757
120230
  const terminalDreams = allDreams.filter(
@@ -119784,6 +120257,7 @@ function useBackgroundTaskView(config) {
119784
120257
  ...agentEntries,
119785
120258
  ...shellEntries,
119786
120259
  ...monitorEntries,
120260
+ ...workflowEntries,
119787
120261
  ...dreamEntries
119788
120262
  ].sort((a, b) => {
119789
120263
  const aActive = isActive(a);
@@ -119800,6 +120274,7 @@ function useBackgroundTaskView(config) {
119800
120274
  agentRegistry.setStatusChangeCallback(refreshFromRegistry);
119801
120275
  shellRegistry.setStatusChangeCallback(refreshFromRegistry);
119802
120276
  monitorRegistry.setStatusChangeCallback(refreshFromRegistry);
120277
+ workflowRegistry.setStatusChangeCallback(refreshFromRegistry);
119803
120278
  agentRegistry.setApprovalChangeCallback(refreshFromRegistry);
119804
120279
  const memoryListener = /* @__PURE__ */ __name(() => {
119805
120280
  const dreams = memoryManager.listTasksByType("dream", projectRoot);
@@ -119814,6 +120289,7 @@ function useBackgroundTaskView(config) {
119814
120289
  agentRegistry.setStatusChangeCallback(void 0);
119815
120290
  shellRegistry.setStatusChangeCallback(void 0);
119816
120291
  monitorRegistry.setStatusChangeCallback(void 0);
120292
+ workflowRegistry.setStatusChangeCallback(void 0);
119817
120293
  agentRegistry.setApprovalChangeCallback(void 0);
119818
120294
  unsubscribeMemory();
119819
120295
  };
@@ -119948,6 +120424,9 @@ function BackgroundTaskViewProvider({
119948
120424
  }
119949
120425
  break;
119950
120426
  }
120427
+ case "workflow":
120428
+ config.getWorkflowRunRegistry().cancel(target.runId, Date.now());
120429
+ break;
119951
120430
  default: {
119952
120431
  const _exhaustive = target;
119953
120432
  throw new Error(
@@ -120124,6 +120603,12 @@ function rowLabel(entry) {
120124
120603
  return `${SHELL_ROW_PREFIX} ${entry.command}`;
120125
120604
  case "monitor":
120126
120605
  return `[monitor] ${entry.description}`;
120606
+ case "workflow": {
120607
+ const label = entry.meta?.name ?? entry.runId;
120608
+ const phase = entry.currentPhase ? ` \xB7 ${entry.currentPhase}` : "";
120609
+ const counts = entry.agentsDispatched > 0 ? ` (${entry.agentsCompleted}/${entry.agentsDispatched})` : "";
120610
+ return `[workflow] ${label}${phase}${counts}`;
120611
+ }
120127
120612
  case "dream":
120128
120613
  return formatDreamRowLabel(entry);
120129
120614
  default: {
@@ -120238,6 +120723,15 @@ var DetailBody = /* @__PURE__ */ __name(({ entry, maxHeight, maxWidth }) => {
120238
120723
  maxWidth
120239
120724
  }
120240
120725
  );
120726
+ case "workflow":
120727
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
120728
+ WorkflowDetailBody,
120729
+ {
120730
+ entry,
120731
+ maxHeight,
120732
+ maxWidth
120733
+ }
120734
+ );
120241
120735
  case "dream":
120242
120736
  return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
120243
120737
  DreamDetailBody,
@@ -120496,6 +120990,69 @@ var MonitorDetailBody = /* @__PURE__ */ __name(({ entry, maxHeight, maxWidth })
120496
120990
  }
120497
120991
  );
120498
120992
  }, "MonitorDetailBody");
120993
+ var MAX_VISIBLE_PHASES = 20;
120994
+ var MAX_VISIBLE_LOG_LINES = 10;
120995
+ var WorkflowDetailBody = /* @__PURE__ */ __name(({ entry, maxHeight, maxWidth }) => {
120996
+ const title = `${t("Workflow")} \u203A ${entry.meta?.name ?? entry.runId}`;
120997
+ const terminal = terminalStatusPresentation(entry.status);
120998
+ const dimSubtitleParts = [elapsedFor(entry)];
120999
+ if (entry.agentsDispatched > 0) {
121000
+ dimSubtitleParts.push(
121001
+ `${entry.agentsCompleted}/${entry.agentsDispatched} ${t("agents")}`
121002
+ );
121003
+ }
121004
+ dimSubtitleParts.push(
121005
+ `${entry.phases.length} ${entry.phases.length === 1 ? t("phase") : t("phases")}`
121006
+ );
121007
+ const phaseOverflow = Math.max(0, entry.phases.length - MAX_VISIBLE_PHASES);
121008
+ const visiblePhases = entry.phases.slice(-MAX_VISIBLE_PHASES);
121009
+ const logOverflow = Math.max(
121010
+ 0,
121011
+ entry.recentLogs.length - MAX_VISIBLE_LOG_LINES
121012
+ );
121013
+ const visibleLogs = entry.recentLogs.slice(-MAX_VISIBLE_LOG_LINES);
121014
+ const hasError = Boolean(entry.error);
121015
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(
121016
+ MaxSizedBox,
121017
+ {
121018
+ maxHeight,
121019
+ maxWidth,
121020
+ overflowDirection: "bottom",
121021
+ children: [
121022
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { bold: true, color: theme.text.accent, children: title }) }),
121023
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(Box_default, { children: [
121024
+ terminal && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { color: terminal.color, children: `${terminal.icon} ${statusVerb(entry.status)} \xB7 ` }),
121025
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { color: theme.text.secondary, children: dimSubtitleParts.join(" \xB7 ") })
121026
+ ] }),
121027
+ entry.meta?.description && /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_react149.Fragment, { children: [
121028
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, {}),
121029
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { wrap: "wrap", children: entry.meta.description }) })
121030
+ ] }),
121031
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, {}),
121032
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { bold: true, dimColor: true, children: t("Phases") }) }),
121033
+ 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: [
121034
+ 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")}` }) }),
121035
+ visiblePhases.map((phaseTitle, i) => {
121036
+ const isCurrent = entry.status === "running" && i === visiblePhases.length - 1 && entry.currentPhase === phaseTitle;
121037
+ const marker = isCurrent ? "\u25B8" : "\xB7";
121038
+ 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}`);
121039
+ })
121040
+ ] }),
121041
+ entry.recentLogs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_react149.Fragment, { children: [
121042
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, {}),
121043
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Text, { bold: true, dimColor: true, children: t("Logs") }) }),
121044
+ 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")}` }) }),
121045
+ 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}`))
121046
+ ] }),
121047
+ hasError && /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_react149.Fragment, { children: [
121048
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Box_default, {}),
121049
+ /* @__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") }) }),
121050
+ /* @__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 }) })
121051
+ ] })
121052
+ ]
121053
+ }
121054
+ );
121055
+ }, "WorkflowDetailBody");
120499
121056
  var BackgroundTasksDialog = /* @__PURE__ */ __name(({
120500
121057
  availableTerminalHeight,
120501
121058
  terminalWidth
@@ -121318,7 +121875,6 @@ var LoadingIndicator = /* @__PURE__ */ __name(({
121318
121875
  currentLoadingPhrase,
121319
121876
  elapsedTime,
121320
121877
  rightContent,
121321
- thought,
121322
121878
  candidatesTokens,
121323
121879
  streamingCharsRef,
121324
121880
  isStreaming,
@@ -121335,7 +121891,7 @@ var LoadingIndicator = /* @__PURE__ */ __name(({
121335
121891
  if (streamingState === "idle" /* Idle */) {
121336
121892
  return null;
121337
121893
  }
121338
- const primaryText = thought?.subject || currentLoadingPhrase;
121894
+ const primaryText = currentLoadingPhrase;
121339
121895
  const streamingTokens = streamingCharsRef ? Math.round(animatedChars / 4) : 0;
121340
121896
  const outputTokens = (candidatesTokens ?? 0) + streamingTokens;
121341
121897
  const showTokens = !isNarrow && outputTokens > 0;
@@ -121457,6 +122013,10 @@ var PrepareLabel = import_react152.default.memo(_PrepareLabel);
121457
122013
  // packages/cli/src/ui/components/SuggestionsDisplay.tsx
121458
122014
  var import_jsx_runtime150 = __toESM(require_jsx_runtime(), 1);
121459
122015
  var MAX_SUGGESTIONS_TO_SHOW = 8;
122016
+ function normalizeDescription(description) {
122017
+ return description.replace(/\s+/g, " ").trim();
122018
+ }
122019
+ __name(normalizeDescription, "normalizeDescription");
121460
122020
  function SuggestionsDisplay({
121461
122021
  suggestions,
121462
122022
  activeIndex,
@@ -121533,7 +122093,7 @@ function SuggestionsDisplay({
121533
122093
  flexGrow: 1,
121534
122094
  flexShrink: 1,
121535
122095
  paddingLeft: 2,
121536
- children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Text, { color: textColor, wrap: "wrap", children: suggestion.description })
122096
+ children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Text, { color: textColor, wrap: "truncate-end", children: normalizeDescription(suggestion.description) })
121537
122097
  }
121538
122098
  ),
121539
122099
  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 +125616,7 @@ var KIND_NAMES = {
125056
125616
  agent: { singular: "local agent", plural: "local agents" },
125057
125617
  shell: { singular: "shell", plural: "shells" },
125058
125618
  monitor: { singular: "monitor", plural: "monitors" },
125619
+ workflow: { singular: "workflow", plural: "workflows" },
125059
125620
  dream: { singular: "dream", plural: "dreams" }
125060
125621
  };
125061
125622
  function hasPendingApproval(entries) {
@@ -125080,12 +125641,13 @@ function getPillLabel(entries) {
125080
125641
  }
125081
125642
  __name(getPillLabel, "getPillLabel");
125082
125643
  function groupAndFormat(entries) {
125083
- const counts = { agent: 0, shell: 0, monitor: 0, dream: 0 };
125644
+ const counts = { agent: 0, shell: 0, monitor: 0, workflow: 0, dream: 0 };
125084
125645
  for (const e of entries) counts[e.kind]++;
125085
125646
  const parts = [];
125086
125647
  if (counts.shell > 0) parts.push(formatCount("shell", counts.shell));
125087
125648
  if (counts.agent > 0) parts.push(formatCount("agent", counts.agent));
125088
125649
  if (counts.monitor > 0) parts.push(formatCount("monitor", counts.monitor));
125650
+ if (counts.workflow > 0) parts.push(formatCount("workflow", counts.workflow));
125089
125651
  if (counts.dream > 0) parts.push(formatCount("dream", counts.dream));
125090
125652
  return parts.join(", ");
125091
125653
  }
@@ -125994,7 +126556,6 @@ var Composer = /* @__PURE__ */ __name(() => {
125994
126556
  !uiState.embeddedShellFocused && !suppressBottomLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime164.jsx)(
125995
126557
  LoadingIndicator,
125996
126558
  {
125997
- thought: uiState.streamingState === "waiting_for_confirmation" /* WaitingForConfirmation */ || config.getAccessibility()?.enableLoadingPhrases === false ? void 0 : uiState.thought,
125998
126559
  currentLoadingPhrase: config.getAccessibility()?.enableLoadingPhrases === false ? void 0 : uiState.currentLoadingPhrase,
125999
126560
  elapsedTime: uiState.elapsedTime,
126000
126561
  candidatesTokens: agentTokens,
@@ -127444,12 +128005,12 @@ import process38 from "node:process";
127444
128005
  init_esbuild_shims();
127445
128006
  var import_react184 = __toESM(require_react(), 1);
127446
128007
  import process25 from "node:process";
127447
- import os21 from "node:os";
128008
+ import os20 from "node:os";
127448
128009
  import v82 from "v8";
127449
128010
  var debugLogger61 = createDebugLogger("MEMORY_MONITOR");
127450
128011
  var MEMORY_WARNING_THRESHOLD = Math.min(
127451
128012
  7 * 1024 * 1024 * 1024,
127452
- Math.floor(os21.totalmem() * 0.85)
128013
+ Math.floor(os20.totalmem() * 0.85)
127453
128014
  );
127454
128015
  var MEMORY_UI_COMPACT_THRESHOLD = /* @__PURE__ */ __name(() => Math.floor(v82.getHeapStatistics().heap_size_limit * 0.65), "MEMORY_UI_COMPACT_THRESHOLD");
127455
128016
  var MEMORY_CHECK_INTERVAL = 60 * 1e3;
@@ -129161,7 +129722,7 @@ init_esbuild_shims();
129161
129722
  var import_react198 = __toESM(require_react(), 1);
129162
129723
  import crypto4 from "node:crypto";
129163
129724
  import path42 from "node:path";
129164
- import os22 from "node:os";
129725
+ import os21 from "node:os";
129165
129726
  import fs36 from "node:fs";
129166
129727
  var OUTPUT_UPDATE_INTERVAL_MS = 1e3;
129167
129728
  var MAX_OUTPUT_LENGTH = 1e4;
@@ -129199,14 +129760,14 @@ var useShellCommandProcessor = /* @__PURE__ */ __name((addItemToHistory, setPend
129199
129760
  { type: "user_shell", text: rawQuery },
129200
129761
  userMessageTimestamp
129201
129762
  );
129202
- const isWindows4 = os22.platform() === "win32";
129763
+ const isWindows4 = os21.platform() === "win32";
129203
129764
  const targetDir = config.getTargetDir();
129204
129765
  let commandToExecute = rawQuery;
129205
129766
  let pwdFilePath;
129206
129767
  if (!isWindows4) {
129207
129768
  let command2 = rawQuery.trim();
129208
129769
  const pwdFileName = `shell_pwd_${crypto4.randomBytes(6).toString("hex")}.tmp`;
129209
- pwdFilePath = path42.join(os22.tmpdir(), pwdFileName);
129770
+ pwdFilePath = path42.join(os21.tmpdir(), pwdFileName);
129210
129771
  if (!command2.endsWith(";") && !command2.endsWith("&")) {
129211
129772
  command2 += ";";
129212
129773
  }
@@ -129882,6 +130443,8 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
129882
130443
  }, [history]);
129883
130444
  const summaryAbortRefsRef = (0, import_react202.useRef)(/* @__PURE__ */ new Set());
129884
130445
  const [pendingHistoryItem, pendingHistoryItemRef, setPendingHistoryItem] = useStateAndRef(null);
130446
+ const [pendingThoughtItem, pendingThoughtItemRef, setPendingThoughtItem] = useStateAndRef(null);
130447
+ const thoughtStartTimeRef = (0, import_react202.useRef)(null);
129885
130448
  const [
129886
130449
  pendingRetryErrorItem,
129887
130450
  pendingRetryErrorItemRef,
@@ -130294,7 +130857,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130294
130857
  [setThought]
130295
130858
  );
130296
130859
  const handleThoughtEvent = (0, import_react202.useCallback)(
130297
- (eventValue, currentThoughtBuffer, userMessageTimestamp) => {
130860
+ (eventValue, currentThoughtBuffer) => {
130298
130861
  if (turnCancelledRef.current) {
130299
130862
  return "";
130300
130863
  }
@@ -130302,56 +130865,41 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130302
130865
  if (!thoughtText) {
130303
130866
  return currentThoughtBuffer;
130304
130867
  }
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
- );
130868
+ const newThoughtBuffer = currentThoughtBuffer + thoughtText;
130869
+ if (newThoughtBuffer.trim().length === 0) {
130870
+ return newThoughtBuffer;
130310
130871
  }
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: "" });
130872
+ const startingNewThought = currentThoughtBuffer.trim().length === 0;
130873
+ const description = startingNewThought ? stripLeadingBlankLines(newThoughtBuffer) : thoughtText;
130874
+ if (startingNewThought) {
130875
+ thoughtStartTimeRef.current = Date.now();
130327
130876
  }
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;
130877
+ mergeThought({
130878
+ ...eventValue,
130879
+ description
130880
+ });
130881
+ setPendingThoughtItem({
130882
+ type: "gemini_thought",
130883
+ text: stripLeadingBlankLines(newThoughtBuffer),
130884
+ durationMs: thoughtStartTimeRef.current ? Date.now() - thoughtStartTimeRef.current : 0
130885
+ });
130886
+ return startingNewThought ? description : newThoughtBuffer;
130887
+ },
130888
+ [mergeThought, setPendingThoughtItem]
130889
+ );
130890
+ const commitPendingThought = (0, import_react202.useCallback)(
130891
+ (userMessageTimestamp) => {
130892
+ if (pendingThoughtItemRef.current) {
130893
+ const item = { ...pendingThoughtItemRef.current };
130894
+ if (item.type === "gemini_thought" && thoughtStartTimeRef.current) {
130895
+ item.durationMs = Date.now() - thoughtStartTimeRef.current;
130896
+ }
130897
+ addItem(item, userMessageTimestamp);
130350
130898
  }
130351
- mergeThought(thoughtToMerge);
130352
- return newThoughtBuffer;
130899
+ setPendingThoughtItem(null);
130900
+ thoughtStartTimeRef.current = null;
130353
130901
  },
130354
- [addItem, pendingHistoryItemRef, setPendingHistoryItem, mergeThought]
130902
+ [addItem, pendingThoughtItemRef, setPendingThoughtItem]
130355
130903
  );
130356
130904
  const handleUserCancelledEvent = (0, import_react202.useCallback)(
130357
130905
  (userMessageTimestamp) => {
@@ -130359,6 +130907,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130359
130907
  return;
130360
130908
  }
130361
130909
  lastPromptErroredRef.current = false;
130910
+ commitPendingThought(userMessageTimestamp);
130362
130911
  if (pendingHistoryItemRef.current) {
130363
130912
  if (pendingHistoryItemRef.current.type === "tool_group") {
130364
130913
  const updatedTools = pendingHistoryItemRef.current.tools.map(
@@ -130384,6 +130933,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130384
130933
  },
130385
130934
  [
130386
130935
  addItem,
130936
+ commitPendingThought,
130387
130937
  pendingHistoryItemRef,
130388
130938
  setPendingHistoryItem,
130389
130939
  setThought,
@@ -130393,6 +130943,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130393
130943
  const handleErrorEvent = (0, import_react202.useCallback)(
130394
130944
  (eventValue, userMessageTimestamp) => {
130395
130945
  lastPromptErroredRef.current = true;
130946
+ commitPendingThought(userMessageTimestamp);
130396
130947
  if (pendingHistoryItemRef.current) {
130397
130948
  addItem(pendingHistoryItemRef.current, userMessageTimestamp);
130398
130949
  setPendingHistoryItem(null);
@@ -130423,6 +130974,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130423
130974
  },
130424
130975
  [
130425
130976
  addItem,
130977
+ commitPendingThought,
130426
130978
  pendingHistoryItemRef,
130427
130979
  setPendingHistoryItem,
130428
130980
  setPendingRetryErrorItem,
@@ -130673,11 +131225,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130673
131225
  description: `${mergedThought.description ?? ""}${queuedThought.value.description ?? ""}`
130674
131226
  };
130675
131227
  }
130676
- thoughtBuffer = handleThoughtEvent(
130677
- mergedThought,
130678
- thoughtBuffer,
130679
- userMessageTimestamp
130680
- );
131228
+ thoughtBuffer = handleThoughtEvent(mergedThought, thoughtBuffer);
130681
131229
  }
130682
131230
  }, "flushBufferedStreamEvents");
130683
131231
  const scheduleBufferedStreamFlush = /* @__PURE__ */ __name(() => {
@@ -130704,11 +131252,20 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130704
131252
  }
130705
131253
  break;
130706
131254
  case "content" /* Content */:
131255
+ if (pendingThoughtItemRef.current || bufferedEvents.some((e) => e.kind === "thought")) {
131256
+ flushBufferedStreamEvents();
131257
+ commitPendingThought(userMessageTimestamp);
131258
+ thoughtBuffer = "";
131259
+ }
131260
+ setThought((prev) => prev ? null : prev);
130707
131261
  bufferedEvents.push({ kind: "content", value: event.value });
130708
131262
  scheduleBufferedStreamFlush();
130709
131263
  break;
130710
131264
  case "tool_call_request" /* ToolCallRequest */:
130711
131265
  flushBufferedStreamEvents();
131266
+ commitPendingThought(userMessageTimestamp);
131267
+ thoughtBuffer = "";
131268
+ setThought((prev) => prev ? null : prev);
130712
131269
  toolCallRequests.push(event.value);
130713
131270
  try {
130714
131271
  const argsJson = JSON.stringify(event.value.args);
@@ -130743,6 +131300,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130743
131300
  break;
130744
131301
  case "finished" /* Finished */:
130745
131302
  flushBufferedStreamEvents();
131303
+ commitPendingThought(userMessageTimestamp);
130746
131304
  handleFinishedEvent(
130747
131305
  event,
130748
131306
  userMessageTimestamp
@@ -130753,6 +131311,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130753
131311
  }
130754
131312
  geminiMessageBuffer = "";
130755
131313
  thoughtBuffer = "";
131314
+ setThought(null);
130756
131315
  break;
130757
131316
  case "citation" /* Citation */:
130758
131317
  flushBufferedStreamEvents();
@@ -130768,8 +131327,10 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130768
131327
  if (pendingHistoryItemRef.current) {
130769
131328
  setPendingHistoryItem(null);
130770
131329
  }
130771
- geminiMessageBuffer = "";
131330
+ commitPendingThought(userMessageTimestamp);
130772
131331
  thoughtBuffer = "";
131332
+ setThought(null);
131333
+ geminiMessageBuffer = "";
130773
131334
  } else {
130774
131335
  flushBufferedStreamEvents();
130775
131336
  }
@@ -130816,6 +131377,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130816
131377
  }
130817
131378
  } finally {
130818
131379
  flushBufferedStreamEvents();
131380
+ commitPendingThought(userMessageTimestamp);
130819
131381
  discardBufferedStreamEvents();
130820
131382
  flushBufferedStreamEventsRef.current.delete(flushBufferedStreamEvents);
130821
131383
  }
@@ -130839,7 +131401,9 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130839
131401
  startRetryCountdown,
130840
131402
  clearRetryCountdown,
130841
131403
  setThought,
131404
+ commitPendingThought,
130842
131405
  pendingHistoryItemRef,
131406
+ pendingThoughtItemRef,
130843
131407
  setPendingHistoryItem,
130844
131408
  handleUserPromptSubmitBlockedEvent,
130845
131409
  handleStopHookLoopEvent,
@@ -130926,6 +131490,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
130926
131490
  );
130927
131491
  }
130928
131492
  setThought(null);
131493
+ setPendingThoughtItem(null);
130929
131494
  }
130930
131495
  if (submitType === "retry" /* Retry */) {
130931
131496
  logUserRetry(config, new UserRetryEvent(prompt_id));
@@ -131047,6 +131612,7 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
131047
131612
  pendingRetryCountdownItemRef,
131048
131613
  pendingRetryErrorItemRef,
131049
131614
  setPendingRetryErrorItem,
131615
+ setPendingThoughtItem,
131050
131616
  dualOutput
131051
131617
  ]
131052
131618
  );
@@ -131289,12 +131855,15 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
131289
131855
  );
131290
131856
  const pendingHistoryItems = (0, import_react202.useMemo)(
131291
131857
  () => [
131858
+ // Reasoning renders above the streaming answer.
131859
+ pendingThoughtItem,
131292
131860
  pendingHistoryItem,
131293
131861
  pendingRetryErrorItem,
131294
131862
  pendingRetryCountdownItem,
131295
131863
  pendingToolCallGroupDisplay
131296
131864
  ].filter((i) => i !== void 0 && i !== null),
131297
131865
  [
131866
+ pendingThoughtItem,
131298
131867
  pendingHistoryItem,
131299
131868
  pendingRetryErrorItem,
131300
131869
  pendingRetryCountdownItem,
@@ -131439,7 +132008,11 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
131439
132008
  }, [config]);
131440
132009
  (0, import_react202.useEffect)(() => {
131441
132010
  const registry2 = config.getMonitorRegistry();
131442
- registry2.setNotificationCallback((displayText, modelText) => {
132011
+ registry2.setNotificationCallback((displayText, modelText, meta) => {
132012
+ if (meta.status === "running" && typeof registry2.get === "function") {
132013
+ const entry = registry2.get(meta.monitorId);
132014
+ if (!entry || entry.status !== "running") return;
132015
+ }
131443
132016
  notificationQueueRef.current.push({
131444
132017
  displayText,
131445
132018
  modelText,
@@ -131453,13 +132026,32 @@ var useGeminiStream = /* @__PURE__ */ __name((geminiClient, history, addItem, co
131453
132026
  }, [config]);
131454
132027
  (0, import_react202.useEffect)(() => {
131455
132028
  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
132029
+ const queue = notificationQueueRef.current;
132030
+ const targetType = queue[0].sendMessageType;
132031
+ if (targetType === "cron" /* Cron */) {
132032
+ const item = queue.shift();
132033
+ addItem(
132034
+ { type: "notification", text: item.displayText },
132035
+ Date.now()
132036
+ );
132037
+ submitQuery(item.modelText, item.sendMessageType, void 0, {
132038
+ notificationDisplayText: item.displayText
132039
+ });
132040
+ return;
132041
+ }
132042
+ let splitIdx = 0;
132043
+ while (splitIdx < queue.length && queue[splitIdx].sendMessageType === targetType) {
132044
+ splitIdx++;
132045
+ }
132046
+ const batch = queue.splice(0, splitIdx);
132047
+ const now = Date.now();
132048
+ for (const item of batch) {
132049
+ addItem({ type: "notification", text: item.displayText }, now);
132050
+ }
132051
+ const combinedModelText = batch.map((e) => e.modelText).join("\n\n");
132052
+ const combinedDisplayText = batch.map((e) => e.displayText).join("; ");
132053
+ submitQuery(combinedModelText, targetType, void 0, {
132054
+ notificationDisplayText: combinedDisplayText
131463
132055
  });
131464
132056
  }
131465
132057
  }, [streamingState, submitQuery, notificationTrigger, addItem]);
@@ -133706,13 +134298,13 @@ import { format as format3 } from "node:util";
133706
134298
  init_esbuild_shims();
133707
134299
  var import_graceful_fs = __toESM(require_graceful_fs(), 1);
133708
134300
  import path49 from "node:path";
133709
- import os25 from "node:os";
134301
+ import os24 from "node:os";
133710
134302
 
133711
134303
  // node_modules/xdg-basedir/index.js
133712
134304
  init_esbuild_shims();
133713
- import os23 from "os";
134305
+ import os22 from "os";
133714
134306
  import path46 from "path";
133715
- var homeDirectory = os23.homedir();
134307
+ var homeDirectory = os22.homedir();
133716
134308
  var { env: env3 } = process;
133717
134309
  var xdgData = env3.XDG_DATA_HOME || (homeDirectory ? path46.join(homeDirectory, ".local", "share") : void 0);
133718
134310
  var xdgConfig = env3.XDG_CONFIG_HOME || (homeDirectory ? path46.join(homeDirectory, ".config") : void 0);
@@ -133947,14 +134539,14 @@ var dist_default6 = FS;
133947
134539
 
133948
134540
  // node_modules/atomically/dist/constants.js
133949
134541
  init_esbuild_shims();
133950
- import os24 from "node:os";
134542
+ import os23 from "node:os";
133951
134543
  import process30 from "node:process";
133952
134544
  var DEFAULT_ENCODING = "utf8";
133953
134545
  var DEFAULT_FILE_MODE = 438;
133954
134546
  var DEFAULT_FOLDER_MODE = 511;
133955
134547
  var DEFAULT_WRITE_OPTIONS = {};
133956
- var DEFAULT_USER_UID = os24.userInfo().uid;
133957
- var DEFAULT_USER_GID = os24.userInfo().gid;
134548
+ var DEFAULT_USER_UID = os23.userInfo().uid;
134549
+ var DEFAULT_USER_GID = os23.userInfo().gid;
133958
134550
  var DEFAULT_TIMEOUT_SYNC = 1e3;
133959
134551
  var IS_POSIX = !!process30.getuid;
133960
134552
  var IS_USER_ROOT2 = process30.getuid ? !process30.getuid() : false;
@@ -134407,7 +134999,7 @@ __name(hasProperty, "hasProperty");
134407
134999
  // node_modules/configstore/index.js
134408
135000
  function getConfigDirectory(id, globalConfigPath) {
134409
135001
  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);
135002
+ const configDirectory = xdgConfig ?? import_graceful_fs.default.mkdtempSync(import_graceful_fs.default.realpathSync(os24.tmpdir()) + path49.sep);
134411
135003
  return path49.join(configDirectory, pathPrefix);
134412
135004
  }
134413
135005
  __name(getConfigDirectory, "getConfigDirectory");
@@ -134686,7 +135278,7 @@ var ansi_styles_default5 = ansiStyles5;
134686
135278
  // node_modules/update-notifier/node_modules/chalk/source/vendor/supports-color/index.js
134687
135279
  init_esbuild_shims();
134688
135280
  import process33 from "node:process";
134689
- import os26 from "node:os";
135281
+ import os25 from "node:os";
134690
135282
  import tty3 from "node:tty";
134691
135283
  function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process33.argv) {
134692
135284
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
@@ -134754,7 +135346,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
134754
135346
  return min;
134755
135347
  }
134756
135348
  if (process33.platform === "win32") {
134757
- const osRelease = os26.release().split(".");
135349
+ const osRelease = os25.release().split(".");
134758
135350
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
134759
135351
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
134760
135352
  }
@@ -135751,7 +136343,7 @@ init_esbuild_shims();
135751
136343
  var import_ini = __toESM(require_ini3(), 1);
135752
136344
  import process35 from "node:process";
135753
136345
  import path50 from "node:path";
135754
- import os27 from "node:os";
136346
+ import os26 from "node:os";
135755
136347
  import fs41 from "node:fs";
135756
136348
  var isWindows3 = process35.platform === "win32";
135757
136349
  var readRc = /* @__PURE__ */ __name((filePath) => {
@@ -135786,7 +136378,7 @@ var getNpmPrefix = /* @__PURE__ */ __name(() => {
135786
136378
  if (envPrefix) {
135787
136379
  return envPrefix;
135788
136380
  }
135789
- const homePrefix = readRc(path50.join(os27.homedir(), ".npmrc"));
136381
+ const homePrefix = readRc(path50.join(os26.homedir(), ".npmrc"));
135790
136382
  if (homePrefix) {
135791
136383
  return homePrefix;
135792
136384
  }
@@ -135817,11 +136409,11 @@ var getYarnPrefix = /* @__PURE__ */ __name(() => {
135817
136409
  if (windowsPrefix) {
135818
136410
  return windowsPrefix;
135819
136411
  }
135820
- const configPrefix = path50.join(os27.homedir(), ".config/yarn");
136412
+ const configPrefix = path50.join(os26.homedir(), ".config/yarn");
135821
136413
  if (fs41.existsSync(configPrefix)) {
135822
136414
  return configPrefix;
135823
136415
  }
135824
- const homePrefix = path50.join(os27.homedir(), ".yarn-config");
136416
+ const homePrefix = path50.join(os26.homedir(), ".yarn-config");
135825
136417
  if (fs41.existsSync(homePrefix)) {
135826
136418
  return homePrefix;
135827
136419
  }
@@ -136954,7 +137546,7 @@ import { spawn as spawn6 } from "node:child_process";
136954
137546
  var spawnWrapper = spawn6;
136955
137547
 
136956
137548
  // packages/cli/src/utils/handleAutoUpdate.ts
136957
- import os28 from "node:os";
137549
+ import os27 from "node:os";
136958
137550
  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
137551
  var UPDATE_FAILED_MESSAGE = "Automatic update failed. Please try updating manually.";
136960
137552
  function handleAutoUpdate(info, settings, projectRoot, spawnFn = spawnWrapper) {
@@ -136993,7 +137585,7 @@ ${installationInfo.updateMessage}`;
136993
137585
  "@latest",
136994
137586
  isNightly ? "@nightly" : `@${info.update.latest}`
136995
137587
  );
136996
- const isWindows4 = os28.platform() === "win32";
137588
+ const isWindows4 = os27.platform() === "win32";
136997
137589
  const shell = isWindows4 ? "cmd.exe" : "bash";
136998
137590
  const shellArgs = isWindows4 ? ["/c", updateCommand2] : ["-c", updateCommand2];
136999
137591
  const updateProcess = spawnFn(shell, shellArgs, { stdio: "pipe" });
@@ -138251,6 +138843,10 @@ function dedupeNewestFirst(messages) {
138251
138843
  return result;
138252
138844
  }
138253
138845
  __name(dedupeNewestFirst, "dedupeNewestFirst");
138846
+ function mergeStartupWarnings(currentWarnings, nextWarnings) {
138847
+ return [.../* @__PURE__ */ new Set([...currentWarnings, ...nextWarnings])];
138848
+ }
138849
+ __name(mergeStartupWarnings, "mergeStartupWarnings");
138254
138850
  var SHELL_WIDTH_FRACTION = 0.89;
138255
138851
  var SHELL_HEIGHT_PADDING = 10;
138256
138852
  var AppContainer = /* @__PURE__ */ __name((props) => {
@@ -138383,6 +138979,9 @@ var AppContainer = /* @__PURE__ */ __name((props) => {
138383
138979
  computeWindowTitle(basename11(config.getTargetDir()))
138384
138980
  );
138385
138981
  const lastTitleRef = (0, import_react230.useRef)(null);
138982
+ const [startupWarnings, setStartupWarnings] = (0, import_react230.useState)(
138983
+ () => props.startupWarnings || []
138984
+ );
138386
138985
  const staticExtraHeight = 3;
138387
138986
  (0, import_react230.useEffect)(() => {
138388
138987
  void loadLowlight().catch((err) => {
@@ -138395,6 +138994,9 @@ var AppContainer = /* @__PURE__ */ __name((props) => {
138395
138994
  (async () => {
138396
138995
  profileCheckpoint("config_initialize_start");
138397
138996
  await config.initialize();
138997
+ setStartupWarnings(
138998
+ (currentWarnings) => mergeStartupWarnings(currentWarnings, config.getWarnings())
138999
+ );
138398
139000
  profileCheckpoint("config_initialize_end");
138399
139001
  setConfigInitialized(true);
138400
139002
  profileCheckpoint("input_enabled");
@@ -140693,7 +141295,7 @@ ${migrationResult.failedFiles.map((f) => ` \u2022 ${f.file}: ${f.error}`).join(
140693
141295
  {
140694
141296
  value: {
140695
141297
  version: props.version,
140696
- startupWarnings: props.startupWarnings || []
141298
+ startupWarnings
140697
141299
  },
140698
141300
  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
141301
  }
@@ -140830,7 +141432,7 @@ __name(relaunchAppInChildProcess, "relaunchAppInChildProcess");
140830
141432
  init_esbuild_shims();
140831
141433
  var import_shell_quote = __toESM(require_shell_quote(), 1);
140832
141434
  import { exec as exec7, execSync as execSync5, spawn as spawn8 } from "node:child_process";
140833
- import os29 from "node:os";
141435
+ import os28 from "node:os";
140834
141436
  import path56 from "node:path";
140835
141437
  import fs46 from "node:fs";
140836
141438
  import { fileURLToPath as fileURLToPath4 } from "node:url";
@@ -140838,7 +141440,7 @@ import { promisify as promisify3 } from "node:util";
140838
141440
  import { randomBytes } from "node:crypto";
140839
141441
  var execAsync2 = promisify3(exec7);
140840
141442
  function getContainerPath(hostPath) {
140841
- if (os29.platform() !== "win32") {
141443
+ if (os28.platform() !== "win32") {
140842
141444
  return hostPath;
140843
141445
  }
140844
141446
  const withForwardSlashes = hostPath.replace(/\\/g, "/");
@@ -140875,7 +141477,7 @@ async function shouldUseCurrentUserInSandbox() {
140875
141477
  if (envVar === "0" || envVar === "false") {
140876
141478
  return false;
140877
141479
  }
140878
- if (os29.platform() === "linux") {
141480
+ if (os28.platform() === "linux") {
140879
141481
  const debugEnv = [process.env["DEBUG"], process.env["DEBUG_MODE"]].some(
140880
141482
  (v) => v === "true" || v === "1"
140881
141483
  );
@@ -140900,7 +141502,7 @@ function ports() {
140900
141502
  }
140901
141503
  __name(ports, "ports");
140902
141504
  function entrypoint(workdir, cliArgs) {
140903
- const isWindows4 = os29.platform() === "win32";
141505
+ const isWindows4 = os28.platform() === "win32";
140904
141506
  const containerWorkdir = getContainerPath(workdir);
140905
141507
  const shellCmds = [];
140906
141508
  const pathSeparator = isWindows4 ? ";" : ":";
@@ -140983,9 +141585,9 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
140983
141585
  "-D",
140984
141586
  `TARGET_DIR=${fs46.realpathSync(process.cwd())}`,
140985
141587
  "-D",
140986
- `TMP_DIR=${fs46.realpathSync(os29.tmpdir())}`,
141588
+ `TMP_DIR=${fs46.realpathSync(os28.tmpdir())}`,
140987
141589
  "-D",
140988
- `HOME_DIR=${fs46.realpathSync(os29.homedir())}`,
141590
+ `HOME_DIR=${fs46.realpathSync(os28.homedir())}`,
140989
141591
  "-D",
140990
141592
  `CACHE_DIR=${fs46.realpathSync(execSync5(`getconf DARWIN_USER_CACHE_DIR`).toString().trim())}`,
140991
141593
  "-D",
@@ -141181,8 +141783,8 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141181
141783
  if (!runtimeSameAsUserSettings) {
141182
141784
  args.push("--env", `QWEN_RUNTIME_DIR=${runtimeBaseDirContainerPath}`);
141183
141785
  }
141184
- args.push("--volume", `${os29.tmpdir()}:${getContainerPath(os29.tmpdir())}`);
141185
- const gcloudConfigDir = path56.join(os29.homedir(), ".config", "gcloud");
141786
+ args.push("--volume", `${os28.tmpdir()}:${getContainerPath(os28.tmpdir())}`);
141787
+ const gcloudConfigDir = path56.join(os28.homedir(), ".config", "gcloud");
141186
141788
  if (fs46.existsSync(gcloudConfigDir)) {
141187
141789
  args.push(
141188
141790
  "--volume",
@@ -141393,7 +141995,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141393
141995
  }
141394
141996
  args.push("--env", `SANDBOX=${containerName}`);
141395
141997
  if (config.command === "podman") {
141396
- const emptyAuthFilePath = path56.join(os29.tmpdir(), "empty_auth.json");
141998
+ const emptyAuthFilePath = path56.join(os28.tmpdir(), "empty_auth.json");
141397
141999
  fs46.writeFileSync(emptyAuthFilePath, "{}", "utf-8");
141398
142000
  args.push("--authfile", emptyAuthFilePath);
141399
142001
  }
@@ -141405,7 +142007,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141405
142007
  const uid = execSync5("id -u").toString().trim();
141406
142008
  const gid = execSync5("id -g").toString().trim();
141407
142009
  const username = "qwen";
141408
- const homeDir = getContainerPath(os29.homedir());
142010
+ const homeDir = getContainerPath(os28.homedir());
141409
142011
  const setupUserCommands = [
141410
142012
  // Use -f with groupadd to avoid errors if the group already exists.
141411
142013
  `groupadd -f -g ${gid} ${username}`,
@@ -141417,7 +142019,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141417
142019
  const suCommand = `su -p ${username} -c '${escapedOriginalCommand}'`;
141418
142020
  finalEntrypoint[2] = `${setupUserCommands} && ${suCommand}`;
141419
142021
  userFlag = `--user ${uid}:${gid}`;
141420
- args.push("--env", `HOME=${os29.homedir()}`);
142022
+ args.push("--env", `HOME=${os28.homedir()}`);
141421
142023
  } else if (isIntegrationTest) {
141422
142024
  args.push("--user", "root");
141423
142025
  userFlag = "--user root";
@@ -141428,7 +142030,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig, cliArgs = []) {
141428
142030
  let sandboxProcess = void 0;
141429
142031
  if (proxyCommand) {
141430
142032
  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";
142033
+ const isWindows4 = os28.platform() === "win32";
141432
142034
  const proxyShell = isWindows4 ? "cmd.exe" : "bash";
141433
142035
  const proxyShellArgs = isWindows4 ? ["/c", proxyContainerCommand] : ["-c", proxyContainerCommand];
141434
142036
  proxyProcess = spawn8(proxyShell, proxyShellArgs, {
@@ -141594,9 +142196,9 @@ __name(ensureSandboxImageIsPresent, "ensureSandboxImageIsPresent");
141594
142196
  // packages/cli/src/utils/startupWarnings.ts
141595
142197
  init_esbuild_shims();
141596
142198
  import fs47 from "node:fs/promises";
141597
- import os30 from "node:os";
142199
+ import os29 from "node:os";
141598
142200
  import { join as pathJoin } from "node:path";
141599
- var warningsFilePath = pathJoin(os30.tmpdir(), "qwen-code-warnings.txt");
142201
+ var warningsFilePath = pathJoin(os29.tmpdir(), "qwen-code-warnings.txt");
141600
142202
  async function getStartupWarnings() {
141601
142203
  try {
141602
142204
  await fs47.access(warningsFilePath);
@@ -141620,7 +142222,7 @@ __name(getStartupWarnings, "getStartupWarnings");
141620
142222
  // packages/cli/src/utils/userStartupWarnings.ts
141621
142223
  init_esbuild_shims();
141622
142224
  import fs48 from "node:fs/promises";
141623
- import * as os31 from "node:os";
142225
+ import * as os30 from "node:os";
141624
142226
  import path57 from "node:path";
141625
142227
  var homeDirectoryCheck = {
141626
142228
  id: "home-directory",
@@ -141628,7 +142230,7 @@ var homeDirectoryCheck = {
141628
142230
  try {
141629
142231
  const [workspaceRealPath, homeRealPath] = await Promise.all([
141630
142232
  fs48.realpath(options.workspaceRoot),
141631
- fs48.realpath(os31.homedir())
142233
+ fs48.realpath(os30.homedir())
141632
142234
  ]);
141633
142235
  if (workspaceRealPath === homeRealPath) {
141634
142236
  return "You are running Qwen Code in your home directory. It is recommended to run in a project-specific directory.";
@@ -143148,9 +143750,10 @@ __name(toPermissionOptions, "toPermissionOptions");
143148
143750
  // packages/cli/src/acp-integration/session/SubAgentTracker.ts
143149
143751
  var debugLogger75 = createDebugLogger("ACP_SUBAGENT_TRACKER");
143150
143752
  var SubAgentTracker = class {
143151
- constructor(ctx, client, parentToolCallId, subagentType) {
143753
+ constructor(ctx, client, parentToolCallId, subagentType, onAskUserQuestionCancel) {
143152
143754
  this.ctx = ctx;
143153
143755
  this.client = client;
143756
+ this.onAskUserQuestionCancel = onAskUserQuestionCancel;
143154
143757
  this.toolCallEmitter = new ToolCallEmitter(ctx);
143155
143758
  this.messageEmitter = new MessageEmitter(ctx);
143156
143759
  this.subagentMeta = { parentToolCallId, subagentType };
@@ -143280,12 +143883,25 @@ var SubAgentTracker = class {
143280
143883
  await event.respond(outcome, {
143281
143884
  answers: "answers" in output ? output.answers : void 0
143282
143885
  });
143886
+ if (outcome === "cancel" /* Cancel */ && event.name === ToolNames.ASK_USER_QUESTION) {
143887
+ this.onAskUserQuestionCancel?.();
143888
+ }
143283
143889
  } catch (error) {
143284
143890
  debugLogger75.error(
143285
143891
  `Permission request failed for subagent tool ${event.name}:`,
143286
143892
  error
143287
143893
  );
143288
- await event.respond("cancel" /* Cancel */);
143894
+ if (event.name === ToolNames.ASK_USER_QUESTION) {
143895
+ this.onAskUserQuestionCancel?.();
143896
+ }
143897
+ try {
143898
+ await event.respond("cancel" /* Cancel */);
143899
+ } catch (respondError) {
143900
+ debugLogger75.error(
143901
+ `Failed to cancel subagent tool ${event.name} after permission request failure:`,
143902
+ respondError
143903
+ );
143904
+ }
143289
143905
  }
143290
143906
  };
143291
143907
  }
@@ -143651,7 +144267,7 @@ function maskApiKeyForDisplay(apiKey) {
143651
144267
  return `${trimmed.slice(0, 3)}...${trimmed.slice(-4)}`;
143652
144268
  }
143653
144269
  __name(maskApiKeyForDisplay, "maskApiKeyForDisplay");
143654
- var MID_TURN_QUEUE_DRAIN_METHOD = "craft/drainMidTurnQueue";
144270
+ 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
144271
  var MID_TURN_QUEUE_DRAIN_TIMEOUT_MS = 2e3;
143656
144272
  var MID_TURN_QUEUE_DRAIN_MAX_TIMEOUT_STRIKES = 3;
143657
144273
  var MidTurnDrainTimeoutError = class extends Error {
@@ -144450,15 +145066,21 @@ ${this.pendingWorktreeNotice}
144450
145066
  );
144451
145067
  }
144452
145068
  if (functionCalls.length > 0) {
144453
- const toolResponseParts = await this.runToolCalls(
145069
+ const toolRun = await this.runToolCalls(
144454
145070
  pendingSend.signal,
144455
145071
  promptId,
144456
145072
  functionCalls
144457
145073
  );
145074
+ if (toolRun.stopAfterUserQuestionCancel) {
145075
+ await this.#preserveCancelledAskUserQuestionToolRun(
145076
+ toolRun
145077
+ );
145078
+ return { stopReason: "end_turn" };
145079
+ }
144458
145080
  nextMessage = {
144459
145081
  role: "user",
144460
145082
  parts: [
144461
- ...toolResponseParts,
145083
+ ...toolRun.parts,
144462
145084
  ...await this.#drainMidTurnUserMessages()
144463
145085
  ]
144464
145086
  };
@@ -144636,15 +145258,19 @@ ${this.pendingWorktreeNotice}
144636
145258
  );
144637
145259
  }
144638
145260
  if (functionCalls.length > 0) {
144639
- const toolResponseParts = await this.runToolCalls(
145261
+ const toolRun = await this.runToolCalls(
144640
145262
  pendingSend.signal,
144641
145263
  promptId,
144642
145264
  functionCalls
144643
145265
  );
145266
+ if (toolRun.stopAfterUserQuestionCancel) {
145267
+ await this.#preserveCancelledAskUserQuestionToolRun(toolRun);
145268
+ return { stopReason: "end_turn" };
145269
+ }
144644
145270
  nextMessage = {
144645
145271
  role: "user",
144646
145272
  parts: [
144647
- ...toolResponseParts,
145273
+ ...toolRun.parts,
144648
145274
  ...await this.#drainMidTurnUserMessages()
144649
145275
  ]
144650
145276
  };
@@ -144768,6 +145394,16 @@ ${this.pendingWorktreeNotice}
144768
145394
  });
144769
145395
  }
144770
145396
  }
145397
+ async #preserveCancelledAskUserQuestionToolRun(toolRun) {
145398
+ this.#preserveUnsentMessageHistory(
145399
+ {
145400
+ role: "user",
145401
+ parts: [...toolRun.parts, ...await this.#drainMidTurnUserMessages()]
145402
+ },
145403
+ true
145404
+ );
145405
+ await this.messageRewriter?.waitForPendingRewrites();
145406
+ }
144771
145407
  #recordCompressionTokenCount(info) {
144772
145408
  this.#syncPromptTokenCountWithCurrentChat();
144773
145409
  const tokenCount = this.#extractCompressionTokenCount(info);
@@ -145047,15 +145683,21 @@ ${this.pendingWorktreeNotice}
145047
145683
  );
145048
145684
  }
145049
145685
  if (functionCalls.length > 0) {
145050
- const toolResponseParts = await this.runToolCalls(
145686
+ const toolRun = await this.runToolCalls(
145051
145687
  ac.signal,
145052
145688
  promptId,
145053
145689
  functionCalls
145054
145690
  );
145691
+ if (toolRun.stopAfterUserQuestionCancel) {
145692
+ await this.#preserveCancelledAskUserQuestionToolRun(
145693
+ toolRun
145694
+ );
145695
+ return;
145696
+ }
145055
145697
  nextMessage = {
145056
145698
  role: "user",
145057
145699
  parts: [
145058
- ...toolResponseParts,
145700
+ ...toolRun.parts,
145059
145701
  ...await this.#drainMidTurnUserMessages()
145060
145702
  ]
145061
145703
  };
@@ -145171,7 +145813,10 @@ ${this.pendingWorktreeNotice}
145171
145813
  break;
145172
145814
  }
145173
145815
  const item = this.notificationQueue.shift();
145174
- await this.#executeBackgroundNotificationPrompt(item);
145816
+ await sessionIdContext.run(
145817
+ this.config.getSessionId(),
145818
+ () => this.#executeBackgroundNotificationPromptInner(item)
145819
+ );
145175
145820
  }
145176
145821
  } finally {
145177
145822
  this.notificationProcessing = false;
@@ -145183,12 +145828,6 @@ ${this.pendingWorktreeNotice}
145183
145828
  }
145184
145829
  }
145185
145830
  }
145186
- async #executeBackgroundNotificationPrompt(item) {
145187
- return sessionIdContext.run(
145188
- this.config.getSessionId(),
145189
- () => this.#executeBackgroundNotificationPromptInner(item)
145190
- );
145191
- }
145192
145831
  async #executeBackgroundNotificationPromptInner(item) {
145193
145832
  return Storage.runWithRuntimeBaseDir(
145194
145833
  this.runtimeBaseDir,
@@ -145279,15 +145918,20 @@ ${this.pendingWorktreeNotice}
145279
145918
  );
145280
145919
  }
145281
145920
  if (functionCalls.length > 0) {
145282
- const toolResponseParts = await this.runToolCalls(
145921
+ const toolRun = await this.runToolCalls(
145283
145922
  ac.signal,
145284
145923
  promptId,
145285
145924
  functionCalls
145286
145925
  );
145926
+ if (toolRun.stopAfterUserQuestionCancel) {
145927
+ await this.#preserveCancelledAskUserQuestionToolRun(toolRun);
145928
+ await this.#emitBackgroundNotificationEndTurn("end_turn");
145929
+ return;
145930
+ }
145287
145931
  nextMessage = {
145288
145932
  role: "user",
145289
145933
  parts: [
145290
- ...toolResponseParts,
145934
+ ...toolRun.parts,
145291
145935
  ...await this.#drainMidTurnUserMessages()
145292
145936
  ]
145293
145937
  };
@@ -145524,8 +146168,9 @@ ${this.pendingWorktreeNotice}
145524
146168
  * on. Response-part ordering matches the original `functionCalls` order.
145525
146169
  */
145526
146170
  async runToolCalls(abortSignal, promptId, functionCalls) {
146171
+ const dedupedFunctionCalls = dedupeToolCallsById(functionCalls);
145527
146172
  const batches = [];
145528
- for (const fc of dedupeToolCallsById(functionCalls)) {
146173
+ for (const fc of dedupedFunctionCalls) {
145529
146174
  const isAgent = fc.name === ToolNames.AGENT;
145530
146175
  const last = batches[batches.length - 1];
145531
146176
  if (isAgent && last?.concurrent) {
@@ -145534,7 +146179,45 @@ ${this.pendingWorktreeNotice}
145534
146179
  batches.push({ concurrent: isAgent, calls: [fc] });
145535
146180
  }
145536
146181
  }
145537
- const runBounded = /* @__PURE__ */ __name(async (calls) => {
146182
+ let skippedToolCallCounter = 0;
146183
+ const recordSkippedToolCall = /* @__PURE__ */ __name(async (fc) => {
146184
+ const toolName = fc.name ?? "unknown_tool";
146185
+ const callId = fc.id ?? `${toolName}-skip-${++skippedToolCallCounter}`;
146186
+ const part = {
146187
+ functionResponse: {
146188
+ id: callId,
146189
+ name: toolName,
146190
+ response: { error: ASK_USER_QUESTION_CANCEL_SKIP_MESSAGE }
146191
+ }
146192
+ };
146193
+ const error = new Error(ASK_USER_QUESTION_CANCEL_SKIP_MESSAGE);
146194
+ try {
146195
+ this.config.getChatRecordingService()?.recordToolResult([part], {
146196
+ callId,
146197
+ status: "error",
146198
+ resultDisplay: void 0,
146199
+ error,
146200
+ errorType: void 0
146201
+ });
146202
+ await this.toolCallEmitter.emitStart({
146203
+ callId,
146204
+ toolName,
146205
+ args: fc.args ?? {},
146206
+ status: "pending"
146207
+ });
146208
+ await this.toolCallEmitter.emitError(callId, toolName, error);
146209
+ } catch (recordError) {
146210
+ debugLogger78.error("Failed to record skipped tool call:", recordError);
146211
+ }
146212
+ return part;
146213
+ }, "recordSkippedToolCall");
146214
+ const appendSkippedAfter = /* @__PURE__ */ __name(async (parts2, fc) => {
146215
+ const startIndex = dedupedFunctionCalls.indexOf(fc) + 1;
146216
+ for (const remainingCall of dedupedFunctionCalls.slice(startIndex)) {
146217
+ parts2.push(await recordSkippedToolCall(remainingCall));
146218
+ }
146219
+ }, "appendSkippedAfter");
146220
+ const runBounded = /* @__PURE__ */ __name(async (calls, runAbortSignal, onStopAfterUserQuestionCancel, shouldSkipUnstarted) => {
145538
146221
  const parsed = parseInt(
145539
146222
  process.env["QWEN_CODE_MAX_TOOL_CONCURRENCY"] || "",
145540
146223
  10
@@ -145544,7 +146227,19 @@ ${this.pendingWorktreeNotice}
145544
146227
  const executing = /* @__PURE__ */ new Set();
145545
146228
  for (let i = 0; i < calls.length; i++) {
145546
146229
  const idx = i;
145547
- const p = this.runTool(abortSignal, promptId, calls[idx]).then((r) => {
146230
+ if (runAbortSignal.aborted && shouldSkipUnstarted?.()) {
146231
+ results[idx] = {
146232
+ parts: [await recordSkippedToolCall(calls[idx])],
146233
+ stopAfterUserQuestionCancel: false
146234
+ };
146235
+ continue;
146236
+ }
146237
+ const p = this.runTool(
146238
+ runAbortSignal,
146239
+ promptId,
146240
+ calls[idx],
146241
+ onStopAfterUserQuestionCancel
146242
+ ).then((r) => {
145548
146243
  results[idx] = r;
145549
146244
  }).finally(() => {
145550
146245
  executing.delete(p);
@@ -145560,16 +146255,54 @@ ${this.pendingWorktreeNotice}
145560
146255
  const parts = [];
145561
146256
  for (const batch of batches) {
145562
146257
  if (batch.concurrent && batch.calls.length > 1) {
145563
- const results = await runBounded(batch.calls);
145564
- for (const r of results) parts.push(...r);
146258
+ const batchAbortController = new AbortController();
146259
+ let batchStopAfterUserQuestionCancel = false;
146260
+ const propagateAbort = /* @__PURE__ */ __name(() => {
146261
+ batchAbortController.abort(abortSignal.reason);
146262
+ }, "propagateAbort");
146263
+ if (abortSignal.aborted) {
146264
+ propagateAbort();
146265
+ } else {
146266
+ abortSignal.addEventListener("abort", propagateAbort, {
146267
+ once: true
146268
+ });
146269
+ }
146270
+ const stopBatchAfterUserQuestionCancel = /* @__PURE__ */ __name(() => {
146271
+ batchStopAfterUserQuestionCancel = true;
146272
+ batchAbortController.abort(USER_CANCEL_ABORT_REASON);
146273
+ }, "stopBatchAfterUserQuestionCancel");
146274
+ let results;
146275
+ try {
146276
+ results = await runBounded(
146277
+ batch.calls,
146278
+ batchAbortController.signal,
146279
+ stopBatchAfterUserQuestionCancel,
146280
+ () => batchStopAfterUserQuestionCancel
146281
+ );
146282
+ } finally {
146283
+ abortSignal.removeEventListener("abort", propagateAbort);
146284
+ }
146285
+ let shouldStop = false;
146286
+ for (const r of results) {
146287
+ parts.push(...r.parts);
146288
+ shouldStop ||= r.stopAfterUserQuestionCancel;
146289
+ }
146290
+ if (shouldStop) {
146291
+ await appendSkippedAfter(parts, batch.calls[batch.calls.length - 1]);
146292
+ return { parts, stopAfterUserQuestionCancel: true };
146293
+ }
145565
146294
  } else {
145566
146295
  for (const fc of batch.calls) {
145567
146296
  const r = await this.runTool(abortSignal, promptId, fc);
145568
- parts.push(...r);
146297
+ parts.push(...r.parts);
146298
+ if (r.stopAfterUserQuestionCancel) {
146299
+ await appendSkippedAfter(parts, fc);
146300
+ return { parts, stopAfterUserQuestionCancel: true };
146301
+ }
145569
146302
  }
145570
146303
  }
145571
146304
  }
145572
- return parts;
146305
+ return { parts, stopAfterUserQuestionCancel: false };
145573
146306
  }
145574
146307
  /**
145575
146308
  * Assemble the per-turn system reminders the model needs to see at the
@@ -145601,11 +146334,15 @@ ${this.pendingWorktreeNotice}
145601
146334
  }
145602
146335
  return reminders;
145603
146336
  }
145604
- async runTool(abortSignal, promptId, fc) {
146337
+ async runTool(abortSignal, promptId, fc, onStopAfterUserQuestionCancel) {
145605
146338
  const callId = fc.id ?? `${fc.name}-${Date.now()}`;
145606
146339
  let args = fc.args ?? {};
145607
146340
  const startTime = Date.now();
145608
146341
  let spanError;
146342
+ let activeToolAbortSignal = abortSignal;
146343
+ let nestedAskUserQuestionCancelled = false;
146344
+ let agentToolAbortController;
146345
+ let removeAgentToolAbortPropagation;
145609
146346
  const errorResponse = /* @__PURE__ */ __name((error) => {
145610
146347
  const durationMs = Date.now() - startTime;
145611
146348
  logToolCall(this.config, {
@@ -145616,7 +146353,7 @@ ${this.pendingWorktreeNotice}
145616
146353
  function_args: args,
145617
146354
  duration_ms: durationMs,
145618
146355
  // An aborted signal means the call was cancelled, not a genuine error.
145619
- status: abortSignal.aborted ? "cancelled" : "error",
146356
+ status: activeToolAbortSignal.aborted ? "cancelled" : "error",
145620
146357
  success: false,
145621
146358
  error: error.message,
145622
146359
  tool_type: typeof tool !== "undefined" && tool instanceof DiscoveredMCPTool ? "mcp" : "native"
@@ -145631,8 +146368,9 @@ ${this.pendingWorktreeNotice}
145631
146368
  }
145632
146369
  ];
145633
146370
  }, "errorResponse");
145634
- const earlyErrorResponse = /* @__PURE__ */ __name(async (error, toolName2 = fc.name ?? "unknown_tool") => {
146371
+ const earlyErrorResponse = /* @__PURE__ */ __name(async (error, toolName2 = fc.name ?? "unknown_tool", opts) => {
145635
146372
  spanError = error.message;
146373
+ removeAgentToolAbortPropagation?.();
145636
146374
  if (toolName2 !== ToolNames.TODO_WRITE) {
145637
146375
  await this.toolCallEmitter.emitError(callId, toolName2, error);
145638
146376
  }
@@ -145644,7 +146382,10 @@ ${this.pendingWorktreeNotice}
145644
146382
  error,
145645
146383
  errorType: void 0
145646
146384
  });
145647
- return errorParts;
146385
+ return {
146386
+ parts: errorParts,
146387
+ stopAfterUserQuestionCancel: opts?.stopAfterUserQuestionCancel ?? false
146388
+ };
145648
146389
  }, "earlyErrorResponse");
145649
146390
  if (!fc.name) {
145650
146391
  return earlyErrorResponse(new Error("Missing function name"));
@@ -145679,6 +146420,23 @@ ${this.pendingWorktreeNotice}
145679
146420
  const isAgentTool = tool.name === ToolNames.AGENT;
145680
146421
  const isExitPlanModeTool = tool.name === ToolNames.EXIT_PLAN_MODE;
145681
146422
  const isEnterPlanModeTool = tool.name === ToolNames.ENTER_PLAN_MODE;
146423
+ if (isAgentTool) {
146424
+ agentToolAbortController = new AbortController();
146425
+ activeToolAbortSignal = agentToolAbortController.signal;
146426
+ const propagateAbort = /* @__PURE__ */ __name(() => {
146427
+ agentToolAbortController?.abort(abortSignal.reason);
146428
+ }, "propagateAbort");
146429
+ if (abortSignal.aborted) {
146430
+ propagateAbort();
146431
+ } else {
146432
+ abortSignal.addEventListener("abort", propagateAbort, {
146433
+ once: true
146434
+ });
146435
+ removeAgentToolAbortPropagation = /* @__PURE__ */ __name(() => {
146436
+ abortSignal.removeEventListener("abort", propagateAbort);
146437
+ }, "removeAgentToolAbortPropagation");
146438
+ }
146439
+ }
145682
146440
  let subAgentCleanupFunctions = [];
145683
146441
  const toolUseId = generateToolUseId();
145684
146442
  const approvalMode = this.config.getApprovalMode();
@@ -145692,11 +146450,16 @@ ${this.pendingWorktreeNotice}
145692
146450
  this,
145693
146451
  this.client,
145694
146452
  parentToolCallId,
145695
- subagentType
146453
+ subagentType,
146454
+ () => {
146455
+ nestedAskUserQuestionCancelled = true;
146456
+ agentToolAbortController?.abort(USER_CANCEL_ABORT_REASON);
146457
+ onStopAfterUserQuestionCancel?.();
146458
+ }
145696
146459
  );
145697
146460
  subAgentCleanupFunctions = subSubAgentTracker.setup(
145698
146461
  taskEventEmitter,
145699
- abortSignal
146462
+ activeToolAbortSignal
145700
146463
  );
145701
146464
  }
145702
146465
  const isAskUserQuestionTool = toolName === ToolNames.ASK_USER_QUESTION;
@@ -145914,9 +146677,15 @@ ${this.pendingWorktreeNotice}
145914
146677
  }
145915
146678
  switch (outcome) {
145916
146679
  case "cancel" /* Cancel */:
146680
+ if (toolName === ToolNames.ASK_USER_QUESTION) {
146681
+ onStopAfterUserQuestionCancel?.();
146682
+ }
145917
146683
  return earlyErrorResponse(
145918
146684
  new Error(`Tool "${toolName}" was canceled by the user.`),
145919
- toolName
146685
+ toolName,
146686
+ {
146687
+ stopAfterUserQuestionCancel: toolName === ToolNames.ASK_USER_QUESTION
146688
+ }
145920
146689
  );
145921
146690
  case "proceed_once" /* ProceedOnce */:
145922
146691
  case "proceed_always" /* ProceedAlways */:
@@ -145953,7 +146722,7 @@ ${this.pendingWorktreeNotice}
145953
146722
  args,
145954
146723
  toolUseId,
145955
146724
  permissionMode,
145956
- abortSignal
146725
+ activeToolAbortSignal
145957
146726
  );
145958
146727
  if (!preHookResult.shouldProceed) {
145959
146728
  const blockReason = preHookResult.blockReason || "Blocked by PreToolUse hook";
@@ -145976,11 +146745,11 @@ ${this.pendingWorktreeNotice}
145976
146745
  `Qwen Code is executing tool ${toolName}`
145977
146746
  );
145978
146747
  try {
145979
- toolResult = await invocation.execute(abortSignal);
146748
+ toolResult = await invocation.execute(activeToolAbortSignal);
145980
146749
  } finally {
145981
146750
  sleepInhibitorHandle.release();
145982
146751
  }
145983
- const aborted2 = abortSignal.aborted;
146752
+ const aborted2 = activeToolAbortSignal.aborted;
145984
146753
  endToolExecutionSpan(execSpan, {
145985
146754
  success: !toolResult.error && !aborted2,
145986
146755
  error: aborted2 ? "tool_cancelled" : toolResult.error ? "tool_error" : void 0,
@@ -145989,12 +146758,13 @@ ${this.pendingWorktreeNotice}
145989
146758
  } catch (execError) {
145990
146759
  endToolExecutionSpan(execSpan, {
145991
146760
  success: false,
145992
- error: abortSignal.aborted ? "tool_cancelled" : "tool_exception",
145993
- cancelled: abortSignal.aborted
146761
+ error: activeToolAbortSignal.aborted ? "tool_cancelled" : "tool_exception",
146762
+ cancelled: activeToolAbortSignal.aborted
145994
146763
  });
145995
146764
  throw execError;
145996
146765
  }
145997
146766
  subAgentCleanupFunctions.forEach((cleanup) => cleanup());
146767
+ removeAgentToolAbortPropagation?.();
145998
146768
  if ((isEnterPlanModeTool || isExitPlanModeTool) && !didRequestPermission && !toolResult.error && this.config.getApprovalMode() !== approvalMode) {
145999
146769
  await this.sendUpdate({
146000
146770
  sessionUpdate: "current_mode_update",
@@ -146006,7 +146776,10 @@ ${this.pendingWorktreeNotice}
146006
146776
  callId,
146007
146777
  toolResult.llmContent
146008
146778
  );
146009
- if (hooksEnabledForTool && messageBusForTool && !toolResult.error) {
146779
+ const aborted = activeToolAbortSignal.aborted;
146780
+ const status = aborted ? "cancelled" : toolResult.error ? "error" : "success";
146781
+ const succeeded = status === "success";
146782
+ if (hooksEnabledForTool && messageBusForTool && !toolResult.error && !aborted && !nestedAskUserQuestionCancelled) {
146010
146783
  const toolResponse = {
146011
146784
  llmContent: toolResult.llmContent,
146012
146785
  returnDisplay: toolResult.returnDisplay
@@ -146018,7 +146791,7 @@ ${this.pendingWorktreeNotice}
146018
146791
  toolResponse,
146019
146792
  toolUseId,
146020
146793
  permissionMode,
146021
- abortSignal
146794
+ activeToolAbortSignal
146022
146795
  );
146023
146796
  if (postHookResult.shouldStop) {
146024
146797
  const stopMessage = postHookResult.stopReason || "Execution stopped by PostToolUse hook";
@@ -146031,17 +146804,17 @@ ${this.pendingWorktreeNotice}
146031
146804
  const contextPart = { text: postHookResult.additionalContext };
146032
146805
  responseParts.push(contextPart);
146033
146806
  }
146034
- } else if (hooksEnabledForTool && messageBusForTool && toolResult.error) {
146807
+ } else if (hooksEnabledForTool && messageBusForTool && (toolResult.error || aborted)) {
146808
+ const isInterrupt = aborted;
146035
146809
  const failureHookResult = await firePostToolUseFailureHook(
146036
146810
  messageBusForTool,
146037
146811
  toolUseId,
146038
146812
  toolName,
146039
146813
  args,
146040
- toolResult.error.message,
146041
- false,
146042
- // not an interrupt
146814
+ toolResult.error?.message ?? "Tool execution was cancelled",
146815
+ isInterrupt,
146043
146816
  permissionMode,
146044
- abortSignal
146817
+ activeToolAbortSignal
146045
146818
  );
146046
146819
  if (failureHookResult.additionalContext) {
146047
146820
  debugLogger78.debug(
@@ -146049,9 +146822,6 @@ ${this.pendingWorktreeNotice}
146049
146822
  );
146050
146823
  }
146051
146824
  }
146052
- const aborted = abortSignal.aborted;
146053
- const status = aborted ? "cancelled" : toolResult.error ? "error" : "success";
146054
- const succeeded = status === "success";
146055
146825
  if (isTodoWriteTool) {
146056
146826
  const todos = this.planEmitter.extractTodos(
146057
146827
  toolResult.returnDisplay,
@@ -146099,14 +146869,18 @@ ${this.pendingWorktreeNotice}
146099
146869
  } else if (aborted) {
146100
146870
  spanError = "Tool execution was cancelled";
146101
146871
  }
146102
- return responseParts;
146872
+ return {
146873
+ parts: responseParts,
146874
+ stopAfterUserQuestionCancel: nestedAskUserQuestionCancelled
146875
+ };
146103
146876
  } catch (e) {
146104
146877
  subAgentCleanupFunctions.forEach((cleanup) => cleanup());
146878
+ removeAgentToolAbortPropagation?.();
146105
146879
  const error = e instanceof Error ? e : new Error(String(e));
146106
146880
  spanError = error.message;
146107
146881
  const hooksEnabledForError = !this.config.getDisableAllHooks?.();
146108
146882
  const messageBusForError = this.config.getMessageBus?.();
146109
- const isInterrupt = abortSignal.aborted;
146883
+ const isInterrupt = activeToolAbortSignal.aborted;
146110
146884
  if (hooksEnabledForError && messageBusForError) {
146111
146885
  const failureHookResult = await firePostToolUseFailureHook(
146112
146886
  messageBusForError,
@@ -146116,7 +146890,7 @@ ${this.pendingWorktreeNotice}
146116
146890
  error.message,
146117
146891
  isInterrupt,
146118
146892
  String(approvalMode),
146119
- abortSignal
146893
+ activeToolAbortSignal
146120
146894
  );
146121
146895
  if (failureHookResult.additionalContext) {
146122
146896
  debugLogger78.debug(
@@ -146138,12 +146912,15 @@ ${this.pendingWorktreeNotice}
146138
146912
  callId,
146139
146913
  // A throw caused by abort (e.g. AbortError) is a cancellation, not
146140
146914
  // a genuine tool error — keep it consistent with the success path.
146141
- status: abortSignal.aborted ? "cancelled" : "error",
146915
+ status: activeToolAbortSignal.aborted ? "cancelled" : "error",
146142
146916
  resultDisplay: void 0,
146143
146917
  error,
146144
146918
  errorType: void 0
146145
146919
  });
146146
- return errorResponse(error);
146920
+ return {
146921
+ parts: errorResponse(error),
146922
+ stopAfterUserQuestionCancel: nestedAskUserQuestionCancelled
146923
+ };
146147
146924
  }
146148
146925
  });
146149
146926
  } finally {
@@ -148190,7 +148967,7 @@ var QwenAgent = class {
148190
148967
  async initialize(args) {
148191
148968
  this.clientCapabilities = args.clientCapabilities;
148192
148969
  const authMethods = buildAuthMethods();
148193
- const version = "0.18.1";
148970
+ const version = "0.18.3-nightly.20260618.bc3e0b405";
148194
148971
  return {
148195
148972
  protocolVersion: PROTOCOL_VERSION,
148196
148973
  agentInfo: {
@@ -151547,7 +152324,10 @@ ${outputText}
151547
152324
  settings,
151548
152325
  argvForSession,
151549
152326
  cwd5,
151550
- [],
152327
+ // ACP sessions do not provide an extension override. Passing [] is a
152328
+ // truthy override and prevents default/argv extension commands from
152329
+ // loading, so leave it unset to preserve normal CLI behavior.
152330
+ void 0,
151551
152331
  // Pass separated hooks for proper source attribution
151552
152332
  {
151553
152333
  userHooks: this.settings.getUserHooks(),
@@ -151773,7 +152553,7 @@ function validateDnsResolutionOrder(order) {
151773
152553
  }
151774
152554
  __name(validateDnsResolutionOrder, "validateDnsResolutionOrder");
151775
152555
  function getNodeMemoryArgs(isDebugMode3) {
151776
- const totalMemoryMB = os32.totalmem() / (1024 * 1024);
152556
+ const totalMemoryMB = os31.totalmem() / (1024 * 1024);
151777
152557
  const heapStats = v83.getHeapStatistics();
151778
152558
  const currentMaxOldSpaceSizeMb = Math.floor(
151779
152559
  heapStats.heap_size_limit / 1024 / 1024
@@ -152275,7 +153055,7 @@ ${finalArgs[promptIndex + 1]}`;
152275
153055
  process.exit(0);
152276
153056
  }
152277
153057
  if (config.isInteractive()) {
152278
- void import("./chunks/scheduler-O66SLJGU.js").then((m) => m.startBackgroundHousekeeping(config, settings)).catch((err) => {
153058
+ void import("./chunks/scheduler-2GZTWP5S.js").then((m) => m.startBackgroundHousekeeping(config, settings)).catch((err) => {
152279
153059
  debugLogger80.warn("failed to start background housekeeping:", err);
152280
153060
  });
152281
153061
  }
@@ -152295,6 +153075,7 @@ ${finalArgs[promptIndex + 1]}`;
152295
153075
  ] : []
152296
153076
  ])
152297
153077
  ];
153078
+ const emittedStartupWarnings = new Set(startupWarnings);
152298
153079
  for (const warning of startupWarnings) {
152299
153080
  writeStderrLine(warning);
152300
153081
  }
@@ -152339,6 +153120,11 @@ ${finalArgs[promptIndex + 1]}`;
152339
153120
  if (inputFormat !== "stream-json" /* STREAM_JSON */) {
152340
153121
  profileCheckpoint("config_initialize_start");
152341
153122
  await config.initialize();
153123
+ for (const warning of config.getWarnings()) {
153124
+ if (emittedStartupWarnings.has(warning)) continue;
153125
+ emittedStartupWarnings.add(warning);
153126
+ writeStderrLine(warning);
153127
+ }
152342
153128
  profileCheckpoint("config_initialize_end");
152343
153129
  await config.waitForMcpReady();
152344
153130
  const failedMcpServers = typeof config.getFailedMcpServerNames === "function" ? config.getFailedMcpServerNames() : [];