@qwen-code/qwen-code 0.19.3 → 0.19.4-nightly.20260702.46814e4f1

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 (308) hide show
  1. package/bundled/loop/SKILL.md +22 -3
  2. package/bundled/loop/SKILL.test.ts +20 -0
  3. package/bundled/loop/autonomous-loop.test.ts +59 -0
  4. package/bundled/loop/autonomous-loop.ts +102 -0
  5. package/bundled/loop/loop-task-file.test.ts +1064 -0
  6. package/bundled/loop/loop-task-file.ts +404 -0
  7. package/bundled/loop/loop-tick-resolver.test.ts +906 -0
  8. package/bundled/loop/loop-tick-resolver.ts +416 -0
  9. package/bundled/qc-helper/SKILL.md +12 -5
  10. package/bundled/qc-helper/docs/configuration/auth.md +1 -1
  11. package/bundled/qc-helper/docs/configuration/settings.md +62 -32
  12. package/bundled/qc-helper/docs/features/approval-mode.md +3 -0
  13. package/bundled/qc-helper/docs/features/auto-mode.md +40 -0
  14. package/bundled/qc-helper/docs/features/channels/overview.md +81 -18
  15. package/bundled/qc-helper/docs/features/channels/plugins.md +1 -1
  16. package/bundled/qc-helper/docs/features/code-review.md +17 -61
  17. package/bundled/qc-helper/docs/features/commands.md +42 -40
  18. package/bundled/qc-helper/docs/features/headless.md +19 -18
  19. package/bundled/qc-helper/docs/features/hooks.md +6 -1
  20. package/bundled/qc-helper/docs/features/mcp.md +3 -1
  21. package/bundled/qc-helper/docs/features/memory.md +1 -1
  22. package/bundled/qc-helper/docs/features/scheduled-tasks.md +10 -0
  23. package/bundled/qc-helper/docs/features/status-line.md +3 -3
  24. package/bundled/qc-helper/docs/ide-integration/ide-integration.md +4 -4
  25. package/bundled/qc-helper/docs/qwen-serve.md +53 -0
  26. package/bundled/qc-helper/docs/support/troubleshooting.md +11 -0
  27. package/bundled/review/DESIGN.md +21 -26
  28. package/bundled/review/SKILL.md +45 -129
  29. package/chunks/MaxSizedBox-GHGRQ2OS.js +69 -0
  30. package/chunks/{StandaloneSessionPicker-Z52JTYST.js → StandaloneSessionPicker-G7YTTM27.js} +49 -42
  31. package/chunks/{acpAgent-7RZUOWOM.js → acpAgent-SDOILBSU.js} +1325 -365
  32. package/chunks/{agent-4FG7WTHJ.js → agent-NTSXGV4L.js} +31 -25
  33. package/chunks/agent-headless-WYURMSAB.js +62 -0
  34. package/chunks/{anthropicContentGenerator-PFITVL7Y.js → anthropicContentGenerator-WL3LJOUB.js} +110 -31
  35. package/chunks/{artifact-tool-D2X7G3C3.js → artifact-tool-W76WC2JX.js} +3 -3
  36. package/chunks/{askUserQuestion-UGETICJQ.js → askUserQuestion-J3P6TH3V.js} +2 -2
  37. package/chunks/bridge-AMOL4W4P.js +73 -0
  38. package/chunks/{ca-IUFWESZL.js → ca-HCMB2I54.js} +10 -9
  39. package/chunks/channel-worker-supervisor-C3IB63V7.js +659 -0
  40. package/chunks/{chunk-STUWFKGD.js → chunk-26JIREA5.js} +466 -543
  41. package/chunks/{chunk-SLNKLLEO.js → chunk-2MRV62AU.js} +37 -8
  42. package/chunks/{chunk-ODLIHNOY.js → chunk-2U4HUMOL.js} +1 -1
  43. package/chunks/{chunk-CKQA6AWF.js → chunk-4D73HUOP.js} +1 -1
  44. package/chunks/{chunk-M2U5NM24.js → chunk-54YZOP7P.js} +309 -72
  45. package/chunks/{chunk-J7FA27RO.js → chunk-5LKL3PAU.js} +3 -3
  46. package/chunks/chunk-5P5XGNYH.js +93 -0
  47. package/chunks/{chunk-UFLGERMB.js → chunk-6JE32BRB.js} +178 -124
  48. package/chunks/{chunk-FKAVULLM.js → chunk-75AVTQJ2.js} +74 -10
  49. package/chunks/{chunk-I2LYBGNI.js → chunk-7IOMIYOE.js} +1 -1
  50. package/chunks/{chunk-4LUZAKMK.js → chunk-7KXAGQJ2.js} +1 -1
  51. package/chunks/{chunk-BXSHL2SF.js → chunk-7LUOQJ3D.js} +1 -1
  52. package/chunks/{chunk-YAINVQ3Q.js → chunk-A5OPLHFM.js} +18693 -17055
  53. package/chunks/chunk-AHNXYU4O.js +24 -0
  54. package/chunks/{chunk-UX4SGCGN.js → chunk-AVQDCKNF.js} +96 -22
  55. package/chunks/{chunk-HYCC3XM3.js → chunk-B236XPGF.js} +1 -1
  56. package/chunks/chunk-B6SZLQAZ.js +3523 -0
  57. package/chunks/{chunk-5DWXLGOM.js → chunk-BJBWRCSK.js} +1 -1
  58. package/chunks/chunk-BPFJQGY7.js +193 -0
  59. package/chunks/{chunk-SKQZZVAV.js → chunk-BZHLWC6T.js} +2 -2
  60. package/chunks/{chunk-U3KSMM7G.js → chunk-D5KISTLW.js} +339 -383
  61. package/chunks/{chunk-GT2FGICD.js → chunk-DE7YXUR7.js} +1 -1
  62. package/chunks/{chunk-BUUQ5HPX.js → chunk-DG573EOO.js} +1 -1
  63. package/chunks/{chunk-VVLOGDB6.js → chunk-DX3TKXNT.js} +2 -2
  64. package/chunks/chunk-E5A7LHNN.js +51 -0
  65. package/chunks/{chunk-3PJXIDKI.js → chunk-E6US47KI.js} +3 -27
  66. package/chunks/{chunk-QBZ22PQX.js → chunk-EWALXUAD.js} +3 -1
  67. package/chunks/{chunk-PDE7CSDS.js → chunk-FXKI7OW6.js} +2 -2
  68. package/chunks/{chunk-F3ZYSEY6.js → chunk-FY4TT4L4.js} +3 -3
  69. package/chunks/{chunk-QLDPRILK.js → chunk-G7OQ3RFJ.js} +3 -3
  70. package/chunks/{chunk-R2BXK7SX.js → chunk-GHOTR7HL.js} +6 -1
  71. package/chunks/{chunk-KMGMKW5Q.js → chunk-GLPV75ES.js} +9 -3
  72. package/chunks/{chunk-LD2XBG6Z.js → chunk-GO6LNQXT.js} +1 -39
  73. package/chunks/{chunk-CNLEDYE3.js → chunk-H6TNLOLM.js} +5 -5
  74. package/chunks/{chunk-JVHEVCAU.js → chunk-HLW4EGKR.js} +31 -6
  75. package/chunks/{chunk-I4H7PRWQ.js → chunk-HTWHAN44.js} +1 -1
  76. package/chunks/{chunk-QE6KJYLT.js → chunk-IPYE5BIS.js} +123 -25
  77. package/chunks/{chunk-EJYJYJZ2.js → chunk-IRJWHZWU.js} +3 -70
  78. package/chunks/{chunk-EDMZZFDU.js → chunk-J3YPTTNL.js} +930 -798
  79. package/chunks/{chunk-GGBIN5K7.js → chunk-JGAJMIJZ.js} +1 -1
  80. package/chunks/{chunk-N4EJFBN5.js → chunk-JVLP5US5.js} +427 -263
  81. package/chunks/{chunk-R5OP2ATH.js → chunk-JZG7VB6C.js} +11 -11
  82. package/chunks/{chunk-QI7GOGJR.js → chunk-KKQWC6WS.js} +1 -1
  83. package/chunks/{chunk-ADCIHOQZ.js → chunk-KX5QZRW2.js} +142 -30
  84. package/chunks/{chunk-SBBN4BWR.js → chunk-L7OJ3ZO3.js} +1 -1
  85. package/chunks/{chunk-NDOC6M5S.js → chunk-L7QPM2YD.js} +2 -2
  86. package/chunks/{chunk-BVSVIN45.js → chunk-LKWAVAB5.js} +3 -3
  87. package/chunks/{chunk-T4T2FNV4.js → chunk-LOW52WYZ.js} +2 -2
  88. package/chunks/{chunk-4QK3O43S.js → chunk-LU7BIVWC.js} +4 -4
  89. package/chunks/{chunk-ZP6UKOPB.js → chunk-LWGLBVWA.js} +1 -1
  90. package/chunks/{chunk-L7OKCI7T.js → chunk-M7BLWURA.js} +15 -1
  91. package/chunks/{chunk-PR32FRT6.js → chunk-MIM62IXS.js} +3 -3
  92. package/chunks/{chunk-RD6YJJJ6.js → chunk-MOUXUCXQ.js} +1 -1
  93. package/chunks/{chunk-VBZ452JT.js → chunk-MSNGFH6L.js} +494 -114
  94. package/chunks/{chunk-BX5YO7UW.js → chunk-MTNTVOJR.js} +542 -370
  95. package/chunks/chunk-MX2YXRER.js +44 -0
  96. package/chunks/chunk-NIOPRZNN.js +27 -0
  97. package/chunks/{chunk-SMYQZVZ3.js → chunk-NOGSPTLJ.js} +1 -1
  98. package/chunks/{chunk-DDMOU62Q.js → chunk-NPQWQYU6.js} +1 -1
  99. package/chunks/{chunk-MNF6S5PR.js → chunk-P5THQV6A.js} +4 -4
  100. package/chunks/{chunk-6V4NZFUS.js → chunk-PCYOT4PK.js} +5 -5
  101. package/chunks/{chunk-CF6BB3LT.js → chunk-PPFWEV7G.js} +10 -1
  102. package/chunks/{chunk-FXKVLFFY.js → chunk-PSFDB5FZ.js} +3 -3
  103. package/chunks/{chunk-XJYUPHRC.js → chunk-QOMAHFYI.js} +3 -3
  104. package/chunks/{chunk-J37FGIOA.js → chunk-QXPI7FEC.js} +38 -4
  105. package/chunks/{chunk-RRFZXMYP.js → chunk-QZDBHNMV.js} +691 -164
  106. package/chunks/{chunk-S7AKE7HL.js → chunk-R6RI2HIC.js} +63 -9
  107. package/chunks/{chunk-HZT4UCFB.js → chunk-RB7S52NJ.js} +4 -4
  108. package/chunks/{chunk-J33ZR6OJ.js → chunk-RK22ACPP.js} +16 -16
  109. package/chunks/chunk-RM3PGSGL.js +66 -0
  110. package/chunks/chunk-RNBYOUGV.js +42 -0
  111. package/chunks/chunk-S6RLAIUR.js +23 -0
  112. package/chunks/{chunk-3TV3HUWZ.js → chunk-SCYK2YLI.js} +81 -30
  113. package/chunks/{chunk-HPZTOP4I.js → chunk-SEKRT4SD.js} +133 -23
  114. package/chunks/chunk-SEZC2725.js +36 -0
  115. package/chunks/chunk-SIUQ3YYX.js +78 -0
  116. package/chunks/{chunk-O2VBQ3Y2.js → chunk-SJBIFVD2.js} +2 -2
  117. package/chunks/chunk-SYCJMSIJ.js +82 -0
  118. package/chunks/{chunk-JE5FVRPC.js → chunk-T22H4V4R.js} +48 -23
  119. package/chunks/{chunk-3227DZO4.js → chunk-T42ACHFI.js} +1 -1
  120. package/chunks/{chunk-UO5GVXQE.js → chunk-TENOUWY2.js} +3 -3
  121. package/chunks/{chunk-JOLIREYR.js → chunk-TOAUDIS7.js} +1 -1
  122. package/chunks/{chunk-QNKBEJO2.js → chunk-UA6XBZT7.js} +2776 -1289
  123. package/chunks/{chunk-O75BHFQW.js → chunk-UQTYK5SS.js} +2 -2
  124. package/chunks/{chunk-Y6YMRS3U.js → chunk-UY2TCIZS.js} +17 -3
  125. package/chunks/{chunk-FNJ7BDPH.js → chunk-UY7ZAYTY.js} +10 -7
  126. package/chunks/{chunk-UYT3MWEB.js → chunk-UYHWM24C.js} +30 -2
  127. package/chunks/{chunk-SMXULRAN.js → chunk-VXGPYF7U.js} +1 -1
  128. package/chunks/{chunk-BTLJ2MF5.js → chunk-W7CG5HPC.js} +3 -3
  129. package/chunks/{chunk-JJXWTVSK.js → chunk-XHZKDN7M.js} +34 -1
  130. package/chunks/{chunk-K5XU6E4T.js → chunk-XKSCTXPK.js} +2 -2
  131. package/chunks/chunk-Y4LITCRB.js +367 -0
  132. package/chunks/chunk-YHTNWGRR.js +239 -0
  133. package/chunks/{chunk-BKXBARJZ.js → chunk-YPCPZSZB.js} +1 -1
  134. package/chunks/{chunk-QWFNTRH4.js → chunk-YSM24SCE.js} +1 -1
  135. package/chunks/chunk-YTFBURQD.js +313 -0
  136. package/chunks/{chunk-NL4C3H6C.js → chunk-YXK4GPYO.js} +1 -1
  137. package/chunks/{chunk-RYLJU2DY.js → chunk-ZN5T4BHI.js} +1 -1
  138. package/chunks/{computer-use-JGB36FDW.js → computer-use-MTSVPLPY.js} +34 -28
  139. package/chunks/contextCommand-VGJ3BPTK.js +67 -0
  140. package/chunks/{cron-create-SKEY55RG.js → cron-create-6YTCOX6P.js} +4 -4
  141. package/chunks/{cron-delete-I3NAT32Z.js → cron-delete-E3NIFSUK.js} +4 -4
  142. package/chunks/{cron-list-6XRRL6TH.js → cron-list-Q64MNQNE.js} +4 -4
  143. package/chunks/daemon-EEB2RYOL.js +8453 -0
  144. package/chunks/daemon-status-provider-H5SNMK42.js +71 -0
  145. package/chunks/{de-EOW5PVHF.js → de-PLLFDERI.js} +10 -9
  146. package/chunks/{dist-NHEYYB2B.js → dist-ADMIQGHI.js} +2 -2
  147. package/chunks/{dist-J37VXPLD.js → dist-BCQ7INM7.js} +40 -15
  148. package/chunks/{dist-663NZ6MI.js → dist-KNZFCY5F.js} +116 -11
  149. package/chunks/{dist-LB6OGPVM.js → dist-LHUWC3K6.js} +26 -5
  150. package/chunks/{dist-PQPZ5Q4N.js → dist-WBBZ76JZ.js} +20 -9
  151. package/chunks/{earlyInputCapture-44RISVVJ.js → earlyInputCapture-U4ZIQSQU.js} +32 -26
  152. package/chunks/{edit-NN6GM5DT.js → edit-SYIQ2KBI.js} +41 -38
  153. package/chunks/{en-HPWEJBTR.js → en-M4EBUBNU.js} +32 -10
  154. package/chunks/{enter-worktree-PB3O2C7D.js → enter-worktree-HPPOO244.js} +31 -25
  155. package/chunks/{enterPlanMode-YQFNNSUA.js → enterPlanMode-56YYO52U.js} +41 -25
  156. package/chunks/{errors-LS7XU5DZ.js → errors-EO4SXCFP.js} +33 -27
  157. package/chunks/{exit-worktree-E2FTNSBK.js → exit-worktree-UDM7E6XH.js} +31 -25
  158. package/chunks/{exitPlanMode-GLYK2BUB.js → exitPlanMode-M6P3AWLJ.js} +149 -33
  159. package/chunks/{fast-path-WQ6M7LI7.js → fast-path-42P4QYWI.js} +33 -14
  160. package/chunks/{fast-path-settings-OAGU3X5H.js → fast-path-settings-UQLRFDQP.js} +2 -2
  161. package/chunks/{fr-BN5NKSAC.js → fr-MBMNQSQ6.js} +10 -9
  162. package/chunks/{gemini-2YFLVA2M.js → gemini-NRLXS5J7.js} +84 -70
  163. package/chunks/{geminiContentGenerator-XV6SV6CD.js → geminiContentGenerator-DLJPYYPA.js} +41 -5
  164. package/chunks/{glob-2H6CDDMK.js → glob-JPY3F74Y.js} +31 -25
  165. package/chunks/{grep-VXIUXM3C.js → grep-HW23YES5.js} +31 -25
  166. package/chunks/initializer-HWOZTC4A.js +67 -0
  167. package/chunks/{ja-7DEUB2TS.js → ja-HFV5QCHR.js} +10 -9
  168. package/chunks/{keychain-token-storage-YLMDLKXT.js → keychain-token-storage-GPAKRDKQ.js} +2 -2
  169. package/chunks/list-OZGAGRDG.js +71 -0
  170. package/chunks/loadedSettingsAdapter-RUTZVVIA.js +66 -0
  171. package/chunks/{loop-wakeup-CITGGQHA.js → loop-wakeup-G2EHBRGR.js} +5 -5
  172. package/chunks/{ls-R5WP4BGZ.js → ls-IDHUVSAG.js} +4 -4
  173. package/chunks/{lsp-GSICJMMW.js → lsp-FSRYXGFT.js} +2 -2
  174. package/chunks/{monitor-HKLRS2HQ.js → monitor-QVWEIXU3.js} +33 -26
  175. package/chunks/nonInteractiveCli-RV2WYPML.js +109 -0
  176. package/chunks/{notebook-edit-Y6SKSGTT.js → notebook-edit-B26W3FFH.js} +37 -34
  177. package/chunks/{openaiContentGenerator-J7G2FYJT.js → openaiContentGenerator-6TH7AZGQ.js} +15 -13
  178. package/chunks/pidfile-KW2QQJZI.js +73 -0
  179. package/chunks/{pt-TNZRNLQB.js → pt-2THT3YHA.js} +10 -9
  180. package/chunks/{qwenContentGenerator-5XIEM5GV.js → qwenContentGenerator-5IQAC7RN.js} +33 -27
  181. package/chunks/{qwenOAuth2-AG3PFFLZ.js → qwenOAuth2-LWLA6MQG.js} +5 -4
  182. package/chunks/{read-file-J7D552ZJ.js → read-file-CWFAHOI2.js} +11 -10
  183. package/chunks/{read-mcp-resource-DQQW7H7T.js → read-mcp-resource-PIJF24RO.js} +2 -2
  184. package/chunks/ripGrep-FTZGDKY4.js +60 -0
  185. package/chunks/{ru-NIAUBKCN.js → ru-Z67YJHBG.js} +10 -9
  186. package/chunks/{run-qwen-serve-SGEEVMXD.js → run-qwen-serve-FN2SW5ZI.js} +545 -97
  187. package/chunks/{scheduler-7CQI3S4Q.js → scheduler-BMS23O3I.js} +31 -25
  188. package/chunks/{send-message-EE4TWKVU.js → send-message-33PYFMCT.js} +20 -4
  189. package/chunks/serve-PXFYKL65.js +71 -0
  190. package/chunks/{server-4QMUWXPW.js → server-BRKALJ4F.js} +4132 -1175
  191. package/chunks/{session-NRO7UFOY.js → session-AQMISBP4.js} +205 -64
  192. package/chunks/{settings-SGWRDQSC.js → settings-JCPVUZMB.js} +35 -29
  193. package/chunks/{shell-62ANGIHL.js → shell-POHCRVN2.js} +31 -25
  194. package/chunks/{skill-VWAQAWW6.js → skill-QPEVHS6H.js} +13 -12
  195. package/chunks/spawnChannel-V3QT62TE.js +69 -0
  196. package/chunks/{src-KUV5J5Q2.js → src-IZSP7L6Y.js} +127 -32
  197. package/chunks/{startInteractiveUI-6EYJN3JV.js → startInteractiveUI-63KATISO.js} +16762 -16075
  198. package/chunks/{syntheticOutput-T5YHQ6S2.js → syntheticOutput-YOSWIHDJ.js} +3 -3
  199. package/chunks/{task-create-BLY7RHXX.js → task-create-NHS2NGB3.js} +9 -7
  200. package/chunks/{task-list-3QUYNVYR.js → task-list-5UIB564R.js} +7 -6
  201. package/chunks/{task-stop-U4RATK2V.js → task-stop-HGXZ2VZ3.js} +2 -2
  202. package/chunks/{task-update-U54O7KJX.js → task-update-IYYWUILG.js} +40 -7
  203. package/chunks/{team-create-LPOGCPM7.js → team-create-E5O2F3CA.js} +31 -25
  204. package/chunks/{team-delete-LKBYPASD.js → team-delete-FEKJCU4P.js} +7 -6
  205. package/chunks/team-plan-approval-2TU4YROB.js +202 -0
  206. package/chunks/theme-manager-37KOGPJL.js +64 -0
  207. package/chunks/{todoWrite-OYXKTVYN.js → todoWrite-TKMVZ2HT.js} +4 -4
  208. package/chunks/{tool-search-YPUFJ3ZQ.js → tool-search-4ZTGNSFI.js} +38 -11
  209. package/chunks/{trustedFolders-5B24TMEA.js → trustedFolders-RJ5WXJ6L.js} +32 -26
  210. package/chunks/{validateNonInterActiveAuth-BTDTYOVT.js → validateNonInterActiveAuth-ZWMHZAOK.js} +66 -55
  211. package/chunks/{web-fetch-EEB5LZYU.js → web-fetch-J4PIW36Q.js} +5 -4
  212. package/chunks/{workflow-LAWIW5LI.js → workflow-6PG2PC5M.js} +68 -39
  213. package/chunks/workspace-providers-status-4QIZN2W4.js +68 -0
  214. package/chunks/workspace-service-CYMCOEIO.js +78 -0
  215. package/chunks/{write-file-PCV226DJ.js → write-file-R354LGQF.js} +41 -40
  216. package/chunks/{zh-5EUYXASN.js → zh-SLZNSSZB.js} +32 -10
  217. package/chunks/{zh-TW-TR3XYGE5.js → zh-TW-P53C2SL5.js} +32 -10
  218. package/cli.js +6 -6
  219. package/locales/ca.js +15 -13
  220. package/locales/de.js +15 -13
  221. package/locales/en.js +52 -15
  222. package/locales/fr.js +15 -14
  223. package/locales/ja.js +15 -14
  224. package/locales/pt.js +15 -13
  225. package/locales/ru.js +15 -13
  226. package/locales/zh-TW.js +50 -14
  227. package/locales/zh.js +50 -14
  228. package/node_modules/@qwen-code/audio-capture/package.json +1 -1
  229. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
  230. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
  231. package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
  232. package/package.json +15 -6
  233. package/patches/chrome-devtools-mcp+1.4.0.patch +31 -0
  234. package/postinstall.js +50 -0
  235. package/web-shell/assets/{arc-DA7r8Ueo.js → arc-Bd3048nX.js} +1 -1
  236. package/web-shell/assets/{architectureDiagram-3BPJPVTR-ZDUxPtZ2.js → architectureDiagram-3BPJPVTR-DyzbzABx.js} +1 -1
  237. package/web-shell/assets/{blockDiagram-GPEHLZMM-vrtOf1kJ.js → blockDiagram-GPEHLZMM-CTjxm9Sy.js} +1 -1
  238. package/web-shell/assets/{c4Diagram-AAUBKEIU-BHFjzIi4.js → c4Diagram-AAUBKEIU-DSOFWNU6.js} +1 -1
  239. package/web-shell/assets/channel-oVoup_Ci.js +1 -0
  240. package/web-shell/assets/{chunk-2J33WTMH-mdeQVz59.js → chunk-2J33WTMH-D_PFdjo2.js} +1 -1
  241. package/web-shell/assets/{chunk-4BX2VUAB-BkKMlwBX.js → chunk-4BX2VUAB-52eG6wOT.js} +1 -1
  242. package/web-shell/assets/{chunk-55IACEB6-B7bnXNfu.js → chunk-55IACEB6-CGTZfKkC.js} +1 -1
  243. package/web-shell/assets/{chunk-727SXJPM-DGz8Mm6i.js → chunk-727SXJPM-CZ-qfRUm.js} +1 -1
  244. package/web-shell/assets/{chunk-AQP2D5EJ-BQAydUNk.js → chunk-AQP2D5EJ-B2dSDcqM.js} +1 -1
  245. package/web-shell/assets/{chunk-FMBD7UC4-GHr2LN_p.js → chunk-FMBD7UC4-Cfy3tyA0.js} +1 -1
  246. package/web-shell/assets/{chunk-ND2GUHAM-7R91lnUx.js → chunk-ND2GUHAM-CApNUpUq.js} +1 -1
  247. package/web-shell/assets/{chunk-QZHKN3VN-aTJD3lSQ.js → chunk-QZHKN3VN-CVBG8kgg.js} +1 -1
  248. package/web-shell/assets/classDiagram-4FO5ZUOK-B8WsaT2G.js +1 -0
  249. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-B8WsaT2G.js +1 -0
  250. package/web-shell/assets/{cose-bilkent-S5V4N54A-BTf8t1RL.js → cose-bilkent-S5V4N54A-URd77-_-.js} +1 -1
  251. package/web-shell/assets/{dagre-BM42HDAG-_sgp3WuA.js → dagre-BM42HDAG-C07H4G9-.js} +1 -1
  252. package/web-shell/assets/{diagram-2AECGRRQ-CROtRy1w.js → diagram-2AECGRRQ-CYbpXrSn.js} +1 -1
  253. package/web-shell/assets/{diagram-5GNKFQAL-BqGRzwSc.js → diagram-5GNKFQAL-SI8s6fjX.js} +1 -1
  254. package/web-shell/assets/{diagram-KO2AKTUF-CMrcEtA7.js → diagram-KO2AKTUF-mBkC4RTW.js} +1 -1
  255. package/web-shell/assets/{diagram-LMA3HP47-BRydGNW5.js → diagram-LMA3HP47-CyBPDzWJ.js} +1 -1
  256. package/web-shell/assets/{diagram-OG6HWLK6-D0ilgNjV.js → diagram-OG6HWLK6-DwK7kBCu.js} +1 -1
  257. package/web-shell/assets/{erDiagram-TEJ5UH35-2lnQeJUM.js → erDiagram-TEJ5UH35-Ds1StEUd.js} +1 -1
  258. package/web-shell/assets/{flowDiagram-I6XJVG4X-C_ZMdQiC.js → flowDiagram-I6XJVG4X-BDC4-jHO.js} +1 -1
  259. package/web-shell/assets/{ganttDiagram-6RSMTGT7-Dw9V_Ny0.js → ganttDiagram-6RSMTGT7-CV2aHQqf.js} +1 -1
  260. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-HDXI-F1B.js → gitGraphDiagram-PVQCEYII-B8RcuV_L.js} +1 -1
  261. package/web-shell/assets/index-B5WZ0qP1.js +717 -0
  262. package/web-shell/assets/index-CYE1IMd1.css +5 -0
  263. package/web-shell/assets/{infoDiagram-5YYISTIA-CuB8Ebua.js → infoDiagram-5YYISTIA-DUPoTf50.js} +1 -1
  264. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-D_tyhVwh.js → ishikawaDiagram-YF4QCWOH-FDYOx9rf.js} +1 -1
  265. package/web-shell/assets/{journeyDiagram-JHISSGLW-CgCwJQNU.js → journeyDiagram-JHISSGLW-C5_ohMRp.js} +1 -1
  266. package/web-shell/assets/{kanban-definition-UN3LZRKU-PZUtcbPx.js → kanban-definition-UN3LZRKU-Bn4UnOMG.js} +1 -1
  267. package/web-shell/assets/{linear-CZqRdJIU.js → linear-Bl0pKQtY.js} +1 -1
  268. package/web-shell/assets/{mermaid.core-CPW_4UEF.js → mermaid.core-sevQFoji.js} +72 -72
  269. package/web-shell/assets/{mindmap-definition-RKZ34NQL-D_Y75ID7.js → mindmap-definition-RKZ34NQL-DSH4JZF9.js} +1 -1
  270. package/web-shell/assets/{pieDiagram-4H26LBE5-Q4dTyLeF.js → pieDiagram-4H26LBE5-acWvdQTD.js} +1 -1
  271. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-ckw329Ft.js → quadrantDiagram-W4KKPZXB-DlggX4Sm.js} +1 -1
  272. package/web-shell/assets/{requirementDiagram-4Y6WPE33-DbVDm4It.js → requirementDiagram-4Y6WPE33--mMqwmV8.js} +1 -1
  273. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-CHuZ_ecH.js → sankeyDiagram-5OEKKPKP-BtV9tZ77.js} +1 -1
  274. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DU2YSpq-.js → sequenceDiagram-3UESZ5HK-iDQzPFlj.js} +1 -1
  275. package/web-shell/assets/{stateDiagram-AJRCARHV-CA9PEBUo.js → stateDiagram-AJRCARHV-CsCyQLZ3.js} +1 -1
  276. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CPapECG9.js +1 -0
  277. package/web-shell/assets/{timeline-definition-PNZ67QCA-Bhlo4WVc.js → timeline-definition-PNZ67QCA-Dl0rnKvr.js} +1 -1
  278. package/web-shell/assets/{vennDiagram-CIIHVFJN-6xtPLsyl.js → vennDiagram-CIIHVFJN-qF7nTZzA.js} +1 -1
  279. package/web-shell/assets/{wardley-L42UT6IY-3eozmXPf.js → wardley-L42UT6IY-fWoK9i7F.js} +1 -1
  280. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BOn6hKss.js → wardleyDiagram-YWT4CUSO-pHGfkMnc.js} +1 -1
  281. package/web-shell/assets/{xychartDiagram-2RQKCTM6-BsP4-I_y.js → xychartDiagram-2RQKCTM6-3Doc4Trz.js} +1 -1
  282. package/web-shell/index.html +18 -2
  283. package/chunks/MaxSizedBox-QNF3EIGU.js +0 -63
  284. package/chunks/agent-headless-RQ5BTX3G.js +0 -56
  285. package/chunks/bridge-JL2PMCIW.js +0 -66
  286. package/chunks/chunk-5GOVVXEV.js +0 -73
  287. package/chunks/chunk-BC3C4F3Q.js +0 -40
  288. package/chunks/chunk-BW4KCQFD.js +0 -1103
  289. package/chunks/chunk-RKIZXJMB.js +0 -13
  290. package/chunks/contextCommand-WYU6OQ2F.js +0 -61
  291. package/chunks/daemon-status-provider-HH2EC5FI.js +0 -65
  292. package/chunks/headlessSafetyWarnings-TBE35GJ4.js +0 -55
  293. package/chunks/initializer-2Y7SLOKV.js +0 -61
  294. package/chunks/list-ZAFHZ7OS.js +0 -65
  295. package/chunks/loadedSettingsAdapter-6KJXD6M3.js +0 -60
  296. package/chunks/nonInteractiveCli-5W4GIZQM.js +0 -96
  297. package/chunks/ripGrep-IEIFIWP4.js +0 -54
  298. package/chunks/serve-V6GVZR6U.js +0 -65
  299. package/chunks/spawnChannel-3VHW5EPY.js +0 -63
  300. package/chunks/theme-manager-LYLGAERF.js +0 -58
  301. package/chunks/workspace-providers-status-PIAFVYHA.js +0 -62
  302. package/chunks/workspace-service-YAIOD4HG.js +0 -71
  303. package/web-shell/assets/channel-iRo68q4Q.js +0 -1
  304. package/web-shell/assets/classDiagram-4FO5ZUOK-iHF24a8X.js +0 -1
  305. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-iHF24a8X.js +0 -1
  306. package/web-shell/assets/index-CHmzAWys.css +0 -5
  307. package/web-shell/assets/index-w6GTOHh1.js +0 -713
  308. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-t1LRI0oY.js +0 -1
