@qwen-code/qwen-code 0.19.7 → 0.19.8-nightly.20260710.205430235

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 (292) hide show
  1. package/bundled/qc-helper/SKILL.md +1 -0
  2. package/bundled/qc-helper/docs/configuration/auth.md +40 -55
  3. package/bundled/qc-helper/docs/configuration/model-providers.md +224 -218
  4. package/bundled/qc-helper/docs/configuration/settings.md +43 -36
  5. package/bundled/qc-helper/docs/features/_meta.ts +1 -0
  6. package/bundled/qc-helper/docs/features/channels/overview.md +20 -12
  7. package/bundled/qc-helper/docs/features/channels/plugins.md +1 -0
  8. package/bundled/qc-helper/docs/features/code-review.md +2 -1
  9. package/bundled/qc-helper/docs/features/commands.md +39 -38
  10. package/bundled/qc-helper/docs/features/computer-use.md +77 -0
  11. package/bundled/qc-helper/docs/features/hooks.md +36 -34
  12. package/bundled/qc-helper/docs/features/memory.md +1 -1
  13. package/bundled/qc-helper/docs/features/tool-use-summaries.md +19 -23
  14. package/bundled/qc-helper/docs/qwen-serve.md +22 -12
  15. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +1 -1
  16. package/bundled/review/DESIGN.md +14 -13
  17. package/bundled/review/SKILL.md +38 -61
  18. package/chunks/{MaxSizedBox-XY5LIO5O.js → MaxSizedBox-LOFYQFYJ.js} +13 -14
  19. package/chunks/{StandaloneSessionPicker-APISIRJZ.js → StandaloneSessionPicker-U5OQBGEB.js} +31 -29
  20. package/chunks/{acpAgent-MMOSC2YA.js → acpAgent-SDIFRIED.js} +637 -131
  21. package/chunks/{agent-TKIBLLQT.js → agent-JIBBVHNQ.js} +10 -10
  22. package/chunks/{agent-headless-VLX4C7KX.js → agent-headless-6LGZYJYU.js} +10 -10
  23. package/chunks/{anthropicContentGenerator-AKYPSZIV.js → anthropicContentGenerator-55REPTTF.js} +30 -3
  24. package/chunks/{artifact-tool-D233YJFH.js → artifact-tool-EIN46DPM.js} +1 -1
  25. package/chunks/{askUserQuestion-MKL5ZTMC.js → askUserQuestion-6YX6ZRX7.js} +1 -1
  26. package/chunks/{bridge-BCU73DZO.js → bridge-HVPFYNM4.js} +17 -16
  27. package/chunks/{ca-HCMB2I54.js → ca-MULEGDVS.js} +89 -5
  28. package/chunks/{channel-worker-supervisor-CRCVYQIE.js → channel-worker-supervisor-OPXXT4JK.js} +20 -3
  29. package/chunks/{chunk-DGHJTO2K.js → chunk-2AF26HVM.js} +31 -2
  30. package/chunks/{chunk-3B26UVCX.js → chunk-2GUVUHJY.js} +6 -4
  31. package/chunks/{chunk-FV7425LN.js → chunk-2SZOMGOR.js} +4 -1
  32. package/chunks/{chunk-CNSF3WO5.js → chunk-32KS5XSX.js} +3 -3
  33. package/chunks/{chunk-4UCTWSTP.js → chunk-34UUM3IN.js} +1 -1
  34. package/chunks/{chunk-G7ZG7CA6.js → chunk-3UP777ZS.js} +8 -7
  35. package/chunks/{chunk-MIG5SQNL.js → chunk-4CSVIZLT.js} +4 -4
  36. package/chunks/{chunk-GD236YPV.js → chunk-4ONWIT5C.js} +1 -1
  37. package/chunks/{chunk-4ZJIPVPB.js → chunk-4XK7TNBP.js} +8 -8
  38. package/chunks/{chunk-I4A4K72C.js → chunk-5F2H3PXG.js} +446 -232
  39. package/chunks/chunk-5HOF2K5U.js +19 -0
  40. package/chunks/{chunk-GMOWQOQQ.js → chunk-5ZVIYNLN.js} +228 -36
  41. package/chunks/chunk-6O6Z2I5Q.js +292 -0
  42. package/chunks/{chunk-RYFZCUJO.js → chunk-6QKT5VNZ.js} +14 -6
  43. package/chunks/{chunk-SD4N3QJ2.js → chunk-6ZPSVWLF.js} +61 -17
  44. package/chunks/{chunk-X265R5C6.js → chunk-7YGSDQ5J.js} +2 -2
  45. package/chunks/{chunk-PRDFOIZF.js → chunk-A6KEUFJO.js} +32 -5
  46. package/chunks/{chunk-OWVIH4HY.js → chunk-B5OAMPJ5.js} +389 -87
  47. package/chunks/{chunk-ME3YSROJ.js → chunk-CV2AT2WJ.js} +22 -10
  48. package/chunks/{chunk-U4FRHCLA.js → chunk-DDKUYKHA.js} +1912 -201
  49. package/chunks/{chunk-YDSYD7UI.js → chunk-E3SA2LY4.js} +2 -2
  50. package/chunks/{chunk-6IAWPIQ6.js → chunk-EDM5O3SX.js} +2 -2
  51. package/chunks/{chunk-CISB3IQF.js → chunk-FONJQQWI.js} +65 -6
  52. package/chunks/{chunk-FRFFNYUY.js → chunk-G3WIMNL4.js} +3 -3
  53. package/chunks/{chunk-B34OV7K2.js → chunk-GGQQA4JW.js} +13 -0
  54. package/chunks/chunk-GLE2YUPU.js +34 -0
  55. package/chunks/{chunk-MJI36HER.js → chunk-GOTMC3BX.js} +1 -1
  56. package/chunks/{chunk-RFIL6REB.js → chunk-GRB4QSBD.js} +168 -31
  57. package/chunks/chunk-GVVY7GSP.js +38 -0
  58. package/chunks/{chunk-7JGISHHZ.js → chunk-HDEUQRAR.js} +14 -156
  59. package/chunks/{chunk-NZEGNV4V.js → chunk-HPRI22FZ.js} +6 -6
  60. package/chunks/{chunk-STAZRKOT.js → chunk-I34IHZFJ.js} +117 -459
  61. package/chunks/{chunk-JF7DFPQ5.js → chunk-I3MBKL6Z.js} +12 -2
  62. package/chunks/{chunk-DNV4FSN5.js → chunk-I5XN6KDI.js} +21 -4
  63. package/chunks/{chunk-VZ7HY3YU.js → chunk-IAMRWMFU.js} +1 -1
  64. package/chunks/{chunk-44NROQYV.js → chunk-JOQMY62N.js} +1 -1
  65. package/chunks/{chunk-VQWAZSXN.js → chunk-JW4IKIZ2.js} +57 -35
  66. package/chunks/{chunk-SAIILPQ3.js → chunk-KJMYXFUR.js} +3 -1
  67. package/chunks/{chunk-AFOLR6YL.js → chunk-KQ6MKCFE.js} +102 -16
  68. package/chunks/{chunk-X3YGAX7V.js → chunk-KS2FRTYI.js} +2 -0
  69. package/chunks/{chunk-IUE7YWC3.js → chunk-LE7EF36E.js} +7 -7
  70. package/chunks/{chunk-B4U2M63D.js → chunk-LRY7HD3Q.js} +2101 -11
  71. package/chunks/{chunk-PUQLHSQ2.js → chunk-ME7E6WZB.js} +6 -8
  72. package/chunks/{chunk-LEIJKM7Q.js → chunk-MEK7ZRJ3.js} +1 -1
  73. package/chunks/{chunk-AJBEAUIS.js → chunk-MG2TNCRX.js} +4 -3
  74. package/chunks/{chunk-GL5TV7B5.js → chunk-MSMQURDV.js} +21 -5
  75. package/chunks/{chunk-6BN7NZ5Z.js → chunk-NXDJLKKX.js} +4 -6
  76. package/chunks/{chunk-FEJ2FZ3U.js → chunk-NY2ZOFMM.js} +1 -1
  77. package/chunks/{chunk-QZF5U5KA.js → chunk-NY5BE643.js} +8 -8
  78. package/chunks/{chunk-4RQIB5UZ.js → chunk-O2YT7VB4.js} +0 -34
  79. package/chunks/{chunk-4KJ2BPIT.js → chunk-OACJLMLD.js} +2 -38
  80. package/chunks/chunk-PCWSPWXZ.js +168 -0
  81. package/chunks/{chunk-XPJH4PKR.js → chunk-PJ74K3DH.js} +1 -1
  82. package/chunks/{chunk-FTFXDZYI.js → chunk-PW7VWRLX.js} +45 -29
  83. package/chunks/chunk-R3SLDK6Y.js +468 -0
  84. package/chunks/{chunk-4O344UEE.js → chunk-SDJOZOYY.js} +38 -18
  85. package/chunks/{chunk-ALZ75L2X.js → chunk-SMYIBRAA.js} +412 -376
  86. package/chunks/{chunk-CCGOFQV3.js → chunk-SS5P6JM6.js} +6 -5
  87. package/chunks/{chunk-AIY5UTFI.js → chunk-T3XHYGMG.js} +925 -2872
  88. package/chunks/{chunk-Q6OEPOOC.js → chunk-TB6GWNV4.js} +1 -1
  89. package/chunks/{chunk-24XYI5EI.js → chunk-TERKDCOZ.js} +3 -3
  90. package/chunks/chunk-TVO5C767.js +159 -0
  91. package/chunks/{chunk-TBAZMRW3.js → chunk-TVW53EK7.js} +1 -1
  92. package/chunks/chunk-TX5QZYK6.js +296 -0
  93. package/chunks/{chunk-JD33UY7E.js → chunk-TZRVTPJ6.js} +15 -9
  94. package/chunks/{chunk-65CFHNSE.js → chunk-UAFB2DNB.js} +59 -59
  95. package/chunks/{chunk-QAKFYMJI.js → chunk-UOXLB2LY.js} +152 -17
  96. package/chunks/chunk-V35MD7KN.js +13 -0
  97. package/chunks/{chunk-XSAFNANZ.js → chunk-VWDJHVXM.js} +12 -12
  98. package/chunks/{chunk-XISQIIT7.js → chunk-W77ZLCSX.js} +1 -1
  99. package/chunks/{chunk-BWVQN2HV.js → chunk-WTEIUA2V.js} +4 -4
  100. package/chunks/{chunk-TDGF35EN.js → chunk-XOHNA2S6.js} +1 -1
  101. package/chunks/{chunk-HJ3GX3Y3.js → chunk-XZVUZSDG.js} +25 -11
  102. package/chunks/{chunk-ADZG46HR.js → chunk-YHGCTQG3.js} +1 -1
  103. package/chunks/{chunk-2NPS2UDH.js → chunk-YUNPEB3Q.js} +478 -43
  104. package/chunks/chunk-Z3I3QJK3.js +47 -0
  105. package/chunks/{chunk-P7I3D7FM.js → chunk-Z466FBSA.js} +1 -1
  106. package/chunks/{chunk-YEGT55NW.js → chunk-ZDAZSR2O.js} +3009 -1220
  107. package/chunks/{chunk-VEB3NYSO.js → chunk-ZJQBTFJ6.js} +6 -1
  108. package/chunks/chunk-ZL5HN75Q.js +61 -0
  109. package/chunks/{computer-use-X4KUU3NM.js → computer-use-IW5XBECT.js} +10 -10
  110. package/chunks/{contextCommand-LAYJZF7H.js → contextCommand-4QPLK2SH.js} +14 -14
  111. package/chunks/create-sub-session-7JK3EYWA.js +212 -0
  112. package/chunks/create-sub-session-EVYZYAE3.js +364 -0
  113. package/chunks/{cron-create-JSXEIPVS.js → cron-create-2CCO2PW6.js} +2 -2
  114. package/chunks/{cron-delete-OIFVEPGU.js → cron-delete-ETVTP5IV.js} +2 -2
  115. package/chunks/{cron-list-D4ZX4IOE.js → cron-list-FS3KWOY5.js} +2 -2
  116. package/chunks/{daemon-F3I2RXP6.js → daemon-NNUYIBWA.js} +461 -0
  117. package/chunks/{daemon-status-provider-XSAFKVDS.js → daemon-status-provider-3EPG6BXX.js} +21 -19
  118. package/chunks/{de-PLLFDERI.js → de-QRG6J2CM.js} +89 -5
  119. package/chunks/{dist-YTRKAVUB.js → dist-3EIIFOJV.js} +1 -1
  120. package/chunks/{dist-PKFTNUHO.js → dist-7F5GWZDZ.js} +2 -1
  121. package/chunks/{dist-FQ5WRJPL.js → dist-CBJ7OJ5R.js} +2 -2
  122. package/chunks/{dist-OT7G2WNM.js → dist-LIFJ2YAI.js} +1 -1
  123. package/chunks/{dist-573HNSVO.js → dist-OKXOQ63L.js} +2 -1
  124. package/chunks/{dist-IMFFBMAT.js → dist-SU5LY5R4.js} +3 -1
  125. package/chunks/{earlyInputCapture-AERYYGXE.js → earlyInputCapture-HP5XAS7A.js} +10 -10
  126. package/chunks/{edit-WZTZDGCI.js → edit-MDICC6KH.js} +11 -11
  127. package/chunks/{en-GA2RMXY5.js → en-HF3KFWZG.js} +91 -5
  128. package/chunks/{enter-worktree-DEPXBJEL.js → enter-worktree-JWTRNEN4.js} +10 -10
  129. package/chunks/{enterPlanMode-JFGXZHHJ.js → enterPlanMode-GMRZMTBQ.js} +10 -10
  130. package/chunks/environment-2CJAFOFN.js +88 -0
  131. package/chunks/{errors-GMZL4QV7.js → errors-UZOVFD2U.js} +13 -13
  132. package/chunks/{exit-worktree-Y7XBK3VV.js → exit-worktree-QQGEG343.js} +10 -10
  133. package/chunks/{exitPlanMode-WQQER65F.js → exitPlanMode-YK2JVAAB.js} +10 -10
  134. package/chunks/{fast-path-W2U6XDNO.js → fast-path-6SD4JNQW.js} +12 -3
  135. package/chunks/{fast-path-settings-RCRXH2JG.js → fast-path-settings-RAQGCIT7.js} +3 -2
  136. package/chunks/{fr-GWNQG4XH.js → fr-RSCO6HHD.js} +89 -5
  137. package/chunks/{gemini-T4WX6SRW.js → gemini-TFQXPUZB.js} +436 -140
  138. package/chunks/{geminiContentGenerator-MKQACXEJ.js → geminiContentGenerator-LJ2BNXHX.js} +1 -1
  139. package/chunks/{glob-4KKSHZDF.js → glob-3IJ6JR5W.js} +10 -10
  140. package/chunks/{grep-GHRYXSLZ.js → grep-UFZ2RFQZ.js} +10 -10
  141. package/chunks/{handleAutoUpdate-HN7ZOSXY.js → handleAutoUpdate-TEZC5ZIR.js} +17 -13
  142. package/chunks/i18n-5QEODTJV.js +84 -0
  143. package/chunks/{initializer-SRN3IM42.js → initializer-222MPCLQ.js} +18 -16
  144. package/chunks/installationInfo-OZ62OHZ2.js +65 -0
  145. package/chunks/{ja-2HOTA47X.js → ja-RRFGG2DC.js} +89 -5
  146. package/chunks/{list-INTVXUPA.js → list-BN5VBIIE.js} +20 -18
  147. package/chunks/{loadedSettingsAdapter-QVHHQPGM.js → loadedSettingsAdapter-EHTUJRFB.js} +18 -16
  148. package/chunks/{loop-wakeup-OHWEMFP5.js → loop-wakeup-SR2KWT4B.js} +3 -3
  149. package/chunks/{ls-L654WOAT.js → ls-RUBQK5Q2.js} +2 -2
  150. package/chunks/{lsp-M35KE54Y.js → lsp-DUTVY2ZA.js} +3 -5
  151. package/chunks/{mcp-7V4T46RG.js → mcp-OPGHD26Y.js} +18 -16
  152. package/chunks/{monitor-464OY2UE.js → monitor-WXBDVYYV.js} +10 -10
  153. package/chunks/{nonInteractiveCli-LJEEODU2.js → nonInteractiveCli-CWIBGJ4U.js} +54 -49
  154. package/chunks/{notebook-edit-BLJYCNDO.js → notebook-edit-T7P7M73F.js} +11 -11
  155. package/chunks/{openaiContentGenerator-PFF6HYB2.js → openaiContentGenerator-OES264C3.js} +7 -7
  156. package/chunks/{pidfile-LIBUENIV.js → pidfile-LJ3NLS2P.js} +10 -10
  157. package/chunks/{pt-2THT3YHA.js → pt-D4CG46JM.js} +89 -5
  158. package/chunks/{qwenContentGenerator-SUUHZ6CR.js → qwenContentGenerator-QJ67LAJ5.js} +12 -12
  159. package/chunks/{read-file-L7TBQVX7.js → read-file-KZD7TLU7.js} +5 -5
  160. package/chunks/{read-mcp-resource-CNQHBSJM.js → read-mcp-resource-Q56IMYOH.js} +1 -1
  161. package/chunks/{record-artifact-PP3LKHTS.js → record-artifact-GZ5D5HZX.js} +4 -4
  162. package/chunks/{ripGrep-CKKX3GRB.js → ripGrep-KUJLX75U.js} +10 -10
  163. package/chunks/{ru-Z67YJHBG.js → ru-O2QUEL22.js} +89 -5
  164. package/chunks/{run-qwen-serve-5OKADVLE.js → run-qwen-serve-M52KVRGI.js} +664 -153
  165. package/chunks/{scheduler-ZRW3AIDU.js → scheduler-FFATTAYZ.js} +10 -10
  166. package/chunks/{send-message-OA6MV4EU.js → send-message-HAGK3VTV.js} +2 -2
  167. package/chunks/{serve-36WS32W6.js → serve-B5S32524.js} +21 -18
  168. package/chunks/{server-M372UENX.js → server-6HK5FJMR.js} +3301 -665
  169. package/chunks/{session-F5KSNP2N.js → session-3WB76VTQ.js} +55 -50
  170. package/chunks/{settings-WFLNS3WT.js → settings-W3IX7NHK.js} +27 -23
  171. package/chunks/{shell-DEDSWN56.js → shell-HZIU2ZG7.js} +10 -10
  172. package/chunks/{skill-A2TL2NPC.js → skill-34OUFB65.js} +5 -5
  173. package/chunks/{spawnChannel-RQHUWTCL.js → spawnChannel-FTZJ3I5O.js} +12 -12
  174. package/chunks/{src-XKZMNHXS.js → src-NELBIIGI.js} +48 -10
  175. package/chunks/standalone-update-LICI2VSK.js +79 -0
  176. package/chunks/{startInteractiveUI-REKSTOHU.js → startInteractiveUI-LZEV5YI2.js} +2203 -1764
  177. package/chunks/stdioHelpers-CA7MG65Z.js +14 -0
  178. package/chunks/{syntheticOutput-F7LSDCAR.js → syntheticOutput-XFFJVCGV.js} +2 -2
  179. package/chunks/{task-create-RPFZNB4B.js → task-create-VINUSVBF.js} +3 -3
  180. package/chunks/{task-list-TGGJX7EA.js → task-list-YZ2AWQEG.js} +1 -1
  181. package/chunks/{task-stop-W7NGTMYQ.js → task-stop-PEXPKUW3.js} +1 -1
  182. package/chunks/{task-update-5WUG5MVQ.js → task-update-BHIX57YH.js} +3 -3
  183. package/chunks/{team-create-TBQVWAG7.js → team-create-2JS2OYSF.js} +10 -10
  184. package/chunks/{team-delete-UHQQ2QQX.js → team-delete-2OHXSBVS.js} +1 -1
  185. package/chunks/{team-plan-approval-FZPGUSHJ.js → team-plan-approval-PHLGYUY7.js} +10 -10
  186. package/chunks/{theme-manager-DQZVNSOC.js → theme-manager-UYXLX37P.js} +10 -10
  187. package/chunks/{todoWrite-C4ZAMSR3.js → todoWrite-7Q4ELT4F.js} +1 -1
  188. package/chunks/{tool-search-FDQ3SLNJ.js → tool-search-2MWA3GWE.js} +6 -6
  189. package/chunks/total-session-admission-PRZK35X4.js +72 -0
  190. package/chunks/{trustedFolders-Z475EIHL.js → trustedFolders-IT4JBNPG.js} +12 -12
  191. package/chunks/{updateCheck-E2ZX7RL7.js → updateCheck-X3ZWDO3Z.js} +17 -13
  192. package/chunks/updateEventEmitter-NXWTRHXY.js +10 -0
  193. package/chunks/{validateNonInterActiveAuth-O4ECBHQL.js → validateNonInterActiveAuth-IAOL7CM3.js} +51 -45
  194. package/chunks/{version-CEDD6ZZR.js → version-25QF6A5H.js} +1 -1
  195. package/chunks/{web-fetch-UYGMOHW4.js → web-fetch-I7FOWHGA.js} +2 -2
  196. package/chunks/{workflow-CQQ4J4I6.js → workflow-LZZ5U3IT.js} +11 -11
  197. package/chunks/{workspace-providers-status-MVYXMYDG.js → workspace-providers-status-7DTOAWEL.js} +21 -18
  198. package/chunks/workspace-registry-BBIPESIZ.js +76 -0
  199. package/chunks/{workspace-service-OMBR6ZLG.js → workspace-service-SY3P3FUY.js} +25 -23
  200. package/chunks/{workspace-skills-status-IMMQ7CAY.js → workspace-skills-status-GTT2A4WN.js} +20 -18
  201. package/chunks/{write-file-VWGY7AJP.js → write-file-M6IHNW3V.js} +11 -11
  202. package/chunks/{zh-7XVVRTDH.js → zh-K2EH6BDD.js} +91 -5
  203. package/chunks/{zh-TW-DPH554OG.js → zh-TW-4GPXJ7ZY.js} +91 -5
  204. package/cli.js +13 -12
  205. package/locales/ca.js +115 -7
  206. package/locales/de.js +114 -7
  207. package/locales/en.js +118 -7
  208. package/locales/fr.js +115 -7
  209. package/locales/ja.js +116 -6
  210. package/locales/pt.js +114 -7
  211. package/locales/ru.js +114 -7
  212. package/locales/zh-TW.js +114 -6
  213. package/locales/zh.js +114 -6
  214. package/package.json +3 -6
  215. package/web-shell/assets/{arc-C7hjaa7g.js → arc-G3HZaqaL.js} +1 -1
  216. package/web-shell/assets/{architectureDiagram-3BPJPVTR-pm9KtMZY.js → architectureDiagram-3BPJPVTR-DhBrwwch.js} +1 -1
  217. package/web-shell/assets/{blockDiagram-GPEHLZMM-CApElKsU.js → blockDiagram-GPEHLZMM-16JbbF0N.js} +1 -1
  218. package/web-shell/assets/{c4Diagram-AAUBKEIU-BeDe0-9N.js → c4Diagram-AAUBKEIU-DQ3-pKgc.js} +1 -1
  219. package/web-shell/assets/channel-CX7ZHuuL.js +1 -0
  220. package/web-shell/assets/{chunk-2J33WTMH-DJEkmLdl.js → chunk-2J33WTMH-ERCn30sp.js} +1 -1
  221. package/web-shell/assets/{chunk-4BX2VUAB-DXX8gdpe.js → chunk-4BX2VUAB-DTysfbFi.js} +1 -1
  222. package/web-shell/assets/{chunk-55IACEB6-DORmk1kQ.js → chunk-55IACEB6-BFGrbTBi.js} +1 -1
  223. package/web-shell/assets/{chunk-727SXJPM-DWmO4mCZ.js → chunk-727SXJPM-DCX4Oar-.js} +1 -1
  224. package/web-shell/assets/{chunk-AQP2D5EJ-C7LRaYw2.js → chunk-AQP2D5EJ-CgT6sBr3.js} +1 -1
  225. package/web-shell/assets/{chunk-FMBD7UC4-CCdXgyC5.js → chunk-FMBD7UC4-C1Uuk1KV.js} +1 -1
  226. package/web-shell/assets/{chunk-ND2GUHAM-SyL_xvWc.js → chunk-ND2GUHAM-DajgESiu.js} +1 -1
  227. package/web-shell/assets/{chunk-QZHKN3VN-BzOuCKxa.js → chunk-QZHKN3VN-DLJSvy9X.js} +1 -1
  228. package/web-shell/assets/classDiagram-4FO5ZUOK-B-oT3UI8.js +1 -0
  229. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-B-oT3UI8.js +1 -0
  230. package/web-shell/assets/{cose-bilkent-S5V4N54A-BMPWyDKc.js → cose-bilkent-S5V4N54A-CH3w3qs7.js} +1 -1
  231. package/web-shell/assets/{dagre-BM42HDAG-B_GnPWik.js → dagre-BM42HDAG-BloXan9B.js} +1 -1
  232. package/web-shell/assets/{diagram-2AECGRRQ-fJqMc3S_.js → diagram-2AECGRRQ-BbZiGcmK.js} +1 -1
  233. package/web-shell/assets/{diagram-5GNKFQAL-ximV3O9D.js → diagram-5GNKFQAL-GQlYvLJv.js} +1 -1
  234. package/web-shell/assets/{diagram-KO2AKTUF-2vVyjzqw.js → diagram-KO2AKTUF-CtIBvVq3.js} +1 -1
  235. package/web-shell/assets/{diagram-LMA3HP47-Dckcx1sT.js → diagram-LMA3HP47-D5TBo9a2.js} +1 -1
  236. package/web-shell/assets/{diagram-OG6HWLK6-BAVv47ga.js → diagram-OG6HWLK6-N0gQhw6R.js} +1 -1
  237. package/web-shell/assets/{erDiagram-TEJ5UH35-Bn3nf5J0.js → erDiagram-TEJ5UH35-zab9vDj3.js} +1 -1
  238. package/web-shell/assets/{flowDiagram-I6XJVG4X-BIbGF9JT.js → flowDiagram-I6XJVG4X-BnnjtWJa.js} +1 -1
  239. package/web-shell/assets/{ganttDiagram-6RSMTGT7-CDbhb3AH.js → ganttDiagram-6RSMTGT7-2T0SQU4f.js} +1 -1
  240. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-CbKG1a_w.js → gitGraphDiagram-PVQCEYII-DAD6_que.js} +1 -1
  241. package/web-shell/assets/index-XLkWfLja.css +5 -0
  242. package/web-shell/assets/index-srlTR1Jg.js +786 -0
  243. package/web-shell/assets/{infoDiagram-5YYISTIA-DUFxTy8m.js → infoDiagram-5YYISTIA-C-j8d0xO.js} +1 -1
  244. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-D69hrBG8.js → ishikawaDiagram-YF4QCWOH-D97bAKoT.js} +1 -1
  245. package/web-shell/assets/{journeyDiagram-JHISSGLW-DsvEw51Y.js → journeyDiagram-JHISSGLW-BJAHfJmm.js} +1 -1
  246. package/web-shell/assets/{kanban-definition-UN3LZRKU-lFFjZEYd.js → kanban-definition-UN3LZRKU-CZgR5aac.js} +1 -1
  247. package/web-shell/assets/{linear-Bo5bWzvo.js → linear-DOd4kYhA.js} +1 -1
  248. package/web-shell/assets/{mermaid.core-C_HKMJx5.js → mermaid.core-BBaplnXA.js} +5 -5
  249. package/web-shell/assets/{mindmap-definition-RKZ34NQL-DlV-NUTs.js → mindmap-definition-RKZ34NQL-IhBF_BR5.js} +1 -1
  250. package/web-shell/assets/{pieDiagram-4H26LBE5-B2e6FH2a.js → pieDiagram-4H26LBE5-B4R4sYyH.js} +1 -1
  251. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-D75kSk-b.js → quadrantDiagram-W4KKPZXB-DKd1SJ61.js} +1 -1
  252. package/web-shell/assets/{requirementDiagram-4Y6WPE33-CQ6xakhM.js → requirementDiagram-4Y6WPE33-Cw96V0Xb.js} +1 -1
  253. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-J_XTKrcY.js → sankeyDiagram-5OEKKPKP-C6ne_yWi.js} +1 -1
  254. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-D7jTcBtf.js → sequenceDiagram-3UESZ5HK-CCyp4PDp.js} +1 -1
  255. package/web-shell/assets/{stateDiagram-AJRCARHV-CrlM_OT3.js → stateDiagram-AJRCARHV-DHvIqTmx.js} +1 -1
  256. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DvFhmpwA.js +1 -0
  257. package/web-shell/assets/{timeline-definition-PNZ67QCA-5oZi76Ef.js → timeline-definition-PNZ67QCA-amb3n9zH.js} +1 -1
  258. package/web-shell/assets/{vennDiagram-CIIHVFJN-DO5YptPK.js → vennDiagram-CIIHVFJN-Abf2qRFJ.js} +1 -1
  259. package/web-shell/assets/{wardley-L42UT6IY-4t1eJDvM.js → wardley-L42UT6IY-BBlOp1av.js} +1 -1
  260. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-DKZc661S.js → wardleyDiagram-YWT4CUSO-gE_sZ0Ak.js} +1 -1
  261. package/web-shell/assets/{xychartDiagram-2RQKCTM6-su9hp08G.js → xychartDiagram-2RQKCTM6-BwOni53i.js} +1 -1
  262. package/web-shell/index.html +16 -4
  263. package/chunks/chunk-6SHO7WFF.js +0 -79
  264. package/chunks/chunk-IFEWJXFS.js +0 -37
  265. package/node_modules/@qwen-code/audio-capture/dist/index.d.ts +0 -35
  266. package/node_modules/@qwen-code/audio-capture/dist/index.js +0 -48
  267. package/node_modules/@qwen-code/audio-capture/dist/index.js.map +0 -1
  268. package/node_modules/@qwen-code/audio-capture/dist/platform.d.ts +0 -7
  269. package/node_modules/@qwen-code/audio-capture/dist/platform.js +0 -18
  270. package/node_modules/@qwen-code/audio-capture/dist/platform.js.map +0 -1
  271. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/LICENSE +0 -21
  272. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/README.md +0 -58
  273. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/SECURITY.md +0 -5
  274. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/bin.js +0 -84
  275. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/build-test.js +0 -19
  276. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/index.js +0 -6
  277. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/node-gyp-build.js +0 -207
  278. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/optional.js +0 -7
  279. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/package.json +0 -43
  280. package/node_modules/@qwen-code/audio-capture/package.json +0 -30
  281. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
  282. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
  283. package/node_modules/@qwen-code/audio-capture/prebuilds/linux-arm64/@qwen-code+audio-capture.node +0 -0
  284. package/node_modules/@qwen-code/audio-capture/prebuilds/linux-x64/@qwen-code+audio-capture.node +0 -0
  285. package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
  286. package/web-shell/assets/channel-BNf1dW-j.js +0 -1
  287. package/web-shell/assets/classDiagram-4FO5ZUOK-uOIGlzgi.js +0 -1
  288. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-uOIGlzgi.js +0 -1
  289. package/web-shell/assets/index-CnE2ur2L.js +0 -779
  290. package/web-shell/assets/index-hSKXrlSE.css +0 -5
  291. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Bs4TK_84.js +0 -1
  292. /package/chunks/{chunk-Y6Z2O3WR.js → chunk-JM7BYJO5.js} +0 -0
