@zubriq/code 0.19.8-1 → 0.19.9-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/dist/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
  2. package/dist/bundled/qc-helper/docs/features/channels/overview.md +23 -12
  3. package/dist/bundled/qc-helper/docs/features/channels/plugins.md +1 -0
  4. package/dist/bundled/qc-helper/docs/features/channels/wecom.md +111 -0
  5. package/dist/bundled/qc-helper/docs/features/hooks.md +36 -34
  6. package/dist/bundled/qc-helper/docs/features/memory.md +1 -1
  7. package/dist/bundled/qc-helper/docs/qwen-serve.md +17 -10
  8. package/dist/bundled/review/SKILL.md +6 -2
  9. package/dist/chunks/{MaxSizedBox-OWTCJQNO.js → MaxSizedBox-W6SAJMJC.js} +13 -11
  10. package/dist/chunks/{StandaloneSessionPicker-6NGEQFBH.js → StandaloneSessionPicker-YBKZZKIA.js} +28 -23
  11. package/dist/chunks/{acpAgent-XPRWSNOW.js → acpAgent-SQJQBOTS.js} +110 -80
  12. package/dist/chunks/{agent-TB6S4VXU.js → agent-QU7Q2RZN.js} +8 -8
  13. package/dist/chunks/{agent-headless-R3XYK5TT.js → agent-headless-PBHLWHND.js} +8 -8
  14. package/dist/chunks/{anthropicContentGenerator-FZQAEMYK.js → anthropicContentGenerator-52G6ZA3D.js} +31 -4
  15. package/dist/chunks/{artifact-tool-H2TNPNP5.js → artifact-tool-D233YJFH.js} +25 -6
  16. package/dist/chunks/{bridge-HVRG6SMU.js → bridge-LJLLDUMW.js} +17 -14
  17. package/dist/chunks/{ca-HCMB2I54.js → ca-MKD32FQL.js} +26 -1
  18. package/dist/chunks/{channel-worker-supervisor-B7MSMB5K.js → channel-worker-supervisor-NZQUOEFJ.js} +3 -3
  19. package/dist/chunks/{chunk-YRM6BC6H.js → chunk-27AYMAL6.js} +506 -63
  20. package/dist/chunks/{chunk-536GZ6UF.js → chunk-2MDC5WDB.js} +17 -111
  21. package/dist/chunks/{chunk-H3D6XAOL.js → chunk-2PRSBVPI.js} +3 -3
  22. package/dist/chunks/chunk-332PWN27.js +19 -0
  23. package/dist/chunks/{chunk-FVMWEHWU.js → chunk-3B26UVCX.js} +114 -12
  24. package/dist/chunks/{chunk-ZM5BPDXV.js → chunk-3F22JT4E.js} +1 -1
  25. package/dist/chunks/{chunk-W6RH6KHR.js → chunk-3GPVYALM.js} +4 -2
  26. package/dist/chunks/{chunk-G7ZG7CA6.js → chunk-3UP777ZS.js} +8 -7
  27. package/dist/chunks/{chunk-PA7QS4X5.js → chunk-43W4YSO6.js} +1 -12
  28. package/dist/chunks/{chunk-5EB2HK3X.js → chunk-4IK56VLC.js} +1 -1
  29. package/dist/chunks/{chunk-UE5TCZE6.js → chunk-5FAUIGXH.js} +5 -13
  30. package/dist/chunks/{chunk-VEB3NYSO.js → chunk-5MBO76SL.js} +5 -0
  31. package/dist/chunks/{chunk-PDITONOB.js → chunk-5MRUKUOG.js} +5347 -4132
  32. package/dist/chunks/{chunk-4UC3U66K.js → chunk-6EUMFVPJ.js} +5 -5
  33. package/dist/chunks/{chunk-YOGGIAGF.js → chunk-6JL5OVLX.js} +1 -1
  34. package/dist/chunks/{chunk-QG4ZO2EB.js → chunk-74E6VVF6.js} +11 -11
  35. package/dist/chunks/chunk-A2X3KLC3.js +3807 -0
  36. package/dist/chunks/{chunk-BA4HLTG2.js → chunk-B6B2MUUF.js} +5 -5
  37. package/dist/chunks/{chunk-XKYOIERV.js → chunk-BN5VYAOZ.js} +681 -1239
  38. package/dist/chunks/{chunk-IO76BGJ3.js → chunk-BYUA6YYS.js} +15 -9
  39. package/dist/chunks/{chunk-NCFY7PWS.js → chunk-CCGOFQV3.js} +51 -2
  40. package/dist/chunks/{chunk-66KNL43D.js → chunk-CD6USWHZ.js} +1 -1
  41. package/dist/chunks/{chunk-ZWSTIPSW.js → chunk-CEITMQ62.js} +2 -2
  42. package/dist/chunks/{chunk-7AQTBTVY.js → chunk-EJP6Z7NU.js} +4 -3
  43. package/dist/chunks/{chunk-RTW5ZXHO.js → chunk-EZTNYRHH.js} +6 -5
  44. package/dist/chunks/{chunk-MJQFA66Z.js → chunk-FAATDXYS.js} +308 -81
  45. package/dist/chunks/{chunk-DNV4FSN5.js → chunk-FBET5XZ2.js} +6 -4
  46. package/dist/chunks/{chunk-HTC4R67V.js → chunk-FES4YXJ3.js} +9 -9
  47. package/dist/chunks/{chunk-NBKE6QRZ.js → chunk-FHTUTVIQ.js} +10 -5
  48. package/dist/chunks/chunk-FII3C4E7.js +168 -0
  49. package/dist/chunks/{chunk-2NL7ED5Q.js → chunk-FV7425LN.js} +22 -1
  50. package/dist/chunks/{chunk-J6OET6C3.js → chunk-GAI76CFX.js} +4 -4
  51. package/dist/chunks/{chunk-B34OV7K2.js → chunk-GGQQA4JW.js} +13 -0
  52. package/dist/chunks/chunk-GLE2YUPU.js +34 -0
  53. package/dist/chunks/{chunk-X265R5C6.js → chunk-GN3F6PIU.js} +1 -1
  54. package/dist/chunks/{chunk-SM624MOZ.js → chunk-GWUN54UD.js} +1 -1
  55. package/dist/chunks/chunk-H3TELH3H.js +942 -0
  56. package/dist/chunks/{chunk-XZULYFIX.js → chunk-HD4DZI2L.js} +2 -2
  57. package/dist/chunks/{chunk-KLLLWQM2.js → chunk-HPQIVXSP.js} +1 -1
  58. package/dist/chunks/{chunk-WSVZFWN4.js → chunk-IBY3Q3HG.js} +693 -104
  59. package/dist/chunks/{chunk-JSEOX4CM.js → chunk-JGR6W4IX.js} +14 -8
  60. package/dist/chunks/chunk-K652V4NH.js +283 -0
  61. package/dist/chunks/{chunk-OCBJKHF2.js → chunk-KH2CZZDD.js} +2 -2
  62. package/dist/chunks/chunk-LGFAYIKX.js +115 -0
  63. package/dist/chunks/{chunk-QG5KDB6X.js → chunk-LZDW5TDV.js} +5 -5
  64. package/dist/chunks/{chunk-ENKWIF75.js → chunk-MA4AZNP7.js} +10 -10
  65. package/dist/chunks/{chunk-4RQIB5UZ.js → chunk-O2YT7VB4.js} +0 -34
  66. package/dist/chunks/{chunk-4KJ2BPIT.js → chunk-OACJLMLD.js} +2 -38
  67. package/dist/chunks/{chunk-ML2ZWH2K.js → chunk-PCWYMX57.js} +14 -153
  68. package/dist/chunks/{chunk-NHFBLJOI.js → chunk-Q3PQ5VGJ.js} +1 -1
  69. package/dist/chunks/{chunk-LGXBB2R2.js → chunk-QK3I36QG.js} +1 -1
  70. package/dist/chunks/chunk-RA7TR75G.js +8223 -0
  71. package/dist/chunks/{chunk-KSPVDFE4.js → chunk-SAIILPQ3.js} +0 -3
  72. package/dist/chunks/{chunk-DHKDK57Q.js → chunk-SNZPA74J.js} +146 -54
  73. package/dist/chunks/{chunk-PWR5MVM3.js → chunk-SSP3UT5C.js} +4 -4
  74. package/dist/chunks/{chunk-4LETJLG2.js → chunk-SUCRVT5L.js} +1 -1
  75. package/dist/chunks/{chunk-5YLZHETW.js → chunk-TRR5KGDN.js} +1 -1
  76. package/dist/chunks/chunk-UIDXQNMV.js +13 -0
  77. package/dist/chunks/{chunk-PIORL4OD.js → chunk-UKV3D7WB.js} +0 -44
  78. package/dist/chunks/chunk-UYNUIGUR.js +167 -0
  79. package/dist/chunks/chunk-V2TYBEWU.js +28 -0
  80. package/dist/chunks/chunk-V35MD7KN.js +13 -0
  81. package/dist/chunks/{chunk-N4HTVZDZ.js → chunk-VR3KCBHH.js} +1 -1
  82. package/dist/chunks/{chunk-APYUOROB.js → chunk-W4CTWW7M.js} +423 -61
  83. package/dist/chunks/{chunk-ABANKQYY.js → chunk-WJAW2O5H.js} +92 -465
  84. package/dist/chunks/{chunk-6RSBRKF5.js → chunk-WN4YJJGH.js} +2 -2
  85. package/dist/chunks/chunk-XNXVCNAT.js +88 -0
  86. package/dist/chunks/{chunk-TDGF35EN.js → chunk-XOHNA2S6.js} +1 -1
  87. package/dist/chunks/chunk-XQPMKWSV.js +487 -0
  88. package/dist/chunks/{chunk-4FQL7KUS.js → chunk-XWDHZP7P.js} +8 -8
  89. package/dist/chunks/{chunk-REPRY4F7.js → chunk-YCKKP4QA.js} +10 -10
  90. package/dist/chunks/{chunk-YNWQ3PUQ.js → chunk-YJWMOGGZ.js} +3 -3
  91. package/dist/chunks/{chunk-RFIL6REB.js → chunk-YKZIAK7C.js} +119 -29
  92. package/dist/chunks/{chunk-45YCXM2H.js → chunk-YZDBUH6S.js} +45 -9
  93. package/dist/chunks/chunk-Z3I3QJK3.js +47 -0
  94. package/dist/chunks/{chunk-G23FFNLT.js → chunk-ZDGPPCTW.js} +20 -8
  95. package/dist/chunks/chunk-ZL5HN75Q.js +61 -0
  96. package/dist/chunks/{chunk-IQX5S2RS.js → chunk-ZL7JCYWM.js} +66 -7
  97. package/dist/chunks/{computer-use-A72BECH4.js → computer-use-4B45EG2F.js} +8 -8
  98. package/dist/chunks/{contextCommand-RREXA4B7.js → contextCommand-GIVRWNTS.js} +12 -11
  99. package/dist/chunks/{cron-create-DDYU4DIR.js → cron-create-JSXEIPVS.js} +1 -1
  100. package/dist/chunks/{cron-delete-DFKOUZWN.js → cron-delete-OIFVEPGU.js} +1 -1
  101. package/dist/chunks/{cron-list-ME5QGAR5.js → cron-list-D4ZX4IOE.js} +1 -1
  102. package/dist/chunks/{daemon-XWG2EGFX.js → daemon-WPAENEBW.js} +71 -3
  103. package/dist/chunks/{daemon-status-provider-Y6AFXTET.js → daemon-status-provider-WBOAMCHE.js} +20 -17
  104. package/dist/chunks/{de-PLLFDERI.js → de-ZFPPQVSF.js} +26 -1
  105. package/dist/chunks/{dist-LPVU3L2M.js → dist-BEXOZXLQ.js} +6 -3792
  106. package/dist/chunks/{dist-7GU63KI5.js → dist-E6UANPIM.js} +1 -1
  107. package/dist/chunks/{dist-VHBP2PIG.js → dist-H2AEJCZ5.js} +2 -2
  108. package/dist/chunks/{dist-3UDX5T4T.js → dist-O2IRTRPP.js} +1 -1
  109. package/dist/chunks/dist-SCFLLYMK.js +3217 -0
  110. package/dist/chunks/{dist-H4HHZYCI.js → dist-Z34QPAQW.js} +2 -2
  111. package/dist/chunks/{earlyInputCapture-OAHBOGOO.js → earlyInputCapture-JWMCAJZR.js} +8 -8
  112. package/dist/chunks/{edit-SFYW3FOV.js → edit-O5FUVHBE.js} +9 -9
  113. package/dist/chunks/{en-AXARKOWO.js → en-N4EPZAQI.js} +31 -2
  114. package/dist/chunks/{enter-worktree-LUPPQ2NH.js → enter-worktree-LOJFRC3D.js} +8 -8
  115. package/dist/chunks/{enterPlanMode-44GEN5U6.js → enterPlanMode-VS3FAUPX.js} +8 -8
  116. package/dist/chunks/environment-WKW5TLSH.js +90 -0
  117. package/dist/chunks/{errors-H3Q3W3DL.js → errors-LEZXHJMR.js} +10 -10
  118. package/dist/chunks/{exit-worktree-34CVVWT4.js → exit-worktree-RN2NXRMP.js} +8 -8
  119. package/dist/chunks/{exitPlanMode-5G5BHNUP.js → exitPlanMode-EPC424I4.js} +8 -8
  120. package/dist/chunks/{fast-path-7PKGFBRM.js → fast-path-UUPAFOSQ.js} +12 -3
  121. package/dist/chunks/{fast-path-settings-RCRXH2JG.js → fast-path-settings-7RIFI3PK.js} +3 -2
  122. package/dist/chunks/{fr-MBMNQSQ6.js → fr-5WWMY53B.js} +30 -1
  123. package/dist/chunks/{gemini-2II6JH4H.js → gemini-QCKK4XNU.js} +438 -265
  124. package/dist/chunks/{geminiContentGenerator-SWEJVOC4.js → geminiContentGenerator-DX4SRXJA.js} +1 -1
  125. package/dist/chunks/{glob-5DFC7DXW.js → glob-4URMJWRX.js} +8 -8
  126. package/dist/chunks/{grep-QYVXGRRJ.js → grep-AEQB5KED.js} +8 -8
  127. package/dist/chunks/handleAutoUpdate-Y4YNG34Y.js +65 -0
  128. package/dist/chunks/{initializer-XX3UGUHE.js → initializer-NDEBMSOG.js} +17 -13
  129. package/dist/chunks/{ja-HFV5QCHR.js → ja-CUHZOLEJ.js} +30 -1
  130. package/dist/chunks/{list-AX5FWBVC.js → list-VSCBNOWT.js} +17 -15
  131. package/dist/chunks/{loadedSettingsAdapter-ISOM6GJ7.js → loadedSettingsAdapter-FDO752BA.js} +15 -13
  132. package/dist/chunks/{loop-wakeup-ZW5P6VPY.js → loop-wakeup-OHWEMFP5.js} +2 -2
  133. package/dist/chunks/{ls-L654WOAT.js → ls-7MFU2QYW.js} +1 -1
  134. package/dist/chunks/{lsp-M35KE54Y.js → lsp-XHDTPTGV.js} +2 -4
  135. package/dist/chunks/{mcp-74F6725E.js → mcp-MLPWTHUV.js} +15 -13
  136. package/dist/chunks/{monitor-W4WRSC2C.js → monitor-WCVHIJUJ.js} +16 -11
  137. package/dist/chunks/{nonInteractiveCli-4QMV6C4J.js → nonInteractiveCli-32HZK274.js} +52 -44
  138. package/dist/chunks/{notebook-edit-XBZEIP42.js → notebook-edit-NPOMPKS4.js} +9 -9
  139. package/dist/chunks/{openaiContentGenerator-RTUJDESE.js → openaiContentGenerator-6AIBSRQK.js} +6 -6
  140. package/dist/chunks/{pidfile-YWSGNTPK.js → pidfile-7Y3QEDSZ.js} +8 -8
  141. package/dist/chunks/{pt-2THT3YHA.js → pt-OLYN42DS.js} +26 -1
  142. package/dist/chunks/{qwenContentGenerator-4ZFYAZLY.js → qwenContentGenerator-OUYOAYT4.js} +10 -10
  143. package/dist/chunks/{read-file-D7DKDIAC.js → read-file-EESFA24L.js} +3 -3
  144. package/dist/chunks/{record-artifact-PP3LKHTS.js → record-artifact-SQ2OKRJW.js} +3 -3
  145. package/dist/chunks/{ripGrep-KG7JYNER.js → ripGrep-DLYV7ZZG.js} +8 -8
  146. package/dist/chunks/{ru-PER5I4OI.js → ru-MKM2HFDS.js} +26 -1
  147. package/dist/chunks/{run-qwen-serve-XGJSNF6S.js → run-qwen-serve-WUEHQROF.js} +602 -143
  148. package/dist/chunks/{scheduler-MOLWOE4G.js → scheduler-SK4Y66V4.js} +8 -8
  149. package/dist/chunks/{send-message-OA6MV4EU.js → send-message-76GT3JMC.js} +1 -1
  150. package/dist/chunks/{serve-4ZNVPYND.js → serve-UCDGVZFI.js} +17 -14
  151. package/dist/chunks/{server-ACWDFHIF.js → server-FVGFFVZ4.js} +1394 -328
  152. package/dist/chunks/{session-VYO2GRO2.js → session-RIGKDMGR.js} +53 -45
  153. package/dist/chunks/{settings-4J2O3K22.js → settings-LVFFGXGE.js} +24 -20
  154. package/dist/chunks/{shell-RKERJYXR.js → shell-PAWNAFYN.js} +8 -8
  155. package/dist/chunks/{skill-JYACZJ5V.js → skill-5YIN3Z6Y.js} +15 -5
  156. package/dist/chunks/{spawnChannel-BA3U3RGX.js → spawnChannel-KIMZHWNR.js} +10 -10
  157. package/dist/chunks/{src-3P337V4P.js → src-BIWCD3VX.js} +21 -9
  158. package/dist/chunks/{startInteractiveUI-SUSZ6FWB.js → startInteractiveUI-AFXLGUFI.js} +33759 -41620
  159. package/dist/chunks/{task-create-RPFZNB4B.js → task-create-WCHTB435.js} +2 -2
  160. package/dist/chunks/{task-update-5WUG5MVQ.js → task-update-XYWMHJGJ.js} +2 -2
  161. package/dist/chunks/{team-create-YVWGRZEA.js → team-create-26WOMISV.js} +8 -8
  162. package/dist/chunks/{team-plan-approval-VRF54TTI.js → team-plan-approval-B5XB6UQC.js} +8 -8
  163. package/dist/chunks/{theme-manager-JW2KOACL.js → theme-manager-4TJ5TEFD.js} +8 -8
  164. package/dist/chunks/{tool-search-KUSMAZBN.js → tool-search-FFU63E6M.js} +6 -23
  165. package/dist/chunks/total-session-admission-JOD7SMPJ.js +72 -0
  166. package/dist/chunks/{trustedFolders-ERGSUCDK.js → trustedFolders-IJ2QHXSC.js} +9 -9
  167. package/dist/chunks/updateCheck-5Z25DCBP.js +65 -0
  168. package/dist/chunks/{validateNonInterActiveAuth-DDI62H5X.js → validateNonInterActiveAuth-G5EY47DE.js} +49 -41
  169. package/dist/chunks/{version-VB3AHVUF.js → version-LGO3GOKQ.js} +2 -1
  170. package/dist/chunks/{workflow-WINKRCI4.js → workflow-ZTK3WT3D.js} +9 -9
  171. package/dist/chunks/{workspace-providers-status-ZVZPXKSO.js → workspace-providers-status-YMPTRKW2.js} +18 -15
  172. package/dist/chunks/workspace-registry-NBUL6LBH.js +74 -0
  173. package/dist/chunks/{workspace-service-GAS2LV2P.js → workspace-service-V6G2RCD4.js} +21 -19
  174. package/dist/chunks/{workspace-skills-status-4WGKYJVA.js → workspace-skills-status-ZCW44BCH.js} +16 -14
  175. package/dist/chunks/{write-file-UTLKVZNN.js → write-file-4FUTAEW6.js} +9 -9
  176. package/dist/chunks/{zh-RS3HZHFH.js → zh-J4F6QWQV.js} +31 -2
  177. package/dist/chunks/{zh-TW-L5GRQ4S4.js → zh-TW-XVDWOLSW.js} +31 -2
  178. package/dist/cli.js +11 -11
  179. package/dist/locales/ca.js +30 -0
  180. package/dist/locales/de.js +30 -0
  181. package/dist/locales/en.js +38 -2
  182. package/dist/locales/fr.js +36 -0
  183. package/dist/locales/ja.js +36 -0
  184. package/dist/locales/pt.js +30 -0
  185. package/dist/locales/ru.js +30 -0
  186. package/dist/locales/zh-TW.js +38 -2
  187. package/dist/locales/zh.js +38 -2
  188. package/dist/package.json +3 -3
  189. package/dist/web-shell/assets/{arc-C6tzvtOa.js → arc-BWyoJpY2.js} +1 -1
  190. package/dist/web-shell/assets/{architectureDiagram-3BPJPVTR-DSYQFGn9.js → architectureDiagram-3BPJPVTR-BT0mGrz2.js} +1 -1
  191. package/dist/web-shell/assets/{blockDiagram-GPEHLZMM-CHjBdXAD.js → blockDiagram-GPEHLZMM-BLgUWvyf.js} +1 -1
  192. package/dist/web-shell/assets/{c4Diagram-AAUBKEIU-BQzK6Yyb.js → c4Diagram-AAUBKEIU-DYx9M7oU.js} +1 -1
  193. package/dist/web-shell/assets/channel-wmPUGHtg.js +1 -0
  194. package/dist/web-shell/assets/{chunk-2J33WTMH-hpP2p3Ij.js → chunk-2J33WTMH-CfMHWbuZ.js} +1 -1
  195. package/dist/web-shell/assets/{chunk-4BX2VUAB-B5KtK1JJ.js → chunk-4BX2VUAB-B1URoqEV.js} +1 -1
  196. package/dist/web-shell/assets/{chunk-55IACEB6-BDv6Mfr2.js → chunk-55IACEB6-DAIaM4QF.js} +1 -1
  197. package/dist/web-shell/assets/{chunk-727SXJPM-BevPWfrX.js → chunk-727SXJPM-B2X34knw.js} +1 -1
  198. package/dist/web-shell/assets/{chunk-AQP2D5EJ-ChDrz2ad.js → chunk-AQP2D5EJ-Cif-zLTQ.js} +1 -1
  199. package/dist/web-shell/assets/{chunk-FMBD7UC4-ClMdVSDs.js → chunk-FMBD7UC4-H18WCXdY.js} +1 -1
  200. package/dist/web-shell/assets/{chunk-ND2GUHAM-BceV8kZS.js → chunk-ND2GUHAM-YFtetHi0.js} +1 -1
  201. package/dist/web-shell/assets/{chunk-QZHKN3VN-DtyK2wwc.js → chunk-QZHKN3VN-By2hiH3r.js} +1 -1
  202. package/dist/web-shell/assets/classDiagram-4FO5ZUOK-BA2ljEjW.js +1 -0
  203. package/dist/web-shell/assets/classDiagram-v2-Q7XG4LA2-BA2ljEjW.js +1 -0
  204. package/dist/web-shell/assets/{cose-bilkent-S5V4N54A-BGMsqwmE.js → cose-bilkent-S5V4N54A-VrcnnLZu.js} +1 -1
  205. package/dist/web-shell/assets/{dagre-BM42HDAG-C-71clpF.js → dagre-BM42HDAG-CGo-IaVV.js} +1 -1
  206. package/dist/web-shell/assets/{diagram-2AECGRRQ-WIzzlkec.js → diagram-2AECGRRQ-Dl4QjzIB.js} +1 -1
  207. package/dist/web-shell/assets/{diagram-5GNKFQAL-CtnhZUP1.js → diagram-5GNKFQAL-qMLmsO0u.js} +1 -1
  208. package/dist/web-shell/assets/{diagram-KO2AKTUF-CS_IUezp.js → diagram-KO2AKTUF-CHlmuxPI.js} +1 -1
  209. package/dist/web-shell/assets/{diagram-LMA3HP47-BQnGRwN9.js → diagram-LMA3HP47-BUwU3GwT.js} +1 -1
  210. package/dist/web-shell/assets/{diagram-OG6HWLK6-By2VIocq.js → diagram-OG6HWLK6-HEhwPDUM.js} +1 -1
  211. package/dist/web-shell/assets/{erDiagram-TEJ5UH35-Dy8WeNkr.js → erDiagram-TEJ5UH35-1n0llBmM.js} +1 -1
  212. package/dist/web-shell/assets/{flowDiagram-I6XJVG4X-Diu_4y0w.js → flowDiagram-I6XJVG4X-BN74uMnt.js} +1 -1
  213. package/dist/web-shell/assets/{ganttDiagram-6RSMTGT7-CH8euujP.js → ganttDiagram-6RSMTGT7-BoOq78i3.js} +1 -1
  214. package/dist/web-shell/assets/{gitGraphDiagram-PVQCEYII-DHiObZq1.js → gitGraphDiagram-PVQCEYII-CN8b00c8.js} +1 -1
  215. package/dist/web-shell/assets/index-CNwoO1Cn.js +783 -0
  216. package/dist/web-shell/assets/index-CWQ0z6kZ.css +5 -0
  217. package/dist/web-shell/assets/{infoDiagram-5YYISTIA-CvC9A6fh.js → infoDiagram-5YYISTIA-CCurnIna.js} +1 -1
  218. package/dist/web-shell/assets/{ishikawaDiagram-YF4QCWOH-BK46kC4E.js → ishikawaDiagram-YF4QCWOH-AwuRqdUP.js} +1 -1
  219. package/dist/web-shell/assets/{journeyDiagram-JHISSGLW-B2TIiKq4.js → journeyDiagram-JHISSGLW-B7IICk-E.js} +1 -1
  220. package/dist/web-shell/assets/{kanban-definition-UN3LZRKU-Bh0WAulO.js → kanban-definition-UN3LZRKU-BYF0OKhx.js} +1 -1
  221. package/dist/web-shell/assets/{linear-Bxe9SHMk.js → linear-GWWguGfD.js} +1 -1
  222. package/dist/web-shell/assets/{mermaid.core-B1Pv6D5B.js → mermaid.core-JqtkxvCl.js} +5 -5
  223. package/dist/web-shell/assets/{mindmap-definition-RKZ34NQL-Bz0joLH8.js → mindmap-definition-RKZ34NQL-B0MmHsZ6.js} +1 -1
  224. package/dist/web-shell/assets/{pieDiagram-4H26LBE5-CnN4x-VS.js → pieDiagram-4H26LBE5-DhImUZLQ.js} +1 -1
  225. package/dist/web-shell/assets/{quadrantDiagram-W4KKPZXB-BYWD4xO4.js → quadrantDiagram-W4KKPZXB-DGeSC3DT.js} +1 -1
  226. package/dist/web-shell/assets/{requirementDiagram-4Y6WPE33-B4MEhI9h.js → requirementDiagram-4Y6WPE33-DkspY6Re.js} +1 -1
  227. package/dist/web-shell/assets/{sankeyDiagram-5OEKKPKP-Dk_FgKLp.js → sankeyDiagram-5OEKKPKP-CaOofS2x.js} +1 -1
  228. package/dist/web-shell/assets/{sequenceDiagram-3UESZ5HK-B4ksiBZQ.js → sequenceDiagram-3UESZ5HK-DFQ_kFnN.js} +1 -1
  229. package/dist/web-shell/assets/{stateDiagram-AJRCARHV-CYf0xSPl.js → stateDiagram-AJRCARHV-D3snw0Tz.js} +1 -1
  230. package/dist/web-shell/assets/stateDiagram-v2-BHNVJYJU-BbSm_9d0.js +1 -0
  231. package/dist/web-shell/assets/{timeline-definition-PNZ67QCA-0CXeWHNY.js → timeline-definition-PNZ67QCA-l4zH8nLM.js} +1 -1
  232. package/dist/web-shell/assets/{vennDiagram-CIIHVFJN-DHoYY9v2.js → vennDiagram-CIIHVFJN-BnRlA98M.js} +1 -1
  233. package/dist/web-shell/assets/{wardley-L42UT6IY-D_65qshr.js → wardley-L42UT6IY-BS0xUdmd.js} +1 -1
  234. package/dist/web-shell/assets/{wardleyDiagram-YWT4CUSO-Cv90x1sd.js → wardleyDiagram-YWT4CUSO-DKGBUWyQ.js} +1 -1
  235. package/dist/web-shell/assets/{xychartDiagram-2RQKCTM6-5FQCYJyh.js → xychartDiagram-2RQKCTM6-DVb2HuOB.js} +1 -1
  236. package/dist/web-shell/index.html +2 -2
  237. package/package.json +3 -2
  238. package/dist/web-shell/assets/channel-V-ZaJrA6.js +0 -1
  239. package/dist/web-shell/assets/classDiagram-4FO5ZUOK-s-H0snGT.js +0 -1
  240. package/dist/web-shell/assets/classDiagram-v2-Q7XG4LA2-s-H0snGT.js +0 -1
  241. package/dist/web-shell/assets/index-DW75jq0K.css +0 -5
  242. package/dist/web-shell/assets/index-tiCo0xbZ.js +0 -779
  243. package/dist/web-shell/assets/stateDiagram-v2-BHNVJYJU-CMtrFRUb.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,12 @@ 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-PA7QS4X5.js";