@@ -1,7 +1,11 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
+ import {
4
+ findCliEntryPath
5
+ } from "./chunk-AHNXYU4O.js";
3
6
  import {
4
7
  CAPABILITIES_SCHEMA_VERSION,
8
+ ClientMcpSenderRegistry,
5
9
  SERVE_CAPABILITY_REGISTRY,
6
10
  allowOriginCors,
7
11
  allowOriginMode,
@@ -13,90 +17,58 @@ import {
13
17
  getRateLimiter,
14
18
  getServeProtocolVersions,
15
19
  hostAllowlist,
16
- isLoopbackBind,
17
20
  listenerMaxConnections,
18
21
  parseAllowOriginPatterns,
19
22
  parseDaemonStatusDetail,
20
23
  positiveFiniteOrNull,
21
24
  require_express,
22
25
  resolveWebShellDir
23
- } from "./chunk-N4EJFBN5.js";
26
+ } from "./chunk-JVLP5US5.js";
27
+ import {
28
+ isLoopbackBind
29
+ } from "./chunk-RNBYOUGV.js";
24
30
  import "./chunk-3HX5LZ6R.js";
25
31
  import "./chunk-7RYW5LQV.js";
32
+ import {
33
+ RUNTIME_STARTUP_CANCELLED_MESSAGE
34
+ } from "./chunk-GHOTR7HL.js";
26
35
  import {
27
36
  getCliVersion
28
- } from "./chunk-GT2FGICD.js";
29
- import "./chunk-VBZ452JT.js";
30
- import "./chunk-QBZ22PQX.js";
31
- import "./chunk-ALX6BUYW.js";
32
- import "./chunk-P7M4GA57.js";
37
+ } from "./chunk-DE7YXUR7.js";
38
+ import "./chunk-EWALXUAD.js";
33
39
  import {
34
40
  canonicalizeWorkspace
35
- } from "./chunk-JE5FVRPC.js";
36
- import "./chunk-FXKVLFFY.js";
37
- import "./chunk-UFC57OYT.js";
38
- import "./chunk-L7OKCI7T.js";
41
+ } from "./chunk-SEZC2725.js";
42
+ import {
43
+ QWEN_SERVER_TOKEN_ENV
44
+ } from "./chunk-S6RLAIUR.js";
45
+ import {
46
+ channelSelectionNames
47
+ } from "./chunk-MX2YXRER.js";
39
48
  import {
40
49
  loadServeFastPathSettings,
41
50
  preResolveServeFastPathHomeEnvOverrides
42
- } from "./chunk-QI7GOGJR.js";
51
+ } from "./chunk-KKQWC6WS.js";
43
52
  import {
44
53
  getGlobalQwenDirLite,
45
54
  resolveConfigPathLite
46
- } from "./chunk-CF6BB3LT.js";
55
+ } from "./chunk-PPFWEV7G.js";
47
56
  import {
48
57
  writeStderrLine,
49
58
  writeStdoutLine
50
59
  } from "./chunk-Y6Z2O3WR.js";