@@ -7,9 +7,6 @@ import {
7
7
  import {
8
8
  findCliEntryPath
9
9
  } from "./chunk-AHNXYU4O.js";
10
- import {
11
- RUNTIME_STARTUP_CANCELLED_MESSAGE
12
- } from "./chunk-GHOTR7HL.js";
13
10
  import {
14
11
  CAPABILITIES_SCHEMA_VERSION,
15
12
  ClientMcpSenderRegistry,
@@ -25,22 +22,41 @@ import {
25
22
  getRateLimiter,
26
23
  getServeProtocolVersions,
27
24
  hostAllowlist,
25
+ isBrowserAutomationMcpAvailable,
28
26
  listenerMaxConnections,
29
27
  parseAllowOriginPatterns,
30
28
  parseDaemonStatusDetail,
31
29
  positiveFiniteOrNull,
32
30
  require_express,
33
31
  resolveWebShellDir
34
- } from "./chunk-RFIL6REB.js";
32
+ } from "./chunk-GRB4QSBD.js";
35
33
  import {
36
34
  isLoopbackBind
37
35
  } from "./chunk-RNBYOUGV.js";
38
36
  import "./chunk-3HX5LZ6R.js";
39
37
  import "./chunk-7RYW5LQV.js";
38
+ import {
39
+ RUNTIME_STARTUP_CANCELLED_MESSAGE
40
+ } from "./chunk-GHOTR7HL.js";
41
+ import {
42
+ LOAD_REPLAY_META_KEY
43
+ } from "./chunk-AGHU5VRK.js";
44
+ import {
45
+ canonicalizeWorkspace
46
+ } from "./chunk-ER3BKOLB.js";
47
+ import {
48
+ DEFAULT_COMPACTED_REPLAY_MAX_BYTES,
49
+ normalizeCompactedReplayMaxBytes
50
+ } from "./chunk-GLE2YUPU.js";
40
51
  import {
41
52
  loadServeFastPathSettings,
42
53
  preResolveServeFastPathHomeEnvOverrides
43
- } from "./chunk-DNV4FSN5.js";
54
+ } from "./chunk-I5XN6KDI.js";
55
+ import {
56
+ getGlobalQwenDirLite,
57
+ resolveConfigPathLite
58
+ } from "./chunk-O2YT7VB4.js";
59
+ import "./chunk-Z3I3QJK3.js";
44
60
  import {
45
61
  QWEN_SERVER_TOKEN_ENV
46
62
  } from "./chunk-S6RLAIUR.js";
