@qwen-code/qwen-code 0.19.7 → 0.19.8

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 (228) hide show
  1. package/bundled/qc-helper/docs/features/channels/overview.md +15 -8
  2. package/bundled/qc-helper/docs/features/channels/plugins.md +1 -0
  3. package/bundled/qc-helper/docs/features/hooks.md +36 -34
  4. package/bundled/qc-helper/docs/features/memory.md +1 -1
  5. package/bundled/qc-helper/docs/qwen-serve.md +17 -10
  6. package/bundled/review/SKILL.md +6 -2
  7. package/chunks/{MaxSizedBox-XY5LIO5O.js → MaxSizedBox-5DT2SD7B.js} +7 -7
  8. package/chunks/{StandaloneSessionPicker-APISIRJZ.js → StandaloneSessionPicker-EYRGH6PJ.js} +23 -21
  9. package/chunks/{acpAgent-MMOSC2YA.js → acpAgent-GRFTTRHW.js} +74 -69
  10. package/chunks/{agent-TKIBLLQT.js → agent-H2DGKS77.js} +4 -4
  11. package/chunks/{agent-headless-VLX4C7KX.js → agent-headless-KFMFIT6J.js} +4 -4
  12. package/chunks/{anthropicContentGenerator-AKYPSZIV.js → anthropicContentGenerator-CPF22MA7.js} +28 -1
  13. package/chunks/{bridge-BCU73DZO.js → bridge-NA3ZQQKJ.js} +11 -10
  14. package/chunks/{ca-HCMB2I54.js → ca-MKD32FQL.js} +26 -1
  15. package/chunks/{channel-worker-supervisor-CRCVYQIE.js → channel-worker-supervisor-NZQUOEFJ.js} +3 -3
  16. package/chunks/{chunk-B4U2M63D.js → chunk-27BHARDE.js} +8 -8
  17. package/chunks/{chunk-OWVIH4HY.js → chunk-2EM7ECZD.js} +251 -71
  18. package/chunks/{chunk-YEGT55NW.js → chunk-3GNOQZDC.js} +1562 -1025
  19. package/chunks/{chunk-G7ZG7CA6.js → chunk-3UP777ZS.js} +8 -7
  20. package/chunks/{chunk-VEB3NYSO.js → chunk-5MBO76SL.js} +5 -0
  21. package/chunks/{chunk-ALZ75L2X.js → chunk-6VK6FIMQ.js} +1 -1
  22. package/chunks/{chunk-SD4N3QJ2.js → chunk-A5JOJ77H.js} +35 -14
  23. package/chunks/{chunk-NZEGNV4V.js → chunk-AYNCLGTW.js} +5 -5
  24. package/chunks/{chunk-AJBEAUIS.js → chunk-BOBOCR5H.js} +4 -3
  25. package/chunks/chunk-BOBRZZKD.js +468 -0
  26. package/chunks/{chunk-GMOWQOQQ.js → chunk-BUZ6HGL4.js} +5 -5
  27. package/chunks/{chunk-PRDFOIZF.js → chunk-BVYU3ZTI.js} +2 -2
  28. package/chunks/{chunk-TBAZMRW3.js → chunk-CD6USWHZ.js} +1 -1
  29. package/chunks/{chunk-YDSYD7UI.js → chunk-CHB5SLZZ.js} +2 -2
  30. package/chunks/{chunk-FRFFNYUY.js → chunk-DCZWC4PF.js} +2 -2
  31. package/chunks/{chunk-XSAFNANZ.js → chunk-DHOLNQLC.js} +11 -11
  32. package/chunks/{chunk-MIG5SQNL.js → chunk-DICGXFAI.js} +1 -1
  33. package/chunks/{chunk-4ZJIPVPB.js → chunk-DIWVZ3VM.js} +8 -8
  34. package/chunks/{chunk-VQWAZSXN.js → chunk-E7EMCSUG.js} +1 -1
  35. package/chunks/{chunk-Q6OEPOOC.js → chunk-EEN2TKST.js} +1 -1
  36. package/chunks/{chunk-DNV4FSN5.js → chunk-FBET5XZ2.js} +6 -4
  37. package/chunks/{chunk-QZF5U5KA.js → chunk-FQNC62B2.js} +4 -4
  38. package/chunks/{chunk-B34OV7K2.js → chunk-GGQQA4JW.js} +13 -0
  39. package/chunks/chunk-GLE2YUPU.js +34 -0
  40. package/chunks/{chunk-X265R5C6.js → chunk-GN3F6PIU.js} +1 -1
  41. package/chunks/{chunk-FTFXDZYI.js → chunk-GSHQYYIV.js} +45 -9
  42. package/chunks/{chunk-MJI36HER.js → chunk-HDOH3QYE.js} +1 -1
  43. package/chunks/{chunk-CISB3IQF.js → chunk-I6WGFJJ3.js} +63 -4
  44. package/chunks/{chunk-2NPS2UDH.js → chunk-IBY3Q3HG.js} +390 -9
  45. package/chunks/{chunk-LEIJKM7Q.js → chunk-J7RCB6N5.js} +1 -1
  46. package/chunks/{chunk-4UCTWSTP.js → chunk-JCH35JB3.js} +1 -1
  47. package/chunks/{chunk-CNSF3WO5.js → chunk-JPALE3PA.js} +3 -3
  48. package/chunks/{chunk-P7I3D7FM.js → chunk-JRQ7EVGE.js} +1 -1
  49. package/chunks/{chunk-24XYI5EI.js → chunk-JZHIQJOE.js} +3 -3
  50. package/chunks/{chunk-7JGISHHZ.js → chunk-L46XKEGM.js} +14 -153
  51. package/chunks/{chunk-HJ3GX3Y3.js → chunk-L4AMBVQG.js} +9 -9
  52. package/chunks/{chunk-JF7DFPQ5.js → chunk-LAXNEOBG.js} +1 -1
  53. package/chunks/{chunk-STAZRKOT.js → chunk-M7S4GK5Z.js} +66 -445
  54. package/chunks/{chunk-4RQIB5UZ.js → chunk-O2YT7VB4.js} +0 -34
  55. package/chunks/{chunk-QAKFYMJI.js → chunk-O33TBKDC.js} +10 -10
  56. package/chunks/chunk-O7FIRWJV.js +168 -0
  57. package/chunks/{chunk-4KJ2BPIT.js → chunk-OACJLMLD.js} +2 -38
  58. package/chunks/{chunk-6BN7NZ5Z.js → chunk-ON3JA3RU.js} +2 -2
  59. package/chunks/{chunk-IUE7YWC3.js → chunk-OQXDAMKY.js} +3 -3
  60. package/chunks/{chunk-DGHJTO2K.js → chunk-P3XEEI3X.js} +1 -1
  61. package/chunks/{chunk-U4FRHCLA.js → chunk-PMFULMLX.js} +296 -81
  62. package/chunks/{chunk-XISQIIT7.js → chunk-PUVCVELY.js} +1 -1
  63. package/chunks/{chunk-PUQLHSQ2.js → chunk-RMLZAUWH.js} +4 -4
  64. package/chunks/{chunk-JD33UY7E.js → chunk-SQ2UATK7.js} +14 -8
  65. package/chunks/{chunk-4O344UEE.js → chunk-TI3BWD4D.js} +1 -1
  66. package/chunks/{chunk-AIY5UTFI.js → chunk-TSPB77TG.js} +57 -35
  67. package/chunks/{chunk-XPJH4PKR.js → chunk-UX6OTBVD.js} +1 -1
  68. package/chunks/{chunk-GD236YPV.js → chunk-UXEW557D.js} +1 -1
  69. package/chunks/chunk-V35MD7KN.js +13 -0
  70. package/chunks/{chunk-RYFZCUJO.js → chunk-VGGOPZUL.js} +6 -5
  71. package/chunks/{chunk-65CFHNSE.js → chunk-WF4FAXDL.js} +2 -2
  72. package/chunks/{chunk-ME3YSROJ.js → chunk-WHJQ3JUS.js} +20 -8
  73. package/chunks/{chunk-BWVQN2HV.js → chunk-WQTHLB5T.js} +3 -3
  74. package/chunks/chunk-XNXVCNAT.js +88 -0
  75. package/chunks/{chunk-TDGF35EN.js → chunk-XOHNA2S6.js} +1 -1
  76. package/chunks/{chunk-GL5TV7B5.js → chunk-XYR5RUA5.js} +14 -5
  77. package/chunks/{chunk-I4A4K72C.js → chunk-YDOXPLYL.js} +244 -47
  78. package/chunks/{chunk-AFOLR6YL.js → chunk-YHKAK72D.js} +11 -11
  79. package/chunks/{chunk-RFIL6REB.js → chunk-YKZIAK7C.js} +119 -29
  80. package/chunks/chunk-Z3I3QJK3.js +47 -0
  81. package/chunks/{chunk-ADZG46HR.js → chunk-ZE6E424U.js} +1 -1
  82. package/chunks/chunk-ZL5HN75Q.js +61 -0
  83. package/chunks/{computer-use-X4KUU3NM.js → computer-use-WMY3UOBX.js} +4 -4
  84. package/chunks/{contextCommand-LAYJZF7H.js → contextCommand-LXFZRP4L.js} +6 -6
  85. package/chunks/{daemon-F3I2RXP6.js → daemon-WPAENEBW.js} +48 -0
  86. package/chunks/{daemon-status-provider-XSAFKVDS.js → daemon-status-provider-GJRXY5EN.js} +15 -13
  87. package/chunks/{de-PLLFDERI.js → de-ZFPPQVSF.js} +26 -1
  88. package/chunks/{dist-IMFFBMAT.js → dist-BEXOZXLQ.js} +1 -1
  89. package/chunks/{dist-OT7G2WNM.js → dist-E6UANPIM.js} +1 -1
  90. package/chunks/{dist-FQ5WRJPL.js → dist-H2AEJCZ5.js} +2 -2
  91. package/chunks/{dist-YTRKAVUB.js → dist-O2IRTRPP.js} +1 -1
  92. package/chunks/{dist-573HNSVO.js → dist-SCFLLYMK.js} +1 -1
  93. package/chunks/{dist-PKFTNUHO.js → dist-Z34QPAQW.js} +1 -1
  94. package/chunks/{earlyInputCapture-AERYYGXE.js → earlyInputCapture-KNOYZ4MJ.js} +4 -4
  95. package/chunks/{edit-WZTZDGCI.js → edit-OTYWAXGP.js} +5 -5
  96. package/chunks/{en-GA2RMXY5.js → en-N4EPZAQI.js} +26 -1
  97. package/chunks/{enter-worktree-DEPXBJEL.js → enter-worktree-HNYBDVCX.js} +4 -4
  98. package/chunks/{enterPlanMode-JFGXZHHJ.js → enterPlanMode-CJCNGT63.js} +4 -4
  99. package/chunks/environment-ATFTYMLZ.js +88 -0
  100. package/chunks/{errors-GMZL4QV7.js → errors-A54HAADA.js} +6 -6
  101. package/chunks/{exit-worktree-Y7XBK3VV.js → exit-worktree-DUUKOE3X.js} +4 -4
  102. package/chunks/{exitPlanMode-WQQER65F.js → exitPlanMode-AMMSXOAJ.js} +4 -4
  103. package/chunks/{fast-path-W2U6XDNO.js → fast-path-OV6NIP3K.js} +12 -3
  104. package/chunks/{fast-path-settings-RCRXH2JG.js → fast-path-settings-7RIFI3PK.js} +3 -2
  105. package/chunks/{fr-GWNQG4XH.js → fr-5WWMY53B.js} +26 -1
  106. package/chunks/{gemini-T4WX6SRW.js → gemini-NQ3WWBKB.js} +431 -135
  107. package/chunks/{geminiContentGenerator-MKQACXEJ.js → geminiContentGenerator-CDUNEJQE.js} +1 -1
  108. package/chunks/{glob-4KKSHZDF.js → glob-ROV3YS4R.js} +4 -4
  109. package/chunks/{grep-GHRYXSLZ.js → grep-NRITKDCD.js} +4 -4
  110. package/chunks/{handleAutoUpdate-HN7ZOSXY.js → handleAutoUpdate-CEZJAARW.js} +6 -6
  111. package/chunks/{initializer-SRN3IM42.js → initializer-BRFJKRRX.js} +11 -9
  112. package/chunks/{ja-2HOTA47X.js → ja-CUHZOLEJ.js} +26 -1
  113. package/chunks/{list-INTVXUPA.js → list-KVHF7O4X.js} +13 -11
  114. package/chunks/{loadedSettingsAdapter-QVHHQPGM.js → loadedSettingsAdapter-LL5PSFKX.js} +11 -9
  115. package/chunks/{ls-L654WOAT.js → ls-7MFU2QYW.js} +1 -1
  116. package/chunks/{lsp-M35KE54Y.js → lsp-XHDTPTGV.js} +2 -4
  117. package/chunks/{mcp-7V4T46RG.js → mcp-3GCXRTOQ.js} +11 -9
  118. package/chunks/{monitor-464OY2UE.js → monitor-FL2ZO33W.js} +4 -4
  119. package/chunks/{nonInteractiveCli-LJEEODU2.js → nonInteractiveCli-PTQI3DV6.js} +44 -41
  120. package/chunks/{notebook-edit-BLJYCNDO.js → notebook-edit-6PULTHL5.js} +5 -5
  121. package/chunks/{openaiContentGenerator-PFF6HYB2.js → openaiContentGenerator-YE42PKCY.js} +3 -3
  122. package/chunks/{pidfile-LIBUENIV.js → pidfile-NZYSCFRK.js} +4 -4
  123. package/chunks/{pt-2THT3YHA.js → pt-OLYN42DS.js} +26 -1
  124. package/chunks/{qwenContentGenerator-SUUHZ6CR.js → qwenContentGenerator-NX2E7PB7.js} +5 -5
  125. package/chunks/{read-file-L7TBQVX7.js → read-file-33XGP5HF.js} +2 -2
  126. package/chunks/{record-artifact-PP3LKHTS.js → record-artifact-SQ2OKRJW.js} +3 -3
  127. package/chunks/{ripGrep-CKKX3GRB.js → ripGrep-QWZLGTAN.js} +4 -4
  128. package/chunks/{ru-Z67YJHBG.js → ru-LDM3GWVQ.js} +26 -1
  129. package/chunks/{run-qwen-serve-5OKADVLE.js → run-qwen-serve-JK2DL7PI.js} +596 -143
  130. package/chunks/{scheduler-ZRW3AIDU.js → scheduler-O4IGVZKK.js} +4 -4
  131. package/chunks/{send-message-OA6MV4EU.js → send-message-76GT3JMC.js} +1 -1
  132. package/chunks/{serve-36WS32W6.js → serve-JTMIGANH.js} +13 -10
  133. package/chunks/{server-M372UENX.js → server-SGNPKX2O.js} +667 -243
  134. package/chunks/{session-F5KSNP2N.js → session-5BNM25EZ.js} +45 -42
  135. package/chunks/{settings-WFLNS3WT.js → settings-3MI4XXP6.js} +20 -16
  136. package/chunks/{shell-DEDSWN56.js → shell-YJKBE67T.js} +4 -4
  137. package/chunks/{skill-A2TL2NPC.js → skill-I22QK5XS.js} +2 -2
  138. package/chunks/{spawnChannel-RQHUWTCL.js → spawnChannel-UNV6W4DU.js} +6 -6
  139. package/chunks/{src-XKZMNHXS.js → src-BBQSM46M.js} +8 -4
  140. package/chunks/{startInteractiveUI-REKSTOHU.js → startInteractiveUI-JII36UGN.js} +619 -288
  141. package/chunks/{task-create-RPFZNB4B.js → task-create-WCHTB435.js} +2 -2
  142. package/chunks/{task-update-5WUG5MVQ.js → task-update-XYWMHJGJ.js} +2 -2
  143. package/chunks/{team-create-TBQVWAG7.js → team-create-A7NUU5AQ.js} +4 -4
  144. package/chunks/{team-plan-approval-FZPGUSHJ.js → team-plan-approval-TOQRJ2KI.js} +4 -4
  145. package/chunks/{theme-manager-DQZVNSOC.js → theme-manager-WZ4RRMMB.js} +4 -4
  146. package/chunks/{tool-search-FDQ3SLNJ.js → tool-search-SZ4EFS2T.js} +3 -3
  147. package/chunks/total-session-admission-ULXJWXFV.js +72 -0
  148. package/chunks/{trustedFolders-Z475EIHL.js → trustedFolders-LAZZPZ3D.js} +5 -5
  149. package/chunks/{updateCheck-E2ZX7RL7.js → updateCheck-KONLM73X.js} +5 -5
  150. package/chunks/{validateNonInterActiveAuth-O4ECBHQL.js → validateNonInterActiveAuth-MPKSRCXD.js} +41 -38
  151. package/chunks/{version-CEDD6ZZR.js → version-NO2XSNNP.js} +1 -1
  152. package/chunks/{workflow-CQQ4J4I6.js → workflow-WO2H6NRI.js} +5 -5
  153. package/chunks/{workspace-providers-status-MVYXMYDG.js → workspace-providers-status-3W7E7DFW.js} +14 -11
  154. package/chunks/workspace-registry-SXJZNN3O.js +74 -0
  155. package/chunks/{workspace-service-OMBR6ZLG.js → workspace-service-CZRQZ4Q4.js} +17 -15
  156. package/chunks/{workspace-skills-status-IMMQ7CAY.js → workspace-skills-status-K7WFREPD.js} +12 -10
  157. package/chunks/{write-file-VWGY7AJP.js → write-file-PX2Z7IBE.js} +5 -5
  158. package/chunks/{zh-7XVVRTDH.js → zh-J4F6QWQV.js} +26 -1
  159. package/chunks/{zh-TW-DPH554OG.js → zh-TW-XVDWOLSW.js} +26 -1
  160. package/cli.js +11 -11
  161. package/locales/ca.js +30 -0
  162. package/locales/de.js +30 -0
  163. package/locales/en.js +30 -0
  164. package/locales/fr.js +30 -0
  165. package/locales/ja.js +30 -0
  166. package/locales/pt.js +30 -0
  167. package/locales/ru.js +30 -0
  168. package/locales/zh-TW.js +30 -0
  169. package/locales/zh.js +30 -0
  170. package/node_modules/@qwen-code/audio-capture/package.json +1 -1
  171. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
  172. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
  173. package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
  174. package/package.json +3 -3
  175. package/web-shell/assets/{arc-C7hjaa7g.js → arc-BWyoJpY2.js} +1 -1
  176. package/web-shell/assets/{architectureDiagram-3BPJPVTR-pm9KtMZY.js → architectureDiagram-3BPJPVTR-BT0mGrz2.js} +1 -1
  177. package/web-shell/assets/{blockDiagram-GPEHLZMM-CApElKsU.js → blockDiagram-GPEHLZMM-BLgUWvyf.js} +1 -1
  178. package/web-shell/assets/{c4Diagram-AAUBKEIU-BeDe0-9N.js → c4Diagram-AAUBKEIU-DYx9M7oU.js} +1 -1
  179. package/web-shell/assets/channel-wmPUGHtg.js +1 -0
  180. package/web-shell/assets/{chunk-2J33WTMH-DJEkmLdl.js → chunk-2J33WTMH-CfMHWbuZ.js} +1 -1
  181. package/web-shell/assets/{chunk-4BX2VUAB-DXX8gdpe.js → chunk-4BX2VUAB-B1URoqEV.js} +1 -1
  182. package/web-shell/assets/{chunk-55IACEB6-DORmk1kQ.js → chunk-55IACEB6-DAIaM4QF.js} +1 -1
  183. package/web-shell/assets/{chunk-727SXJPM-DWmO4mCZ.js → chunk-727SXJPM-B2X34knw.js} +1 -1
  184. package/web-shell/assets/{chunk-AQP2D5EJ-C7LRaYw2.js → chunk-AQP2D5EJ-Cif-zLTQ.js} +1 -1
  185. package/web-shell/assets/{chunk-FMBD7UC4-CCdXgyC5.js → chunk-FMBD7UC4-H18WCXdY.js} +1 -1
  186. package/web-shell/assets/{chunk-ND2GUHAM-SyL_xvWc.js → chunk-ND2GUHAM-YFtetHi0.js} +1 -1
  187. package/web-shell/assets/{chunk-QZHKN3VN-BzOuCKxa.js → chunk-QZHKN3VN-By2hiH3r.js} +1 -1
  188. package/web-shell/assets/classDiagram-4FO5ZUOK-BA2ljEjW.js +1 -0
  189. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BA2ljEjW.js +1 -0
  190. package/web-shell/assets/{cose-bilkent-S5V4N54A-BMPWyDKc.js → cose-bilkent-S5V4N54A-VrcnnLZu.js} +1 -1
  191. package/web-shell/assets/{dagre-BM42HDAG-B_GnPWik.js → dagre-BM42HDAG-CGo-IaVV.js} +1 -1
  192. package/web-shell/assets/{diagram-2AECGRRQ-fJqMc3S_.js → diagram-2AECGRRQ-Dl4QjzIB.js} +1 -1
  193. package/web-shell/assets/{diagram-5GNKFQAL-ximV3O9D.js → diagram-5GNKFQAL-qMLmsO0u.js} +1 -1
  194. package/web-shell/assets/{diagram-KO2AKTUF-2vVyjzqw.js → diagram-KO2AKTUF-CHlmuxPI.js} +1 -1
  195. package/web-shell/assets/{diagram-LMA3HP47-Dckcx1sT.js → diagram-LMA3HP47-BUwU3GwT.js} +1 -1
  196. package/web-shell/assets/{diagram-OG6HWLK6-BAVv47ga.js → diagram-OG6HWLK6-HEhwPDUM.js} +1 -1
  197. package/web-shell/assets/{erDiagram-TEJ5UH35-Bn3nf5J0.js → erDiagram-TEJ5UH35-1n0llBmM.js} +1 -1
  198. package/web-shell/assets/{flowDiagram-I6XJVG4X-BIbGF9JT.js → flowDiagram-I6XJVG4X-BN74uMnt.js} +1 -1
  199. package/web-shell/assets/{ganttDiagram-6RSMTGT7-CDbhb3AH.js → ganttDiagram-6RSMTGT7-BoOq78i3.js} +1 -1
  200. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-CbKG1a_w.js → gitGraphDiagram-PVQCEYII-CN8b00c8.js} +1 -1
  201. package/web-shell/assets/index-CNwoO1Cn.js +783 -0
  202. package/web-shell/assets/index-CWQ0z6kZ.css +5 -0
  203. package/web-shell/assets/{infoDiagram-5YYISTIA-DUFxTy8m.js → infoDiagram-5YYISTIA-CCurnIna.js} +1 -1
  204. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-D69hrBG8.js → ishikawaDiagram-YF4QCWOH-AwuRqdUP.js} +1 -1
  205. package/web-shell/assets/{journeyDiagram-JHISSGLW-DsvEw51Y.js → journeyDiagram-JHISSGLW-B7IICk-E.js} +1 -1
  206. package/web-shell/assets/{kanban-definition-UN3LZRKU-lFFjZEYd.js → kanban-definition-UN3LZRKU-BYF0OKhx.js} +1 -1
  207. package/web-shell/assets/{linear-Bo5bWzvo.js → linear-GWWguGfD.js} +1 -1
  208. package/web-shell/assets/{mermaid.core-C_HKMJx5.js → mermaid.core-JqtkxvCl.js} +5 -5
  209. package/web-shell/assets/{mindmap-definition-RKZ34NQL-DlV-NUTs.js → mindmap-definition-RKZ34NQL-B0MmHsZ6.js} +1 -1
  210. package/web-shell/assets/{pieDiagram-4H26LBE5-B2e6FH2a.js → pieDiagram-4H26LBE5-DhImUZLQ.js} +1 -1
  211. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-D75kSk-b.js → quadrantDiagram-W4KKPZXB-DGeSC3DT.js} +1 -1
  212. package/web-shell/assets/{requirementDiagram-4Y6WPE33-CQ6xakhM.js → requirementDiagram-4Y6WPE33-DkspY6Re.js} +1 -1
  213. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-J_XTKrcY.js → sankeyDiagram-5OEKKPKP-CaOofS2x.js} +1 -1
  214. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-D7jTcBtf.js → sequenceDiagram-3UESZ5HK-DFQ_kFnN.js} +1 -1
  215. package/web-shell/assets/{stateDiagram-AJRCARHV-CrlM_OT3.js → stateDiagram-AJRCARHV-D3snw0Tz.js} +1 -1
  216. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BbSm_9d0.js +1 -0
  217. package/web-shell/assets/{timeline-definition-PNZ67QCA-5oZi76Ef.js → timeline-definition-PNZ67QCA-l4zH8nLM.js} +1 -1
  218. package/web-shell/assets/{vennDiagram-CIIHVFJN-DO5YptPK.js → vennDiagram-CIIHVFJN-BnRlA98M.js} +1 -1
  219. package/web-shell/assets/{wardley-L42UT6IY-4t1eJDvM.js → wardley-L42UT6IY-BS0xUdmd.js} +1 -1
  220. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-DKZc661S.js → wardleyDiagram-YWT4CUSO-DKGBUWyQ.js} +1 -1
  221. package/web-shell/assets/{xychartDiagram-2RQKCTM6-su9hp08G.js → xychartDiagram-2RQKCTM6-DVb2HuOB.js} +1 -1
  222. package/web-shell/index.html +2 -2
  223. package/web-shell/assets/channel-BNf1dW-j.js +0 -1
  224. package/web-shell/assets/classDiagram-4FO5ZUOK-uOIGlzgi.js +0 -1
  225. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-uOIGlzgi.js +0 -1
  226. package/web-shell/assets/index-CnE2ur2L.js +0 -779
  227. package/web-shell/assets/index-hSKXrlSE.css +0 -5
  228. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Bs4TK_84.js +0 -1