51
60
  import "./chunk-QYUE6W3T.js";
52
- import "./chunk-YAINVQ3Q.js";
53
- import "./chunk-K5PGHDBN.js";
61
+ import "./chunk-5P5XGNYH.js";
54
62
  import "./chunk-SKAZWEV5.js";
55
- import "./chunk-XJYUPHRC.js";
56
- import "./chunk-QLDPRILK.js";
57
- import "./chunk-BVSVIN45.js";
58
- import "./chunk-SBBN4BWR.js";
59
- import "./chunk-S7AKE7HL.js";
60
- import "./chunk-2MPVVENX.js";
61
- import "./chunk-ZTQ26VBE.js";
62
- import "./chunk-O2VBQ3Y2.js";
63
- import "./chunk-MLZQVCF3.js";
64
- import "./chunk-LQ7TMOCE.js";
65
- import "./chunk-LD2XBG6Z.js";
66
- import "./chunk-HYCC3XM3.js";
67
- import "./chunk-NL4C3H6C.js";
68
- import "./chunk-JOLIREYR.js";
69
- import "./chunk-DDMOU62Q.js";
70
- import "./chunk-QNKBEJO2.js";
71
- import "./chunk-3PJXIDKI.js";
72
63
  import "./chunk-UWCTAVOD.js";
