@qwen-code/qwen-code 0.17.0 → 0.17.1

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 (91) hide show
  1. package/bundled/qc-helper/docs/configuration/_meta.ts +0 -3
  2. package/bundled/qc-helper/docs/configuration/settings.md +13 -12
  3. package/bundled/qc-helper/docs/configuration/themes.md +39 -0
  4. package/bundled/qc-helper/docs/features/approval-mode.md +26 -22
  5. package/bundled/qc-helper/docs/features/commands.md +68 -12
  6. package/bundled/qc-helper/docs/features/status-line.md +168 -32
  7. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +16 -0
  8. package/bundled/simplify/SKILL.md +123 -0
  9. package/chunks/{agent-KVXFGIOU.js → agent-ZJHHICAC.js} +14 -13
  10. package/chunks/{anthropicContentGenerator-L4HWAOIV.js → anthropicContentGenerator-M45RXZVS.js} +48 -5
  11. package/chunks/{askUserQuestion-DC6OWQIL.js → askUserQuestion-TGRD7FNQ.js} +1 -1
  12. package/chunks/{ca-NMZFEGAU.js → ca-6RSCDYUS.js} +2 -1
  13. package/chunks/{chunk-7EHPK6TK.js → chunk-2KEXT6RB.js} +4007 -2390
  14. package/chunks/{chunk-J5VCSWPA.js → chunk-3PJXIDKI.js} +1153 -103
  15. package/chunks/{chunk-7NNBQRV7.js → chunk-5JBZM7FZ.js} +4 -4
  16. package/chunks/{chunk-EMVEDSVZ.js → chunk-6O244QKR.js} +43 -3
  17. package/chunks/chunk-7TQVELRB.js +10412 -0
  18. package/chunks/{chunk-HCSJIOLR.js → chunk-BNESGOSJ.js} +7450 -3516
  19. package/chunks/{chunk-MEN6IEKX.js → chunk-C5CUHYSM.js} +456 -1225
  20. package/chunks/{chunk-7YJIR2FX.js → chunk-G4K6P5KN.js} +8 -15
  21. package/chunks/chunk-HX3JRTWL.js +393 -0
  22. package/chunks/{chunk-V7LMZR76.js → chunk-JBSYXHJF.js} +1 -1
  23. package/chunks/{chunk-R2B65CAN.js → chunk-JKUAX6UT.js} +0 -1
  24. package/chunks/chunk-MRO43B25.js +30 -0
  25. package/chunks/{chunk-JI7FDD65.js → chunk-NJJER6E2.js} +9 -6
  26. package/chunks/{chunk-ODPVJ6JJ.js → chunk-OJFMTECH.js} +6 -1
  27. package/chunks/{chunk-QEXSIXLX.js → chunk-PLYRQYKC.js} +10 -10
  28. package/chunks/{chunk-U2K6HDUJ.js → chunk-QVJ33ZBG.js} +23 -13
  29. package/chunks/{chunk-HAQCNXSG.js → chunk-RQW7WUJR.js} +15 -0
  30. package/chunks/{chunk-UQRYJQBE.js → chunk-SOGUPKP6.js} +1 -1
  31. package/chunks/{chunk-6NUSWV4M.js → chunk-TDZCEIK6.js} +2 -0
  32. package/chunks/{chunk-4O2TWJK4.js → chunk-X2474BTT.js} +183 -40
  33. package/chunks/{computer-use-2J5ZXEER.js → computer-use-NAHQPV2L.js} +24 -6
  34. package/chunks/{contextCommand-52NTEMCT.js → contextCommand-7KJT3UJS.js} +16 -15
  35. package/chunks/{cron-create-FXRORK2U.js → cron-create-V3UK2SJN.js} +1 -1
  36. package/chunks/{cron-delete-D24IN6CA.js → cron-delete-MANALPCP.js} +1 -1
  37. package/chunks/{cron-list-SMOX26SL.js → cron-list-UDIYK3B3.js} +1 -1
  38. package/chunks/{de-OIMT3OMI.js → de-APURNJ3I.js} +2 -1
  39. package/chunks/{dist-GRQVFL3G.js → dist-ATAKC63R.js} +1 -1
  40. package/chunks/{edit-RLFUTT5F.js → edit-JWXCQ4KK.js} +14 -13
  41. package/chunks/{en-2IFZ5THF.js → en-FYO57HJW.js} +3 -1
  42. package/chunks/{enter-worktree-CYRAPQKJ.js → enter-worktree-G4CJXPT4.js} +14 -13
  43. package/chunks/{exit-worktree-WQZM72QD.js → exit-worktree-MYZ2FGU2.js} +14 -13
  44. package/chunks/{exitPlanMode-STFEBQZE.js → exitPlanMode-ELJ6FSMU.js} +14 -13
  45. package/chunks/{fr-PVELSHTV.js → fr-32YHQZIS.js} +2 -1
  46. package/chunks/{geminiContentGenerator-DIV32SKO.js → geminiContentGenerator-3LR7MKCQ.js} +4 -3
  47. package/chunks/{glob-N3XO4RVI.js → glob-CANUAUTC.js} +14 -13
  48. package/chunks/{grep-AK5MP7P3.js → grep-WZWNJRDX.js} +14 -13
  49. package/chunks/{ja-P5TK5GNN.js → ja-PEUXN4XT.js} +2 -1
  50. package/chunks/{ls-7FYQHPWF.js → ls-T4SVZWR6.js} +1 -1
  51. package/chunks/{lsp-DKG34USR.js → lsp-U4ZQLNIS.js} +1 -1
  52. package/chunks/{monitor-IVBWJZEZ.js → monitor-CCKNOUFG.js} +17 -14
  53. package/chunks/{multipart-parser-IXGBIOIN.js → multipart-parser-AJ4WASWR.js} +2 -2
  54. package/chunks/{notebook-edit-PM46AXFS.js → notebook-edit-XDUY5Q4I.js} +14 -13
  55. package/chunks/{openaiContentGenerator-4QXCH7L2.js → openaiContentGenerator-N3O3MYIT.js} +11 -10
  56. package/chunks/{pt-A5GHG66T.js → pt-2INS7YVC.js} +2 -1
  57. package/chunks/{qwenContentGenerator-BLXQIIMX.js → qwenContentGenerator-DEOIWKVH.js} +16 -15
  58. package/chunks/{qwenOAuth2-BAN2EGSH.js → qwenOAuth2-LKXG7XVO.js} +2 -1
  59. package/chunks/{read-file-IEQAS3EZ.js → read-file-BRNXGILN.js} +8 -7
  60. package/chunks/{ripGrep-HQO7IE4C.js → ripGrep-ZRY5PKUZ.js} +14 -13
  61. package/chunks/{ru-66XKB4QX.js → ru-6CQ5HNHB.js} +2 -1
  62. package/chunks/scheduler-SSFABMN5.js +306 -0
  63. package/chunks/{send-message-ZL7CDM7K.js → send-message-GFYV7WLL.js} +1 -1
  64. package/chunks/{serve-CYRAK4UM.js → serve-B5O72CRN.js} +43 -30
  65. package/chunks/{shell-UZBGNO2Q.js → shell-SGYNBVMK.js} +14 -13
  66. package/chunks/{skill-JVC34QYN.js → skill-V7Y6DOFB.js} +9 -8
  67. package/chunks/{src-TMOD5X6F.js → src-7XL4G4DC.js} +88 -46
  68. package/chunks/{src-FOODLH7B.js → src-OKFFQGXB.js} +41 -15
  69. package/chunks/{syntheticOutput-U3YJ3GOO.js → syntheticOutput-DM43O6TY.js} +2 -2
  70. package/chunks/{task-stop-NPUI3YBA.js → task-stop-WKP5OB3V.js} +1 -1
  71. package/chunks/{todoWrite-Y6F7YEIM.js → todoWrite-GHL6DCLP.js} +14 -3
  72. package/chunks/{tool-search-P7PRPOW3.js → tool-search-7MHT3HGM.js} +8 -7
  73. package/chunks/{web-fetch-XWEK4TFX.js → web-fetch-SZIV74ZX.js} +2 -2
  74. package/chunks/{write-file-SIIEUON5.js → write-file-ARS2Z6BJ.js} +16 -15
  75. package/chunks/{zh-TW-3ND6DQRX.js → zh-TW-SSL3ATVZ.js} +3 -1
  76. package/chunks/{zh-OB5P2ZDO.js → zh-ZHZCMIRG.js} +3 -1
  77. package/cli.js +38665 -53791
  78. package/locales/ca.js +2 -1
  79. package/locales/de.js +2 -1
  80. package/locales/en.js +4 -1
  81. package/locales/fr.js +2 -1
  82. package/locales/ja.js +2 -1
  83. package/locales/pt.js +2 -1
  84. package/locales/ru.js +2 -1
  85. package/locales/zh-TW.js +4 -1
  86. package/locales/zh.js +4 -1
  87. package/package.json +2 -2
  88. package/chunks/chunk-EM6ETG2K.js +0 -60
  89. package/chunks/chunk-TI4GXJKO.js +0 -4277
  90. package/chunks/multipart-parser-3QWGTLK3.js +0 -384
  91. package/chunks/src-IPWIHNMI.js +0 -1406