@@ -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,
@@ -31,16 +28,29 @@ import {
31
28
  positiveFiniteOrNull,
32
29
  require_express,
33
30
  resolveWebShellDir
34
- } from "./chunk-RFIL6REB.js";
31
+ } from "./chunk-YKZIAK7C.js";
35
32
  import {
36
33
  isLoopbackBind
37
34
  } from "./chunk-RNBYOUGV.js";
38
35
  import "./chunk-3HX5LZ6R.js";
39
36
  import "./chunk-7RYW5LQV.js";
37
+ import {
38
+ RUNTIME_STARTUP_CANCELLED_MESSAGE
39
+ } from "./chunk-GHOTR7HL.js";
40
+ import {
41
+ LOAD_REPLAY_META_KEY
42
+ } from "./chunk-AGHU5VRK.js";
43
+ import {
44
+ DEFAULT_COMPACTED_REPLAY_MAX_BYTES,
45
+ normalizeCompactedReplayMaxBytes
46
+ } from "./chunk-GLE2YUPU.js";
47
+ import {
48
+ canonicalizeWorkspace
49
+ } from "./chunk-ER3BKOLB.js";
40
50
  import {
41
51
  loadServeFastPathSettings,
42
52
  preResolveServeFastPathHomeEnvOverrides
43
- } from "./chunk-DNV4FSN5.js";
53
+ } from "./chunk-FBET5XZ2.js";
44
54
  import {
45
55
  QWEN_SERVER_TOKEN_ENV
46
56
  } from "./chunk-S6RLAIUR.js";
