@mmmbuto/qwen-code-termux 0.16.1-termux → 0.18.0-termux

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 (185) hide show
  1. package/README.md +79 -109
  2. package/bundled/new-app/SKILL.md +22 -0
  3. package/bundled/qc-helper/SKILL.md +29 -24
  4. package/bundled/qc-helper/docs/_meta.ts +1 -0
  5. package/bundled/qc-helper/docs/configuration/_meta.ts +0 -3
  6. package/bundled/qc-helper/docs/configuration/settings.md +37 -31
  7. package/bundled/qc-helper/docs/configuration/themes.md +39 -0
  8. package/bundled/qc-helper/docs/features/_meta.ts +1 -3
  9. package/bundled/qc-helper/docs/features/approval-mode.md +35 -35
  10. package/bundled/qc-helper/docs/features/auto-mode.md +54 -9
  11. package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
  12. package/bundled/qc-helper/docs/features/channels/feishu.md +170 -0
  13. package/bundled/qc-helper/docs/features/commands.md +115 -35
  14. package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
  15. package/bundled/qc-helper/docs/features/headless.md +32 -0
  16. package/bundled/qc-helper/docs/features/markdown-rendering.md +21 -1
  17. package/bundled/qc-helper/docs/features/memory.md +22 -5
  18. package/bundled/qc-helper/docs/features/scheduled-tasks.md +1 -1
  19. package/bundled/qc-helper/docs/features/status-line.md +168 -32
  20. package/bundled/qc-helper/docs/features/sub-agents.md +60 -0
  21. package/bundled/qc-helper/docs/features/worktree.md +345 -0
  22. package/bundled/qc-helper/docs/overview.md +4 -4
  23. package/bundled/qc-helper/docs/quickstart.md +4 -4
  24. package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +221 -0
  25. package/bundled/qc-helper/docs/qwen-serve.md +234 -24
  26. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +16 -0
  27. package/bundled/qc-helper/docs/support/Uninstall.md +19 -1
  28. package/bundled/qc-helper/docs/support/troubleshooting.md +2 -1
  29. package/bundled/simplify/SKILL.md +123 -0
  30. package/chunks/agent-IDS4HMOX.js +56 -0
  31. package/chunks/agent-headless-5Q2EUSPS.js +50 -0
  32. package/chunks/{anthropicContentGenerator-SSGKR6DO.js → anthropicContentGenerator-2HBRNQ3B.js} +52 -9
  33. package/chunks/{askUserQuestion-PJWUUXKN.js → askUserQuestion-75TDJVK2.js} +45 -3
  34. package/chunks/{ca-UZ7BANMN.js → ca-BARBRL6N.js} +89 -5
  35. package/chunks/{chunk-GGNTZ2NH.js → chunk-2Y5SYSD3.js} +368 -597
  36. package/chunks/{chunk-2LA2TREA.js → chunk-3AA2DK35.js} +1448 -207
  37. package/chunks/{chunk-I2V5WXHJ.js → chunk-3AUHFMSK.js} +80 -38
  38. package/chunks/chunk-3DHXZ6EV.js +241 -0
  39. package/chunks/{chunk-PR4T27R7.js → chunk-3HTIVKZE.js} +42 -8
  40. package/chunks/chunk-3HX5LZ6R.js +1798 -0
  41. package/chunks/chunk-3PJXIDKI.js +2517 -0
  42. package/chunks/{chunk-MYAKAFEC.js → chunk-55ZMG67I.js} +7451 -3517
  43. package/chunks/{chunk-66CXYE4B.js → chunk-5IFG2VC4.js} +293 -242
  44. package/chunks/chunk-64WXLC72.js +98 -0
  45. package/chunks/{chunk-C6WMLUNB.js → chunk-72LDN5PP.js} +1 -1
  46. package/chunks/{chunk-F23NCRJ2.js → chunk-A7B4ISQP.js} +1 -1
  47. package/chunks/chunk-B7HXHOHU.js +393 -0
  48. package/chunks/{chunk-XEGHDASV.js → chunk-D3RHSPAS.js} +435 -540
  49. package/chunks/{chunk-XKS5KBFJ.js → chunk-EYENRK4D.js} +694 -384
  50. package/chunks/chunk-H6BD2ELD.js +36 -0
  51. package/chunks/{chunk-XP27SJMH.js → chunk-HR7SV7AY.js} +79 -48
  52. package/chunks/{chunk-D5NTAHYL.js → chunk-IDX6COTE.js} +7 -2
  53. package/chunks/{chunk-SHT4VJWU.js → chunk-IWKSG2AR.js} +2 -2
  54. package/chunks/chunk-J37FGIOA.js +1623 -0
  55. package/chunks/chunk-J5MDQKJL.js +2230 -0
  56. package/chunks/{chunk-USE2VQ5P.js → chunk-JTQAQBTV.js} +21 -0
  57. package/chunks/{chunk-NCTLV2NB.js → chunk-KQJMQJPI.js} +1 -1
  58. package/chunks/{chunk-5FBA5XC2.js → chunk-KRIHGKNA.js} +1 -1
  59. package/chunks/chunk-LD2XBG6Z.js +102 -0
  60. package/chunks/{chunk-MAY32HXD.js → chunk-M6VTDSVR.js} +3 -1
  61. package/chunks/chunk-MRO43B25.js +30 -0
  62. package/chunks/{chunk-N4WOREMD.js → chunk-NVFMZBX2.js} +43 -3
  63. package/chunks/chunk-OHEGWO4L.js +264 -0
  64. package/chunks/{chunk-K6O2NBMF.js → chunk-OQ7NJIY7.js} +4604 -6397
  65. package/chunks/chunk-QQDPRDVW.js +25 -0
  66. package/chunks/{chunk-KXZ4TJB4.js → chunk-SEGYWKIH.js} +1 -1
  67. package/chunks/chunk-SKBPNJEW.js +45 -0
  68. package/chunks/{chunk-4AOCVI6J.js → chunk-SNGELLWX.js} +52 -6
  69. package/chunks/{chunk-3OCRHZA3.js → chunk-TD4OPI4T.js} +56742 -44104
  70. package/chunks/{chunk-DQ4QTG7E.js → chunk-VV4F63BD.js} +11 -11
  71. package/chunks/chunk-XBY7E2FX.js +605 -0
  72. package/chunks/{chunk-JKMBWLFB.js → chunk-YILFYI5W.js} +48 -26
  73. package/chunks/chunk-YOGAOMYB.js +159 -0
  74. package/chunks/{chunk-QWSRH265.js → chunk-Z2Z3GUXZ.js} +777 -776
  75. package/chunks/{chunk-SDHRQFOS.js → chunk-ZTZ4DDQE.js} +2 -2
  76. package/chunks/computer-use-W2TYQNEE.js +825 -0
  77. package/chunks/contextCommand-6FGX3A7J.js +52 -0
  78. package/chunks/{cron-create-3ZBBN7WB.js → cron-create-APL5LU6I.js} +3 -3
  79. package/chunks/{cron-delete-NAGKKIIG.js → cron-delete-4SBJSCN4.js} +3 -3
  80. package/chunks/{cron-list-PAGRXNAI.js → cron-list-2AMGOMVO.js} +3 -3
  81. package/chunks/{de-V4IE2OOZ.js → de-YGKK2BC4.js} +89 -5
  82. package/chunks/{devtools-TWVXEJQB.js → devtools-FM6GJPYG.js} +2 -1
  83. package/chunks/{dist-4L54HRX2.js → dist-4LXD6L6X.js} +24 -5
  84. package/chunks/dist-H6ONXVLG.js +94146 -0
  85. package/chunks/{dist-XKWIWPWQ.js → dist-KAZ3SEBX.js} +1083 -3856
  86. package/chunks/{dist-BXDUQ2QY.js → dist-PK7DFCAW.js} +1 -1
  87. package/chunks/{edit-NVO3FOAK.js → edit-ZCEZC264.js} +30 -22
  88. package/chunks/{en-HGJ2SPLM.js → en-DHGYHIHX.js} +127 -6
  89. package/chunks/{enter-worktree-UEBG4WFC.js → enter-worktree-BBHCFCHG.js} +30 -20
  90. package/chunks/enterPlanMode-3M6KTD3B.js +158 -0
  91. package/chunks/{exit-worktree-UZ3MAQZN.js → exit-worktree-73YPIEQO.js} +27 -19
  92. package/chunks/exitPlanMode-TYZM6BAE.js +703 -0
  93. package/chunks/{fr-CJULI7ZX.js → fr-JXBKPJKQ.js} +89 -5
  94. package/chunks/{geminiContentGenerator-3UZFXGNT.js → geminiContentGenerator-7N2V3VW2.js} +8 -6
  95. package/chunks/{getMachineId-bsd-JXOSIJV2.js → getMachineId-bsd-4CASPIU4.js} +4 -4
  96. package/chunks/{getMachineId-darwin-TE4QRR42.js → getMachineId-darwin-HPQPEMZR.js} +4 -4
  97. package/chunks/{getMachineId-linux-S3OL52XK.js → getMachineId-linux-AUARKYHL.js} +3 -3
  98. package/chunks/{getMachineId-unsupported-DWUSBAPX.js → getMachineId-unsupported-S32ZDA2T.js} +3 -3
  99. package/chunks/{getMachineId-win-AAC5P3AP.js → getMachineId-win-4EFLHYIJ.js} +4 -4
  100. package/chunks/{glob-KNHSFFFG.js → glob-5XBCPQ2A.js} +27 -19
  101. package/chunks/{grep-LACWDZW4.js → grep-VIUU3A7X.js} +30 -19
  102. package/chunks/{ja-L7CHRQEW.js → ja-TGPZSP2B.js} +89 -5
  103. package/chunks/{keychain-token-storage-335UOLJ6.js → keychain-token-storage-6IU6ORQN.js} +3 -3
  104. package/chunks/{ls-AGXQOKSG.js → ls-JRGYIGLY.js} +4 -4
  105. package/chunks/{lsp-UDMUHNPA.js → lsp-SHMKFOAC.js} +3 -3
  106. package/chunks/{monitor-ETKWPJEH.js → monitor-6R4LIJL5.js} +40 -25
  107. package/chunks/{multipart-parser-3QWGTLK3.js → multipart-parser-AJ4WASWR.js} +2 -2
  108. package/chunks/{notebook-edit-QJJLPNYT.js → notebook-edit-5E7ULDVQ.js} +28 -20
  109. package/chunks/{openaiContentGenerator-CNNN424U.js → openaiContentGenerator-ZVHFKM3O.js} +17 -14
  110. package/chunks/{pt-M6JULLEQ.js → pt-TIBG6BIO.js} +89 -5
  111. package/chunks/{qwenContentGenerator-BOLCGK3R.js → qwenContentGenerator-B2VTVSPJ.js} +31 -23
  112. package/chunks/{qwenOAuth2-EEJGROP7.js → qwenOAuth2-2KCKWDCF.js} +6 -4
  113. package/chunks/read-file-GIT7BCDR.js +27 -0
  114. package/chunks/ripGrep-MWKFVYMS.js +48 -0
  115. package/chunks/{ru-QILM4HBC.js → ru-JBCHCK4L.js} +89 -5
  116. package/chunks/scheduler-5VOOYGBH.js +308 -0
  117. package/chunks/send-message-4QNWQJF4.js +244 -0
  118. package/chunks/{serve-OLSI7WSR.js → serve-MN6HZBWN.js} +14262 -7414
  119. package/chunks/shell-NQZQGFM2.js +56 -0
  120. package/chunks/{skill-D6YRHTTI.js → skill-WCFW4644.js} +145 -119
  121. package/chunks/{src-TMOD5X6F.js → src-7XL4G4DC.js} +88 -46
  122. package/chunks/{src-4QH4FZ6I.js → src-IHA6DTUV.js} +452 -62
  123. package/chunks/{syntheticOutput-5PVFDDJ4.js → syntheticOutput-YTYS2ZMQ.js} +4 -4
  124. package/chunks/task-create-MPORPYN6.js +19 -0
  125. package/chunks/task-list-R2YDYPZT.js +151 -0
  126. package/chunks/{task-stop-AJKPSR6R.js → task-stop-SYWJYBCM.js} +3 -3
  127. package/chunks/task-update-E4NSLKMQ.js +408 -0
  128. package/chunks/team-create-7R7KA5IP.js +314 -0
  129. package/chunks/team-delete-25OIWUPN.js +116 -0
  130. package/chunks/{todoWrite-VLAUG4CA.js → todoWrite-4YHMIF4X.js} +16 -5
  131. package/chunks/{tool-search-MZGHUUKD.js → tool-search-YBRVZCLI.js} +29 -11
  132. package/chunks/{tts-notification-K3X7X7MN.js → tts-notification-7SOEMQK4.js} +5 -4
  133. package/chunks/{web-fetch-OILB464A.js → web-fetch-MFIRHIHI.js} +5 -5
  134. package/chunks/workflow-5RIKVCIE.js +960 -0
  135. package/chunks/{write-file-BIQAA57V.js → write-file-DMQTJZOM.js} +32 -24
  136. package/chunks/{zh-PWL2NKY3.js → zh-7H5OQC4I.js} +135 -11
  137. package/chunks/{zh-TW-S3YGWICZ.js → zh-TW-P4IDHD3M.js} +128 -11
  138. package/cli.js +45402 -20570
  139. package/examples/agent/agents/diary.md +86 -0
  140. package/examples/agent/qwen-extension.json +5 -0
  141. package/examples/commands/commands/fs/grep-code.md +3 -0
  142. package/examples/commands/qwen-extension.json +5 -0
  143. package/examples/context/QWEN.md +8 -0
  144. package/examples/context/qwen-extension.json +5 -0
  145. package/examples/mcp-server/example.ts +60 -0
  146. package/examples/mcp-server/package.json +18 -0
  147. package/examples/mcp-server/qwen-extension.json +12 -0
  148. package/examples/mcp-server/tsconfig.json +13 -0
  149. package/examples/skills/qwen-extension.json +5 -0
  150. package/examples/skills/skills/synonyms/SKILL.md +48 -0
  151. package/examples/starter/QWEN.md +30 -0
  152. package/examples/starter/README.md +59 -0
  153. package/examples/starter/agents/diary.md +86 -0
  154. package/examples/starter/commands/writing/polish.md +13 -0
  155. package/examples/starter/example.ts +64 -0
  156. package/examples/starter/package.json +18 -0
  157. package/examples/starter/qwen-extension.json +12 -0
  158. package/examples/starter/skills/synonyms/SKILL.md +48 -0
  159. package/examples/starter/tsconfig.json +13 -0
  160. package/fzfWorker.js +1083 -0
  161. package/locales/ca.js +118 -5
  162. package/locales/de.js +117 -5
  163. package/locales/en.js +169 -7
  164. package/locales/fr.js +119 -5
  165. package/locales/ja.js +114 -5
  166. package/locales/pt.js +117 -5
  167. package/locales/ru.js +116 -5
  168. package/locales/zh-TW.js +161 -12
  169. package/locales/zh.js +169 -12
  170. package/package.json +4 -2
  171. package/scripts/postinstall.cjs +2 -1
  172. package/bundled/qc-helper/docs/features/checkpointing.md +0 -77
  173. package/chunks/agent-7ZN3CRHR.js +0 -48
  174. package/chunks/chunk-6PCB2DEF.js +0 -434
  175. package/chunks/chunk-EM6ETG2K.js +0 -60
  176. package/chunks/chunk-G7YTSRES.js +0 -150
  177. package/chunks/contextCommand-7IBASARL.js +0 -44
  178. package/chunks/exitPlanMode-PZAMWIRW.js +0 -227
  179. package/chunks/multipart-parser-IXGBIOIN.js +0 -384
  180. package/chunks/read-file-CCUEUFG2.js +0 -24
  181. package/chunks/ripGrep-TADOH2HK.js +0 -40
  182. package/chunks/send-message-YL44UZFC.js +0 -151
  183. package/chunks/shell-7KKKC5G7.js +0 -48
  184. package/chunks/src-IPWIHNMI.js +0 -1406
  185. package/chunks/undici-F6ZOXSS5.js +0 -8
@@ -6,26 +6,31 @@ import {
6
6
  getLanguageSettingsOptions,
7
7
  t,
8
8
  writeStderrLine
9
- } from "./chunk-DQ4QTG7E.js";
9
+ } from "./chunk-VV4F63BD.js";
10
10
  import {
11
11
  DEFAULT_STOP_HOOK_BLOCK_CAP,
12
+ DEFAULT_TOOL_OUTPUT_BATCH_BUDGET,
12
13
  DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
13
14
  DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
14
15
  IdeClient,
15
16
  SkillError,
16
17
  ideContextStore,
17
18
  require_main
18
- } from "./chunk-3OCRHZA3.js";
19
+ } from "./chunk-TD4OPI4T.js";
19
20
  import {
20
- isWithinRoot
21
- } from "./chunk-K6O2NBMF.js";
21
+ isWithinRoot,
22
+ stripRuntimeSnapshotPrefix
23
+ } from "./chunk-OQ7NJIY7.js";
24
+ import {
25
+ atomicWriteFileSync
26
+ } from "./chunk-B7HXHOHU.js";
22
27
  import {
23
28
  FatalConfigError,
24
29
  QWEN_DIR,
25
30
  Storage,
26
31
  createDebugLogger,
27
32
  getErrorMessage
28
- } from "./chunk-XP27SJMH.js";
33
+ } from "./chunk-HR7SV7AY.js";
29
34
  import {
30
35
  init_esbuild_shims
31
36
  } from "./chunk-A4BMJM77.js";
@@ -11997,13 +12002,13 @@ var require_hosts = __commonJS({
11997
12002
  var defaults = {
11998
12003
  sshtemplate: /* @__PURE__ */ __name(({ domain, user, project, committish }) => `git@${domain}:${user}/${project}.git${maybeJoin("#", committish)}`, "sshtemplate"),
11999
12004
  sshurltemplate: /* @__PURE__ */ __name(({ domain, user, project, committish }) => `git+ssh://git@${domain}/${user}/${project}.git${maybeJoin("#", committish)}`, "sshurltemplate"),
12000
- edittemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, editpath, path: path8 }) => `https://${domain}/${user}/${project}${maybeJoin("/", editpath, "/", maybeEncode(committish || "HEAD"), "/", path8)}`, "edittemplate"),
12005
+ edittemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, editpath, path: path9 }) => `https://${domain}/${user}/${project}${maybeJoin("/", editpath, "/", maybeEncode(committish || "HEAD"), "/", path9)}`, "edittemplate"),
12001
12006
  browsetemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, treepath }) => `https://${domain}/${user}/${project}${maybeJoin("/", treepath, "/", maybeEncode(committish))}`, "browsetemplate"),
12002
- browsetreetemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, treepath, path: path8, fragment, hashformat }) => `https://${domain}/${user}/${project}/${treepath}/${maybeEncode(committish || "HEAD")}/${path8}${maybeJoin("#", hashformat(fragment || ""))}`, "browsetreetemplate"),
12003
- browseblobtemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, blobpath, path: path8, fragment, hashformat }) => `https://${domain}/${user}/${project}/${blobpath}/${maybeEncode(committish || "HEAD")}/${path8}${maybeJoin("#", hashformat(fragment || ""))}`, "browseblobtemplate"),
12007
+ browsetreetemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, treepath, path: path9, fragment, hashformat }) => `https://${domain}/${user}/${project}/${treepath}/${maybeEncode(committish || "HEAD")}/${path9}${maybeJoin("#", hashformat(fragment || ""))}`, "browsetreetemplate"),
12008
+ browseblobtemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, blobpath, path: path9, fragment, hashformat }) => `https://${domain}/${user}/${project}/${blobpath}/${maybeEncode(committish || "HEAD")}/${path9}${maybeJoin("#", hashformat(fragment || ""))}`, "browseblobtemplate"),
12004
12009
  docstemplate: /* @__PURE__ */ __name(({ domain, user, project, treepath, committish }) => `https://${domain}/${user}/${project}${maybeJoin("/", treepath, "/", maybeEncode(committish))}#readme`, "docstemplate"),