@@ -8480,7 +8480,7 @@ var require_agent = __commonJS({
8480
8480
  return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts);
8481
8481
  }
8482
8482
  __name(defaultFactory, "defaultFactory");
8483
- var Agent = class extends DispatcherBase {
8483
+ var Agent2 = class extends DispatcherBase {
8484
8484
  static {
8485
8485
  __name(this, "Agent");
8486
8486
  }
@@ -8555,7 +8555,7 @@ var require_agent = __commonJS({
8555
8555
  await Promise.all(destroyPromises);
8556
8556
  }
8557
8557
  };
8558
- module.exports = Agent;
8558
+ module.exports = Agent2;
8559
8559
  }
8560
8560
  });
8561
8561
 
@@ -8566,7 +8566,7 @@ var require_proxy_agent = __commonJS({
8566
8566
  init_esbuild_shims();
8567
8567
  var { kProxy, kClose, kDestroy, kDispatch, kInterceptors } = require_symbols();
8568
8568
  var { URL: URL2 } = __require("node:url");
8569
- var Agent = require_agent();
8569
+ var Agent2 = require_agent();
8570
8570
  var Pool = require_pool();
8571
8571
  var DispatcherBase = require_dispatcher_base();
8572
8572
  var { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = require_errors();
@@ -8690,7 +8690,7 @@ var require_proxy_agent = __commonJS({
8690
8690
  return agentFactory(origin2, options);
8691
8691
  }, "factory");
8692
8692
  this[kClient] = clientFactory(url, { connect });
8693
- this[kAgent] = new Agent({
8693
+ this[kAgent] = new Agent2({
8694
8694
  ...opts,
8695
8695
  factory,
8696
8696
  connect: /* @__PURE__ */ __name(async (opts2, callback) => {
@@ -8802,7 +8802,7 @@ var require_env_http_proxy_agent = __commonJS({
8802
8802
  var DispatcherBase = require_dispatcher_base();
8803
8803
  var { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = require_symbols();
8804
8804
  var ProxyAgent2 = require_proxy_agent();
8805
- var Agent = require_agent();
8805
+ var Agent2 = require_agent();
8806
8806
  var DEFAULT_PORTS = {
8807
8807
  "http:": 80,
8808
8808
  "https:": 443
@@ -8825,7 +8825,7 @@ var require_env_http_proxy_agent = __commonJS({
8825
8825
  });
8826
8826
  }
8827
8827
  const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts;
8828
- this[kNoProxyAgent] = new Agent(agentOpts);
8828
+ this[kNoProxyAgent] = new Agent2(agentOpts);
8829
8829
  const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY;
8830
8830
  if (HTTP_PROXY) {
8831
8831
  this[kHttpProxyAgent] = new ProxyAgent2({ ...agentOpts, uri: HTTP_PROXY });
@@ -11231,7 +11231,7 @@ var require_mock_agent = __commonJS({
11231
11231
  "use strict";
11232
11232
  init_esbuild_shims();
11233
11233
  var { kClients } = require_symbols();
11234
- var Agent = require_agent();
11234
+ var Agent2 = require_agent();
11235
11235
  var {
11236
11236
  kAgent,
11237
11237
  kMockAgentSet,
@@ -11261,7 +11261,7 @@ var require_mock_agent = __commonJS({
11261
11261
  if (opts?.agent && typeof opts.agent.dispatch !== "function") {
11262
11262
  throw new InvalidArgumentError("Argument opts.agent must implement Agent");
11263
11263
  }
11264
- const agent = opts?.agent ? opts.agent : new Agent(opts);
11264
+ const agent = opts?.agent ? opts.agent : new Agent2(opts);
11265
11265
  this[kAgent] = agent;
11266
11266
  this[kClients] = agent[kClients];
11267
11267
  this[kOptions] = buildMockOptions(opts);
@@ -11366,9 +11366,9 @@ var require_global2 = __commonJS({
11366
11366
  init_esbuild_shims();
11367
11367
  var globalDispatcher = Symbol.for("undici.globalDispatcher.1");
11368
11368
  var { InvalidArgumentError } = require_errors();
11369
- var Agent = require_agent();
11369
+ var Agent2 = require_agent();
11370
11370
  if (getGlobalDispatcher() === void 0) {
11371
- setGlobalDispatcher(new Agent());
11371
+ setGlobalDispatcher(new Agent2());
11372
11372
  }
11373
11373
  function setGlobalDispatcher(agent) {
11374
11374
  if (!agent || typeof agent.dispatch !== "function") {
@@ -18833,7 +18833,7 @@ var require_undici = __commonJS({
18833
18833
  var Dispatcher = require_dispatcher();
18834
18834
  var Pool = require_pool();
18835
18835
  var BalancedPool = require_balanced_pool();
18836
- var Agent = require_agent();
18836
+ var Agent2 = require_agent();
18837
18837
  var ProxyAgent2 = require_proxy_agent();
18838
18838
  var EnvHttpProxyAgent = require_env_http_proxy_agent();
18839
18839
  var RetryAgent = require_retry_agent();
@@ -18856,7 +18856,7 @@ var require_undici = __commonJS({
18856
18856
  module.exports.Client = Client;
18857
18857
  module.exports.Pool = Pool;
18858
18858
  module.exports.BalancedPool = BalancedPool;
18859
- module.exports.Agent = Agent;
18859
+ module.exports.Agent = Agent2;
18860
18860
  module.exports.ProxyAgent = ProxyAgent2;
18861
18861
  module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent;
18862
18862
  module.exports.RetryAgent = RetryAgent;
@@ -19273,7 +19273,17 @@ function recordProxyFailure(hostname) {
19273
19273
  __name(recordProxyFailure, "recordProxyFailure");
19274
19274
  function buildFetchOptionsWithDispatcher(sdkType, proxyUrl) {
19275
19275
  if (!proxyUrl) {
19276
- return NO_DISPATCHER_FALLBACK[sdkType];
19276
+ const NO_PROXY_KEY = "__no_proxy__";
19277
+ let dispatcher = dispatcherCache.get(NO_PROXY_KEY);
19278
+ if (!dispatcher) {
19279
+ dispatcher = new import_undici.Agent({
19280
+ headersTimeout: 0,
19281
+ bodyTimeout: 0,
19282
+ keepAliveTimeout: 6e4
19283
+ });
19284
+ dispatcherCache.set(NO_PROXY_KEY, dispatcher);
19285
+ }
19286
+ return { fetchOptions: { dispatcher }, fetch: import_undici.fetch };
19277
19287
  }
19278
19288
  try {
19279
19289
  const dispatcher = getOrCreateSharedDispatcher(proxyUrl);
@@ -25,6 +25,7 @@ var HookEventName = /* @__PURE__ */ ((HookEventName2) => {
25
25
  HookEventName2["PreToolUse"] = "PreToolUse";
26
26
  HookEventName2["PostToolUse"] = "PostToolUse";
27
27
  HookEventName2["PostToolUseFailure"] = "PostToolUseFailure";
28
+ HookEventName2["PostToolBatch"] = "PostToolBatch";
28
29
  HookEventName2["Notification"] = "Notification";
29
30
  HookEventName2["UserPromptSubmit"] = "UserPromptSubmit";
30
31
  HookEventName2["SessionStart"] = "SessionStart";
@@ -78,6 +79,8 @@ function createHookOutput(eventName, data) {
78
79
  return new PostToolUseHookOutput(data);
79
80
  case "PostToolUseFailure" /* PostToolUseFailure */:
80
81
  return new PostToolUseFailureHookOutput(data);
82
+ case "PostToolBatch" /* PostToolBatch */:
83
+ return new PostToolBatchHookOutput(data);
81
84
  case "Stop" /* Stop */:
82
85
  case "SubagentStop" /* SubagentStop */:
83
86
  return new StopHookOutput(data);
@@ -248,6 +251,17 @@ var PostToolUseFailureHookOutput = class extends DefaultHookOutput {
248
251
  return super.getAdditionalContext();
249
252
  }
250
253
  };
254
+ var PostToolBatchHookOutput = class extends DefaultHookOutput {
255
+ static {
256
+ __name(this, "PostToolBatchHookOutput");
257
+ }
258
+ /**
259
+ * Check if batch processing should stop after the resolved tool calls.
260
+ */
261
+ shouldStopExecution() {
262
+ return super.shouldStopExecution() || this.isBlockingDecision();
263
+ }
264
+ };
251
265
  var StopHookOutput = class extends DefaultHookOutput {
252
266
  static {
253
267
  __name(this, "StopHookOutput");
@@ -398,6 +412,7 @@ export {
398
412
  PreToolUseHookOutput,
399
413
  PostToolUseHookOutput,
400
414
  PostToolUseFailureHookOutput,
415
+ PostToolBatchHookOutput,
401
416
  StopHookOutput,
402
417
  PermissionRequestHookOutput,
403
418
  NotificationType,
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  BaseDeclarativeTool,
9
9
  BaseToolInvocation
10
- } from "./chunk-R2B65CAN.js";
10
+ } from "./chunk-JKUAX6UT.js";
11
11
  import {
12
12
  init_esbuild_shims
13
13
  } from "./chunk-A4BMJM77.js";
@@ -474,6 +474,8 @@ var PATTERNS = [
474
474
  // -------------------
475
475
  // MiniMax
476
476
  // -------------------
477
+ [/^minimax-m3/i, LIMITS["1m"]],
478
+ // MiniMax-M3: 1,000,000
477
479
  [/^minimax-m2\.5/i, LIMITS["192k"]],
478
480
  // MiniMax-M2.5: 196,608
479
481
  [/^minimax-/i, LIMITS["200k"]],
@@ -6,7 +6,7 @@ import {
6
6
  getLanguageSettingsOptions,
7
7
  t,
8
8
  writeStderrLine
9
- } from "./chunk-QEXSIXLX.js";
9
+ } from "./chunk-PLYRQYKC.js";
10
10
  import {
11
11
  DEFAULT_STOP_HOOK_BLOCK_CAP,
12
12
  DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
@@ -15,10 +15,13 @@ import {
15
15
  SkillError,
16
16
  ideContextStore,
17
17
  require_main
18
- } from "./chunk-7EHPK6TK.js";
18
+ } from "./chunk-2KEXT6RB.js";
19
19
  import {
20
20
  isWithinRoot
21
- } from "./chunk-MEN6IEKX.js";
21
+ } from "./chunk-C5CUHYSM.js";
22
+ import {
23
+ atomicWriteFileSync
24
+ } from "./chunk-HX3JRTWL.js";
22
25
  import {
23
26
  FatalConfigError,
24
27
  QWEN_DIR,
@@ -14618,10 +14621,16 @@ function saveTrustedFolders(trustedFoldersFile) {
14618
14621
  if (!fs2.existsSync(dirPath)) {
14619
14622
  fs2.mkdirSync(dirPath, { recursive: true });
14620
14623
  }
14621
- fs2.writeFileSync(
14624
+ atomicWriteFileSync(
14622
14625
  trustedFoldersFile.path,
14623
14626
  JSON.stringify(trustedFoldersFile.config, null, 2),
14624
- { encoding: "utf-8", mode: 384 }
14627
+ // noFollow: refuse to follow any pre-placed symlink at the
14628
+ // config path — a redirected write could either leak the
14629
+ // trusted-folder list to an attacker target or leave the user's
14630
+ // real config silently stale. Matches the credential write
14631
+ // sites' security posture (sharedTokenManager, oauth-token-storage,
14632
+ // file-token-storage all use noFollow:true).
14633
+ { encoding: "utf-8", mode: 384, forceMode: true, noFollow: true }
14625
14634
  );
14626
14635
  } catch (error) {
14627
14636
  writeStderrLine("Error saving trusted folders file.");
@@ -14902,6 +14911,18 @@ var SETTINGS_SCHEMA = {
14902
14911
  description: "How many minutes the terminal must be blurred before an auto-recap fires on the next focus-in. Matches Claude Code's default of 5 minutes; raise if you briefly alt-tab and do not want recaps to pile up.",
14903
14912
  showInDialog: true
14904
14913
  },
14914
+ cleanupPeriodDays: {
14915
+ type: "number",
14916
+ label: "Cleanup Period (days)",
14917
+ category: "General",
14918
+ // LoadedSettings._merged is cached without verified setValue→recompute
14919
+ // paths in all UI flows. Mark restart-required so users aren't
14920
+ // surprised when a mid-session edit doesn't take effect immediately.
14921
+ requiresRestart: true,
14922
+ default: 30,
14923
+ description: "Number of days to retain ~/.qwen/file-history/ session backups used by /rewind. Backups older than this are removed by a background housekeeping pass that runs at most once per day. Set to 0 for minimum retention (~1 hour) \u2014 protects sessions touched in the last hour, plus the currently active session. Other persistent caches will honor the same setting in the future.",
14924
+ showInDialog: true
14925
+ },
14905
14926
  gitCoAuthor: {
14906
14927
  type: "object",
14907
14928
  label: "Attribution",
@@ -15118,7 +15139,7 @@ var SETTINGS_SCHEMA = {
15118
15139
  category: "UI",
15119
15140
  requiresRestart: false,
15120
15141
  default: void 0,
15121
- description: 'Status line display configuration. Use `type: "preset"` with built-in item ids, or `type: "command"` with a shell command. Optional command `refreshInterval` (seconds, >= 1) re-runs the command on a timer so external data stays fresh.',
15142
+ description: 'Status line display configuration. Use `type: "preset"` with built-in item ids, or `type: "command"` with a shell command. Optional command `refreshInterval` (seconds, >= 1) re-runs the command on a timer so external data stays fresh. Set `respectUserColors: true` to preserve ANSI color codes in command output instead of applying dim/theme styling. Set `hideContextIndicator: true` to hide the built-in context usage indicator in the footer right section.',
15122
15143
  showInDialog: false
15123
15144
  },
15124
15145
  customThemes: {
@@ -15298,6 +15319,15 @@ var SETTINGS_SCHEMA = {
15298
15319
  description: "Hide tool output and thinking for a cleaner view (toggle with Ctrl+O).",
15299
15320
  showInDialog: true
15300
15321
  },
15322
+ useTerminalBuffer: {
15323
+ type: "boolean",
15324
+ label: "Virtualized History (reduces flicker on long sessions)",
15325
+ category: "UI",
15326
+ requiresRestart: false,
15327
+ default: false,
15328
+ description: "Render conversation history in an in-app scrollable viewport instead of the terminal scrollback buffer. Recommended if you see flicker, scroll-storm, or interface freeze on long sessions, after Ctrl+O, after Ctrl+E / Ctrl+F (expand), after window resize, or when alt-tabbing back. Scroll with Shift+\u2191/\u2193 (line), PgUp/PgDn (page), Ctrl+Home/End (top/bottom), or the mouse wheel. Does NOT use the host terminal scrollback while enabled; for native text selection, hold Shift (or Option on macOS) while dragging.",
15329
+ showInDialog: true
15330
+ },
15301
15331
  shellOutputMaxLines: {
15302
15332
  type: "number",
15303
15333
  label: "Shell Output Max Lines",
@@ -16118,7 +16148,7 @@ var SETTINGS_SCHEMA = {
16118
16148
  showInDialog: true,
16119
16149
  options: [
16120
16150
  { value: "plan" /* PLAN */, label: "Plan" },
16121
- { value: "default" /* DEFAULT */, label: "Default" },
16151
+ { value: "default" /* DEFAULT */, label: "Ask permissions" },
16122
16152
  { value: "auto-edit" /* AUTO_EDIT */, label: "Auto Edit" },
16123
16153
  { value: "auto" /* AUTO */, label: "Auto" },
16124
16154
  { value: "yolo" /* YOLO */, label: "YOLO" }
@@ -16592,6 +16622,17 @@ var SETTINGS_SCHEMA = {
16592
16622
  mergeStrategy: "concat" /* CONCAT */,
16593
16623
  items: HOOK_DEFINITION_ITEMS
16594
16624
  },
16625
+ PostToolBatch: {
16626
+ type: "array",
16627
+ label: "Post Tool Batch Hooks",
16628
+ category: "Advanced",
16629
+ requiresRestart: false,
16630
+ default: [],
16631
+ description: "Hooks that execute once after all tool calls in a batch resolve.",
16632
+ showInDialog: false,
16633
+ mergeStrategy: "concat" /* CONCAT */,
16634
+ items: HOOK_DEFINITION_ITEMS
16635
+ },
16595
16636
  SessionStart: {
16596
16637
  type: "array",
16597
16638
  label: "Session Start Hooks",
@@ -17952,7 +17993,14 @@ function getUserSettingsDir() {
17952
17993
  }
17953
17994
  __name(getUserSettingsDir, "getUserSettingsDir");
17954
17995
  var DEFAULT_EXCLUDED_ENV_VARS = ["DEBUG", "DEBUG_MODE"];
17955
- var PROJECT_ENV_HARDCODED_EXCLUSIONS = ["QWEN_HOME", "QWEN_RUNTIME_DIR"];
17996
+ var ENV_CORRUPTED_PATH = "QWEN_CODE_SETTINGS_CORRUPTED_PATH";
17997
+ var ENV_WAS_RECOVERED = "QWEN_CODE_SETTINGS_WAS_RECOVERED";
17998
+ var PROJECT_ENV_HARDCODED_EXCLUSIONS = [
17999
+ "QWEN_HOME",
18000
+ "QWEN_RUNTIME_DIR",
18001
+ ENV_CORRUPTED_PATH,
18002
+ ENV_WAS_RECOVERED
18003
+ ];
17956
18004
  var SETTINGS_VERSION = 4;
17957
18005
  var SETTINGS_VERSION_KEY = "$version";
17958
18006
  function getSystemSettingsPath() {
@@ -18100,7 +18148,7 @@ var LoadedSettings = class {
18100
18148
  static {
18101
18149
  __name(this, "LoadedSettings");
18102
18150
  }
18103
- constructor(system, systemDefaults, user, workspace, isTrusted, migratedInMemorScopes, migrationWarnings = []) {
18151
+ constructor(system, systemDefaults, user, workspace, isTrusted, migratedInMemorScopes, migrationWarnings = [], corruptedPath = void 0, wasRecovered = false) {
18104
18152
  this.system = system;
18105
18153
  this.systemDefaults = systemDefaults;
18106
18154
  this.user = user;
@@ -18108,6 +18156,8 @@ var LoadedSettings = class {
18108
18156
  this.isTrusted = isTrusted;
18109
18157
  this.migratedInMemorScopes = migratedInMemorScopes;
18110
18158
  this.migrationWarnings = migrationWarnings;
18159
+ this.corruptedPath = corruptedPath;
18160
+ this.wasRecovered = wasRecovered;
18111
18161
  this._merged = this.computeMergedSettings();
18112
18162
  }
18113
18163
  system;
@@ -18117,6 +18167,9 @@ var LoadedSettings = class {
18117
18167
  isTrusted;
18118
18168
  migratedInMemorScopes;
18119
18169
  migrationWarnings;
18170
+ corruptedPath;
18171
+ wasRecovered;
18172
+ corruptionDialogDismissed = false;
18120
18173
  _merged;
18121
18174
  get merged() {
18122
18175
  return this._merged;
@@ -18155,6 +18208,34 @@ var LoadedSettings = class {
18155
18208
  recomputeMerged() {
18156
18209
  this._merged = this.computeMergedSettings();
18157
18210
  }
18211
+ reloadScopeFromDisk(scope) {
18212
+ const file = this.forScope(scope);
18213
+ try {
18214
+ if (!fs6.existsSync(file.path)) {
18215
+ file.settings = {};
18216
+ file.originalSettings = {};
18217
+ file.rawJson = void 0;
18218
+ this._merged = this.computeMergedSettings();
18219
+ return;
18220
+ }
18221
+ const content = fs6.readFileSync(file.path, "utf-8");
18222
+ const parsed = JSON.parse((0, import_strip_json_comments2.default)(content));
18223
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
18224
+ const resolved = resolveEnvVarsInObject(
18225
+ parsed,
18226
+ getHomeEnvFallbackVars()
18227
+ );
18228
+ file.settings = resolved;
18229
+ file.originalSettings = structuredClone(parsed);
18230
+ file.rawJson = content;
18231
+ }
18232
+ } catch (err) {
18233
+ debugLogger3.warn(
18234
+ `reloadScopeFromDisk(${scope}): ${getErrorMessage(err)}`
18235
+ );
18236
+ }
18237
+ this._merged = this.computeMergedSettings();
18238
+ }
18158
18239
  /**
18159
18240
  * Get user-level hooks from user settings (not merged with workspace).
18160
18241
  * These hooks should always be loaded regardless of folder trust.
@@ -18187,7 +18268,9 @@ function createMinimalSettings() {
18187
18268
  emptySettingsFile,
18188
18269
  false,
18189
18270
  /* @__PURE__ */ new Set(),
18190
- []
18271
+ [],
18272
+ void 0,
18273
+ false
18191
18274
  );
18192
18275
  }
18193
18276
  __name(createMinimalSettings, "createMinimalSettings");
@@ -18245,6 +18328,33 @@ function readHomeEnvInto(file) {
18245
18328
  }
18246
18329
  }
18247
18330
  __name(readHomeEnvInto, "readHomeEnvInto");
18331
+ function getHomeEnvFallbackVars() {
18332
+ const globalQwenDir = Storage.getGlobalQwenDir();
18333
+ const candidates = [path3.join(globalQwenDir, ".env")];
18334
+ if (!process2.env["QWEN_HOME"]) {
18335
+ candidates.push(path3.join(path3.dirname(globalQwenDir), ".env"));
18336
+ }
18337
+ const result = {};
18338
+ for (const candidate of candidates) {
18339
+ if (!fs6.existsSync(candidate)) {
18340
+ continue;
18341
+ }
18342
+ try {
18343
+ const parsed = dotenv.parse(fs6.readFileSync(candidate, "utf-8"));
18344
+ for (const key in parsed) {
18345
+ if (Object.hasOwn(parsed, key) && !Object.hasOwn(process2.env, key)) {
18346
+ result[key] ??= parsed[key];
18347
+ }
18348
+ }
18349
+ } catch (e) {
18350
+ debugLogger3.warn(
18351
+ `Failed to read home .env candidate ${candidate}: ${getErrorMessage(e)}`
18352
+ );
18353
+ }
18354
+ }
18355
+ return result;
18356
+ }
18357
+ __name(getHomeEnvFallbackVars, "getHomeEnvFallbackVars");
18248
18358
  function detectQwenHomeRedirectWithoutMigration(activeUserSettingsPath) {
18249
18359
  if (!process2.env["QWEN_HOME"]) {
18250
18360
  return null;
@@ -18372,7 +18482,8 @@ function loadEnvironment(settings) {
18372
18482
  }
18373
18483
  }
18374
18484
  __name(loadEnvironment, "loadEnvironment");
18375
- function loadSettings(workspaceDir = process2.cwd()) {
18485
+ var CORRUPTED_SUFFIX = ".corrupted";
18486
+ function loadSettings(workspaceDir = process2.cwd(), consumeCorruptionEnvVars = true) {
18376
18487
  preResolveHomeEnvOverrides();
18377
18488
  const userSettingsPath = getUserSettingsPath();
18378
18489
  const qwenHomeRedirectWarning = detectQwenHomeRedirectWithoutMigration(userSettingsPath);
@@ -18400,10 +18511,21 @@ function loadSettings(workspaceDir = process2.cwd()) {
18400
18511
  if (fs6.existsSync(filePath)) {
18401
18512
  let content = fs6.readFileSync(filePath, "utf-8");
18402
18513
  let rawSettings;
18403
- let recoveryWarning;
18514
+ const corruptedPath = `${filePath}${CORRUPTED_SUFFIX}`;
18515
+ let corruptedSaved = false;
18516
+ let recoveredFromBackup = false;
18517
+ let recoveredFromEnvVar = null;
18404
18518
  try {
18405
18519
  rawSettings = JSON.parse((0, import_strip_json_comments2.default)(content));
18406
18520
  } catch (parseError) {
18521
+ try {
18522
+ fs6.copyFileSync(filePath, corruptedPath);
18523
+ corruptedSaved = true;
18524
+ } catch (copyError) {
18525
+ debugLogger3.warn(
18526
+ `Failed to copy corrupted file: ${getErrorMessage(copyError)}`
18527
+ );
18528
+ }
18407
18529
  const backupPath = `${filePath}.orig`;
18408
18530
  if (fs6.existsSync(backupPath)) {
18409
18531
  debugLogger3.warn(
@@ -18419,7 +18541,7 @@ function loadSettings(workspaceDir = process2.cwd()) {
18419
18541
  rawSettings = backupSettings;
18420
18542
  const recoveryMsg = `Settings file ${filePath} had invalid JSON and was recovered from backup ${backupPath}. Some recent settings changes may have been lost.`;
18421
18543
  debugLogger3.warn(recoveryMsg);
18422
- recoveryWarning = recoveryMsg;
18544
+ recoveredFromBackup = true;
18423
18545
  } catch (backupError) {
18424
18546
  debugLogger3.warn(
18425
18547
  `Failed to recover from backup ${backupPath}: ${getErrorMessage(backupError)}. Falling back to empty settings.`
@@ -18427,24 +18549,29 @@ function loadSettings(workspaceDir = process2.cwd()) {
18427
18549
  }
18428
18550
  }
18429
18551
  if (!rawSettings) {
18430
- const corruptedPath = `${filePath}.corrupted.${Date.now()}`;
18431
- let warningMsg;
18432
- try {
18433
- fs6.renameSync(filePath, corruptedPath);
18434
- warningMsg = `Settings file ${filePath} has invalid JSON and was renamed to ${corruptedPath}. Your settings have been reset. To recover, fix the JSON in ${corruptedPath} and rename it back.`;
18435
- } catch (renameError) {
18436
- debugLogger3.error(
18437
- `Failed to rename corrupted settings file: ${getErrorMessage(renameError)}`
18438
- );
18439
- warningMsg = `Settings file ${filePath} has invalid JSON. Your settings have been reset. Please fix the JSON in ${filePath} manually.`;
18440
- }
18552
+ const warningMsg = `Settings file ${filePath} has invalid JSON. Your settings have been reset.`;
18441
18553
  debugLogger3.warn(warningMsg);
18554
+ if (corruptedSaved) {
18555
+ try {
18556
+ fs6.writeFileSync(filePath, "{}", "utf-8");
18557
+ } catch {
18558
+ }
18559
+ }
18442
18560
  return {
18443
18561
  settings: {},
18444
- migrationWarnings: [warningMsg]
18562
+ migrationWarnings: [],
18563
+ corruptedPath: corruptedSaved ? corruptedPath : void 0,
18564
+ wasRecovered: false
18445
18565
  };
18446
18566
  }
18447
18567
  }
18568
+ const envCorruptedPath = process2.env[ENV_CORRUPTED_PATH];
18569
+ if (consumeCorruptionEnvVars && envCorruptedPath && envCorruptedPath === corruptedPath && scope === "User" /* User */) {
18570
+ corruptedSaved = true;
18571
+ recoveredFromEnvVar = process2.env[ENV_WAS_RECOVERED] === "1";
18572
+ delete process2.env[ENV_CORRUPTED_PATH];
18573
+ delete process2.env[ENV_WAS_RECOVERED];
18574
+ }
18448
18575
  if (typeof rawSettings !== "object" || rawSettings === null || Array.isArray(rawSettings)) {
18449
18576
  settingsErrors.push({
18450
18577
  message: "Settings file is not a valid JSON object.",
@@ -18480,26 +18607,27 @@ function loadSettings(workspaceDir = process2.cwd()) {
18480
18607
  settingsObject = migrationResult.settings;
18481
18608
  migrationWarnings = migrationResult.warnings;
18482
18609
  persistSettingsObject("Error migrating settings file on disk");
18483
- } else if (hasLegacyNumericVersion || hasInvalidVersion) {
18610
+ } else if ((hasLegacyNumericVersion || hasInvalidVersion) && !corruptedSaved) {
18484
18611
  settingsObject[SETTINGS_VERSION_KEY] = SETTINGS_VERSION;
18485
18612
  debugLogger3.warn(
18486
18613
  `Settings version metadata in ${filePath} could not be migrated by any registered migration. Normalizing ${SETTINGS_VERSION_KEY} to ${SETTINGS_VERSION}.`
18487
18614
  );
18488
18615
  persistSettingsObject("Error normalizing settings version on disk");
18489
18616
  }
18490
- } else if (!hasVersionKey || hasInvalidVersion || hasLegacyNumericVersion) {
18617
+ } else if ((!hasVersionKey || hasInvalidVersion || hasLegacyNumericVersion) && !corruptedSaved) {
18491
18618
  settingsObject[SETTINGS_VERSION_KEY] = SETTINGS_VERSION;
18492
18619
  persistSettingsObject("Error normalizing settings version on disk");
18493
18620
  }
18494
- const allWarnings = [
18495
- ...recoveryWarning ? [recoveryWarning] : [],
18496
- ...migrationWarnings ?? []
18497
- ];
18498
- return {
18621
+ const result = {
18499
18622
  settings: settingsObject,
18500
18623
  rawJson: content,
18501
- migrationWarnings: allWarnings.length > 0 ? allWarnings : migrationWarnings
18624
+ migrationWarnings: migrationWarnings ?? []
18502
18625
  };
18626
+ if (corruptedSaved) {
18627
+ result.corruptedPath = corruptedPath;
18628
+ result.wasRecovered = recoveredFromBackup || (recoveredFromEnvVar ?? false);
18629
+ }
18630
+ return result;
18503
18631
  }
18504
18632
  } catch (error) {
18505
18633
  settingsErrors.push({
@@ -18531,10 +18659,20 @@ function loadSettings(workspaceDir = process2.cwd()) {
18531
18659
  );
18532
18660
  const userOriginalSettings = structuredClone(userResult.settings);
18533
18661
  const workspaceOriginalSettings = structuredClone(workspaceResult.settings);
18534
- systemSettings = resolveEnvVarsInObject(systemResult.settings);
18535
- systemDefaultSettings = resolveEnvVarsInObject(systemDefaultsResult.settings);
18536
- userSettings = resolveEnvVarsInObject(userResult.settings);
18537
- workspaceSettings = resolveEnvVarsInObject(workspaceResult.settings);
18662
+ const homeEnvFallback = getHomeEnvFallbackVars();
18663
+ systemSettings = resolveEnvVarsInObject(
18664
+ systemResult.settings,
18665
+ homeEnvFallback
18666
+ );
18667
+ systemDefaultSettings = resolveEnvVarsInObject(
18668
+ systemDefaultsResult.settings,
18669
+ homeEnvFallback
18670
+ );
18671
+ userSettings = resolveEnvVarsInObject(userResult.settings, homeEnvFallback);
18672
+ workspaceSettings = resolveEnvVarsInObject(
18673
+ workspaceResult.settings,
18674
+ homeEnvFallback
18675
+ );
18538
18676
  if (userSettings.ui?.theme === "VS") {
18539
18677
  userSettings.ui.theme = DefaultLight.name;
18540
18678
  } else if (userSettings.ui?.theme === "VS2015") {
@@ -18603,7 +18741,9 @@ Please fix the configuration file(s) and try again.`
18603
18741
  },
18604
18742
  isTrusted,
18605
18743
  migratedInMemorScopes,
18606
- allMigrationWarnings
18744
+ allMigrationWarnings,
18745
+ userResult.corruptedPath,
18746
+ userResult.wasRecovered ?? false
18607
18747
  );
18608
18748
  }
18609
18749
  __name(loadSettings, "loadSettings");
@@ -18872,7 +19012,7 @@ __name(getPackageJson, "getPackageJson");
18872
19012
  // packages/cli/src/utils/version.ts
18873
19013
  async function getCliVersion() {
18874
19014
  const pkgJson = await getPackageJson();
18875
- return "0.17.0";
19015
+ return "0.17.1";
18876
19016
  }
18877
19017
  __name(getCliVersion, "getCliVersion");
18878
19018
 
@@ -18967,7 +19107,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds, options) => {
18967
19107
 
18968
19108
  // packages/cli/src/generated/git-commit.ts
18969
19109
  init_esbuild_shims();
18970
- var GIT_COMMIT_INFO = "58f57bec2";
19110
+ var GIT_COMMIT_INFO = "09d0faf6b";
18971
19111
 
18972
19112
  // packages/cli/src/utils/systemInfo.ts
18973
19113
  var debugLogger4 = createDebugLogger("STATUS");
@@ -19157,11 +19297,14 @@ export {
19157
19297
  cleanupSettingsBackup,
19158
19298
  SETTINGS_DIRECTORY_NAME,
19159
19299
  getUserSettingsDir,
19300
+ ENV_CORRUPTED_PATH,
19301
+ ENV_WAS_RECOVERED,
19160
19302
  SettingScope,
19161
19303
  getSettingsWarnings,
19162
19304
  createMinimalSettings,
19163
19305
  preResolveHomeEnvOverrides,
19164
19306
  loadEnvironment,
19307
+ CORRUPTED_SUFFIX,
19165
19308
  loadSettings,
19166
19309
  require_debug,
19167
19310
  require_constants,
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  Client,
5
5
  StdioClientTransport
6
- } from "./chunk-TI4GXJKO.js";
6
+ } from "./chunk-7TQVELRB.js";
7
7
  import "./chunk-AKBFRR6J.js";
8
8
  import {
9
9
  safeJsonStringify
@@ -11,7 +11,7 @@ import {
11
11
  import {
12
12
  BaseDeclarativeTool,
13
13
  BaseToolInvocation
14
- } from "./chunk-R2B65CAN.js";
14
+ } from "./chunk-JKUAX6UT.js";
15
15
  import "./chunk-ACBGEKB7.js";
16
16
  import "./chunk-QWSRH265.js";
17
17
  import {
@@ -32,9 +32,10 @@ init_esbuild_shims();
32
32
 
33
33
  // packages/core/src/tools/computer-use/constants.ts
34
34
  init_esbuild_shims();
35
- var PINNED_OPEN_COMPUTER_USE_VERSION = "0.1.51";
35
+ var PINNED_OPEN_COMPUTER_USE_PACKAGE_NAME = "@qwen-code/open-computer-use";
36
+ var PINNED_OPEN_COMPUTER_USE_VERSION = "0.2.3";
36
37
  function resolveComputerUsePackageSpec() {
37
- return process.env["QWEN_COMPUTER_USE_PACKAGE"] ?? `open-computer-use@${PINNED_OPEN_COMPUTER_USE_VERSION}`;
38
+ return process.env["QWEN_COMPUTER_USE_PACKAGE"] ?? `${PINNED_OPEN_COMPUTER_USE_PACKAGE_NAME}@${PINNED_OPEN_COMPUTER_USE_VERSION}`;
38
39
  }
39
40
  __name(resolveComputerUsePackageSpec, "resolveComputerUsePackageSpec");
40
41
 
@@ -241,6 +242,22 @@ async function probePermissionsViaDoctor(packageSpec) {
241
242
  }
242
243
  }
243
244
  __name(probePermissionsViaDoctor, "probePermissionsViaDoctor");
245
+ async function probePermissionStatusViaCLI(packageSpec) {
246
+ try {
247
+ const { stdout } = await execFileAsync(
248
+ "npx",
249
+ ["-y", packageSpec, "permission-status"],
250
+ {
251
+ timeout: 3e4,
252
+ env: process.env
253
+ }
254
+ );
255
+ return parseDoctorStdout(stdout);
256
+ } catch {
257
+ return "other";
258
+ }
259
+ }
260
+ __name(probePermissionStatusViaCLI, "probePermissionStatusViaCLI");
244
261
  function defaultDeps() {
245
262
  const packageSpec = resolveComputerUsePackageSpec();
246
263
  return {
@@ -260,7 +277,8 @@ Set QWEN_COMPUTER_USE_AUTO_APPROVE=1 to skip this prompt.
260
277
  );
261
278
  return process.env["QWEN_COMPUTER_USE_AUTO_APPROVE"] === "1";
262
279
  }, "promptInstallApproval"),
263
- probePermissions: probePermissionsViaDoctor
280
+ probePermissions: probePermissionsViaDoctor,
281
+ probePermissionStatus: probePermissionStatusViaCLI
264
282
  };
265
283
  }
266
284
  __name(defaultDeps, "defaultDeps");
@@ -307,7 +325,7 @@ async function runBootstrap(client, ctx, depsOverride) {
307
325
  );
308
326
  }
309
327
  await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
310
- const next = await deps.probePermissions(deps.packageSpec);
328
+ const next = await deps.probePermissionStatus(deps.packageSpec);
311
329
  if (next === "ok" || next === "other") return;
312
330
  if (next !== lastProbeKind) {
313
331
  ctx.updateOutput?.(