67
+ } from "./chunk-V2TYBEWU.js";
68
+ import "./chunk-43W4YSO6.js";
63
69
  import {
64
70
  writeStderrLine,
65
71
  writeStdoutLine
@@ -104,7 +110,7 @@ var DuplicateWorkspaceInputError = class extends Error {
104
110
  }
105
111
  constructor(workspace) {
106
112
  super(
107
- `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.`
108
114
  );
109
115
  this.name = "DuplicateWorkspaceInputError";
110
116
  }
@@ -115,22 +121,11 @@ var NestedWorkspaceInputError = class extends Error {
115
121
  }
116
122
  constructor(parent, child) {
117
123
  super(
118
- `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.`
119
125
  );
120
126
  this.name = "NestedWorkspaceInputError";
121
127
  }
122
128
  };
123
- var MultipleWorkspaceInputError = class extends Error {
124
- static {
125
- __name(this, "MultipleWorkspaceInputError");
126
- }
127
- constructor() {
128
- super(
129
- "Multiple --workspace values are not supported yet. Multi-workspace serve is not enabled; pass one --workspace."
130
- );
131
- this.name = "MultipleWorkspaceInputError";
132
- }
133
- };
134
129
  var MissingWorkspaceInputError = class extends Error {
135
130
  static {
136
131
  __name(this, "MissingWorkspaceInputError");
@@ -155,7 +150,7 @@ function isNestedWorkspace(parent, child) {
155
150
  return parent !== child && isWithinRoot(child, parent);
156
151
  }
157
152
  __name(isNestedWorkspace, "isNestedWorkspace");
158
- function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
153
+ function rejectDuplicateOrNestedWorkspaceInputs(workspaces) {
159
154
  if (workspaces.length <= 1) return;
160
155
  let canonicalWorkspaces;
161
156
  try {
@@ -163,7 +158,7 @@ function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
163
158
  (workspace) => canonicalizeWorkspace(workspace)
164
159
  );
165
160
  } catch {
166
- throw new MultipleWorkspaceInputError();
161
+ return;
167
162
  }
168
163
  const seen = /* @__PURE__ */ new Set();
169
164
  for (const workspace of canonicalWorkspaces) {
@@ -184,15 +179,14 @@ function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
184
179
  }
185
180
  }
186
181
  }