12005
12010
  httpstemplate: /* @__PURE__ */ __name(({ auth, domain, user, project, committish }) => `git+https://${maybeJoin(auth, "@")}${domain}/${user}/${project}.git${maybeJoin("#", committish)}`, "httpstemplate"),
12006
- filetemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, path: path8 }) => `https://${domain}/${user}/${project}/raw/${maybeEncode(committish || "HEAD")}/${path8}`, "filetemplate"),
12011
+ filetemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, path: path9 }) => `https://${domain}/${user}/${project}/raw/${maybeEncode(committish || "HEAD")}/${path9}`, "filetemplate"),
12007
12012
  shortcuttemplate: /* @__PURE__ */ __name(({ type, user, project, committish }) => `${type}:${user}/${project}${maybeJoin("#", committish)}`, "shortcuttemplate"),
12008
12013
  pathtemplate: /* @__PURE__ */ __name(({ user, project, committish }) => `${user}/${project}${maybeJoin("#", committish)}`, "pathtemplate"),
12009
12014
  bugstemplate: /* @__PURE__ */ __name(({ domain, user, project }) => `https://${domain}/${user}/${project}/issues`, "bugstemplate"),
@@ -12018,7 +12023,7 @@ var require_hosts = __commonJS({
12018
12023
  treepath: "tree",
12019
12024
  blobpath: "blob",
12020
12025
  editpath: "edit",
12021
- filetemplate: /* @__PURE__ */ __name(({ auth, user, project, committish, path: path8 }) => `https://${maybeJoin(auth, "@")}raw.githubusercontent.com/${user}/${project}/${maybeEncode(committish || "HEAD")}/${path8}`, "filetemplate"),
12026
+ filetemplate: /* @__PURE__ */ __name(({ auth, user, project, committish, path: path9 }) => `https://${maybeJoin(auth, "@")}raw.githubusercontent.com/${user}/${project}/${maybeEncode(committish || "HEAD")}/${path9}`, "filetemplate"),
12022
12027
  gittemplate: /* @__PURE__ */ __name(({ auth, domain, user, project, committish }) => `git://${maybeJoin(auth, "@")}${domain}/${user}/${project}.git${maybeJoin("#", committish)}`, "gittemplate"),
12023
12028
  tarballtemplate: /* @__PURE__ */ __name(({ domain, user, project, committish }) => `https://codeload.${domain}/${user}/${project}/tar.gz/${maybeEncode(committish || "HEAD")}`, "tarballtemplate"),
12024
12029
  extract: /* @__PURE__ */ __name((url) => {
@@ -12044,7 +12049,7 @@ var require_hosts = __commonJS({
12044
12049
  treepath: "src",
12045
12050
  blobpath: "src",
12046
12051
  editpath: "?mode=edit",
12047
- edittemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, treepath, path: path8, editpath }) => `https://${domain}/${user}/${project}${maybeJoin("/", treepath, "/", maybeEncode(committish || "HEAD"), "/", path8, editpath)}`, "edittemplate"),
12052
+ edittemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, treepath, path: path9, editpath }) => `https://${domain}/${user}/${project}${maybeJoin("/", treepath, "/", maybeEncode(committish || "HEAD"), "/", path9, editpath)}`, "edittemplate"),
12048
12053
  tarballtemplate: /* @__PURE__ */ __name(({ domain, user, project, committish }) => `https://${domain}/${user}/${project}/get/${maybeEncode(committish || "HEAD")}.tar.gz`, "tarballtemplate"),