73
- import "./chunk-OFEVLU4C.js";
74
- import "./chunk-OMX7CUOE.js";
75
- import "./chunk-RD6YJJJ6.js";
76
- import "./chunk-SKQZZVAV.js";
77
- import "./chunk-BUUQ5HPX.js";
78
- import "./chunk-BX5YO7UW.js";
79
- import "./chunk-UO5GVXQE.js";
80
- import "./chunk-KMGMKW5Q.js";
81
- import "./chunk-22IFUCVR.js";
82
- import "./chunk-3227DZO4.js";
83
- import "./chunk-U3KSMM7G.js";
84
- import "./chunk-BKXBARJZ.js";
85
- import "./chunk-EJYJYJZ2.js";
86
- import "./chunk-55ZMG67I.js";
87
- import "./chunk-H6BD2ELD.js";
88
- import "./chunk-5IFG2VC4.js";
89
- import "./chunk-64WXLC72.js";
90
- import "./chunk-UX4SGCGN.js";
64
+ import "./chunk-SYCJMSIJ.js";
91
65
  import {
92
66
  finalizeStartupProfile,
93
67
  profileCheckpoint
94
68
  } from "./chunk-ITOGNELQ.js";
95
69
  import "./chunk-FXGLL2HL.js";
96
- import "./chunk-ZERZSAZL.js";
97
70
  import "./chunk-QN5NZ3UQ.js";
98
71
  import "./chunk-BR4QREVK.js";
99
- import "./chunk-Z2Z3GUXZ.js";
100
72
  import {
101
73
  init_esbuild_shims
102
74
  } from "./chunk-A4BMJM77.js";