@@ -48,26 +64,16 @@ import {
48
64
  channelSelectionNames
49
65
  } from "./chunk-MX2YXRER.js";
50
66
  import {
51
- getGlobalQwenDirLite,
52
- resolveConfigPathLite
53
- } from "./chunk-4RQIB5UZ.js";
54
- import {
55
- LOAD_REPLAY_META_KEY
56
- } from "./chunk-AGHU5VRK.js";
57
- import {
58
- canonicalizeWorkspace
59
- } from "./chunk-ER3BKOLB.js";
67
+ isWithinRoot
68
+ } from "./chunk-QYUE6W3T.js";
60
69
  import {
61
70
  getCliVersion
62
- } from "./chunk-GD236YPV.js";
71
+ } from "./chunk-4ONWIT5C.js";
63
72
  import "./chunk-43W4YSO6.js";
64
73
  import {
65
74
  writeStderrLine,
66
75
  writeStdoutLine
67
- } from "./chunk-Y6Z2O3WR.js";
68
- import {
69
- isWithinRoot
70
- } from "./chunk-QYUE6W3T.js";
76
+ } from "./chunk-JM7BYJO5.js";
71
77
  import "./chunk-5P5XGNYH.js";
72
78
  import "./chunk-SKAZWEV5.js";
73
79
  import "./chunk-UWCTAVOD.js";
@@ -105,7 +111,7 @@ var DuplicateWorkspaceInputError = class extends Error {
105
111
  }
106
112
  constructor(workspace) {
107
113
  super(
108
- `Duplicate --workspace value resolves to ${JSON.stringify(workspace)}. Multi-workspace serve is not enabled; pass one --workspace.`
114
+ `Duplicate --workspace value resolves to ${JSON.stringify(workspace)}. Pass distinct --workspace values.`
109
115
  );
110
116
  this.name = "DuplicateWorkspaceInputError";
111
117
  }
@@ -116,22 +122,11 @@ var NestedWorkspaceInputError = class extends Error {
116
122
  }
117
123
  constructor(parent, child) {
118
124
  super(
119
- `Nested --workspace values are not supported yet: ${JSON.stringify(child)} is inside ${JSON.stringify(parent)}. Multi-workspace serve is not enabled; pass one --workspace.`
125
+ `Nested --workspace values are not supported yet: ${JSON.stringify(child)} is inside ${JSON.stringify(parent)}. Pass non-nested --workspace values.`
120
126
  );
121
127
  this.name = "NestedWorkspaceInputError";
122
128
  }
123
129
  };
124
- var MultipleWorkspaceInputError = class extends Error {
125
- static {
126
- __name(this, "MultipleWorkspaceInputError");
127
- }
128
- constructor() {
129
- super(
130
- "Multiple --workspace values are not supported yet. Multi-workspace serve is not enabled; pass one --workspace."
131
- );
132
- this.name = "MultipleWorkspaceInputError";
133
- }
134
- };
135
130
  var MissingWorkspaceInputError = class extends Error {
136
131
  static {
137
132
  __name(this, "MissingWorkspaceInputError");
@@ -156,7 +151,7 @@ function isNestedWorkspace(parent, child) {
156
151
  return parent !== child && isWithinRoot(child, parent);
157
152
  }
158
153
  __name(isNestedWorkspace, "isNestedWorkspace");
159
- function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
154
+ function rejectDuplicateOrNestedWorkspaceInputs(workspaces) {
160
155
  if (workspaces.length <= 1) return;
161
156
  let canonicalWorkspaces;
162
157
  try {
@@ -164,7 +159,7 @@ function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
164
159
  (workspace) => canonicalizeWorkspace(workspace)
165
160
  );
166
161
  } catch {
167
- throw new MultipleWorkspaceInputError();
162
+ return;
168
163
  }
169
164
  const seen = /* @__PURE__ */ new Set();
170
165
  for (const workspace of canonicalWorkspaces) {
@@ -185,15 +180,14 @@ function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
185
180
  }
186
181
  }
187
182
  }
188
- throw new MultipleWorkspaceInputError();
189
183
  }