12049
12054
  extract: /* @__PURE__ */ __name((url) => {
12050
12055
  let [, user, project, aux] = url.pathname.split("/", 4);
@@ -12069,11 +12074,11 @@ var require_hosts = __commonJS({
12069
12074
  httpstemplate: /* @__PURE__ */ __name(({ auth, domain, user, project, committish }) => `git+https://${maybeJoin(auth, "@")}${domain}/${user}/${project}.git${maybeJoin("#", committish)}`, "httpstemplate"),
12070
12075
  tarballtemplate: /* @__PURE__ */ __name(({ domain, user, project, committish }) => `https://${domain}/${user}/${project}/repository/archive.tar.gz?ref=${maybeEncode(committish || "HEAD")}`, "tarballtemplate"),
12071
12076
  extract: /* @__PURE__ */ __name((url) => {
12072
- const path8 = url.pathname.slice(1);
12073
- if (path8.includes("/-/") || path8.includes("/archive.tar.gz")) {
12077
+ const path9 = url.pathname.slice(1);
12078
+ if (path9.includes("/-/") || path9.includes("/archive.tar.gz")) {
12074
12079
  return;
12075
12080
  }
12076
- const segments = path8.split("/");
12081
+ const segments = path9.split("/");
12077
12082
  let project = segments.pop();
12078
12083
  if (project.endsWith(".git")) {
12079
12084
  project = project.slice(0, -4);
@@ -12093,11 +12098,11 @@ var require_hosts = __commonJS({
12093
12098
  sshurltemplate: /* @__PURE__ */ __name(({ domain, project, committish }) => `git+ssh://git@${domain}/${project}.git${maybeJoin("#", committish)}`, "sshurltemplate"),
12094
12099
  edittemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, editpath }) => `https://${domain}/${user}/${project}${maybeJoin("/", maybeEncode(committish))}/${editpath}`, "edittemplate"),
12095
12100
  browsetemplate: /* @__PURE__ */ __name(({ domain, project, committish }) => `https://${domain}/${project}${maybeJoin("/", maybeEncode(committish))}`, "browsetemplate"),
12096
- browsetreetemplate: /* @__PURE__ */ __name(({ domain, project, committish, path: path8, hashformat }) => `https://${domain}/${project}${maybeJoin("/", maybeEncode(committish))}${maybeJoin("#", hashformat(path8))}`, "browsetreetemplate"),
12097
- browseblobtemplate: /* @__PURE__ */ __name(({ domain, project, committish, path: path8, hashformat }) => `https://${domain}/${project}${maybeJoin("/", maybeEncode(committish))}${maybeJoin("#", hashformat(path8))}`, "browseblobtemplate"),
12101
+ browsetreetemplate: /* @__PURE__ */ __name(({ domain, project, committish, path: path9, hashformat }) => `https://${domain}/${project}${maybeJoin("/", maybeEncode(committish))}${maybeJoin("#", hashformat(path9))}`, "browsetreetemplate"),
12102
+ browseblobtemplate: /* @__PURE__ */ __name(({ domain, project, committish, path: path9, hashformat }) => `https://${domain}/${project}${maybeJoin("/", maybeEncode(committish))}${maybeJoin("#", hashformat(path9))}`, "browseblobtemplate"),
12098
12103
  docstemplate: /* @__PURE__ */ __name(({ domain, project, committish }) => `https://${domain}/${project}${maybeJoin("/", maybeEncode(committish))}`, "docstemplate"),
12099
12104
  httpstemplate: /* @__PURE__ */ __name(({ domain, project, committish }) => `git+https://${domain}/${project}.git${maybeJoin("#", committish)}`, "httpstemplate"),
12100
- filetemplate: /* @__PURE__ */ __name(({ user, project, committish, path: path8 }) => `https://gist.githubusercontent.com/${user}/${project}/raw${maybeJoin("/", maybeEncode(committish))}/${path8}`, "filetemplate"),
12105
+ filetemplate: /* @__PURE__ */ __name(({ user, project, committish, path: path9 }) => `https://gist.githubusercontent.com/${user}/${project}/raw${maybeJoin("/", maybeEncode(committish))}/${path9}`, "filetemplate"),
12101
12106
  shortcuttemplate: /* @__PURE__ */ __name(({ type, project, committish }) => `${type}:${project}${maybeJoin("#", committish)}`, "shortcuttemplate"),
12102
12107
  pathtemplate: /* @__PURE__ */ __name(({ project, committish }) => `${project}${maybeJoin("#", committish)}`, "pathtemplate"),
12103
12108
  bugstemplate: /* @__PURE__ */ __name(({ domain, project }) => `https://${domain}/${project}`, "bugstemplate"),
@@ -12129,7 +12134,7 @@ var require_hosts = __commonJS({
12129
12134
  domain: "git.sr.ht",
12130
12135
  treepath: "tree",
12131
12136
  blobpath: "tree",
12132
- filetemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, path: path8 }) => `https://${domain}/${user}/${project}/blob/${maybeEncode(committish) || "HEAD"}/${path8}`, "filetemplate"),
12137
+ filetemplate: /* @__PURE__ */ __name(({ domain, user, project, committish, path: path9 }) => `https://${domain}/${user}/${project}/blob/${maybeEncode(committish) || "HEAD"}/${path9}`, "filetemplate"),
12133
12138
  httpstemplate: /* @__PURE__ */ __name(({ domain, user, project, committish }) => `https://${domain}/${user}/${project}.git${maybeJoin("#", committish)}`, "httpstemplate"),
12134
12139
  tarballtemplate: /* @__PURE__ */ __name(({ domain, user, project, committish }) => `https://${domain}/${user}/${project}/archive/${maybeEncode(committish) || "HEAD"}.tar.gz`, "tarballtemplate"),
12135
12140
  bugstemplate: /* @__PURE__ */ __name(() => null, "bugstemplate"),
@@ -12323,8 +12328,8 @@ var require_lib3 = __commonJS({
12323
12328
  return null;
12324
12329
  }
12325
12330
  const proto = /(?:git\+)http:$/.test(protocol) ? "http:" : "https:";
12326
- const path8 = pathname.replace(/\.git$/, "");
12327
- return `${proto}//${hostname}${path8}`;
12331
+ const path9 = pathname.replace(/\.git$/, "");
12332
+ return `${proto}//${hostname}${path9}`;
12328
12333
  } catch {
12329
12334
  return null;
12330
12335
  }
@@ -12420,25 +12425,25 @@ var require_lib3 = __commonJS({
12420
12425
  sshurl(opts) {
12421
12426
  return this.#fill(this.sshurltemplate, opts);
12422
12427
  }
12423
- browse(path8, ...args) {
12424
- if (typeof path8 !== "string") {
12425
- return this.#fill(this.browsetemplate, path8);
12428
+ browse(path9, ...args) {
12429
+ if (typeof path9 !== "string") {
12430
+ return this.#fill(this.browsetemplate, path9);
12426
12431
  }
12427
12432
  if (typeof args[0] !== "string") {
12428
- return this.#fill(this.browsetreetemplate, { ...args[0], path: path8 });
12433
+ return this.#fill(this.browsetreetemplate, { ...args[0], path: path9 });
12429
12434
  }
12430
- return this.#fill(this.browsetreetemplate, { ...args[1], fragment: args[0], path: path8 });
12435
+ return this.#fill(this.browsetreetemplate, { ...args[1], fragment: args[0], path: path9 });
12431
12436
  }
12432
12437
  // If the path is known to be a file, then browseFile should be used. For some hosts
12433
12438
  // the url is the same as browse, but for others like GitHub a file can use both `/tree/`
12434
12439
  // and `/blob/` in the path. When using a default committish of `HEAD` then the `/tree/`
12435
12440
  // path will redirect to a specific commit. Using the `/blob/` path avoids this and
12436
12441
  // does not redirect to a different commit.
12437
- browseFile(path8, ...args) {
12442
+ browseFile(path9, ...args) {
12438
12443
  if (typeof args[0] !== "string") {
12439
- return this.#fill(this.browseblobtemplate, { ...args[0], path: path8 });
12444
+ return this.#fill(this.browseblobtemplate, { ...args[0], path: path9 });
12440
12445
  }
12441
- return this.#fill(this.browseblobtemplate, { ...args[1], fragment: args[0], path: path8 });
12446
+ return this.#fill(this.browseblobtemplate, { ...args[1], fragment: args[0], path: path9 });
12442
12447
  }
12443
12448
  docs(opts) {
12444
12449
  return this.#fill(this.docstemplate, opts);
@@ -12461,11 +12466,11 @@ var require_lib3 = __commonJS({
12461
12466
  tarball(opts) {
12462
12467
  return this.#fill(this.tarballtemplate, { ...opts, noCommittish: false });
12463
12468
  }
12464
- file(path8, opts) {
12465
- return this.#fill(this.filetemplate, { ...opts, path: path8 });
12469
+ file(path9, opts) {
12470
+ return this.#fill(this.filetemplate, { ...opts, path: path9 });
12466
12471
  }
12467
- edit(path8, opts) {
12468
- return this.#fill(this.edittemplate, { ...opts, path: path8 });
12472
+ edit(path9, opts) {
12473
+ return this.#fill(this.edittemplate, { ...opts, path: path9 });
12469
12474
  }
12470
12475
  getDefaultRepresentation() {
12471
12476
  return this.default;
@@ -13118,6 +13123,11 @@ var DEFAULT_RING_SIZE = 8e3;
13118
13123
  var WARN_THRESHOLD_RATIO = 0.75;
13119
13124
  var WARN_RESET_RATIO = 0.375;
13120
13125
  var DEFAULT_MAX_SUBSCRIBERS = 64;
13126
+ function getServerTimestamp(meta) {
13127
+ const existing = meta?.["serverTimestamp"];
13128
+ return typeof existing === "number" && Number.isFinite(existing) ? existing : Date.now();
13129
+ }
13130
+ __name(getServerTimestamp, "getServerTimestamp");
13121
13131
  var SubscriberLimitExceededError = class extends Error {
13122
13132
  static {
13123
13133
  __name(this, "SubscriberLimitExceededError");
@@ -13130,9 +13140,10 @@ var SubscriberLimitExceededError = class extends Error {
13130
13140
  }
13131
13141
  };
13132
13142
  var EventBus = class {
13133
- constructor(ringSize = DEFAULT_RING_SIZE, maxSubscribers = DEFAULT_MAX_SUBSCRIBERS) {
13143
+ constructor(ringSize = DEFAULT_RING_SIZE, maxSubscribers = DEFAULT_MAX_SUBSCRIBERS, compactionEngine) {
13134
13144
  this.ringSize = ringSize;
13135
13145
  this.maxSubscribers = maxSubscribers;
13146
+ this.compactionEngine = compactionEngine;
13136
13147
  }
13137
13148
  static {
13138
13149
  __name(this, "EventBus");
@@ -13141,6 +13152,9 @@ var EventBus = class {
13141
13152
  ring = [];
13142
13153
  subs = /* @__PURE__ */ new Set();
13143
13154
  closed = false;
13155
+ snapshotReplay() {
13156
+ return this.compactionEngine?.snapshot();
13157
+ }
13144
13158
  /** Most recent id ever assigned by `publish`. 0 if no events published. */
13145
13159
  get lastEventId() {
13146
13160
  return this.nextId - 1;
@@ -13154,7 +13168,7 @@ var EventBus = class {
13154
13168
  * (with `id` + `v` assigned) on success, or `undefined` when the
13155
13169
  * bus is closed.
13156
13170
  *
13157
- * **Never throws** (BX9_p contract). Closing the bus mid-publish
13171
+ * **Never throws** (never-throws contract). Closing the bus mid-publish
13158
13172
  * is the only abnormal path and is handled as a return-undefined
13159
13173
  * no-op; subscriber-enqueue failures are caught internally and
13160
13174
  * translated to per-subscriber eviction. Call sites can rely on
@@ -13165,12 +13179,21 @@ var EventBus = class {
13165
13179
  */
13166
13180
  publish(input) {
13167
13181
  if (this.closed) return void 0;
13182
+ const existingMeta = input._meta;
13168
13183
  const event = {
13169
13184
  id: this.nextId++,
13170
13185
  v: EVENT_SCHEMA_VERSION,
13171
- ...input
13186
+ ...input,
13187
+ _meta: {
13188
+ ...existingMeta ?? {},
13189
+ serverTimestamp: getServerTimestamp(existingMeta)
13190
+ }
13172
13191
  };
13173
13192
  this.ring.push(event);
13193
+ try {
13194
+ this.compactionEngine?.ingest(event);
13195
+ } catch {
13196
+ }
13174
13197
  if (this.ring.length > this.ringSize) this.ring.shift();
13175
13198
  for (const sub of Array.from(this.subs)) {
13176
13199
  if (sub.evicted) continue;
@@ -13243,11 +13266,61 @@ var EventBus = class {
13243
13266
  };
13244
13267
  this.subs.add(sub);
13245
13268
  if (opts.lastEventId !== void 0) {
13269
+ const epochReset = opts.lastEventId >= this.nextId;
13270
+ if (epochReset) {
13271
+ queue.forcePush({
13272
+ v: EVENT_SCHEMA_VERSION,
13273
+ type: "state_resync_required",
13274
+ data: {
13275
+ reason: "epoch_reset",
13276
+ lastDeliveredId: opts.lastEventId,
13277
+ // Ring is typically empty right after a restart; fall back to
13278
+ // `nextId` (the first id this epoch will assign) so the field
13279
+ // stays meaningful ("fresh sequence starts here").
13280
+ earliestAvailableId: this.ring[0]?.id ?? this.nextId
13281
+ }
13282
+ });
13283
+ } else {
13284
+ const earliestInRing = this.ring[0]?.id;
13285
+ if (earliestInRing !== void 0 && earliestInRing > opts.lastEventId + 1) {
13286
+ queue.forcePush({
13287
+ v: EVENT_SCHEMA_VERSION,
13288
+ type: "state_resync_required",
13289
+ data: {
13290
+ reason: "ring_evicted",
13291
+ lastDeliveredId: opts.lastEventId,
13292
+ earliestAvailableId: earliestInRing
13293
+ }
13294
+ });
13295
+ }
13296
+ }
13297
+ const replayFrom = epochReset ? 0 : opts.lastEventId;
13298
+ let replayedCount = 0;
13299
+ let lastReplayedId;
13246
13300
  for (const e of this.ring) {
13247
- if (e.id !== void 0 && e.id > opts.lastEventId) {
13301
+ if (e.id !== void 0 && e.id > replayFrom) {
13248
13302
  queue.forcePush(e);
13303
+ replayedCount += 1;
13304
+ lastReplayedId = e.id;
13305
+ }
13306
+ }
13307
+ queue.forcePush({
13308
+ v: EVENT_SCHEMA_VERSION,
13309
+ type: "replay_complete",
13310
+ data: {
13311
+ // Note: `lastReplayedEventId`
13312
+ // is the canonical wire name — the old `lastEventId` collided
13313
+ // semantically with the SSE protocol's `Last-Event-ID` (envelope
13314
+ // `id`) in raw daemon traces. Emit both: `lastReplayedEventId`
13315
+ // for current SDKs and `lastEventId` as a deprecated alias so
13316
+ // pre-rename consumers keep working (additive, non-breaking).
13317
+ ...lastReplayedId !== void 0 ? {
13318
+ lastReplayedEventId: lastReplayedId,
13319
+ lastEventId: lastReplayedId
13320
+ } : {},
13321
+ replayedCount
13249
13322
  }
13250
- }
13323
+ });
13251
13324
  }
13252
13325
  let disposed = false;
13253
13326
  const dispose = /* @__PURE__ */ __name(() => {
@@ -13289,6 +13362,7 @@ var EventBus = class {
13289
13362
  this.closed = true;
13290
13363
  for (const sub of this.subs) sub.queue.close();
13291
13364
  this.subs.clear();
13365
+ this.compactionEngine?.close();
13292
13366
  }
13293
13367
  };
13294
13368
  function emptyAsyncIterable() {
@@ -13392,13 +13466,320 @@ var BoundedAsyncQueue = class {
13392
13466
  done: true
13393
13467
  });
13394
13468
  }
13395
- return new Promise((resolve2) => this.resolvers.push(resolve2));
13469
+ return new Promise((resolve3) => this.resolvers.push(resolve3));
13396
13470
  }
13397
13471
  };
13398
13472
 
13399
13473
  // packages/cli/src/serve/eventBus.ts
13400
13474
  init_esbuild_shims();
13401
13475
 
13476
+ // packages/acp-bridge/src/bridgeErrors.ts
13477
+ init_esbuild_shims();
13478
+
13479
+ // packages/acp-bridge/src/workspacePaths.ts
13480
+ init_esbuild_shims();
13481
+ import { realpathSync } from "node:fs";
13482
+ import * as path from "node:path";
13483
+ function canonicalizeWorkspace(p) {
13484
+ const resolved = path.resolve(p);
13485
+ try {
13486
+ return realpathSync.native(resolved);
13487
+ } catch (err) {
13488
+ if (err && typeof err === "object" && err.code === "ENOENT") {
13489
+ return resolved;
13490
+ }
13491
+ throw err;
13492
+ }
13493
+ }
13494
+ __name(canonicalizeWorkspace, "canonicalizeWorkspace");
13495
+ var MAX_WORKSPACE_PATH_LENGTH = 4096;
13496
+
13497
+ // packages/acp-bridge/src/bridgeErrors.ts
13498
+ var NOT_CURRENTLY_GENERATING_CANCEL_MESSAGE = "Not currently generating";
13499
+ function isNotCurrentlyGeneratingCancelError(err) {
13500
+ if (!err || typeof err !== "object") return false;
13501
+ const maybe = err;
13502
+ if (isNotCurrentlyGeneratingText(maybe.message)) return true;
13503
+ if (!maybe.data || typeof maybe.data !== "object") return false;
13504
+ return isNotCurrentlyGeneratingText(
13505
+ maybe.data.details
13506
+ );
13507
+ }
13508
+ __name(isNotCurrentlyGeneratingCancelError, "isNotCurrentlyGeneratingCancelError");
13509
+ function isNotCurrentlyGeneratingText(value) {
13510
+ return typeof value === "string" && /\bnot currently generating\b/i.test(value);
13511
+ }
13512
+ __name(isNotCurrentlyGeneratingText, "isNotCurrentlyGeneratingText");
13513
+ var SessionNotFoundError = class extends Error {
13514
+ static {
13515
+ __name(this, "SessionNotFoundError");
13516
+ }
13517
+ sessionId;
13518
+ constructor(sessionId, extra) {
13519
+ super(`No session with id "${sessionId}"` + (extra ? `. ${extra}` : ""));
13520
+ this.name = "SessionNotFoundError";
13521
+ this.sessionId = sessionId;
13522
+ }
13523
+ };
13524
+ var RestoreInProgressError = class extends Error {
13525
+ static {
13526
+ __name(this, "RestoreInProgressError");
13527
+ }
13528
+ sessionId;
13529
+ activeAction;
13530
+ requestedAction;
13531
+ constructor(sessionId, activeAction, requestedAction) {
13532
+ super(
13533
+ `Session "${sessionId}" is already being restored via session/${activeAction}; retry session/${requestedAction} after it completes`
13534
+ );
13535
+ this.name = "RestoreInProgressError";
13536
+ this.sessionId = sessionId;
13537
+ this.activeAction = activeAction;
13538
+ this.requestedAction = requestedAction;
13539
+ }
13540
+ };
13541
+ var InvalidSessionScopeError = class extends Error {
13542
+ static {
13543
+ __name(this, "InvalidSessionScopeError");
13544
+ }
13545
+ sessionScope;
13546
+ constructor(sessionScope) {
13547
+ super(
13548
+ `Invalid sessionScope: ${JSON.stringify(sessionScope)}. Expected 'single' or 'thread'.`
13549
+ );
13550
+ this.name = "InvalidSessionScopeError";
13551
+ this.sessionScope = sessionScope;
13552
+ }
13553
+ };
13554
+ var SessionLimitExceededError = class extends Error {
13555
+ static {
13556
+ __name(this, "SessionLimitExceededError");
13557
+ }
13558
+ limit;
13559
+ constructor(limit) {
13560
+ super(`Session limit reached (${limit})`);
13561
+ this.name = "SessionLimitExceededError";
13562
+ this.limit = limit;
13563
+ }
13564
+ };
13565
+ var WorkspaceMismatchError = class extends Error {
13566
+ static {
13567
+ __name(this, "WorkspaceMismatchError");
13568
+ }
13569
+ bound;
13570
+ requested;
13571
+ constructor(bound, requested) {
13572
+ const safeRequested = requested.length > MAX_WORKSPACE_PATH_LENGTH ? `${requested.slice(0, MAX_WORKSPACE_PATH_LENGTH)}\u2026[truncated]` : requested;
13573
+ super(
13574
+ `Workspace mismatch: daemon is bound to "${bound}" but request asked for "${safeRequested}". Each \`qwen serve\` daemon binds to exactly one workspace; start a separate daemon for "${safeRequested}" (or route the request to one via an orchestrator).`
13575
+ );
13576
+ this.name = "WorkspaceMismatchError";
13577
+ this.bound = bound;
13578
+ this.requested = safeRequested;
13579
+ }
13580
+ };
13581
+ var InvalidClientIdError = class extends Error {
13582
+ static {
13583
+ __name(this, "InvalidClientIdError");
13584
+ }
13585
+ sessionId;
13586
+ clientId;
13587
+ constructor(sessionId, clientId) {
13588
+ super(`Client id "${clientId}" is not registered for session ${sessionId}`);
13589
+ this.name = "InvalidClientIdError";
13590
+ this.sessionId = sessionId;
13591
+ this.clientId = clientId;
13592
+ }
13593
+ };
13594
+ var InvalidPermissionOptionError = class extends Error {
13595
+ static {
13596
+ __name(this, "InvalidPermissionOptionError");
13597
+ }
13598
+ requestId;
13599
+ optionId;
13600
+ constructor(requestId, optionId) {
13601
+ super(
13602
+ `Permission ${requestId}: optionId "${optionId}" is not in the set of options the agent offered.`
13603
+ );
13604
+ this.name = "InvalidPermissionOptionError";
13605
+ this.requestId = requestId;
13606
+ this.optionId = optionId;
13607
+ }
13608
+ };
13609
+ var InvalidSessionMetadataError = class extends Error {
13610
+ static {
13611
+ __name(this, "InvalidSessionMetadataError");
13612
+ }
13613
+ field;
13614
+ constructor(field, reason) {
13615
+ super(`Invalid session metadata: ${field} ${reason}`);
13616
+ this.name = "InvalidSessionMetadataError";
13617
+ this.field = field;
13618
+ }
13619
+ };
13620
+ var PermissionPolicyNotImplementedError = class extends Error {
13621
+ static {
13622
+ __name(this, "PermissionPolicyNotImplementedError");
13623
+ }
13624
+ policy;
13625
+ constructor(policy) {
13626
+ super(
13627
+ `Permission policy "${policy}" is declared in the contract but not yet implemented in this daemon build.`
13628
+ );
13629
+ this.name = "PermissionPolicyNotImplementedError";
13630
+ this.policy = policy;
13631
+ }
13632
+ };
13633
+ var CancelSentinelCollisionError = class extends Error {
13634
+ static {
13635
+ __name(this, "CancelSentinelCollisionError");
13636
+ }
13637
+ requestId;
13638
+ sentinel;
13639
+ constructor(requestId, sentinel) {
13640
+ super(
13641
+ `Permission ${requestId}: agent-declared optionId set contains the cancel-vote sentinel "${sentinel}", which would prevent the daemon from disambiguating cancel intent from a real vote.`
13642
+ );
13643
+ this.name = "CancelSentinelCollisionError";
13644
+ this.requestId = requestId;
13645
+ this.sentinel = sentinel;
13646
+ }
13647
+ };
13648
+ var PermissionForbiddenError = class extends Error {
13649
+ static {
13650
+ __name(this, "PermissionForbiddenError");
13651
+ }
13652
+ requestId;
13653
+ sessionId;
13654
+ reason;
13655
+ constructor(requestId, sessionId, reason) {
13656
+ super(
13657
+ `Permission ${requestId} on session ${sessionId}: vote rejected by policy (${reason}).`
13658
+ );
13659
+ this.name = "PermissionForbiddenError";
13660
+ this.requestId = requestId;
13661
+ this.sessionId = sessionId;
13662
+ this.reason = reason;
13663
+ }
13664
+ };
13665
+ var WorkspaceInitConflictError = class extends Error {
13666
+ static {
13667
+ __name(this, "WorkspaceInitConflictError");
13668
+ }
13669
+ path;
13670
+ existingSize;
13671
+ constructor(path9, existingSize) {
13672
+ super(
13673
+ `Workspace file ${path9} already exists (${existingSize} bytes); pass {force: true} to overwrite.`
13674
+ );
13675
+ this.name = "WorkspaceInitConflictError";
13676
+ this.path = path9;
13677
+ this.existingSize = existingSize;
13678
+ }
13679
+ };
13680
+ var WorkspaceInitPathEscapeError = class extends Error {
13681
+ static {
13682
+ __name(this, "WorkspaceInitPathEscapeError");
13683
+ }
13684
+ filename;
13685
+ boundWorkspace;
13686
+ constructor(filename, boundWorkspace) {
13687
+ super(
13688
+ `Configured workspace context filename ${JSON.stringify(filename)} resolves outside the bound workspace ${JSON.stringify(boundWorkspace)}. Refusing to write.`
13689
+ );
13690
+ this.name = "WorkspaceInitPathEscapeError";
13691
+ this.filename = filename;
13692
+ this.boundWorkspace = boundWorkspace;
13693
+ }
13694
+ };
13695
+ var WorkspaceInitSymlinkError = class extends Error {
13696
+ static {
13697
+ __name(this, "WorkspaceInitSymlinkError");
13698
+ }
13699
+ target;
13700
+ kind;
13701
+ constructor(target, kind, detail) {
13702
+ super(detail);
13703
+ this.name = "WorkspaceInitSymlinkError";
13704
+ this.target = target;
13705
+ this.kind = kind;
13706
+ }
13707
+ };
13708
+ var WorkspaceInitRaceError = class extends Error {
13709
+ static {
13710
+ __name(this, "WorkspaceInitRaceError");
13711
+ }
13712
+ target;
13713
+ kind;
13714
+ constructor(target, kind, detail) {
13715
+ super(detail);
13716
+ this.name = "WorkspaceInitRaceError";
13717
+ this.target = target;
13718
+ this.kind = kind;
13719
+ }
13720
+ };
13721
+ var McpServerNotFoundError = class extends Error {
13722
+ static {
13723
+ __name(this, "McpServerNotFoundError");
13724
+ }
13725
+ serverName;
13726
+ constructor(serverName) {
13727
+ super(`MCP server not configured: ${JSON.stringify(serverName)}`);
13728
+ this.name = "McpServerNotFoundError";
13729
+ this.serverName = serverName;
13730
+ }
13731
+ };
13732
+ var McpServerRestartFailedError = class extends Error {
13733
+ static {
13734
+ __name(this, "McpServerRestartFailedError");
13735
+ }
13736
+ serverName;
13737
+ mcpStatus;
13738
+ constructor(serverName, mcpStatus) {
13739
+ super(
13740
+ `MCP server ${JSON.stringify(serverName)} did not reach a connected state after restart (status: ${mcpStatus}).`
13741
+ );
13742
+ this.name = "McpServerRestartFailedError";
13743
+ this.serverName = serverName;
13744
+ this.mcpStatus = mcpStatus;
13745
+ }
13746
+ };
13747
+ var SessionBusyError = class extends Error {
13748
+ static {
13749
+ __name(this, "SessionBusyError");
13750
+ }
13751
+ sessionId;
13752
+ constructor(sessionId, message) {
13753
+ super(message ?? `Session ${sessionId} is busy (prompt running)`);
13754
+ this.name = "SessionBusyError";
13755
+ this.sessionId = sessionId;
13756
+ }
13757
+ };
13758
+ var InvalidRewindTargetError = class extends Error {
13759
+ static {
13760
+ __name(this, "InvalidRewindTargetError");
13761
+ }
13762
+ sessionId;
13763
+ constructor(sessionId, message) {
13764
+ super(
13765
+ message ?? `Cannot rewind to the requested turn (compressed or does not exist)`
13766
+ );
13767
+ this.name = "InvalidRewindTargetError";
13768
+ this.sessionId = sessionId;
13769
+ }
13770
+ };
13771
+ var BranchWhilePromptActiveError = class extends Error {
13772
+ static {
13773
+ __name(this, "BranchWhilePromptActiveError");
13774
+ }
13775
+ sessionId;
13776
+ constructor(sessionId) {
13777
+ super(`Cannot branch session ${sessionId}: a prompt is currently active`);
13778
+ this.name = "BranchWhilePromptActiveError";
13779
+ this.sessionId = sessionId;
13780
+ }
13781
+ };
13782
+
13402
13783
  // packages/acp-bridge/src/status.ts
13403
13784
  init_esbuild_shims();
13404
13785
  var STATUS_SCHEMA_VERSION = 1;
@@ -13411,10 +13792,17 @@ var SERVE_ERROR_KINDS = [
13411
13792
  "missing_file",
13412
13793
  "parse_error",
13413
13794
  "stat_failed",
13414
- // Issue #4175 PR 14: budget refusal under `--mcp-budget-mode=enforce`.
13795
+ // Budget refusal under `--mcp-budget-mode=enforce`.
13415
13796
  // Surfaced on per-server `mcp_server` cells (refused at discovery)
13416
13797
  // and on the workspace-level `mcp_budget` cell (any refusal this pass).
13417
- "budget_exhausted"
13798
+ "budget_exhausted",
13799
+ // Runtime MCP mutation routes
13800
+ "mcp_budget_would_exceed",
13801
+ "mcp_server_spawn_failed",
13802
+ "invalid_config",
13803
+ // Prompt deadline + writer idle timeout
13804
+ "prompt_deadline_exceeded",
13805
+ "writer_idle_timeout"
13418
13806
  ];
13419
13807
  var BridgeTimeoutError = class extends Error {
13420
13808
  static {
@@ -13423,7 +13811,7 @@ var BridgeTimeoutError = class extends Error {
13423
13811
  label;
13424
13812
  timeoutMs;
13425
13813
  constructor(label, timeoutMs) {
13426
- super(`HttpAcpBridge ${label} timed out after ${timeoutMs}ms`);
13814
+ super(`AcpSessionBridge ${label} timed out after ${timeoutMs}ms`);
13427
13815
  this.name = "BridgeTimeoutError";
13428
13816
  this.label = label;
13429
13817
  this.timeoutMs = timeoutMs;
@@ -13453,18 +13841,123 @@ var MissingCliEntryError = class extends Error {
13453
13841
  };
13454
13842
  var SERVE_STATUS_EXT_METHODS = {
13455
13843
  workspaceMcp: "qwen/status/workspace/mcp",
13844
+ workspaceMcpTools: "qwen/status/workspace/mcp/tools",
13456
13845
  workspaceSkills: "qwen/status/workspace/skills",
13846
+ workspaceTools: "qwen/status/workspace/tools",
13457
13847
  workspaceProviders: "qwen/status/workspace/providers",
13458
13848
  workspaceMemory: "qwen/status/workspace/memory",
13459
13849
  workspaceAgents: "qwen/status/workspace/agents",
13460
13850
  workspacePreflight: "qwen/status/workspace/preflight",
13461
13851
  sessionContext: "qwen/status/session/context",
13462
- sessionSupportedCommands: "qwen/status/session/supported_commands"
13852
+ sessionContextUsage: "qwen/status/session/context_usage",
13853
+ sessionSupportedCommands: "qwen/status/session/supported_commands",
13854
+ sessionTasks: "qwen/status/session/tasks",
13855
+ sessionStats: "qwen/status/session/stats",
13856
+ sessionRewindSnapshots: "qwen/status/session/rewind_snapshots",
13857
+ workspaceHooks: "qwen/status/workspace/hooks",
13858
+ sessionHooks: "qwen/status/session/hooks",
13859
+ workspaceExtensions: "qwen/status/workspace/extensions"
13463
13860
  };
13464
13861
  var SERVE_CONTROL_EXT_METHODS = {
13862
+ sessionClose: "qwen/control/session/close",
13465
13863
  sessionApprovalMode: "qwen/control/session/approval_mode",
13466
- workspaceMcpRestart: "qwen/control/workspace/mcp/restart"
13864
+ sessionBranch: "qwen/control/session/branch",
13865
+ sessionRecap: "qwen/control/session/recap",
13866
+ sessionBtw: "qwen/control/session/btw",
13867
+ sessionShellHistory: "qwen/control/session/shell_history",
13868
+ sessionLanguage: "qwen/control/session/language",
13869
+ sessionRewind: "qwen/control/session/rewind",
13870
+ workspaceMcpRestart: "qwen/control/workspace/mcp/restart",
13871
+ workspaceMcpManage: "qwen/control/workspace/mcp/manage",
13872
+ workspaceAgentGenerate: "qwen/control/workspace/agents/generate",
13873
+ // Runtime MCP server mutation ext-methods
13874
+ sessionTaskCancel: "qwen/control/session/task/cancel",
13875
+ sessionGoalClear: "qwen/control/session/goal/clear",
13876
+ workspaceMcpRuntimeAdd: "qwen/control/workspace/mcp/runtime-add",
13877
+ workspaceMcpRuntimeRemove: "qwen/control/workspace/mcp/runtime-remove",
13878
+ workspaceReload: "qwen/control/workspace/reload"
13879
+ };
13880
+ var IDLE_HOOK_EVENTS = {
13881
+ PreToolUse: { description: "Before tool execution", matcherKind: "toolName" },
13882
+ PostToolUse: { description: "After tool execution", matcherKind: "toolName" },
13883
+ PostToolUseFailure: {
13884
+ description: "After tool execution fails",
13885
+ matcherKind: "toolName"
13886
+ },
13887
+ PostToolBatch: { description: "After a batch of tool calls resolves" },
13888
+ Notification: {
13889
+ description: "When notifications are sent",
13890
+ matcherKind: "notificationType"
13891
+ },
13892
+ UserPromptSubmit: { description: "When the user submits a prompt" },
13893
+ UserPromptExpansion: {
13894
+ description: "When a slash command expands into a prompt",
13895
+ matcherKind: "commandName"
13896
+ },
13897
+ SessionStart: {
13898
+ description: "When a new session is started",
13899
+ matcherKind: "sessionTrigger"
13900
+ },
13901
+ Stop: { description: "Right before Qwen Code concludes its response" },
13902
+ SubagentStart: {
13903
+ description: "When a subagent is started",
13904
+ matcherKind: "agentType"
13905
+ },
13906
+ SubagentStop: {
13907
+ description: "Right before a subagent concludes its response",
13908
+ matcherKind: "agentType"
13909
+ },
13910
+ PreCompact: {
13911
+ description: "Before conversation compaction",
13912
+ matcherKind: "trigger"
13913
+ },
13914
+ PostCompact: {
13915
+ description: "After conversation compaction",
13916
+ matcherKind: "trigger"
13917
+ },
13918
+ SessionEnd: {
13919
+ description: "When a session is ending",
13920
+ matcherKind: "sessionTrigger"
13921
+ },
13922
+ PermissionRequest: {
13923
+ description: "When a permission dialog is displayed",
13924
+ matcherKind: "toolName"
13925
+ },
13926
+ PermissionDenied: {
13927
+ description: "When a tool call is denied",
13928
+ matcherKind: "toolName"
13929
+ },
13930
+ StopFailure: {
13931
+ description: "When the turn ends due to an API error",
13932
+ matcherKind: "error"
13933
+ },
13934
+ TodoCreated: { description: "When a new todo item is created" },
13935
+ TodoCompleted: { description: "When a todo item is marked as completed" },
13936
+ InstructionsLoaded: {
13937
+ description: "When an instruction or context file is loaded",
13938
+ matcherKind: "filePath"
13939
+ }
13467
13940
  };
13941
+ function createIdleWorkspaceExtensionsStatus(workspaceCwd) {
13942
+ return {
13943
+ v: STATUS_SCHEMA_VERSION,
13944
+ workspaceCwd,
13945
+ initialized: false,
13946
+ extensions: []
13947
+ };
13948
+ }
13949
+ __name(createIdleWorkspaceExtensionsStatus, "createIdleWorkspaceExtensionsStatus");
13950
+ function createIdleWorkspaceHooksStatus(workspaceCwd) {
13951
+ return {
13952
+ v: STATUS_SCHEMA_VERSION,
13953
+ workspaceCwd,
13954
+ initialized: false,
13955
+ disabled: false,
13956
+ hooks: [],
13957
+ events: IDLE_HOOK_EVENTS
13958
+ };
13959
+ }
13960
+ __name(createIdleWorkspaceHooksStatus, "createIdleWorkspaceHooksStatus");
13468
13961
  function createIdleWorkspaceMemoryStatus(workspaceCwd) {
13469
13962
  return {
13470
13963
  v: STATUS_SCHEMA_VERSION,
@@ -13585,7 +14078,7 @@ init_esbuild_shims();
13585
14078
  // packages/cli/src/utils/languageUtils.ts
13586
14079
  init_esbuild_shims();
13587
14080
  import * as fs from "node:fs";
13588
- import * as path from "node:path";
14081
+ import * as path2 from "node:path";
13589
14082
  var LLM_OUTPUT_LANGUAGE_RULE_FILENAME = "output-language.md";
13590
14083
  var LLM_OUTPUT_LANGUAGE_MARKER_PREFIX = "qwen-code:llm-output-language:";
13591
14084
  var OUTPUT_LANGUAGE_AUTO = "auto";
@@ -13611,7 +14104,7 @@ function resolveOutputLanguage(value) {
13611
14104
  }
13612
14105
  __name(resolveOutputLanguage, "resolveOutputLanguage");
13613
14106
  function getOutputLanguageFilePath() {
13614
- return path.join(
14107
+ return path2.join(
13615
14108
  Storage.getGlobalQwenDir(),
13616
14109
  LLM_OUTPUT_LANGUAGE_RULE_FILENAME
13617
14110
  );
@@ -13674,19 +14167,27 @@ function readOutputLanguageFromFile() {
13674
14167
  }
13675
14168
  }
13676
14169
  __name(readOutputLanguageFromFile, "readOutputLanguageFromFile");
13677
- function writeOutputLanguageFile(language) {
13678
- const filePath = getOutputLanguageFilePath();
14170
+ function writeOutputLanguageFile(language, targetPath) {
14171
+ const filePath = targetPath ?? getOutputLanguageFilePath();
13679
14172
  const content = generateOutputLanguageFileContent(language);
13680
- const dir = path.dirname(filePath);
14173
+ const dir = path2.dirname(filePath);
13681
14174
  fs.mkdirSync(dir, { recursive: true });
13682
14175
  fs.writeFileSync(filePath, content, "utf-8");
13683
14176
  }
13684
14177
  __name(writeOutputLanguageFile, "writeOutputLanguageFile");
13685
- function updateOutputLanguageFile(settingValue) {
14178
+ function updateOutputLanguageFile(settingValue, targetPath) {
13686
14179
  const resolved = resolveOutputLanguage(settingValue);
13687
- writeOutputLanguageFile(resolved);
14180
+ writeOutputLanguageFile(resolved, targetPath);
13688
14181
  }
13689
14182
  __name(updateOutputLanguageFile, "updateOutputLanguageFile");
14183
+ function writeOutputLanguageAndRegisterPath(settingValue, config) {
14184
+ const targetPath = config?.getOutputLanguageFilePath();
14185
+ updateOutputLanguageFile(settingValue, targetPath);
14186
+ if (!targetPath) {
14187
+ config?.setOutputLanguageFilePath(getOutputLanguageFilePath());
14188
+ }
14189
+ }
14190
+ __name(writeOutputLanguageAndRegisterPath, "writeOutputLanguageAndRegisterPath");
13690
14191
  function initializeLlmOutputLanguage(outputLanguage) {
13691
14192
  const currentFileLanguage = readOutputLanguageFromFile();
13692
14193
  if (currentFileLanguage) {
@@ -13701,7 +14202,7 @@ __name(initializeLlmOutputLanguage, "initializeLlmOutputLanguage");
13701
14202
  init_esbuild_shims();
13702
14203
  var dotenv = __toESM(require_main(), 1);
13703
14204
  import * as fs6 from "node:fs";
13704
- import * as path3 from "node:path";
14205
+ import * as path4 from "node:path";
13705
14206
  import { homedir, platform } from "node:os";
13706
14207
  import process2 from "node:process";
13707
14208
  var import_strip_json_comments2 = __toESM(require_strip_json_comments(), 1);
@@ -13894,6 +14395,89 @@ function resolveColor(colorValue) {
13894
14395
  return void 0;
13895
14396
  }
13896
14397
  __name(resolveColor, "resolveColor");
14398
+ var INK_NAME_TO_HEX = {
14399
+ black: "#000000",
14400
+ red: "#ff0000",
14401
+ green: "#00ff00",
14402
+ yellow: "#ffff00",
14403
+ blue: "#0000ff",
14404
+ cyan: "#00ffff",
14405
+ magenta: "#ff00ff",
14406
+ white: "#ffffff",
14407
+ gray: "#808080",
14408
+ grey: "#808080",
14409
+ blackbright: "#808080",
14410
+ redbright: "#ff8080",
14411
+ greenbright: "#80ff80",
14412
+ yellowbright: "#ffff80",
14413
+ bluebright: "#8080ff",
14414
+ cyanbright: "#80ffff",
14415
+ magentabright: "#ff80ff",
14416
+ whitebright: "#ffffff"
14417
+ };
14418
+ function toHex(color) {
14419
+ const resolved = (resolveColor(color) ?? color).toLowerCase();
14420
+ if (resolved.startsWith("#")) {
14421
+ if (/^#[0-9a-f]{3}$/.test(resolved)) {
14422
+ return `#${resolved.slice(1).split("").map((c) => c + c).join("")}`;
14423
+ }
14424
+ if (/^#[0-9a-f]{6}$/.test(resolved)) {
14425
+ return resolved;
14426
+ }
14427
+ return void 0;
14428
+ }
14429
+ return INK_NAME_TO_HEX[resolved];
14430
+ }
14431
+ __name(toHex, "toHex");
14432
+ function interpolateColor(color1, color2, factor) {
14433
+ if (factor <= 0) {
14434
+ return color1;
14435
+ }
14436
+ if (factor >= 1) {
14437
+ return color2;
14438
+ }
14439
+ const h1 = toHex(color1);
14440
+ const h2 = toHex(color2);
14441
+ if (!h1 || !h2) {
14442
+ return "";
14443
+ }
14444
+ const r1 = parseInt(h1.slice(1, 3), 16);
14445
+ const g1 = parseInt(h1.slice(3, 5), 16);
14446
+ const b1 = parseInt(h1.slice(5, 7), 16);
14447
+ const r2 = parseInt(h2.slice(1, 3), 16);
14448
+ const g2 = parseInt(h2.slice(3, 5), 16);
14449
+ const b2 = parseInt(h2.slice(5, 7), 16);
14450
+ const lerp = /* @__PURE__ */ __name((a, b) => Math.round(a + (b - a) * factor), "lerp");
14451
+ const toByte = /* @__PURE__ */ __name((n) => Math.max(0, Math.min(255, n)).toString(16).padStart(2, "0"), "toByte");
14452
+ return `#${toByte(lerp(r1, r2))}${toByte(lerp(g1, g2))}${toByte(lerp(b1, b2))}`;
14453
+ }
14454
+ __name(interpolateColor, "interpolateColor");
14455
+ function subtleBandColor(bgColor, factor = 0.06) {
14456
+ const hex = toHex(bgColor);
14457
+ if (!hex) {
14458
+ return "";
14459
+ }
14460
+ const r = parseInt(hex.slice(1, 3), 16);
14461
+ const g = parseInt(hex.slice(3, 5), 16);
14462
+ const b = parseInt(hex.slice(5, 7), 16);
14463
+ const isDark = (r * 299 + g * 587 + b * 114) / 1e3 < 128;
14464
+ const target = isDark ? "#ffffff" : "#000000";
14465
+ return interpolateColor(hex, target, factor);
14466
+ }
14467
+ __name(subtleBandColor, "subtleBandColor");
14468
+ var _supportsTrueColor;
14469
+ function supportsTrueColor() {
14470
+ if (_supportsTrueColor !== void 0) return _supportsTrueColor;
14471
+ const colorterm = process.env["COLORTERM"];
14472
+ if (colorterm === "truecolor" || colorterm === "24bit" || colorterm === "kmscon") {
14473
+ return _supportsTrueColor = true;
14474
+ }
14475
+ if (process.stdout.getColorDepth && process.stdout.getColorDepth() >= 24) {
14476
+ return _supportsTrueColor = true;
14477
+ }
14478
+ return _supportsTrueColor = false;
14479
+ }
14480
+ __name(supportsTrueColor, "supportsTrueColor");
13897
14481
 
13898
14482
  // packages/cli/src/ui/themes/theme.ts
13899
14483
  var lightTheme = {
@@ -14512,14 +15096,14 @@ var DefaultDark = new Theme(
14512
15096
  // packages/cli/src/config/trustedFolders.ts
14513
15097
  init_esbuild_shims();
14514
15098
  import * as fs2 from "node:fs";
14515
- import * as path2 from "node:path";
15099
+ import * as path3 from "node:path";
14516
15100
  var import_strip_json_comments = __toESM(require_strip_json_comments(), 1);
14517
15101
  var TRUSTED_FOLDERS_FILENAME = "trustedFolders.json";
14518
15102
  function getTrustedFoldersPath() {
14519
15103
  if (process.env["QWEN_CODE_TRUSTED_FOLDERS_PATH"]) {
14520
15104
  return process.env["QWEN_CODE_TRUSTED_FOLDERS_PATH"];
14521
15105
  }
14522
- return path2.join(Storage.getGlobalQwenDir(), TRUSTED_FOLDERS_FILENAME);
15106
+ return path3.join(Storage.getGlobalQwenDir(), TRUSTED_FOLDERS_FILENAME);
14523
15107
  }
14524
15108
  __name(getTrustedFoldersPath, "getTrustedFoldersPath");
14525
15109
  var LoadedTrustedFolders = class {
@@ -14531,8 +15115,8 @@ var LoadedTrustedFolders = class {
14531
15115
  __name(this, "LoadedTrustedFolders");
14532
15116
  }
14533
15117
  get rules() {
14534
- return Object.entries(this.user.config).map(([path8, trustLevel]) => ({
14535
- path: path8,
15118
+ return Object.entries(this.user.config).map(([path9, trustLevel]) => ({
15119
+ path: path9,
14536
15120
  trustLevel
14537
15121
  }));
14538
15122
  }
@@ -14552,7 +15136,7 @@ var LoadedTrustedFolders = class {
14552
15136
  trustedPaths.push(rule.path);
14553
15137
  break;
14554
15138
  case "TRUST_PARENT" /* TRUST_PARENT */:
14555
- trustedPaths.push(path2.dirname(rule.path));
15139
+ trustedPaths.push(path3.dirname(rule.path));
14556
15140
  break;
14557
15141
  case "DO_NOT_TRUST" /* DO_NOT_TRUST */:
14558
15142
  untrustedPaths.push(rule.path);
@@ -14567,14 +15151,14 @@ var LoadedTrustedFolders = class {
14567
15151
  }
14568
15152
  }
14569
15153
  for (const untrustedPath of untrustedPaths) {
14570
- if (path2.normalize(location) === path2.normalize(untrustedPath)) {
15154
+ if (path3.normalize(location) === path3.normalize(untrustedPath)) {
14571
15155
  return false;
14572
15156
  }
14573
15157
  }
14574
15158
  return void 0;
14575
15159
  }
14576
- setValue(path8, trustLevel) {
14577
- this.user.config[path8] = trustLevel;
15160
+ setValue(path9, trustLevel) {
15161
+ this.user.config[path9] = trustLevel;
14578
15162
  saveTrustedFolders(this.user);
14579
15163
  }
14580
15164
  };
@@ -14614,14 +15198,20 @@ function loadTrustedFolders() {
14614
15198
  __name(loadTrustedFolders, "loadTrustedFolders");
14615
15199
  function saveTrustedFolders(trustedFoldersFile) {
14616
15200
  try {
14617
- const dirPath = path2.dirname(trustedFoldersFile.path);
15201
+ const dirPath = path3.dirname(trustedFoldersFile.path);
14618
15202
  if (!fs2.existsSync(dirPath)) {
14619
15203
  fs2.mkdirSync(dirPath, { recursive: true });
14620
15204
  }
14621
- fs2.writeFileSync(
15205
+ atomicWriteFileSync(
14622
15206
  trustedFoldersFile.path,
14623
15207
  JSON.stringify(trustedFoldersFile.config, null, 2),
14624
- { encoding: "utf-8", mode: 384 }
15208
+ // noFollow: refuse to follow any pre-placed symlink at the
15209
+ // config path — a redirected write could either leak the
15210
+ // trusted-folder list to an attacker target or leave the user's
15211
+ // real config silently stale. Matches the credential write
15212
+ // sites' security posture (sharedTokenManager, oauth-token-storage,
15213
+ // file-token-storage all use noFollow:true).
15214
+ { encoding: "utf-8", mode: 384, forceMode: true, noFollow: true }
14625
15215
  );
14626
15216
  } catch (error) {
14627
15217
  writeStderrLine("Error saving trusted folders file.");
@@ -14902,6 +15492,18 @@ var SETTINGS_SCHEMA = {
14902
15492
  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
15493
  showInDialog: true
14904
15494
  },
15495
+ cleanupPeriodDays: {
15496
+ type: "number",
15497
+ label: "Cleanup Period (days)",
15498
+ category: "General",
15499
+ // LoadedSettings._merged is cached without verified setValue→recompute
15500
+ // paths in all UI flows. Mark restart-required so users aren't
15501
+ // surprised when a mid-session edit doesn't take effect immediately.
15502
+ requiresRestart: true,
15503
+ default: 30,
15504
+ 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.",
15505
+ showInDialog: true
15506
+ },
14905
15507
  gitCoAuthor: {
14906
15508
  type: "object",
14907
15509
  label: "Attribution",
@@ -14942,26 +15544,6 @@ var SETTINGS_SCHEMA = {
14942
15544
  }
14943
15545
  }
14944
15546
  },
14945
- checkpointing: {
14946
- type: "object",
14947
- label: "Checkpointing",
14948
- category: "General",
14949
- requiresRestart: true,
14950
- default: {},
14951
- description: "Session checkpointing settings.",
14952
- showInDialog: false,
14953
- properties: {
14954
- enabled: {
14955
- type: "boolean",
14956
- label: "Enable Checkpointing",
14957
- category: "General",
14958
- requiresRestart: true,
14959
- default: false,
14960
- description: "Enable session checkpointing for recovery",
14961
- showInDialog: false
14962
- }
14963
- }
14964
- },
14965
15547
  debugKeystrokeLogging: {
14966
15548
  type: "boolean",
14967
15549
  label: "Debug Keystroke Logging",
@@ -15008,6 +15590,18 @@ var SETTINGS_SCHEMA = {
15008
15590
  description: "Play terminal bell sound when response completes or needs approval.",
15009
15591
  showInDialog: true
15010
15592
  },
15593
+ preventSystemSleep: {
15594
+ type: "boolean",
15595
+ label: "Prevent System Sleep While Running",
15596
+ category: "General",
15597
+ // Read once at startup via Config.preventSystemSleep (a readonly field
15598
+ // captured in loadCliConfig), so a runtime toggle only takes effect
15599
+ // after restart.
15600
+ requiresRestart: true,
15601
+ default: true,
15602
+ description: "Prevent the system from sleeping while Qwen Code is streaming a model response or executing tools. Idle prompt time and permission prompts do not inhibit sleep.",
15603
+ showInDialog: true
15604
+ },
15011
15605
  chatRecording: {
15012
15606
  type: "boolean",
15013
15607
  label: "Chat Recording",
@@ -15118,7 +15712,7 @@ var SETTINGS_SCHEMA = {
15118
15712
  category: "UI",
15119
15713
  requiresRestart: false,
15120
15714
  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.',
15715
+ 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
15716
  showInDialog: false
15123
15717
  },
15124
15718
  customThemes: {
@@ -15298,6 +15892,24 @@ var SETTINGS_SCHEMA = {
15298
15892
  description: "Hide tool output and thinking for a cleaner view (toggle with Ctrl+O).",
15299
15893
  showInDialog: true
15300
15894
  },
15895
+ compactInline: {
15896
+ type: "boolean",
15897
+ label: "Compact Inline",
15898
+ category: "UI",
15899
+ requiresRestart: true,
15900
+ default: false,
15901
+ description: "Compact tool display within each group instead of merging across groups. Requires compactMode to be enabled.",
15902
+ showInDialog: true
15903
+ },
15904
+ useTerminalBuffer: {
15905
+ type: "boolean",
15906
+ label: "Virtualized History (reduces flicker on long sessions)",
15907
+ category: "UI",
15908
+ requiresRestart: false,
15909
+ default: false,
15910
+ 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.",
15911
+ showInDialog: true
15912
+ },
15301
15913
  shellOutputMaxLines: {
15302
15914
  type: "number",
15303
15915
  label: "Shell Output Max Lines",
@@ -15484,6 +16096,26 @@ var SETTINGS_SCHEMA = {
15484
16096
  additionalProperties: true
15485
16097
  }
15486
16098
  },
16099
+ outboundCorrelation: {
16100
+ type: "object",
16101
+ label: "Outbound Correlation",
16102
+ category: "Advanced",
16103
+ requiresRestart: true,
16104
+ default: void 0,
16105
+ description: "SECURITY-RELEVANT. Controls what client-side correlation data qwen-code writes into outbound LLM API requests (DashScope, OpenAI, Anthropic, etc.) \u2014 separate from `telemetry.*` which governs data flow into the operator's OWN OTLP collector. All values default to off. Opt in only when the LLM provider also reports into your OTel collector for cross-process trace stitching (e.g. ARMS Tracing + DashScope).",
16106
+ showInDialog: false,
16107
+ jsonSchemaOverride: {
16108
+ type: "object",
16109
+ properties: {
16110
+ propagateTraceContext: {
16111
+ description: "Requires `telemetry.enabled: true`. Inject W3C `traceparent` on outbound `fetch` requests (LLM SDK calls, MCP StreamableHTTP, WebFetch, ...) AND as a `TRACEPARENT` environment variable in shell child processes (Bash tool, hooks, monitor). When enabled, any existing `TRACEPARENT` in the parent environment is overwritten with qwen-code's own trace context. Default: false \u2014 trace context stays internal to the operator's OTLP collector. Set true when you want cross-process trace stitching with an OTel-aware LLM provider (e.g. ARMS+DashScope) or need shell scripts / CLI tools to participate in distributed tracing.",
16112
+ type: "boolean",
16113
+ default: false
16114
+ }
16115
+ },
16116
+ additionalProperties: false
16117
+ }
16118
+ },
15487
16119
  fastModel: {
15488
16120
  type: "string",
15489
16121
  label: "Fast Model",
@@ -15520,6 +16152,24 @@ var SETTINGS_SCHEMA = {
15520
16152
  description: "Maximum number of user/model/tool turns to keep in a session. -1 means unlimited.",
15521
16153
  showInDialog: false
15522
16154
  },
16155
+ maxWallTimeSeconds: {
16156
+ type: "number",
16157
+ label: "Max Wall-Clock Time (seconds)",
16158
+ category: "Model",
16159
+ requiresRestart: false,
16160
+ default: -1,
16161
+ description: "Run-level wall-clock budget for headless / unattended runs, in seconds. -1 means unlimited; otherwise must be in [1, ~2,147,483] (sub-second values and values above ~24 days are rejected as typos). Overridable per-invocation via --max-wall-time (which also accepts duration suffixes like 5m, 1.5h).",
16162
+ showInDialog: false
16163
+ },
16164
+ maxToolCalls: {
16165
+ type: "number",
16166
+ label: "Max Tool Calls",
16167
+ category: "Model",
16168
+ requiresRestart: false,
16169
+ default: -1,
16170
+ description: 'Cumulative tool-call budget for a run (counts every executed tool, success or failure; structured_output under --json-schema is exempt). -1 means unlimited; 0 means "no tool calls allowed" (first call aborts). Capped at 1,000,000 to catch typos. Overridable via --max-tool-calls.',
16171
+ showInDialog: false
16172
+ },
15523
16173
  chatCompression: {
15524
16174
  type: "object",
15525
16175
  label: "Chat Compression",
@@ -15553,7 +16203,7 @@ var SETTINGS_SCHEMA = {
15553
16203
  category: "Model",
15554
16204
  requiresRestart: false,
15555
16205
  default: true,
15556
- description: "Disable all loop detection checks (streaming and LLM).",
16206
+ description: "Skip streaming loop detection. Defaults to true to avoid false-positive interruptions; set to false to re-enable as an unattended-run guardrail.",
15557
16207
  showInDialog: false
15558
16208
  },
15559
16209
  skipStartupContext: {
@@ -15627,8 +16277,8 @@ var SETTINGS_SCHEMA = {
15627
16277
  label: "Split Tool Result Media",
15628
16278
  category: "Generation Configuration",
15629
16279
  requiresRestart: false,
15630
- default: false,
15631
- description: 'When true, media (images / audio / video / files) returned by MCP tool calls is split into a follow-up user message instead of being embedded in the tool message. Required for strict OpenAI-compatible servers (e.g., LM Studio) that reject non-text content on `role: "tool"` messages with HTTP 400 "Invalid \'messages\' in payload". Default false preserves the prior behavior for permissive providers. See QwenLM/qwen-code#3616.',
16280
+ default: true,
16281
+ description: 'When true, media (images / audio / video / files) returned by tool calls \u2014 including the built-in read_file and MCP tools \u2014 is split into a follow-up user message instead of being embedded in the `role: "tool"` message. The OpenAI Chat Completions spec only permits text on tool messages, so strict OpenAI-compatible servers (e.g., doubao / new-api / LM Studio) silently drop or reject embedded media and the model never sees an image read via read_file (QwenLM/qwen-code#4876, #3616). Default true is spec-compliant and safe for permissive providers; set false only to restore the legacy embed-in-tool-message behavior.',
15632
16282
  parentKey: "generationConfig",
15633
16283
  showInDialog: false
15634
16284
  },
@@ -15816,7 +16466,7 @@ var SETTINGS_SCHEMA = {
15816
16466
  label: "Enable Managed Auto-Dream",
15817
16467
  category: "Memory",
15818
16468
  requiresRestart: false,
15819
- default: false,
16469
+ default: true,
15820
16470
  description: "Enable automatic consolidation (dream) of collected memories.",
15821
16471
  showInDialog: false
15822
16472
  },
@@ -15825,7 +16475,7 @@ var SETTINGS_SCHEMA = {
15825
16475
  label: "Enable Auto Skill",
15826
16476
  category: "Memory",
15827
16477
  requiresRestart: false,
15828
- default: false,
16478
+ default: true,
15829
16479
  description: "Enable background review for reusable project skills after tool-heavy sessions.",
15830
16480
  showInDialog: false
15831
16481
  }
@@ -15852,6 +16502,27 @@ var SETTINGS_SCHEMA = {
15852
16502
  }
15853
16503
  }
15854
16504
  },
16505
+ skills: {
16506
+ type: "object",
16507
+ label: "Skills",
16508
+ category: "Advanced",
16509
+ requiresRestart: false,
16510
+ default: {},
16511
+ description: "Configuration for skills (SKILL.md-based capabilities) exposed to the model.",
16512
+ showInDialog: false,
16513
+ properties: {
16514
+ disabled: {
16515
+ type: "array",
16516
+ label: "Disabled Skills",
16517
+ category: "Advanced",
16518
+ requiresRestart: false,
16519
+ default: void 0,
16520
+ description: "Skill names to hide. Matched case-insensitively against the skill name. Hidden skills do not appear in <available_skills> or as /<name> slash commands. UNION-merged across systemDefaults/user/workspace/system scopes \u2014 workspace cannot remove entries defined in higher scopes.",
16521
+ showInDialog: false,
16522
+ mergeStrategy: "union" /* UNION */
16523
+ }
16524
+ }
16525
+ },
15855
16526
  permissions: {
15856
16527
  type: "object",
15857
16528
  label: "Permissions",
@@ -15900,6 +16571,66 @@ var SETTINGS_SCHEMA = {
15900
16571
  description: "Settings consumed by the AUTO approval mode classifier.",
15901
16572
  showInDialog: false,
15902
16573
  properties: {
16574
+ classifier: {
16575
+ type: "object",
16576
+ label: "Auto Mode Classifier",
16577
+ category: "Tools",
16578
+ requiresRestart: true,
16579
+ default: {},
16580
+ description: "Runtime controls for the AUTO approval mode classifier.",
16581
+ showInDialog: false,
16582
+ properties: {
16583
+ timeouts: {
16584
+ type: "object",
16585
+ label: "Auto Mode Classifier Timeouts",
16586
+ category: "Tools",
16587
+ requiresRestart: true,
16588
+ default: {},
16589
+ description: "Timeouts for the two AUTO classifier stages, in milliseconds.",
16590
+ showInDialog: false,
16591
+ properties: {
16592
+ stage1Ms: {
16593
+ type: "number",
16594
+ label: "Auto Mode Stage 1 Timeout",
16595
+ category: "Tools",
16596
+ requiresRestart: true,
16597
+ default: void 0,
16598
+ description: "Timeout in milliseconds for the fast stage-1 AUTO classifier.",
16599
+ showInDialog: false
16600
+ },
16601
+ stage2Ms: {
16602
+ type: "number",
16603
+ label: "Auto Mode Stage 2 Timeout",
16604
+ category: "Tools",
16605
+ requiresRestart: true,
16606
+ default: void 0,
16607
+ description: "Timeout in milliseconds for the stage-2 AUTO classifier review.",
16608
+ showInDialog: false
16609
+ }
16610
+ }
16611
+ },
16612
+ thinking: {
16613
+ type: "object",
16614
+ label: "Auto Mode Classifier Thinking",
16615
+ category: "Tools",
16616
+ requiresRestart: true,
16617
+ default: {},
16618
+ description: "Provider/API-level thinking controls for the AUTO classifier.",
16619
+ showInDialog: false,
16620
+ properties: {
16621
+ stage2Enabled: {
16622
+ type: "boolean",
16623
+ label: "Auto Mode Stage 2 Thinking",
16624
+ category: "Tools",
16625
+ requiresRestart: true,
16626
+ default: false,
16627
+ description: "Whether stage 2 may use provider/API-level thinking. Stage 1 always keeps thinking disabled.",
16628
+ showInDialog: false
16629
+ }
16630
+ }
16631
+ }
16632
+ }
16633
+ },
15903
16634
  hints: {
15904
16635
  type: "object",
15905
16636
  label: "Classifier Hints",
@@ -15919,13 +16650,33 @@ var SETTINGS_SCHEMA = {
15919
16650
  showInDialog: false,
15920
16651
  mergeStrategy: "union" /* UNION */
15921
16652
  },
16653
+ softDeny: {
16654
+ type: "array",
16655
+ label: "Auto Mode Soft-Deny Hints",
16656
+ category: "Tools",
16657
+ requiresRestart: true,
16658
+ default: void 0,
16659
+ description: "Natural-language descriptions of destructive / irreversible actions AUTO mode should block unless the user explicitly authorised that exact action and scope.",
16660
+ showInDialog: false,
16661
+ mergeStrategy: "union" /* UNION */
16662
+ },
16663
+ hardDeny: {
16664
+ type: "array",
16665
+ label: "Auto Mode Hard-Deny Hints",
16666
+ category: "Tools",
16667
+ requiresRestart: true,
16668
+ default: void 0,
16669
+ description: "Natural-language descriptions of security-boundary actions the AUTO classifier must block even when an autoMode allow hint or recent user request would normally authorise them. Does not override permissions.allow; use permissions.deny for deterministic hard permission rules.",
16670
+ showInDialog: false,
16671
+ mergeStrategy: "union" /* UNION */
16672
+ },
15922
16673
  deny: {
15923
16674
  type: "array",
15924
- label: "Auto Mode Deny Hints",
16675
+ label: "Auto Mode Deny Hints (legacy)",
15925
16676
  category: "Tools",
15926
16677
  requiresRestart: true,
15927
16678
  default: void 0,
15928
- description: "Natural-language descriptions of actions AUTO mode should block.",
16679
+ description: "Deprecated alias for `softDeny`. Entries here are merged into the SOFT BLOCK user section so existing settings keep working; new configurations should use `softDeny` or `hardDeny` instead.",
15929
16680
  showInDialog: false,
15930
16681
  mergeStrategy: "union" /* UNION */
15931
16682
  }
@@ -16080,7 +16831,7 @@ var SETTINGS_SCHEMA = {
16080
16831
  showInDialog: true,
16081
16832
  options: [
16082
16833
  { value: "plan" /* PLAN */, label: "Plan" },
16083
- { value: "default" /* DEFAULT */, label: "Default" },
16834
+ { value: "default" /* DEFAULT */, label: "Ask permissions" },
16084
16835
  { value: "auto-edit" /* AUTO_EDIT */, label: "Auto Edit" },
16085
16836
  { value: "auto" /* AUTO */, label: "Auto" },
16086
16837
  { value: "yolo" /* YOLO */, label: "YOLO" }
@@ -16148,6 +16899,80 @@ var SETTINGS_SCHEMA = {
16148
16899
  default: DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
16149
16900
  description: "The number of lines to keep when truncating tool output.",
16150
16901
  showInDialog: false
16902
+ },
16903
+ toolOutputBatchBudget: {
16904
+ type: "number",
16905
+ label: "Tool Output Batch Budget",
16906
+ category: "General",
16907
+ requiresRestart: true,
16908
+ default: DEFAULT_TOOL_OUTPUT_BATCH_BUDGET,
16909
+ description: "Per-message budget (characters) for the combined output of one batch of tool calls; the largest results are offloaded to disk when exceeded. Set to -1 to disable.",
16910
+ showInDialog: false
16911
+ },
16912
+ computerUse: {
16913
+ type: "object",
16914
+ label: "Computer Use",
16915
+ category: "Tools",
16916
+ requiresRestart: true,
16917
+ default: {},
16918
+ description: "Cross-platform desktop automation via the upstream open-computer-use MCP server. Tools: list_apps, get_app_state, click, type_text, scroll, drag, press_key, perform_secondary_action, set_value. On first invocation, the upstream binary is fetched via npx and the user is walked through macOS Accessibility / Screen Recording permissions if needed.",
16919
+ showInDialog: false,
16920
+ properties: {
16921
+ enabled: {
16922
+ type: "boolean",
16923
+ label: "Enable Computer Use",
16924
+ category: "Tools",
16925
+ requiresRestart: true,
16926
+ default: true,
16927
+ description: "When enabled (default), the 9 computer_use__* tools are registered as deferred built-ins.",
16928
+ showInDialog: true
16929
+ }
16930
+ }
16931
+ }
16932
+ }
16933
+ },
16934
+ policy: {
16935
+ type: "object",
16936
+ label: "Daemon Policy",
16937
+ category: "Daemon",
16938
+ requiresRestart: true,
16939
+ default: {},
16940
+ description: "Daemon multi-client coordination policies. Tool-level allow/deny rules live under `permissions`; this section is for runtime mediation behavior between concurrent HTTP clients sharing one `qwen serve` daemon.",
16941
+ showInDialog: false,
16942
+ properties: {
16943
+ permissionStrategy: {
16944
+ type: "enum",
16945
+ label: "Permission Mediation Policy",
16946
+ category: "Daemon",
16947
+ requiresRestart: true,
16948
+ default: "first-responder",
16949
+ description: 'How permission requests resolve when multiple clients are attached. `first-responder` (default) = any client decides, first wins. `designated` = only the prompt originator decides; falls back to first-responder if originator is anonymous. NOTE: client identity comes from self-declared X-Qwen-Client-Id with no proof-of-possession (pair-token identity is not implemented yet), so any client observing originatorClientId on SSE frames can register with the same id and impersonate the originator. `consensus` = N-of-M voters must agree. Default N=floor(M/2)+1, which means UNANIMITY for M=2 (quorum=2, both must agree) and supermajority for larger even M (M=4 \u2192 quorum=3; M=6 \u2192 quorum=4). For M=2 specifically, split votes resolve only via permissionTimeoutMs. `local-only` = only loopback clients can RESOLVE; remote clients can still ABORT a pending permission via the cancel sentinel ({outcome:"cancelled"}) \u2014 cancel stays cross-policy for consistency. Strict-cancel-too deployments need a dedicated loopback-bound daemon. Requires daemon restart \u2014 read once at boot.',
16950
+ showInDialog: true,
16951
+ options: [
16952
+ { value: "first-responder", label: "First Responder" },
16953
+ { value: "designated", label: "Designated Originator" },
16954
+ { value: "consensus", label: "Consensus Quorum" },
16955
+ { value: "local-only", label: "Local Only" }
16956
+ ]
16957
+ },
16958
+ consensusQuorum: {
16959
+ type: "number",
16960
+ label: "Consensus Quorum Override",
16961
+ category: "Daemon",
16962
+ requiresRestart: true,
16963
+ default: void 0,
16964
+ description: "Optional fixed quorum size for consensus policy. Capped at M (count of registered voters at request issue time) to prevent unreachable quorum. Unset = floor(M/2)+1. Requires daemon restart \u2014 read once at boot.",
16965
+ showInDialog: false,
16966
+ // runQwenServe.ts validates `Number.isInteger(n) && n >= 1` and
16967
+ // refuses to boot otherwise. Override the generated schema so IDE
16968
+ // (VSCode, JetBrains via JSON Schema) flags `0`, `-1`, `1.5`
16969
+ // BEFORE the user restarts the daemon. The bare `type:'number'`
16970
+ // mapping accepts all of these.
16971
+ jsonSchemaOverride: {
16972
+ type: "integer",
16973
+ minimum: 1,
16974
+ description: "Optional fixed quorum size for consensus policy. Capped at M (count of registered voters at request issue time) to prevent unreachable quorum. Unset = floor(M/2)+1. Requires daemon restart \u2014 read once at boot."
16975
+ }
16151
16976
  }
16152
16977
  }
16153
16978
  },
@@ -16479,6 +17304,17 @@ var SETTINGS_SCHEMA = {
16479
17304
  mergeStrategy: "concat" /* CONCAT */,
16480
17305
  items: HOOK_DEFINITION_ITEMS
16481
17306
  },
17307
+ UserPromptExpansion: {
17308
+ type: "array",
17309
+ label: "Prompt Expansion Hooks",
17310
+ category: "Advanced",
17311
+ requiresRestart: false,
17312
+ default: [],
17313
+ description: "Hooks that execute when a slash command expands into a prompt.",
17314
+ showInDialog: false,
17315
+ mergeStrategy: "concat" /* CONCAT */,
17316
+ items: HOOK_DEFINITION_ITEMS
17317
+ },
16482
17318
  Stop: {
16483
17319
  type: "array",
16484
17320
  label: "After Agent Hooks",
@@ -16534,6 +17370,17 @@ var SETTINGS_SCHEMA = {
16534
17370
  mergeStrategy: "concat" /* CONCAT */,
16535
17371
  items: HOOK_DEFINITION_ITEMS
16536
17372
  },
17373
+ PostToolBatch: {
17374
+ type: "array",
17375
+ label: "Post Tool Batch Hooks",
17376
+ category: "Advanced",
17377
+ requiresRestart: false,
17378
+ default: [],
17379
+ description: "Hooks that execute once after all tool calls in a batch resolve.",
17380
+ showInDialog: false,
17381
+ mergeStrategy: "concat" /* CONCAT */,
17382
+ items: HOOK_DEFINITION_ITEMS
17383
+ },
16537
17384
  SessionStart: {
16538
17385
  type: "array",
16539
17386
  label: "Session Start Hooks",
@@ -16616,8 +17463,17 @@ var SETTINGS_SCHEMA = {
16616
17463
  label: "Enable Cron/Loop Tools",
16617
17464
  category: "Experimental",
16618
17465
  requiresRestart: true,
17466
+ default: true,
17467
+ description: "Enable in-session cron/loop tools. When enabled, the model can create recurring prompts using cron_create, cron_list, and cron_delete tools. Can be disabled via QWEN_CODE_DISABLE_CRON=1 environment variable.",
17468
+ showInDialog: true
17469
+ },
17470
+ agentTeam: {
17471
+ type: "boolean",
17472
+ label: "Enable Agent Team",
17473
+ category: "Experimental",
17474
+ requiresRestart: true,
16619
17475
  default: false,
16620
- description: "Enable in-session cron/loop tools (experimental). When enabled, the model can create recurring prompts using cron_create, cron_list, and cron_delete tools. Can also be enabled via QWEN_CODE_ENABLE_CRON=1 environment variable.",
17476
+ description: "Enable agent team collaboration tools (experimental). When enabled, the model can create agent teams and coordinate work using team_create, team_delete, send_message, task_create, task_update, and task_list tools. Can also be enabled via QWEN_CODE_ENABLE_AGENT_TEAM=1 environment variable.",
16621
17477
  showInDialog: true
16622
17478
  },
16623
17479
  emitToolUseSummaries: {
@@ -16630,6 +17486,26 @@ var SETTINGS_SCHEMA = {
16630
17486
  showInDialog: true
16631
17487
  }
16632
17488
  }
17489
+ },
17490
+ worktree: {
17491
+ type: "object",
17492
+ label: "Worktree",
17493
+ category: "Advanced",
17494
+ requiresRestart: false,
17495
+ default: {},
17496
+ description: 'Configuration for general-purpose git worktrees created by the CLI (the `enter_worktree` tool, the `agent isolation: "worktree"` parameter, and the startup `--worktree` flag). Does NOT affect Agent Arena worktrees \u2014 see `agents.arena.worktreeBaseDir` for those.',
17497
+ showInDialog: false,
17498
+ properties: {
17499
+ symlinkDirectories: {
17500
+ type: "array",
17501
+ label: "Symlink Directories Into Worktrees",
17502
+ category: "Advanced",
17503
+ requiresRestart: false,
17504
+ default: void 0,
17505
+ description: "Directories under the main repository to symlink into every general-purpose worktree on creation. Useful for sharing large opt-in dirs like `node_modules` so the model can run tests / builds inside the worktree without a fresh install. Paths must be relative to the repo root; absolute paths, anything containing `..`, and any path inside `.git` or `.qwen` (the CLI-managed metadata tree, which contains the worktrees directory itself) are rejected. Missing source dirs and existing destination paths are silently skipped (no overwrite, no failure).",
17506
+ showInDialog: false
17507
+ }
17508
+ }
16633
17509
  }
16634
17510
  };
16635
17511
  function getSettingsSchema() {
@@ -16734,8 +17610,8 @@ function getDefaultValue(key) {
16734
17610
  return getFlattenedSchema()[key]?.default;
16735
17611
  }
16736
17612
  __name(getDefaultValue, "getDefaultValue");
16737
- function getNestedValue(obj, path8) {
16738
- const [first, ...rest] = path8;
17613
+ function getNestedValue(obj, path9) {
17614
+ const [first, ...rest] = path9;
16739
17615
  if (!first || !(first in obj)) {
16740
17616
  return void 0;
16741
17617
  }
@@ -16749,8 +17625,8 @@ function getNestedValue(obj, path8) {
16749
17625
  return void 0;
16750
17626
  }
16751
17627
  __name(getNestedValue, "getNestedValue");
16752
- function getNestedProperty(obj, path8) {
16753
- return getNestedValue(obj, path8.split("."));
17628
+ function getNestedProperty(obj, path9) {
17629
+ return getNestedValue(obj, path9.split("."));
16754
17630
  }
16755
17631
  __name(getNestedProperty, "getNestedProperty");
16756
17632
  function getEffectiveValue(key, settings, mergedSettings) {
@@ -16758,12 +17634,12 @@ function getEffectiveValue(key, settings, mergedSettings) {
16758
17634
  if (!definition) {
16759
17635
  return void 0;
16760
17636
  }
16761
- const path8 = key.split(".");
16762
- let value = getNestedValue(settings, path8);
17637
+ const path9 = key.split(".");
17638
+ let value = getNestedValue(settings, path9);
16763
17639
  if (value !== void 0) {
16764
17640
  return value;
16765
17641
  }
16766
- value = getNestedValue(mergedSettings, path8);
17642
+ value = getNestedValue(mergedSettings, path9);
16767
17643
  if (value !== void 0) {
16768
17644
  return value;
16769
17645
  }
@@ -16814,8 +17690,8 @@ function getDialogSettingKeys() {
16814
17690
  }
16815
17691
  __name(getDialogSettingKeys, "getDialogSettingKeys");
16816
17692
  function settingExistsInScope(key, scopeSettings) {
16817
- const path8 = key.split(".");
16818
- const value = getNestedValue(scopeSettings, path8);
17693
+ const path9 = key.split(".");
17694
+ const value = getNestedValue(scopeSettings, path9);
16819
17695
  return value !== void 0;
16820
17696
  }
16821
17697
  __name(settingExistsInScope, "settingExistsInScope");
@@ -16828,8 +17704,8 @@ function pathHasUnsafeSegment(keys) {
16828
17704
  return false;
16829
17705
  }
16830
17706
  __name(pathHasUnsafeSegment, "pathHasUnsafeSegment");
16831
- function setNestedPropertyForce(obj, path8, value) {
16832
- const keys = path8.split(".");
17707
+ function setNestedPropertyForce(obj, path9, value) {
17708
+ const keys = path9.split(".");
16833
17709
  if (pathHasUnsafeSegment(keys)) return;
16834
17710
  const lastKey = keys.pop();
16835
17711
  if (!lastKey) return;
@@ -16843,8 +17719,8 @@ function setNestedPropertyForce(obj, path8, value) {
16843
17719
  current[lastKey] = value;
16844
17720
  }
16845
17721
  __name(setNestedPropertyForce, "setNestedPropertyForce");
16846
- function setNestedPropertySafe(obj, path8, value) {
16847
- const keys = path8.split(".");
17722
+ function setNestedPropertySafe(obj, path9, value) {
17723
+ const keys = path9.split(".");
16848
17724
  if (pathHasUnsafeSegment(keys)) return;
16849
17725
  const lastKey = keys.pop();
16850
17726
  if (!lastKey) return;
@@ -16863,8 +17739,8 @@ function setNestedPropertySafe(obj, path8, value) {
16863
17739
  current[lastKey] = value;
16864
17740
  }
16865
17741
  __name(setNestedPropertySafe, "setNestedPropertySafe");
16866
- function deleteNestedPropertySafe(obj, path8) {
16867
- const keys = path8.split(".");
17742
+ function deleteNestedPropertySafe(obj, path9) {
17743
+ const keys = path9.split(".");
16868
17744
  const lastKey = keys.pop();
16869
17745
  if (!lastKey) return;
16870
17746
  let current = obj;
@@ -16896,10 +17772,10 @@ function getRestartRequiredFromModified(modifiedSettings) {
16896
17772
  __name(getRestartRequiredFromModified, "getRestartRequiredFromModified");
16897
17773
  function saveModifiedSettings(modifiedSettings, pendingSettings, loadedSettings, scope) {
16898
17774
  modifiedSettings.forEach((settingKey) => {
16899
- const path8 = settingKey.split(".");
17775
+ const path9 = settingKey.split(".");
16900
17776
  const value = getNestedValue(
16901
17777
  pendingSettings,
16902
- path8
17778
+ path9
16903
17779
  );
16904
17780
  const existsInOriginalFile = settingExistsInScope(
16905
17781
  settingKey,
@@ -17001,12 +17877,12 @@ function isPlainObject(item) {
17001
17877
  return !!item && typeof item === "object" && !Array.isArray(item);
17002
17878
  }
17003
17879
  __name(isPlainObject, "isPlainObject");
17004
- function mergeRecursively(target, source, getMergeStrategyForPath2, path8 = []) {
17880
+ function mergeRecursively(target, source, getMergeStrategyForPath2, path9 = []) {
17005
17881
  for (const key of Object.keys(source)) {
17006
17882
  if (key === "__proto__" || key === "constructor" || key === "prototype") {
17007
17883
  continue;
17008
17884
  }
17009
- const newPath = [...path8, key];
17885
+ const newPath = [...path9, key];
17010
17886
  const srcValue = source[key];
17011
17887
  const objValue = target[key];
17012
17888
  const mergeStrategy = getMergeStrategyForPath2(newPath);
@@ -17139,7 +18015,7 @@ function writeWithBackupSync(targetPath, content, options = {}) {
17139
18015
  __name(writeWithBackupSync, "writeWithBackupSync");
17140
18016
 
17141
18017
  // packages/cli/src/utils/commentJson.ts
17142
- function updateSettingsFilePreservingFormat(filePath, updates, sync = false) {
18018
+ function updateSettingsFilePreservingFormat(filePath, updates, sync = false, replacePath = []) {
17143
18019
  if (!fs5.existsSync(filePath)) {
17144
18020
  const content = (0, import_comment_json.stringify)(updates, null, 2);
17145
18021
  writeWithBackupSync(filePath, content);
@@ -17156,7 +18032,7 @@ function updateSettingsFilePreservingFormat(filePath, updates, sync = false) {
17156
18032
  );
17157
18033
  return false;
17158
18034
  }
17159
- const updatedStructure = applyUpdates(parsed, updates, sync);
18035
+ const updatedStructure = applyUpdates(parsed, updates, sync, replacePath);
17160
18036
  const updatedContent = (0, import_comment_json.stringify)(updatedStructure, null, 2);
17161
18037
  try {
17162
18038
  (0, import_comment_json.parse)(updatedContent);
@@ -17173,7 +18049,7 @@ function updateSettingsFilePreservingFormat(filePath, updates, sync = false) {
17173
18049
  return true;
17174
18050
  }
17175
18051
  __name(updateSettingsFilePreservingFormat, "updateSettingsFilePreservingFormat");
17176
- function applyUpdates(current, updates, sync = false) {
18052
+ function applyUpdates(current, updates, sync = false, replacePath = [], currentPath = []) {
17177
18053
  const result = current;
17178
18054
  if (sync) {
17179
18055
  const keysToRemove = Object.keys(result).filter((key) => !(key in updates));
@@ -17182,12 +18058,31 @@ function applyUpdates(current, updates, sync = false) {
17182
18058
  }
17183
18059
  }
17184
18060
  for (const key of Object.getOwnPropertyNames(updates)) {
18061
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
18062
+ continue;
18063
+ }
17185
18064
  const value = updates[key];
17186
- if (typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length > 0 && typeof result[key] === "object" && result[key] !== null && !Array.isArray(result[key])) {
18065
+ const nextPath = [...currentPath, key];
18066
+ const valueIsObject = typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length > 0;
18067
+ if (pathsEqual(nextPath, replacePath)) {
18068
+ result[key] = valueIsObject ? applyUpdates({}, value) : value;
18069
+ continue;
18070
+ }
18071
+ if (valueIsObject && (typeof result[key] !== "object" || result[key] === null || Array.isArray(result[key]))) {
18072
+ result[key] = applyUpdates(
18073
+ {},
18074
+ value,
18075
+ sync,
18076
+ replacePath,
18077
+ nextPath
18078
+ );
18079
+ } else if (valueIsObject && typeof result[key] === "object" && result[key] !== null && !Array.isArray(result[key])) {
17187
18080
  result[key] = applyUpdates(
17188
18081
  result[key],
17189
18082
  value,
17190
- sync
18083
+ sync,
18084
+ replacePath,
18085
+ nextPath
17191
18086
  );
17192
18087
  } else {
17193
18088
  result[key] = value;
@@ -17196,6 +18091,10 @@ function applyUpdates(current, updates, sync = false) {
17196
18091
  return result;
17197
18092
  }
17198
18093
  __name(applyUpdates, "applyUpdates");
18094
+ function pathsEqual(left, right) {
18095
+ return left.length === right.length && left.every((segment, index) => segment === right[index]);
18096
+ }
18097
+ __name(pathsEqual, "pathsEqual");
17199
18098
 
17200
18099
  // packages/cli/src/config/migration/index.ts
17201
18100
  init_esbuild_shims();
@@ -17828,10 +18727,10 @@ __name(needsMigration, "needsMigration");
17828
18727
 
17829
18728
  // packages/cli/src/config/settings.ts
17830
18729
  var debugLogger3 = createDebugLogger("SETTINGS");
17831
- function getMergeStrategyForPath(path8) {
18730
+ function getMergeStrategyForPath(path9) {
17832
18731
  let current = void 0;
17833
18732
  let currentSchema = getSettingsSchema();
17834
- for (const key of path8) {
18733
+ for (const key of path9) {
17835
18734
  if (!currentSchema || !currentSchema[key]) {
17836
18735
  return void 0;
17837
18736
  }
@@ -17847,11 +18746,42 @@ function getUserSettingsPath() {
17847
18746
  }
17848
18747
  __name(getUserSettingsPath, "getUserSettingsPath");
17849
18748
  function getUserSettingsDir() {
17850
- return path3.dirname(getUserSettingsPath());
18749
+ return path4.dirname(getUserSettingsPath());
17851
18750
  }
17852
18751
  __name(getUserSettingsDir, "getUserSettingsDir");
17853
18752
  var DEFAULT_EXCLUDED_ENV_VARS = ["DEBUG", "DEBUG_MODE"];
17854
- var PROJECT_ENV_HARDCODED_EXCLUSIONS = ["QWEN_HOME", "QWEN_RUNTIME_DIR"];
18753
+ var ENV_CORRUPTED_PATH = "QWEN_CODE_SETTINGS_CORRUPTED_PATH";
18754
+ var ENV_WAS_RECOVERED = "QWEN_CODE_SETTINGS_WAS_RECOVERED";
18755
+ var PROJECT_ENV_HARDCODED_EXCLUSIONS = [
18756
+ "QWEN_HOME",
18757
+ "QWEN_RUNTIME_DIR",
18758
+ ENV_CORRUPTED_PATH,
18759
+ ENV_WAS_RECOVERED
18760
+ ];
18761
+ var RELOAD_EXCLUDED_KEYS = /* @__PURE__ */ new Set([
18762
+ ...PROJECT_ENV_HARDCODED_EXCLUSIONS,
18763
+ "QWEN_SERVER_TOKEN",
18764
+ "QWEN_CLI_ENTRY",
18765
+ "NODE_OPTIONS",
18766
+ "NODE_PATH",
18767
+ "NODE_TLS_REJECT_UNAUTHORIZED",
18768
+ "LD_PRELOAD",
18769
+ "LD_AUDIT",
18770
+ "LD_LIBRARY_PATH",
18771
+ "DYLD_INSERT_LIBRARIES",
18772
+ "DYLD_LIBRARY_PATH",
18773
+ "BASH_ENV",
18774
+ "ENV",
18775
+ "PATH",
18776
+ "HOME",
18777
+ "TMPDIR",
18778
+ "TMP",
18779
+ "TEMP"
18780
+ ]);
18781
+ var dotEnvSourcedKeys = /* @__PURE__ */ new Set();
18782
+ var settingsEnvSourcedKeys = /* @__PURE__ */ new Set();
18783
+ var lastReloadSnapshot = /* @__PURE__ */ new Map();
18784
+ var lastReloadSnapshotSeeded = false;
17855
18785
  var SETTINGS_VERSION = 4;
17856
18786
  var SETTINGS_VERSION_KEY = "$version";
17857
18787
  function getSystemSettingsPath() {
@@ -17871,8 +18801,8 @@ function getSystemDefaultsPath() {
17871
18801
  if (process2.env["QWEN_CODE_SYSTEM_DEFAULTS_PATH"]) {
17872
18802
  return process2.env["QWEN_CODE_SYSTEM_DEFAULTS_PATH"];
17873
18803
  }
17874
- return path3.join(
17875
- path3.dirname(getSystemSettingsPath()),
18804
+ return path4.join(
18805
+ path4.dirname(getSystemSettingsPath()),
17876
18806
  "system-defaults.json"
17877
18807
  );
17878
18808
  }
@@ -17999,7 +18929,7 @@ var LoadedSettings = class {
17999
18929
  static {
18000
18930
  __name(this, "LoadedSettings");
18001
18931
  }
18002
- constructor(system, systemDefaults, user, workspace, isTrusted, migratedInMemorScopes, migrationWarnings = []) {
18932
+ constructor(system, systemDefaults, user, workspace, isTrusted, migratedInMemorScopes, migrationWarnings = [], corruptedPath = void 0, wasRecovered = false) {
18003
18933
  this.system = system;
18004
18934
  this.systemDefaults = systemDefaults;
18005
18935
  this.user = user;
@@ -18007,6 +18937,8 @@ var LoadedSettings = class {
18007
18937
  this.isTrusted = isTrusted;
18008
18938
  this.migratedInMemorScopes = migratedInMemorScopes;
18009
18939
  this.migrationWarnings = migrationWarnings;
18940
+ this.corruptedPath = corruptedPath;
18941
+ this.wasRecovered = wasRecovered;
18010
18942
  this._merged = this.computeMergedSettings();
18011
18943
  }
18012
18944
  system;
@@ -18016,6 +18948,9 @@ var LoadedSettings = class {
18016
18948
  isTrusted;
18017
18949
  migratedInMemorScopes;
18018
18950
  migrationWarnings;
18951
+ corruptedPath;
18952
+ wasRecovered;
18953
+ corruptionDialogDismissed = false;
18019
18954
  _merged;
18020
18955
  get merged() {
18021
18956
  return this._merged;
@@ -18044,15 +18979,47 @@ var LoadedSettings = class {
18044
18979
  }
18045
18980
  }
18046
18981
  setValue(scope, key, value) {
18982
+ if (key === "model.name" && typeof value === "string") {
18983
+ value = stripRuntimeSnapshotPrefix(value);
18984
+ }
18047
18985
  const settingsFile = this.forScope(scope);
18048
18986
  setNestedPropertySafe(settingsFile.settings, key, value);
18049
18987
  setNestedPropertySafe(settingsFile.originalSettings, key, value);
18050
18988
  this._merged = this.computeMergedSettings();
18051
- saveSettings(settingsFile, createSettingsUpdate(key, value));
18989
+ const replacePath = key === "mcpServers" ? key.split(".") : [];
18990
+ saveSettings(settingsFile, createSettingsUpdate(key, value), replacePath);
18052
18991
  }
18053
18992
  recomputeMerged() {
18054
18993
  this._merged = this.computeMergedSettings();
18055
18994
  }
18995
+ reloadScopeFromDisk(scope) {
18996
+ const file = this.forScope(scope);
18997
+ try {
18998
+ if (!fs6.existsSync(file.path)) {
18999
+ file.settings = {};
19000
+ file.originalSettings = {};
19001
+ file.rawJson = void 0;
19002
+ this._merged = this.computeMergedSettings();
19003
+ return;
19004
+ }
19005
+ const content = fs6.readFileSync(file.path, "utf-8");
19006
+ const parsed = JSON.parse((0, import_strip_json_comments2.default)(content));
19007
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
19008
+ const resolved = resolveEnvVarsInObject(
19009
+ parsed,
19010
+ getHomeEnvFallbackVars()
19011
+ );
19012
+ file.settings = resolved;
19013
+ file.originalSettings = structuredClone(parsed);
19014
+ file.rawJson = content;
19015
+ }
19016
+ } catch (err) {
19017
+ debugLogger3.warn(
19018
+ `reloadScopeFromDisk(${scope}): ${getErrorMessage(err)}`
19019
+ );
19020
+ }
19021
+ this._merged = this.computeMergedSettings();
19022
+ }
18056
19023
  /**
18057
19024
  * Get user-level hooks from user settings (not merged with workspace).
18058
19025
  * These hooks should always be loaded regardless of folder trust.
@@ -18085,7 +19052,9 @@ function createMinimalSettings() {
18085
19052
  emptySettingsFile,
18086
19053
  false,
18087
19054
  /* @__PURE__ */ new Set(),
18088
- []
19055
+ [],
19056
+ void 0,
19057
+ false
18089
19058
  );
18090
19059
  }
18091
19060
  __name(createMinimalSettings, "createMinimalSettings");
@@ -18093,10 +19062,10 @@ function getUserLevelEnvPaths() {
18093
19062
  const homeDir = homedir();
18094
19063
  const globalQwenDir = Storage.getGlobalQwenDir();
18095
19064
  const paths = /* @__PURE__ */ new Set([
18096
- path3.normalize(path3.join(homeDir, ".env")),
18097
- path3.normalize(path3.join(globalQwenDir, ".env"))
19065
+ path4.normalize(path4.join(homeDir, ".env")),
19066
+ path4.normalize(path4.join(globalQwenDir, ".env"))
18098
19067
  ]);
18099
- const legacyQwenEnv = path3.normalize(path3.join(homeDir, QWEN_DIR, ".env"));
19068
+ const legacyQwenEnv = path4.normalize(path4.join(homeDir, QWEN_DIR, ".env"));
18100
19069
  paths.add(legacyQwenEnv);
18101
19070
  return paths;
18102
19071
  }
@@ -18112,9 +19081,9 @@ function preResolveHomeEnvOverrides() {
18112
19081
  }
18113
19082
  const initialQwenHome = process2.env["QWEN_HOME"];
18114
19083
  const initialQwenDir = Storage.getGlobalQwenDir();
18115
- const candidates = [path3.join(initialQwenDir, ".env")];
19084
+ const candidates = [path4.join(initialQwenDir, ".env")];
18116
19085
  if (!initialQwenHome) {
18117
- candidates.push(path3.join(path3.dirname(initialQwenDir), ".env"));
19086
+ candidates.push(path4.join(path4.dirname(initialQwenDir), ".env"));
18118
19087
  }
18119
19088
  for (const candidate of candidates) {
18120
19089
  readHomeEnvInto(candidate);
@@ -18123,7 +19092,7 @@ function preResolveHomeEnvOverrides() {
18123
19092
  if (discoveredQwenHome && discoveredQwenHome !== initialQwenHome) {
18124
19093
  const discoveredDir = Storage.getGlobalQwenDir();
18125
19094
  if (discoveredDir !== initialQwenDir) {
18126
- readHomeEnvInto(path3.join(discoveredDir, ".env"));
19095
+ readHomeEnvInto(path4.join(discoveredDir, ".env"));
18127
19096
  }
18128
19097
  }
18129
19098
  }
@@ -18143,6 +19112,33 @@ function readHomeEnvInto(file) {
18143
19112
  }
18144
19113
  }
18145
19114
  __name(readHomeEnvInto, "readHomeEnvInto");
19115
+ function getHomeEnvFallbackVars() {
19116
+ const globalQwenDir = Storage.getGlobalQwenDir();
19117
+ const candidates = [path4.join(globalQwenDir, ".env")];
19118
+ if (!process2.env["QWEN_HOME"]) {
19119
+ candidates.push(path4.join(path4.dirname(globalQwenDir), ".env"));
19120
+ }
19121
+ const result = {};
19122
+ for (const candidate of candidates) {
19123
+ if (!fs6.existsSync(candidate)) {
19124
+ continue;
19125
+ }
19126
+ try {
19127
+ const parsed = dotenv.parse(fs6.readFileSync(candidate, "utf-8"));
19128
+ for (const key in parsed) {
19129
+ if (Object.hasOwn(parsed, key) && !Object.hasOwn(process2.env, key)) {
19130
+ result[key] ??= parsed[key];
19131
+ }
19132
+ }
19133
+ } catch (e) {
19134
+ debugLogger3.warn(
19135
+ `Failed to read home .env candidate ${candidate}: ${getErrorMessage(e)}`
19136
+ );
19137
+ }
19138
+ }
19139
+ return result;
19140
+ }
19141
+ __name(getHomeEnvFallbackVars, "getHomeEnvFallbackVars");
18146
19142
  function detectQwenHomeRedirectWithoutMigration(activeUserSettingsPath) {
18147
19143
  if (!process2.env["QWEN_HOME"]) {
18148
19144
  return null;
@@ -18156,13 +19152,13 @@ function detectQwenHomeRedirectWithoutMigration(activeUserSettingsPath) {
18156
19152
  } finally {
18157
19153
  process2.env["QWEN_HOME"] = savedQwenHome;
18158
19154
  }
18159
- if (path3.resolve(activeQwenDir) === path3.resolve(legacyQwenDir)) {
19155
+ if (path4.resolve(activeQwenDir) === path4.resolve(legacyQwenDir)) {
18160
19156
  return null;
18161
19157
  }
18162
19158
  if (fs6.existsSync(activeUserSettingsPath)) {
18163
19159
  return null;
18164
19160
  }
18165
- const legacyUserSettings = path3.join(legacyQwenDir, "settings.json");
19161
+ const legacyUserSettings = path4.join(legacyQwenDir, "settings.json");
18166
19162
  if (!fs6.existsSync(legacyUserSettings)) {
18167
19163
  return null;
18168
19164
  }
@@ -18173,15 +19169,15 @@ function findEnvFile(settings, startDir, userLevelPaths = getUserLevelEnvPaths()
18173
19169
  const homeDir = homedir();
18174
19170
  const isTrusted = isWorkspaceTrusted(settings).isTrusted;
18175
19171
  const globalQwenDir = Storage.getGlobalQwenDir();
18176
- const legacyQwenDir = path3.normalize(path3.join(homeDir, QWEN_DIR));
18177
- const hasCustomConfigDir = path3.normalize(globalQwenDir) !== legacyQwenDir;
18178
- const canUseEnvFile = /* @__PURE__ */ __name((filePath) => isTrusted !== false || userLevelPaths.has(path3.normalize(filePath)), "canUseEnvFile");
19172
+ const legacyQwenDir = path4.normalize(path4.join(homeDir, QWEN_DIR));
19173
+ const hasCustomConfigDir = path4.normalize(globalQwenDir) !== legacyQwenDir;
19174
+ const canUseEnvFile = /* @__PURE__ */ __name((filePath) => isTrusted !== false || userLevelPaths.has(path4.normalize(filePath)), "canUseEnvFile");
18179
19175
  const findHomeCandidate = /* @__PURE__ */ __name(() => {
18180
- const candidates = [path3.join(globalQwenDir, ".env")];
19176
+ const candidates = [path4.join(globalQwenDir, ".env")];
18181
19177
  if (hasCustomConfigDir) {
18182
- candidates.push(path3.join(legacyQwenDir, ".env"));
19178
+ candidates.push(path4.join(legacyQwenDir, ".env"));
18183
19179
  }
18184
- candidates.push(path3.join(homeDir, ".env"));
19180
+ candidates.push(path4.join(homeDir, ".env"));
18185
19181
  for (const candidate of candidates) {
18186
19182
  if (fs6.existsSync(candidate) && canUseEnvFile(candidate)) {
18187
19183
  return candidate;
@@ -18189,7 +19185,7 @@ function findEnvFile(settings, startDir, userLevelPaths = getUserLevelEnvPaths()
18189
19185
  }
18190
19186
  return null;
18191
19187
  }, "findHomeCandidate");
18192
- let currentDir = path3.resolve(startDir);
19188
+ let currentDir = path4.resolve(startDir);
18193
19189
  let visitedHomeDir = false;
18194
19190
  while (true) {
18195
19191
  if (currentDir === homeDir) {
@@ -18197,16 +19193,16 @@ function findEnvFile(settings, startDir, userLevelPaths = getUserLevelEnvPaths()
18197
19193
  const found = findHomeCandidate();
18198
19194
  if (found) return found;
18199
19195
  } else {
18200
- const geminiEnvPath = path3.join(currentDir, QWEN_DIR, ".env");
19196
+ const geminiEnvPath = path4.join(currentDir, QWEN_DIR, ".env");
18201
19197
  if (fs6.existsSync(geminiEnvPath) && canUseEnvFile(geminiEnvPath)) {
18202
19198
  return geminiEnvPath;
18203
19199
  }
18204
- const envPath = path3.join(currentDir, ".env");
19200
+ const envPath = path4.join(currentDir, ".env");
18205
19201
  if (fs6.existsSync(envPath) && canUseEnvFile(envPath)) {
18206
19202
  return envPath;
18207
19203
  }
18208
19204
  }
18209
- const parentDir = path3.dirname(currentDir);
19205
+ const parentDir = path4.dirname(currentDir);
18210
19206
  if (parentDir === currentDir || !parentDir) {
18211
19207
  return visitedHomeDir ? null : findHomeCandidate();
18212
19208
  }
@@ -18239,9 +19235,9 @@ function loadEnvironment(settings) {
18239
19235
  const envFileContent = fs6.readFileSync(envFilePath, "utf-8");
18240
19236
  const parsedEnv = dotenv.parse(envFileContent);
18241
19237
  const excludedVars = settings?.advanced?.excludedEnvVars || DEFAULT_EXCLUDED_ENV_VARS;
18242
- const normalizedEnvFilePath = path3.normalize(envFilePath);
19238
+ const normalizedEnvFilePath = path4.normalize(envFilePath);
18243
19239
  const isHomeScopedEnvFile = userLevelPaths.has(normalizedEnvFilePath);
18244
- const isQwenScopedEnvFile = isHomeScopedEnvFile || path3.basename(path3.dirname(normalizedEnvFilePath)) === QWEN_DIR;
19240
+ const isQwenScopedEnvFile = isHomeScopedEnvFile || path4.basename(path4.dirname(normalizedEnvFilePath)) === QWEN_DIR;
18245
19241
  for (const key in parsedEnv) {
18246
19242
  if (Object.hasOwn(parsedEnv, key)) {
18247
19243
  if (!isHomeScopedEnvFile && PROJECT_ENV_HARDCODED_EXCLUSIONS.includes(key)) {
@@ -18252,6 +19248,10 @@ function loadEnvironment(settings) {
18252
19248
  }
18253
19249
  if (!Object.hasOwn(process2.env, key)) {
18254
19250
  process2.env[key] = parsedEnv[key];
19251
+ dotEnvSourcedKeys.add(key);
19252
+ }
19253
+ if (!lastReloadSnapshotSeeded) {
19254
+ lastReloadSnapshot.set(key, parsedEnv[key]);
18255
19255
  }
18256
19256
  }
18257
19257
  }
@@ -18265,12 +19265,110 @@ function loadEnvironment(settings) {
18265
19265
  }
18266
19266
  if (!Object.hasOwn(process2.env, key) && typeof value === "string") {
18267
19267
  process2.env[key] = value;
19268
+ settingsEnvSourcedKeys.add(key);
19269
+ }
19270
+ if (!lastReloadSnapshotSeeded && typeof value === "string" && !lastReloadSnapshot.has(key)) {
19271
+ lastReloadSnapshot.set(key, value);
18268
19272
  }
18269
19273
  }
18270
19274
  }
19275
+ lastReloadSnapshotSeeded = true;
18271
19276
  }
18272
19277
  __name(loadEnvironment, "loadEnvironment");
18273
- function loadSettings(workspaceDir = process2.cwd()) {
19278
+ function reloadEnvironment(settings, workspaceCwd) {
19279
+ const userLevelPaths = getUserLevelEnvPaths();
19280
+ const envFilePath = findEnvFile(settings, workspaceCwd, userLevelPaths);
19281
+ if (process2.env["CLOUD_SHELL"] === "true") {
19282
+ setUpCloudShellEnvironment(envFilePath);
19283
+ }
19284
+ let dotEnvReadFailed = false;
19285
+ const newDotEnvKeys = /* @__PURE__ */ new Map();
19286
+ const newSettingsEnvKeys = /* @__PURE__ */ new Map();
19287
+ if (envFilePath) {
19288
+ try {
19289
+ const envFileContent = fs6.readFileSync(envFilePath, "utf-8");
19290
+ const parsedEnv = dotenv.parse(envFileContent);
19291
+ const excludedVars = settings?.advanced?.excludedEnvVars || DEFAULT_EXCLUDED_ENV_VARS;
19292
+ const normalizedEnvFilePath = path4.normalize(envFilePath);
19293
+ const isHomeScopedEnvFile = userLevelPaths.has(normalizedEnvFilePath);
19294
+ const isQwenScopedEnvFile = isHomeScopedEnvFile || path4.basename(path4.dirname(normalizedEnvFilePath)) === QWEN_DIR;
19295
+ for (const key in parsedEnv) {
19296
+ if (!Object.hasOwn(parsedEnv, key)) continue;
19297
+ if (RELOAD_EXCLUDED_KEYS.has(key)) continue;
19298
+ if (!isHomeScopedEnvFile && PROJECT_ENV_HARDCODED_EXCLUSIONS.includes(key)) {
19299
+ continue;
19300
+ }
19301
+ if (!isQwenScopedEnvFile && excludedVars.includes(key)) continue;
19302
+ newDotEnvKeys.set(key, parsedEnv[key]);
19303
+ }
19304
+ } catch {
19305
+ dotEnvReadFailed = true;
19306
+ }
19307
+ }
19308
+ if (settings.env) {
19309
+ for (const [key, value] of Object.entries(settings.env)) {
19310
+ if (RELOAD_EXCLUDED_KEYS.has(key)) continue;
19311
+ if (PROJECT_ENV_HARDCODED_EXCLUSIONS.includes(key)) continue;
19312
+ if (typeof value !== "string") continue;
19313
+ if (newDotEnvKeys.has(key)) continue;
19314
+ if (dotEnvReadFailed && lastReloadSnapshot.has(key)) continue;
19315
+ newSettingsEnvKeys.set(key, value);
19316
+ }
19317
+ }
19318
+ const allNewKeys = /* @__PURE__ */ new Set([
19319
+ ...newDotEnvKeys.keys(),
19320
+ ...newSettingsEnvKeys.keys()
19321
+ ]);
19322
+ const updatedKeys = [];
19323
+ const removedKeys = [];
19324
+ if (!dotEnvReadFailed) {
19325
+ const previouslyKnown = /* @__PURE__ */ new Set([
19326
+ ...lastReloadSnapshot.keys(),
19327
+ ...dotEnvSourcedKeys,
19328
+ ...settingsEnvSourcedKeys
19329
+ ]);
19330
+ for (const key of previouslyKnown) {
19331
+ if (!allNewKeys.has(key) && !RELOAD_EXCLUDED_KEYS.has(key)) {
19332
+ delete process2.env[key];
19333
+ removedKeys.push(key);
19334
+ }
19335
+ }
19336
+ }
19337
+ for (const [key, value] of newDotEnvKeys) {
19338
+ if (process2.env[key] !== value) {
19339
+ updatedKeys.push(key);
19340
+ }
19341
+ process2.env[key] = value;
19342
+ }
19343
+ for (const [key, value] of newSettingsEnvKeys) {
19344
+ if (process2.env[key] !== value) {
19345
+ updatedKeys.push(key);
19346
+ }
19347
+ process2.env[key] = value;
19348
+ }
19349
+ if (!dotEnvReadFailed) {
19350
+ dotEnvSourcedKeys.clear();
19351
+ for (const key of newDotEnvKeys.keys()) {
19352
+ dotEnvSourcedKeys.add(key);
19353
+ }
19354
+ lastReloadSnapshot.clear();
19355
+ for (const [key, value] of newDotEnvKeys) {
19356
+ lastReloadSnapshot.set(key, value);
19357
+ }
19358
+ for (const [key, value] of newSettingsEnvKeys) {
19359
+ lastReloadSnapshot.set(key, value);
19360
+ }
19361
+ }
19362
+ settingsEnvSourcedKeys.clear();
19363
+ for (const key of newSettingsEnvKeys.keys()) {
19364
+ settingsEnvSourcedKeys.add(key);
19365
+ }
19366
+ return { updatedKeys, removedKeys };
19367
+ }
19368
+ __name(reloadEnvironment, "reloadEnvironment");
19369
+ var CORRUPTED_SUFFIX = ".corrupted";
19370
+ function loadSettings(workspaceDir = process2.cwd(), consumeCorruptionEnvVars = true) {
19371
+ const opts = typeof consumeCorruptionEnvVars === "object" ? consumeCorruptionEnvVars : { consumeCorruptionEnvVars };
18274
19372
  preResolveHomeEnvOverrides();
18275
19373
  const userSettingsPath = getUserSettingsPath();
18276
19374
  const qwenHomeRedirectWarning = detectQwenHomeRedirectWithoutMigration(userSettingsPath);
@@ -18282,8 +19380,8 @@ function loadSettings(workspaceDir = process2.cwd()) {
18282
19380
  const systemSettingsPath = getSystemSettingsPath();
18283
19381
  const systemDefaultsPath = getSystemDefaultsPath();
18284
19382
  const migratedInMemorScopes = /* @__PURE__ */ new Set();
18285
- const resolvedWorkspaceDir = path3.resolve(workspaceDir);
18286
- const resolvedHomeDir = path3.resolve(homedir());
19383
+ const resolvedWorkspaceDir = path4.resolve(workspaceDir);
19384
+ const resolvedHomeDir = path4.resolve(homedir());
18287
19385
  let realWorkspaceDir = resolvedWorkspaceDir;
18288
19386
  try {
18289
19387
  realWorkspaceDir = fs6.realpathSync(resolvedWorkspaceDir);
@@ -18298,10 +19396,21 @@ function loadSettings(workspaceDir = process2.cwd()) {
18298
19396
  if (fs6.existsSync(filePath)) {
18299
19397
  let content = fs6.readFileSync(filePath, "utf-8");
18300
19398
  let rawSettings;
18301
- let recoveryWarning;
19399
+ const corruptedPath = `${filePath}${CORRUPTED_SUFFIX}`;
19400
+ let corruptedSaved = false;
19401
+ let recoveredFromBackup = false;
19402
+ let recoveredFromEnvVar = null;
18302
19403
  try {
18303
19404
  rawSettings = JSON.parse((0, import_strip_json_comments2.default)(content));
18304
19405
  } catch (parseError) {
19406
+ try {
19407
+ fs6.copyFileSync(filePath, corruptedPath);
19408
+ corruptedSaved = true;
19409
+ } catch (copyError) {
19410
+ debugLogger3.warn(
19411
+ `Failed to copy corrupted file: ${getErrorMessage(copyError)}`
19412
+ );
19413
+ }
18305
19414
  const backupPath = `${filePath}.orig`;
18306
19415
  if (fs6.existsSync(backupPath)) {
18307
19416
  debugLogger3.warn(
@@ -18317,7 +19426,7 @@ function loadSettings(workspaceDir = process2.cwd()) {
18317
19426
  rawSettings = backupSettings;
18318
19427
  const recoveryMsg = `Settings file ${filePath} had invalid JSON and was recovered from backup ${backupPath}. Some recent settings changes may have been lost.`;
18319
19428
  debugLogger3.warn(recoveryMsg);
18320
- recoveryWarning = recoveryMsg;
19429
+ recoveredFromBackup = true;
18321
19430
  } catch (backupError) {
18322
19431
  debugLogger3.warn(
18323
19432
  `Failed to recover from backup ${backupPath}: ${getErrorMessage(backupError)}. Falling back to empty settings.`
@@ -18325,24 +19434,29 @@ function loadSettings(workspaceDir = process2.cwd()) {
18325
19434
  }
18326
19435
  }
18327
19436
  if (!rawSettings) {
18328
- const corruptedPath = `${filePath}.corrupted.${Date.now()}`;
18329
- let warningMsg;
18330
- try {
18331
- fs6.renameSync(filePath, corruptedPath);
18332
- 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.`;
18333
- } catch (renameError) {
18334
- debugLogger3.error(
18335
- `Failed to rename corrupted settings file: ${getErrorMessage(renameError)}`
18336
- );
18337
- warningMsg = `Settings file ${filePath} has invalid JSON. Your settings have been reset. Please fix the JSON in ${filePath} manually.`;
18338
- }
19437
+ const warningMsg = `Settings file ${filePath} has invalid JSON. Your settings have been reset.`;
18339
19438
  debugLogger3.warn(warningMsg);
19439
+ if (corruptedSaved) {
19440
+ try {
19441
+ fs6.writeFileSync(filePath, "{}", "utf-8");
19442
+ } catch {
19443
+ }
19444
+ }
18340
19445
  return {
18341
19446
  settings: {},
18342
- migrationWarnings: [warningMsg]
19447
+ migrationWarnings: [],
19448
+ corruptedPath: corruptedSaved ? corruptedPath : void 0,
19449
+ wasRecovered: false
18343
19450
  };
18344
19451
  }
18345
19452
  }
19453
+ const envCorruptedPath = process2.env[ENV_CORRUPTED_PATH];
19454
+ if ((opts.consumeCorruptionEnvVars ?? true) && envCorruptedPath && envCorruptedPath === corruptedPath && scope === "User" /* User */) {
19455
+ corruptedSaved = true;
19456
+ recoveredFromEnvVar = process2.env[ENV_WAS_RECOVERED] === "1";
19457
+ delete process2.env[ENV_CORRUPTED_PATH];
19458
+ delete process2.env[ENV_WAS_RECOVERED];
19459
+ }
18346
19460
  if (typeof rawSettings !== "object" || rawSettings === null || Array.isArray(rawSettings)) {
18347
19461
  settingsErrors.push({
18348
19462
  message: "Settings file is not a valid JSON object.",
@@ -18378,26 +19492,27 @@ function loadSettings(workspaceDir = process2.cwd()) {
18378
19492
  settingsObject = migrationResult.settings;
18379
19493
  migrationWarnings = migrationResult.warnings;
18380
19494
  persistSettingsObject("Error migrating settings file on disk");
18381
- } else if (hasLegacyNumericVersion || hasInvalidVersion) {
19495
+ } else if ((hasLegacyNumericVersion || hasInvalidVersion) && !corruptedSaved) {
18382
19496
  settingsObject[SETTINGS_VERSION_KEY] = SETTINGS_VERSION;
18383
19497
  debugLogger3.warn(
18384
19498
  `Settings version metadata in ${filePath} could not be migrated by any registered migration. Normalizing ${SETTINGS_VERSION_KEY} to ${SETTINGS_VERSION}.`
18385
19499
  );
18386
19500
  persistSettingsObject("Error normalizing settings version on disk");
18387
19501
  }
18388
- } else if (!hasVersionKey || hasInvalidVersion || hasLegacyNumericVersion) {
19502
+ } else if ((!hasVersionKey || hasInvalidVersion || hasLegacyNumericVersion) && !corruptedSaved) {
18389
19503
  settingsObject[SETTINGS_VERSION_KEY] = SETTINGS_VERSION;
18390
19504
  persistSettingsObject("Error normalizing settings version on disk");
18391
19505
  }
18392
- const allWarnings = [
18393
- ...recoveryWarning ? [recoveryWarning] : [],
18394
- ...migrationWarnings ?? []
18395
- ];
18396
- return {
19506
+ const result = {
18397
19507
  settings: settingsObject,
18398
19508
  rawJson: content,
18399
- migrationWarnings: allWarnings.length > 0 ? allWarnings : migrationWarnings
19509
+ migrationWarnings: migrationWarnings ?? []
18400
19510
  };
19511
+ if (corruptedSaved) {
19512
+ result.corruptedPath = corruptedPath;
19513
+ result.wasRecovered = recoveredFromBackup || (recoveredFromEnvVar ?? false);
19514
+ }
19515
+ return result;
18401
19516
  }
18402
19517
  } catch (error) {
18403
19518
  settingsErrors.push({
@@ -18429,10 +19544,20 @@ function loadSettings(workspaceDir = process2.cwd()) {
18429
19544
  );
18430
19545
  const userOriginalSettings = structuredClone(userResult.settings);
18431
19546
  const workspaceOriginalSettings = structuredClone(workspaceResult.settings);
18432
- systemSettings = resolveEnvVarsInObject(systemResult.settings);
18433
- systemDefaultSettings = resolveEnvVarsInObject(systemDefaultsResult.settings);
18434
- userSettings = resolveEnvVarsInObject(userResult.settings);
18435
- workspaceSettings = resolveEnvVarsInObject(workspaceResult.settings);
19547
+ const homeEnvFallback = getHomeEnvFallbackVars();
19548
+ systemSettings = resolveEnvVarsInObject(
19549
+ systemResult.settings,
19550
+ homeEnvFallback
19551
+ );
19552
+ systemDefaultSettings = resolveEnvVarsInObject(
19553
+ systemDefaultsResult.settings,
19554
+ homeEnvFallback
19555
+ );
19556
+ userSettings = resolveEnvVarsInObject(userResult.settings, homeEnvFallback);
19557
+ workspaceSettings = resolveEnvVarsInObject(
19558
+ workspaceResult.settings,
19559
+ homeEnvFallback
19560
+ );
18436
19561
  if (userSettings.ui?.theme === "VS") {
18437
19562
  userSettings.ui.theme = DefaultLight.name;
18438
19563
  } else if (userSettings.ui?.theme === "VS2015") {
@@ -18457,7 +19582,9 @@ function loadSettings(workspaceDir = process2.cwd()) {
18457
19582
  workspaceSettings,
18458
19583
  isTrusted
18459
19584
  );
18460
- loadEnvironment(tempMergedSettings);
19585
+ if (!opts.skipLoadEnvironment) {
19586
+ loadEnvironment(tempMergedSettings);
19587
+ }
18461
19588
  if (settingsErrors.length > 0) {
18462
19589
  const errorMessages = settingsErrors.map(
18463
19590
  (error) => `Error in ${error.path}: ${error.message}`
@@ -18501,7 +19628,9 @@ Please fix the configuration file(s) and try again.`
18501
19628
  },
18502
19629
  isTrusted,
18503
19630
  migratedInMemorScopes,
18504
- allMigrationWarnings
19631
+ allMigrationWarnings,
19632
+ userResult.corruptedPath,
19633
+ userResult.wasRecovered ?? false
18505
19634
  );
18506
19635
  }
18507
19636
  __name(loadSettings, "loadSettings");
@@ -18511,13 +19640,23 @@ function createSettingsUpdate(key, value) {
18511
19640
  return root;
18512
19641
  }
18513
19642
  __name(createSettingsUpdate, "createSettingsUpdate");
18514
- function saveSettings(settingsFile, updates = settingsFile.originalSettings) {
19643
+ function saveSettings(settingsFile, updates = settingsFile.originalSettings, replacePath = []) {
18515
19644
  try {
18516
- const dirPath = path3.dirname(settingsFile.path);
19645
+ const dirPath = path4.dirname(settingsFile.path);
18517
19646
  if (!fs6.existsSync(dirPath)) {
18518
19647
  fs6.mkdirSync(dirPath, { recursive: true });
18519
19648
  }
18520
- updateSettingsFilePreservingFormat(settingsFile.path, updates);
19649
+ const written = updateSettingsFilePreservingFormat(
19650
+ settingsFile.path,
19651
+ updates,
19652
+ false,
19653
+ replacePath
19654
+ );
19655
+ if (!written) {
19656
+ debugLogger3.error(
19657
+ `saveSettings: updateSettingsFilePreservingFormat returned false for ${settingsFile.path}`
19658
+ );
19659
+ }
18521
19660
  } catch (error) {
18522
19661
  debugLogger3.error("Error saving user settings file.");
18523
19662
  debugLogger3.error(error instanceof Error ? error.message : String(error));
@@ -18534,26 +19673,26 @@ init_esbuild_shims();
18534
19673
 
18535
19674
  // node_modules/read-package-up/index.js
18536
19675
  init_esbuild_shims();
18537
- import path6 from "node:path";
19676
+ import path7 from "node:path";
18538
19677
 
18539
19678
  // node_modules/find-up-simple/index.js
18540
19679
  init_esbuild_shims();
18541
19680
  import process3 from "node:process";
18542
19681
  import fsPromises from "node:fs/promises";
18543
19682
  import { fileURLToPath } from "node:url";
18544
- import path4 from "node:path";
19683
+ import path5 from "node:path";
18545
19684
  var toPath = /* @__PURE__ */ __name((urlOrPath) => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath, "toPath");
18546
19685
  async function findUp(name, {
18547
19686
  cwd = process3.cwd(),
18548
19687
  type = "file",
18549
19688
  stopAt
18550
19689
  } = {}) {
18551
- let directory = path4.resolve(toPath(cwd) ?? "");
18552
- const { root } = path4.parse(directory);
18553
- stopAt = path4.resolve(directory, toPath(stopAt ?? root));
18554
- const isAbsoluteName = path4.isAbsolute(name);
19690
+ let directory = path5.resolve(toPath(cwd) ?? "");
19691
+ const { root } = path5.parse(directory);
19692
+ stopAt = path5.resolve(directory, toPath(stopAt ?? root));
19693
+ const isAbsoluteName = path5.isAbsolute(name);
18555
19694
  while (directory) {
18556
- const filePath = isAbsoluteName ? name : path4.join(directory, name);
19695
+ const filePath = isAbsoluteName ? name : path5.join(directory, name);
18557
19696
  try {
18558
19697
  const stats = await fsPromises.stat(filePath);
18559
19698
  if (type === "file" && stats.isFile() || type === "directory" && stats.isDirectory()) {
@@ -18564,7 +19703,7 @@ async function findUp(name, {
18564
19703
  if (directory === stopAt || directory === root) {
18565
19704
  break;
18566
19705
  }
18567
- directory = path4.dirname(directory);
19706
+ directory = path5.dirname(directory);
18568
19707
  }
18569
19708
  }
18570
19709
  __name(findUp, "findUp");
@@ -18572,7 +19711,7 @@ __name(findUp, "findUp");
18572
19711
  // node_modules/read-pkg/index.js
18573
19712
  init_esbuild_shims();
18574
19713
  import fsPromises2 from "node:fs/promises";
18575
- import path5 from "node:path";
19714
+ import path6 from "node:path";
18576
19715
 
18577
19716
  // node_modules/parse-json/index.js
18578
19717
  init_esbuild_shims();
@@ -18711,7 +19850,7 @@ function toPath2(urlOrPath) {
18711
19850
  __name(toPath2, "toPath");
18712
19851
 
18713
19852
  // node_modules/read-pkg/index.js
18714
- var getPackagePath = /* @__PURE__ */ __name((cwd) => path5.resolve(toPath2(cwd) ?? ".", "package.json"), "getPackagePath");
19853
+ var getPackagePath = /* @__PURE__ */ __name((cwd) => path6.resolve(toPath2(cwd) ?? ".", "package.json"), "getPackagePath");
18715
19854
  var _readPackage = /* @__PURE__ */ __name((file, normalize3) => {
18716
19855
  const json = typeof file === "string" ? parseJson(file) : file;
18717
19856
  if (normalize3) {
@@ -18732,7 +19871,7 @@ async function readPackageUp(options) {
18732
19871
  return;
18733
19872
  }
18734
19873
  return {
18735
- packageJson: await readPackage({ ...options, cwd: path6.dirname(filePath) }),
19874
+ packageJson: await readPackage({ ...options, cwd: path7.dirname(filePath) }),
18736
19875
  path: filePath
18737
19876
  };
18738
19877
  }
@@ -18740,9 +19879,9 @@ __name(readPackageUp, "readPackageUp");
18740
19879
 
18741
19880
  // packages/cli/src/utils/package.ts
18742
19881
  import { fileURLToPath as fileURLToPath3 } from "node:url";
18743
- import path7 from "node:path";
19882
+ import path8 from "node:path";
18744
19883
  var __filename = fileURLToPath3(import.meta.url);
18745
- var __dirname = path7.dirname(__filename);
19884
+ var __dirname = path8.dirname(__filename);
18746
19885
  var packageJson;
18747
19886
  async function getPackageJson() {
18748
19887
  if (packageJson) {
@@ -18760,16 +19899,10 @@ __name(getPackageJson, "getPackageJson");
18760
19899
  // packages/cli/src/utils/version.ts
18761
19900
  async function getCliVersion() {
18762
19901
  const pkgJson = await getPackageJson();
18763
- return "0.16.1-termux";
19902
+ return "0.18.0-termux";
18764
19903
  }
18765
19904
  __name(getCliVersion, "getCliVersion");
18766
19905
 
18767
- // packages/cli/src/utils/systemInfo.ts
18768
- init_esbuild_shims();
18769
- import process4 from "node:process";
18770
- import os from "node:os";
18771
- import { execFile } from "node:child_process";
18772
-
18773
19906
  // packages/cli/src/ui/utils/formatters.ts
18774
19907
  init_esbuild_shims();
18775
19908
  var formatMemoryUsage = /* @__PURE__ */ __name((bytes) => {
@@ -18853,25 +19986,86 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds, options) => {
18853
19986
  return parts.join(" ");
18854
19987
  }, "formatDuration");
18855
19988
 
19989
+ // packages/cli/src/config/loadedSettingsAdapter.ts
19990
+ init_esbuild_shims();
19991
+ function createLoadedSettingsAdapter(settings, scope) {
19992
+ const persistScope = scope ?? getPersistScopeForModelSelection(settings);
19993
+ const settingsFile = settings.forScope(persistScope);
19994
+ let settingsSnapshot = null;
19995
+ let originalSnapshot = null;
19996
+ return {
19997
+ getValue(key) {
19998
+ return getNestedProperty(settings.merged, key);
19999
+ },
20000
+ setValue(key, value) {
20001
+ for (const part of key.split(".")) {
20002
+ if (part === "__proto__" || part === "constructor" || part === "prototype") {
20003
+ throw new Error(
20004
+ `Refusing to write settings key with reserved segment: ${key}`
20005
+ );
20006
+ }
20007
+ }
20008
+ settings.setValue(persistScope, key, value);
20009
+ },
20010
+ getModelProviders() {
20011
+ return settings.merged.modelProviders ?? {};
20012
+ },
20013
+ persist() {
20014
+ },
20015
+ backup() {
20016
+ backupSettingsFile(settingsFile.path);
20017
+ settingsSnapshot = structuredClone(settingsFile.settings);
20018
+ originalSnapshot = structuredClone(settingsFile.originalSettings);
20019
+ },
20020
+ restore() {
20021
+ const restored = restoreSettingsFromBackup(settingsFile.path);
20022
+ if (!restored) {
20023
+ console.error(
20024
+ `[loadedSettingsAdapter] On-disk rollback of ${settingsFile.path} failed; in-memory state was restored but the file may be inconsistent. Re-run /auth or inspect the file directly to recover.`
20025
+ );
20026
+ }
20027
+ if (settingsSnapshot !== null) {
20028
+ settingsFile.settings = settingsSnapshot;
20029
+ }
20030
+ if (originalSnapshot !== null) {
20031
+ settingsFile.originalSettings = originalSnapshot;
20032
+ }
20033
+ settings.recomputeMerged();
20034
+ },
20035
+ cleanupBackup() {
20036
+ cleanupSettingsBackup(settingsFile.path);
20037
+ settingsSnapshot = null;
20038
+ originalSnapshot = null;
20039
+ }
20040
+ };
20041
+ }
20042
+ __name(createLoadedSettingsAdapter, "createLoadedSettingsAdapter");
20043
+
20044
+ // packages/cli/src/utils/systemInfo.ts
20045
+ init_esbuild_shims();
20046
+ import process4 from "node:process";
20047
+ import os from "node:os";
20048
+ import { execFile } from "node:child_process";
20049
+
18856
20050
  // packages/cli/src/generated/git-commit.ts
18857
20051
  init_esbuild_shims();
18858
- var GIT_COMMIT_INFO = "5fd0fd640";
20052
+ var GIT_COMMIT_INFO = "b74e9dbb4";
18859
20053
 
18860
20054
  // packages/cli/src/utils/systemInfo.ts
18861
20055
  var debugLogger4 = createDebugLogger("STATUS");
18862
20056
  var VERSION_PROBE_TIMEOUT_MS = 5e3;
18863
20057
  function probeVersion(binary) {
18864
- return new Promise((resolve2) => {
20058
+ return new Promise((resolve3) => {
18865
20059
  execFile(
18866
20060
  binary,
18867
20061
  ["--version"],
18868
20062
  { timeout: VERSION_PROBE_TIMEOUT_MS, encoding: "utf-8" },
18869
20063
  (err, stdout) => {
18870
20064
  if (err) {
18871
- resolve2("unknown");
20065
+ resolve3("unknown");
18872
20066
  return;
18873
20067
  }
18874
- resolve2(typeof stdout === "string" ? stdout.trim() : "unknown");
20068
+ resolve3(typeof stdout === "string" ? stdout.trim() : "unknown");
18875
20069
  }
18876
20070
  );
18877
20071
  });
@@ -19009,6 +20203,9 @@ __name(formatLspStatusSnapshot, "formatLspStatusSnapshot");
19009
20203
 
19010
20204
  export {
19011
20205
  require_strip_json_comments,
20206
+ resolveColor,
20207
+ subtleBandColor,
20208
+ supportsTrueColor,
19012
20209
  lightTheme,
19013
20210
  darkTheme,
19014
20211
  ansiTheme,
@@ -19018,13 +20215,16 @@ export {
19018
20215
  DefaultLight,
19019
20216
  DefaultDark,
19020
20217
  loadTrustedFolders,
20218
+ isFolderTrustEnabled,
19021
20219
  isWorkspaceTrusted,
19022
20220
  getPersistScopeForModelSelection,
19023
20221
  TOGGLE_TYPES,
19024
20222
  OUTPUT_LANGUAGE_AUTO,
19025
20223
  isAutoLanguage,
19026
20224
  resolveOutputLanguage,
20225
+ getOutputLanguageFilePath,
19027
20226
  updateOutputLanguageFile,
20227
+ writeOutputLanguageAndRegisterPath,
19028
20228
  initializeLlmOutputLanguage,
19029
20229
  getSettingDefinition,
19030
20230
  requiresRestart,
@@ -19040,16 +20240,17 @@ export {
19040
20240
  saveModifiedSettings,
19041
20241
  getDisplayValue,
19042
20242
  isDefaultValue,
19043
- backupSettingsFile,
19044
- restoreSettingsFromBackup,
19045
- cleanupSettingsBackup,
19046
20243
  SETTINGS_DIRECTORY_NAME,
19047
20244
  getUserSettingsDir,
20245
+ ENV_CORRUPTED_PATH,
20246
+ ENV_WAS_RECOVERED,
19048
20247
  SettingScope,
19049
20248
  getSettingsWarnings,
19050
20249
  createMinimalSettings,
19051
20250
  preResolveHomeEnvOverrides,
19052
20251
  loadEnvironment,
20252
+ reloadEnvironment,
20253
+ CORRUPTED_SUFFIX,
19053
20254
  loadSettings,
19054
20255
  require_debug,
19055
20256
  require_constants,
@@ -19066,6 +20267,30 @@ export {
19066
20267
  DEFAULT_RING_SIZE,
19067
20268
  SubscriberLimitExceededError,
19068
20269
  EventBus,
20270
+ canonicalizeWorkspace,
20271
+ MAX_WORKSPACE_PATH_LENGTH,
20272
+ NOT_CURRENTLY_GENERATING_CANCEL_MESSAGE,
20273
+ isNotCurrentlyGeneratingCancelError,
20274
+ SessionNotFoundError,
20275
+ RestoreInProgressError,
20276
+ InvalidSessionScopeError,
20277
+ SessionLimitExceededError,
20278
+ WorkspaceMismatchError,
20279
+ InvalidClientIdError,
20280
+ InvalidPermissionOptionError,
20281
+ InvalidSessionMetadataError,
20282
+ PermissionPolicyNotImplementedError,
20283
+ CancelSentinelCollisionError,
20284
+ PermissionForbiddenError,
20285
+ WorkspaceInitConflictError,
20286
+ WorkspaceInitPathEscapeError,
20287
+ WorkspaceInitSymlinkError,
20288
+ WorkspaceInitRaceError,
20289
+ McpServerNotFoundError,
20290
+ McpServerRestartFailedError,
20291
+ SessionBusyError,
20292
+ InvalidRewindTargetError,
20293
+ BranchWhilePromptActiveError,
19069
20294
  STATUS_SCHEMA_VERSION,
19070
20295
  SERVE_ERROR_KINDS,
19071
20296
  BridgeTimeoutError,
@@ -19073,6 +20298,9 @@ export {
19073
20298
  MissingCliEntryError,
19074
20299
  SERVE_STATUS_EXT_METHODS,
19075
20300
  SERVE_CONTROL_EXT_METHODS,
20301
+ IDLE_HOOK_EVENTS,
20302
+ createIdleWorkspaceExtensionsStatus,
20303
+ createIdleWorkspaceHooksStatus,
19076
20304
  createIdleWorkspaceMemoryStatus,
19077
20305
  createIdleWorkspaceMcpStatus,
19078
20306
  createIdleWorkspaceSkillsStatus,
@@ -19087,7 +20315,8 @@ export {
19087
20315
  formatDuration,
19088
20316
  getNpmVersion,
19089
20317
  getGitVersion,
19090
- getExtendedSystemInfo
20318
+ getExtendedSystemInfo,
20319
+ createLoadedSettingsAdapter
19091
20320
  };
19092
20321
  /**
19093
20322
  * @license
@@ -19104,6 +20333,18 @@ export {
19104
20333
  * Copyright 2025 Google LLC
19105
20334
  * SPDX-License-Identifier: Apache-2.0
19106
20335
  */
20336
+ /**
20337
+ * @license
20338
+ * Copyright 2025 Qwen Team
20339
+ * SPDX-License-Identifier: Apache-2.0
20340
+ *
20341
+ * Adapter that lets core's `applyProviderInstallPlan` write through
20342
+ * `LoadedSettings` while preserving CLI-specific guarantees:
20343
+ * - scope resolution via `getPersistScopeForModelSelection`
20344
+ * - on-disk `.orig` backup of the target settings file
20345
+ * - in-memory snapshot of `settings` / `originalSettings` for rollback
20346
+ * - merged-settings recomputation after restore
20347
+ */
19107
20348
  /**
19108
20349
  * @license
19109
20350
  * Copyright 2026 Google LLC