@@ -108,7 +80,9 @@ import {
108
80
  // packages/cli/src/serve/run-qwen-serve.ts
109
81
  init_esbuild_shims();
110
82
  var import_express = __toESM(require_express(), 1);
83
+ import { X509Certificate } from "node:crypto";
111
84
  import * as fs from "node:fs";
85
+ import * as https from "node:https";
112
86
  import * as path from "node:path";
113
87
  import { performance } from "node:perf_hooks";
114
88
 
@@ -391,11 +365,14 @@ function initDaemonLogger(opts) {
391
365
  __name(initDaemonLogger, "initDaemonLogger");
392
366
 
393
367
  // packages/cli/src/serve/run-qwen-serve.ts
394
- var QWEN_SERVER_TOKEN_ENV = "QWEN_SERVER_TOKEN";
368
+ var QWEN_SERVE_CLIENT_MCP_OVER_WS_ENV = "QWEN_SERVE_CLIENT_MCP_OVER_WS";
369
+ var QWEN_SERVE_CDP_TUNNEL_OVER_WS_ENV = "QWEN_SERVE_CDP_TUNNEL_OVER_WS";
395
370
  var QWEN_SERVE_PROMPT_DEADLINE_MS_ENV = "QWEN_SERVE_PROMPT_DEADLINE_MS";
396
371
  var QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS_ENV = "QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS";
397
372
  var SHUTDOWN_FORCE_CLOSE_MS = 5e3;
398
373
  var DEFAULT_RUNTIME_STARTUP_TIMEOUT_MS = 12e4;
374
+ var FAST_PATH_RUNTIME_START_AFTER_HEALTH_MS = 50;
375
+ var FAST_PATH_RUNTIME_START_FALLBACK_MS = 1e3;
399
376
  var RUNTIME_STARTUP_TIMEOUT_ENV = "QWEN_SERVE_RUNTIME_STARTUP_TIMEOUT_MS";
400
377
  var MAX_EVENT_RING_SIZE = 1e6;
401
378
  var DEFAULT_MAX_SESSIONS = 20;
@@ -436,6 +413,18 @@ function parseDeadlineEnv(envName, raw) {
436
413
  return parsed;
437
414
  }
438
415
  __name(parseDeadlineEnv, "parseDeadlineEnv");
416
+ function envFlagDisabled(raw) {
417
+ if (raw === void 0) return false;
418
+ const normalized = raw.trim().toLowerCase();
419
+ return normalized === "0" || normalized === "false";
420
+ }
421
+ __name(envFlagDisabled, "envFlagDisabled");
422
+ function hasChromeExtensionOrigin(origins) {
423
+ return origins?.some(
424
+ (origin) => origin.trim().toLowerCase().startsWith("chrome-extension://")
425
+ ) === true;
426
+ }
427
+ __name(hasChromeExtensionOrigin, "hasChromeExtensionOrigin");
439
428
  function createDaemonTelemetryRuntimeConfig(telemetry, cliVersion, daemonSessionId, defaults) {
440
429
  return {
441
430
  getTelemetryEnabled: /* @__PURE__ */ __name(() => telemetry.enabled ?? false, "getTelemetryEnabled"),
@@ -506,6 +495,14 @@ function formatHostForUrl(host) {
506
495
  return host;
507
496
  }
508
497
  __name(formatHostForUrl, "formatHostForUrl");
498
+ function formatChannelWorkerDaemonUrl(host, port) {
499
+ const normalized = host.trim().toLowerCase();
500
+ if (normalized === "" || normalized === "0.0.0.0" || normalized === "::" || normalized === "[::]") {
501
+ return `http://127.0.0.1:${port}`;
502
+ }
503
+ return `http://${formatHostForUrl(host)}:${port}`;
504
+ }
505
+ __name(formatChannelWorkerDaemonUrl, "formatChannelWorkerDaemonUrl");
509
506
  function extractContextFilename(value) {
510
507
  if (typeof value === "string") {
511
508
  const trimmed = value.trim();
@@ -531,6 +528,52 @@ function withSettingsLock(workspace, fn) {
531
528
  return next;
532
529
  }
533
530
  __name(withSettingsLock, "withSettingsLock");
531
+ var channelWorkerRuntimePromise;
532
+ async function loadChannelWorkerRuntime() {
533
+ channelWorkerRuntimePromise ??= Promise.all([
534
+ import("./channel-worker-supervisor-C3IB63V7.js"),
535
+ import("./pidfile-KW2QQJZI.js")
536
+ ]).then(([supervisor, pidfile]) => ({
537
+ createChannelWorkerSupervisor: supervisor.createChannelWorkerSupervisor,
538
+ channelServicePidfile: pidfile
539
+ })).catch((err) => {
540
+ channelWorkerRuntimePromise = void 0;
541
+ throw err;
542
+ });
543
+ return channelWorkerRuntimePromise;
544
+ }
545
+ __name(loadChannelWorkerRuntime, "loadChannelWorkerRuntime");
546
+ function createDisabledChannelWorkerSupervisor() {
547
+ const snapshot = {
548
+ enabled: false,
549
+ state: "disabled",
550
+ channels: []
551
+ };
552
+ return {
553
+ async start() {
554
+ },
555
+ async stop() {
556
+ },
557
+ killAllSync() {
558
+ },
559
+ snapshot: /* @__PURE__ */ __name(() => ({ ...snapshot, channels: [] }), "snapshot")
560
+ };
561
+ }
562
+ __name(createDisabledChannelWorkerSupervisor, "createDisabledChannelWorkerSupervisor");
563
+ function writeServeChannelReservation(channelServicePidfile, channels) {
564
+ channelServicePidfile.reserveServeServiceInfo({
565
+ channels,
566
+ servePid: process.pid
567
+ });
568
+ }
569
+ __name(writeServeChannelReservation, "writeServeChannelReservation");
570
+ function channelServicePidfileConflictError(info) {
571
+ const owner = info.owner === "serve" ? "qwen serve" : "qwen channel start";
572
+ return new Error(
573
+ `Channel service is already running under ${owner} (PID ${info.pid}). Stop it before starting qwen serve --channel.`
574
+ );
575
+ }
576
+ __name(channelServicePidfileConflictError, "channelServicePidfileConflictError");
534
577
  function normalizeInstallModelIds(req, provider, getDefaultModelIds) {
535
578
  const fromRequest = req.modelIds?.map((id) => id.trim()).filter((id) => id.length > 0);
536
579
  const modelIds = fromRequest && fromRequest.length > 0 ? fromRequest : getDefaultModelIds(provider);
@@ -560,7 +603,7 @@ function shouldPreheatBridge(deps) {
560
603
  __name(shouldPreheatBridge, "shouldPreheatBridge");
561
604
  var coreRuntimePromise;
562
605
  function loadCoreRuntime() {
563
- coreRuntimePromise ??= import("./src-KUV5J5Q2.js");
606
+ coreRuntimePromise ??= import("./src-IZSP7L6Y.js");
564
607
  return coreRuntimePromise;
565
608
  }
566
609
  __name(loadCoreRuntime, "loadCoreRuntime");
@@ -590,9 +633,9 @@ __name(resolveDaemonLogBaseDirForRun, "resolveDaemonLogBaseDirForRun");
590
633
  var settingsRuntimePromise;
591
634
  function loadSettingsRuntimeModules() {
592
635
  settingsRuntimePromise ??= Promise.all([
593
- import("./settings-SGWRDQSC.js"),
594
- import("./loadedSettingsAdapter-6KJXD6M3.js"),
595
- import("./trustedFolders-5B24TMEA.js")
636
+ import("./settings-JCPVUZMB.js"),
637
+ import("./loadedSettingsAdapter-RUTZVVIA.js"),
638
+ import("./trustedFolders-RJ5WXJ6L.js")
596
639
  ]).then(([settings, loadedSettingsAdapter, trustedFolders]) => ({
597
640
  settings,
598
641
  loadedSettingsAdapter,
@@ -611,13 +654,13 @@ async function loadServeRuntimeModules() {
611
654
  daemonStatusProviderModule,
612
655
  workspaceProvidersStatusModule
613
656
  ] = await Promise.all([
614
- import("./server-4QMUWXPW.js"),
615
- import("./bridge-JL2PMCIW.js"),
616
- import("./spawnChannel-3VHW5EPY.js"),
617
- import("./workspace-service-YAIOD4HG.js"),
657
+ import("./server-BRKALJ4F.js"),
658
+ import("./bridge-AMOL4W4P.js"),
659
+ import("./spawnChannel-V3QT62TE.js"),
660
+ import("./workspace-service-CYMCOEIO.js"),
618
661
  import("./types-QX5C3CHJ.js"),
619
- import("./daemon-status-provider-HH2EC5FI.js"),
620
- import("./workspace-providers-status-PIAFVYHA.js")
662
+ import("./daemon-status-provider-H5SNMK42.js"),
663
+ import("./workspace-providers-status-4QIZN2W4.js")
621
664
  ]);
622
665
  return {
623
666
  createServeApp: serverModule.createServeApp,
@@ -662,7 +705,11 @@ function currentServeFeaturesForRunQwenServe(opts, sessionShellCommandEnabled) {
662
705
  persistSettingAvailable: true,
663
706
  sessionShellCommandEnabled,
664
707
  rateLimit: opts.rateLimit === true,
665
- reloadAvailable: true
708
+ reloadAvailable: true,
709
+ // Advertise the same WS feature flags as the runtime path (serve-features.ts)
710
+ // so the bootstrap `/capabilities` window doesn't briefly under-report them.
711
+ clientMcpOverWsEnabled: opts.clientMcpOverWs === true,
712
+ cdpTunnelOverWsEnabled: opts.cdpTunnelOverWs === true
666
713
  });
667
714
  }
668
715
  __name(currentServeFeaturesForRunQwenServe, "currentServeFeaturesForRunQwenServe");
@@ -721,8 +768,23 @@ function installSameOriginOriginStrip(app, getPort) {
721
768
  `http://127.0.0.1:${port}`,
722
769
  `http://localhost:${port}`,
723
770
  `http://[::1]:${port}`,
724
- `http://host.docker.internal:${port}`
771
+ `http://host.docker.internal:${port}`,
772
+ `https://127.0.0.1:${port}`,
773
+ `https://localhost:${port}`,
774
+ `https://[::1]:${port}`,
775
+ `https://host.docker.internal:${port}`
725
776
  ]);
777
+ if (port === 80 || port === 443) {
778
+ for (const host of [
779
+ "127.0.0.1",
780
+ "localhost",
781
+ "[::1]",
782
+ "host.docker.internal"
783
+ ]) {
784
+ cachedSelfOrigins.add(`http://${host}`);
785
+ cachedSelfOrigins.add(`https://${host}`);
786
+ }
787
+ }
726
788
  }
727
789
  if (cachedSelfOrigins.has(origin)) {
728
790
  delete req.headers.origin;
@@ -787,6 +849,14 @@ async function waitForRuntimeStartingForShutdown(runtimeStarting, daemonLog, tim
787
849
  });
788
850
  }
789
851
  __name(waitForRuntimeStartingForShutdown, "waitForRuntimeStartingForShutdown");
852
+ var BOOTSTRAP_HEALTH_PATH = "/health";
853
+ var BOOTSTRAP_CAPABILITIES_PATH = "/capabilities";
854
+ var BOOTSTRAP_DAEMON_STATUS_PATH = "/daemon/status";
855
+ var BOOTSTRAP_SERVE_PATHS = /* @__PURE__ */ new Set([
856
+ BOOTSTRAP_HEALTH_PATH,
857
+ BOOTSTRAP_CAPABILITIES_PATH,
858
+ BOOTSTRAP_DAEMON_STATUS_PATH
859
+ ]);
790
860
  function createBootstrapServeApp(input) {
791
861
  const {
792
862
  opts,
@@ -797,7 +867,9 @@ function createBootstrapServeApp(input) {
797
867
  qwenCodeVersion,
798
868
  sessionShellCommandEnabled,
799
869
  permissionPolicy,
800
- getRuntimeError
870
+ getRuntimeError,
871
+ getChannelWorkerSnapshot,
872
+ onHealthServed
801
873
  } = input;
802
874
  const app = (0, import_express.default)();
803
875
  installSameOriginOriginStrip(app, getPort);
@@ -816,18 +888,21 @@ function createBootstrapServeApp(input) {
816
888
  });
817
889
  return;
818
890
  }
891
+ if (onHealthServed) {
892
+ res.once("finish", onHealthServed);
893
+ }
819
894
  res.status(200).json({ status: "ok" });
820
895
  }, "healthHandler");
821
896
  const loopback = isLoopbackBind(opts.hostname);
822
897
  const exposeHealthPreAuth = loopback && !opts.requireAuth;
823
898
  if (exposeHealthPreAuth) {
824
- app.get("/health", healthHandler);
899
+ app.get(BOOTSTRAP_HEALTH_PATH, healthHandler);
825
900
  }
826
901
  app.use(bearerAuth(opts.token));
827
902
  if (!exposeHealthPreAuth) {
828
- app.get("/health", healthHandler);
903
+ app.get(BOOTSTRAP_HEALTH_PATH, healthHandler);
829
904
  }
830
- app.get("/capabilities", (_req, res) => {
905
+ app.get(BOOTSTRAP_CAPABILITIES_PATH, (_req, res) => {
831
906
  res.status(200).json(
832
907
  createBootstrapCapabilities({
833
908
  opts,
@@ -838,7 +913,7 @@ function createBootstrapServeApp(input) {
838
913
  })
839
914
  );
840
915
  });
841
- app.get("/daemon/status", (req, res) => {
916
+ app.get(BOOTSTRAP_DAEMON_STATUS_PATH, (req, res) => {
842
917
  const detail = parseDaemonStatusDetail(req.query["detail"]);
843
918
  if (!detail.ok || !detail.detail) {
844
919
  res.status(400).json({
@@ -848,6 +923,7 @@ function createBootstrapServeApp(input) {
848
923
  return;
849
924
  }
850
925
  const runtimeError = getRuntimeError();
926
+ const channelWorker = getChannelWorkerSnapshot();
851
927
  const runtimeFailed = runtimeError !== void 0;
852
928
  const issue = runtimeError ? {
853
929
  code: "daemon_runtime_failed",
@@ -914,6 +990,7 @@ function createBootstrapServeApp(input) {
914
990
  policy: permissionPolicy ?? "first-responder"
915
991
  },
916
992
  channel: { live: false },
993
+ channelWorker,
917
994
  transport: {
918
995
  restSseActive: 0,
919
996
  acp: {
@@ -960,16 +1037,58 @@ function createBootstrapServeApp(input) {
960
1037
  return app;
961
1038
  }
962
1039
  __name(createBootstrapServeApp, "createBootstrapServeApp");
963
- function createDelegatingServeApp(bootstrapApp, getRuntimeApp) {
1040
+ function createDelegatingServeApp(bootstrapApp, getRuntimeApp, options = {}) {
964
1041
  const app = (0, import_express.default)();
965
1042
  app.use((req, res, next) => {
966
- const target = getRuntimeApp() ?? bootstrapApp;
967
- const handler = target;
968
- handler(req, res, next);
1043
+ const dispatch = /* @__PURE__ */ __name(async () => {
1044
+ let target = getRuntimeApp();
1045
+ if (!target && options.waitForDeferredRuntimeRoutes === true && !isBootstrapServeRoute(req) && !isCorsPreflightRequest(req) && options.startRuntime && options.runtimeReady) {
1046
+ if (options.authenticateDeferredRuntimeRequest && !runSynchronousRequestGate(
1047
+ options.authenticateDeferredRuntimeRequest,
1048
+ req,
1049
+ res,
1050
+ next
1051
+ )) {
1052
+ return;
1053
+ }
1054
+ options.startRuntime();
1055
+ try {
1056
+ await options.runtimeReady;
1057
+ } catch {
1058
+ }
1059
+ target = getRuntimeApp();
1060
+ }
1061
+ const handler = target ?? bootstrapApp;
1062
+ handler(req, res, next);
1063
+ }, "dispatch");
1064
+ void dispatch().catch(next);
969
1065
  });
970
1066
  return app;
971
1067
  }
972
1068
  __name(createDelegatingServeApp, "createDelegatingServeApp");
1069
+ function isBootstrapServeRoute(req) {
1070
+ const path2 = req.path.length > 1 && req.path.endsWith("/") ? req.path.slice(0, -1) : req.path;
1071
+ return BOOTSTRAP_SERVE_PATHS.has(path2);
1072
+ }
1073
+ __name(isBootstrapServeRoute, "isBootstrapServeRoute");
1074
+ function isCorsPreflightRequest(req) {
1075
+ return req.method === "OPTIONS" && Boolean(req.headers.origin) && Boolean(
1076
+ req.headers["access-control-request-method"] || req.headers["access-control-request-headers"]
1077
+ );
1078
+ }
1079
+ __name(isCorsPreflightRequest, "isCorsPreflightRequest");
1080
+ function runSynchronousRequestGate(handler, req, res, next) {
1081
+ let passed = false;
1082
+ handler(req, res, (err) => {
1083
+ if (err) {
1084
+ next(err);
1085
+ return;
1086
+ }
1087
+ passed = true;
1088
+ });
1089
+ return passed;
1090
+ }
1091
+ __name(runSynchronousRequestGate, "runSynchronousRequestGate");
973
1092
  async function runQwenServe(optsIn, deps = {}) {
974
1093
  const runStartedAt = performance.now();
975
1094
  const shouldPreheat = !deps.bridge && shouldPreheatBridge(deps);
@@ -998,12 +1117,78 @@ async function runQwenServe(optsIn, deps = {}) {
998
1117
  QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS_ENV,
999
1118
  process.env[QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS_ENV]
1000
1119
  );
1120
+ const clientMcpOverWsEnv = process.env[QWEN_SERVE_CLIENT_MCP_OVER_WS_ENV];
1121
+ const cdpTunnelOverWsEnv = process.env[QWEN_SERVE_CDP_TUNNEL_OVER_WS_ENV];
1122
+ const chromeExtensionOriginAllowed = hasChromeExtensionOrigin(
1123
+ optsIn.allowOrigins
1124
+ );
1001
1125
  const opts = {
1002
1126
  ...optsIn,
1003
1127
  token,
1004
1128
  promptDeadlineMs,
1005
- writerIdleTimeoutMs
1129
+ writerIdleTimeoutMs,
1130
+ clientMcpOverWs: optsIn.clientMcpOverWs ?? (!envFlagDisabled(clientMcpOverWsEnv) && clientMcpOverWsEnv !== void 0),
1131
+ cdpTunnelOverWs: optsIn.cdpTunnelOverWs ?? (!envFlagDisabled(cdpTunnelOverWsEnv) && (cdpTunnelOverWsEnv !== void 0 || chromeExtensionOriginAllowed))
1006
1132
  };
1133
+ const channelRuntime = opts.channelSelection ? await loadChannelWorkerRuntime() : void 0;
1134
+ const channelServicePidfile = deps.channelServicePidfile ?? channelRuntime?.channelServicePidfile;
1135
+ let channelPidfileReserved = false;
1136
+ const removeCurrentServePidfile = /* @__PURE__ */ __name(() => {
1137
+ if (!opts.channelSelection || !channelServicePidfile) return;
1138
+ if (!channelPidfileReserved) return;
1139
+ if (channelServicePidfile.removeServeServiceInfo) {
1140
+ if (channelServicePidfile.removeServeServiceInfo(process.pid)) {
1141
+ channelPidfileReserved = false;
1142
+ }
1143
+ return;
1144
+ }
1145
+ const info = channelServicePidfile.readServiceInfo();
1146
+ if (info?.owner === "serve" && info.pid === process.pid && info.servePid === process.pid) {
1147
+ channelServicePidfile.removeServiceInfo();
1148
+ channelPidfileReserved = false;
1149
+ }
1150
+ }, "removeCurrentServePidfile");
1151
+ const reserveChannelServicePidfile = /* @__PURE__ */ __name(() => {
1152
+ if (!opts.channelSelection) return;
1153
+ if (!channelServicePidfile) {
1154
+ throw new Error("Channel service pidfile runtime is not available.");
1155
+ }
1156
+ const channelPidfileNames = channelSelectionNames(opts.channelSelection);
1157
+ const existingChannelService = channelServicePidfile.readServiceInfo();
1158
+ if (existingChannelService) {
1159
+ throw channelServicePidfileConflictError(existingChannelService);
1160
+ }
1161
+ try {
1162
+ writeServeChannelReservation(channelServicePidfile, channelPidfileNames);
1163
+ channelPidfileReserved = true;
1164
+ } catch (err) {
1165
+ if (err && typeof err === "object" && "code" in err) {
1166
+ const code = err.code;
1167
+ if (code === "EEXIST") {
1168
+ const info = channelServicePidfile.readServiceInfo();
1169
+ if (info) {
1170
+ throw channelServicePidfileConflictError(info);
1171
+ }
1172
+ try {
1173
+ writeServeChannelReservation(
1174
+ channelServicePidfile,
1175
+ channelPidfileNames
1176
+ );
1177
+ channelPidfileReserved = true;
1178
+ return;
1179
+ } catch (retryErr) {
1180
+ if (retryErr && typeof retryErr === "object" && "code" in retryErr && retryErr.code === "EEXIST") {
1181
+ throw new Error(
1182
+ "Channel service is already starting. Retry after the current startup finishes."
1183
+ );
1184
+ }
1185
+ throw retryErr;
1186
+ }
1187
+ }
1188
+ }
1189
+ throw err;
1190
+ }
1191
+ }, "reserveChannelServicePidfile");
1007
1192
  validateRateLimitOptions(opts);
1008
1193
  if (!opts.hostname.startsWith("[") && opts.hostname.split(":").length === 2) {
1009
1194
  const [host, port] = opts.hostname.split(":");
@@ -1011,6 +1196,50 @@ async function runQwenServe(optsIn, deps = {}) {
1011
1196
  `Invalid --hostname "${opts.hostname}": looks like a "host:port" combination. Use --port for the port, e.g. "--hostname ${host} --port ${port}".`
1012
1197
  );
1013
1198
  }
1199
+ let tlsOptions;
1200
+ if (opts.tlsCert && !opts.tlsKey || !opts.tlsCert && opts.tlsKey) {
1201
+ throw new Error(
1202
+ `--tls-cert and --tls-key must be provided together (got only --tls-${opts.tlsCert ? "cert" : "key"}).`
1203
+ );
1204
+ }
1205
+ if (opts.tlsCert && opts.tlsKey) {
1206
+ let cert;
1207
+ let key;
1208
+ try {
1209
+ cert = fs.readFileSync(opts.tlsCert);
1210
+ } catch (err) {
1211
+ throw new Error(
1212
+ `Failed to read --tls-cert "${opts.tlsCert}": ${err instanceof Error ? err.message : String(err)}`
1213
+ );
1214
+ }
1215
+ try {
1216
+ key = fs.readFileSync(opts.tlsKey);
1217
+ } catch (err) {
1218
+ throw new Error(
1219
+ `Failed to read --tls-key "${opts.tlsKey}": ${err instanceof Error ? err.message : String(err)}`
1220
+ );
1221
+ }
1222
+ let x509;
1223
+ try {
1224
+ x509 = new X509Certificate(cert);
1225
+ } catch (err) {
1226
+ throw new Error(
1227
+ `--tls-cert "${opts.tlsCert}" is not a valid certificate: ${err instanceof Error ? err.message : String(err)}`
1228
+ );
1229
+ }
1230
+ const now = Date.now();
1231
+ if (new Date(x509.validTo).getTime() < now) {
1232
+ throw new Error(
1233
+ `--tls-cert "${opts.tlsCert}" expired on ${x509.validTo}. Renew the certificate and restart.`
1234
+ );
1235
+ }
1236
+ if (new Date(x509.validFrom).getTime() > now) {
1237
+ throw new Error(
1238
+ `--tls-cert "${opts.tlsCert}" is not yet valid (validFrom: ${x509.validFrom}). Check the certificate's notBefore date or the system clock.`
1239
+ );
1240
+ }
1241
+ tlsOptions = { cert, key };
1242
+ }
1014
1243
  if (!isLoopbackBind(opts.hostname) && !token) {
1015
1244
  throw new Error(
1016
1245
  `Refusing to bind ${opts.hostname}:${opts.port} without a bearer token. Set ${QWEN_SERVER_TOKEN_ENV} or pass --token, or rebind to loopback (127.0.0.1, localhost, ::1, or [::1]).`
@@ -1182,7 +1411,8 @@ async function runQwenServe(optsIn, deps = {}) {
1182
1411
  }
1183
1412
  const childEnvOverrides = {
1184
1413
  QWEN_SERVE_MCP_CLIENT_BUDGET: opts.mcpClientBudget !== void 0 ? String(opts.mcpClientBudget) : void 0,
1185
- QWEN_SERVE_MCP_BUDGET_MODE: opts.mcpBudgetMode
1414
+ QWEN_SERVE_MCP_BUDGET_MODE: opts.mcpBudgetMode,
1415
+ QWEN_SERVE_CDP_TUNNEL_OVER_WS: opts.cdpTunnelOverWs ? "1" : void 0
1186
1416
  };
1187
1417
  const cliVersionPromise = getCliVersion();
1188
1418
  let cliVersion;
@@ -1217,12 +1447,31 @@ async function runQwenServe(optsIn, deps = {}) {
1217
1447
  let markRuntimeReady;
1218
1448
  let markRuntimeFailed;
1219
1449
  let runtimeStartupSettled = false;
1450
+ let startRuntimeAfterHealth;
1451
+ let startRuntimeForRequest;
1452
+ const deferRuntimeUntilFirstHealth = deps.resolveOnListen === true && deps.deferRuntimeUntilFirstHealth === true;
1220
1453
  const runtimeReady = new Promise((resolve, reject) => {
1221
1454
  markRuntimeReady = resolve;
1222
1455
  markRuntimeFailed = reject;
1223
1456
  });
1224
1457
  void runtimeReady.catch(() => {
1225
1458
  });
1459
+ let channelWorker = createDisabledChannelWorkerSupervisor();
1460
+ const getChannelWorkerSnapshot = /* @__PURE__ */ __name(() => channelWorker.snapshot(), "getChannelWorkerSnapshot");
1461
+ const writeChannelWorkerPidfile = /* @__PURE__ */ __name((snapshot = channelWorker.snapshot(), options = {}) => {
1462
+ if (!opts.channelSelection || !channelServicePidfile) return;
1463
+ try {
1464
+ channelServicePidfile.writeServeServiceInfo({
1465
+ channels: snapshot.channels,
1466
+ servePid: process.pid,
1467
+ ...!options.clearWorkerPid && snapshot.pid !== void 0 ? { workerPid: snapshot.pid } : {}
1468
+ });
1469
+ } catch (err) {
1470
+ daemonLog.warn(
1471
+ `failed to write channel worker pidfile metadata: ${err instanceof Error ? err.message : String(err)}`
1472
+ );
1473
+ }
1474
+ }, "writeChannelWorkerPidfile");
1226
1475
  const handleBridge = deps.bridge ?? createLazyBridgeProxy(
1227
1476
  () => bridgeRef,
1228
1477
  () => runtimeStartupError
@@ -1329,6 +1578,7 @@ async function runQwenServe(optsIn, deps = {}) {
1329
1578
  });
1330
1579
  const statusProvider = runtime.createDaemonStatusProvider();
1331
1580
  const workspaceProvidersStatusProvider = runtime.createWorkspaceProvidersStatusProvider();
1581
+ const clientMcpSenderRegistry = new ClientMcpSenderRegistry();
1332
1582
  const persistDisabledToolsFn = /* @__PURE__ */ __name((workspace, toolName, enabled) => withSettingsLock(workspace, async () => {
1333
1583
  const fresh = settingsRuntime.settings.loadSettings(workspace);
1334
1584
  const wsScope = fresh.forScope(WORKSPACE_SETTING_SCOPE).settings;
@@ -1376,6 +1626,9 @@ async function runQwenServe(optsIn, deps = {}) {
1376
1626
  }
1377
1627
  }), "persistSettingsFn");
1378
1628
  const bridge = deps.bridge ?? runtime.createAcpSessionBridge({
1629
+ // Reverse tool channel: let `BridgeClient.extMethod` reach the WS
1630
+ // connection that hosts a named client MCP server (#5626).
1631
+ clientMcpSender: clientMcpSenderRegistry.lookup,
1379
1632
  maxSessions: opts.maxSessions,
1380
1633
  ...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
1381
1634
  ...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
@@ -1438,7 +1691,11 @@ async function runQwenServe(optsIn, deps = {}) {
1438
1691
  startup,
1439
1692
  fsFactory,
1440
1693
  daemonLog,
1694
+ getChannelWorkerSnapshot,
1441
1695
  workspace: workspaceService,
1696
+ // Reverse tool channel (#5626): the SAME registry wired into `bridge` above,
1697
+ // so the WS provider and the child-answering bridge share one sender map.
1698
+ clientMcpSenderRegistry,
1442
1699
  persistDisabledTools: persistDisabledToolsFn,
1443
1700
  persistSetting: persistSettingFn,
1444
1701
  persistSettings: persistSettingsFn,
@@ -1487,8 +1744,10 @@ async function runQwenServe(optsIn, deps = {}) {
1487
1744
  runtimeAppForCleanup = runtime.app;
1488
1745
  runtimeApp = runtime.app;
1489
1746
  bridgeRef = runtime.bridge;
1490
- runtimeStartupSettled = true;
1491
- markRuntimeReady();
1747
+ if (!opts.channelSelection) {
1748
+ runtimeStartupSettled = true;
1749
+ markRuntimeReady();
1750
+ }
1492
1751
  }
1493
1752
  cliVersion ??= await cliVersionPromise;
1494
1753
  const bootstrapApp = createBootstrapServeApp({
@@ -1500,9 +1759,16 @@ async function runQwenServe(optsIn, deps = {}) {
1500
1759
  qwenCodeVersion: cliVersion,
1501
1760
  sessionShellCommandEnabled,
1502
1761
  permissionPolicy,
1503
- getRuntimeError: /* @__PURE__ */ __name(() => runtimeStartupError, "getRuntimeError")
1762
+ getRuntimeError: /* @__PURE__ */ __name(() => runtimeStartupError, "getRuntimeError"),
1763
+ getChannelWorkerSnapshot,
1764
+ onHealthServed: deferRuntimeUntilFirstHealth ? () => startRuntimeAfterHealth?.() : void 0
1765
+ });
1766
+ const app = runtimeApp ?? createDelegatingServeApp(bootstrapApp, () => runtimeApp, {
1767
+ waitForDeferredRuntimeRoutes: deferRuntimeUntilFirstHealth,
1768
+ startRuntime: /* @__PURE__ */ __name(() => startRuntimeForRequest?.(), "startRuntime"),
1769
+ runtimeReady,
1770
+ authenticateDeferredRuntimeRequest: bearerAuth(opts.token)
1504
1771
  });
1505
- const app = runtimeApp ?? createDelegatingServeApp(bootstrapApp, () => runtimeApp);
1506
1772
  let listenHostname = opts.hostname;
1507
1773
  if (opts.hostname.startsWith("[")) {
1508
1774
  const inner = opts.hostname.slice(1, -1);
@@ -1518,8 +1784,9 @@ async function runQwenServe(optsIn, deps = {}) {
1518
1784
  `Invalid maxConnections: ${opts.maxConnections}. Must be >= 0 (0 / Infinity = unlimited).`
1519
1785
  );
1520
1786
  }
1787
+ reserveChannelServicePidfile();
1521
1788
  return await new Promise((resolve, reject) => {
1522
- const server = app.listen(opts.port, listenHostname, () => {
1789
+ const onListening = /* @__PURE__ */ __name(() => {
1523
1790
  startup.listenerReadyAt = (/* @__PURE__ */ new Date()).toISOString();
1524
1791
  startup.processToListenMs = Math.round(process.uptime() * 1e3);
1525
1792
  startup.runQwenServeToListenMs = Math.round(
@@ -1533,7 +1800,55 @@ async function runQwenServe(optsIn, deps = {}) {
1533
1800
  }
1534
1801
  const addr = server.address();
1535
1802
  actualPort = typeof addr === "object" && addr ? addr.port : opts.port;
1536
- const url = `http://${formatHostForUrl(opts.hostname)}:${actualPort}`;
1803
+ const scheme = tlsOptions ? "https" : "http";
1804
+ const url = `${scheme}://${formatHostForUrl(opts.hostname)}:${actualPort}`;
1805
+ try {
1806
+ if (opts.channelSelection) {
1807
+ const createSupervisor = deps.channelWorkerSupervisorFactory ?? channelRuntime?.createChannelWorkerSupervisor;
1808
+ if (!createSupervisor) {
1809
+ throw new Error(
1810
+ "Channel worker supervisor runtime is not available."
1811
+ );
1812
+ }
1813
+ channelWorker = createSupervisor({
1814
+ cliEntryPath: findCliEntryPath(),
1815
+ daemonUrl: formatChannelWorkerDaemonUrl(opts.hostname, actualPort),
1816
+ ...token ? { daemonToken: token } : {},
1817
+ workspace: boundWorkspace,
1818
+ selection: opts.channelSelection,
1819
+ onReady: /* @__PURE__ */ __name((snapshot) => {
1820
+ writeChannelWorkerPidfile(snapshot);
1821
+ }, "onReady"),
1822
+ onLog: /* @__PURE__ */ __name(({ stream, line }) => {
1823
+ const message = `channel worker ${stream}: ${line}`;
1824
+ if (stream === "stderr") {
1825
+ daemonLog.warn(message);
1826
+ } else {
1827
+ daemonLog.info(message);
1828
+ }
1829
+ }, "onLog"),
1830
+ onExit: /* @__PURE__ */ __name((snapshot) => {
1831
+ daemonLog.warn(
1832
+ `channel worker exited (state=${snapshot.state}, pid=${snapshot.pid ?? "unknown"}, code=${snapshot.exitCode ?? "null"}, signal=${snapshot.signal ?? "null"}, error=${snapshot.error ?? "none"}, restartCount=${snapshot.restartCount ?? 0}, nextRestartAt=${snapshot.nextRestartAt ?? "none"}, staleHeartbeatAt=${snapshot.staleHeartbeatAt ?? "none"})`
1833
+ );
1834
+ writeChannelWorkerPidfile(snapshot, { clearWorkerPid: true });
1835
+ }, "onExit")
1836
+ });
1837
+ }
1838
+ } catch (err) {
1839
+ removeCurrentServePidfile();
1840
+ const error = err instanceof Error ? err : new Error(String(err));
1841
+ server.close((closeErr) => {
1842
+ if (closeErr) {
1843
+ daemonLog.error(
1844
+ "server close after channel worker setup error failed",
1845
+ closeErr
1846
+ );
1847
+ }
1848
+ reject(error);
1849
+ });
1850
+ return;
1851
+ }
1537
1852
  writeStdoutLine(
1538
1853
  `qwen serve listening on ${url} (mode=${opts.mode}, workspace=${boundWorkspace})`
1539
1854
  );
@@ -1547,6 +1862,11 @@ async function runQwenServe(optsIn, deps = {}) {
1547
1862
  writeStderrLine(
1548
1863
  `qwen serve: bearer auth disabled (loopback default). Set ${QWEN_SERVER_TOKEN_ENV} to enable.`
1549
1864
  );
1865
+ if (opts.clientMcpOverWs === true) {
1866
+ writeStderrLine(
1867
+ `qwen serve: client-hosted MCP tools are accepted over the WebSocket without auth. Set ${QWEN_SERVE_CLIENT_MCP_OVER_WS_ENV}=0 to disable.`
1868
+ );
1869
+ }
1550
1870
  } else if (opts.requireAuth) {
1551
1871
  writeStderrLine(
1552
1872
  "qwen serve: --require-auth enabled (bearer token mandatory on every route, including loopback /health)."
@@ -1555,6 +1875,8 @@ async function runQwenServe(optsIn, deps = {}) {
1555
1875
  let shuttingDown = false;
1556
1876
  let closePromise;
1557
1877
  let runtimeStartupTimer;
1878
+ let runtimeStartAfterHealthTimer;
1879
+ let runtimeStartFallbackTimer;
1558
1880
  const runtimeStartupTimeoutMs = resolveRuntimeStartupTimeoutMs(
1559
1881
  deps.runtimeStartupTimeoutMs
1560
1882
  );
@@ -1563,6 +1885,27 @@ async function runQwenServe(optsIn, deps = {}) {
1563
1885
  clearTimeout(runtimeStartupTimer);
1564
1886
  runtimeStartupTimer = void 0;
1565
1887
  }, "clearRuntimeStartupTimer");
1888
+ const clearRuntimeStartFallbackTimer = /* @__PURE__ */ __name(() => {
1889
+ if (!runtimeStartFallbackTimer) return;
1890
+ clearTimeout(runtimeStartFallbackTimer);
1891
+ runtimeStartFallbackTimer = void 0;
1892
+ }, "clearRuntimeStartFallbackTimer");
1893
+ const clearRuntimeStartAfterHealthTimer = /* @__PURE__ */ __name(() => {
1894
+ if (!runtimeStartAfterHealthTimer) return;
1895
+ clearTimeout(runtimeStartAfterHealthTimer);
1896
+ runtimeStartAfterHealthTimer = void 0;
1897
+ }, "clearRuntimeStartAfterHealthTimer");
1898
+ const cancelDeferredRuntimeStartup = /* @__PURE__ */ __name(() => {
1899
+ if (!deferRuntimeUntilFirstHealth || runtimeStarting || runtimeStartupSettled)
1900
+ return;
1901
+ daemonLog.info(
1902
+ "deferred runtime: cancelled, server closed before startup"
1903
+ );
1904
+ runtimeStartupSettled = true;
1905
+ const error = new Error(RUNTIME_STARTUP_CANCELLED_MESSAGE);
1906
+ runtimeStartupError = error.message;
1907
+ markRuntimeFailed(error);
1908
+ }, "cancelDeferredRuntimeStartup");
1566
1909
  const shutdownBridgeAfterFailedStartup = /* @__PURE__ */ __name(async (bridge) => {
1567
1910
  if (!bridge || deps.bridge) return;
1568
1911
  try {
@@ -1578,6 +1921,14 @@ async function runQwenServe(optsIn, deps = {}) {
1578
1921
  }
1579
1922
  }
1580
1923
  }, "shutdownBridgeAfterFailedStartup");
1924
+ const stopChannelWorkerAfterFailedStartup = /* @__PURE__ */ __name(async () => {
1925
+ await channelWorker.stop().catch((stopErr) => {
1926
+ daemonLog.error(
1927
+ "channel worker stop after runtime startup error failed",
1928
+ stopErr instanceof Error ? stopErr : null
1929
+ );
1930
+ });
1931
+ }, "stopChannelWorkerAfterFailedStartup");
1581
1932
  const failRuntimeStartup = /* @__PURE__ */ __name(async (err, bridgeForCleanup) => {
1582
1933
  const error = err instanceof Error ? err : new Error(String(err));
1583
1934
  if (runtimeStartupSettled) {
@@ -1594,9 +1945,33 @@ async function runQwenServe(optsIn, deps = {}) {
1594
1945
  }
1595
1946
  writeStderrLine(`qwen serve: runtime startup failed: ${message}`);
1596
1947
  daemonLog.error("runtime startup failed", error);
1597
- markRuntimeFailed(error);
1948
+ await stopChannelWorkerAfterFailedStartup();
1949
+ removeCurrentServePidfile();
1598
1950
  await shutdownBridgeAfterFailedStartup(bridgeForCleanup ?? bridgeRef);
1951
+ markRuntimeFailed(error);
1599
1952
  }, "failRuntimeStartup");
1953
+ const armRuntimeStartupTimer = /* @__PURE__ */ __name(() => {
1954
+ if (runtimeStartupTimeoutMs <= 0 || runtimeStartupTimer) return;
1955
+ runtimeStartupTimer = setTimeout(() => {
1956
+ void failRuntimeStartup(
1957
+ new Error(
1958
+ `Daemon runtime startup timed out after ${runtimeStartupTimeoutMs}ms.`
1959
+ )
1960
+ );
1961
+ }, runtimeStartupTimeoutMs);
1962
+ runtimeStartupTimer.unref();
1963
+ }, "armRuntimeStartupTimer");
1964
+ const completeRuntimeStartup = /* @__PURE__ */ __name(async () => {
1965
+ if (runtimeStartupSettled) return;
1966
+ if (opts.channelSelection) {
1967
+ await channelWorker.start();
1968
+ if (runtimeStartupSettled) return;
1969
+ }
1970
+ if (runtimeStartupSettled) return;
1971
+ runtimeStartupSettled = true;
1972
+ clearRuntimeStartupTimer();
1973
+ markRuntimeReady();
1974
+ }, "completeRuntimeStartup");
1600
1975
  const startBridgePreheat = /* @__PURE__ */ __name((bridge) => {
1601
1976
  startup.preheat.status = "running";
1602
1977
  const preheatStartedAt = performance.now();
@@ -1619,6 +1994,9 @@ async function runQwenServe(optsIn, deps = {}) {
1619
1994
  }, "startBridgePreheat");
1620
1995
  const startRuntime = /* @__PURE__ */ __name(() => {
1621
1996
  if (runtimeStarting) return;
1997
+ armRuntimeStartupTimer();
1998
+ clearRuntimeStartAfterHealthTimer();
1999
+ clearRuntimeStartFallbackTimer();
1622
2000
  runtimeStarting = buildRuntime().then(async (runtime) => {
1623
2001
  if (runtimeStartupSettled) {
1624
2002
  await shutdownBridgeAfterFailedStartup(runtime.bridge);
@@ -1639,26 +2017,47 @@ async function runQwenServe(optsIn, deps = {}) {
1639
2017
  if (shouldPreheat) {
1640
2018
  startBridgePreheat(runtime.bridge);
1641
2019
  }
1642
- runtimeStartupSettled = true;
1643
- clearRuntimeStartupTimer();
1644
- markRuntimeReady();
2020
+ await completeRuntimeStartup();
1645
2021
  }).catch((err) => failRuntimeStartup(err));
1646
- if (runtimeStartupTimeoutMs > 0) {
1647
- runtimeStartupTimer = setTimeout(() => {
1648
- void failRuntimeStartup(
1649
- new Error(
1650
- `Daemon runtime startup timed out after ${runtimeStartupTimeoutMs}ms.`
1651
- )
1652
- );
1653
- }, runtimeStartupTimeoutMs);
1654
- runtimeStartupTimer.unref();
1655
- }
1656
2022
  }, "startRuntime");
2023
+ startRuntimeForRequest = startRuntime;
2024
+ const scheduleRuntimeStartFallback = /* @__PURE__ */ __name(() => {
2025
+ if (shuttingDown || runtimeStarting || runtimeStartFallbackTimer)
2026
+ return;
2027
+ daemonLog.info(
2028
+ `deferred runtime: scheduling fallback start in ${FAST_PATH_RUNTIME_START_FALLBACK_MS}ms`
2029
+ );
2030
+ runtimeStartFallbackTimer = setTimeout(() => {
2031
+ runtimeStartFallbackTimer = void 0;
2032
+ if (shuttingDown) return;
2033
+ daemonLog.info("deferred runtime: fallback timer fired, starting");
2034
+ startRuntime();
2035
+ }, FAST_PATH_RUNTIME_START_FALLBACK_MS);
2036
+ runtimeStartFallbackTimer.unref();
2037
+ }, "scheduleRuntimeStartFallback");
2038
+ startRuntimeAfterHealth = /* @__PURE__ */ __name(() => {
2039
+ if (shuttingDown || runtimeStarting || runtimeStartAfterHealthTimer) {
2040
+ return;
2041
+ }
2042
+ clearRuntimeStartFallbackTimer();
2043
+ daemonLog.info(
2044
+ `deferred runtime: health served, scheduling start in ${FAST_PATH_RUNTIME_START_AFTER_HEALTH_MS}ms`
2045
+ );
2046
+ runtimeStartAfterHealthTimer = setTimeout(() => {
2047
+ runtimeStartAfterHealthTimer = void 0;
2048
+ if (shuttingDown) return;
2049
+ daemonLog.info("deferred runtime: health timer fired, starting");
2050
+ startRuntime();
2051
+ }, FAST_PATH_RUNTIME_START_AFTER_HEALTH_MS);
2052
+ runtimeStartAfterHealthTimer.unref();
2053
+ }, "startRuntimeAfterHealth");
1657
2054
  const onSignal = /* @__PURE__ */ __name(async (signal) => {
1658
2055
  if (shuttingDown) {
1659
2056
  daemonLog.warn(`received ${signal} during drain \u2014 forcing exit`);
1660
2057
  try {
2058
+ channelWorker.killAllSync();
1661
2059
  bridgeRef?.killAllSync();
2060
+ removeCurrentServePidfile();
1662
2061
  } catch (err) {
1663
2062
  daemonLog.error(
1664
2063
  "force-kill error",
@@ -1682,6 +2081,11 @@ async function runQwenServe(optsIn, deps = {}) {
1682
2081
  process.exit(1);
1683
2082
  }
1684
2083
  }, "onSignal");
2084
+ const onUncaughtExceptionMonitor = /* @__PURE__ */ __name(() => {
2085
+ if (process.listenerCount("uncaughtException") === 0) {
2086
+ removeCurrentServePidfile();
2087
+ }
2088
+ }, "onUncaughtExceptionMonitor");
1685
2089
  const handle = {
1686
2090
  server,
1687
2091
  url,
@@ -1693,6 +2097,9 @@ async function runQwenServe(optsIn, deps = {}) {
1693
2097
  if (closePromise) return closePromise;
1694
2098
  closePromise = new Promise((res, rej) => {
1695
2099
  shuttingDown = true;
2100
+ clearRuntimeStartAfterHealthTimer();
2101
+ clearRuntimeStartFallbackTimer();
2102
+ cancelDeferredRuntimeStartup();
1696
2103
  let settled = false;
1697
2104
  let bridgeShutdownError;
1698
2105
  const finish = /* @__PURE__ */ __name((err) => {
@@ -1700,6 +2107,10 @@ async function runQwenServe(optsIn, deps = {}) {
1700
2107
  settled = true;
1701
2108
  process.removeListener("SIGINT", onSignal);
1702
2109
  process.removeListener("SIGTERM", onSignal);
2110
+ process.removeListener(
2111
+ "uncaughtExceptionMonitor",
2112
+ onUncaughtExceptionMonitor
2113
+ );
1703
2114
  void (coreRuntimePromise ? coreRuntimePromise.then((core) => core.shutdownTelemetry()) : Promise.resolve()).catch((telemetryErr) => {
1704
2115
  writeStderrLine(
1705
2116
  `qwen serve: telemetry shutdown error: ${telemetryErr instanceof Error ? telemetryErr.message : String(telemetryErr)}`
@@ -1747,6 +2158,13 @@ async function runQwenServe(optsIn, deps = {}) {
1747
2158
  rl.setDraining(true);
1748
2159
  rl.dispose();
1749
2160
  }
2161
+ await channelWorker.stop().catch((err) => {
2162
+ daemonLog.error(
2163
+ "channel worker stop error",
2164
+ err instanceof Error ? err : null
2165
+ );
2166
+ });
2167
+ removeCurrentServePidfile();
1750
2168
  const bridgeForShutdown = bridgeRef;
1751
2169
  if (bridgeForShutdown) {
1752
2170
  await bridgeForShutdown.shutdown().catch((err) => {
@@ -1786,6 +2204,7 @@ async function runQwenServe(optsIn, deps = {}) {
1786
2204
  };
1787
2205
  process.on("SIGINT", onSignal);
1788
2206
  process.on("SIGTERM", onSignal);
2207
+ process.on("uncaughtExceptionMonitor", onUncaughtExceptionMonitor);
1789
2208
  server.removeAllListeners("error");
1790
2209
  server.on("error", (err) => {
1791
2210
  daemonLog.error("server error", err instanceof Error ? err : null);
@@ -1796,6 +2215,14 @@ async function runQwenServe(optsIn, deps = {}) {
1796
2215
  if (shouldPreheat) {
1797
2216
  startBridgePreheat(bridgeRef);
1798
2217
  }
2218
+ if (opts.channelSelection && !runtimeStartupSettled) {
2219
+ armRuntimeStartupTimer();
2220
+ runtimeStarting = completeRuntimeStartup().catch(
2221
+ (err) => failRuntimeStartup(err, bridgeRef)
2222
+ );
2223
+ }
2224
+ } else if (deferRuntimeUntilFirstHealth) {
2225
+ scheduleRuntimeStartFallback();
1799
2226
  } else {
1800
2227
  startRuntime();
1801
2228
  }
@@ -1816,8 +2243,28 @@ async function runQwenServe(optsIn, deps = {}) {
1816
2243
  }
1817
2244
  );
1818
2245
  }
2246
+ }, "onListening");
2247
+ let server;
2248
+ if (tlsOptions) {
2249
+ let httpsServer;
2250
+ try {
2251
+ httpsServer = https.createServer(tlsOptions, app);
2252
+ } catch (err) {
2253
+ reject(
2254
+ new Error(
2255
+ `--tls-cert "${opts.tlsCert}" and --tls-key "${opts.tlsKey}" could not be loaded (do they match?): ${err instanceof Error ? err.message : String(err)}`
2256
+ )
2257
+ );
2258
+ return;
2259
+ }
2260
+ server = httpsServer.listen(opts.port, listenHostname, onListening);
2261
+ } else {
2262
+ server = app.listen(opts.port, listenHostname, onListening);
2263
+ }
2264
+ server.once("error", (err) => {
2265
+ removeCurrentServePidfile();
2266
+ reject(err);
1819
2267
  });
1820
- server.once("error", reject);
1821
2268
  });
1822
2269
  }
1823
2270
  __name(runQwenServe, "runQwenServe");
@@ -1825,6 +2272,7 @@ export {
1825
2272
  InvalidPolicyConfigError,
1826
2273
  createLazyBridgeProxy,
1827
2274
  extractContextFilename,
2275
+ formatChannelWorkerDaemonUrl,
1828
2276
  resolveRuntimeStartupTimeoutMs,
1829
2277
  runQwenServe,
1830
2278
  validatePolicyConfig,