187
- throw new MultipleWorkspaceInputError();
188
182
  }
189
- __name(rejectUnsupportedMultiWorkspaceInputs, "rejectUnsupportedMultiWorkspaceInputs");
190
- function resolveSingleWorkspaceInput(workspace) {
183
+ __name(rejectDuplicateOrNestedWorkspaceInputs, "rejectDuplicateOrNestedWorkspaceInputs");
184
+ function resolveWorkspaceInputs(workspace) {
191
185
  const workspaces = normalizeWorkspaceInputs(workspace);
192
- rejectUnsupportedMultiWorkspaceInputs(workspaces);
193
- return workspaces[0];
186
+ rejectDuplicateOrNestedWorkspaceInputs(workspaces);
187
+ return workspaces;
194
188
  }
195
- __name(resolveSingleWorkspaceInput, "resolveSingleWorkspaceInput");
189
+ __name(resolveWorkspaceInputs, "resolveWorkspaceInputs");
196
190
 
197
191
  // packages/cli/src/serve/permission-audit.ts
198
192
  init_esbuild_shims();
@@ -938,11 +932,21 @@ function isNonNegativeIntegerOrInfinity(value) {
938
932
  return value === Number.POSITIVE_INFINITY || Number.isFinite(value) && Number.isInteger(value) && value >= 0;
939
933
  }
940
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");
941
944
  function isNonNegativeIntegerMs(value) {
942
945
  return Number.isFinite(value) && Number.isInteger(value) && value >= 0;
943
946
  }
944
947
  __name(isNonNegativeIntegerMs, "isNonNegativeIntegerMs");
945
948
  var MAX_TIMEOUT_MS = 2147483647;
949
+ var MAX_PORT_ATTEMPTS = 10;
946
950
  function assertTimerDelayInRange(name, value) {
947
951
  if (value > MAX_TIMEOUT_MS) {
948
952
  throw new TypeError(
@@ -1081,8 +1085,8 @@ __name(withSettingsLock, "withSettingsLock");
1081
1085
  var channelWorkerRuntimePromise;
1082
1086
  async function loadChannelWorkerRuntime() {
1083
1087
  channelWorkerRuntimePromise ??= Promise.all([
1084
- import("./channel-worker-supervisor-B7MSMB5K.js"),
1085
- import("./pidfile-YWSGNTPK.js")
1088
+ import("./channel-worker-supervisor-NZQUOEFJ.js"),
1089
+ import("./pidfile-7Y3QEDSZ.js")
1086
1090
  ]).then(([supervisor, pidfile]) => ({
1087
1091
  createChannelWorkerSupervisor: supervisor.createChannelWorkerSupervisor,
1088
1092
  channelServicePidfile: pidfile
@@ -1153,7 +1157,7 @@ function shouldPreheatBridge(deps) {
1153
1157
  __name(shouldPreheatBridge, "shouldPreheatBridge");
1154
1158
  var coreRuntimePromise;
1155
1159
  function loadCoreRuntime() {
1156
- coreRuntimePromise ??= import("./src-3P337V4P.js");
1160
+ coreRuntimePromise ??= import("./src-BIWCD3VX.js");
1157
1161
  return coreRuntimePromise;
1158
1162
  }
1159
1163
  __name(loadCoreRuntime, "loadCoreRuntime");
@@ -1183,11 +1187,13 @@ __name(resolveDaemonLogBaseDirForRun, "resolveDaemonLogBaseDirForRun");
1183
1187
  var settingsRuntimePromise;
1184
1188
  function loadSettingsRuntimeModules() {
1185
1189
  settingsRuntimePromise ??= Promise.all([
1186
- import("./settings-4J2O3K22.js"),
1187
- import("./loadedSettingsAdapter-ISOM6GJ7.js"),
1188
- import("./trustedFolders-ERGSUCDK.js")
1189
- ]).then(([settings, loadedSettingsAdapter, trustedFolders]) => ({
1190
+ import("./settings-LVFFGXGE.js"),
1191
+ import("./environment-WKW5TLSH.js"),
1192
+ import("./loadedSettingsAdapter-FDO752BA.js"),
1193
+ import("./trustedFolders-IJ2QHXSC.js")
1194
+ ]).then(([settings, environment, loadedSettingsAdapter, trustedFolders]) => ({
1190
1195
  settings,
1196
+ environment,
1191
1197
  loadedSettingsAdapter,
1192
1198
  trustedFolders
1193
1199
  }));
@@ -1203,16 +1209,20 @@ async function loadServeRuntimeModules() {
1203
1209
  workspaceTypesModule,
1204
1210
  daemonStatusProviderModule,
1205
1211
  workspaceProvidersStatusModule,
1206
- workspaceSkillsStatusModule
1212
+ workspaceSkillsStatusModule,
1213
+ totalSessionAdmissionModule,
1214
+ workspaceRegistryModule
1207
1215
  ] = await Promise.all([
1208
- import("./server-ACWDFHIF.js"),
1209
- import("./bridge-HVRG6SMU.js"),
1210
- import("./spawnChannel-BA3U3RGX.js"),
1211
- import("./workspace-service-GAS2LV2P.js"),
1216
+ import("./server-FVGFFVZ4.js"),
1217
+ import("./bridge-LJLLDUMW.js"),
1218
+ import("./spawnChannel-KIMZHWNR.js"),
1219
+ import("./workspace-service-V6G2RCD4.js"),
1212
1220
  import("./types-QX5C3CHJ.js"),
1213
- import("./daemon-status-provider-Y6AFXTET.js"),
1214
- import("./workspace-providers-status-ZVZPXKSO.js"),
1215
- import("./workspace-skills-status-4WGKYJVA.js")
1221
+ import("./daemon-status-provider-WBOAMCHE.js"),
1222
+ import("./workspace-providers-status-YMPTRKW2.js"),
1223
+ import("./workspace-skills-status-ZCW44BCH.js"),
1224
+ import("./total-session-admission-JOD7SMPJ.js"),
1225
+ import("./workspace-registry-NBUL6LBH.js")
1216
1226
  ]);
1217
1227
  return {
1218
1228
  createServeApp: serverModule.createServeApp,
@@ -1225,7 +1235,9 @@ async function loadServeRuntimeModules() {
1225
1235
  WorkspaceSettingsPartialPersistError: workspaceTypesModule.WorkspaceSettingsPartialPersistError,
1226
1236
  createDaemonStatusProvider: daemonStatusProviderModule.createDaemonStatusProvider,
1227
1237
  createWorkspaceProvidersStatusProvider: workspaceProvidersStatusModule.createWorkspaceProvidersStatusProvider,
1228
- createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider
1238
+ createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider,
1239
+ createTotalSessionAdmissionController: totalSessionAdmissionModule.createTotalSessionAdmissionController,
1240
+ createWorkspaceRegistry: workspaceRegistryModule.createWorkspaceRegistry
1229
1241
  };
1230
1242
  }
1231
1243
  __name(loadServeRuntimeModules, "loadServeRuntimeModules");
@@ -1421,6 +1433,7 @@ function createBootstrapServeApp(input) {
1421
1433
  qwenCodeVersion,
1422
1434
  sessionShellCommandEnabled,
1423
1435
  permissionPolicy,
1436
+ multiWorkspaceCapabilitiesRequireRuntime,
1424
1437
  getRuntimeError,
1425
1438
  getChannelWorkerSnapshot,
1426
1439
  onHealthServed
@@ -1457,6 +1470,17 @@ function createBootstrapServeApp(input) {
1457
1470
  app.get(BOOTSTRAP_HEALTH_PATH, healthHandler);
1458
1471
  }
1459
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
+ }
1460
1484
  res.status(200).json(
1461
1485
  createBootstrapCapabilities({
1462
1486
  opts,
@@ -1517,11 +1541,13 @@ function createBootstrapServeApp(input) {
1517
1541
  },
1518
1542
  limits: {
1519
1543
  maxSessions: advertisedMaxSessions(opts.maxSessions),
1544
+ maxTotalSessions: positiveFiniteOrNull(opts.maxTotalSessions),
1520
1545
  maxPendingPromptsPerSession: advertisedMaxPendingPromptsPerSession(
1521
1546
  opts.maxPendingPromptsPerSession
1522
1547
  ),
1523
1548
  listenerMaxConnections: listenerMaxConnections(opts.maxConnections),
1524
1549
  eventRingSize: opts.eventRingSize ?? DEFAULT_EVENT_RING_SIZE,
1550
+ compactedReplayMaxBytes: opts.compactedReplayMaxBytes ?? DEFAULT_COMPACTED_REPLAY_MAX_BYTES,
1525
1551
  promptDeadlineMs: positiveFiniteOrNull(opts.promptDeadlineMs),
1526
1552
  writerIdleTimeoutMs: positiveFiniteOrNull(opts.writerIdleTimeoutMs),
1527
1553
  channelIdleTimeoutMs: channelIdleTimeoutMs(opts.channelIdleTimeoutMs),
@@ -1662,6 +1688,9 @@ async function runQwenServe(optsIn, deps = {}) {
1662
1688
  }
1663
1689
  };
1664
1690
  preResolveServeFastPathHomeEnvOverrides();
1691
+ const daemonRuntimeBaseEnv = Object.freeze({
1692
+ ...process.env
1693
+ });
1665
1694
  const rawToken = optsIn.token ?? process.env[QWEN_SERVER_TOKEN_ENV];
1666
1695
  const token = typeof rawToken === "string" && rawToken.trim().length > 0 ? rawToken.trim() : void 0;
1667
1696
  const sessionShellCommandEnabled = optsIn.enableSessionShell === true && token !== void 0;
@@ -1683,7 +1712,8 @@ async function runQwenServe(optsIn, deps = {}) {
1683
1712
  const chromeExtensionOriginAllowed = hasChromeExtensionOrigin(
1684
1713
  optsIn.allowOrigins
1685
1714
  );
1686
- const rawWorkspace = resolveSingleWorkspaceInput(optsIn.workspace);
1715
+ const rawWorkspaces = resolveWorkspaceInputs(optsIn.workspace);
1716
+ const rawWorkspace = rawWorkspaces[0];
1687
1717
  const opts = {
1688
1718
  ...optsIn,
1689
1719
  token,
@@ -1829,35 +1859,76 @@ async function runQwenServe(optsIn, deps = {}) {
1829
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."
1830
1860
  );
1831
1861
  }
1832
- if (!path.isAbsolute(rawWorkspace)) {
1833
- throw new Error(
1834
- `Invalid --workspace "${rawWorkspace}": must be an absolute path.`
1835
- );
1836
- }
1837
- try {
1838
- const stats = fs.statSync(rawWorkspace);
1839
- if (!stats.isDirectory()) {
1862
+ const validateAndCanonicalizeWorkspace = /* @__PURE__ */ __name((workspace) => {
1863
+ if (!path.isAbsolute(workspace)) {
1840
1864
  throw new Error(
1841
- `Invalid --workspace "${rawWorkspace}": exists but is not a directory.`
1865
+ `Invalid --workspace "${workspace}": must be an absolute path.`
1842
1866
  );
1843
1867
  }
1844
- } catch (err) {
1845
- if (err && typeof err === "object" && "code" in err) {
1846
- const code = err.code;
1847
- if (code === "ENOENT") {
1868
+ try {
1869
+ const stats = fs.statSync(workspace);
1870
+ if (!stats.isDirectory()) {
1848
1871
  throw new Error(
1849
- `Invalid --workspace "${rawWorkspace}": directory does not exist.`
1872
+ `Invalid --workspace "${workspace}": exists but is not a directory.`
1850
1873
  );
1851
1874
  }
1852
- 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)) {
1853
1916
  throw new Error(
1854
- `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)}.`
1855
1923
  );
1856
1924
  }
1857
1925
  }
1858
- throw err;
1859
1926
  }
1860
- 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
+ }
1861
1932
  let contextFilenameForInit;
1862
1933
  let permissionPolicy;
1863
1934
  let permissionConsensusQuorum;
@@ -1918,6 +1989,13 @@ async function runQwenServe(optsIn, deps = {}) {
1918
1989
  );
1919
1990
  }
1920
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
+ }
1921
1999
  if (opts.maxPendingPromptsPerSession !== void 0) {
1922
2000
  if (!isNonNegativeIntegerOrInfinity(opts.maxPendingPromptsPerSession)) {
1923
2001
  throw new TypeError(
@@ -1932,6 +2010,9 @@ async function runQwenServe(optsIn, deps = {}) {
1932
2010
  );
1933
2011
  }
1934
2012
  }
2013
+ if (opts.compactedReplayMaxBytes !== void 0) {
2014
+ normalizeCompactedReplayMaxBytes(opts.compactedReplayMaxBytes);
2015
+ }
1935
2016
  if (opts.writerIdleTimeoutMs !== void 0) {
1936
2017
  if (!isPositiveIntegerMs(opts.writerIdleTimeoutMs)) {
1937
2018
  throw new TypeError(
@@ -1967,6 +2048,10 @@ async function runQwenServe(optsIn, deps = {}) {
1967
2048
  );
1968
2049
  }
1969
2050
  }
2051
+ opts.maxTotalSessions ??= deriveDefaultMaxTotalSessions(
2052
+ opts.maxSessions,
2053
+ workspaceInputs.length
2054
+ );
1970
2055
  const inheritedNoPool = process.env["QWEN_SERVE_NO_MCP_POOL"] === "1";
1971
2056
  if (opts.mcpPoolActive === void 0 && inheritedNoPool) {
1972
2057
  opts.mcpPoolActive = false;
@@ -2004,6 +2089,7 @@ async function runQwenServe(optsIn, deps = {}) {
2004
2089
  let runtimeApp;
2005
2090
  let runtimeAppForCleanup;
2006
2091
  let bridgeRef = deps.bridge;
2092
+ const internalRuntimeBridgesForCleanup = [];
2007
2093
  let daemonEventLoopMonitor;
2008
2094
  let daemonMetricsSampler;
2009
2095
  let runtimeStartupError;
@@ -2046,6 +2132,17 @@ async function runQwenServe(optsIn, deps = {}) {
2046
2132
  () => bridgeRef,
2047
2133
  () => runtimeStartupError
2048
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");
2049
2146
  const buildRuntime = /* @__PURE__ */ __name(async () => {
2050
2147
  const [runtime, core, settingsRuntime, resolvedCliVersion] = await Promise.all([
2051
2148
  loadServeRuntimeModules(),
@@ -2072,6 +2169,43 @@ async function runQwenServe(optsIn, deps = {}) {
2072
2169
  { workspace: boundWorkspace }
2073
2170
  );
2074
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
+ };
2075
2209
  const daemonWorkspaceHash = core.hashDaemonWorkspace(boundWorkspace);
2076
2210
  let daemonTelemetrySettings;
2077
2211
  try {
@@ -2144,54 +2278,58 @@ async function runQwenServe(optsIn, deps = {}) {
2144
2278
  promptQueueWaitStats.lastMs = durationMs;
2145
2279
  core.recordDaemonPromptQueueWait(durationMs);
2146
2280
  }, "recordPromptQueueWait");
2147
- const daemonTelemetry = core.createDaemonBridgeTelemetry();
2148
- daemonTelemetry.metrics = {
2149
- sessionLifecycle(action) {
2150
- core.recordDaemonSessionLifecycle(action);
2151
- core.emitDaemonLog(
2152
- `Session ${action}.`,
2153
- {
2154
- "qwen-code.workspace.hash": daemonWorkspaceHash
2155
- },
2156
- {
2157
- eventName: `qwen-code.daemon.session.${action}`
2158
- }
2159
- );
2160
- },
2161
- channelLifecycle(action, expected) {
2162
- core.recordDaemonChannelLifecycle(action, expected);
2163
- core.emitDaemonLog(
2164
- action === "spawn" ? "ACP channel spawned." : `ACP channel exited (expected=${expected ?? true}).`,
2165
- {
2166
- ...action === "exit" ? { "qwen-code.daemon.channel.expected": expected ?? true } : {}
2167
- },
2168
- {
2169
- eventName: `qwen-code.daemon.channel.${action}`,
2170
- ...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);
2171
2327
  }
2172
- );
2173
- },
2174
- promptQueueWait(durationMs) {
2175
- recordPromptQueueWait(durationMs);
2176
- metricsRing.recordPromptQueueWait(durationMs);
2177
- },
2178
- promptDuration(durationMs) {
2179
- core.recordDaemonPromptDuration(durationMs);
2180
- metricsRing.recordPromptDuration(durationMs);
2181
- },
2182
- cancelled: core.recordDaemonCancel,
2183
- // Per-round model token usage + LLM round-trip time sniffed off
2184
- // `agent_message_chunk._meta` (`usage` + `durationMs`) at the bridge's
2185
- // single session/update fan-in. Increments (not cumulative), so the ring
2186
- // sums tokens per window (token-burn chart) and pools the round-trip times
2187
- // for the LLM-latency percentiles.
2188
- tokenUsage(inputTokens, outputTokens, durationMs) {
2189
- metricsRing.recordTokens(inputTokens, outputTokens);
2190
- if (typeof durationMs === "number") {
2191
- metricsRing.recordLlmDuration(durationMs);
2192
2328
  }
2193
- }
2194
- };
2329
+ };
2330
+ return telemetry;
2331
+ }, "createRuntimeBridgeTelemetry");
2332
+ const daemonTelemetry = createRuntimeBridgeTelemetry(daemonWorkspaceHash);
2195
2333
  const permissionAuditRing = new PermissionAuditRing();
2196
2334
  const permissionAuditPublisher = createPermissionAuditPublisher({
2197
2335
  ring: permissionAuditRing
@@ -2238,7 +2376,17 @@ async function runQwenServe(optsIn, deps = {}) {
2238
2376
  pathLocks: sharedPathLocks,
2239
2377
  ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2240
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
+ });
2241
2388
  const channelFactory = runtime.createSpawnChannelFactory({
2389
+ sourceEnv: runtimeEffectiveEnv,
2242
2390
  onDiagnosticLine: diagnosticSink,
2243
2391
  pipeHooks: {
2244
2392
  onMessageSent: /* @__PURE__ */ __name((bytes) => recordPipeMessage("outbound", bytes), "onMessageSent"),
@@ -2251,10 +2399,21 @@ async function runQwenServe(optsIn, deps = {}) {
2251
2399
  },
2252
2400
  ...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
2253
2401
  });
2254
- const statusProvider = runtime.createDaemonStatusProvider();
2255
- const workspaceProvidersStatusProvider = runtime.createWorkspaceProvidersStatusProvider();
2402
+ const statusProvider = runtime.createDaemonStatusProvider({
2403
+ env: runtimeEffectiveEnv
2404
+ });
2405
+ const workspaceProvidersStatusProvider = runtime.createWorkspaceProvidersStatusProvider({
2406
+ env: runtimeEffectiveEnv
2407
+ });
2256
2408
  const workspaceSkillsStatusProvider = runtime.createWorkspaceSkillsStatusProvider();
2257
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
+ );
2258
2417
  const persistDisabledToolsFn = /* @__PURE__ */ __name((workspace, toolName, enabled) => withSettingsLock(workspace, async () => {
2259
2418
  const fresh = settingsRuntime.settings.loadSettings(workspace);
2260
2419
  const wsScope = fresh.forScope(WORKSPACE_SETTING_SCOPE).settings;
@@ -2306,8 +2465,10 @@ async function runQwenServe(optsIn, deps = {}) {
2306
2465
  // connection that hosts a named client MCP server (#5626).
2307
2466
  clientMcpSender: clientMcpSenderRegistry.lookup,
2308
2467
  maxSessions: opts.maxSessions,
2468
+ freshSessionAdmission: totalSessionAdmission.admit,
2309
2469
  ...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
2310
2470
  ...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
2471
+ ...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
2311
2472
  ...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
2312
2473
  ...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
2313
2474
  ...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
@@ -2330,7 +2491,9 @@ async function runQwenServe(optsIn, deps = {}) {
2330
2491
  });
2331
2492
  if (!deps.bridge) {
2332
2493
  bridgeRef = bridge;
2494
+ internalRuntimeBridgesForCleanup.push(bridge);
2333
2495
  }
2496
+ runtimeBridges.push(bridge);
2334
2497
  const workspaceService = runtime.createDaemonWorkspaceService({
2335
2498
  boundWorkspace,
2336
2499
  contextFilename: contextFilenameForInit ?? "QWEN.md",
@@ -2345,18 +2508,273 @@ async function runQwenServe(optsIn, deps = {}) {
2345
2508
  const fresh = settingsRuntime.settings.loadSettings(workspace, {
2346
2509
  skipLoadEnvironment: true
2347
2510
  });
2348
- return settingsRuntime.settings.reloadEnvironment(
2511
+ const result = settingsRuntime.settings.reloadEnvironment(
2349
2512
  fresh.merged,
2350
2513
  workspace
2351
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;
2352
2565
  }), "reloadDaemonEnv"),
2353
2566
  queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => bridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
2354
2567
  invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => bridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
2355
2568
  refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => bridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
2356
2569
  publishWorkspaceEvent: /* @__PURE__ */ __name((event) => bridge.publishWorkspaceEvent(event), "publishWorkspaceEvent")
2357
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);
2358
2776
  core.registerDaemonGaugeCallbacks({
2359
- sessionCount: /* @__PURE__ */ __name(() => bridge.sessionCount, "sessionCount"),
2777
+ sessionCount: /* @__PURE__ */ __name(() => workspaceRegistry.list().reduce((sum, item) => sum + item.bridge.sessionCount, 0), "sessionCount"),
2360
2778
  sseCount: /* @__PURE__ */ __name(() => runtime.getActiveSseCount(), "sseCount"),
2361
2779
  heapUsed: /* @__PURE__ */ __name(() => process.memoryUsage().heapUsed, "heapUsed")
2362
2780
  });
@@ -2396,9 +2814,15 @@ async function runQwenServe(optsIn, deps = {}) {
2396
2814
  cpuPercent,
2397
2815
  rssBytes: mem.rss,
2398
2816
  heapUsedBytes: mem.heapUsed,
2399
- activeSessions: bridge.sessionCount,
2400
- activePrompts: bridge.activePromptCount,
2401
- 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
+ ),
2402
2826
  eventLoopLagP99Ms,
2403
2827
  sseConnections: runtime.getActiveSseCount(),
2404
2828
  wsConnections: acp?.wsStreams ?? 0,
@@ -2441,21 +2865,19 @@ async function runQwenServe(optsIn, deps = {}) {
2441
2865
  }
2442
2866
  };
2443
2867
  const app2 = runtime.createServeApp(opts, () => actualPort, {
2868
+ workspaceRegistry,
2444
2869
  bridge,
2445
2870
  webShellDir,
2446
2871
  boundWorkspace,
2447
2872
  qwenCodeVersion: resolvedCliVersion,
2448
2873
  startup,
2449
- fsFactory: runtime.resolveBridgeFsFactory({
2450
- // REST routes still return primary-relative paths, so keep their
2451
- // filesystem boundary primary-only until responses carry root IDs.
2452
- boundWorkspaces: [boundWorkspace],
2453
- trusted: trustedWorkspace,
2454
- emit: deps.fsAuditEmit,
2455
- pathLocks: sharedPathLocks,
2456
- ...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
2457
- }),
2874
+ // The real long-running daemon keeps scheduled-task sessions resident
2875
+ // (keepalive) and reloads them on boot (rehydration). Off by default so
2876
+ // direct createServeApp embeds/tests don't spawn sessions.
2877
+ manageScheduledTaskSessions: true,
2878
+ fsFactory: routeFsFactory,
2458
2879
  primaryWorkspaceTrusted: trustedWorkspace,
2880
+ primaryRuntimeEnv,
2459
2881
  daemonLog,
2460
2882
  getChannelWorkerSnapshot,
2461
2883
  getPerfSnapshot: /* @__PURE__ */ __name(() => ({
@@ -2472,6 +2894,7 @@ async function runQwenServe(optsIn, deps = {}) {
2472
2894
  }
2473
2895
  }), "getPerfSnapshot"),
2474
2896
  getMetricsSeries: /* @__PURE__ */ __name(() => metricsRing.snapshot(), "getMetricsSeries"),
2897
+ getTotalSessionAdmissionSnapshot: totalSessionAdmission.snapshot,
2475
2898
  recordDaemonRequest: /* @__PURE__ */ __name((durationMs, statusCode) => metricsRing.recordRequest(durationMs, statusCode), "recordDaemonRequest"),
2476
2899
  workspace: workspaceService,
2477
2900
  // Reverse tool channel (#5626): the SAME registry wired into `bridge` above,
@@ -2540,6 +2963,7 @@ async function runQwenServe(optsIn, deps = {}) {
2540
2963
  qwenCodeVersion: cliVersion,
2541
2964
  sessionShellCommandEnabled,
2542
2965
  permissionPolicy,
2966
+ multiWorkspaceCapabilitiesRequireRuntime: workspaceInputs.length > 1,
2543
2967
  getRuntimeError: /* @__PURE__ */ __name(() => runtimeStartupError, "getRuntimeError"),
2544
2968
  getChannelWorkerSnapshot,
2545
2969
  onHealthServed: deferRuntimeUntilFirstHealth ? () => startRuntimeAfterHealth?.() : void 0
@@ -2689,6 +3113,8 @@ async function runQwenServe(optsIn, deps = {}) {
2689
3113
  }, "cancelDeferredRuntimeStartup");
2690
3114
  const shutdownBridgeAfterFailedStartup = /* @__PURE__ */ __name(async (bridge) => {
2691
3115
  if (!bridge || deps.bridge) return;
3116
+ if (shutdownBridges.has(bridge)) return;
3117
+ shutdownBridges.add(bridge);
2692
3118
  try {
2693
3119
  await bridge.shutdown();
2694
3120
  } catch (shutdownErr) {
@@ -2729,7 +3155,10 @@ async function runQwenServe(optsIn, deps = {}) {
2729
3155
  await stopChannelWorkerAfterFailedStartup();
2730
3156
  disposeDaemonEventLoopMonitor();
2731
3157
  removeCurrentServePidfile();
2732
- await shutdownBridgeAfterFailedStartup(bridgeForCleanup ?? bridgeRef);
3158
+ const bridgesForCleanup = bridgeForCleanup ? [bridgeForCleanup, ...getRuntimeBridgesForCleanup()] : getRuntimeBridgesForCleanup();
3159
+ for (const bridge of [...new Set(bridgesForCleanup)]) {
3160
+ await shutdownBridgeAfterFailedStartup(bridge);
3161
+ }
2733
3162
  markRuntimeFailed(error);
2734
3163
  }, "failRuntimeStartup");
2735
3164
  const armRuntimeStartupTimer = /* @__PURE__ */ __name(() => {
@@ -2838,7 +3267,9 @@ async function runQwenServe(optsIn, deps = {}) {
2838
3267
  daemonLog.warn(`received ${signal} during drain \u2014 forcing exit`);
2839
3268
  try {
2840
3269
  channelWorker.killAllSync();
2841
- bridgeRef?.killAllSync();
3270
+ for (const runtimeBridge of getRuntimeBridgesForCleanup()) {
3271
+ runtimeBridge.killAllSync();
3272
+ }
2842
3273
  removeCurrentServePidfile();
2843
3274
  } catch (err) {
2844
3275
  daemonLog.error(
@@ -2879,6 +3310,7 @@ async function runQwenServe(optsIn, deps = {}) {
2879
3310
  if (closePromise) return closePromise;
2880
3311
  closePromise = new Promise((res, rej) => {
2881
3312
  shuttingDown = true;
3313
+ app.locals.stopScheduledTaskKeepalive?.();
2882
3314
  clearRuntimeStartAfterHealthTimer();
2883
3315
  clearRuntimeStartFallbackTimer();
2884
3316
  cancelDeferredRuntimeStartup();
@@ -2948,8 +3380,9 @@ async function runQwenServe(optsIn, deps = {}) {
2948
3380
  );
2949
3381
  });
2950
3382
  removeCurrentServePidfile();
2951
- const bridgeForShutdown = bridgeRef;
2952
- if (bridgeForShutdown) {
3383
+ for (const bridgeForShutdown of getRuntimeBridgesForCleanup()) {
3384
+ if (shutdownBridges.has(bridgeForShutdown)) continue;
3385
+ shutdownBridges.add(bridgeForShutdown);
2953
3386
  await bridgeForShutdown.shutdown().catch((err) => {
2954
3387
  daemonLog.error(
2955
3388
  "bridge shutdown error",
@@ -3028,8 +3461,8 @@ async function runQwenServe(optsIn, deps = {}) {
3028
3461
  }
3029
3462
  }, "onListening");
3030
3463
  let server;
3464
+ let httpsServer;
3031
3465
  if (tlsOptions) {
3032
- let httpsServer;
3033
3466
  try {
3034
3467
  httpsServer = https.createServer(tlsOptions, app);
3035
3468
  } catch (err) {
@@ -3040,14 +3473,40 @@ async function runQwenServe(optsIn, deps = {}) {
3040
3473
  );
3041
3474
  return;
3042
3475
  }
3043
- server = httpsServer.listen(opts.port, listenHostname, onListening);
3044
- } else {
3045
- server = app.listen(opts.port, listenHostname, onListening);
3046
3476
  }
3047
- server.once("error", (err) => {
3048
- removeCurrentServePidfile();
3049
- reject(err);
3050
- });
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);
3051
3510
  });
3052
3511
  }
3053
3512
  __name(runQwenServe, "runQwenServe");