@@ -50,16 +60,11 @@ import {
50
60
  import {
51
61
  getGlobalQwenDirLite,
52
62
  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";
63
+ } from "./chunk-O2YT7VB4.js";
64
+ import "./chunk-Z3I3QJK3.js";
60
65
  import {
61
66
  getCliVersion
62
- } from "./chunk-GD236YPV.js";
67
+ } from "./chunk-UXEW557D.js";
63
68
  import "./chunk-43W4YSO6.js";
64
69
  import {
65
70
  writeStderrLine,
@@ -105,7 +110,7 @@ var DuplicateWorkspaceInputError = class extends Error {
105
110
  }
106
111
  constructor(workspace) {
107
112
  super(
108
- `Duplicate --workspace value resolves to ${JSON.stringify(workspace)}. Multi-workspace serve is not enabled; pass one --workspace.`
113
+ `Duplicate --workspace value resolves to ${JSON.stringify(workspace)}. Pass distinct --workspace values.`
109
114
  );
110
115
  this.name = "DuplicateWorkspaceInputError";
111
116
  }
@@ -116,22 +121,11 @@ var NestedWorkspaceInputError = class extends Error {
116
121
  }
117
122
  constructor(parent, child) {
118
123
  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.`
124
+ `Nested --workspace values are not supported yet: ${JSON.stringify(child)} is inside ${JSON.stringify(parent)}. Pass non-nested --workspace values.`
120
125
  );
121
126
  this.name = "NestedWorkspaceInputError";
122
127
  }
123
128
  };
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
129
  var MissingWorkspaceInputError = class extends Error {
136
130
  static {
137
131
  __name(this, "MissingWorkspaceInputError");
@@ -156,7 +150,7 @@ function isNestedWorkspace(parent, child) {
156
150
  return parent !== child && isWithinRoot(child, parent);
157
151
  }
158
152
  __name(isNestedWorkspace, "isNestedWorkspace");
159
- function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
153
+ function rejectDuplicateOrNestedWorkspaceInputs(workspaces) {
160
154
  if (workspaces.length <= 1) return;
161
155
  let canonicalWorkspaces;
162
156
  try {
@@ -164,7 +158,7 @@ function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
164
158
  (workspace) => canonicalizeWorkspace(workspace)
165
159
  );
166
160
  } catch {
167
- throw new MultipleWorkspaceInputError();
161
+ return;
168
162
  }
169
163
  const seen = /* @__PURE__ */ new Set();
170
164
  for (const workspace of canonicalWorkspaces) {
@@ -185,15 +179,14 @@ function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
185
179
  }
186
180
  }
187
181
  }
188
- throw new MultipleWorkspaceInputError();
189
182
  }
190
- __name(rejectUnsupportedMultiWorkspaceInputs, "rejectUnsupportedMultiWorkspaceInputs");
191
- function resolveSingleWorkspaceInput(workspace) {
183
+ __name(rejectDuplicateOrNestedWorkspaceInputs, "rejectDuplicateOrNestedWorkspaceInputs");
184
+ function resolveWorkspaceInputs(workspace) {
192
185
  const workspaces = normalizeWorkspaceInputs(workspace);
193
- rejectUnsupportedMultiWorkspaceInputs(workspaces);
194
- return workspaces[0];
186
+ rejectDuplicateOrNestedWorkspaceInputs(workspaces);
187
+ return workspaces;
195
188
  }
196
- __name(resolveSingleWorkspaceInput, "resolveSingleWorkspaceInput");
189
+ __name(resolveWorkspaceInputs, "resolveWorkspaceInputs");
197
190
 
198
191
  // packages/cli/src/serve/permission-audit.ts
199
192
  init_esbuild_shims();
@@ -939,11 +932,21 @@ function isNonNegativeIntegerOrInfinity(value) {
939
932
  return value === Number.POSITIVE_INFINITY || Number.isFinite(value) && Number.isInteger(value) && value >= 0;
940
933
  }
941
934
  __name(isNonNegativeIntegerOrInfinity, "isNonNegativeIntegerOrInfinity");
935
+ function deriveDefaultMaxTotalSessions(maxSessionsPerWorkspace, workspaceCount) {
936
+ if (workspaceCount <= 1) return void 0;
937
+ const perWorkspace = maxSessionsPerWorkspace ?? DEFAULT_MAX_SESSIONS;
938
+ if (perWorkspace === 0 || perWorkspace === Number.POSITIVE_INFINITY) {
939
+ return void 0;
940
+ }
941
+ return perWorkspace * workspaceCount;
942
+ }
943
+ __name(deriveDefaultMaxTotalSessions, "deriveDefaultMaxTotalSessions");
942
944
  function isNonNegativeIntegerMs(value) {
943
945
  return Number.isFinite(value) && Number.isInteger(value) && value >= 0;
944
946
  }
945
947
  __name(isNonNegativeIntegerMs, "isNonNegativeIntegerMs");
946
948
  var MAX_TIMEOUT_MS = 2147483647;
949
+ var MAX_PORT_ATTEMPTS = 10;
947
950
  function assertTimerDelayInRange(name, value) {
948
951
  if (value > MAX_TIMEOUT_MS) {
949
952
  throw new TypeError(
@@ -1082,8 +1085,8 @@ __name(withSettingsLock, "withSettingsLock");
1082
1085
  var channelWorkerRuntimePromise;
1083
1086
  async function loadChannelWorkerRuntime() {
1084
1087
  channelWorkerRuntimePromise ??= Promise.all([
1085
- import("./channel-worker-supervisor-CRCVYQIE.js"),
1086
- import("./pidfile-LIBUENIV.js")
1088
+ import("./channel-worker-supervisor-NZQUOEFJ.js"),
1089
+ import("./pidfile-NZYSCFRK.js")
1087
1090
  ]).then(([supervisor, pidfile]) => ({
1088
1091
  createChannelWorkerSupervisor: supervisor.createChannelWorkerSupervisor,
1089
1092
  channelServicePidfile: pidfile
@@ -1154,7 +1157,7 @@ function shouldPreheatBridge(deps) {
1154
1157
  __name(shouldPreheatBridge, "shouldPreheatBridge");
1155
1158
  var coreRuntimePromise;
1156
1159
  function loadCoreRuntime() {
1157
- coreRuntimePromise ??= import("./src-XKZMNHXS.js");
1160
+ coreRuntimePromise ??= import("./src-BBQSM46M.js");
1158
1161
  return coreRuntimePromise;
1159
1162
  }
1160
1163
  __name(loadCoreRuntime, "loadCoreRuntime");
@@ -1184,11 +1187,13 @@ __name(resolveDaemonLogBaseDirForRun, "resolveDaemonLogBaseDirForRun");
1184
1187
  var settingsRuntimePromise;
1185
1188
  function loadSettingsRuntimeModules() {
1186
1189
  settingsRuntimePromise ??= Promise.all([
1187
- import("./settings-WFLNS3WT.js"),
1188
- import("./loadedSettingsAdapter-QVHHQPGM.js"),
1189
- import("./trustedFolders-Z475EIHL.js")
1190
- ]).then(([settings, loadedSettingsAdapter, trustedFolders]) => ({
1190
+ import("./settings-3MI4XXP6.js"),
1191
+ import("./environment-ATFTYMLZ.js"),
1192
+ import("./loadedSettingsAdapter-LL5PSFKX.js"),
1193
+ import("./trustedFolders-LAZZPZ3D.js")
1194
+ ]).then(([settings, environment, loadedSettingsAdapter, trustedFolders]) => ({
1191
1195
  settings,
1196
+ environment,
1192
1197
  loadedSettingsAdapter,
1193
1198
  trustedFolders
1194
1199
  }));
@@ -1204,16 +1209,20 @@ async function loadServeRuntimeModules() {
1204
1209
  workspaceTypesModule,
1205
1210
  daemonStatusProviderModule,
1206
1211
  workspaceProvidersStatusModule,
1207
- workspaceSkillsStatusModule
1212
+ workspaceSkillsStatusModule,
1213
+ totalSessionAdmissionModule,
1214
+ workspaceRegistryModule
1208
1215
  ] = await Promise.all([
1209
- import("./server-M372UENX.js"),
1210
- import("./bridge-BCU73DZO.js"),
1211
- import("./spawnChannel-RQHUWTCL.js"),
1212
- import("./workspace-service-OMBR6ZLG.js"),
1216
+ import("./server-SGNPKX2O.js"),
1217
+ import("./bridge-NA3ZQQKJ.js"),
1218
+ import("./spawnChannel-UNV6W4DU.js"),
1219
+ import("./workspace-service-CZRQZ4Q4.js"),
1213
1220
  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")
1221
+ import("./daemon-status-provider-GJRXY5EN.js"),
1222
+ import("./workspace-providers-status-3W7E7DFW.js"),
1223
+ import("./workspace-skills-status-K7WFREPD.js"),
1224
+ import("./total-session-admission-ULXJWXFV.js"),
1225
+ import("./workspace-registry-SXJZNN3O.js")
1217
1226
  ]);
1218
1227
  return {
1219
1228
  createServeApp: serverModule.createServeApp,
@@ -1226,7 +1235,9 @@ async function loadServeRuntimeModules() {
1226
1235
  WorkspaceSettingsPartialPersistError: workspaceTypesModule.WorkspaceSettingsPartialPersistError,
1227
1236
  createDaemonStatusProvider: daemonStatusProviderModule.createDaemonStatusProvider,
1228
1237
  createWorkspaceProvidersStatusProvider: workspaceProvidersStatusModule.createWorkspaceProvidersStatusProvider,
1229
- createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider
1238
+ createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider,
1239
+ createTotalSessionAdmissionController: totalSessionAdmissionModule.createTotalSessionAdmissionController,
1240
+ createWorkspaceRegistry: workspaceRegistryModule.createWorkspaceRegistry
1230
1241
  };
1231
1242
  }
1232
1243
  __name(loadServeRuntimeModules, "loadServeRuntimeModules");
@@ -1422,6 +1433,7 @@ function createBootstrapServeApp(input) {
1422
1433
  qwenCodeVersion,
1423
1434
  sessionShellCommandEnabled,
1424
1435
  permissionPolicy,
1436
+ multiWorkspaceCapabilitiesRequireRuntime,
1425
1437
  getRuntimeError,
1426
1438
  getChannelWorkerSnapshot,
1427
1439
  onHealthServed
@@ -1458,6 +1470,17 @@ function createBootstrapServeApp(input) {
1458
1470
  app.get(BOOTSTRAP_HEALTH_PATH, healthHandler);
1459
1471
  }
1460
1472
  app.get(BOOTSTRAP_CAPABILITIES_PATH, (_req, res) => {
1473
+ if (multiWorkspaceCapabilitiesRequireRuntime) {
1474
+ const runtimeError = getRuntimeError();
1475
+ if (runtimeError === void 0) {
1476
+ res.setHeader("Retry-After", "1");
1477
+ }
1478
+ res.status(503).json({
1479
+ error: runtimeError ? "Daemon runtime failed to start" : "Daemon runtime is still starting",
1480
+ code: runtimeError ? "daemon_runtime_failed" : "daemon_runtime_starting"
1481
+ });
1482
+ return;
1483
+ }
1461
1484
  res.status(200).json(
1462
1485
  createBootstrapCapabilities({
1463
1486
  opts,
@@ -1518,11 +1541,13 @@ function createBootstrapServeApp(input) {
1518
1541
  },
1519
1542
  limits: {
1520
1543
  maxSessions: advertisedMaxSessions(opts.maxSessions),
1544
+ maxTotalSessions: positiveFiniteOrNull(opts.maxTotalSessions),
1521
1545
  maxPendingPromptsPerSession: advertisedMaxPendingPromptsPerSession(
1522
1546
  opts.maxPendingPromptsPerSession
1523
1547
  ),
1524
1548
  listenerMaxConnections: listenerMaxConnections(opts.maxConnections),
1525
1549
  eventRingSize: opts.eventRingSize ?? DEFAULT_EVENT_RING_SIZE,
1550
+ compactedReplayMaxBytes: opts.compactedReplayMaxBytes ?? DEFAULT_COMPACTED_REPLAY_MAX_BYTES,
1526
1551
  promptDeadlineMs: positiveFiniteOrNull(opts.promptDeadlineMs),
1527
1552
  writerIdleTimeoutMs: positiveFiniteOrNull(opts.writerIdleTimeoutMs),
1528
1553
  channelIdleTimeoutMs: channelIdleTimeoutMs(opts.channelIdleTimeoutMs),
@@ -1663,6 +1688,9 @@ async function runQwenServe(optsIn, deps = {}) {
1663
1688
  }
1664
1689
  };
1665
1690
  preResolveServeFastPathHomeEnvOverrides();
1691
+ const daemonRuntimeBaseEnv = Object.freeze({
1692
+ ...process.env
1693
+ });
1666
1694
  const rawToken = optsIn.token ?? process.env[QWEN_SERVER_TOKEN_ENV];
1667
1695
  const token = typeof rawToken === "string" && rawToken.trim().length > 0 ? rawToken.trim() : void 0;
1668
1696
  const sessionShellCommandEnabled = optsIn.enableSessionShell === true && token !== void 0;
@@ -1684,7 +1712,8 @@ async function runQwenServe(optsIn, deps = {}) {
1684
1712
  const chromeExtensionOriginAllowed = hasChromeExtensionOrigin(
1685
1713
  optsIn.allowOrigins
1686
1714
  );
1687
- const rawWorkspace = resolveSingleWorkspaceInput(optsIn.workspace);
1715
+ const rawWorkspaces = resolveWorkspaceInputs(optsIn.workspace);
1716
+ const rawWorkspace = rawWorkspaces[0];
1688
1717
  const opts = {
1689
1718
  ...optsIn,
1690
1719
  token,
@@ -1830,35 +1859,76 @@ async function runQwenServe(optsIn, deps = {}) {
1830
1859
  "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
1860
  );
1832
1861
  }
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()) {
1862
+ const validateAndCanonicalizeWorkspace = /* @__PURE__ */ __name((workspace) => {
1863
+ if (!path.isAbsolute(workspace)) {
1841
1864
  throw new Error(
1842
- `Invalid --workspace "${rawWorkspace}": exists but is not a directory.`
1865
+ `Invalid --workspace "${workspace}": must be an absolute path.`
1843
1866
  );
1844
1867
  }
1845
- } catch (err) {
1846
- if (err && typeof err === "object" && "code" in err) {
1847
- const code = err.code;
1848
- if (code === "ENOENT") {
1868
+ try {
1869
+ const stats = fs.statSync(workspace);
1870
+ if (!stats.isDirectory()) {
1849
1871
  throw new Error(
1850
- `Invalid --workspace "${rawWorkspace}": directory does not exist.`
1872
+ `Invalid --workspace "${workspace}": exists but is not a directory.`
1851
1873
  );
1852
1874
  }
1853
- if (code === "EACCES" || code === "EPERM") {
1875
+ } catch (err) {
1876
+ if (err && typeof err === "object" && "code" in err) {
1877
+ const code = err.code;
1878
+ if (code === "ENOENT") {
1879
+ throw new Error(
1880
+ `Invalid --workspace "${workspace}": directory does not exist.`
1881
+ );
1882
+ }
1883
+ if (code === "EACCES" || code === "EPERM") {
1884
+ throw new Error(
1885
+ `Invalid --workspace "${workspace}": permission denied (${String(code)}). The path exists but cannot be stat'd by the current user.`
1886
+ );
1887
+ }
1888
+ }
1889
+ throw err;
1890
+ }
1891
+ return canonicalizeWorkspace(workspace);
1892
+ }, "validateAndCanonicalizeWorkspace");
1893
+ const workspaceInputs = rawWorkspaces.map((workspace) => ({
1894
+ raw: workspace,
1895
+ cwd: validateAndCanonicalizeWorkspace(workspace)
1896
+ }));
1897
+ const boundWorkspace = workspaceInputs[0].cwd;
1898
+ const seenCanonicalWorkspaces = /* @__PURE__ */ new Set();
1899
+ for (const workspace of workspaceInputs) {
1900
+ if (seenCanonicalWorkspaces.has(workspace.cwd)) {
1901
+ throw new Error(
1902
+ `Duplicate --workspace value resolves to ${JSON.stringify(
1903
+ workspace.cwd
1904
+ )}.`
1905
+ );
1906
+ }
1907
+ seenCanonicalWorkspaces.add(workspace.cwd);
1908
+ }
1909
+ for (let i = 0; i < workspaceInputs.length; i++) {
1910
+ for (let j = i + 1; j < workspaceInputs.length; j++) {
1911
+ const first = workspaceInputs[i].cwd;
1912
+ const second = workspaceInputs[j].cwd;
1913
+ const firstRel = path.relative(first, second);
1914
+ const secondRel = path.relative(second, first);
1915
+ if (firstRel && !firstRel.startsWith("..") && !path.isAbsolute(firstRel)) {
1854
1916
  throw new Error(
1855
- `Invalid --workspace "${rawWorkspace}": permission denied (${String(code)}). The path exists but cannot be stat'd by the current user.`
1917
+ `Nested --workspace values are not supported: ${JSON.stringify(second)} is inside ${JSON.stringify(first)}.`
1918
+ );
1919
+ }
1920
+ if (secondRel && !secondRel.startsWith("..") && !path.isAbsolute(secondRel)) {
1921
+ throw new Error(
1922
+ `Nested --workspace values are not supported: ${JSON.stringify(first)} is inside ${JSON.stringify(second)}.`
1856
1923
  );
1857
1924
  }
1858
1925
  }
1859
- throw err;
1860
1926
  }