190
- __name(rejectUnsupportedMultiWorkspaceInputs, "rejectUnsupportedMultiWorkspaceInputs");
191
- function resolveSingleWorkspaceInput(workspace) {
184
+ __name(rejectDuplicateOrNestedWorkspaceInputs, "rejectDuplicateOrNestedWorkspaceInputs");
185
+ function resolveWorkspaceInputs(workspace) {
192
186
  const workspaces = normalizeWorkspaceInputs(workspace);
193
- rejectUnsupportedMultiWorkspaceInputs(workspaces);
194
- return workspaces[0];
187
+ rejectDuplicateOrNestedWorkspaceInputs(workspaces);
188
+ return workspaces;
195
189
  }
196
- __name(resolveSingleWorkspaceInput, "resolveSingleWorkspaceInput");
190
+ __name(resolveWorkspaceInputs, "resolveWorkspaceInputs");
197
191
 
198
192
  // packages/cli/src/serve/permission-audit.ts
199
193
  init_esbuild_shims();
@@ -939,11 +933,21 @@ function isNonNegativeIntegerOrInfinity(value) {
939
933
  return value === Number.POSITIVE_INFINITY || Number.isFinite(value) && Number.isInteger(value) && value >= 0;
940
934
  }
941
935
  __name(isNonNegativeIntegerOrInfinity, "isNonNegativeIntegerOrInfinity");
936
+ function deriveDefaultMaxTotalSessions(maxSessionsPerWorkspace, workspaceCount) {
937
+ if (workspaceCount <= 1) return void 0;
938
+ const perWorkspace = maxSessionsPerWorkspace ?? DEFAULT_MAX_SESSIONS;
939
+ if (perWorkspace === 0 || perWorkspace === Number.POSITIVE_INFINITY) {
940
+ return void 0;
941
+ }
942
+ return perWorkspace * workspaceCount;
943
+ }
944
+ __name(deriveDefaultMaxTotalSessions, "deriveDefaultMaxTotalSessions");
942
945
  function isNonNegativeIntegerMs(value) {
943
946
  return Number.isFinite(value) && Number.isInteger(value) && value >= 0;
944
947
  }
945
948
  __name(isNonNegativeIntegerMs, "isNonNegativeIntegerMs");
946
949
  var MAX_TIMEOUT_MS = 2147483647;
950
+ var MAX_PORT_ATTEMPTS = 10;
947
951
  function assertTimerDelayInRange(name, value) {
948
952
  if (value > MAX_TIMEOUT_MS) {
949
953
  throw new TypeError(
@@ -1071,6 +1075,10 @@ function extractContextFilename(value) {
1071
1075
  return void 0;
1072
1076
  }
1073
1077
  __name(extractContextFilename, "extractContextFilename");
1078
+ function sessionArtifactsPersistenceAvailableFromSettings(settings) {
1079
+ return settings?.general?.chatRecording !== false;
1080
+ }
1081
+ __name(sessionArtifactsPersistenceAvailableFromSettings, "sessionArtifactsPersistenceAvailableFromSettings");
1074
1082
  var settingsWriteLocks = /* @__PURE__ */ new Map();
1075
1083
  function withSettingsLock(workspace, fn) {
1076
1084
  const prev = settingsWriteLocks.get(workspace) ?? Promise.resolve();
@@ -1082,8 +1090,8 @@ __name(withSettingsLock, "withSettingsLock");
1082
1090
  var channelWorkerRuntimePromise;
1083
1091
  async function loadChannelWorkerRuntime() {
1084
1092
  channelWorkerRuntimePromise ??= Promise.all([
1085
- import("./channel-worker-supervisor-CRCVYQIE.js"),
1086
- import("./pidfile-LIBUENIV.js")
1093
+ import("./channel-worker-supervisor-OPXXT4JK.js"),
1094
+ import("./pidfile-LJ3NLS2P.js")
1087
1095
  ]).then(([supervisor, pidfile]) => ({
1088
1096
  createChannelWorkerSupervisor: supervisor.createChannelWorkerSupervisor,
1089
1097
  channelServicePidfile: pidfile
@@ -1105,6 +1113,9 @@ function createDisabledChannelWorkerSupervisor() {
1105
1113
  },
1106
1114
  async stop() {
1107
1115
  },
1116
+ async restart() {
1117
+ return { ...snapshot, channels: [] };
1118
+ },
1108
1119
  killAllSync() {
1109
1120
  },
1110
1121
  snapshot: /* @__PURE__ */ __name(() => ({ ...snapshot, channels: [] }), "snapshot")
@@ -1154,7 +1165,7 @@ function shouldPreheatBridge(deps) {
1154
1165
  __name(shouldPreheatBridge, "shouldPreheatBridge");
1155
1166
  var coreRuntimePromise;
1156
1167
  function loadCoreRuntime() {
1157
- coreRuntimePromise ??= import("./src-XKZMNHXS.js");
1168
+ coreRuntimePromise ??= import("./src-NELBIIGI.js");
1158
1169
  return coreRuntimePromise;
1159
1170
  }
1160
1171
  __name(loadCoreRuntime, "loadCoreRuntime");
@@ -1184,11 +1195,13 @@ __name(resolveDaemonLogBaseDirForRun, "resolveDaemonLogBaseDirForRun");
1184
1195
  var settingsRuntimePromise;
1185
1196
  function loadSettingsRuntimeModules() {
1186
1197
  settingsRuntimePromise ??= Promise.all([
1187
- import("./settings-WFLNS3WT.js"),
1188
- import("./loadedSettingsAdapter-QVHHQPGM.js"),
1189
- import("./trustedFolders-Z475EIHL.js")
1190
- ]).then(([settings, loadedSettingsAdapter, trustedFolders]) => ({
1198
+ import("./settings-W3IX7NHK.js"),
1199
+ import("./environment-2CJAFOFN.js"),
1200
+ import("./loadedSettingsAdapter-EHTUJRFB.js"),
1201
+ import("./trustedFolders-IT4JBNPG.js")
1202
+ ]).then(([settings, environment, loadedSettingsAdapter, trustedFolders]) => ({
1191
1203
  settings,
1204
+ environment,
1192
1205
  loadedSettingsAdapter,
1193
1206
  trustedFolders
1194
1207
  }));
@@ -1204,16 +1217,20 @@ async function loadServeRuntimeModules() {
1204
1217
  workspaceTypesModule,
1205
1218
  daemonStatusProviderModule,
1206
1219
  workspaceProvidersStatusModule,
1207
- workspaceSkillsStatusModule
1220
+ workspaceSkillsStatusModule,
1221
+ totalSessionAdmissionModule,
1222
+ workspaceRegistryModule
1208
1223
  ] = await Promise.all([
1209
- import("./server-M372UENX.js"),
1210
- import("./bridge-BCU73DZO.js"),
1211
- import("./spawnChannel-RQHUWTCL.js"),
1212
- import("./workspace-service-OMBR6ZLG.js"),
1224
+ import("./server-6HK5FJMR.js"),
1225
+ import("./bridge-HVPFYNM4.js"),
1226
+ import("./spawnChannel-FTZJ3I5O.js"),
1227
+ import("./workspace-service-SY3P3FUY.js"),
1213
1228
  import("./types-QX5C3CHJ.js"),
1214
- import("./daemon-status-provider-XSAFKVDS.js"),
1215
- import("./workspace-providers-status-MVYXMYDG.js"),
1216
- import("./workspace-skills-status-IMMQ7CAY.js")
1229
+ import("./daemon-status-provider-3EPG6BXX.js"),
1230
+ import("./workspace-providers-status-7DTOAWEL.js"),
1231
+ import("./workspace-skills-status-GTT2A4WN.js"),
1232
+ import("./total-session-admission-PRZK35X4.js"),
1233
+ import("./workspace-registry-BBIPESIZ.js")
1217
1234
  ]);
1218
1235
  return {
1219
1236
  createServeApp: serverModule.createServeApp,
@@ -1226,7 +1243,10 @@ async function loadServeRuntimeModules() {
1226
1243
  WorkspaceSettingsPartialPersistError: workspaceTypesModule.WorkspaceSettingsPartialPersistError,
1227
1244
  createDaemonStatusProvider: daemonStatusProviderModule.createDaemonStatusProvider,
1228
1245
  createWorkspaceProvidersStatusProvider: workspaceProvidersStatusModule.createWorkspaceProvidersStatusProvider,
1229
- createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider
1246
+ createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider,
1247
+ createTotalSessionAdmissionController: totalSessionAdmissionModule.createTotalSessionAdmissionController,
1248
+ createWorkspaceRegistry: workspaceRegistryModule.createWorkspaceRegistry,
1249
+ createWorkspaceSessionOwnerIndex: workspaceRegistryModule.createWorkspaceSessionOwnerIndex
1230
1250
  };
1231
1251
  }
1232
1252
  __name(loadServeRuntimeModules, "loadServeRuntimeModules");
@@ -1250,7 +1270,7 @@ function sessionIdleTimeoutMs(value) {
1250
1270
  return value !== void 0 ? channelIdleTimeoutMs(value) : DEFAULT_SESSION_IDLE_TIMEOUT_MS;
1251
1271
  }
1252
1272
  __name(sessionIdleTimeoutMs, "sessionIdleTimeoutMs");
1253
- function currentServeFeaturesForRunQwenServe(opts, sessionShellCommandEnabled) {
1273
+ function currentServeFeaturesForRunQwenServe(opts, sessionShellCommandEnabled, sessionArtifactsPersistenceAvailable) {
1254
1274
  return getAdvertisedServeFeatures(void 0, {
1255
1275
  requireAuth: opts.requireAuth === true,
1256
1276
  mcpPoolActive: opts.mcpPoolActive !== false,
@@ -1259,12 +1279,18 @@ function currentServeFeaturesForRunQwenServe(opts, sessionShellCommandEnabled) {
1259
1279
  ...opts.writerIdleTimeoutMs !== void 0 ? { writerIdleTimeoutMs: opts.writerIdleTimeoutMs } : {},
1260
1280
  persistSettingAvailable: true,
1261
1281
  sessionShellCommandEnabled,
1282
+ sessionArtifactsPersistenceAvailable,
1262
1283
  rateLimit: opts.rateLimit === true,
1263
1284
  reloadAvailable: true,
1285
+ channelReloadAvailable: opts.channelSelection !== void 0,
1264
1286
  // Advertise the same WS feature flags as the runtime path (serve-features.ts)
1265
1287
  // so the bootstrap `/capabilities` window doesn't briefly under-report them.
1266
1288
  clientMcpOverWsEnabled: opts.clientMcpOverWs === true,
1267
- cdpTunnelOverWsEnabled: opts.cdpTunnelOverWs === true
1289
+ cdpTunnelOverWsEnabled: opts.cdpTunnelOverWs === true,
1290
+ browserAutomationMcpAvailable: isBrowserAutomationMcpAvailable(
1291
+ opts,
1292
+ process.env
1293
+ )
1268
1294
  });
1269
1295
  }
1270
1296
  __name(currentServeFeaturesForRunQwenServe, "currentServeFeaturesForRunQwenServe");
@@ -1276,7 +1302,8 @@ function createBootstrapCapabilities(input) {
1276
1302
  mode: input.opts.mode,
1277
1303
  features: currentServeFeaturesForRunQwenServe(
1278
1304
  input.opts,
1279
- input.sessionShellCommandEnabled
1305
+ input.sessionShellCommandEnabled,
1306
+ input.sessionArtifactsPersistenceAvailable
1280
1307
  ),
1281
1308
  modelServices: [],
1282
1309
  workspaceCwd: input.boundWorkspace,
@@ -1421,7 +1448,9 @@ function createBootstrapServeApp(input) {
1421
1448
  daemonLog,
1422
1449
  qwenCodeVersion,
1423
1450
  sessionShellCommandEnabled,
1451
+ sessionArtifactsPersistenceAvailable,
1424
1452
  permissionPolicy,
1453
+ multiWorkspaceCapabilitiesRequireRuntime,
1425
1454
  getRuntimeError,
1426
1455
  getChannelWorkerSnapshot,
1427
1456
  onHealthServed
@@ -1458,12 +1487,24 @@ function createBootstrapServeApp(input) {
1458
1487
  app.get(BOOTSTRAP_HEALTH_PATH, healthHandler);
1459
1488
  }
1460
1489
  app.get(BOOTSTRAP_CAPABILITIES_PATH, (_req, res) => {
1490
+ if (multiWorkspaceCapabilitiesRequireRuntime) {
1491
+ const runtimeError = getRuntimeError();
1492
+ if (runtimeError === void 0) {
1493
+ res.setHeader("Retry-After", "1");
1494
+ }
1495
+ res.status(503).json({
1496
+ error: runtimeError ? "Daemon runtime failed to start" : "Daemon runtime is still starting",
1497
+ code: runtimeError ? "daemon_runtime_failed" : "daemon_runtime_starting"
1498
+ });
1499
+ return;
1500
+ }
1461
1501
  res.status(200).json(
1462
1502
  createBootstrapCapabilities({
1463
1503
  opts,
1464
1504
  boundWorkspace,
1465
1505
  qwenCodeVersion,
1466
1506
  sessionShellCommandEnabled,
1507
+ sessionArtifactsPersistenceAvailable,
1467
1508
  permissionPolicy
1468
1509
  })
1469
1510
  );
@@ -1518,11 +1559,13 @@ function createBootstrapServeApp(input) {
1518
1559
  },
1519
1560
  limits: {
1520
1561
  maxSessions: advertisedMaxSessions(opts.maxSessions),
1562
+ maxTotalSessions: positiveFiniteOrNull(opts.maxTotalSessions),
1521
1563
  maxPendingPromptsPerSession: advertisedMaxPendingPromptsPerSession(
1522
1564
  opts.maxPendingPromptsPerSession
1523
1565
  ),
1524
1566
  listenerMaxConnections: listenerMaxConnections(opts.maxConnections),
1525
1567
  eventRingSize: opts.eventRingSize ?? DEFAULT_EVENT_RING_SIZE,
1568
+ compactedReplayMaxBytes: opts.compactedReplayMaxBytes ?? DEFAULT_COMPACTED_REPLAY_MAX_BYTES,
1526
1569
  promptDeadlineMs: positiveFiniteOrNull(opts.promptDeadlineMs),
1527
1570
  writerIdleTimeoutMs: positiveFiniteOrNull(opts.writerIdleTimeoutMs),
1528
1571
  channelIdleTimeoutMs: channelIdleTimeoutMs(opts.channelIdleTimeoutMs),
@@ -1533,7 +1576,8 @@ function createBootstrapServeApp(input) {
1533
1576
  protocolVersions: getServeProtocolVersions(),
1534
1577
  features: currentServeFeaturesForRunQwenServe(
1535
1578
  opts,
1536
- sessionShellCommandEnabled
1579
+ sessionShellCommandEnabled,
1580
+ sessionArtifactsPersistenceAvailable
1537
1581
  )
1538
1582
  },
1539
1583
  runtime: {
@@ -1663,6 +1707,9 @@ async function runQwenServe(optsIn, deps = {}) {
1663
1707
  }
1664
1708
  };
1665
1709
  preResolveServeFastPathHomeEnvOverrides();
1710
+ const daemonRuntimeBaseEnv = Object.freeze({
1711
+ ...process.env
1712
+ });
1666
1713
  const rawToken = optsIn.token ?? process.env[QWEN_SERVER_TOKEN_ENV];
1667
1714
  const token = typeof rawToken === "string" && rawToken.trim().length > 0 ? rawToken.trim() : void 0;
1668
1715
  const sessionShellCommandEnabled = optsIn.enableSessionShell === true && token !== void 0;
@@ -1684,7 +1731,8 @@ async function runQwenServe(optsIn, deps = {}) {
1684
1731
  const chromeExtensionOriginAllowed = hasChromeExtensionOrigin(
1685
1732
  optsIn.allowOrigins
1686
1733
  );
1687
- const rawWorkspace = resolveSingleWorkspaceInput(optsIn.workspace);
1734
+ const rawWorkspaces = resolveWorkspaceInputs(optsIn.workspace);
1735
+ const rawWorkspace = rawWorkspaces[0];
1688
1736
  const opts = {
1689
1737
  ...optsIn,
1690
1738
  token,
@@ -1830,41 +1878,84 @@ async function runQwenServe(optsIn, deps = {}) {
1830
1878
  "qwen serve: --allow-private-auth-base-url enabled; /workspace/auth/provider may install localhost/private-network model endpoints. Use only for local development with trusted clients."
1831
1879
  );
1832
1880
  }
1833
- if (!path.isAbsolute(rawWorkspace)) {
1834
- throw new Error(
1835
- `Invalid --workspace "${rawWorkspace}": must be an absolute path.`
1836
- );
1837
- }
1838
- try {
1839
- const stats = fs.statSync(rawWorkspace);
1840
- if (!stats.isDirectory()) {
1881
+ const validateAndCanonicalizeWorkspace = /* @__PURE__ */ __name((workspace) => {
1882
+ if (!path.isAbsolute(workspace)) {
1841
1883
  throw new Error(
1842
- `Invalid --workspace "${rawWorkspace}": exists but is not a directory.`
1884
+ `Invalid --workspace "${workspace}": must be an absolute path.`
1843
1885
  );
1844
1886
  }
1845
- } catch (err) {
1846
- if (err && typeof err === "object" && "code" in err) {
1847
- const code = err.code;
1848
- if (code === "ENOENT") {
1887
+ try {
1888
+ const stats = fs.statSync(workspace);
1889
+ if (!stats.isDirectory()) {
1890
+ throw new Error(
1891
+ `Invalid --workspace "${workspace}": exists but is not a directory.`
1892
+ );
1893
+ }
1894
+ } catch (err) {
1895
+ if (err && typeof err === "object" && "code" in err) {
1896
+ const code = err.code;
1897
+ if (code === "ENOENT") {
1898
+ throw new Error(
1899
+ `Invalid --workspace "${workspace}": directory does not exist.`
1900
+ );
1901
+ }
1902
+ if (code === "EACCES" || code === "EPERM") {
1903
+ throw new Error(
1904
+ `Invalid --workspace "${workspace}": permission denied (${String(code)}). The path exists but cannot be stat'd by the current user.`
1905
+ );
1906
+ }
1907
+ }
1908
+ throw err;
1909
+ }
1910
+ return canonicalizeWorkspace(workspace);
1911
+ }, "validateAndCanonicalizeWorkspace");
1912
+ const workspaceInputs = rawWorkspaces.map((workspace) => ({
1913
+ raw: workspace,
1914
+ cwd: validateAndCanonicalizeWorkspace(workspace)
1915
+ }));
1916
+ const boundWorkspace = workspaceInputs[0].cwd;
1917
+ const seenCanonicalWorkspaces = /* @__PURE__ */ new Set();
1918
+ for (const workspace of workspaceInputs) {
1919
+ if (seenCanonicalWorkspaces.has(workspace.cwd)) {
1920
+ throw new Error(
1921
+ `Duplicate --workspace value resolves to ${JSON.stringify(
1922
+ workspace.cwd
1923
+ )}.`
1924
+ );
1925
+ }
1926
+ seenCanonicalWorkspaces.add(workspace.cwd);
1927
+ }
1928
+ for (let i = 0; i < workspaceInputs.length; i++) {
1929
+ for (let j = i + 1; j < workspaceInputs.length; j++) {
1930
+ const first = workspaceInputs[i].cwd;
1931
+ const second = workspaceInputs[j].cwd;
1932
+ const firstRel = path.relative(first, second);
1933
+ const secondRel = path.relative(second, first);
1934
+ if (firstRel && !firstRel.startsWith("..") && !path.isAbsolute(firstRel)) {
1849
1935
  throw new Error(
1850
- `Invalid --workspace "${rawWorkspace}": directory does not exist.`
1936
+ `Nested --workspace values are not supported: ${JSON.stringify(second)} is inside ${JSON.stringify(first)}.`
1851
1937
  );
1852
1938
  }
1853
- if (code === "EACCES" || code === "EPERM") {
1939
+ if (secondRel && !secondRel.startsWith("..") && !path.isAbsolute(secondRel)) {
1854
1940
  throw new Error(
1855
- `Invalid --workspace "${rawWorkspace}": permission denied (${String(code)}). The path exists but cannot be stat'd by the current user.`
1941
+ `Nested --workspace values are not supported: ${JSON.stringify(first)} is inside ${JSON.stringify(second)}.`
1856
1942
  );
1857
1943
  }
1858
1944
  }
1859
- throw err;
1860
1945
  }
1861
- const boundWorkspace = canonicalizeWorkspace(rawWorkspace);
1946
+ if (workspaceInputs.length > 1 && deps.bridge) {
1947
+ throw new Error(
1948
+ "Injected bridge dependencies are only supported with a single workspace; multiple --workspace values require runQwenServe to construct one bridge per workspace."
1949
+ );
1950
+ }
1862
1951
  let contextFilenameForInit;
1863
1952
  let permissionPolicy;
1864
1953
  let permissionConsensusQuorum;
1865
1954
  let bootSettings;
1955
+ let sessionArtifactsPersistenceAvailable = true;
1866
1956
  try {
1867
1957
  bootSettings = deps.bootSettings ?? loadServeFastPathSettings(boundWorkspace);
1958
+ sessionArtifactsPersistenceAvailable = sessionArtifactsPersistenceAvailableFromSettings(bootSettings);
1868
1959
  contextFilenameForInit = extractContextFilename(
1869
1960
  bootSettings.context?.fileName
1870
1961
  );
@@ -1919,6 +2010,13 @@ async function runQwenServe(optsIn, deps = {}) {
1919
2010
  );
1920
2011
  }
1921
2012
  }
2013
+ if (opts.maxTotalSessions !== void 0) {
2014
+ if (!isNonNegativeIntegerOrInfinity(opts.maxTotalSessions)) {
2015
+ throw new TypeError(
2016
+ `Invalid maxTotalSessions: ${opts.maxTotalSessions}. Must be a non-negative integer (0 / Infinity = unlimited).`
2017
+ );
2018
+ }
2019
+ }
1922
2020
  if (opts.maxPendingPromptsPerSession !== void 0) {
1923
2021
  if (!isNonNegativeIntegerOrInfinity(opts.maxPendingPromptsPerSession)) {
1924
2022
  throw new TypeError(
@@ -1933,6 +2031,9 @@ async function runQwenServe(optsIn, deps = {}) {
1933
2031
  );
1934
2032
  }
1935
2033
  }
2034
+ if (opts.compactedReplayMaxBytes !== void 0) {
2035
+ normalizeCompactedReplayMaxBytes(opts.compactedReplayMaxBytes);
2036
+ }
1936
2037
  if (opts.writerIdleTimeoutMs !== void 0) {
1937
2038
  if (!isPositiveIntegerMs(opts.writerIdleTimeoutMs)) {
1938
2039
  throw new TypeError(
@@ -1968,6 +2069,10 @@ async function runQwenServe(optsIn, deps = {}) {
1968
2069
  );
1969
2070
  }
1970
2071
  }
2072
+ opts.maxTotalSessions ??= deriveDefaultMaxTotalSessions(
2073
+ opts.maxSessions,
2074
+ workspaceInputs.length
2075
+ );
1971
2076
  const inheritedNoPool = process.env["QWEN_SERVE_NO_MCP_POOL"] === "1";
1972
2077
  if (opts.mcpPoolActive === void 0 && inheritedNoPool) {
1973
2078
  opts.mcpPoolActive = false;
@@ -2005,6 +2110,7 @@ async function runQwenServe(optsIn, deps = {}) {
2005
2110
  let runtimeApp;
2006
2111
  let runtimeAppForCleanup;
2007
2112
  let bridgeRef = deps.bridge;
2113
+ const internalRuntimeBridgesForCleanup = [];
2008
2114
  let daemonEventLoopMonitor;
2009
2115
  let daemonMetricsSampler;
2010
2116
  let runtimeStartupError;
@@ -2029,6 +2135,7 @@ async function runQwenServe(optsIn, deps = {}) {
2029
2135
  }, "disposeDaemonEventLoopMonitor");
2030
2136
  let channelWorker = createDisabledChannelWorkerSupervisor();
2031
2137
  const getChannelWorkerSnapshot = /* @__PURE__ */ __name(() => channelWorker.snapshot(), "getChannelWorkerSnapshot");
2138
+ const reloadChannelWorker = /* @__PURE__ */ __name(() => channelWorker.restart(), "reloadChannelWorker");
2032
2139
  const writeChannelWorkerPidfile = /* @__PURE__ */ __name((snapshot = channelWorker.snapshot(), options = {}) => {
2033
2140
  if (!opts.channelSelection || !channelServicePidfile) return;
2034
2141
  try {
@@ -2047,6 +2154,17 @@ async function runQwenServe(optsIn, deps = {}) {
2047
2154
  () => bridgeRef,
2048
2155
  () => runtimeStartupError
2049
2156
  );
2157
+ const shutdownBridges = /* @__PURE__ */ new WeakSet();
2158
+ const getRuntimeBridgesForCleanup = /* @__PURE__ */ __name(() => {
2159
+ const appForCleanup = runtimeApp ?? runtimeAppForCleanup;
2160
+ const registry = appForCleanup?.locals?.["workspaceRegistry"];
2161
+ const bridges = [
2162
+ ...registry ? registry.list().map((runtime) => runtime.bridge) : [],
2163
+ ...bridgeRef ? [bridgeRef] : [],
2164
+ ...internalRuntimeBridgesForCleanup
2165
+ ];
2166
+ return [...new Set(bridges)];
2167
+ }, "getRuntimeBridgesForCleanup");
2050
2168
  const buildRuntime = /* @__PURE__ */ __name(async () => {
2051
2169
  const [runtime, core, settingsRuntime, resolvedCliVersion] = await Promise.all([
2052
2170
  loadServeRuntimeModules(),
@@ -2073,6 +2191,43 @@ async function runQwenServe(optsIn, deps = {}) {
2073
2191
  { workspace: boundWorkspace }
2074
2192
  );
2075
2193
  }
2194
+ const runtimeEnvSnapshot = runtimeBootSettings ? settingsRuntime.environment.buildRuntimeEnvironment(
2195
+ runtimeBootSettings.merged,
2196
+ boundWorkspace,
2197
+ daemonRuntimeBaseEnv
2198
+ ) : {
2199
+ effectiveEnv: { ...daemonRuntimeBaseEnv },
2200
+ overlayKeys: Object.freeze([]),
2201
+ envFilePaths: Object.freeze([]),
2202
+ envFileReadFailed: false,
2203
+ envFileReadFailures: Object.freeze([])
2204
+ };
2205
+ const logRuntimeEnvFileReadFailures = /* @__PURE__ */ __name((workspace, snapshot) => {
2206
+ if (!snapshot.envFileReadFailed) return;
2207
+ const failedFiles = snapshot.envFileReadFailures ?? [];
2208
+ daemonLog.warn("one or more runtime env files could not be read", {
2209
+ workspace,
2210
+ ...failedFiles.length > 0 ? { failedFiles } : {}
2211
+ });
2212
+ }, "logRuntimeEnvFileReadFailures");
2213
+ logRuntimeEnvFileReadFailures(boundWorkspace, runtimeEnvSnapshot);
2214
+ const runtimeEffectiveEnv = {
2215
+ ...runtimeEnvSnapshot.effectiveEnv
2216
+ };
2217
+ const replaceRuntimeEffectiveEnv = /* @__PURE__ */ __name((nextEnv) => {
2218
+ for (const key of Object.keys(runtimeEffectiveEnv)) {
2219
+ delete runtimeEffectiveEnv[key];
2220
+ }
2221
+ Object.assign(runtimeEffectiveEnv, nextEnv);
2222
+ }, "replaceRuntimeEffectiveEnv");
2223
+ const primaryRuntimeEnv = {
2224
+ mode: "runtime-overlay",
2225
+ overlayKeys: [...runtimeEnvSnapshot.overlayKeys],
2226
+ effectiveEnv: runtimeEffectiveEnv,
2227
+ envFilePaths: [...runtimeEnvSnapshot.envFilePaths],
2228
+ envFileReadFailed: runtimeEnvSnapshot.envFileReadFailed,
2229
+ envFileReadFailures: [...runtimeEnvSnapshot.envFileReadFailures]
2230
+ };
2076
2231
  const daemonWorkspaceHash = core.hashDaemonWorkspace(boundWorkspace);
2077
2232
  let daemonTelemetrySettings;
2078
2233
  try {
@@ -2145,54 +2300,58 @@ async function runQwenServe(optsIn, deps = {}) {
2145
2300
  promptQueueWaitStats.lastMs = durationMs;
2146
2301
  core.recordDaemonPromptQueueWait(durationMs);
2147
2302
  }, "recordPromptQueueWait");
2148
- const daemonTelemetry = core.createDaemonBridgeTelemetry();
2149
- daemonTelemetry.metrics = {
2150
- sessionLifecycle(action) {
2151
- core.recordDaemonSessionLifecycle(action);
2152
- core.emitDaemonLog(
2153
- `Session ${action}.`,
2154
- {
2155
- "qwen-code.workspace.hash": daemonWorkspaceHash
2156
- },
2157
- {
2158
- eventName: `qwen-code.daemon.session.${action}`
2159
- }
2160
- );
2161
- },
2162
- channelLifecycle(action, expected) {
2163
- core.recordDaemonChannelLifecycle(action, expected);
2164
- core.emitDaemonLog(
2165
- action === "spawn" ? "ACP channel spawned." : `ACP channel exited (expected=${expected ?? true}).`,
2166
- {
2167
- ...action === "exit" ? { "qwen-code.daemon.channel.expected": expected ?? true } : {}
2168
- },
2169
- {
2170
- eventName: `qwen-code.daemon.channel.${action}`,
2171
- ...expected === false && action === "exit" ? { severityNumber: 13 } : {}
2303
+ const createRuntimeBridgeTelemetry = /* @__PURE__ */ __name((workspaceHash) => {
2304
+ const telemetry = core.createDaemonBridgeTelemetry();
2305
+ telemetry.metrics = {
2306
+ sessionLifecycle(action) {
2307
+ core.recordDaemonSessionLifecycle(action);
2308
+ core.emitDaemonLog(
2309
+ `Session ${action}.`,
2310
+ {
2311
+ "qwen-code.workspace.hash": workspaceHash
2312
+ },
2313
+ {
2314
+ eventName: `qwen-code.daemon.session.${action}`
2315
+ }
2316
+ );
2317
+ },
2318
+ channelLifecycle(action, expected) {
2319
+ core.recordDaemonChannelLifecycle(action, expected);
2320
+ core.emitDaemonLog(
2321
+ action === "spawn" ? "ACP channel spawned." : `ACP channel exited (expected=${expected ?? true}).`,
2322
+ {
2323
+ ...action === "exit" ? { "qwen-code.daemon.channel.expected": expected ?? true } : {}
2324
+ },
2325
+ {
2326
+ eventName: `qwen-code.daemon.channel.${action}`,
2327
+ ...expected === false && action === "exit" ? { severityNumber: 13 } : {}
2328
+ }
2329
+ );
2330
+ },
2331
+ promptQueueWait(durationMs) {
2332
+ recordPromptQueueWait(durationMs);
2333
+ metricsRing.recordPromptQueueWait(durationMs);
2334
+ },
2335
+ promptDuration(durationMs) {
2336
+ core.recordDaemonPromptDuration(durationMs);
2337
+ metricsRing.recordPromptDuration(durationMs);
2338
+ },
2339
+ cancelled: core.recordDaemonCancel,
2340
+ // Per-round model token usage + LLM round-trip time sniffed off
2341
+ // `agent_message_chunk._meta` (`usage` + `durationMs`) at the bridge's
2342
+ // single session/update fan-in. Increments (not cumulative), so the ring
2343
+ // sums tokens per window (token-burn chart) and pools the round-trip times
2344
+ // for the LLM-latency percentiles.
2345
+ tokenUsage(inputTokens, outputTokens, durationMs) {
2346
+ metricsRing.recordTokens(inputTokens, outputTokens);
2347
+ if (typeof durationMs === "number") {
2348
+ metricsRing.recordLlmDuration(durationMs);
2172
2349
  }
2173
- );
2174
- },
2175
- promptQueueWait(durationMs) {
2176
- recordPromptQueueWait(durationMs);
2177
- metricsRing.recordPromptQueueWait(durationMs);
2178
- },
2179
- promptDuration(durationMs) {
2180
- core.recordDaemonPromptDuration(durationMs);
2181
- metricsRing.recordPromptDuration(durationMs);
2182
- },
2183
- cancelled: core.recordDaemonCancel,
2184
- // Per-round model token usage + LLM round-trip time sniffed off
2185
- // `agent_message_chunk._meta` (`usage` + `durationMs`) at the bridge's
2186
- // single session/update fan-in. Increments (not cumulative), so the ring
2187
- // sums tokens per window (token-burn chart) and pools the round-trip times
2188
- // for the LLM-latency percentiles.
2189
- tokenUsage(inputTokens, outputTokens, durationMs) {
2190
- metricsRing.recordTokens(inputTokens, outputTokens);
2191
- if (typeof durationMs === "number") {
2192
- metricsRing.recordLlmDuration(durationMs);
2193
2350
  }
2194
- }
2195
- };
2351
+ };
2352
+ return telemetry;
2353
+ }, "createRuntimeBridgeTelemetry");
2354
+ const daemonTelemetry = createRuntimeBridgeTelemetry(daemonWorkspaceHash);
2196
2355
  const permissionAuditRing = new PermissionAuditRing();
2197
2356
  const permissionAuditPublisher = createPermissionAuditPublisher({
2198
2357
  ring: permissionAuditRing
@@ -2239,7 +2398,17 @@ async function runQwenServe(optsIn, deps = {}) {
2239
2398
  pathLocks: sharedPathLocks,
2240
2399
  ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2241
2400
  });
2401
+ const routeFsFactory = runtime.resolveBridgeFsFactory({
2402
+ // REST routes still return primary-relative paths, so keep their
2403
+ // filesystem boundary primary-only until responses carry root IDs.
2404
+ boundWorkspaces: [boundWorkspace],
2405
+ trusted: trustedWorkspace,
2406
+ emit: deps.fsAuditEmit,
2407
+ pathLocks: sharedPathLocks,
2408
+ ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2409
+ });
2242
2410
  const channelFactory = runtime.createSpawnChannelFactory({
2411
+ sourceEnv: runtimeEffectiveEnv,
2243
2412
  onDiagnosticLine: diagnosticSink,
2244
2413
  pipeHooks: {
2245
2414
  onMessageSent: /* @__PURE__ */ __name((bytes) => recordPipeMessage("outbound", bytes), "onMessageSent"),
@@ -2252,10 +2421,22 @@ async function runQwenServe(optsIn, deps = {}) {
2252
2421
  },
2253
2422
  ...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
2254
2423
  });
2255
- const statusProvider = runtime.createDaemonStatusProvider();
2256
- const workspaceProvidersStatusProvider = runtime.createWorkspaceProvidersStatusProvider();
2424
+ const statusProvider = runtime.createDaemonStatusProvider({
2425
+ env: runtimeEffectiveEnv
2426
+ });
2427
+ const workspaceProvidersStatusProvider = runtime.createWorkspaceProvidersStatusProvider({
2428
+ env: runtimeEffectiveEnv
2429
+ });
2257
2430
  const workspaceSkillsStatusProvider = runtime.createWorkspaceSkillsStatusProvider();
2258
2431
  const clientMcpSenderRegistry = new ClientMcpSenderRegistry();
2432
+ const runtimeBridges = [];
2433
+ const totalSessionAdmission = runtime.createTotalSessionAdmissionController(
2434
+ {
2435
+ maxTotalSessions: opts.maxTotalSessions,
2436
+ getBridges: /* @__PURE__ */ __name(() => runtimeBridges.length > 0 ? runtimeBridges : bridgeRef ? [bridgeRef] : [], "getBridges")
2437
+ }
2438
+ );
2439
+ const sessionOwnerIndex = runtime.createWorkspaceSessionOwnerIndex();
2259
2440
  const persistDisabledToolsFn = /* @__PURE__ */ __name((workspace, toolName, enabled) => withSettingsLock(workspace, async () => {
2260
2441
  const fresh = settingsRuntime.settings.loadSettings(workspace);
2261
2442
  const wsScope = fresh.forScope(WORKSPACE_SETTING_SCOPE).settings;
@@ -2302,13 +2483,22 @@ async function runQwenServe(optsIn, deps = {}) {
2302
2483
  );
2303
2484
  }
2304
2485
  }), "persistSettingsFn");
2486
+ const { createSubSessionLauncher } = await import("./create-sub-session-EVYZYAE3.js");
2487
+ const subSessionLauncher = createSubSessionLauncher({
2488
+ getBridge: /* @__PURE__ */ __name(() => bridgeRef, "getBridge"),
2489
+ boundWorkspace
2490
+ });
2305
2491
  const bridge = deps.bridge ?? runtime.createAcpSessionBridge({
2306
2492
  // Reverse tool channel: let `BridgeClient.extMethod` reach the WS
2307
2493
  // connection that hosts a named client MCP server (#5626).
2308
2494
  clientMcpSender: clientMcpSenderRegistry.lookup,
2495
+ onCreateSubSession: subSessionLauncher.launch,
2309
2496
  maxSessions: opts.maxSessions,
2497
+ freshSessionAdmission: totalSessionAdmission.admit,
2498
+ sessionLifecycle: sessionOwnerIndex.handleBridgeSessionLifecycle,
2310
2499
  ...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
2311
2500
  ...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
2501
+ ...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
2312
2502
  ...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
2313
2503
  ...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
2314
2504
  ...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
@@ -2331,7 +2521,9 @@ async function runQwenServe(optsIn, deps = {}) {
2331
2521
  });
2332
2522
  if (!deps.bridge) {
2333
2523
  bridgeRef = bridge;
2524
+ internalRuntimeBridgesForCleanup.push(bridge);
2334
2525
  }
2526
+ runtimeBridges.push(bridge);
2335
2527
  const workspaceService = runtime.createDaemonWorkspaceService({
2336
2528
  boundWorkspace,
2337
2529
  contextFilename: contextFilenameForInit ?? "QWEN.md",
@@ -2342,22 +2534,291 @@ async function runQwenServe(optsIn, deps = {}) {
2342
2534
  persistDisabledTools: persistDisabledToolsFn,
2343
2535
  persistSetting: persistSettingFn,
2344
2536
  persistSettings: persistSettingsFn,
2537
+ preheatAcpChild: /* @__PURE__ */ __name(() => bridge.preheat(), "preheatAcpChild"),
2345
2538
  reloadDaemonEnv: /* @__PURE__ */ __name((workspace) => withSettingsLock(workspace, async () => {
2346
2539
  const fresh = settingsRuntime.settings.loadSettings(workspace, {
2347
2540
  skipLoadEnvironment: true
2348
2541
  });
2349
- return settingsRuntime.settings.reloadEnvironment(
2542
+ const result = settingsRuntime.settings.reloadEnvironment(
2350
2543
  fresh.merged,
2351
2544
  workspace
2352
2545
  );
2546
+ let refreshedRuntimeEnv;
2547
+ let fallbackReason;
2548
+ try {
2549
+ refreshedRuntimeEnv = settingsRuntime.environment.buildRuntimeEnvironment(
2550
+ fresh.merged,
2551
+ workspace,
2552
+ daemonRuntimeBaseEnv
2553
+ );
2554
+ } catch (err) {
2555
+ fallbackReason = err instanceof Error ? err.message : String(err);
2556
+ daemonLog.warn(
2557
+ "failed to rebuild runtime env snapshot after daemon env reload; preserving previous runtime env",
2558
+ {
2559
+ error: fallbackReason
2560
+ }
2561
+ );
2562
+ refreshedRuntimeEnv = {
2563
+ effectiveEnv: { ...runtimeEffectiveEnv },
2564
+ overlayKeys: [...primaryRuntimeEnv.overlayKeys],
2565
+ envFilePaths: [...primaryRuntimeEnv.envFilePaths],
2566
+ envFileReadFailed: primaryRuntimeEnv.envFileReadFailed ?? false,
2567
+ envFileReadFailures: [
2568
+ ...primaryRuntimeEnv.envFileReadFailures ?? []
2569
+ ]
2570
+ };
2571
+ }
2572
+ logRuntimeEnvFileReadFailures(workspace, refreshedRuntimeEnv);
2573
+ replaceRuntimeEffectiveEnv(refreshedRuntimeEnv.effectiveEnv);
2574
+ if (fallbackReason) {
2575
+ primaryRuntimeEnv.fallbackReason = fallbackReason;
2576
+ } else {
2577
+ delete primaryRuntimeEnv.fallbackReason;
2578
+ }
2579
+ primaryRuntimeEnv.envFileReadFailed = refreshedRuntimeEnv.envFileReadFailed;
2580
+ primaryRuntimeEnv.envFileReadFailures.splice(
2581
+ 0,
2582
+ primaryRuntimeEnv.envFileReadFailures.length,
2583
+ ...refreshedRuntimeEnv.envFileReadFailures
2584
+ );
2585
+ primaryRuntimeEnv.overlayKeys.splice(
2586
+ 0,
2587
+ primaryRuntimeEnv.overlayKeys.length,
2588
+ ...refreshedRuntimeEnv.overlayKeys
2589
+ );
2590
+ primaryRuntimeEnv.envFilePaths.splice(
2591
+ 0,
2592
+ primaryRuntimeEnv.envFilePaths.length,
2593
+ ...refreshedRuntimeEnv.envFilePaths
2594
+ );
2595
+ return result;
2353
2596
  }), "reloadDaemonEnv"),
2354
2597
  queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => bridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
2355
2598
  invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => bridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
2356
2599
  refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => bridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
2357
2600
  publishWorkspaceEvent: /* @__PURE__ */ __name((event) => bridge.publishWorkspaceEvent(event), "publishWorkspaceEvent")
2358
2601
  });
2602
+ const workspaceRuntimes = [
2603
+ {
2604
+ workspaceId: daemonWorkspaceHash,
2605
+ workspaceCwd: boundWorkspace,
2606
+ primary: true,
2607
+ trusted: trustedWorkspace,
2608
+ env: primaryRuntimeEnv,
2609
+ bridge,
2610
+ workspaceService,
2611
+ routeFileSystemFactory: routeFsFactory,
2612
+ clientMcpSenderRegistry
2613
+ }
2614
+ ];
2615
+ const createRuntimeEnvMetadata = /* @__PURE__ */ __name((workspace, settings) => {
2616
+ const snapshot = settings ? settingsRuntime.environment.buildRuntimeEnvironment(
2617
+ settings.merged,
2618
+ workspace,
2619
+ daemonRuntimeBaseEnv
2620
+ ) : {
2621
+ effectiveEnv: { ...daemonRuntimeBaseEnv },
2622
+ overlayKeys: Object.freeze([]),
2623
+ envFilePaths: Object.freeze([]),
2624
+ envFileReadFailed: false,
2625
+ envFileReadFailures: Object.freeze([])
2626
+ };
2627
+ logRuntimeEnvFileReadFailures(workspace, snapshot);
2628
+ const effectiveEnv = { ...snapshot.effectiveEnv };
2629
+ const metadata = {
2630
+ mode: "runtime-overlay",
2631
+ overlayKeys: [...snapshot.overlayKeys],
2632
+ effectiveEnv,
2633
+ envFilePaths: [...snapshot.envFilePaths],
2634
+ envFileReadFailed: snapshot.envFileReadFailed,
2635
+ envFileReadFailures: [...snapshot.envFileReadFailures]
2636
+ };
2637
+ return {
2638
+ metadata,
2639
+ effectiveEnv,
2640
+ replace(nextEnv) {
2641
+ for (const key of Object.keys(effectiveEnv)) {
2642
+ delete effectiveEnv[key];
2643
+ }
2644
+ Object.assign(effectiveEnv, nextEnv);
2645
+ }
2646
+ };
2647
+ }, "createRuntimeEnvMetadata");
2648
+ const subSessionStoppers = [];
2649
+ for (const workspaceInput of workspaceInputs.slice(1)) {
2650
+ let secondarySettings;
2651
+ try {
2652
+ secondarySettings = settingsRuntime.settings.loadSettings(
2653
+ workspaceInput.cwd
2654
+ );
2655
+ } catch (err) {
2656
+ writeStderrLine(
2657
+ `qwen serve: could not read full settings for secondary workspace ${workspaceInput.cwd} (${err instanceof Error ? err.message : String(err)}); falling back to defaults.`
2658
+ );
2659
+ }
2660
+ const secondaryTrusted = secondarySettings ? settingsRuntime.trustedFolders.getWorkspaceTrustStatus(
2661
+ secondarySettings.merged,
2662
+ workspaceInput.cwd
2663
+ ).effective.state === "trusted" : false;
2664
+ if (!secondaryTrusted) {
2665
+ daemonLog.warn("secondary workspace is not trusted", {
2666
+ workspace: workspaceInput.cwd,
2667
+ trustSettingsAvailable: secondarySettings !== void 0
2668
+ });
2669
+ }
2670
+ const secondaryEnv = createRuntimeEnvMetadata(
2671
+ workspaceInput.cwd,
2672
+ secondarySettings
2673
+ );
2674
+ const secondaryWorkspaceHash = core.hashDaemonWorkspace(
2675
+ workspaceInput.cwd
2676
+ );
2677
+ const secondaryStatusProvider = runtime.createDaemonStatusProvider({
2678
+ env: secondaryEnv.effectiveEnv
2679
+ });
2680
+ const secondaryBridgeFsFactory = runtime.resolveBridgeFsFactory({
2681
+ boundWorkspaces: [workspaceInput.cwd],
2682
+ trusted: secondaryTrusted,
2683
+ emit: deps.fsAuditEmit,
2684
+ pathLocks: sharedPathLocks,
2685
+ ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2686
+ });
2687
+ const secondaryChannelFactory = runtime.createSpawnChannelFactory({
2688
+ sourceEnv: secondaryEnv.effectiveEnv,
2689
+ onDiagnosticLine: diagnosticSink,
2690
+ pipeHooks: {
2691
+ onMessageSent: /* @__PURE__ */ __name((bytes) => recordPipeMessage("outbound", bytes), "onMessageSent"),
2692
+ onMessageReceived: /* @__PURE__ */ __name((bytes) => recordPipeMessage("inbound", bytes), "onMessageReceived"),
2693
+ onMessageObserved: /* @__PURE__ */ __name(({ direction, bytes, message }) => observeLargePipeFrame({
2694
+ direction: daemonPipeDirection(direction),
2695
+ bytes,
2696
+ message
2697
+ }), "onMessageObserved")
2698
+ },
2699
+ ...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
2700
+ });
2701
+ const secondaryClientMcpSenderRegistry = new ClientMcpSenderRegistry();
2702
+ let secondaryBridgeRef;
2703
+ const secondarySubSessionLauncher = createSubSessionLauncher({
2704
+ getBridge: /* @__PURE__ */ __name(() => secondaryBridgeRef, "getBridge"),
2705
+ boundWorkspace: workspaceInput.cwd
2706
+ });
2707
+ const secondaryBridge = runtime.createAcpSessionBridge({
2708
+ clientMcpSender: secondaryClientMcpSenderRegistry.lookup,
2709
+ onCreateSubSession: secondarySubSessionLauncher.launch,
2710
+ maxSessions: opts.maxSessions,
2711
+ freshSessionAdmission: totalSessionAdmission.admit,
2712
+ sessionLifecycle: sessionOwnerIndex.handleBridgeSessionLifecycle,
2713
+ ...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
2714
+ ...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
2715
+ ...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
2716
+ ...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
2717
+ ...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
2718
+ ...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
2719
+ ...opts.permissionResponseTimeoutMs !== void 0 ? { permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs } : {},
2720
+ boundWorkspace: workspaceInput.cwd,
2721
+ sessionShellCommandEnabled,
2722
+ childEnvOverrides,
2723
+ channelFactory: secondaryChannelFactory,
2724
+ onDiagnosticLine: diagnosticSink,
2725
+ telemetry: createRuntimeBridgeTelemetry(secondaryWorkspaceHash),
2726
+ ...permissionPolicy !== void 0 ? { permissionPolicy } : {},
2727
+ ...permissionConsensusQuorum !== void 0 ? {
2728
+ permissionConsensusQuorum
2729
+ } : {},
2730
+ permissionAudit: permissionAuditPublisher,
2731
+ statusProvider: secondaryStatusProvider,
2732
+ fileSystem: createBridgeFileSystemAdapter(secondaryBridgeFsFactory),
2733
+ persistApprovalMode: /* @__PURE__ */ __name((workspace, mode) => withSettingsLock(workspace, async () => {
2734
+ const fresh = settingsRuntime.settings.loadSettings(workspace);
2735
+ fresh.setValue(WORKSPACE_SETTING_SCOPE, "tools.approvalMode", mode);
2736
+ }), "persistApprovalMode")
2737
+ });
2738
+ secondaryBridgeRef = secondaryBridge;
2739
+ runtimeBridges.push(secondaryBridge);
2740
+ internalRuntimeBridgesForCleanup.push(secondaryBridge);
2741
+ subSessionStoppers.push(secondarySubSessionLauncher.stop);
2742
+ const secondaryWorkspaceService = runtime.createDaemonWorkspaceService({
2743
+ boundWorkspace: workspaceInput.cwd,
2744
+ contextFilename: contextFilenameForInit ?? "QWEN.md",
2745
+ statusProvider: secondaryStatusProvider,
2746
+ workspaceProvidersStatusProvider: runtime.createWorkspaceProvidersStatusProvider({
2747
+ env: secondaryEnv.effectiveEnv
2748
+ }),
2749
+ workspaceSkillsStatusProvider: runtime.createWorkspaceSkillsStatusProvider(),
2750
+ isChannelLive: /* @__PURE__ */ __name(() => secondaryBridge.isChannelLive(), "isChannelLive"),
2751
+ preheatAcpChild: /* @__PURE__ */ __name(() => secondaryBridge.preheat(), "preheatAcpChild"),
2752
+ persistDisabledTools: persistDisabledToolsFn,
2753
+ persistSetting: persistSettingFn,
2754
+ persistSettings: persistSettingsFn,
2755
+ reloadDaemonEnv: /* @__PURE__ */ __name((workspace) => withSettingsLock(workspace, async () => {
2756
+ const fresh = settingsRuntime.settings.loadSettings(workspace, {
2757
+ skipLoadEnvironment: true
2758
+ });
2759
+ const result = settingsRuntime.settings.reloadEnvironment(
2760
+ fresh.merged,
2761
+ workspace
2762
+ );
2763
+ try {
2764
+ const refreshedRuntimeEnv = settingsRuntime.environment.buildRuntimeEnvironment(
2765
+ fresh.merged,
2766
+ workspace,
2767
+ daemonRuntimeBaseEnv
2768
+ );
2769
+ logRuntimeEnvFileReadFailures(workspace, refreshedRuntimeEnv);
2770
+ secondaryEnv.replace(refreshedRuntimeEnv.effectiveEnv);
2771
+ secondaryEnv.metadata.envFileReadFailed = refreshedRuntimeEnv.envFileReadFailed;
2772
+ secondaryEnv.metadata.envFileReadFailures.splice(
2773
+ 0,
2774
+ secondaryEnv.metadata.envFileReadFailures.length,
2775
+ ...refreshedRuntimeEnv.envFileReadFailures
2776
+ );
2777
+ secondaryEnv.metadata.overlayKeys.splice(
2778
+ 0,
2779
+ secondaryEnv.metadata.overlayKeys.length,
2780
+ ...refreshedRuntimeEnv.overlayKeys
2781
+ );
2782
+ secondaryEnv.metadata.envFilePaths.splice(
2783
+ 0,
2784
+ secondaryEnv.metadata.envFilePaths.length,
2785
+ ...refreshedRuntimeEnv.envFilePaths
2786
+ );
2787
+ delete secondaryEnv.metadata.fallbackReason;
2788
+ } catch (err) {
2789
+ secondaryEnv.metadata.fallbackReason = err instanceof Error ? err.message : String(err);
2790
+ daemonLog.warn(
2791
+ "failed to rebuild secondary runtime env snapshot after daemon env reload; preserving previous runtime env",
2792
+ {
2793
+ workspace,
2794
+ error: secondaryEnv.metadata.fallbackReason
2795
+ }
2796
+ );
2797
+ }
2798
+ return result;
2799
+ }), "reloadDaemonEnv"),
2800
+ queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => secondaryBridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
2801
+ invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => secondaryBridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
2802
+ refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => secondaryBridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
2803
+ publishWorkspaceEvent: /* @__PURE__ */ __name((event) => secondaryBridge.publishWorkspaceEvent(event), "publishWorkspaceEvent")
2804
+ });
2805
+ workspaceRuntimes.push({
2806
+ workspaceId: secondaryWorkspaceHash,
2807
+ workspaceCwd: workspaceInput.cwd,
2808
+ primary: false,
2809
+ trusted: secondaryTrusted,
2810
+ env: secondaryEnv.metadata,
2811
+ bridge: secondaryBridge,
2812
+ workspaceService: secondaryWorkspaceService,
2813
+ routeFileSystemFactory: secondaryBridgeFsFactory,
2814
+ clientMcpSenderRegistry: secondaryClientMcpSenderRegistry
2815
+ });
2816
+ }
2817
+ const workspaceRegistry = runtime.createWorkspaceRegistry(workspaceRuntimes, {
2818
+ sessionOwnerIndex
2819
+ });
2359
2820
  core.registerDaemonGaugeCallbacks({
2360
- sessionCount: /* @__PURE__ */ __name(() => bridge.sessionCount, "sessionCount"),
2821
+ sessionCount: /* @__PURE__ */ __name(() => workspaceRegistry.list().reduce((sum, item) => sum + item.bridge.sessionCount, 0), "sessionCount"),
2361
2822
  sseCount: /* @__PURE__ */ __name(() => runtime.getActiveSseCount(), "sseCount"),
2362
2823
  heapUsed: /* @__PURE__ */ __name(() => process.memoryUsage().heapUsed, "heapUsed")
2363
2824
  });
@@ -2397,9 +2858,15 @@ async function runQwenServe(optsIn, deps = {}) {
2397
2858
  cpuPercent,
2398
2859
  rssBytes: mem.rss,
2399
2860
  heapUsedBytes: mem.heapUsed,
2400
- activeSessions: bridge.sessionCount,
2401
- activePrompts: bridge.activePromptCount,
2402
- queuedPrompts: bridge.pendingPromptTotal ?? 0,
2861
+ activeSessions: workspaceRegistry.list().reduce((sum, item) => sum + item.bridge.sessionCount, 0),
2862
+ activePrompts: workspaceRegistry.list().reduce(
2863
+ (sum, item) => sum + (item.bridge.activePromptCount ?? 0),
2864
+ 0
2865
+ ),
2866
+ queuedPrompts: workspaceRegistry.list().reduce(
2867
+ (sum, item) => sum + (item.bridge.pendingPromptTotal ?? 0),
2868
+ 0
2869
+ ),
2403
2870
  eventLoopLagP99Ms,
2404
2871
  sseConnections: runtime.getActiveSseCount(),
2405
2872
  wsConnections: acp?.wsStreams ?? 0,
@@ -2442,6 +2909,7 @@ async function runQwenServe(optsIn, deps = {}) {
2442
2909
  }
2443
2910
  };
2444
2911
  const app2 = runtime.createServeApp(opts, () => actualPort, {
2912
+ workspaceRegistry,
2445
2913
  bridge,
2446
2914
  webShellDir,
2447
2915
  boundWorkspace,
@@ -2451,18 +2919,15 @@ async function runQwenServe(optsIn, deps = {}) {
2451
2919
  // (keepalive) and reloads them on boot (rehydration). Off by default so
2452
2920
  // direct createServeApp embeds/tests don't spawn sessions.
2453
2921
  manageScheduledTaskSessions: true,
2454
- fsFactory: runtime.resolveBridgeFsFactory({
2455
- // REST routes still return primary-relative paths, so keep their
2456
- // filesystem boundary primary-only until responses carry root IDs.
2457
- boundWorkspaces: [boundWorkspace],
2458
- trusted: trustedWorkspace,
2459
- emit: deps.fsAuditEmit,
2460
- pathLocks: sharedPathLocks,
2461
- ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2462
- }),
2922
+ fsFactory: routeFsFactory,
2463
2923
  primaryWorkspaceTrusted: trustedWorkspace,
2924
+ primaryRuntimeEnv,
2464
2925
  daemonLog,
2465
2926
  getChannelWorkerSnapshot,
2927
+ // Gate both the `channel_reload` capability and the reload route on the
2928
+ // presence of this dep, so it is advertised only when a channel worker
2929
+ // exists to reload.
2930
+ ...opts.channelSelection ? { reloadChannelWorker } : {},
2466
2931
  getPerfSnapshot: /* @__PURE__ */ __name(() => ({
2467
2932
  eventLoop: currentDaemonEventLoopMonitor.snapshot(),
2468
2933
  promptQueueWait: {
@@ -2477,6 +2942,7 @@ async function runQwenServe(optsIn, deps = {}) {
2477
2942
  }
2478
2943
  }), "getPerfSnapshot"),
2479
2944
  getMetricsSeries: /* @__PURE__ */ __name(() => metricsRing.snapshot(), "getMetricsSeries"),
2945
+ getTotalSessionAdmissionSnapshot: totalSessionAdmission.snapshot,
2480
2946
  recordDaemonRequest: /* @__PURE__ */ __name((durationMs, statusCode) => metricsRing.recordRequest(durationMs, statusCode), "recordDaemonRequest"),
2481
2947
  workspace: workspaceService,
2482
2948
  // Reverse tool channel (#5626): the SAME registry wired into `bridge` above,
@@ -2485,6 +2951,9 @@ async function runQwenServe(optsIn, deps = {}) {
2485
2951
  persistDisabledTools: persistDisabledToolsFn,
2486
2952
  persistSetting: persistSettingFn,
2487
2953
  persistSettings: persistSettingsFn,
2954
+ sessionArtifactsPersistenceAvailable: sessionArtifactsPersistenceAvailableFromSettings(
2955
+ runtimeBootSettings?.merged
2956
+ ),
2488
2957
  installAuthProvider: /* @__PURE__ */ __name((req) => withSettingsLock(
2489
2958
  boundWorkspace,
2490
2959
  async () => {
@@ -2523,6 +2992,8 @@ async function runQwenServe(optsIn, deps = {}) {
2523
2992
  }
2524
2993
  ), "installAuthProvider")
2525
2994
  });
2995
+ app2.locals.subSessionStoppers = subSessionStoppers;
2996
+ subSessionStoppers.push(subSessionLauncher.stop);
2526
2997
  return { app: app2, bridge };
2527
2998
  }, "buildRuntime");
2528
2999
  if (deps.bridge) {
@@ -2544,7 +3015,9 @@ async function runQwenServe(optsIn, deps = {}) {
2544
3015
  daemonLog,
2545
3016
  qwenCodeVersion: cliVersion,
2546
3017
  sessionShellCommandEnabled,
3018
+ sessionArtifactsPersistenceAvailable,
2547
3019
  permissionPolicy,
3020
+ multiWorkspaceCapabilitiesRequireRuntime: workspaceInputs.length > 1,
2548
3021
  getRuntimeError: /* @__PURE__ */ __name(() => runtimeStartupError, "getRuntimeError"),
2549
3022
  getChannelWorkerSnapshot,
2550
3023
  onHealthServed: deferRuntimeUntilFirstHealth ? () => startRuntimeAfterHealth?.() : void 0
@@ -2694,6 +3167,8 @@ async function runQwenServe(optsIn, deps = {}) {
2694
3167
  }, "cancelDeferredRuntimeStartup");
2695
3168
  const shutdownBridgeAfterFailedStartup = /* @__PURE__ */ __name(async (bridge) => {
2696
3169
  if (!bridge || deps.bridge) return;
3170
+ if (shutdownBridges.has(bridge)) return;
3171
+ shutdownBridges.add(bridge);
2697
3172
  try {
2698
3173
  await bridge.shutdown();
2699
3174
  } catch (shutdownErr) {
@@ -2734,7 +3209,10 @@ async function runQwenServe(optsIn, deps = {}) {
2734
3209
  await stopChannelWorkerAfterFailedStartup();
2735
3210
  disposeDaemonEventLoopMonitor();
2736
3211
  removeCurrentServePidfile();
2737
- await shutdownBridgeAfterFailedStartup(bridgeForCleanup ?? bridgeRef);
3212
+ const bridgesForCleanup = bridgeForCleanup ? [bridgeForCleanup, ...getRuntimeBridgesForCleanup()] : getRuntimeBridgesForCleanup();
3213
+ for (const bridge of [...new Set(bridgesForCleanup)]) {
3214
+ await shutdownBridgeAfterFailedStartup(bridge);
3215
+ }
2738
3216
  markRuntimeFailed(error);
2739
3217
  }, "failRuntimeStartup");
2740
3218
  const armRuntimeStartupTimer = /* @__PURE__ */ __name(() => {
@@ -2843,7 +3321,9 @@ async function runQwenServe(optsIn, deps = {}) {
2843
3321
  daemonLog.warn(`received ${signal} during drain \u2014 forcing exit`);
2844
3322
  try {
2845
3323
  channelWorker.killAllSync();
2846
- bridgeRef?.killAllSync();
3324
+ for (const runtimeBridge of getRuntimeBridgesForCleanup()) {
3325
+ runtimeBridge.killAllSync();
3326
+ }
2847
3327
  removeCurrentServePidfile();
2848
3328
  } catch (err) {
2849
3329
  daemonLog.error(
@@ -2885,6 +3365,10 @@ async function runQwenServe(optsIn, deps = {}) {
2885
3365
  closePromise = new Promise((res, rej) => {
2886
3366
  shuttingDown = true;
2887
3367
  app.locals.stopScheduledTaskKeepalive?.();
3368
+ const stoppers = app.locals.subSessionStoppers;
3369
+ if (stoppers) {
3370
+ for (const stop of stoppers) stop();
3371
+ }
2888
3372
  clearRuntimeStartAfterHealthTimer();
2889
3373
  clearRuntimeStartFallbackTimer();
2890
3374
  cancelDeferredRuntimeStartup();
@@ -2954,8 +3438,9 @@ async function runQwenServe(optsIn, deps = {}) {
2954
3438
  );
2955
3439
  });
2956
3440
  removeCurrentServePidfile();
2957
- const bridgeForShutdown = bridgeRef;
2958
- if (bridgeForShutdown) {
3441
+ for (const bridgeForShutdown of getRuntimeBridgesForCleanup()) {
3442
+ if (shutdownBridges.has(bridgeForShutdown)) continue;
3443
+ shutdownBridges.add(bridgeForShutdown);
2959
3444
  await bridgeForShutdown.shutdown().catch((err) => {
2960
3445
  daemonLog.error(
2961
3446
  "bridge shutdown error",
@@ -3034,8 +3519,8 @@ async function runQwenServe(optsIn, deps = {}) {
3034
3519
  }
3035
3520
  }, "onListening");
3036
3521
  let server;
3522
+ let httpsServer;
3037
3523
  if (tlsOptions) {
3038
- let httpsServer;
3039
3524
  try {
3040
3525
  httpsServer = https.createServer(tlsOptions, app);
3041
3526
  } catch (err) {
@@ -3046,14 +3531,40 @@ async function runQwenServe(optsIn, deps = {}) {
3046
3531
  );
3047
3532
  return;
3048
3533
  }
3049
- server = httpsServer.listen(opts.port, listenHostname, onListening);
3050
- } else {
3051
- server = app.listen(opts.port, listenHostname, onListening);
3052
3534
  }
3053
- server.once("error", (err) => {
3054
- removeCurrentServePidfile();
3055
- reject(err);
3056
- });
3535
+ const tryListen = /* @__PURE__ */ __name((attemptPort, attempt) => {
3536
+ try {
3537
+ if (httpsServer) {
3538
+ httpsServer.removeAllListeners("listening");
3539
+ server = httpsServer.listen(attemptPort, listenHostname, onListening);
3540
+ } else {
3541
+ server = app.listen(attemptPort, listenHostname, onListening);
3542
+ }
3543
+ } catch (err) {
3544
+ removeCurrentServePidfile();
3545
+ reject(err instanceof Error ? err : new Error(String(err)));
3546
+ return;
3547
+ }
3548
+ server.once("error", (err) => {
3549
+ server.close();
3550
+ const nextPort = attemptPort + 1;
3551
+ if (err.code === "EADDRINUSE" && opts.port !== 0 && nextPort <= 65535 && attempt < MAX_PORT_ATTEMPTS - 1) {
3552
+ writeStderrLine(
3553
+ `qwen serve: port ${attemptPort} is in use, trying ${nextPort}...`
3554
+ );
3555
+ tryListen(nextPort, attempt + 1);
3556
+ } else {
3557
+ if (err.code === "EADDRINUSE" && attempt > 0) {
3558
+ writeStderrLine(
3559
+ `qwen serve: all ports ${opts.port}\u2013${attemptPort} are in use`
3560
+ );
3561
+ }
3562
+ removeCurrentServePidfile();
3563
+ reject(err);
3564
+ }
3565
+ });
3566
+ }, "tryListen");
3567
+ tryListen(opts.port, 0);
3057
3568
  });
3058
3569
  }
3059
3570
  __name(runQwenServe, "runQwenServe");