1861
- const boundWorkspace = canonicalizeWorkspace(rawWorkspace);
1927
+ if (workspaceInputs.length > 1 && deps.bridge) {
1928
+ throw new Error(
1929
+ "Injected bridge dependencies are only supported with a single workspace; multiple --workspace values require runQwenServe to construct one bridge per workspace."
1930
+ );
1931
+ }
1862
1932
  let contextFilenameForInit;
1863
1933
  let permissionPolicy;
1864
1934
  let permissionConsensusQuorum;
@@ -1919,6 +1989,13 @@ async function runQwenServe(optsIn, deps = {}) {
1919
1989
  );
1920
1990
  }
1921
1991
  }
1992
+ if (opts.maxTotalSessions !== void 0) {
1993
+ if (!isNonNegativeIntegerOrInfinity(opts.maxTotalSessions)) {
1994
+ throw new TypeError(
1995
+ `Invalid maxTotalSessions: ${opts.maxTotalSessions}. Must be a non-negative integer (0 / Infinity = unlimited).`
1996
+ );
1997
+ }
1998
+ }
1922
1999
  if (opts.maxPendingPromptsPerSession !== void 0) {
1923
2000
  if (!isNonNegativeIntegerOrInfinity(opts.maxPendingPromptsPerSession)) {
1924
2001
  throw new TypeError(
@@ -1933,6 +2010,9 @@ async function runQwenServe(optsIn, deps = {}) {
1933
2010
  );
1934
2011
  }
1935
2012
  }
2013
+ if (opts.compactedReplayMaxBytes !== void 0) {
2014
+ normalizeCompactedReplayMaxBytes(opts.compactedReplayMaxBytes);
2015
+ }
1936
2016
  if (opts.writerIdleTimeoutMs !== void 0) {
1937
2017
  if (!isPositiveIntegerMs(opts.writerIdleTimeoutMs)) {
1938
2018
  throw new TypeError(
@@ -1968,6 +2048,10 @@ async function runQwenServe(optsIn, deps = {}) {
1968
2048
  );
1969
2049
  }
1970
2050
  }
2051
+ opts.maxTotalSessions ??= deriveDefaultMaxTotalSessions(
2052
+ opts.maxSessions,
2053
+ workspaceInputs.length
2054
+ );
1971
2055
  const inheritedNoPool = process.env["QWEN_SERVE_NO_MCP_POOL"] === "1";
1972
2056
  if (opts.mcpPoolActive === void 0 && inheritedNoPool) {
1973
2057
  opts.mcpPoolActive = false;
@@ -2005,6 +2089,7 @@ async function runQwenServe(optsIn, deps = {}) {
2005
2089
  let runtimeApp;
2006
2090
  let runtimeAppForCleanup;
2007
2091
  let bridgeRef = deps.bridge;
2092
+ const internalRuntimeBridgesForCleanup = [];
2008
2093
  let daemonEventLoopMonitor;
2009
2094
  let daemonMetricsSampler;
2010
2095
  let runtimeStartupError;
@@ -2047,6 +2132,17 @@ async function runQwenServe(optsIn, deps = {}) {
2047
2132
  () => bridgeRef,
2048
2133
  () => runtimeStartupError
2049
2134
  );
2135
+ const shutdownBridges = /* @__PURE__ */ new WeakSet();
2136
+ const getRuntimeBridgesForCleanup = /* @__PURE__ */ __name(() => {
2137
+ const appForCleanup = runtimeApp ?? runtimeAppForCleanup;
2138
+ const registry = appForCleanup?.locals?.["workspaceRegistry"];
2139
+ const bridges = [
2140
+ ...registry ? registry.list().map((runtime) => runtime.bridge) : [],
2141
+ ...bridgeRef ? [bridgeRef] : [],
2142
+ ...internalRuntimeBridgesForCleanup
2143
+ ];
2144
+ return [...new Set(bridges)];
2145
+ }, "getRuntimeBridgesForCleanup");
2050
2146
  const buildRuntime = /* @__PURE__ */ __name(async () => {
2051
2147
  const [runtime, core, settingsRuntime, resolvedCliVersion] = await Promise.all([
2052
2148
  loadServeRuntimeModules(),
@@ -2073,6 +2169,43 @@ async function runQwenServe(optsIn, deps = {}) {
2073
2169
  { workspace: boundWorkspace }
2074
2170
  );
2075
2171
  }
2172
+ const runtimeEnvSnapshot = runtimeBootSettings ? settingsRuntime.environment.buildRuntimeEnvironment(
2173
+ runtimeBootSettings.merged,
2174
+ boundWorkspace,
2175
+ daemonRuntimeBaseEnv
2176
+ ) : {
2177
+ effectiveEnv: { ...daemonRuntimeBaseEnv },
2178
+ overlayKeys: Object.freeze([]),
2179
+ envFilePaths: Object.freeze([]),
2180
+ envFileReadFailed: false,
2181
+ envFileReadFailures: Object.freeze([])
2182
+ };
2183
+ const logRuntimeEnvFileReadFailures = /* @__PURE__ */ __name((workspace, snapshot) => {
2184
+ if (!snapshot.envFileReadFailed) return;
2185
+ const failedFiles = snapshot.envFileReadFailures ?? [];
2186
+ daemonLog.warn("one or more runtime env files could not be read", {
2187
+ workspace,
2188
+ ...failedFiles.length > 0 ? { failedFiles } : {}
2189
+ });
2190
+ }, "logRuntimeEnvFileReadFailures");
2191
+ logRuntimeEnvFileReadFailures(boundWorkspace, runtimeEnvSnapshot);
2192
+ const runtimeEffectiveEnv = {
2193
+ ...runtimeEnvSnapshot.effectiveEnv
2194
+ };
2195
+ const replaceRuntimeEffectiveEnv = /* @__PURE__ */ __name((nextEnv) => {
2196
+ for (const key of Object.keys(runtimeEffectiveEnv)) {
2197
+ delete runtimeEffectiveEnv[key];
2198
+ }
2199
+ Object.assign(runtimeEffectiveEnv, nextEnv);
2200
+ }, "replaceRuntimeEffectiveEnv");
2201
+ const primaryRuntimeEnv = {
2202
+ mode: "runtime-overlay",
2203
+ overlayKeys: [...runtimeEnvSnapshot.overlayKeys],
2204
+ effectiveEnv: runtimeEffectiveEnv,
2205
+ envFilePaths: [...runtimeEnvSnapshot.envFilePaths],
2206
+ envFileReadFailed: runtimeEnvSnapshot.envFileReadFailed,
2207
+ envFileReadFailures: [...runtimeEnvSnapshot.envFileReadFailures]
2208
+ };
2076
2209
  const daemonWorkspaceHash = core.hashDaemonWorkspace(boundWorkspace);
2077
2210
  let daemonTelemetrySettings;
2078
2211
  try {
@@ -2145,54 +2278,58 @@ async function runQwenServe(optsIn, deps = {}) {
2145
2278
  promptQueueWaitStats.lastMs = durationMs;
2146
2279
  core.recordDaemonPromptQueueWait(durationMs);
2147
2280
  }, "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 } : {}
2281
+ const createRuntimeBridgeTelemetry = /* @__PURE__ */ __name((workspaceHash) => {
2282
+ const telemetry = core.createDaemonBridgeTelemetry();
2283
+ telemetry.metrics = {
2284
+ sessionLifecycle(action) {
2285
+ core.recordDaemonSessionLifecycle(action);
2286
+ core.emitDaemonLog(
2287
+ `Session ${action}.`,
2288
+ {
2289
+ "qwen-code.workspace.hash": workspaceHash
2290
+ },
2291
+ {
2292
+ eventName: `qwen-code.daemon.session.${action}`
2293
+ }
2294
+ );
2295
+ },
2296
+ channelLifecycle(action, expected) {
2297
+ core.recordDaemonChannelLifecycle(action, expected);
2298
+ core.emitDaemonLog(
2299
+ action === "spawn" ? "ACP channel spawned." : `ACP channel exited (expected=${expected ?? true}).`,
2300
+ {
2301
+ ...action === "exit" ? { "qwen-code.daemon.channel.expected": expected ?? true } : {}
2302
+ },
2303
+ {
2304
+ eventName: `qwen-code.daemon.channel.${action}`,
2305
+ ...expected === false && action === "exit" ? { severityNumber: 13 } : {}
2306
+ }
2307
+ );
2308
+ },
2309
+ promptQueueWait(durationMs) {
2310
+ recordPromptQueueWait(durationMs);
2311
+ metricsRing.recordPromptQueueWait(durationMs);
2312
+ },
2313
+ promptDuration(durationMs) {
2314
+ core.recordDaemonPromptDuration(durationMs);
2315
+ metricsRing.recordPromptDuration(durationMs);
2316
+ },
2317
+ cancelled: core.recordDaemonCancel,
2318
+ // Per-round model token usage + LLM round-trip time sniffed off
2319
+ // `agent_message_chunk._meta` (`usage` + `durationMs`) at the bridge's
2320
+ // single session/update fan-in. Increments (not cumulative), so the ring
2321
+ // sums tokens per window (token-burn chart) and pools the round-trip times
2322
+ // for the LLM-latency percentiles.
2323
+ tokenUsage(inputTokens, outputTokens, durationMs) {
2324
+ metricsRing.recordTokens(inputTokens, outputTokens);
2325
+ if (typeof durationMs === "number") {
2326
+ metricsRing.recordLlmDuration(durationMs);
2172
2327
  }
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
2328
  }
2194
- }
2195
- };
2329
+ };
2330
+ return telemetry;
2331
+ }, "createRuntimeBridgeTelemetry");
2332
+ const daemonTelemetry = createRuntimeBridgeTelemetry(daemonWorkspaceHash);
2196
2333
  const permissionAuditRing = new PermissionAuditRing();
2197
2334
  const permissionAuditPublisher = createPermissionAuditPublisher({
2198
2335
  ring: permissionAuditRing
@@ -2239,7 +2376,17 @@ async function runQwenServe(optsIn, deps = {}) {
2239
2376
  pathLocks: sharedPathLocks,
2240
2377
  ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2241
2378
  });
2379
+ const routeFsFactory = runtime.resolveBridgeFsFactory({
2380
+ // REST routes still return primary-relative paths, so keep their
2381
+ // filesystem boundary primary-only until responses carry root IDs.
2382
+ boundWorkspaces: [boundWorkspace],
2383
+ trusted: trustedWorkspace,
2384
+ emit: deps.fsAuditEmit,
2385
+ pathLocks: sharedPathLocks,
2386
+ ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2387
+ });
2242
2388
  const channelFactory = runtime.createSpawnChannelFactory({
2389
+ sourceEnv: runtimeEffectiveEnv,
2243
2390
  onDiagnosticLine: diagnosticSink,
2244
2391
  pipeHooks: {
2245
2392
  onMessageSent: /* @__PURE__ */ __name((bytes) => recordPipeMessage("outbound", bytes), "onMessageSent"),
@@ -2252,10 +2399,21 @@ async function runQwenServe(optsIn, deps = {}) {
2252
2399
  },
2253
2400
  ...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
2254
2401
  });
2255
- const statusProvider = runtime.createDaemonStatusProvider();
2256
- const workspaceProvidersStatusProvider = runtime.createWorkspaceProvidersStatusProvider();
2402
+ const statusProvider = runtime.createDaemonStatusProvider({
2403
+ env: runtimeEffectiveEnv
2404
+ });
2405
+ const workspaceProvidersStatusProvider = runtime.createWorkspaceProvidersStatusProvider({
2406
+ env: runtimeEffectiveEnv
2407
+ });
2257
2408
  const workspaceSkillsStatusProvider = runtime.createWorkspaceSkillsStatusProvider();
2258
2409
  const clientMcpSenderRegistry = new ClientMcpSenderRegistry();
2410
+ const runtimeBridges = [];
2411
+ const totalSessionAdmission = runtime.createTotalSessionAdmissionController(
2412
+ {
2413
+ maxTotalSessions: opts.maxTotalSessions,
2414
+ getBridges: /* @__PURE__ */ __name(() => runtimeBridges.length > 0 ? runtimeBridges : bridgeRef ? [bridgeRef] : [], "getBridges")
2415
+ }
2416
+ );
2259
2417
  const persistDisabledToolsFn = /* @__PURE__ */ __name((workspace, toolName, enabled) => withSettingsLock(workspace, async () => {
2260
2418
  const fresh = settingsRuntime.settings.loadSettings(workspace);
2261
2419
  const wsScope = fresh.forScope(WORKSPACE_SETTING_SCOPE).settings;
@@ -2307,8 +2465,10 @@ async function runQwenServe(optsIn, deps = {}) {
2307
2465
  // connection that hosts a named client MCP server (#5626).
2308
2466
  clientMcpSender: clientMcpSenderRegistry.lookup,
2309
2467
  maxSessions: opts.maxSessions,
2468
+ freshSessionAdmission: totalSessionAdmission.admit,
2310
2469
  ...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
2311
2470
  ...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
2471
+ ...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
2312
2472
  ...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
2313
2473
  ...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
2314
2474
  ...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
@@ -2331,7 +2491,9 @@ async function runQwenServe(optsIn, deps = {}) {
2331
2491
  });
2332
2492
  if (!deps.bridge) {
2333
2493
  bridgeRef = bridge;
2494
+ internalRuntimeBridgesForCleanup.push(bridge);
2334
2495
  }
2496
+ runtimeBridges.push(bridge);
2335
2497
  const workspaceService = runtime.createDaemonWorkspaceService({
2336
2498
  boundWorkspace,
2337
2499
  contextFilename: contextFilenameForInit ?? "QWEN.md",
@@ -2346,18 +2508,273 @@ async function runQwenServe(optsIn, deps = {}) {
2346
2508
  const fresh = settingsRuntime.settings.loadSettings(workspace, {
2347
2509
  skipLoadEnvironment: true
2348
2510
  });
2349
- return settingsRuntime.settings.reloadEnvironment(
2511
+ const result = settingsRuntime.settings.reloadEnvironment(
2350
2512
  fresh.merged,
2351
2513
  workspace
2352
2514
  );
2515
+ let refreshedRuntimeEnv;
2516
+ let fallbackReason;
2517
+ try {
2518
+ refreshedRuntimeEnv = settingsRuntime.environment.buildRuntimeEnvironment(
2519
+ fresh.merged,
2520
+ workspace,
2521
+ daemonRuntimeBaseEnv
2522
+ );
2523
+ } catch (err) {
2524
+ fallbackReason = err instanceof Error ? err.message : String(err);
2525
+ daemonLog.warn(
2526
+ "failed to rebuild runtime env snapshot after daemon env reload; preserving previous runtime env",
2527
+ {
2528
+ error: fallbackReason
2529
+ }
2530
+ );
2531
+ refreshedRuntimeEnv = {
2532
+ effectiveEnv: { ...runtimeEffectiveEnv },
2533
+ overlayKeys: [...primaryRuntimeEnv.overlayKeys],
2534
+ envFilePaths: [...primaryRuntimeEnv.envFilePaths],
2535
+ envFileReadFailed: primaryRuntimeEnv.envFileReadFailed ?? false,
2536
+ envFileReadFailures: [
2537
+ ...primaryRuntimeEnv.envFileReadFailures ?? []
2538
+ ]
2539
+ };
2540
+ }
2541
+ logRuntimeEnvFileReadFailures(workspace, refreshedRuntimeEnv);
2542
+ replaceRuntimeEffectiveEnv(refreshedRuntimeEnv.effectiveEnv);
2543
+ if (fallbackReason) {
2544
+ primaryRuntimeEnv.fallbackReason = fallbackReason;
2545
+ } else {
2546
+ delete primaryRuntimeEnv.fallbackReason;
2547
+ }
2548
+ primaryRuntimeEnv.envFileReadFailed = refreshedRuntimeEnv.envFileReadFailed;
2549
+ primaryRuntimeEnv.envFileReadFailures.splice(
2550
+ 0,
2551
+ primaryRuntimeEnv.envFileReadFailures.length,
2552
+ ...refreshedRuntimeEnv.envFileReadFailures
2553
+ );
2554
+ primaryRuntimeEnv.overlayKeys.splice(
2555
+ 0,
2556
+ primaryRuntimeEnv.overlayKeys.length,
2557
+ ...refreshedRuntimeEnv.overlayKeys
2558
+ );
2559
+ primaryRuntimeEnv.envFilePaths.splice(
2560
+ 0,
2561
+ primaryRuntimeEnv.envFilePaths.length,
2562
+ ...refreshedRuntimeEnv.envFilePaths
2563
+ );
2564
+ return result;
2353
2565
  }), "reloadDaemonEnv"),
2354
2566
  queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => bridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
2355
2567
  invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => bridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
2356
2568
  refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => bridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
2357
2569
  publishWorkspaceEvent: /* @__PURE__ */ __name((event) => bridge.publishWorkspaceEvent(event), "publishWorkspaceEvent")
2358
2570
  });
2571
+ const workspaceRuntimes = [
2572
+ {
2573
+ workspaceId: daemonWorkspaceHash,
2574
+ workspaceCwd: boundWorkspace,
2575
+ primary: true,
2576
+ trusted: trustedWorkspace,
2577
+ env: primaryRuntimeEnv,
2578
+ bridge,
2579
+ workspaceService,
2580
+ routeFileSystemFactory: routeFsFactory,
2581
+ clientMcpSenderRegistry
2582
+ }
2583
+ ];
2584
+ const createRuntimeEnvMetadata = /* @__PURE__ */ __name((workspace, settings) => {
2585
+ const snapshot = settings ? settingsRuntime.environment.buildRuntimeEnvironment(
2586
+ settings.merged,
2587
+ workspace,
2588
+ daemonRuntimeBaseEnv
2589
+ ) : {
2590
+ effectiveEnv: { ...daemonRuntimeBaseEnv },
2591
+ overlayKeys: Object.freeze([]),
2592
+ envFilePaths: Object.freeze([]),
2593
+ envFileReadFailed: false,
2594
+ envFileReadFailures: Object.freeze([])
2595
+ };
2596
+ logRuntimeEnvFileReadFailures(workspace, snapshot);
2597
+ const effectiveEnv = { ...snapshot.effectiveEnv };
2598
+ const metadata = {
2599
+ mode: "runtime-overlay",
2600
+ overlayKeys: [...snapshot.overlayKeys],
2601
+ effectiveEnv,
2602
+ envFilePaths: [...snapshot.envFilePaths],
2603
+ envFileReadFailed: snapshot.envFileReadFailed,
2604
+ envFileReadFailures: [...snapshot.envFileReadFailures]
2605
+ };
2606
+ return {
2607
+ metadata,
2608
+ effectiveEnv,
2609
+ replace(nextEnv) {
2610
+ for (const key of Object.keys(effectiveEnv)) {
2611
+ delete effectiveEnv[key];
2612
+ }
2613
+ Object.assign(effectiveEnv, nextEnv);
2614
+ }
2615
+ };
2616
+ }, "createRuntimeEnvMetadata");
2617
+ for (const workspaceInput of workspaceInputs.slice(1)) {
2618
+ let secondarySettings;
2619
+ try {
2620
+ secondarySettings = settingsRuntime.settings.loadSettings(
2621
+ workspaceInput.cwd
2622
+ );
2623
+ } catch (err) {
2624
+ writeStderrLine(
2625
+ `qwen serve: could not read full settings for secondary workspace ${workspaceInput.cwd} (${err instanceof Error ? err.message : String(err)}); falling back to defaults.`
2626
+ );
2627
+ }
2628
+ const secondaryTrusted = secondarySettings ? settingsRuntime.trustedFolders.getWorkspaceTrustStatus(
2629
+ secondarySettings.merged,
2630
+ workspaceInput.cwd
2631
+ ).effective.state === "trusted" : false;
2632
+ if (!secondaryTrusted) {
2633
+ daemonLog.warn("secondary workspace is not trusted", {
2634
+ workspace: workspaceInput.cwd,
2635
+ trustSettingsAvailable: secondarySettings !== void 0
2636
+ });
2637
+ }
2638
+ const secondaryEnv = createRuntimeEnvMetadata(
2639
+ workspaceInput.cwd,
2640
+ secondarySettings
2641
+ );
2642
+ const secondaryWorkspaceHash = core.hashDaemonWorkspace(
2643
+ workspaceInput.cwd
2644
+ );
2645
+ const secondaryStatusProvider = runtime.createDaemonStatusProvider({
2646
+ env: secondaryEnv.effectiveEnv
2647
+ });
2648
+ const secondaryBridgeFsFactory = runtime.resolveBridgeFsFactory({
2649
+ boundWorkspaces: [workspaceInput.cwd],
2650
+ trusted: secondaryTrusted,
2651
+ emit: deps.fsAuditEmit,
2652
+ pathLocks: sharedPathLocks,
2653
+ ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2654
+ });
2655
+ const secondaryChannelFactory = runtime.createSpawnChannelFactory({
2656
+ sourceEnv: secondaryEnv.effectiveEnv,
2657
+ onDiagnosticLine: diagnosticSink,
2658
+ pipeHooks: {
2659
+ onMessageSent: /* @__PURE__ */ __name((bytes) => recordPipeMessage("outbound", bytes), "onMessageSent"),
2660
+ onMessageReceived: /* @__PURE__ */ __name((bytes) => recordPipeMessage("inbound", bytes), "onMessageReceived"),
2661
+ onMessageObserved: /* @__PURE__ */ __name(({ direction, bytes, message }) => observeLargePipeFrame({
2662
+ direction: daemonPipeDirection(direction),
2663
+ bytes,
2664
+ message
2665
+ }), "onMessageObserved")
2666
+ },
2667
+ ...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
2668
+ });
2669
+ const secondaryClientMcpSenderRegistry = new ClientMcpSenderRegistry();
2670
+ const secondaryBridge = runtime.createAcpSessionBridge({
2671
+ clientMcpSender: secondaryClientMcpSenderRegistry.lookup,
2672
+ maxSessions: opts.maxSessions,
2673
+ freshSessionAdmission: totalSessionAdmission.admit,
2674
+ ...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
2675
+ ...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
2676
+ ...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
2677
+ ...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
2678
+ ...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
2679
+ ...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
2680
+ ...opts.permissionResponseTimeoutMs !== void 0 ? { permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs } : {},
2681
+ boundWorkspace: workspaceInput.cwd,
2682
+ sessionShellCommandEnabled,
2683
+ childEnvOverrides,
2684
+ channelFactory: secondaryChannelFactory,
2685
+ onDiagnosticLine: diagnosticSink,
2686
+ telemetry: createRuntimeBridgeTelemetry(secondaryWorkspaceHash),
2687
+ ...permissionPolicy !== void 0 ? { permissionPolicy } : {},
2688
+ ...permissionConsensusQuorum !== void 0 ? {
2689
+ permissionConsensusQuorum
2690
+ } : {},
2691
+ permissionAudit: permissionAuditPublisher,
2692
+ statusProvider: secondaryStatusProvider,
2693
+ fileSystem: createBridgeFileSystemAdapter(secondaryBridgeFsFactory),
2694
+ persistApprovalMode: /* @__PURE__ */ __name((workspace, mode) => withSettingsLock(workspace, async () => {
2695
+ const fresh = settingsRuntime.settings.loadSettings(workspace);
2696
+ fresh.setValue(WORKSPACE_SETTING_SCOPE, "tools.approvalMode", mode);
2697
+ }), "persistApprovalMode")
2698
+ });
2699
+ runtimeBridges.push(secondaryBridge);
2700
+ internalRuntimeBridgesForCleanup.push(secondaryBridge);
2701
+ const secondaryWorkspaceService = runtime.createDaemonWorkspaceService({
2702
+ boundWorkspace: workspaceInput.cwd,
2703
+ contextFilename: contextFilenameForInit ?? "QWEN.md",
2704
+ statusProvider: secondaryStatusProvider,
2705
+ workspaceProvidersStatusProvider: runtime.createWorkspaceProvidersStatusProvider({
2706
+ env: secondaryEnv.effectiveEnv
2707
+ }),
2708
+ workspaceSkillsStatusProvider: runtime.createWorkspaceSkillsStatusProvider(),
2709
+ isChannelLive: /* @__PURE__ */ __name(() => secondaryBridge.isChannelLive(), "isChannelLive"),
2710
+ persistDisabledTools: persistDisabledToolsFn,
2711
+ persistSetting: persistSettingFn,
2712
+ persistSettings: persistSettingsFn,
2713
+ reloadDaemonEnv: /* @__PURE__ */ __name((workspace) => withSettingsLock(workspace, async () => {
2714
+ const fresh = settingsRuntime.settings.loadSettings(workspace, {
2715
+ skipLoadEnvironment: true
2716
+ });
2717
+ const result = settingsRuntime.settings.reloadEnvironment(
2718
+ fresh.merged,
2719
+ workspace
2720
+ );
2721
+ try {
2722
+ const refreshedRuntimeEnv = settingsRuntime.environment.buildRuntimeEnvironment(
2723
+ fresh.merged,
2724
+ workspace,
2725
+ daemonRuntimeBaseEnv
2726
+ );
2727
+ logRuntimeEnvFileReadFailures(workspace, refreshedRuntimeEnv);
2728
+ secondaryEnv.replace(refreshedRuntimeEnv.effectiveEnv);
2729
+ secondaryEnv.metadata.envFileReadFailed = refreshedRuntimeEnv.envFileReadFailed;
2730
+ secondaryEnv.metadata.envFileReadFailures.splice(
2731
+ 0,
2732
+ secondaryEnv.metadata.envFileReadFailures.length,
2733
+ ...refreshedRuntimeEnv.envFileReadFailures
2734
+ );
2735
+ secondaryEnv.metadata.overlayKeys.splice(
2736
+ 0,
2737
+ secondaryEnv.metadata.overlayKeys.length,
2738
+ ...refreshedRuntimeEnv.overlayKeys
2739
+ );
2740
+ secondaryEnv.metadata.envFilePaths.splice(
2741
+ 0,
2742
+ secondaryEnv.metadata.envFilePaths.length,
2743
+ ...refreshedRuntimeEnv.envFilePaths
2744
+ );
2745
+ delete secondaryEnv.metadata.fallbackReason;
2746
+ } catch (err) {
2747
+ secondaryEnv.metadata.fallbackReason = err instanceof Error ? err.message : String(err);
2748
+ daemonLog.warn(
2749
+ "failed to rebuild secondary runtime env snapshot after daemon env reload; preserving previous runtime env",
2750
+ {
2751
+ workspace,
2752
+ error: secondaryEnv.metadata.fallbackReason
2753
+ }
2754
+ );
2755
+ }
2756
+ return result;
2757
+ }), "reloadDaemonEnv"),
2758
+ queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => secondaryBridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
2759
+ invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => secondaryBridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
2760
+ refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => secondaryBridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
2761
+ publishWorkspaceEvent: /* @__PURE__ */ __name((event) => secondaryBridge.publishWorkspaceEvent(event), "publishWorkspaceEvent")
2762
+ });
2763
+ workspaceRuntimes.push({
2764
+ workspaceId: secondaryWorkspaceHash,
2765
+ workspaceCwd: workspaceInput.cwd,
2766
+ primary: false,
2767
+ trusted: secondaryTrusted,
2768
+ env: secondaryEnv.metadata,
2769
+ bridge: secondaryBridge,
2770
+ workspaceService: secondaryWorkspaceService,
2771
+ routeFileSystemFactory: secondaryBridgeFsFactory,
2772
+ clientMcpSenderRegistry: secondaryClientMcpSenderRegistry
2773
+ });
2774
+ }
2775
+ const workspaceRegistry = runtime.createWorkspaceRegistry(workspaceRuntimes);
2359
2776
  core.registerDaemonGaugeCallbacks({
2360
- sessionCount: /* @__PURE__ */ __name(() => bridge.sessionCount, "sessionCount"),
2777
+ sessionCount: /* @__PURE__ */ __name(() => workspaceRegistry.list().reduce((sum, item) => sum + item.bridge.sessionCount, 0), "sessionCount"),
2361
2778
  sseCount: /* @__PURE__ */ __name(() => runtime.getActiveSseCount(), "sseCount"),
2362
2779
  heapUsed: /* @__PURE__ */ __name(() => process.memoryUsage().heapUsed, "heapUsed")
2363
2780
  });
@@ -2397,9 +2814,15 @@ async function runQwenServe(optsIn, deps = {}) {
2397
2814
  cpuPercent,
2398
2815
  rssBytes: mem.rss,
2399
2816
  heapUsedBytes: mem.heapUsed,
2400
- activeSessions: bridge.sessionCount,
2401
- activePrompts: bridge.activePromptCount,
2402
- queuedPrompts: bridge.pendingPromptTotal ?? 0,
2817
+ activeSessions: workspaceRegistry.list().reduce((sum, item) => sum + item.bridge.sessionCount, 0),
2818
+ activePrompts: workspaceRegistry.list().reduce(
2819
+ (sum, item) => sum + (item.bridge.activePromptCount ?? 0),
2820
+ 0
2821
+ ),
2822
+ queuedPrompts: workspaceRegistry.list().reduce(
2823
+ (sum, item) => sum + (item.bridge.pendingPromptTotal ?? 0),
2824
+ 0
2825
+ ),
2403
2826
  eventLoopLagP99Ms,
2404
2827
  sseConnections: runtime.getActiveSseCount(),
2405
2828
  wsConnections: acp?.wsStreams ?? 0,
@@ -2442,6 +2865,7 @@ async function runQwenServe(optsIn, deps = {}) {
2442
2865
  }
2443
2866
  };
2444
2867
  const app2 = runtime.createServeApp(opts, () => actualPort, {
2868
+ workspaceRegistry,
2445
2869
  bridge,
2446
2870
  webShellDir,
2447
2871
  boundWorkspace,
@@ -2451,16 +2875,9 @@ async function runQwenServe(optsIn, deps = {}) {
2451
2875
  // (keepalive) and reloads them on boot (rehydration). Off by default so
2452
2876
  // direct createServeApp embeds/tests don't spawn sessions.
2453
2877
  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
- }),
2878
+ fsFactory: routeFsFactory,
2463
2879
  primaryWorkspaceTrusted: trustedWorkspace,
2880
+ primaryRuntimeEnv,
2464
2881
  daemonLog,
2465
2882
  getChannelWorkerSnapshot,
2466
2883
  getPerfSnapshot: /* @__PURE__ */ __name(() => ({
@@ -2477,6 +2894,7 @@ async function runQwenServe(optsIn, deps = {}) {
2477
2894
  }
2478
2895
  }), "getPerfSnapshot"),
2479
2896
  getMetricsSeries: /* @__PURE__ */ __name(() => metricsRing.snapshot(), "getMetricsSeries"),
2897
+ getTotalSessionAdmissionSnapshot: totalSessionAdmission.snapshot,
2480
2898
  recordDaemonRequest: /* @__PURE__ */ __name((durationMs, statusCode) => metricsRing.recordRequest(durationMs, statusCode), "recordDaemonRequest"),
2481
2899
  workspace: workspaceService,
2482
2900
  // Reverse tool channel (#5626): the SAME registry wired into `bridge` above,
@@ -2545,6 +2963,7 @@ async function runQwenServe(optsIn, deps = {}) {
2545
2963
  qwenCodeVersion: cliVersion,
2546
2964
  sessionShellCommandEnabled,
2547
2965
  permissionPolicy,
2966
+ multiWorkspaceCapabilitiesRequireRuntime: workspaceInputs.length > 1,
2548
2967
  getRuntimeError: /* @__PURE__ */ __name(() => runtimeStartupError, "getRuntimeError"),
2549
2968
  getChannelWorkerSnapshot,
2550
2969
  onHealthServed: deferRuntimeUntilFirstHealth ? () => startRuntimeAfterHealth?.() : void 0
@@ -2694,6 +3113,8 @@ async function runQwenServe(optsIn, deps = {}) {
2694
3113
  }, "cancelDeferredRuntimeStartup");
2695
3114
  const shutdownBridgeAfterFailedStartup = /* @__PURE__ */ __name(async (bridge) => {
2696
3115
  if (!bridge || deps.bridge) return;
3116
+ if (shutdownBridges.has(bridge)) return;
3117
+ shutdownBridges.add(bridge);
2697
3118
  try {
2698
3119
  await bridge.shutdown();
2699
3120
  } catch (shutdownErr) {
@@ -2734,7 +3155,10 @@ async function runQwenServe(optsIn, deps = {}) {
2734
3155
  await stopChannelWorkerAfterFailedStartup();
2735
3156
  disposeDaemonEventLoopMonitor();
2736
3157
  removeCurrentServePidfile();
2737
- await shutdownBridgeAfterFailedStartup(bridgeForCleanup ?? bridgeRef);
3158
+ const bridgesForCleanup = bridgeForCleanup ? [bridgeForCleanup, ...getRuntimeBridgesForCleanup()] : getRuntimeBridgesForCleanup();
3159
+ for (const bridge of [...new Set(bridgesForCleanup)]) {
3160
+ await shutdownBridgeAfterFailedStartup(bridge);
3161
+ }
2738
3162
  markRuntimeFailed(error);
2739
3163
  }, "failRuntimeStartup");
2740
3164
  const armRuntimeStartupTimer = /* @__PURE__ */ __name(() => {
@@ -2843,7 +3267,9 @@ async function runQwenServe(optsIn, deps = {}) {
2843
3267
  daemonLog.warn(`received ${signal} during drain \u2014 forcing exit`);
2844
3268
  try {
2845
3269
  channelWorker.killAllSync();
2846
- bridgeRef?.killAllSync();
3270
+ for (const runtimeBridge of getRuntimeBridgesForCleanup()) {
3271
+ runtimeBridge.killAllSync();
3272
+ }
2847
3273
  removeCurrentServePidfile();
2848
3274
  } catch (err) {
2849
3275
  daemonLog.error(
@@ -2954,8 +3380,9 @@ async function runQwenServe(optsIn, deps = {}) {
2954
3380
  );
2955
3381
  });
2956
3382
  removeCurrentServePidfile();
2957
- const bridgeForShutdown = bridgeRef;
2958
- if (bridgeForShutdown) {
3383
+ for (const bridgeForShutdown of getRuntimeBridgesForCleanup()) {
3384
+ if (shutdownBridges.has(bridgeForShutdown)) continue;
3385
+ shutdownBridges.add(bridgeForShutdown);
2959
3386
  await bridgeForShutdown.shutdown().catch((err) => {
2960
3387
  daemonLog.error(
2961
3388
  "bridge shutdown error",
@@ -3034,8 +3461,8 @@ async function runQwenServe(optsIn, deps = {}) {
3034
3461
  }
3035
3462
  }, "onListening");
3036
3463
  let server;
3464
+ let httpsServer;
3037
3465
  if (tlsOptions) {
3038
- let httpsServer;
3039
3466
  try {
3040
3467
  httpsServer = https.createServer(tlsOptions, app);
3041
3468
  } catch (err) {
@@ -3046,14 +3473,40 @@ async function runQwenServe(optsIn, deps = {}) {
3046
3473
  );
3047
3474
  return;
3048
3475
  }
3049
- server = httpsServer.listen(opts.port, listenHostname, onListening);
3050
- } else {
3051
- server = app.listen(opts.port, listenHostname, onListening);
3052
3476
  }
3053
- server.once("error", (err) => {
3054
- removeCurrentServePidfile();
3055
- reject(err);
3056
- });
3477
+ const tryListen = /* @__PURE__ */ __name((attemptPort, attempt) => {
3478
+ try {
3479
+ if (httpsServer) {
3480
+ httpsServer.removeAllListeners("listening");
3481
+ server = httpsServer.listen(attemptPort, listenHostname, onListening);
3482
+ } else {
3483
+ server = app.listen(attemptPort, listenHostname, onListening);
3484
+ }
3485
+ } catch (err) {
3486
+ removeCurrentServePidfile();
3487
+ reject(err instanceof Error ? err : new Error(String(err)));
3488
+ return;
3489
+ }
3490
+ server.once("error", (err) => {
3491
+ server.close();
3492
+ const nextPort = attemptPort + 1;
3493
+ if (err.code === "EADDRINUSE" && opts.port !== 0 && nextPort <= 65535 && attempt < MAX_PORT_ATTEMPTS - 1) {
3494
+ writeStderrLine(
3495
+ `qwen serve: port ${attemptPort} is in use, trying ${nextPort}...`
3496
+ );
3497
+ tryListen(nextPort, attempt + 1);
3498
+ } else {
3499
+ if (err.code === "EADDRINUSE" && attempt > 0) {
3500
+ writeStderrLine(
3501
+ `qwen serve: all ports ${opts.port}\u2013${attemptPort} are in use`
3502
+ );
3503
+ }
3504
+ removeCurrentServePidfile();
3505
+ reject(err);
3506
+ }
3507
+ });
3508
+ }, "tryListen");
3509
+ tryListen(opts.port, 0);
3057
3510
  });
3058
3511
  }
3059
3512
  __name(runQwenServe, "runQwenServe");