@qwen-code/qwen-code 0.19.10 → 0.19.11-nightly.20260717.f8e6e8931

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 (275) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +7 -6
  2. package/bundled/qc-helper/docs/features/approval-mode.md +2 -2
  3. package/bundled/qc-helper/docs/features/channels/dingtalk.md +30 -0
  4. package/bundled/qc-helper/docs/features/channels/overview.md +53 -17
  5. package/bundled/qc-helper/docs/features/channels/wecom.md +8 -7
  6. package/bundled/qc-helper/docs/features/sandbox.md +2 -0
  7. package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +42 -7
  8. package/bundled/qc-helper/docs/qwen-serve.md +53 -46
  9. package/bundled/review/SKILL.md +163 -403
  10. package/chunks/{MaxSizedBox-67ODZ4SZ.js → MaxSizedBox-JGTP7YJQ.js} +13 -13
  11. package/chunks/{StandaloneSessionPicker-SIPBQT5Z.js → StandaloneSessionPicker-2XQDOYZ5.js} +27 -27
  12. package/chunks/{acpAgent-VPZJXLFX.js → acpAgent-RXRJA7GD.js} +1135 -373
  13. package/chunks/{agent-Z7NWL6XL.js → agent-UQP53UWQ.js} +10 -10
  14. package/chunks/{agent-headless-73HZ6ROQ.js → agent-headless-I52OXDCK.js} +10 -10
  15. package/chunks/{anthropicContentGenerator-56U3YCP2.js → anthropicContentGenerator-HBRXJSP4.js} +76 -14
  16. package/chunks/{artifact-tool-BWZZJ42H.js → artifact-tool-MIZLXBLF.js} +1 -1
  17. package/chunks/{askUserQuestion-WU3S5A5T.js → askUserQuestion-XMJVPNWM.js} +1 -1
  18. package/chunks/{bridge-XFKW6S7Q.js → bridge-3DVRNBSF.js} +14 -16
  19. package/chunks/{ca-C2JTT2N5.js → ca-CODEN7TD.js} +5 -0
  20. package/chunks/channel-worker-group-SOUWTFHC.js +21 -0
  21. package/chunks/{channel-worker-manager-5RWKSGEU.js → channel-worker-manager-LOVSV3WW.js} +34 -10
  22. package/chunks/{channel-worker-supervisor-PCDAZN4D.js → channel-worker-supervisor-XW6MHJBQ.js} +6 -4
  23. package/chunks/{chunk-BBNVFRGD.js → chunk-3DWIFU7L.js} +1 -1
  24. package/chunks/{chunk-ZQTZXVHP.js → chunk-3KSHYS4T.js} +4 -18
  25. package/chunks/{chunk-ZKMGAFYV.js → chunk-3LS57JZI.js} +1 -1
  26. package/chunks/{chunk-B5I2IIWY.js → chunk-46Y6SSQ7.js} +5 -5
  27. package/chunks/{chunk-GDQQRV43.js → chunk-4BJVSIS3.js} +2 -2
  28. package/chunks/{chunk-L37RC7MQ.js → chunk-4HTHLSIH.js} +1 -1
  29. package/chunks/{chunk-DPFBNG72.js → chunk-4UBEB74N.js} +1 -1
  30. package/chunks/{chunk-AAR5SGMD.js → chunk-4YR7FSAM.js} +7 -5
  31. package/chunks/{chunk-OATTJGPJ.js → chunk-5CNYZ7TN.js} +7 -7
  32. package/chunks/{chunk-JSJFKYWT.js → chunk-5VWYKIMW.js} +1 -1
  33. package/chunks/{chunk-6GETGQWP.js → chunk-5WWYHNAH.js} +39 -10
  34. package/chunks/{chunk-65N2J6V2.js → chunk-6ANLV27M.js} +2 -2
  35. package/chunks/{chunk-L62SEJWY.js → chunk-6RV42SFP.js} +4 -4
  36. package/chunks/{chunk-XXJKGHZV.js → chunk-6VMOP2Z7.js} +4 -4
  37. package/chunks/{chunk-URU5UEK6.js → chunk-6WGZDD67.js} +135 -68
  38. package/chunks/{chunk-7NAWTFVY.js → chunk-6WPJRYLZ.js} +2 -2
  39. package/chunks/chunk-6WVLHULT.js +59 -0
  40. package/chunks/{chunk-N6FXRR6P.js → chunk-7ZFXHKKZ.js} +1 -1
  41. package/chunks/{chunk-E67NFMF4.js → chunk-A2HWMJVO.js} +35 -1
  42. package/chunks/{chunk-4FMG7EDJ.js → chunk-AEKHQ3E5.js} +77 -11
  43. package/chunks/{chunk-WIASPMLX.js → chunk-AH3YAJU6.js} +22 -33
  44. package/chunks/{chunk-6GKMJPOC.js → chunk-AHAH5H6D.js} +3 -3
  45. package/chunks/{chunk-3XJFUTNM.js → chunk-AVAU67KP.js} +57 -10
  46. package/chunks/{chunk-LNUXFLLJ.js → chunk-BDHYJ2MM.js} +53 -5
  47. package/chunks/{chunk-P6LART6G.js → chunk-BTSE2DUP.js} +957 -122
  48. package/chunks/{chunk-7MJAZMXK.js → chunk-BZ5D7OVV.js} +28 -77
  49. package/chunks/{chunk-WDWJ4OQJ.js → chunk-CC2UASQ4.js} +3 -3
  50. package/chunks/{chunk-WLXYAKV7.js → chunk-D7KYA6EY.js} +3 -3
  51. package/chunks/{chunk-5LROA5W4.js → chunk-DD45XVOQ.js} +3 -3
  52. package/chunks/{chunk-H3FQOPPS.js → chunk-DOPUYNXO.js} +2 -2
  53. package/chunks/{chunk-SPUYQB4T.js → chunk-DPXB3XRN.js} +1 -1
  54. package/chunks/{chunk-XLIRF7IK.js → chunk-E7ECGLZW.js} +1 -1
  55. package/chunks/{chunk-RDRVMDWV.js → chunk-EMJJBXS7.js} +10 -10
  56. package/chunks/{chunk-TXY2C3D2.js → chunk-F333XEAU.js} +1 -1
  57. package/chunks/chunk-FEOZBUMT.js +77 -0
  58. package/chunks/{chunk-YYPXHMWO.js → chunk-FEYHXPZG.js} +4 -4
  59. package/chunks/{chunk-ZRKBI3DP.js → chunk-FNX3LGAK.js} +1 -1
  60. package/chunks/chunk-FXK3QMRD.js +140 -0
  61. package/chunks/{chunk-422XAKCK.js → chunk-G5ZKRK2E.js} +2 -2
  62. package/chunks/{chunk-DK33QJ3V.js → chunk-GCRFH57X.js} +732 -13
  63. package/chunks/{chunk-EQY6POVO.js → chunk-GLEJW7T2.js} +1 -1
  64. package/chunks/{chunk-FXMC7SL2.js → chunk-I6NOSIVF.js} +1 -1
  65. package/chunks/{chunk-VBRRNQB7.js → chunk-IHJRUIWN.js} +109 -22
  66. package/chunks/{chunk-F7NXQH4Y.js → chunk-IIXEI2VE.js} +1 -1
  67. package/chunks/{chunk-2UUAIFQO.js → chunk-JGUT3LWZ.js} +5 -0
  68. package/chunks/{chunk-5EBKKSBX.js → chunk-JY74T7PW.js} +1 -1
  69. package/chunks/chunk-KSZKSE23.js +226 -0
  70. package/chunks/{chunk-MO7O5722.js → chunk-KW46DBFM.js} +35 -2
  71. package/chunks/{chunk-TISZXPAX.js → chunk-L263ROM6.js} +1 -1
  72. package/chunks/chunk-LXXMOYPL.js +22 -0
  73. package/chunks/{chunk-YX4LLZ3D.js → chunk-NABT4VOY.js} +109 -35
  74. package/chunks/{chunk-W34A5MJH.js → chunk-NROLDLP4.js} +1 -1
  75. package/chunks/{chunk-V7EQTZYR.js → chunk-O3WCEZEN.js} +191 -44
  76. package/chunks/{chunk-K4PZ5F5T.js → chunk-OWT2CAEQ.js} +1 -1
  77. package/chunks/{chunk-4YWLED2A.js → chunk-PNCWEDF6.js} +7 -4
  78. package/chunks/{chunk-WDW64OW3.js → chunk-PSDTLRAV.js} +5 -5
  79. package/chunks/{chunk-7R4DPSRA.js → chunk-R3VWUU2E.js} +1 -1
  80. package/chunks/{chunk-K7CRWKOE.js → chunk-R6AO7HBQ.js} +4617 -4012
  81. package/chunks/{chunk-6OATMEYN.js → chunk-RTV5TUYB.js} +12 -4
  82. package/chunks/{chunk-6W6DI34P.js → chunk-SE6GSFAO.js} +159 -2
  83. package/chunks/{chunk-WTSXKLG5.js → chunk-SUARMD4Q.js} +1 -1
  84. package/chunks/chunk-T4TZQJ7W.js +48 -0
  85. package/chunks/{chunk-LTNI523B.js → chunk-T7CZYIAU.js} +28 -5
  86. package/chunks/{chunk-3MX7D6QN.js → chunk-TIOE2OPE.js} +32 -4
  87. package/chunks/{chunk-TTUO4DNG.js → chunk-UF6ZTWU5.js} +75 -710
  88. package/chunks/{chunk-Q5GLXH5Q.js → chunk-UJG4VV2O.js} +5 -5
  89. package/chunks/{chunk-CJFNEBYB.js → chunk-VFEZWI6F.js} +1 -1
  90. package/chunks/{chunk-UFOKA4PR.js → chunk-VHCSIMTF.js} +114 -4
  91. package/chunks/{chunk-TQBODCFD.js → chunk-VRR65QYW.js} +250 -2
  92. package/chunks/{chunk-CUUXANEQ.js → chunk-W6J7RSCK.js} +6 -1
  93. package/chunks/{chunk-YHN5SUIJ.js → chunk-W7H223ZZ.js} +1 -1
  94. package/chunks/{chunk-WX6SD4IQ.js → chunk-WTNZ6DXB.js} +1 -1
  95. package/chunks/{chunk-GGJII3FM.js → chunk-WZJELXEU.js} +92 -3
  96. package/chunks/{chunk-OFEVHGVU.js → chunk-X5HZX4EP.js} +9 -11
  97. package/chunks/{chunk-KSO42X3Z.js → chunk-X6YQWCIJ.js} +21 -2
  98. package/chunks/{chunk-7L4XBYVW.js → chunk-XK42MWWO.js} +9 -2
  99. package/chunks/{chunk-X362TMXZ.js → chunk-XQDPCQ3A.js} +7 -5
  100. package/chunks/{chunk-YU56QGXX.js → chunk-Y3TNSHKF.js} +1 -1
  101. package/chunks/{chunk-HHEFI4RP.js → chunk-YOJGIRTD.js} +714 -109
  102. package/chunks/{chunk-CEW4HDPK.js → chunk-ZK4AMPKI.js} +2459 -350
  103. package/chunks/{chunk-SXU3KKNI.js → chunk-ZQIYGQCG.js} +251 -54
  104. package/chunks/{computer-use-IYTX45WA.js → computer-use-LTW3VB6L.js} +10 -10
  105. package/chunks/{config-utils-CFT33LTP.js → config-utils-IQQT3GCI.js} +3 -3
  106. package/chunks/{contextCommand-272V77WU.js → contextCommand-GLMC6CTP.js} +12 -12
  107. package/chunks/{create-sub-session-WNX2OQVX.js → create-sub-session-EAB2U5XW.js} +1 -1
  108. package/chunks/{create-sub-session-CBJMQLYP.js → create-sub-session-YMWQAWSN.js} +10 -10
  109. package/chunks/{cron-create-36TIFKRT.js → cron-create-GMVKSXZT.js} +1 -1
  110. package/chunks/{cron-delete-OQD3WULU.js → cron-delete-VDZKUAVK.js} +1 -1
  111. package/chunks/{cron-list-4533T2FH.js → cron-list-UG7C7RAR.js} +1 -1
  112. package/chunks/{daemon-RNGFPMAB.js → daemon-PRB64RP5.js} +303 -71
  113. package/chunks/{daemon-status-provider-L4STG5VO.js → daemon-status-provider-5OMM5JHF.js} +19 -20
  114. package/chunks/{de-2VCDRDGU.js → de-NOXPCSYN.js} +5 -0
  115. package/chunks/{dist-ERCPDVA6.js → dist-4WCQEZIN.js} +4 -51
  116. package/chunks/{dist-MOEC47TR.js → dist-DOPL5LSQ.js} +1 -1
  117. package/chunks/{dist-JZE7F6YR.js → dist-GXJVCOS7.js} +1 -1
  118. package/chunks/{dist-PHEPJLXD.js → dist-PX2ERZ6I.js} +2 -2
  119. package/chunks/{dist-HNN7DR2L.js → dist-V2YVLYOW.js} +58 -30
  120. package/chunks/{dist-3V3ZV6ML.js → dist-VYWUKURL.js} +1 -1
  121. package/chunks/{earlyInputCapture-EN4BRREQ.js → earlyInputCapture-A3WSRN4T.js} +10 -10
  122. package/chunks/{edit-OMAF2QDR.js → edit-7PG4AH27.js} +10 -10
  123. package/chunks/{en-NJCA3TAA.js → en-JFVULHTB.js} +6 -0
  124. package/chunks/{enter-worktree-BBZX52HG.js → enter-worktree-QUSB44RE.js} +10 -10
  125. package/chunks/{enterPlanMode-5NNFMBUY.js → enterPlanMode-NVSIEL7X.js} +10 -10
  126. package/chunks/{environment-7TEWMJYN.js → environment-AHHXHQTI.js} +12 -12
  127. package/chunks/{errors-I4VKVX3F.js → errors-NSWSRXC7.js} +12 -12
  128. package/chunks/{exit-worktree-FUWRJI33.js → exit-worktree-FXYEYHPL.js} +10 -10
  129. package/chunks/{exitPlanMode-IHCJ5EEI.js → exitPlanMode-JI5GK3F6.js} +10 -10
  130. package/chunks/{fast-path-ZA57TOH4.js → fast-path-X7EVDLKZ.js} +2 -2
  131. package/chunks/{fr-5F3E7WKD.js → fr-HVFNU42H.js} +5 -0
  132. package/chunks/{gemini-UOAKVXBG.js → gemini-YRLHY5KS.js} +162 -206
  133. package/chunks/{geminiContentGenerator-G6UCE6MW.js → geminiContentGenerator-SPLFPV5E.js} +1 -1
  134. package/chunks/{glob-4GJQ2UFF.js → glob-WASUBCSA.js} +10 -10
  135. package/chunks/{grep-5QSYXF2E.js → grep-DUVG3NGA.js} +10 -10
  136. package/chunks/{handleAutoUpdate-ULHNWL6R.js → handleAutoUpdate-NGE5AQ2N.js} +14 -14
  137. package/chunks/{i18n-CYDUTF6F.js → i18n-QNVR36NB.js} +11 -11
  138. package/chunks/{initializer-NRFKUGIO.js → initializer-ZY7ORPMH.js} +15 -15
  139. package/chunks/{installationInfo-WELKRHHE.js → installationInfo-4R75MFTB.js} +11 -11
  140. package/chunks/{ja-66J6B53L.js → ja-PY5AF544.js} +5 -0
  141. package/chunks/{list-JVDXEG2E.js → list-36JCMZRS.js} +18 -18
  142. package/chunks/{loadedSettingsAdapter-WAM4VUTG.js → loadedSettingsAdapter-PQIOJUSJ.js} +15 -15
  143. package/chunks/{loop-wakeup-MVUKDVCP.js → loop-wakeup-QXWZSCYM.js} +2 -2
  144. package/chunks/{ls-RXNIAQDE.js → ls-2OUTG3IZ.js} +1 -1
  145. package/chunks/{lsp-HB5LM5IL.js → lsp-4VMNXZW6.js} +1 -1
  146. package/chunks/{mcp-YHOZN3ZM.js → mcp-QXY6XA6H.js} +15 -15
  147. package/chunks/{monitor-R7XZPJHQ.js → monitor-AVEKRSY3.js} +12 -11
  148. package/chunks/{nonInteractiveCli-NSOB6D74.js → nonInteractiveCli-YWIBKX4M.js} +50 -50
  149. package/chunks/{notebook-edit-6RNKE2L2.js → notebook-edit-4SBTJX72.js} +10 -10
  150. package/chunks/{openaiContentGenerator-XNS5S64I.js → openaiContentGenerator-4EBAO7LR.js} +8 -8
  151. package/chunks/{pidfile-XE4RRR2P.js → pidfile-JMIUPXSU.js} +10 -10
  152. package/chunks/processUtils-EOINMEIH.js +29 -0
  153. package/chunks/{pt-TFZO5Y6T.js → pt-A3PRQXMU.js} +5 -0
  154. package/chunks/{qwenContentGenerator-APDPJ3VN.js → qwenContentGenerator-M7UBL3JS.js} +12 -12
  155. package/chunks/{read-file-XSUWXSR7.js → read-file-DXSEFHCV.js} +5 -5
  156. package/chunks/{read-mcp-resource-6LRTZKXI.js → read-mcp-resource-JUFHCKSC.js} +1 -1
  157. package/chunks/{record-artifact-PMDTY4OS.js → record-artifact-DWSMBXYY.js} +1 -1
  158. package/chunks/{ripGrep-APB3CDMU.js → ripGrep-VTRVFMDJ.js} +10 -10
  159. package/chunks/{ru-4L4LFHIT.js → ru-IBCWUTOC.js} +5 -0
  160. package/chunks/{run-qwen-serve-NWTGPERT.js → run-qwen-serve-P7WQDZAS.js} +59 -38
  161. package/chunks/{runtime-EIO3NQKR.js → runtime-UHYO6JGN.js} +19 -19
  162. package/chunks/{scheduler-JJDZBDRN.js → scheduler-WTK7ZLV5.js} +10 -10
  163. package/chunks/{send-message-SR4WSXP2.js → send-message-JZ752NWD.js} +2 -2
  164. package/chunks/{serve-WTIPB3EI.js → serve-AG2AOG56.js} +15 -15
  165. package/chunks/{server-NJPHQHLH.js → server-G5MM2BRI.js} +1157 -225
  166. package/chunks/{session-O4AO7FTS.js → session-NUAGEMVS.js} +51 -51
  167. package/chunks/{settings-HQNDK7TG.js → settings-VQA5PR2M.js} +14 -14
  168. package/chunks/{shell-UIXM6PWG.js → shell-X33RWGLP.js} +12 -10
  169. package/chunks/{skill-3XMB4ULV.js → skill-PHSU2OPP.js} +5 -5
  170. package/chunks/{spawnChannel-3R632QRM.js → spawnChannel-D6TZN4W7.js} +12 -13
  171. package/chunks/{src-USZKPUOC.js → src-6OJFUPTL.js} +95 -34
  172. package/chunks/{standalone-update-L5XW3D7K.js → standalone-update-ZARRW44Y.js} +12 -12
  173. package/chunks/{startInteractiveUI-CPZOL2WB.js → startInteractiveUI-C6IZRTF3.js} +176 -158
  174. package/chunks/{syntheticOutput-YKFNUQZD.js → syntheticOutput-LELY6HAI.js} +2 -2
  175. package/chunks/{task-create-NUFOHU53.js → task-create-QY3BIMNM.js} +3 -3
  176. package/chunks/{task-list-Z2IKQY3S.js → task-list-D2U47WBJ.js} +1 -1
  177. package/chunks/{task-stop-KQFIVQTJ.js → task-stop-N6E5IYLH.js} +1 -1
  178. package/chunks/{task-update-HKADXSTD.js → task-update-HJCQILLB.js} +3 -3
  179. package/chunks/{team-create-XXPRF3IQ.js → team-create-H434NQP2.js} +10 -10
  180. package/chunks/{team-delete-SDNTGZLG.js → team-delete-RCWYDRF4.js} +1 -1
  181. package/chunks/{team-plan-approval-EOTTKHDW.js → team-plan-approval-IIOHXZU6.js} +10 -10
  182. package/chunks/{theme-manager-P6UITO2L.js → theme-manager-IEOPHMX6.js} +10 -10
  183. package/chunks/{todoWrite-YNXB27GB.js → todoWrite-FKCGATPJ.js} +1 -1
  184. package/chunks/{tool-search-DDNGK2LR.js → tool-search-WIIEDALL.js} +6 -6
  185. package/chunks/{total-session-admission-PL5N7DNY.js → total-session-admission-WU3DORRW.js} +15 -17
  186. package/chunks/{trustedFolders-C5LMF3UR.js → trustedFolders-JVUTUAJ3.js} +11 -11
  187. package/chunks/update-relaunch-X5EQKCH5.js +87 -0
  188. package/chunks/{updateCheck-QTVVISH7.js → updateCheck-TGO2X735.js} +14 -12
  189. package/chunks/{validateNonInterActiveAuth-RY4RKBQG.js → validateNonInterActiveAuth-2MEUL2ME.js} +46 -46
  190. package/chunks/{version-U45RYOSD.js → version-KBGQKZWV.js} +1 -1
  191. package/chunks/{web-fetch-ZSPR3PRR.js → web-fetch-CFCWTCAP.js} +2 -3
  192. package/chunks/{workflow-TCIAQYOA.js → workflow-PAOSF4CG.js} +11 -11
  193. package/chunks/{workspace-providers-status-I3G2HYLY.js → workspace-providers-status-AYHJYSVO.js} +18 -18
  194. package/chunks/{workspace-registration-store-IH5GLZ6Y.js → workspace-registration-store-GZMR53QL.js} +1 -1
  195. package/chunks/{workspace-registry-QEKBELIX.js → workspace-registry-C2IXZWPF.js} +15 -17
  196. package/chunks/{workspace-service-ORKHGLP3.js → workspace-service-KDDAW33F.js} +20 -21
  197. package/chunks/{workspace-skills-status-D7QCNDYY.js → workspace-skills-status-WWEZBZXY.js} +16 -16
  198. package/chunks/{write-file-JGRQR5VM.js → write-file-ACN3TAIX.js} +10 -10
  199. package/chunks/{zh-FSAH32JB.js → zh-PAUNIMHQ.js} +6 -0
  200. package/chunks/{zh-TW-D2YIE2LO.js → zh-TW-GNEUIUFF.js} +6 -0
  201. package/cli-entry.js +92 -8
  202. package/cli.js +11 -11
  203. package/locales/ca.js +10 -0
  204. package/locales/de.js +10 -0
  205. package/locales/en.js +11 -0
  206. package/locales/fr.js +10 -0
  207. package/locales/ja.js +10 -0
  208. package/locales/pt.js +10 -0
  209. package/locales/ru.js +10 -0
  210. package/locales/zh-TW.js +11 -0
  211. package/locales/zh.js +11 -0
  212. package/package.json +3 -3
  213. package/web-shell/assets/{arc-CUeDlxvE.js → arc-Blc5_CnD.js} +1 -1
  214. package/web-shell/assets/{architectureDiagram-3BPJPVTR-PiUszkQA.js → architectureDiagram-3BPJPVTR-Dyv1BvGP.js} +1 -1
  215. package/web-shell/assets/{blockDiagram-GPEHLZMM-s2wYSO7e.js → blockDiagram-GPEHLZMM-CVAb8DyB.js} +1 -1
  216. package/web-shell/assets/{c4Diagram-AAUBKEIU-DyLxZoz9.js → c4Diagram-AAUBKEIU-ClHPb_6S.js} +1 -1
  217. package/web-shell/assets/channel-DkPTtnGS.js +1 -0
  218. package/web-shell/assets/{chunk-2J33WTMH-Dsdai7Tk.js → chunk-2J33WTMH-Dad9g3ZA.js} +1 -1
  219. package/web-shell/assets/{chunk-4BX2VUAB-DEosOjV7.js → chunk-4BX2VUAB-IJJSSdDs.js} +1 -1
  220. package/web-shell/assets/{chunk-55IACEB6-sNsRLTXf.js → chunk-55IACEB6-DRcc-Hl9.js} +1 -1
  221. package/web-shell/assets/{chunk-727SXJPM-DkRNZzmh.js → chunk-727SXJPM-DOCFB-6a.js} +1 -1
  222. package/web-shell/assets/{chunk-AQP2D5EJ-BrsRNpzd.js → chunk-AQP2D5EJ-CRZnSjHp.js} +1 -1
  223. package/web-shell/assets/{chunk-FMBD7UC4-CI039lpl.js → chunk-FMBD7UC4-BwUI4Yes.js} +1 -1
  224. package/web-shell/assets/{chunk-ND2GUHAM-M-pkeIfu.js → chunk-ND2GUHAM-DLy8doxd.js} +1 -1
  225. package/web-shell/assets/{chunk-QZHKN3VN-C4ckGNbH.js → chunk-QZHKN3VN-Bhz7iysj.js} +1 -1
  226. package/web-shell/assets/classDiagram-4FO5ZUOK-DBdPU8ix.js +1 -0
  227. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-DBdPU8ix.js +1 -0
  228. package/web-shell/assets/{cose-bilkent-S5V4N54A-BciKUAFq.js → cose-bilkent-S5V4N54A-jT1e8KzN.js} +1 -1
  229. package/web-shell/assets/{dagre-BM42HDAG-C1nTSgU6.js → dagre-BM42HDAG-C1veApQk.js} +1 -1
  230. package/web-shell/assets/{diagram-2AECGRRQ-BDPNWr1m.js → diagram-2AECGRRQ-C_NOwKeT.js} +1 -1
  231. package/web-shell/assets/{diagram-5GNKFQAL-CNFhTszL.js → diagram-5GNKFQAL-Bigfuz1r.js} +1 -1
  232. package/web-shell/assets/{diagram-KO2AKTUF-CjPa4p5a.js → diagram-KO2AKTUF-CpXltPpU.js} +1 -1
  233. package/web-shell/assets/{diagram-LMA3HP47-ZzPykSyG.js → diagram-LMA3HP47-DYawbYbH.js} +1 -1
  234. package/web-shell/assets/{diagram-OG6HWLK6-0UVtZ9A4.js → diagram-OG6HWLK6-D2t-ttd1.js} +1 -1
  235. package/web-shell/assets/{erDiagram-TEJ5UH35-CajDZCat.js → erDiagram-TEJ5UH35-Buc53PB5.js} +1 -1
  236. package/web-shell/assets/{flowDiagram-I6XJVG4X-BRuFBIvL.js → flowDiagram-I6XJVG4X-DwdFsCN7.js} +1 -1
  237. package/web-shell/assets/{ganttDiagram-6RSMTGT7-BevGmJqG.js → ganttDiagram-6RSMTGT7-XhiEKGoP.js} +1 -1
  238. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-DvPMpBMb.js → gitGraphDiagram-PVQCEYII-D6We014a.js} +1 -1
  239. package/web-shell/assets/index-BctAmeF3.js +1143 -0
  240. package/web-shell/assets/{index-DzHwQkQq.js → index-CAWqS-bZ.js} +1 -1
  241. package/web-shell/assets/index-DLyhlZZO.css +5 -0
  242. package/web-shell/assets/{infoDiagram-5YYISTIA-Oixn7tA9.js → infoDiagram-5YYISTIA-C_iugRHQ.js} +1 -1
  243. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-BgKpeg-j.js → ishikawaDiagram-YF4QCWOH-CAn9Kaix.js} +1 -1
  244. package/web-shell/assets/{journeyDiagram-JHISSGLW-74mwxIaA.js → journeyDiagram-JHISSGLW-BjDYOkEB.js} +1 -1
  245. package/web-shell/assets/{kanban-definition-UN3LZRKU-D4D6cEqA.js → kanban-definition-UN3LZRKU-Br_oI3Ob.js} +1 -1
  246. package/web-shell/assets/{linear-atZRE_L2.js → linear-BqnWHE9E.js} +1 -1
  247. package/web-shell/assets/{mermaid.core-KKudX-JC.js → mermaid.core-CT-sofSb.js} +5 -5
  248. package/web-shell/assets/{mindmap-definition-RKZ34NQL-CMCej9yG.js → mindmap-definition-RKZ34NQL-BbvrZR4B.js} +1 -1
  249. package/web-shell/assets/{pieDiagram-4H26LBE5-nhx40X7q.js → pieDiagram-4H26LBE5-gAwi3h_Q.js} +1 -1
  250. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-CUmVcN3M.js → quadrantDiagram-W4KKPZXB-CONvBIuO.js} +1 -1
  251. package/web-shell/assets/{requirementDiagram-4Y6WPE33-C_vyEwyy.js → requirementDiagram-4Y6WPE33-lpkrcy1e.js} +1 -1
  252. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-DU6G4VWR.js → sankeyDiagram-5OEKKPKP-Bk6FJHqb.js} +1 -1
  253. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DdeRR_KJ.js → sequenceDiagram-3UESZ5HK-B9b9bBzt.js} +1 -1
  254. package/web-shell/assets/{stateDiagram-AJRCARHV-C6iCI8ps.js → stateDiagram-AJRCARHV-JqBGC-S3.js} +1 -1
  255. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-B_w4fDnm.js +1 -0
  256. package/web-shell/assets/{timeline-definition-PNZ67QCA-B_Ea8Cb7.js → timeline-definition-PNZ67QCA-CCCceXDP.js} +1 -1
  257. package/web-shell/assets/{vennDiagram-CIIHVFJN-BPUVZEJA.js → vennDiagram-CIIHVFJN-EHRnmZ09.js} +1 -1
  258. package/web-shell/assets/{wardley-L42UT6IY-BWEj0lKY.js → wardley-L42UT6IY-CYIcHx3_.js} +1 -1
  259. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BvDsdIQw.js → wardleyDiagram-YWT4CUSO-B81AuYRl.js} +1 -1
  260. package/web-shell/assets/{xychartDiagram-2RQKCTM6-crz0QhF_.js → xychartDiagram-2RQKCTM6-DOQ6E3z7.js} +1 -1
  261. package/web-shell/index.html +2 -2
  262. package/chunks/channel-worker-group-K7QKH6IG.js +0 -13
  263. package/chunks/chunk-B7NUUEXC.js +0 -311
  264. package/chunks/chunk-CARU2RR2.js +0 -24
  265. package/chunks/chunk-GYTKQYDB.js +0 -23
  266. package/chunks/chunk-LQU7EVFA.js +0 -30
  267. package/chunks/chunk-OCPBI7J5.js +0 -18
  268. package/chunks/chunk-OJAMDVF5.js +0 -66
  269. package/chunks/chunk-TEGEBB2I.js +0 -122
  270. package/web-shell/assets/channel-DkuJJ0qd.js +0 -1
  271. package/web-shell/assets/classDiagram-4FO5ZUOK-CwqHc0TB.js +0 -1
  272. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CwqHc0TB.js +0 -1
  273. package/web-shell/assets/index-Cnvv4VcI.css +0 -5
  274. package/web-shell/assets/index-D1Uyklxa.js +0 -1088
  275. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-C0_6nR6C.js +0 -1
@@ -1,22 +1,25 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
3
  import {
4
- openQwenAsrRealtimeStream,
5
- openVoiceStream,
6
- openVoiceStreamWithRetry
7
- } from "./chunk-JSJFKYWT.js";
8
- import {
4
+ GENERATION_MAX_PROMPT_BYTES,
9
5
  MAX_REMEMBER_CONTENT_BYTES,
10
6
  createWorkspaceMemoryExtractionErrorLogger,
11
7
  extractRememberErrorCode,
12
8
  formatWorkspaceMemoryDreamSummary,
13
9
  formatWorkspaceMemoryForgetSummary,
14
10
  isValidServerName,
11
+ redactMcpServersSetting,
15
12
  replayTranscriptRecordPage,
13
+ restoreRedactedMcpServersSetting,
16
14
  shouldSuppressRememberErrorDetails,
17
15
  workspaceMemoryFailureCode,
18
16
  workspaceMemoryFailureDiagnostics
19
- } from "./chunk-6W6DI34P.js";
17
+ } from "./chunk-SE6GSFAO.js";
18
+ import {
19
+ openQwenAsrRealtimeStream,
20
+ openVoiceStream,
21
+ openVoiceStreamWithRetry
22
+ } from "./chunk-5VWYKIMW.js";
20
23
  import {
21
24
  SetupGithubError,
22
25
  collectSessionData,
@@ -27,9 +30,9 @@ import {
27
30
  toJson,
28
31
  toJsonl,
29
32
  toMarkdown
30
- } from "./chunk-4FMG7EDJ.js";
31
- import "./chunk-SPUYQB4T.js";
32
- import "./chunk-WTSXKLG5.js";
33
+ } from "./chunk-AEKHQ3E5.js";
34
+ import "./chunk-DPXB3XRN.js";
35
+ import "./chunk-SUARMD4Q.js";
33
36
  import "./chunk-QHTIBUWB.js";
34
37
  import "./chunk-L573Z2QZ.js";
35
38
  import {
@@ -62,9 +65,11 @@ import {
62
65
  denyBrowserOriginCors,
63
66
  detectFromLoopback,
64
67
  getAdvertisedServeFeatures,
68
+ getDeferredRuntimeRequestTiming,
65
69
  getServeProtocolVersions,
66
70
  hostAllowlist,
67
71
  isBrowserAutomationMcpAvailable,
72
+ isDeepHealthQuery,
68
73
  parseAllowOriginPatterns,
69
74
  parseAndValidateWorkspaceClientId,
70
75
  parseClientIdHeader,
@@ -85,28 +90,29 @@ import {
85
90
  setRateLimiter,
86
91
  unsafeRevealSecret,
87
92
  validateMcpRuntimeServerName
88
- } from "./chunk-MO7O5722.js";
93
+ } from "./chunk-KW46DBFM.js";
89
94
  import {
90
95
  isLoopbackBind
91
96
  } from "./chunk-RXFQM6FQ.js";
92
97
  import {
93
98
  createDaemonStatusProvider
94
- } from "./chunk-ZQTZXVHP.js";
95
- import "./chunk-WDWJ4OQJ.js";
99
+ } from "./chunk-3KSHYS4T.js";
100
+ import "./chunk-LXXMOYPL.js";
101
+ import "./chunk-CC2UASQ4.js";
96
102
  import "./chunk-E5Z2AVNV.js";
97
103
  import {
98
104
  createWorkspaceProvidersStatusProvider
99
- } from "./chunk-7MJAZMXK.js";
105
+ } from "./chunk-BZ5D7OVV.js";
100
106
  import {
101
107
  getAuthTypeFromEnv,
102
108
  resolveCliGenerationConfig
103
- } from "./chunk-GGJII3FM.js";
109
+ } from "./chunk-WZJELXEU.js";
104
110
  import {
105
111
  snapshotProcessEnv
106
- } from "./chunk-ZKMGAFYV.js";
112
+ } from "./chunk-3LS57JZI.js";
107
113
  import {
108
114
  createWorkspaceSkillsStatusProvider
109
- } from "./chunk-WLXYAKV7.js";
115
+ } from "./chunk-D7KYA6EY.js";
110
116
  import "./chunk-2W3OOD4W.js";
111
117
  import {
112
118
  EMPTY_WORKSPACE_VOICE_UPDATE_ERROR,
@@ -118,14 +124,14 @@ import {
118
124
  transcribeWorkspaceVoiceAudio,
119
125
  validateWorkspaceVoiceState,
120
126
  voiceSettingsScopeToWire
121
- } from "./chunk-OFEVHGVU.js";
127
+ } from "./chunk-X5HZX4EP.js";
122
128
  import {
123
129
  PermissionRulesValidationError,
124
130
  buildPermissionSettings,
125
131
  isPermissionRuleType,
126
132
  normalizePermissionRules,
127
133
  readPermissionRuleSet
128
- } from "./chunk-N6FXRR6P.js";
134
+ } from "./chunk-7ZFXHKKZ.js";
129
135
  import {
130
136
  assertVoiceBaseUrlNetworkAllowed,
131
137
  isStreamingVoiceModel,
@@ -133,12 +139,12 @@ import {
133
139
  resolveVoiceTranscriptionConfig,
134
140
  sanitizeVoiceErrorMessage,
135
141
  transcribeVoiceAudio
136
- } from "./chunk-FXMC7SL2.js";
142
+ } from "./chunk-I6NOSIVF.js";
137
143
  import {
138
144
  isVoiceEnabled,
139
145
  isVoiceMode,
140
146
  readVoiceModel
141
- } from "./chunk-DPFBNG72.js";
147
+ } from "./chunk-4UBEB74N.js";
142
148
  import "./chunk-FSA7ERJ2.js";
143
149
  import {
144
150
  WorkspacePermissionRulesSessionRequiredError,
@@ -148,24 +154,24 @@ import {
148
154
  } from "./chunk-OA4JVLSA.js";
149
155
  import {
150
156
  createTotalSessionAdmissionController
151
- } from "./chunk-7R4DPSRA.js";
157
+ } from "./chunk-R3VWUU2E.js";
152
158
  import {
153
159
  createSingleWorkspaceRegistry,
154
160
  createWorkspaceSessionOwnerIndex
155
- } from "./chunk-YHN5SUIJ.js";
161
+ } from "./chunk-W7H223ZZ.js";
156
162
  import "./chunk-GRC5HGPI.js";
157
163
  import {
158
164
  SessionArtifactAuthorizationError,
159
165
  SessionArtifactValidationError,
160
- createAcpSessionBridge
161
- } from "./chunk-HHEFI4RP.js";
166
+ createAcpSessionBridge,
167
+ parseSessionSource
168
+ } from "./chunk-YOJGIRTD.js";
162
169
  import "./chunk-PZL23GTM.js";
163
170
  import {
164
171
  EVENT_SCHEMA_VERSION,
165
172
  SubscriberLimitExceededError
166
173
  } from "./chunk-6RLROE6G.js";
167
174
  import "./chunk-COH43MRJ.js";
168
- import "./chunk-OCPBI7J5.js";
169
175
  import {
170
176
  BranchWhilePromptActiveError,
171
177
  CancelSentinelCollisionError,
@@ -186,6 +192,7 @@ import {
186
192
  SessionBusyError,
187
193
  SessionConflictError,
188
194
  SessionLimitExceededError,
195
+ SessionNotArchivedError,
189
196
  SessionNotFoundError,
190
197
  SessionShellClientRequiredError,
191
198
  SessionShellDisabledError,
@@ -196,39 +203,44 @@ import {
196
203
  WorkspaceInitRaceError,
197
204
  WorkspaceInitSymlinkError,
198
205
  WorkspaceMismatchError
199
- } from "./chunk-KSO42X3Z.js";
206
+ } from "./chunk-X6YQWCIJ.js";
200
207
  import "./chunk-WBL3FJEU.js";
201
208
  import {
202
209
  loadChannelsConfig
203
- } from "./chunk-Q5GLXH5Q.js";
204
- import "./chunk-AAR5SGMD.js";
210
+ } from "./chunk-UJG4VV2O.js";
211
+ import "./chunk-4YR7FSAM.js";
205
212
  import "./chunk-57OAHC2Y.js";
206
213
  import {
207
214
  parseChannelWebhookConfigLenient
208
- } from "./chunk-OATTJGPJ.js";
209
- import "./chunk-ZRKBI3DP.js";
215
+ } from "./chunk-5CNYZ7TN.js";
216
+ import "./chunk-FNX3LGAK.js";
210
217
  import "./chunk-V6WHFGST.js";
211
- import "./chunk-UFOKA4PR.js";
212
- import "./chunk-TEGEBB2I.js";
218
+ import "./chunk-VHCSIMTF.js";
213
219
  import {
214
220
  STATUS_SCHEMA_VERSION,
215
221
  createIdleWorkspaceMemoryStatus,
216
222
  mapDomainErrorToErrorKind
217
- } from "./chunk-CUUXANEQ.js";
223
+ } from "./chunk-W6J7RSCK.js";
218
224
  import {
219
225
  MAX_REGISTERED_WORKSPACES,
220
226
  WorkspaceRegistrationStoreCommittedError,
221
227
  WorkspaceRegistrationStoreLimitError,
222
228
  workspaceRegistrationId
223
- } from "./chunk-L37RC7MQ.js";
229
+ } from "./chunk-4HTHLSIH.js";
224
230
  import {
225
231
  MAX_WORKSPACE_PATH_LENGTH,
226
232
  canonicalizeWorkspace,
227
233
  canonicalizeWorkspaces
228
234
  } from "./chunk-W7FJ3N32.js";
229
235
  import {
230
- QWEN_SERVER_TOKEN_ENV
231
- } from "./chunk-GYTKQYDB.js";
236
+ MAX_CHANNEL_STARTUP_FAILURES,
237
+ MAX_CHANNEL_STARTUP_FAILURE_CHANNEL_LENGTH,
238
+ MAX_CHANNEL_STARTUP_FAILURE_CODE_LENGTH,
239
+ MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH,
240
+ QWEN_SERVER_TOKEN_ENV,
241
+ isChannelWebhookEnqueueError,
242
+ normalizeWorkerDiagnostic
243
+ } from "./chunk-KSZKSE23.js";
232
244
  import {
233
245
  normalizeServeChannelSelection
234
246
  } from "./chunk-TJTKSVIV.js";
@@ -236,11 +248,10 @@ import {
236
248
  redactLogCredentials
237
249
  } from "./chunk-M5GB774H.js";
238
250
  import "./chunk-5HBA2Z7V.js";
239
- import {
240
- isChannelWebhookEnqueueError
241
- } from "./chunk-OJAMDVF5.js";
242
251
  import "./chunk-T2NCM2ET.js";
243
- import "./chunk-SXU3KKNI.js";
252
+ import {
253
+ sanitizeLogText
254
+ } from "./chunk-ZQIYGQCG.js";
244
255
  import "./chunk-UDXSXLER.js";
245
256
  import {
246
257
  getDialogSettingKeys,
@@ -251,18 +262,18 @@ import {
251
262
  getWritableScopes,
252
263
  loadSettings,
253
264
  validateSettingValue
254
- } from "./chunk-6GETGQWP.js";
265
+ } from "./chunk-5WWYHNAH.js";
255
266
  import "./chunk-RKUWKYED.js";
256
267
  import {
257
268
  SUPPORTED_LANGUAGES
258
- } from "./chunk-RDRVMDWV.js";
259
- import "./chunk-5EBKKSBX.js";
269
+ } from "./chunk-EMJJBXS7.js";
270
+ import "./chunk-JY74T7PW.js";
260
271
  import "./chunk-GOXKNSDZ.js";
261
272
  import "./chunk-IDS7MSUP.js";
262
273
  import "./chunk-QRUIS3DN.js";
263
274
  import {
264
275
  getWorkspaceTrustStatus
265
- } from "./chunk-4YWLED2A.js";
276
+ } from "./chunk-PNCWEDF6.js";
266
277
  import "./chunk-ALGGS7UH.js";
267
278
  import {
268
279
  isWithinRoot as isWithinRoot2
@@ -270,7 +281,7 @@ import {
270
281
  import {
271
282
  writeStderrLine
272
283
  } from "./chunk-YUZI3WAC.js";
273
- import "./chunk-YU56QGXX.js";
284
+ import "./chunk-Y3TNSHKF.js";
274
285
  import "./chunk-VJNBRRZG.js";
275
286
  import {
276
287
  ALL_PROVIDERS,
@@ -284,6 +295,7 @@ import {
284
295
  InvalidSessionTranscriptCursorError,
285
296
  ModelsConfig,
286
297
  RUNTIME_MCP_IF_ABSENT_CONFIG_FLAG,
298
+ SESSION_TRANSCRIPT_MAX_INDEX_BYTES,
287
299
  SESSION_TRANSCRIPT_MAX_LIMIT,
288
300
  SessionOrganizationError,
289
301
  SessionOrganizationService,
@@ -315,18 +327,18 @@ import {
315
327
  stripTerminalControlSequences,
316
328
  watchRepoBranch,
317
329
  writeWorkspaceContextFile
318
- } from "./chunk-K7CRWKOE.js";
330
+ } from "./chunk-R6AO7HBQ.js";
331
+ import "./chunk-T4TZQJ7W.js";
319
332
  import "./chunk-H6XPXXMH.js";
320
333
  import "./chunk-5M6IDOMF.js";
321
334
  import {
322
335
  MAX_JOBS,
323
336
  nextDurableFireMs
324
- } from "./chunk-E67NFMF4.js";
337
+ } from "./chunk-A2HWMJVO.js";
325
338
  import "./chunk-RCEEXIOO.js";
326
339
  import "./chunk-KKRTYONM.js";
327
340
  import "./chunk-TV6K2FB4.js";
328
341
  import "./chunk-E2UVIFI2.js";
329
- import "./chunk-6OATMEYN.js";
330
342
  import {
331
343
  nextFireTime,
332
344
  parseCron
@@ -347,7 +359,7 @@ import {
347
359
  APPROVAL_MODES,
348
360
  SubagentError,
349
361
  SubagentErrorCode
350
- } from "./chunk-TXY2C3D2.js";
362
+ } from "./chunk-F333XEAU.js";
351
363
  import "./chunk-6AM5D4ME.js";
352
364
  import "./chunk-2Z5UX4KI.js";
353
365
  import "./chunk-ARKANCNX.js";
@@ -366,15 +378,15 @@ import {
366
378
  recordDaemonHttpRequest,
367
379
  recordDaemonHttpResponse,
368
380
  withDaemonRequestSpan
369
- } from "./chunk-P6LART6G.js";
381
+ } from "./chunk-BTSE2DUP.js";
370
382
  import "./chunk-4WKAA4KS.js";
371
383
  import "./chunk-CR3C7WXL.js";
372
- import "./chunk-CARU2RR2.js";
384
+ import "./chunk-RTV5TUYB.js";
373
385
  import "./chunk-VGC4I5JJ.js";
374
386
  import "./chunk-FBU7WRZI.js";
375
387
  import "./chunk-Y66VOBRP.js";
376
- import "./chunk-WX6SD4IQ.js";
377
- import "./chunk-2UUAIFQO.js";
388
+ import "./chunk-WTNZ6DXB.js";
389
+ import "./chunk-JGUT3LWZ.js";
378
390
  import {
379
391
  QwenOAuth2Client,
380
392
  QwenOAuthPollError,
@@ -388,8 +400,8 @@ import "./chunk-ZPAHLFZU.js";
388
400
  import "./chunk-JESCGQM3.js";
389
401
  import "./chunk-WIEO4CWB.js";
390
402
  import "./chunk-XVNQMZ2I.js";
391
- import "./chunk-B7NUUEXC.js";
392
- import "./chunk-TQBODCFD.js";
403
+ import "./chunk-FEOZBUMT.js";
404
+ import "./chunk-VRR65QYW.js";
393
405
  import "./chunk-A4UCTEB5.js";
394
406
  import "./chunk-XWRJCPHC.js";
395
407
  import "./chunk-4LD5APFL.js";
@@ -2900,7 +2912,7 @@ async function handleSetupGithub(req, res, deps) {
2900
2912
  const result = await setupGithub({
2901
2913
  cwd: deps.boundWorkspace,
2902
2914
  workspaceRoot: deps.boundWorkspace,
2903
- proxy: resolveSetupGithubProxy(deps.boundWorkspace),
2915
+ proxy: resolveSetupGithubProxy(deps.boundWorkspace, deps.env),
2904
2916
  abortSignal: requestAbortSignal(req, res),
2905
2917
  fileOps: createSetupGithubFileOps(factory, ROUTE, originatorClientId)
2906
2918
  });
@@ -3118,14 +3130,14 @@ function setupGithubEventData(result) {
3118
3130
  };
3119
3131
  }
3120
3132
  __name(setupGithubEventData, "setupGithubEventData");
3121
- function resolveSetupGithubProxy(boundWorkspace) {
3133
+ function resolveSetupGithubProxy(boundWorkspace, env) {
3122
3134
  const settings = loadSettings(boundWorkspace, { skipLoadEnvironment: true });
3123
3135
  const trustState = getWorkspaceTrustStatus(
3124
3136
  settingsForSetupGithubTrust(settings),
3125
3137
  boundWorkspace
3126
3138
  ).effective.state;
3127
3139
  const settingsProxy = trustState === "trusted" ? settings.merged.proxy : settings.user.settings.proxy || settings.system.settings.proxy || settings.systemDefaults.settings.proxy;
3128
- return settingsProxy || process.env["HTTPS_PROXY"] || process.env["https_proxy"] || process.env["HTTP_PROXY"] || process.env["http_proxy"];
3140
+ return settingsProxy || env["HTTPS_PROXY"] || env["https_proxy"] || env["HTTP_PROXY"] || env["http_proxy"];
3129
3141
  }
3130
3142
  __name(resolveSetupGithubProxy, "resolveSetupGithubProxy");
3131
3143
  function settingsForSetupGithubTrust(settings) {
@@ -6226,6 +6238,21 @@ async function assertSessionLoadable(workspaceCwd, sessionId) {
6226
6238
  return location;
6227
6239
  }
6228
6240
  __name(assertSessionLoadable, "assertSessionLoadable");
6241
+ async function assertSessionArchived(workspaceCwd, sessionId) {
6242
+ const location = await new SessionService(workspaceCwd).getSessionLocation(
6243
+ sessionId
6244
+ );
6245
+ if (location === "active") {
6246
+ throw new SessionNotArchivedError(sessionId);
6247
+ }
6248
+ if (location === "conflict") {
6249
+ throw new SessionConflictError(sessionId);
6250
+ }
6251
+ if (location === void 0) {
6252
+ throw new SessionNotFoundError(sessionId);
6253
+ }
6254
+ }
6255
+ __name(assertSessionArchived, "assertSessionArchived");
6229
6256
  function isSessionNotFoundError(err) {
6230
6257
  return err instanceof SessionNotFoundError || err instanceof Error && err.name === "SessionNotFoundError";
6231
6258
  }
@@ -6928,9 +6955,10 @@ function rpcErrorFrame(id, err) {
6928
6955
  __name(rpcErrorFrame, "rpcErrorFrame");
6929
6956
  var ACP_PROTOCOL_VERSION = 1;
6930
6957
  var AcpDispatcher = class {
6931
- constructor(bridge, boundWorkspace, workspace, workspaceRememberLane, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator()) {
6958
+ constructor(bridge, boundWorkspace, env, workspace, workspaceRememberLane, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator()) {
6932
6959
  this.bridge = bridge;
6933
6960
  this.boundWorkspace = boundWorkspace;
6961
+ this.env = env;
6934
6962
  this.workspace = workspace;
6935
6963
  this.workspaceRememberLane = workspaceRememberLane;
6936
6964
  this.fsFactory = fsFactory;
@@ -6944,8 +6972,14 @@ var AcpDispatcher = class {
6944
6972
  __name(this, "AcpDispatcher");
6945
6973
  }
6946
6974
  agentManager;
6947
- killOrphanSession(sessionId) {
6948
- void this.bridge.killSession(sessionId, { requireZeroAttaches: true }).catch(
6975
+ killOrphanSession(sessionId, removePersistedSession = false) {
6976
+ void this.bridge.killSession(sessionId, { requireZeroAttaches: true }).then(async (killed) => {
6977
+ if (killed && removePersistedSession) {
6978
+ await new SessionService(this.boundWorkspace).removeSession(
6979
+ sessionId
6980
+ );
6981
+ }
6982
+ }).catch(
6949
6983
  (err) => writeStderrLine(
6950
6984
  `qwen serve: /acp orphan killSession(${logSafe(sessionId)}) failed: ${logSafe(errMsg(err))}`
6951
6985
  )
@@ -7229,26 +7263,40 @@ var AcpDispatcher = class {
7229
7263
  return;
7230
7264
  case "session/new": {
7231
7265
  const cwd = parseOptionalWorkspaceCwd2(params, this.boundWorkspace);
7266
+ const source = parseSessionSource(
7267
+ params["sourceType"],
7268
+ params["sourceId"]
7269
+ );
7270
+ if ("error" in source) {
7271
+ if (id !== void 0) {
7272
+ conn.sendConn(error(id, RPC.INVALID_PARAMS, source.error));
7273
+ }
7274
+ return;
7275
+ }
7232
7276
  const session = await this.bridge.spawnOrAttach({
7233
7277
  workspaceCwd: cwd,
7234
7278
  clientId: conn.clientId,
7235
- sessionScope: "thread"
7279
+ sessionScope: "thread",
7280
+ ...source
7236
7281
  });
7237
7282
  if (conn.destroyed) {
7238
- this.killOrphanSession(session.sessionId);
7283
+ this.killOrphanSession(session.sessionId, true);
7239
7284
  return;
7240
7285
  }
7241
7286
  conn.getOrCreateSession(session.sessionId).clientId = session.clientId;
7242
7287
  conn.ownSession(session.sessionId);
7243
7288
  const configOptions = await this.configOptionsFor(session.sessionId);
7244
7289
  if (conn.destroyed) {
7245
- this.killOrphanSession(session.sessionId);
7290
+ this.killOrphanSession(session.sessionId, true);
7246
7291
  return;
7247
7292
  }
7248
7293
  const models = this.extractModelState(configOptions);
7249
7294
  const modes = this.extractModeState(configOptions);
7250
7295
  this.replyConn(conn, id, {
7251
7296
  sessionId: session.sessionId,
7297
+ ...session.sourceType ? { sourceType: session.sourceType } : {},
7298
+ ...session.sourceId !== void 0 ? { sourceId: session.sourceId } : {},
7299
+ ...session.sourcePersisted !== void 0 ? { sourcePersisted: session.sourcePersisted } : {},
7252
7300
  ...configOptions ? { configOptions } : {},
7253
7301
  ...models ? { models } : {},
7254
7302
  ...modes ? { modes } : {}
@@ -7283,20 +7331,20 @@ var AcpDispatcher = class {
7283
7331
  [sessionId],
7284
7332
  async () => {
7285
7333
  await assertSessionLoadable(cwd, sessionId);
7286
- const parentSessionId = await new SessionService(
7334
+ const metadata = await new SessionService(
7287
7335
  cwd
7288
- ).readParentSessionId(sessionId);
7336
+ ).readCreationMetadata(sessionId);
7289
7337
  return method === "session/load" ? await this.bridge.loadSession({
7290
7338
  sessionId,
7291
7339
  workspaceCwd: cwd,
7292
7340
  clientId: conn.clientId,
7293
7341
  historyReplay: "response",
7294
- ...parentSessionId !== void 0 ? { parentSessionId } : {}
7342
+ ...metadata
7295
7343
  }) : await this.bridge.resumeSession({
7296
7344
  sessionId,
7297
7345
  workspaceCwd: cwd,
7298
7346
  clientId: conn.clientId,
7299
- ...parentSessionId !== void 0 ? { parentSessionId } : {}
7347
+ ...metadata
7300
7348
  });
7301
7349
  }
7302
7350
  );
@@ -7395,6 +7443,13 @@ var AcpDispatcher = class {
7395
7443
  );
7396
7444
  }
7397
7445
  }
7446
+ const parsedSource = parseSessionSource(
7447
+ params["sourceType"],
7448
+ params["sourceId"]
7449
+ );
7450
+ if ("error" in parsedSource) {
7451
+ throw new AcpParamError(parsedSource.error);
7452
+ }
7398
7453
  const result = await listWorkspaceSessionsForResponse(
7399
7454
  this.bridge,
7400
7455
  workspaceCwd,
@@ -7404,7 +7459,8 @@ var AcpDispatcher = class {
7404
7459
  archiveState,
7405
7460
  view,
7406
7461
  group,
7407
- parentSessionId
7462
+ parentSessionId,
7463
+ ...parsedSource
7408
7464
  }
7409
7465
  );
7410
7466
  this.replyConn(conn, id, {
@@ -7417,6 +7473,8 @@ var AcpDispatcher = class {
7417
7473
  displayName: s.displayName,
7418
7474
  title: s.displayName,
7419
7475
  ...s.parentSessionId !== void 0 ? { parentSessionId: s.parentSessionId } : {},
7476
+ ...s.sourceType !== void 0 ? { sourceType: s.sourceType } : {},
7477
+ ...s.sourceId !== void 0 ? { sourceId: s.sourceId } : {},
7420
7478
  clientCount: s.clientCount,
7421
7479
  hasActivePrompt: s.hasActivePrompt,
7422
7480
  isArchived: s.isArchived === true,
@@ -8277,7 +8335,7 @@ var AcpDispatcher = class {
8277
8335
  const result = await setupGithub({
8278
8336
  cwd: this.boundWorkspace,
8279
8337
  workspaceRoot: this.boundWorkspace,
8280
- proxy: resolveSetupGithubProxy(this.boundWorkspace),
8338
+ proxy: resolveSetupGithubProxy(this.boundWorkspace, this.env),
8281
8339
  abortSignal: conn.abortSignal,
8282
8340
  fileOps: createSetupGithubFileOps(
8283
8341
  this.fsFactory,
@@ -11748,11 +11806,11 @@ function delay(ms) {
11748
11806
  return new Promise((resolve5) => setTimeout(resolve5, ms));
11749
11807
  }
11750
11808
  __name(delay, "delay");
11751
- function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname) {
11809
+ function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname, env) {
11752
11810
  if (localPort === void 0 || !Number.isInteger(localPort) || localPort <= 0) {
11753
11811
  return void 0;
11754
11812
  }
11755
- const command = resolveCdpMcpCommand(process.env);
11813
+ const command = resolveCdpMcpCommand(env);
11756
11814
  if (!command) {
11757
11815
  writeStderrLine(
11758
11816
  `qwen serve: set ${QWEN_CDP_MCP_COMMAND_ENV} to enable browser automation MCP (no adapter is bundled)`
@@ -11858,9 +11916,18 @@ function workspaceRateLimitKey(mount, clientKey) {
11858
11916
  return JSON.stringify([clientKey, mount.rateLimitScope]);
11859
11917
  }
11860
11918
  __name(workspaceRateLimitKey, "workspaceRateLimitKey");
11919
+ function runtimeEffectiveEnv(runtime, daemonEnv) {
11920
+ if (runtime.env.mode === "runtime-overlay") {
11921
+ return runtime.env.effectiveEnv ?? {};
11922
+ }
11923
+ return runtime.env.effectiveEnv ?? daemonEnv;
11924
+ }
11925
+ __name(runtimeEffectiveEnv, "runtimeEffectiveEnv");
11861
11926
  function mountAcpHttp(app, bridge, opts) {
11862
11927
  const enabled = opts.enabled ?? resolveAcpHttpEnabled();
11863
11928
  if (!enabled) return void 0;
11929
+ const daemonEnv = opts.daemonEnv ?? process.env;
11930
+ const primaryEnv = opts.workspaceRegistry ? runtimeEffectiveEnv(opts.workspaceRegistry.primary, daemonEnv) : daemonEnv;
11864
11931
  const path15 = opts.path ?? "/acp";
11865
11932
  const dispatcherRef = {};
11866
11933
  let disposed = false;
@@ -11950,7 +12017,8 @@ function mountAcpHttp(app, bridge, opts) {
11950
12017
  }
11951
12018
  const runtimeConfig = buildChromeDevToolsMcpRuntimeConfig(
11952
12019
  localPort,
11953
- opts.hostname
12020
+ opts.hostname,
12021
+ daemonEnv
11954
12022
  );
11955
12023
  if (!runtimeConfig) {
11956
12024
  cdpMcpTerminalSkipLogged = true;
@@ -12009,6 +12077,7 @@ function mountAcpHttp(app, bridge, opts) {
12009
12077
  const dispatcher = new AcpDispatcher(
12010
12078
  bridge,
12011
12079
  opts.boundWorkspace,
12080
+ primaryEnv,
12012
12081
  opts.workspace,
12013
12082
  opts.workspaceRememberLane,
12014
12083
  opts.fsFactory,
@@ -12297,6 +12366,7 @@ function mountAcpHttp(app, bridge, opts) {
12297
12366
  const secondaryDispatcher = new AcpDispatcher(
12298
12367
  rt.bridge,
12299
12368
  rt.workspaceCwd,
12369
+ runtimeEffectiveEnv(rt, daemonEnv),
12300
12370
  rt.workspaceService,
12301
12371
  workspaceRememberLane,
12302
12372
  rt.routeFileSystemFactory,
@@ -14402,7 +14472,13 @@ __name(getDemoHtml, "getDemoHtml");
14402
14472
 
14403
14473
  // packages/cli/src/serve/routes/health-demo.ts
14404
14474
  function createHealthDemoRoutes(deps) {
14405
- const { opts, getPort, bridge, getActiveSseCount: getActiveSseCount2, getRateLimiter } = deps;
14475
+ const {
14476
+ opts,
14477
+ getPort,
14478
+ workspaceRegistry,
14479
+ getActiveSseCount: getActiveSseCount2,
14480
+ getRateLimiter
14481
+ } = deps;
14406
14482
  const demoHandler = /* @__PURE__ */ __name((_req, res) => {
14407
14483
  try {
14408
14484
  res.type("html").set("X-Frame-Options", "DENY").set(
@@ -14417,32 +14493,55 @@ function createHealthDemoRoutes(deps) {
14417
14493
  }
14418
14494
  }, "demoHandler");
14419
14495
  const healthHandler = /* @__PURE__ */ __name((req, res) => {
14420
- const deepQuery = req.query["deep"];
14421
- const deep = deepQuery === "1" || deepQuery === "true" || deepQuery === "";
14422
- if (!deep) {
14496
+ if (!isDeepHealthQuery(req.query["deep"])) {
14423
14497
  res.status(200).json({ status: "ok" });
14424
14498
  return;
14425
14499
  }
14500
+ let failedWorkspaceId;
14426
14501
  try {
14427
- const lastActivity = bridge.lastActivityAt;
14502
+ const runtimes = workspaceRegistry.listManaged();
14503
+ let sessions = 0;
14504
+ let pendingPermissions = 0;
14505
+ let activePrompts = 0;
14506
+ let channelAlive = false;
14507
+ let lastActivity = null;
14508
+ for (const runtime of runtimes) {
14509
+ failedWorkspaceId = runtime.workspaceId;
14510
+ const bridge = runtime.bridge;
14511
+ const runtimeSessions = bridge.sessionCount;
14512
+ const runtimePendingPermissions = bridge.pendingPermissionCount;
14513
+ const runtimeActivePrompts = bridge.activePromptCount;
14514
+ const runtimeChannelAlive = bridge.isChannelLive();
14515
+ const runtimeLastActivity = bridge.lastActivityAt;
14516
+ sessions += runtimeSessions;
14517
+ pendingPermissions += runtimePendingPermissions;
14518
+ activePrompts += runtimeActivePrompts;
14519
+ channelAlive = channelAlive || runtimeChannelAlive;
14520
+ if (runtimeLastActivity !== null && (lastActivity === null || runtimeLastActivity > lastActivity)) {
14521
+ lastActivity = runtimeLastActivity;
14522
+ }
14523
+ failedWorkspaceId = void 0;
14524
+ }
14428
14525
  const now = Date.now();
14429
14526
  const rateLimiter = getRateLimiter();
14430
14527
  res.status(200).json({
14431
14528
  status: "ok",
14432
- sessions: bridge.sessionCount,
14433
- pendingPermissions: bridge.pendingPermissionCount,
14434
- activePrompts: bridge.activePromptCount,
14529
+ workspaceCount: runtimes.length,
14530
+ sessions,
14531
+ pendingPermissions,
14532
+ activePrompts,
14435
14533
  connectedClients: getActiveSseCount2(),
14436
- channelAlive: bridge.isChannelLive(),
14534
+ channelAlive,
14437
14535
  lastActivityAt: lastActivity !== null ? new Date(lastActivity).toISOString() : null,
14438
14536
  idleSinceMs: lastActivity !== null ? now - lastActivity : null,
14439
14537
  ...rateLimiter ? { rateLimitHits: rateLimiter.getHitCounts() } : {}
14440
14538
  });
14441
14539
  } catch (err) {
14540
+ const workspaceContext = failedWorkspaceId !== void 0 ? ` for workspace ${JSON.stringify(failedWorkspaceId)}` : "";
14442
14541
  writeStderrLine(
14443
- `qwen serve: /health deep probe failed: ${err instanceof Error ? err.message : String(err)}`
14542
+ `qwen serve: /health deep probe failed${workspaceContext}: ${err instanceof Error ? err.message : String(err)}`
14444
14543
  );
14445
- res.status(503).json({ status: "degraded" });
14544
+ res.status(503).json({ status: "degraded", reason: "aggregation_failed" });
14446
14545
  }
14447
14546
  }, "healthHandler");
14448
14547
  const loopback = isLoopbackBind(opts.hostname);
@@ -14950,6 +15049,7 @@ __name(registerWorkspaceAuthRoutes, "registerWorkspaceAuthRoutes");
14950
15049
 
14951
15050
  // packages/cli/src/serve/routes/workspace-extensions.ts
14952
15051
  init_esbuild_shims();
15052
+ import * as crypto2 from "node:crypto";
14953
15053
 
14954
15054
  // packages/cli/src/serve/extension-operation-scheduler.ts
14955
15055
  init_esbuild_shims();
@@ -15029,6 +15129,18 @@ init_esbuild_shims();
15029
15129
  import * as crypto from "node:crypto";
15030
15130
  var MAX_UNFINISHED_EXTENSION_OPERATIONS = 10;
15031
15131
  var sanitizeDaemonMessage = /* @__PURE__ */ __name((message) => redactUrlCredentials(stripAnsiAndControl(message)), "sanitizeDaemonMessage");
15132
+ var redactExtensionDisplaySource = /* @__PURE__ */ __name((source) => {
15133
+ const redacted = redactUrlCredentials(source);
15134
+ if (/^[A-Za-z]:[\\/]/.test(redacted)) return redacted;
15135
+ try {
15136
+ const url = new URL(redacted);
15137
+ url.search = "";
15138
+ url.hash = "";
15139
+ return url.toString();
15140
+ } catch {
15141
+ return redacted;
15142
+ }
15143
+ }, "redactExtensionDisplaySource");
15032
15144
  var EXTENSION_PREPARATION_CONCURRENCY = 2;
15033
15145
  var EXTENSION_REFRESH_TIMEOUT_MS = 3e4;
15034
15146
  var RECONCILE_SLOW_MS = 3e4;
@@ -15057,21 +15169,21 @@ function createExtensionsController(deps) {
15057
15169
  unfinishedOperationCount -= 1;
15058
15170
  };
15059
15171
  }, "acquireOperationSlot");
15060
- const createExtensionManager = /* @__PURE__ */ __name((workspaceDir = boundWorkspace, trustedOverride) => new ExtensionManager({
15172
+ const createExtensionManager = /* @__PURE__ */ __name((workspaceDir = boundWorkspace, trustedOverride, interactions) => new ExtensionManager({
15061
15173
  workspaceDir,
15062
15174
  isWorkspaceTrusted: trustedOverride ?? getWorkspaceTrustStatus(loadSettings(workspaceDir).merged, workspaceDir).effective.state === "trusted",
15063
15175
  requestConsent: /* @__PURE__ */ __name(() => Promise.resolve(), "requestConsent"),
15064
15176
  networkPolicy: "public",
15065
- requestSetting: /* @__PURE__ */ __name(async (setting) => {
15177
+ requestSetting: interactions?.requestSetting ?? (async (setting) => {
15066
15178
  throw new Error(
15067
15179
  `Extension setting "${setting.envVar}" requires interactive configuration and is not supported over the daemon install endpoint.`
15068
15180
  );
15069
- }, "requestSetting"),
15070
- requestChoicePlugin: /* @__PURE__ */ __name(async () => {
15181
+ }),
15182
+ requestChoicePlugin: interactions?.requestChoicePlugin ?? (async () => {
15071
15183
  throw new Error(
15072
15184
  "Marketplace plugin selection is not supported over the daemon install endpoint. Specify a plugin name in the source."
15073
15185
  );
15074
- }, "requestChoicePlugin")
15186
+ })
15075
15187
  }), "createExtensionManager");
15076
15188
  const validateExtensionMutationClient = /* @__PURE__ */ __name((req, res, opts = {}) => {
15077
15189
  const clientId = parseAndValidateWorkspaceClientId(
@@ -15090,10 +15202,10 @@ function createExtensionsController(deps) {
15090
15202
  return true;
15091
15203
  }, "validateExtensionMutationClient");
15092
15204
  const extensionOperations = /* @__PURE__ */ new Map();
15093
- const isTerminalExtensionOperation = /* @__PURE__ */ __name((operation) => operation.status !== "queued" && operation.status !== "running", "isTerminalExtensionOperation");
15205
+ const isTerminalExtensionOperation = /* @__PURE__ */ __name((operation) => operation.status !== "queued" && operation.status !== "running" && operation.status !== "waiting_for_input", "isTerminalExtensionOperation");
15094
15206
  const redactExtensionOperationResult = /* @__PURE__ */ __name((event) => ({
15095
15207
  ...event,
15096
- ...event.source ? { source: redactUrlCredentials(event.source) } : {}
15208
+ ...event.source ? { source: redactExtensionDisplaySource(event.source) } : {}
15097
15209
  }), "redactExtensionOperationResult");
15098
15210
  const bridgeMutationEvent = /* @__PURE__ */ __name((event) => {
15099
15211
  const redacted = redactExtensionOperationResult(event);
@@ -15174,7 +15286,7 @@ function createExtensionsController(deps) {
15174
15286
  status: "queued",
15175
15287
  createdAt: now,
15176
15288
  updatedAt: now,
15177
- ...failureContext.source ? { source: redactUrlCredentials(failureContext.source) } : {},
15289
+ ...failureContext.source ? { source: redactExtensionDisplaySource(failureContext.source) } : {},
15178
15290
  ...failureContext.name ? { name: failureContext.name } : {}
15179
15291
  });
15180
15292
  const operationBasePath = options.operationBasePath ?? "/workspace/extensions/operations";
@@ -15201,7 +15313,7 @@ function createExtensionsController(deps) {
15201
15313
  status: "running",
15202
15314
  phase: "preparing"
15203
15315
  });
15204
- const extensionManager = options.manager ?? createExtensionManager();
15316
+ const extensionManager = options.manager ?? options.createManager?.(operationId) ?? createExtensionManager();
15205
15317
  const deadlineController = new AbortController();
15206
15318
  let deadlineStarted = false;
15207
15319
  const startDeadline = /* @__PURE__ */ __name(() => {
@@ -15302,7 +15414,8 @@ function createExtensionsController(deps) {
15302
15414
  const event = await run(
15303
15415
  extensionManager,
15304
15416
  deadlineController.signal,
15305
- context
15417
+ context,
15418
+ operationId
15306
15419
  );
15307
15420
  mutationEvent = event;
15308
15421
  if (deadline) clearTimeout(deadline);
@@ -15527,7 +15640,9 @@ function createExtensionsController(deps) {
15527
15640
  bridge.broadcastExtensionsChanged({
15528
15641
  ...mutationEvent ? bridgeMutationEvent(mutationEvent) : {
15529
15642
  ...failureContext.source ? {
15530
- source: redactUrlCredentials(failureContext.source)
15643
+ source: redactExtensionDisplaySource(
15644
+ failureContext.source
15645
+ )
15531
15646
  } : {},
15532
15647
  ...failureContext.name ? { name: failureContext.name } : {}
15533
15648
  },
@@ -15548,13 +15663,14 @@ function createExtensionsController(deps) {
15548
15663
  updateExtensionOperation(operationId, {
15549
15664
  status: "failed",
15550
15665
  phase: void 0,
15666
+ interaction: void 0,
15551
15667
  error: message.slice(0, 500),
15552
15668
  ...code ? { code } : {}
15553
15669
  });
15554
15670
  try {
15555
15671
  bridge.broadcastExtensionsChanged({
15556
15672
  status: "failed",
15557
- ...failureContext.source ? { source: redactUrlCredentials(failureContext.source) } : {},
15673
+ ...failureContext.source ? { source: redactExtensionDisplaySource(failureContext.source) } : {},
15558
15674
  ...failureContext.name ? { name: failureContext.name } : {},
15559
15675
  refreshed: 0,
15560
15676
  failed: 0,
@@ -15576,6 +15692,7 @@ function createExtensionsController(deps) {
15576
15692
  } finally {
15577
15693
  if (deadline) clearTimeout(deadline);
15578
15694
  reconciliationReservation?.release();
15695
+ options.onSettled?.(operationId);
15579
15696
  releaseOperationSlot();
15580
15697
  }
15581
15698
  })();
@@ -15610,7 +15727,11 @@ function createExtensionsController(deps) {
15610
15727
  version: ext.version,
15611
15728
  isActive: ext.isActive,
15612
15729
  path: ext.path,
15613
- ...ext.installMetadata?.source ? { source: redactUrlCredentials(ext.installMetadata.source) } : {},
15730
+ ...ext.installMetadata?.source ? {
15731
+ source: redactExtensionDisplaySource(
15732
+ ext.installMetadata.source
15733
+ )
15734
+ } : {},
15614
15735
  ...ext.installMetadata?.type ? { installType: ext.installMetadata.type } : {},
15615
15736
  ...ext.installMetadata?.originSource ? { originSource: ext.installMetadata.originSource } : {},
15616
15737
  ...ext.installMetadata?.ref ? { ref: ext.installMetadata.ref } : {},
@@ -15646,6 +15767,10 @@ function createExtensionsController(deps) {
15646
15767
  buildLocalExtensionsStatus,
15647
15768
  refreshExtensionsForAllSessions,
15648
15769
  getOperation: /* @__PURE__ */ __name((operationId) => extensionOperations.get(operationId), "getOperation"),
15770
+ getActiveOperations: /* @__PURE__ */ __name(() => [...extensionOperations.values()].filter(
15771
+ (operation) => !isTerminalExtensionOperation(operation)
15772
+ ), "getActiveOperations"),
15773
+ updateOperation: updateExtensionOperation,
15649
15774
  preparationQueue,
15650
15775
  acquireOperationSlot,
15651
15776
  validateExtensionMutationClient,
@@ -15656,6 +15781,8 @@ __name(createExtensionsController, "createExtensionsController");
15656
15781
 
15657
15782
  // packages/cli/src/serve/routes/workspace-extensions.ts
15658
15783
  var EXTENSION_PREPARE_DEADLINE_MS = 10 * 6e4;
15784
+ var EXTENSION_INTERACTION_DEADLINE_MS = 10 * 6e4;
15785
+ var EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS = EXTENSION_PREPARE_DEADLINE_MS + EXTENSION_INTERACTION_DEADLINE_MS;
15659
15786
  var EXTENSION_UPDATE_CHECK_DEADLINE_MS = 2 * 6e4;
15660
15787
  var parseExtensionScope = /* @__PURE__ */ __name((body, res) => {
15661
15788
  const scope = body["scope"];
@@ -15761,6 +15888,96 @@ function registerWorkspaceExtensionRoutes(app, deps) {
15761
15888
  const primaryController = createExtensionsController(
15762
15889
  controllerDeps(boundWorkspace, bridge, workspace)
15763
15890
  );
15891
+ const pendingExtensionInteractions = /* @__PURE__ */ new Map();
15892
+ const supersededInstallOperations = /* @__PURE__ */ new Set();
15893
+ const cancelPendingExtensionInteraction = /* @__PURE__ */ __name((operationId, reason) => {
15894
+ const pending = pendingExtensionInteractions.get(operationId);
15895
+ if (!pending) return;
15896
+ clearTimeout(pending.timeout);
15897
+ pendingExtensionInteractions.delete(operationId);
15898
+ pending.reject(new Error(reason));
15899
+ }, "cancelPendingExtensionInteraction");
15900
+ const supersedeActiveInstallOperations = /* @__PURE__ */ __name((controller, currentOperationId) => {
15901
+ for (const operation of controller.getActiveOperations()) {
15902
+ if (operation.operation !== "install" || operation.operationId === currentOperationId) {
15903
+ continue;
15904
+ }
15905
+ supersededInstallOperations.add(operation.operationId);
15906
+ cancelPendingExtensionInteraction(
15907
+ operation.operationId,
15908
+ "Extension installation cancelled by a new install request"
15909
+ );
15910
+ }
15911
+ }, "supersedeActiveInstallOperations");
15912
+ const waitForExtensionInteraction = /* @__PURE__ */ __name((controller, operationId, interaction) => {
15913
+ if (supersededInstallOperations.delete(operationId)) {
15914
+ return Promise.reject(
15915
+ new Error("Extension installation superseded by a new install request")
15916
+ );
15917
+ }
15918
+ const operation = controller.getOperation(operationId);
15919
+ if (operation && operation.status !== "queued" && operation.status !== "running" && operation.status !== "waiting_for_input") {
15920
+ return Promise.reject(new Error("Extension operation already completed"));
15921
+ }
15922
+ const pendingInteraction = {
15923
+ ...interaction,
15924
+ id: crypto2.randomUUID()
15925
+ };
15926
+ return new Promise((resolve5, reject) => {
15927
+ const timeout = setTimeout(() => {
15928
+ pendingExtensionInteractions.delete(operationId);
15929
+ controller.updateOperation(operationId, {
15930
+ status: "failed",
15931
+ phase: void 0,
15932
+ interaction: void 0,
15933
+ error: "Extension interaction timed out"
15934
+ });
15935
+ reject(new Error("Extension interaction timed out"));
15936
+ }, EXTENSION_INTERACTION_DEADLINE_MS);
15937
+ timeout.unref?.();
15938
+ pendingExtensionInteractions.set(operationId, {
15939
+ interaction: pendingInteraction,
15940
+ resolve: resolve5,
15941
+ reject,
15942
+ timeout
15943
+ });
15944
+ controller.updateOperation(operationId, {
15945
+ status: "waiting_for_input",
15946
+ phase: void 0,
15947
+ interaction: pendingInteraction
15948
+ });
15949
+ });
15950
+ }, "waitForExtensionInteraction");
15951
+ const extensionInteractionHandlers = /* @__PURE__ */ __name((controller, operationId) => ({
15952
+ requestSetting: /* @__PURE__ */ __name((setting) => waitForExtensionInteraction(controller, operationId, {
15953
+ kind: "setting",
15954
+ setting: {
15955
+ name: setting.name,
15956
+ description: setting.description,
15957
+ sensitive: setting.sensitive === true
15958
+ }
15959
+ }), "requestSetting"),
15960
+ requestChoicePlugin: /* @__PURE__ */ __name((marketplace) => {
15961
+ if (marketplace.plugins.length === 0) {
15962
+ return Promise.reject(
15963
+ new Error(`Marketplace "${marketplace.name}" has no plugins`)
15964
+ );
15965
+ }
15966
+ return waitForExtensionInteraction(controller, operationId, {
15967
+ kind: "marketplace_plugin",
15968
+ marketplace: { name: marketplace.name },
15969
+ plugins: marketplace.plugins.map((plugin) => ({
15970
+ name: plugin.name,
15971
+ ...plugin.description ? { description: plugin.description } : {},
15972
+ source: redactExtensionDisplaySource(
15973
+ typeof plugin.source === "string" ? plugin.source : plugin.source.source === "github" ? plugin.source.repo : plugin.source.url
15974
+ ),
15975
+ ...plugin.category ? { category: plugin.category } : {},
15976
+ ...plugin.tags ? { tags: plugin.tags } : {}
15977
+ }))
15978
+ });
15979
+ }, "requestChoicePlugin")
15980
+ }), "extensionInteractionHandlers");
15764
15981
  const runtimeReconciliationQueue = createFifoTaskQueue(1);
15765
15982
  const reserveRuntimeReconciliation = /* @__PURE__ */ __name(() => {
15766
15983
  let provideTask;
@@ -15877,6 +16094,11 @@ function registerWorkspaceExtensionRoutes(app, deps) {
15877
16094
  sendBridgeError2(res, err, { route: `GET ${base}` });
15878
16095
  }
15879
16096
  });
16097
+ app.get(`${base}/operations`, async (req, res) => {
16098
+ const ctrl = resolve5(req, res, false);
16099
+ if (!ctrl) return;
16100
+ res.status(200).json({ v: 1, operations: ctrl.getActiveOperations() });
16101
+ });
15880
16102
  app.get(`${base}/operations/:operationId`, async (req, res) => {
15881
16103
  const ctrl = resolve5(req, res, false);
15882
16104
  if (!ctrl) return;
@@ -15918,11 +16140,85 @@ function registerWorkspaceExtensionRoutes(app, deps) {
15918
16140
  });
15919
16141
  }
15920
16142
  });
16143
+ app.post(
16144
+ `${base}/operations/:operationId/interactions/:interactionId`,
16145
+ mutate({ strict: true }),
16146
+ async (req, res) => {
16147
+ const ctrl = resolve5(req, res, false);
16148
+ if (!ctrl) return;
16149
+ try {
16150
+ if (!ctrl.validateExtensionMutationClient(req, res, {
16151
+ requireClientId: false
16152
+ })) {
16153
+ return;
16154
+ }
16155
+ const operationId = req.params["operationId"];
16156
+ const interactionId = req.params["interactionId"];
16157
+ const pending = operationId ? pendingExtensionInteractions.get(operationId) : void 0;
16158
+ if (!operationId || !interactionId || !pending) {
16159
+ res.status(404).json({ error: "Extension interaction not found" });
16160
+ return;
16161
+ }
16162
+ if (pending.interaction.id !== interactionId) {
16163
+ res.status(404).json({ error: "Extension interaction not found" });
16164
+ return;
16165
+ }
16166
+ const body = safeBody2(req);
16167
+ let value;
16168
+ if (body["cancelled"] === true) {
16169
+ clearTimeout(pending.timeout);
16170
+ pendingExtensionInteractions.delete(operationId);
16171
+ ctrl.updateOperation(operationId, {
16172
+ status: "failed",
16173
+ phase: void 0,
16174
+ interaction: void 0,
16175
+ error: "Extension operation cancelled"
16176
+ });
16177
+ pending.reject(new Error("Extension operation cancelled"));
16178
+ res.status(200).json({ accepted: true });
16179
+ return;
16180
+ }
16181
+ if (pending.interaction.kind === "marketplace_plugin") {
16182
+ const pluginName = body["pluginName"];
16183
+ if (typeof pluginName !== "string" || !pending.interaction.plugins.some(
16184
+ (plugin) => plugin.name === pluginName
16185
+ )) {
16186
+ res.status(400).json({ error: "Invalid marketplace plugin name" });
16187
+ return;
16188
+ }
16189
+ value = pluginName;
16190
+ } else {
16191
+ const settingValue = body["value"];
16192
+ if (typeof settingValue !== "string") {
16193
+ res.status(400).json({ error: "Extension setting value must be a string" });
16194
+ return;
16195
+ }
16196
+ value = settingValue;
16197
+ }
16198
+ clearTimeout(pending.timeout);
16199
+ pendingExtensionInteractions.delete(operationId);
16200
+ ctrl.updateOperation(operationId, {
16201
+ status: "running",
16202
+ phase: "preparing",
16203
+ interaction: void 0,
16204
+ error: void 0
16205
+ });
16206
+ pending.resolve(value);
16207
+ res.status(200).json({ accepted: true });
16208
+ } catch (err) {
16209
+ sendBridgeError2(res, err, {
16210
+ route: `POST ${base}/operations/:operationId/interactions/:interactionId`
16211
+ });
16212
+ }
16213
+ }
16214
+ );
15921
16215
  app.post(`${base}/install`, mutate({ strict: true }), async (req, res) => {
15922
16216
  const ctrl = resolve5(req, res, true);
15923
16217
  if (!ctrl) return;
15924
16218
  try {
15925
- if (!ctrl.validateExtensionMutationClient(req, res)) {
16219
+ if (!ctrl.validateExtensionMutationClient(req, res, {
16220
+ requireClientId: false
16221
+ })) {
15926
16222
  return;
15927
16223
  }
15928
16224
  const body = safeBody2(req);
@@ -15972,11 +16268,56 @@ function registerWorkspaceExtensionRoutes(app, deps) {
15972
16268
  if (!validateExtensionSourceHost(sourceValue, res)) {
15973
16269
  return;
15974
16270
  }
16271
+ const localSource = /^[A-Za-z]:[\\/]/.test(sourceValue) || sourceValue.startsWith("/") || sourceValue.startsWith(".");
16272
+ if (localSource) {
16273
+ try {
16274
+ const metadata = await parseInstallSource(sourceValue, {
16275
+ networkPolicy: "public"
16276
+ });
16277
+ if (metadata.type !== "git" && metadata.type !== "github-release" && metadata.type !== "npm") {
16278
+ res.status(400).json({
16279
+ error: "Only GitHub, Git, and npm extension installs are supported over the daemon endpoint."
16280
+ });
16281
+ return;
16282
+ }
16283
+ } catch (error2) {
16284
+ const message = error2 instanceof Error ? error2.message : "Invalid install source";
16285
+ res.status(400).json({
16286
+ error: redactUrlCredentials(
16287
+ message.replaceAll(
16288
+ sourceValue,
16289
+ redactExtensionDisplaySource(sourceValue)
16290
+ )
16291
+ )
16292
+ });
16293
+ return;
16294
+ }
16295
+ }
16296
+ const npmSource = sourceValue.startsWith("@");
16297
+ const remoteSource = npmSource || sourceValue.startsWith("https://") || /^[^/\s]+\/[^/\s]+/.test(sourceValue);
16298
+ if (!localSource && !remoteSource) {
16299
+ res.status(400).json({
16300
+ error: `Install source not found: ${redactExtensionDisplaySource(
16301
+ sourceValue
16302
+ )}`
16303
+ });
16304
+ return;
16305
+ }
16306
+ if (npmSource && refValue) {
16307
+ res.status(400).json({ error: "--ref is not applicable for npm extensions." });
16308
+ return;
16309
+ }
16310
+ if (!npmSource && registryValue) {
16311
+ res.status(400).json({
16312
+ error: "--registry is only applicable for npm extensions."
16313
+ });
16314
+ return;
16315
+ }
15975
16316
  ctrl.runQueuedExtensionMutation(
15976
16317
  "install",
15977
16318
  { source: sourceValue },
15978
16319
  res,
15979
- async (extensionManager, _signal, context) => {
16320
+ async (extensionManager, _signal, context, operationId) => {
15980
16321
  const prepared = await context.prepare(async (signal) => {
15981
16322
  const installMetadata = await parseInstallSource(sourceValue, {
15982
16323
  networkPolicy: "public"
@@ -16000,6 +16341,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
16000
16341
  if (installMetadata.type === "npm" && registryUrl) {
16001
16342
  installMetadata.registryUrl = registryUrl;
16002
16343
  }
16344
+ supersedeActiveInstallOperations(ctrl, operationId);
16003
16345
  return await extensionManager.prepareExtensionInstall({
16004
16346
  installMetadata: {
16005
16347
  ...installMetadata,
@@ -16030,7 +16372,19 @@ function registerWorkspaceExtensionRoutes(app, deps) {
16030
16372
  }
16031
16373
  },
16032
16374
  {
16033
- deadlineMs: EXTENSION_PREPARE_DEADLINE_MS,
16375
+ createManager: /* @__PURE__ */ __name((operationId) => ctrl.createExtensionManager(
16376
+ void 0,
16377
+ void 0,
16378
+ extensionInteractionHandlers(ctrl, operationId)
16379
+ ), "createManager"),
16380
+ onSettled: /* @__PURE__ */ __name((operationId) => {
16381
+ supersededInstallOperations.delete(operationId);
16382
+ cancelPendingExtensionInteraction(
16383
+ operationId,
16384
+ "Extension operation ended"
16385
+ );
16386
+ }, "onSettled"),
16387
+ deadlineMs: EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS,
16034
16388
  ...globalReconciliationOptions()
16035
16389
  }
16036
16390
  );
@@ -16047,7 +16401,9 @@ function registerWorkspaceExtensionRoutes(app, deps) {
16047
16401
  let timer;
16048
16402
  let releaseOperationSlot;
16049
16403
  try {
16050
- if (!ctrl.validateExtensionMutationClient(req, res)) {
16404
+ if (!ctrl.validateExtensionMutationClient(req, res, {
16405
+ requireClientId: false
16406
+ })) {
16051
16407
  return;
16052
16408
  }
16053
16409
  releaseOperationSlot = ctrl.acquireOperationSlot(res);
@@ -16107,7 +16463,9 @@ function registerWorkspaceExtensionRoutes(app, deps) {
16107
16463
  const ctrl = resolve5(req, res, true);
16108
16464
  if (!ctrl) return;
16109
16465
  try {
16110
- if (!ctrl.validateExtensionMutationClient(req, res)) {
16466
+ if (!ctrl.validateExtensionMutationClient(req, res, {
16467
+ requireClientId: false
16468
+ })) {
16111
16469
  return;
16112
16470
  }
16113
16471
  const releaseOperationSlot = ctrl.acquireOperationSlot(res);
@@ -16223,7 +16581,9 @@ function registerWorkspaceExtensionRoutes(app, deps) {
16223
16581
  const ctrl = resolve5(req, res, true);
16224
16582
  if (!ctrl) return;
16225
16583
  try {
16226
- if (!ctrl.validateExtensionMutationClient(req, res)) {
16584
+ if (!ctrl.validateExtensionMutationClient(req, res, {
16585
+ requireClientId: false
16586
+ })) {
16227
16587
  return;
16228
16588
  }
16229
16589
  const name = req.params["name"];
@@ -16280,7 +16640,18 @@ function registerWorkspaceExtensionRoutes(app, deps) {
16280
16640
  }
16281
16641
  },
16282
16642
  {
16283
- deadlineMs: EXTENSION_PREPARE_DEADLINE_MS,
16643
+ createManager: /* @__PURE__ */ __name((operationId) => ctrl.createExtensionManager(
16644
+ void 0,
16645
+ void 0,
16646
+ extensionInteractionHandlers(ctrl, operationId)
16647
+ ), "createManager"),
16648
+ onSettled: /* @__PURE__ */ __name((operationId) => {
16649
+ cancelPendingExtensionInteraction(
16650
+ operationId,
16651
+ "Extension operation ended"
16652
+ );
16653
+ }, "onSettled"),
16654
+ deadlineMs: EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS,
16284
16655
  ...globalReconciliationOptions()
16285
16656
  }
16286
16657
  );
@@ -16293,7 +16664,9 @@ function registerWorkspaceExtensionRoutes(app, deps) {
16293
16664
  const ctrl = resolve5(req, res, true);
16294
16665
  if (!ctrl) return;
16295
16666
  try {
16296
- if (!ctrl.validateExtensionMutationClient(req, res)) {
16667
+ if (!ctrl.validateExtensionMutationClient(req, res, {
16668
+ requireClientId: false
16669
+ })) {
16297
16670
  return;
16298
16671
  }
16299
16672
  const name = req.params["name"];
@@ -17509,7 +17882,7 @@ __name(registerPermissionRoutes, "registerPermissionRoutes");
17509
17882
 
17510
17883
  // packages/cli/src/serve/routes/session.ts
17511
17884
  init_esbuild_shims();
17512
- import * as crypto2 from "node:crypto";
17885
+ import * as crypto3 from "node:crypto";
17513
17886
  import * as path11 from "node:path";
17514
17887
 
17515
17888
  // packages/cli/src/serve/server/prompt-deadline.ts
@@ -17566,7 +17939,7 @@ function parseOrganizedCursor(cursor, expected) {
17566
17939
  const decoded = Buffer.from(cursor, "base64url").toString("utf8");
17567
17940
  const parsed = JSON.parse(decoded);
17568
17941
  const last = parsed.last;
17569
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.isPinned !== "boolean" || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.group !== expected.group || parsed.archiveState !== expected.archiveState) {
17942
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.isPinned !== "boolean" || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.group !== expected.group || parsed.archiveState !== expected.archiveState || parsed.sourceType !== expected.sourceType || parsed.sourceId !== expected.sourceId) {
17570
17943
  throw new Error("invalid organized cursor");
17571
17944
  }
17572
17945
  return last;
@@ -17575,9 +17948,9 @@ function parseOrganizedCursor(cursor, expected) {
17575
17948
  }
17576
17949
  }
17577
17950
  __name(parseOrganizedCursor, "parseOrganizedCursor");
17578
- function encodeOrganizedCursor(last, group, archiveState) {
17951
+ function encodeOrganizedCursor(last, group, archiveState, sourceType, sourceId) {
17579
17952
  return Buffer.from(
17580
- JSON.stringify({ group, archiveState, last }),
17953
+ JSON.stringify({ group, archiveState, sourceType, sourceId, last }),
17581
17954
  "utf8"
17582
17955
  ).toString("base64url");
17583
17956
  }
@@ -17601,29 +17974,39 @@ function encodeLiveSessionCursor(last) {
17601
17974
  return Buffer.from(JSON.stringify(last), "utf8").toString("base64url");
17602
17975
  }
17603
17976
  __name(encodeLiveSessionCursor, "encodeLiveSessionCursor");
17604
- function parseParentSessionCursor(cursor, expected) {
17977
+ function matchesSessionMetadataSource(session, filter) {
17978
+ const sourceTypeMatches = filter.sourceType === void 0 || session.sourceType === filter.sourceType || // Legacy sessions without source metadata belong to the default catalog.
17979
+ filter.sourceType === "default" && session.sourceType === void 0;
17980
+ return sourceTypeMatches && // sourceId remains exact; only the default source type has legacy fallback.
17981
+ (filter.sourceId === void 0 || session.sourceId === filter.sourceId);
17982
+ }
17983
+ __name(matchesSessionMetadataSource, "matchesSessionMetadataSource");
17984
+ function parseMetadataSessionCursor(cursor, expected) {
17605
17985
  if (cursor === "") return void 0;
17606
17986
  try {
17607
17987
  const parsed = JSON.parse(
17608
17988
  Buffer.from(cursor, "base64url").toString("utf8")
17609
17989
  );
17610
17990
  const last = parsed.last;
17611
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.parentSessionId !== expected.parentSessionId || parsed.archiveState !== expected.archiveState) {
17612
- throw new Error("invalid parent cursor");
17991
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.parentSessionId !== expected.parentSessionId || parsed.sourceType !== expected.sourceType || parsed.sourceId !== expected.sourceId || parsed.archiveState !== expected.archiveState) {
17992
+ throw new Error("invalid metadata cursor");
17613
17993
  }
17614
17994
  return { activityTime: last.activityTime, sessionId: last.sessionId };
17615
17995
  } catch {
17616
- throw new InvalidCursorError(cursor, "parent");
17996
+ throw new InvalidCursorError(
17997
+ cursor,
17998
+ expected.sourceType === void 0 ? "parent" : "metadata"
17999
+ );
17617
18000
  }
17618
18001
  }
17619
- __name(parseParentSessionCursor, "parseParentSessionCursor");
17620
- function encodeParentSessionCursor(last, parentSessionId, archiveState) {
18002
+ __name(parseMetadataSessionCursor, "parseMetadataSessionCursor");
18003
+ function encodeMetadataSessionCursor(last, filter, archiveState) {
17621
18004
  return Buffer.from(
17622
- JSON.stringify({ parentSessionId, archiveState, last }),
18005
+ JSON.stringify({ ...filter, archiveState, last }),
17623
18006
  "utf8"
17624
18007
  ).toString("base64url");
17625
18008
  }
17626
- __name(encodeParentSessionCursor, "encodeParentSessionCursor");
18009
+ __name(encodeMetadataSessionCursor, "encodeMetadataSessionCursor");
17627
18010
  function toSummary2(item) {
17628
18011
  return {
17629
18012
  sessionId: item.sessionId,
@@ -17632,6 +18015,8 @@ function toSummary2(item) {
17632
18015
  updatedAt: new Date(item.mtime).toISOString(),
17633
18016
  displayName: item.customTitle || item.prompt,
17634
18017
  ...item.parentSessionId ? { parentSessionId: item.parentSessionId } : {},
18018
+ ...item.sourceType ? { sourceType: item.sourceType } : {},
18019
+ ...item.sourceId !== void 0 ? { sourceId: item.sourceId } : {},
17635
18020
  clientCount: 0,
17636
18021
  hasActivePrompt: false,
17637
18022
  isArchived: item.isArchived === true
@@ -17647,6 +18032,8 @@ function mergeLiveSessionSummary(existing, live) {
17647
18032
  // Immutable lineage; the persisted transcript is authoritative, and a live
17648
18033
  // entry only carries it when spawned this run.
17649
18034
  parentSessionId: existing.parentSessionId ?? live.parentSessionId,
18035
+ sourceType: existing.sourceType ?? live.sourceType,
18036
+ sourceId: existing.sourceType !== void 0 ? existing.sourceId : live.sourceId,
17650
18037
  updatedAt: live.updatedAt ?? existing.updatedAt,
17651
18038
  clientCount: live.clientCount,
17652
18039
  hasActivePrompt: live.hasActivePrompt,
@@ -17746,7 +18133,12 @@ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, o
17746
18133
  "group"
17747
18134
  );
17748
18135
  }
17749
- const cursorKey = options.cursor !== void 0 ? parseOrganizedCursor(options.cursor, { group, archiveState }) : void 0;
18136
+ const cursorKey = options.cursor !== void 0 ? parseOrganizedCursor(options.cursor, {
18137
+ group,
18138
+ archiveState,
18139
+ sourceType: options.sourceType,
18140
+ sourceId: options.sourceId
18141
+ }) : void 0;
17750
18142
  const isFirstPage = cursorKey === void 0;
17751
18143
  let liveMergeFailed = false;
17752
18144
  const bySessionId = /* @__PURE__ */ new Map();
@@ -17798,6 +18190,7 @@ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, o
17798
18190
  }
17799
18191
  }
17800
18192
  const filtered = [...bySessionId.values()].filter((session) => {
18193
+ if (!matchesSessionMetadataSource(session, options)) return false;
17801
18194
  if (group === "all") return true;
17802
18195
  if (group === "pinned") return session.isPinned === true;
17803
18196
  if (group === "ungrouped")
@@ -17821,7 +18214,9 @@ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, o
17821
18214
  const nextCursor = page.length < afterCursor.length ? encodeOrganizedCursor(
17822
18215
  getOrganizedCursorKey(activityTimeById, page[page.length - 1]),
17823
18216
  group,
17824
- archiveState
18217
+ archiveState,
18218
+ options.sourceType,
18219
+ options.sourceId
17825
18220
  ) : void 0;
17826
18221
  return {
17827
18222
  sessions: page,
@@ -17831,7 +18226,7 @@ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, o
17831
18226
  };
17832
18227
  }
17833
18228
  __name(listOrganizedWorkspaceSessionsForResponse, "listOrganizedWorkspaceSessionsForResponse");
17834
- async function listWorkspaceSessionsByParentForResponse(bridge, workspaceCwd, options, pageSize, parentSessionId, readOptions) {
18229
+ async function listWorkspaceSessionsByMetadataForResponse(bridge, workspaceCwd, options, pageSize, filter, readOptions) {
17835
18230
  const archiveState = options.archiveState ?? "active";
17836
18231
  const sessionService = new SessionService(workspaceCwd);
17837
18232
  const bySessionId = /* @__PURE__ */ new Map();
@@ -17865,18 +18260,20 @@ async function listWorkspaceSessionsByParentForResponse(bridge, workspaceCwd, op
17865
18260
  } catch (error2) {
17866
18261
  liveMergeFailed = true;
17867
18262
  writeStderrLine(
17868
- `qwen serve: session-by-parent live merge failed; using persisted sessions only: ${error2 instanceof Error ? error2.message : String(error2)}`
18263
+ `qwen serve: session metadata filter live merge failed; using persisted sessions only: ${error2 instanceof Error ? error2.message : String(error2)}`
17869
18264
  );
17870
18265
  }
17871
18266
  }
17872
- const matches = [...bySessionId.values()].filter((session) => session.parentSessionId === parentSessionId).sort(
18267
+ const matches = [...bySessionId.values()].filter(
18268
+ (session) => (filter.parentSessionId === void 0 || session.parentSessionId === filter.parentSessionId) && matchesSessionMetadataSource(session, filter)
18269
+ ).sort(
17873
18270
  (a, b) => compareLiveSessionCursorKeys(
17874
18271
  getLiveSessionCursorKey(a),
17875
18272
  getLiveSessionCursorKey(b)
17876
18273
  )
17877
18274
  );
17878
- const cursorKey = options.cursor !== void 0 && options.cursor !== "" ? parseParentSessionCursor(options.cursor, {
17879
- parentSessionId,
18275
+ const cursorKey = options.cursor !== void 0 && options.cursor !== "" ? parseMetadataSessionCursor(options.cursor, {
18276
+ ...filter,
17880
18277
  archiveState
17881
18278
  }) : void 0;
17882
18279
  const afterCursor = cursorKey === void 0 ? matches : matches.filter(
@@ -17886,9 +18283,9 @@ async function listWorkspaceSessionsByParentForResponse(bridge, workspaceCwd, op
17886
18283
  ) < 0
17887
18284
  );
17888
18285
  const page = afterCursor.slice(0, pageSize);
17889
- const nextCursor = page.length < afterCursor.length ? encodeParentSessionCursor(
18286
+ const nextCursor = page.length < afterCursor.length ? encodeMetadataSessionCursor(
17890
18287
  getLiveSessionCursorKey(page[page.length - 1]),
17891
- parentSessionId,
18288
+ filter,
17892
18289
  archiveState
17893
18290
  ) : void 0;
17894
18291
  return {
@@ -17898,7 +18295,7 @@ async function listWorkspaceSessionsByParentForResponse(bridge, workspaceCwd, op
17898
18295
  ...persisted.truncated ? { truncated: true } : {}
17899
18296
  };
17900
18297
  }
17901
- __name(listWorkspaceSessionsByParentForResponse, "listWorkspaceSessionsByParentForResponse");
18298
+ __name(listWorkspaceSessionsByMetadataForResponse, "listWorkspaceSessionsByMetadataForResponse");
17902
18299
  async function listWorkspaceSessionsForResponse(bridge, workspaceCwd, options, readOptions = {}) {
17903
18300
  const rawSize = options?.size;
17904
18301
  const requestedSize = typeof rawSize === "number" && Number.isSafeInteger(rawSize) ? rawSize : DEFAULT_SESSION_PAGE_SIZE;
@@ -17912,13 +18309,17 @@ async function listWorkspaceSessionsForResponse(bridge, workspaceCwd, options, r
17912
18309
  readOptions
17913
18310
  );
17914
18311
  }
17915
- if (options?.parentSessionId !== void 0) {
17916
- return listWorkspaceSessionsByParentForResponse(
18312
+ if (options?.parentSessionId !== void 0 || options?.sourceType !== void 0) {
18313
+ return listWorkspaceSessionsByMetadataForResponse(
17917
18314
  bridge,
17918
18315
  workspaceCwd,
17919
18316
  options,
17920
18317
  pageSize,
17921
- options.parentSessionId,
18318
+ {
18319
+ ...options.parentSessionId !== void 0 ? { parentSessionId: options.parentSessionId } : {},
18320
+ ...options.sourceType !== void 0 ? { sourceType: options.sourceType } : {},
18321
+ ...options.sourceId !== void 0 ? { sourceId: options.sourceId } : {}
18322
+ },
17922
18323
  readOptions
17923
18324
  );
17924
18325
  }
@@ -18036,9 +18437,10 @@ function sessionExportFormatValues() {
18036
18437
  __name(sessionExportFormatValues, "sessionExportFormatValues");
18037
18438
  async function exportSessionTranscript(params) {
18038
18439
  const { workspaceCwd, sessionId, format } = params;
18039
- const sessionData = await new SessionService(workspaceCwd).loadSession(
18040
- sessionId
18041
- );
18440
+ const service = new SessionService(workspaceCwd);
18441
+ const sessionData = params.archiveState === "archived" ? await service.loadArchivedSession(sessionId, {
18442
+ maxBytes: SESSION_TRANSCRIPT_MAX_INDEX_BYTES
18443
+ }) : await service.loadSession(sessionId);
18042
18444
  if (!sessionData) {
18043
18445
  throw new SessionNotFoundError(sessionId);
18044
18446
  }
@@ -18067,6 +18469,60 @@ var WORKSPACE_TRANSCRIPT_PAGE_SOURCE_MAX_BYTES = 4 * 1024 * 1024;
18067
18469
  var WORKSPACE_TRANSCRIPT_RESPONSE_MAX_BYTES = 32 * 1024 * 1024;
18068
18470
  var WORKSPACE_TRANSCRIPT_CURSOR_MAX_BYTES = 64 * 1024;
18069
18471
  var TRANSCRIPT_CURSOR_TOO_LARGE_REPLAY_ERROR = "Transcript pagination state exceeds the safe limit";
18472
+ var GENERATION_HEARTBEAT_MS = 15e3;
18473
+ var PRIMARY_ONLY_LIVE_SESSION_ROUTES = [
18474
+ "POST /session/:id/branch",
18475
+ "POST /session/:id/fork",
18476
+ "POST /session/:id/cd"
18477
+ ];
18478
+ function isPrimaryOnlyLiveSessionRoute(route) {
18479
+ return PRIMARY_ONLY_LIVE_SESSION_ROUTES.includes(
18480
+ route
18481
+ );
18482
+ }
18483
+ __name(isPrimaryOnlyLiveSessionRoute, "isPrimaryOnlyLiveSessionRoute");
18484
+ function formatGenerationSse(event, data) {
18485
+ return `event: ${event}
18486
+ data: ${JSON.stringify({ v: 1, ...data })}
18487
+
18488
+ `;
18489
+ }
18490
+ __name(formatGenerationSse, "formatGenerationSse");
18491
+ function writeGenerationSseChunk(res, chunk) {
18492
+ if (res.destroyed) {
18493
+ return Promise.reject(new Error("Generation SSE connection destroyed"));
18494
+ }
18495
+ const writable = res.write(chunk);
18496
+ const flush = res.flush;
18497
+ flush?.call(res);
18498
+ if (writable) {
18499
+ return res.destroyed ? Promise.reject(new Error("Generation SSE connection destroyed")) : Promise.resolve();
18500
+ }
18501
+ return new Promise((resolve5, reject) => {
18502
+ const cleanup = /* @__PURE__ */ __name(() => {
18503
+ res.off("drain", onDrain);
18504
+ res.off("close", onClose);
18505
+ res.off("error", onError);
18506
+ }, "cleanup");
18507
+ const onDrain = /* @__PURE__ */ __name(() => {
18508
+ cleanup();
18509
+ resolve5();
18510
+ }, "onDrain");
18511
+ const onClose = /* @__PURE__ */ __name(() => {
18512
+ cleanup();
18513
+ reject(new Error("Generation SSE connection closed"));
18514
+ }, "onClose");
18515
+ const onError = /* @__PURE__ */ __name((error2) => {
18516
+ cleanup();
18517
+ reject(error2);
18518
+ }, "onError");
18519
+ res.once("drain", onDrain);
18520
+ res.once("close", onClose);
18521
+ res.once("error", onError);
18522
+ if (res.destroyed) onClose();
18523
+ });
18524
+ }
18525
+ __name(writeGenerationSseChunk, "writeGenerationSseChunk");
18070
18526
  function isReadOnlyWorkspaceInspection(runtime) {
18071
18527
  return !runtime.primary && !runtime.trusted;
18072
18528
  }
@@ -18212,14 +18668,14 @@ function registerSessionRoutes(app, deps) {
18212
18668
  sessionShellCommandEnabled
18213
18669
  } = deps;
18214
18670
  const LANGUAGE_CODES = deps.languageCodes;
18215
- const transcriptCursorMasterKey = crypto2.randomBytes(32);
18671
+ const transcriptCursorMasterKey = crypto3.randomBytes(32);
18216
18672
  const transcriptCursorCodecs = /* @__PURE__ */ new Map();
18217
18673
  const getTranscriptCursorCodec = /* @__PURE__ */ __name((runtime) => {
18218
18674
  const canonicalCwd = canonicalizeWorkspace(runtime.workspaceCwd);
18219
18675
  const cacheKey = `${runtime.workspaceId}\0${canonicalCwd}`;
18220
18676
  const cached = transcriptCursorCodecs.get(cacheKey);
18221
18677
  if (cached) return cached;
18222
- const derivedKey = crypto2.hkdfSync(
18678
+ const derivedKey = crypto3.hkdfSync(
18223
18679
  "sha256",
18224
18680
  transcriptCursorMasterKey,
18225
18681
  Buffer.alloc(0),
@@ -18397,11 +18853,16 @@ function registerSessionRoutes(app, deps) {
18397
18853
  const result = await archiveCoordinator.runSharedMany(
18398
18854
  [sessionId],
18399
18855
  async () => {
18400
- await assertSessionLoadable(target.workspaceCwd, sessionId);
18856
+ if (target.archiveState === "archived") {
18857
+ await assertSessionArchived(target.workspaceCwd, sessionId);
18858
+ } else {
18859
+ await assertSessionLoadable(target.workspaceCwd, sessionId);
18860
+ }
18401
18861
  return exportSessionTranscript({
18402
18862
  workspaceCwd: target.workspaceCwd,
18403
18863
  sessionId,
18404
18864
  format,
18865
+ archiveState: target.archiveState,
18405
18866
  config: { getChannel: /* @__PURE__ */ __name(() => "daemon", "getChannel") }
18406
18867
  });
18407
18868
  }
@@ -18573,7 +19034,7 @@ function registerSessionRoutes(app, deps) {
18573
19034
  }), "resolveLiveSessionRuntime");
18574
19035
  const sendNonPrimarySessionRouteUnsupported = /* @__PURE__ */ __name((res, route, sessionId, runtime) => {
18575
19036
  res.status(400).json({
18576
- error: `Route "${route}" is primary-only for non-primary workspace sessions in Phase 2a.`,
19037
+ error: `Route "${route}" is only available for primary workspace sessions.`,
18577
19038
  code: "non_primary_session_route_not_supported",
18578
19039
  sessionId,
18579
19040
  workspaceId: runtime.workspaceId,
@@ -18722,23 +19183,37 @@ function registerSessionRoutes(app, deps) {
18722
19183
  }
18723
19184
  return key;
18724
19185
  }, "resolveWorkspaceParam");
18725
- const withMutableSession = /* @__PURE__ */ __name((route, handler) => async (req, res) => {
18726
- const sessionId = requireSessionId(req, res);
18727
- if (sessionId === null) return;
18728
- const runtime = resolveLiveSessionRuntime(sessionId, res, route);
18729
- if (!runtime) return;
18730
- if (!runtime.primary) {
18731
- sendNonPrimarySessionRouteUnsupported(res, route, sessionId, runtime);
18732
- return;
19186
+ const withPrimaryOnlyMutableSession = /* @__PURE__ */ __name((route, handler) => {
19187
+ if (!isPrimaryOnlyLiveSessionRoute(route)) {
19188
+ throw new Error(`Unregistered primary-only session route: ${route}`);
18733
19189
  }
18734
- try {
18735
- await archiveCoordinator.runSharedMany([sessionId], async () => {
18736
- await handler(req, res, sessionId);
18737
- });
18738
- } catch (err) {
18739
- sendBridgeError2(res, err, { route, sessionId });
18740
- }
18741
- }, "withMutableSession");
19190
+ return async (req, res) => {
19191
+ const sessionId = requireSessionId(req, res);
19192
+ if (sessionId === null) return;
19193
+ const runtime = resolveLiveSessionRuntime(sessionId, res, route);
19194
+ if (!runtime) return;
19195
+ if (!runtime.primary) {
19196
+ logSessionRoutingFailure(
19197
+ route,
19198
+ "non_primary_session_route_not_supported",
19199
+ {
19200
+ sessionId,
19201
+ workspaceId: runtime.workspaceId,
19202
+ workspaceCwd: runtime.workspaceCwd
19203
+ }
19204
+ );
19205
+ sendNonPrimarySessionRouteUnsupported(res, route, sessionId, runtime);
19206
+ return;
19207
+ }
19208
+ try {
19209
+ await archiveCoordinator.runSharedMany([sessionId], async () => {
19210
+ await handler(req, res, sessionId);
19211
+ });
19212
+ } catch (err) {
19213
+ sendBridgeError2(res, err, { route, sessionId });
19214
+ }
19215
+ };
19216
+ }, "withPrimaryOnlyMutableSession");
18742
19217
  app.post("/session", mutate(), async (req, res) => {
18743
19218
  const body = safeBody(req);
18744
19219
  const resolvedRuntime = resolveRuntimeForSessionCreation(body, res);
@@ -18759,6 +19234,14 @@ function registerSessionRoutes(app, deps) {
18759
19234
  }
18760
19235
  const approvalMode = parseOptionalApprovalMode(body, res);
18761
19236
  if (approvalMode === null) return;
19237
+ const source = parseSessionSource(body["sourceType"], body["sourceId"]);
19238
+ if ("error" in source) {
19239
+ res.status(400).json({
19240
+ error: source.error,
19241
+ code: "invalid_session_source"
19242
+ });
19243
+ return;
19244
+ }
18762
19245
  const clientId = parseClientIdHeader(req, res);
18763
19246
  if (clientId === null) return;
18764
19247
  try {
@@ -18767,7 +19250,9 @@ function registerSessionRoutes(app, deps) {
18767
19250
  modelServiceId,
18768
19251
  ...clientId !== void 0 ? { clientId } : {},
18769
19252
  ...sessionScope !== void 0 ? { sessionScope } : {},
18770
- ...approvalMode !== void 0 ? { approvalMode } : {}
19253
+ ...approvalMode !== void 0 ? { approvalMode } : {},
19254
+ ...source.sourceType !== void 0 ? { sourceType: source.sourceType } : {},
19255
+ ...source.sourceId !== void 0 ? { sourceId: source.sourceId } : {}
18771
19256
  });
18772
19257
  if (daemonLog) {
18773
19258
  daemonLog.info(
@@ -18786,8 +19271,17 @@ function registerSessionRoutes(app, deps) {
18786
19271
  );
18787
19272
  }
18788
19273
  if (!session.attached) {
18789
- runtime.bridge.killSession(session.sessionId, { requireZeroAttaches: true }).catch(() => {
18790
- });
19274
+ try {
19275
+ const killed = await runtime.bridge.killSession(session.sessionId, {
19276
+ requireZeroAttaches: true
19277
+ });
19278
+ if (killed) {
19279
+ await new SessionService(runtime.workspaceCwd).removeSession(
19280
+ session.sessionId
19281
+ );
19282
+ }
19283
+ } catch {
19284
+ }
18791
19285
  } else {
18792
19286
  runtime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
18793
19287
  });
@@ -18840,22 +19334,22 @@ function registerSessionRoutes(app, deps) {
18840
19334
  [sessionId],
18841
19335
  async () => {
18842
19336
  await assertSessionLoadable(workspaceCwd, sessionId);
18843
- const parentSessionId = await new SessionService(
19337
+ const metadata = await new SessionService(
18844
19338
  workspaceCwd
18845
- ).readParentSessionId(sessionId);
19339
+ ).readCreationMetadata(sessionId);
18846
19340
  return action === "load" ? await runtime.bridge.loadSession({
18847
19341
  sessionId,
18848
19342
  workspaceCwd,
18849
19343
  historyReplay: "response",
18850
19344
  ...clientId !== void 0 ? { clientId } : {},
18851
19345
  ...approvalMode !== void 0 ? { approvalMode } : {},
18852
- ...parentSessionId !== void 0 ? { parentSessionId } : {}
19346
+ ...metadata
18853
19347
  }) : await runtime.bridge.resumeSession({
18854
19348
  sessionId,
18855
19349
  workspaceCwd,
18856
19350
  ...clientId !== void 0 ? { clientId } : {},
18857
19351
  ...approvalMode !== void 0 ? { approvalMode } : {},
18858
- ...parentSessionId !== void 0 ? { parentSessionId } : {}
19352
+ ...metadata
18859
19353
  });
18860
19354
  }
18861
19355
  );
@@ -18890,7 +19384,7 @@ function registerSessionRoutes(app, deps) {
18890
19384
  app.post(
18891
19385
  "/session/:id/branch",
18892
19386
  mutate(),
18893
- withMutableSession(
19387
+ withPrimaryOnlyMutableSession(
18894
19388
  "POST /session/:id/branch",
18895
19389
  async (req, res, sessionId) => {
18896
19390
  const body = safeBody(req);
@@ -18925,7 +19419,7 @@ function registerSessionRoutes(app, deps) {
18925
19419
  app.post(
18926
19420
  "/session/:id/fork",
18927
19421
  mutate(),
18928
- withMutableSession(
19422
+ withPrimaryOnlyMutableSession(
18929
19423
  "POST /session/:id/fork",
18930
19424
  async (req, res, sessionId) => {
18931
19425
  const body = safeBody(req);
@@ -18951,25 +19445,28 @@ function registerSessionRoutes(app, deps) {
18951
19445
  app.post(
18952
19446
  "/session/:id/cd",
18953
19447
  mutate(),
18954
- withMutableSession("POST /session/:id/cd", async (req, res, sessionId) => {
18955
- const body = safeBody(req);
18956
- const targetPath = body["path"];
18957
- if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
18958
- res.status(400).json({
18959
- error: "`path` is required and must be an absolute path",
18960
- code: "invalid_path"
18961
- });
18962
- return;
19448
+ withPrimaryOnlyMutableSession(
19449
+ "POST /session/:id/cd",
19450
+ async (req, res, sessionId) => {
19451
+ const body = safeBody(req);
19452
+ const targetPath = body["path"];
19453
+ if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
19454
+ res.status(400).json({
19455
+ error: "`path` is required and must be an absolute path",
19456
+ code: "invalid_path"
19457
+ });
19458
+ return;
19459
+ }
19460
+ const clientId = parseClientIdHeader(req, res);
19461
+ if (clientId === null) return;
19462
+ const result = await bridge.changeSessionCwd(
19463
+ sessionId,
19464
+ { path: targetPath },
19465
+ clientId !== void 0 ? { clientId } : void 0
19466
+ );
19467
+ res.status(200).json(result);
18963
19468
  }
18964
- const clientId = parseClientIdHeader(req, res);
18965
- if (clientId === null) return;
18966
- const result = await bridge.changeSessionCwd(
18967
- sessionId,
18968
- { path: targetPath },
18969
- clientId !== void 0 ? { clientId } : void 0
18970
- );
18971
- res.status(200).json(result);
18972
- })
19469
+ )
18973
19470
  );
18974
19471
  app.get("/session/:id/status", (req, res) => {
18975
19472
  const sessionId = requireSessionId(req, res);
@@ -19005,6 +19502,20 @@ function registerSessionRoutes(app, deps) {
19005
19502
  workspaceQualified: true
19006
19503
  });
19007
19504
  });
19505
+ app.get(
19506
+ "/workspaces/:workspace/session/:id/archive/export",
19507
+ async (req, res) => {
19508
+ const route = "GET /workspaces/:workspace/session/:id/archive/export";
19509
+ const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
19510
+ if (!runtime) return;
19511
+ await handleSessionExport(req, res, {
19512
+ route,
19513
+ workspaceCwd: runtime.workspaceCwd,
19514
+ workspaceQualified: true,
19515
+ archiveState: "archived"
19516
+ });
19517
+ }
19518
+ );
19008
19519
  app.get("/session/:id/transcript", async (req, res) => {
19009
19520
  const route = "GET /session/:id/transcript";
19010
19521
  const sessionId = requireSessionId(req, res);
@@ -19348,7 +19859,7 @@ function registerSessionRoutes(app, deps) {
19348
19859
  async (req, res, sessionId, runtime) => {
19349
19860
  const clientId = parseClientIdHeader(req, res);
19350
19861
  if (clientId === null) return;
19351
- const promptId = crypto2.randomUUID();
19862
+ const promptId = crypto3.randomUUID();
19352
19863
  res.status(200).json(
19353
19864
  await runtime.bridge.continueSession(sessionId, {
19354
19865
  ...clientId !== void 0 ? { clientId } : {},
@@ -19395,7 +19906,7 @@ function registerSessionRoutes(app, deps) {
19395
19906
  }
19396
19907
  const clientId = parseClientIdHeader(req, res);
19397
19908
  if (clientId === null) return;
19398
- const promptId = crypto2.randomUUID();
19909
+ const promptId = crypto3.randomUUID();
19399
19910
  const forwardedBody = { ...body };
19400
19911
  delete forwardedBody["deadlineMs"];
19401
19912
  const lastEventId = ownerBridge.getSessionLastEventId(sessionId);
@@ -19496,6 +20007,88 @@ function registerSessionRoutes(app, deps) {
19496
20007
  }
19497
20008
  )
19498
20009
  );
20010
+ app.post(
20011
+ "/session/:id/generate",
20012
+ mutate(),
20013
+ withOwnerReadSession(
20014
+ "POST /session/:id/generate",
20015
+ async (req, res, sessionId, runtime) => {
20016
+ const body = safeBody(req);
20017
+ const prompt = body["prompt"];
20018
+ if (typeof prompt !== "string" || prompt.trim().length === 0 || Buffer.byteLength(prompt, "utf8") > GENERATION_MAX_PROMPT_BYTES) {
20019
+ res.status(400).json({
20020
+ error: `\`prompt\` must be a non-empty string no larger than ${GENERATION_MAX_PROMPT_BYTES} UTF-8 bytes`,
20021
+ code: "invalid_prompt"
20022
+ });
20023
+ return;
20024
+ }
20025
+ const clientId = parseClientIdHeader(req, res);
20026
+ if (clientId === null) return;
20027
+ if (!runtime.bridge.generateSessionContent) {
20028
+ res.status(501).json({
20029
+ error: "Stateless generation is not supported by this bridge",
20030
+ code: "generation_not_supported"
20031
+ });
20032
+ return;
20033
+ }
20034
+ const abort = new AbortController();
20035
+ let completed = false;
20036
+ const onClose = /* @__PURE__ */ __name(() => {
20037
+ if (!completed) abort.abort();
20038
+ }, "onClose");
20039
+ res.once("close", onClose);
20040
+ const stream = runtime.bridge.generateSessionContent(
20041
+ sessionId,
20042
+ prompt,
20043
+ abort.signal,
20044
+ clientId !== void 0 ? { clientId } : void 0
20045
+ );
20046
+ res.status(200);
20047
+ res.setHeader("Content-Type", "text/event-stream");
20048
+ res.setHeader("Cache-Control", "no-cache, no-transform");
20049
+ res.setHeader("Connection", "keep-alive");
20050
+ res.setHeader("X-Accel-Buffering", "no");
20051
+ res.flushHeaders();
20052
+ let writeChain = Promise.resolve();
20053
+ const write = /* @__PURE__ */ __name((chunk) => {
20054
+ writeChain = writeChain.then(
20055
+ () => writeGenerationSseChunk(res, chunk)
20056
+ );
20057
+ return writeChain;
20058
+ }, "write");
20059
+ await write(": connected\n\n");
20060
+ const heartbeat = setInterval(() => {
20061
+ void write(": heartbeat\n\n").catch(() => abort.abort());
20062
+ }, GENERATION_HEARTBEAT_MS);
20063
+ heartbeat.unref();
20064
+ try {
20065
+ for await (const event of stream) {
20066
+ await write(formatGenerationSse(event.type, event));
20067
+ }
20068
+ } catch (err) {
20069
+ if (!abort.signal.aborted && !res.destroyed) {
20070
+ daemonLog?.error(
20071
+ "session generation failed",
20072
+ err instanceof Error ? err : new Error(String(err)),
20073
+ { sessionId, clientId }
20074
+ );
20075
+ await write(
20076
+ formatGenerationSse("error", {
20077
+ type: "error",
20078
+ code: "generation_failed",
20079
+ message: "Generation failed"
20080
+ })
20081
+ ).catch(() => void 0);
20082
+ }
20083
+ } finally {
20084
+ completed = true;
20085
+ clearInterval(heartbeat);
20086
+ res.off("close", onClose);
20087
+ if (!res.destroyed) res.end();
20088
+ }
20089
+ }
20090
+ )
20091
+ );
19499
20092
  app.post(
19500
20093
  "/session/:id/heartbeat",
19501
20094
  mutate(),
@@ -20064,16 +20657,28 @@ function registerSessionRoutes(app, deps) {
20064
20657
  }
20065
20658
  parentSessionId = rawParentSessionId;
20066
20659
  }
20660
+ const parsedSource = parseSessionSource(
20661
+ req.query["sourceType"],
20662
+ req.query["sourceId"]
20663
+ );
20664
+ if ("error" in parsedSource) {
20665
+ res.status(400).json({
20666
+ error: parsedSource.error,
20667
+ code: "invalid_session_source"
20668
+ });
20669
+ return;
20670
+ }
20067
20671
  const options = {
20068
20672
  ...cursor !== void 0 ? { cursor } : {},
20069
20673
  ...size !== void 0 ? { size } : {},
20070
20674
  ...archiveState !== void 0 ? { archiveState } : {},
20071
20675
  ...view !== void 0 ? { view } : {},
20072
20676
  ...group !== void 0 ? { group } : {},
20073
- ...parentSessionId !== void 0 ? { parentSessionId } : {}
20677
+ ...parentSessionId !== void 0 ? { parentSessionId } : {},
20678
+ ...parsedSource
20074
20679
  };
20075
- const usePersisted = readOnlySecondary || runtime.primary || view === "organized" || archiveState === "archived" || parentSessionId !== void 0 || (cursor !== void 0 && cursor !== "" ? isNumericSessionCursor(cursor) : await hasActivePersistedSessions(key));
20076
- if (!usePersisted && (view !== void 0 || archiveState === "archived")) {
20680
+ const usePersisted = readOnlySecondary || runtime.primary || view === "organized" || archiveState === "archived" || parentSessionId !== void 0 || parsedSource.sourceType !== void 0 || (cursor !== void 0 && cursor !== "" ? isNumericSessionCursor(cursor) : await hasActivePersistedSessions(key));
20681
+ if (!usePersisted && (view !== void 0 || archiveState === "archived" || parentSessionId !== void 0 || parsedSource.sourceType !== void 0)) {
20077
20682
  throw new Error(
20078
20683
  "session list live path received persisted-only options"
20079
20684
  );
@@ -20672,6 +21277,7 @@ function registerScheduledTaskCrudRoutes(app, deps) {
20672
21277
  }
20673
21278
  const recurring = body["recurring"] !== false;
20674
21279
  const enabled = body["enabled"] !== false;
21280
+ const taskId = generateCronTaskId();
20675
21281
  let boundSessionId;
20676
21282
  if (bridge) {
20677
21283
  try {
@@ -20687,7 +21293,9 @@ function registerScheduledTaskCrudRoutes(app, deps) {
20687
21293
  try {
20688
21294
  const session = await bridge.spawnOrAttach({
20689
21295
  workspaceCwd,
20690
- sessionScope: "thread"
21296
+ sessionScope: "thread",
21297
+ sourceType: "scheduled_task",
21298
+ sourceId: taskId
20691
21299
  });
20692
21300
  boundSessionId = session.sessionId;
20693
21301
  try {
@@ -20709,7 +21317,7 @@ function registerScheduledTaskCrudRoutes(app, deps) {
20709
21317
  }
20710
21318
  const now = Date.now();
20711
21319
  const task = {
20712
- id: generateCronTaskId(),
21320
+ id: taskId,
20713
21321
  cron,
20714
21322
  prompt,
20715
21323
  recurring,
@@ -21192,7 +21800,9 @@ async function bindAndNameSessions(bridge, boundWorkspace, tasks, renamed, spawn
21192
21800
  binding.add(task.id);
21193
21801
  const rawSpawn = bridge.spawnOrAttach({
21194
21802
  workspaceCwd: boundWorkspace,
21195
- sessionScope: "thread"
21803
+ sessionScope: "thread",
21804
+ sourceType: "scheduled_task",
21805
+ sourceId: task.id
21196
21806
  });
21197
21807
  let timedOut = false;
21198
21808
  rawSpawn.then(({ sessionId: sessionId2 }) => {
@@ -21301,12 +21911,16 @@ function startScheduledTaskKeepalive(opts) {
21301
21911
  continue;
21302
21912
  }
21303
21913
  log.debug("keepalive: recordHeartbeat failed for", sessionId, err);
21914
+ reviving.add(sessionId);
21915
+ const metadata = await new SessionService(
21916
+ boundWorkspace
21917
+ ).readCreationMetadata(sessionId);
21304
21918
  const load = bridge.loadSession({
21305
21919
  sessionId,
21306
21920
  workspaceCwd: boundWorkspace,
21307
- historyReplay: "response"
21921
+ historyReplay: "response",
21922
+ ...metadata
21308
21923
  });
21309
- reviving.add(sessionId);
21310
21924
  void load.catch(() => {
21311
21925
  }).finally(() => {
21312
21926
  reviving.delete(sessionId);
@@ -21417,10 +22031,14 @@ async function rehydrateScheduledTaskSessions(deps) {
21417
22031
  const loaded = [];
21418
22032
  const failed = [];
21419
22033
  const loadOne = /* @__PURE__ */ __name(async (sessionId) => {
22034
+ const metadata = await new SessionService(
22035
+ boundWorkspace
22036
+ ).readCreationMetadata(sessionId);
21420
22037
  const load = bridge.loadSession({
21421
22038
  sessionId,
21422
22039
  workspaceCwd: boundWorkspace,
21423
- historyReplay: "response"
22040
+ historyReplay: "response",
22041
+ ...metadata
21424
22042
  });
21425
22043
  void load.catch(() => {
21426
22044
  });
@@ -21767,6 +22385,7 @@ function createServeFeatures(deps) {
21767
22385
  boundWorkspace,
21768
22386
  persistSettingAvailable,
21769
22387
  sessionArtifactsPersistenceAvailable,
22388
+ sessionGenerationAvailable,
21770
22389
  reloadAvailable,
21771
22390
  channelReloadAvailable,
21772
22391
  channelControlAvailable,
@@ -21800,6 +22419,7 @@ function createServeFeatures(deps) {
21800
22419
  persistSettingAvailable,
21801
22420
  sessionShellCommandEnabled,
21802
22421
  sessionArtifactsPersistenceAvailable,
22422
+ sessionGenerationAvailable: sessionGenerationAvailable(),
21803
22423
  rateLimit: opts.rateLimit === true,
21804
22424
  reloadAvailable,
21805
22425
  channelReloadAvailable: channelReloadAvailable(),
@@ -22089,6 +22709,7 @@ init_esbuild_shims();
22089
22709
  var TUI_ONLY_SETTINGS = /* @__PURE__ */ new Set([
22090
22710
  "general.vimMode",
22091
22711
  "general.terminalBell",
22712
+ "general.notificationMode",
22092
22713
  "general.preferredEditor",
22093
22714
  "general.outputLanguage",
22094
22715
  "ide.enabled",
@@ -22099,9 +22720,14 @@ var TUI_ONLY_SETTINGS = /* @__PURE__ */ new Set([
22099
22720
  "ui.accessibility.enableLoadingPhrases",
22100
22721
  "ui.enableWelcomeBack"
22101
22722
  ]);
22102
- var WEB_SHELL_SETTINGS = /* @__PURE__ */ new Set(["ui.compactMode", "voiceModel"]);
22723
+ var WEB_SHELL_SETTINGS = /* @__PURE__ */ new Set([
22724
+ "ui.compactMode",
22725
+ "voiceModel",
22726
+ "mcpServers"
22727
+ ]);
22103
22728
  var VALID_WRITE_SCOPES = /* @__PURE__ */ new Set(["workspace", "user"]);
22104
22729
  var QUALIFIED_WRITE_SCOPES = /* @__PURE__ */ new Set(["workspace"]);
22730
+ var mcpServerMutationQueues = /* @__PURE__ */ new Map();
22105
22731
  var SECURITY_SENSITIVE_SETTINGS = /* @__PURE__ */ new Set(["tools.approvalMode"]);
22106
22732
  function getAllowedKeys() {
22107
22733
  const keys = new Set(
@@ -22133,11 +22759,12 @@ function buildSettingsResponse(boundWorkspace, keys) {
22133
22759
  loaded.workspace.settings,
22134
22760
  key
22135
22761
  );
22762
+ const publicValue = /* @__PURE__ */ __name((value) => key === "mcpServers" ? redactMcpServersSetting(value) : value, "publicValue");
22136
22763
  const values = {
22137
- effective: effective !== void 0 ? effective : def.default
22764
+ effective: publicValue(effective !== void 0 ? effective : def.default)
22138
22765
  };
22139
- if (userVal !== void 0) values.user = userVal;
22140
- if (wsVal !== void 0) values.workspace = wsVal;
22766
+ if (userVal !== void 0) values.user = publicValue(userVal);
22767
+ if (wsVal !== void 0) values.workspace = publicValue(wsVal);
22141
22768
  settings.push({
22142
22769
  key,
22143
22770
  type: def.type,
@@ -22165,9 +22792,62 @@ function buildSettingsResponse(boundWorkspace, keys) {
22165
22792
  }
22166
22793
  __name(buildSettingsResponse, "buildSettingsResponse");
22167
22794
  var SCOPE_MAP = {
22168
- workspace: "Workspace" /* Workspace */,
22169
- user: "User" /* User */
22795
+ user: "User" /* User */,
22796
+ workspace: "Workspace" /* Workspace */
22170
22797
  };
22798
+ function prepareSettingWrite(workspace, scope, key, value, mcpServerMutation) {
22799
+ if (key !== "mcpServers") {
22800
+ return { persistedValue: value, publicValue: value };
22801
+ }
22802
+ const existing = loadSettings(workspace).forScope(scope).settings.mcpServers ?? {};
22803
+ let nextValue = value;
22804
+ if (mcpServerMutation) {
22805
+ const servers = { ...existing };
22806
+ if (mcpServerMutation.operation === "set") {
22807
+ servers[mcpServerMutation.name] = value;
22808
+ } else {
22809
+ delete servers[mcpServerMutation.name];
22810
+ }
22811
+ nextValue = servers;
22812
+ }
22813
+ const persistedValue = restoreRedactedMcpServersSetting(nextValue, existing);
22814
+ return {
22815
+ persistedValue,
22816
+ publicValue: redactMcpServersSetting(persistedValue)
22817
+ };
22818
+ }
22819
+ __name(prepareSettingWrite, "prepareSettingWrite");
22820
+ function parseMcpServerMutation(key, value) {
22821
+ if (value === void 0) return void 0;
22822
+ if (key !== "mcpServers" || typeof value !== "object" || value === null) {
22823
+ throw new Error("mcpServerMutation is only valid for mcpServers");
22824
+ }
22825
+ const operation = value["operation"];
22826
+ const name = value["name"];
22827
+ if (operation !== "set" && operation !== "remove" || typeof name !== "string" || !name.trim()) {
22828
+ throw new Error("mcpServerMutation requires a valid operation and name");
22829
+ }
22830
+ return { operation, name };
22831
+ }
22832
+ __name(parseMcpServerMutation, "parseMcpServerMutation");
22833
+ async function withMcpServerMutationLock(workspace, scope, operation) {
22834
+ const key = `${workspace}\0${scope}`;
22835
+ const previous = mcpServerMutationQueues.get(key) ?? Promise.resolve();
22836
+ const run = previous.catch(() => void 0).then(operation);
22837
+ const tail = run.then(
22838
+ () => void 0,
22839
+ () => void 0
22840
+ );
22841
+ mcpServerMutationQueues.set(key, tail);
22842
+ try {
22843
+ return await run;
22844
+ } finally {
22845
+ if (mcpServerMutationQueues.get(key) === tail) {
22846
+ mcpServerMutationQueues.delete(key);
22847
+ }
22848
+ }
22849
+ }
22850
+ __name(withMcpServerMutationLock, "withMcpServerMutationLock");
22171
22851
  function registerWorkspaceSettingsRoutes(app, deps) {
22172
22852
  const {
22173
22853
  boundWorkspace,
@@ -22200,6 +22880,19 @@ function registerWorkspaceSettingsRoutes(app, deps) {
22200
22880
  const scope = body["scope"];
22201
22881
  const key = body["key"];
22202
22882
  const value = body["value"];
22883
+ let mcpServerMutation;
22884
+ try {
22885
+ mcpServerMutation = parseMcpServerMutation(
22886
+ typeof key === "string" ? key : "",
22887
+ body["mcpServerMutation"]
22888
+ );
22889
+ } catch (error2) {
22890
+ res.status(400).json({
22891
+ error: error2 instanceof Error ? error2.message : String(error2),
22892
+ code: "invalid_mcp_server_mutation"
22893
+ });
22894
+ return;
22895
+ }
22203
22896
  if (typeof scope !== "string" || !VALID_WRITE_SCOPES.has(scope)) {
22204
22897
  res.status(400).json({
22205
22898
  error: `scope must be one of: ${[...VALID_WRITE_SCOPES].join(", ")}`,
@@ -22246,16 +22939,41 @@ function registerWorkspaceSettingsRoutes(app, deps) {
22246
22939
  }
22247
22940
  const clientId = parseAndValidateClientId(req, res);
22248
22941
  if (clientId === null) return;
22942
+ const settingScope = SCOPE_MAP[scope];
22943
+ if (!settingScope) {
22944
+ res.status(400).json({
22945
+ error: `scope must be one of: ${[...VALID_WRITE_SCOPES].join(", ")}`,
22946
+ code: "invalid_scope"
22947
+ });
22948
+ return;
22949
+ }
22950
+ let publicValue = value;
22249
22951
  try {
22250
- const settingScope = SCOPE_MAP[scope];
22251
- if (!settingScope) {
22252
- res.status(400).json({
22253
- error: `scope must be one of: ${[...VALID_WRITE_SCOPES].join(", ")}`,
22254
- code: "invalid_scope"
22255
- });
22256
- return;
22952
+ const persist = /* @__PURE__ */ __name(async () => {
22953
+ const prepared = prepareSettingWrite(
22954
+ boundWorkspace,
22955
+ settingScope,
22956
+ key,
22957
+ value,
22958
+ mcpServerMutation
22959
+ );
22960
+ publicValue = prepared.publicValue;
22961
+ await persistSetting(
22962
+ boundWorkspace,
22963
+ settingScope,
22964
+ key,
22965
+ prepared.persistedValue
22966
+ );
22967
+ }, "persist");
22968
+ if (mcpServerMutation) {
22969
+ await withMcpServerMutationLock(
22970
+ boundWorkspace,
22971
+ settingScope,
22972
+ persist
22973
+ );
22974
+ } else {
22975
+ await persist();
22257
22976
  }
22258
- await persistSetting(boundWorkspace, settingScope, key, value);
22259
22977
  } catch (err) {
22260
22978
  writeStderrLine(
22261
22979
  `qwen serve: POST /workspace/settings persist error (key=${key}, scope=${scope}, workspace=${boundWorkspace}): ${err instanceof Error ? err.message : String(err)}`
@@ -22267,7 +22985,7 @@ function registerWorkspaceSettingsRoutes(app, deps) {
22267
22985
  return;
22268
22986
  }
22269
22987
  try {
22270
- broadcastSettingsChanged(key, value, scope, clientId);
22988
+ broadcastSettingsChanged(key, publicValue, scope, clientId);
22271
22989
  } catch (err) {
22272
22990
  writeStderrLine(
22273
22991
  `qwen serve: POST /workspace/settings broadcast error (key=${key}, scope=${scope}): ${err instanceof Error ? err.message : String(err)}`
@@ -22276,7 +22994,7 @@ function registerWorkspaceSettingsRoutes(app, deps) {
22276
22994
  res.status(200).json({
22277
22995
  key,
22278
22996
  scope,
22279
- value,
22997
+ value: publicValue,
22280
22998
  requiresRestart: def.requiresRestart
22281
22999
  });
22282
23000
  }
@@ -22319,6 +23037,19 @@ function registerWorkspaceQualifiedSettingsRoutes(app, deps) {
22319
23037
  const scope = body["scope"];
22320
23038
  const key = body["key"];
22321
23039
  const value = body["value"];
23040
+ let mcpServerMutation;
23041
+ try {
23042
+ mcpServerMutation = parseMcpServerMutation(
23043
+ typeof key === "string" ? key : "",
23044
+ body["mcpServerMutation"]
23045
+ );
23046
+ } catch (error2) {
23047
+ res.status(400).json({
23048
+ error: error2 instanceof Error ? error2.message : String(error2),
23049
+ code: "invalid_mcp_server_mutation"
23050
+ });
23051
+ return;
23052
+ }
22322
23053
  if (typeof scope !== "string" || !QUALIFIED_WRITE_SCOPES.has(scope)) {
22323
23054
  res.status(400).json({
22324
23055
  error: `scope must be one of: ${[...QUALIFIED_WRITE_SCOPES].join(", ")}`,
@@ -22377,13 +23108,33 @@ function registerWorkspaceQualifiedSettingsRoutes(app, deps) {
22377
23108
  });
22378
23109
  return;
22379
23110
  }
23111
+ let publicValue = value;
22380
23112
  try {
22381
- await deps.persistSetting(
22382
- runtime.workspaceCwd,
22383
- settingScope,
22384
- key,
22385
- value
22386
- );
23113
+ const persist = /* @__PURE__ */ __name(async () => {
23114
+ const prepared = prepareSettingWrite(
23115
+ runtime.workspaceCwd,
23116
+ settingScope,
23117
+ key,
23118
+ value,
23119
+ mcpServerMutation
23120
+ );
23121
+ publicValue = prepared.publicValue;
23122
+ await deps.persistSetting(
23123
+ runtime.workspaceCwd,
23124
+ settingScope,
23125
+ key,
23126
+ prepared.persistedValue
23127
+ );
23128
+ }, "persist");
23129
+ if (mcpServerMutation) {
23130
+ await withMcpServerMutationLock(
23131
+ runtime.workspaceCwd,
23132
+ settingScope,
23133
+ persist
23134
+ );
23135
+ } else {
23136
+ await persist();
23137
+ }
22387
23138
  } catch (err) {
22388
23139
  writeStderrLine(
22389
23140
  `qwen serve: POST /workspaces/:workspace/settings persist error (key=${key}, scope=${scope}, workspace=${runtime.workspaceCwd}): ${err instanceof Error ? err.message : String(err)}`
@@ -22397,13 +23148,13 @@ function registerWorkspaceQualifiedSettingsRoutes(app, deps) {
22397
23148
  deps.invalidateServeFeaturesCache();
22398
23149
  runtime.bridge.publishWorkspaceEvent({
22399
23150
  type: "settings_changed",
22400
- data: { key, value, scope },
23151
+ data: { key, value: publicValue, scope },
22401
23152
  ...clientId ? { originatorClientId: clientId } : {}
22402
23153
  });
22403
23154
  res.status(200).json({
22404
23155
  key,
22405
23156
  scope,
22406
- value,
23157
+ value: publicValue,
22407
23158
  requiresRestart: def.requiresRestart
22408
23159
  });
22409
23160
  }
@@ -22621,6 +23372,14 @@ function sendBridgeError(res, err, ctx, daemonLog) {
22621
23372
  });
22622
23373
  return;
22623
23374
  }
23375
+ if (err instanceof SessionNotArchivedError) {
23376
+ res.status(409).json({
23377
+ error: err.message,
23378
+ code: "session_not_archived",
23379
+ sessionId: err.sessionId
23380
+ });
23381
+ return;
23382
+ }
22624
23383
  if (err instanceof SessionConflictError) {
22625
23384
  res.status(409).json({
22626
23385
  error: err.message,
@@ -22674,7 +23433,7 @@ function sendBridgeError(res, err, ctx, daemonLog) {
22674
23433
  }
22675
23434
  if (err instanceof WorkspaceMismatchError) {
22676
23435
  writeStderrLine(
22677
- `qwen serve: workspace_mismatch (POST /session): daemon bound to ${JSON.stringify(err.bound)}, rejected ${JSON.stringify(err.requested)}`
23436
+ `qwen serve: workspace_mismatch (POST /session): runtime bound to ${JSON.stringify(err.bound)}, rejected ${JSON.stringify(err.requested)}`
22678
23437
  );
22679
23438
  res.status(400).json({
22680
23439
  error: err.message,
@@ -23774,6 +24533,15 @@ function resolveDaemonTelemetryRoute(req) {
23774
24533
  sessionId: workspaceExport[1]
23775
24534
  };
23776
24535
  }
24536
+ const workspaceArchivedExport = path15.match(
24537
+ /^\/workspaces\/[^/]+\/session\/([^/]+)\/archive\/export$/
24538
+ );
24539
+ if (workspaceArchivedExport?.[1] && req.method === "GET") {
24540
+ return {
24541
+ route: "GET /workspaces/:workspace/session/:id/archive/export",
24542
+ sessionId: workspaceArchivedExport[1]
24543
+ };
24544
+ }
23777
24545
  const pluralWorkspacePrefix = /^\/workspaces\/[^/]+/;
23778
24546
  if (pluralWorkspacePrefix.test(path15)) {
23779
24547
  const suffix = path15.replace(pluralWorkspacePrefix, "/workspace");
@@ -23811,7 +24579,7 @@ function resolveDaemonTelemetryRoute(req) {
23811
24579
  if (/^\/workspace\/agents\/[^/]+$/.test(suffix)) {
23812
24580
  return { route: "POST /workspace/agents/:agentType" };
23813
24581
  }
23814
- if (/^\/workspace\/mcp\/[^/]+\/(enable|disable|authenticate|clear-auth)$/.test(
24582
+ if (/^\/workspace\/mcp\/[^/]+\/(approve|enable|disable|authenticate|clear-auth)$/.test(
23815
24583
  suffix
23816
24584
  )) {
23817
24585
  return {
@@ -23913,7 +24681,8 @@ function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest, resolveSe
23913
24681
  const workspaceHash = resolveWorkspaceHash(workspaceCwd);
23914
24682
  const rawClientId = req.get(CLIENT_ID_HEADER);
23915
24683
  const clientId = rawClientId !== void 0 && rawClientId !== "" && rawClientId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawClientId) ? rawClientId : void 0;
23916
- const startMs = Date.now();
24684
+ const deferredRuntime = getDeferredRuntimeRequestTiming(req);
24685
+ const startMs = deferredRuntime?.startedAt.getTime() ?? Date.now();
23917
24686
  void withDaemonRequestSpan(
23918
24687
  {
23919
24688
  method: req.method,
@@ -23921,7 +24690,12 @@ function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest, resolveSe
23921
24690
  workspaceHash,
23922
24691
  ...sessionId ? { sessionId } : {},
23923
24692
  ...route.permissionRequestId ? { permissionRequestId: route.permissionRequestId } : {},
23924
- ...clientId ? { clientId } : {}
24693
+ ...clientId ? { clientId } : {},
24694
+ ...deferredRuntime?.waitMs !== void 0 ? {
24695
+ startTime: deferredRuntime.startedAt,
24696
+ deferredRuntimeWaitMs: deferredRuntime.waitMs,
24697
+ deferredRuntimePath: deferredRuntime.path
24698
+ } : {}
23925
24699
  },
23926
24700
  async (span) => await new Promise((resolve5, reject) => {
23927
24701
  let done = false;
@@ -23930,7 +24704,12 @@ function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest, resolveSe
23930
24704
  done = true;
23931
24705
  recordDaemonHttpResponse(span, res.statusCode);
23932
24706
  const durationMs = Date.now() - startMs;
23933
- recordDaemonHttpRequest(durationMs, route.route, res.statusCode);
24707
+ recordDaemonHttpRequest(
24708
+ durationMs,
24709
+ route.route,
24710
+ res.statusCode,
24711
+ deferredRuntime?.path
24712
+ );
23934
24713
  if (route.route !== "GET /daemon/status") {
23935
24714
  recordRequest?.(durationMs, res.statusCode);
23936
24715
  }
@@ -25330,6 +26109,30 @@ function registerWorkspaceMcpControlRoutes(app, deps) {
25330
26109
  parseAndValidateClientId
25331
26110
  } = deps;
25332
26111
  const buildWorkspaceCtx = createBuildWorkspaceCtx(boundWorkspace);
26112
+ app.post(
26113
+ "/workspace/mcp/initialize",
26114
+ mutate({ strict: true }),
26115
+ async (_req, res) => {
26116
+ try {
26117
+ const result = await bridge.initializeWorkspaceMcp();
26118
+ res.status(202).json(result);
26119
+ } catch (err) {
26120
+ sendBridgeError2(res, err, { route: "POST /workspace/mcp/initialize" });
26121
+ }
26122
+ }
26123
+ );
26124
+ app.post(
26125
+ "/workspace/mcp/reload",
26126
+ mutate({ strict: true }),
26127
+ async (_req, res) => {
26128
+ try {
26129
+ const result = await bridge.reloadWorkspaceMcp();
26130
+ res.status(202).json(result);
26131
+ } catch (err) {
26132
+ sendBridgeError2(res, err, { route: "POST /workspace/mcp/reload" });
26133
+ }
26134
+ }
26135
+ );
25333
26136
  app.post(
25334
26137
  "/workspace/mcp/:server/restart",
25335
26138
  mutate({ strict: true }),
@@ -25384,6 +26187,7 @@ function registerWorkspaceMcpControlRoutes(app, deps) {
25384
26187
  }
25385
26188
  );
25386
26189
  for (const [routeAction, bridgeAction] of [
26190
+ ["approve", "approve"],
25387
26191
  ["enable", "enable"],
25388
26192
  ["disable", "disable"],
25389
26193
  ["authenticate", "authenticate"],
@@ -25498,6 +26302,44 @@ function resolveTrustedMcpRuntime(registry, req, res) {
25498
26302
  }
25499
26303
  __name(resolveTrustedMcpRuntime, "resolveTrustedMcpRuntime");
25500
26304
  function registerWorkspaceQualifiedMcpControlRoutes(app, deps) {
26305
+ app.post(
26306
+ "/workspaces/:workspace/mcp/initialize",
26307
+ deps.mutate({ strict: true }),
26308
+ async (req, res) => {
26309
+ const runtime = resolveTrustedMcpRuntime(
26310
+ deps.workspaceRegistry,
26311
+ req,
26312
+ res
26313
+ );
26314
+ if (!runtime) return;
26315
+ const route = "POST /workspaces/:workspace/mcp/initialize";
26316
+ try {
26317
+ const result = await runtime.bridge.initializeWorkspaceMcp();
26318
+ res.status(202).json(result);
26319
+ } catch (err) {
26320
+ deps.sendBridgeError(res, err, { route });
26321
+ }
26322
+ }
26323
+ );
26324
+ app.post(
26325
+ "/workspaces/:workspace/mcp/reload",
26326
+ deps.mutate({ strict: true }),
26327
+ async (req, res) => {
26328
+ const runtime = resolveTrustedMcpRuntime(
26329
+ deps.workspaceRegistry,
26330
+ req,
26331
+ res
26332
+ );
26333
+ if (!runtime) return;
26334
+ const route = "POST /workspaces/:workspace/mcp/reload";
26335
+ try {
26336
+ const result = await runtime.bridge.reloadWorkspaceMcp();
26337
+ res.status(202).json(result);
26338
+ } catch (err) {
26339
+ deps.sendBridgeError(res, err, { route });
26340
+ }
26341
+ }
26342
+ );
25501
26343
  app.post(
25502
26344
  "/workspaces/:workspace/mcp/:server/restart",
25503
26345
  deps.mutate({ strict: true }),
@@ -25561,6 +26403,7 @@ function registerWorkspaceQualifiedMcpControlRoutes(app, deps) {
25561
26403
  }
25562
26404
  );
25563
26405
  for (const [routeAction, bridgeAction] of [
26406
+ ["approve", "approve"],
25564
26407
  ["enable", "enable"],
25565
26408
  ["disable", "disable"],
25566
26409
  ["authenticate", "authenticate"],
@@ -25752,11 +26595,84 @@ function parseSelection(body, res) {
25752
26595
  }
25753
26596
  }
25754
26597
  __name(parseSelection, "parseSelection");
26598
+ function sanitizeControlDiagnostic(value, maxLength) {
26599
+ return sanitizeLogText(
26600
+ redactLogCredentials(normalizeWorkerDiagnostic(value)),
26601
+ maxLength
26602
+ );
26603
+ }
26604
+ __name(sanitizeControlDiagnostic, "sanitizeControlDiagnostic");
26605
+ function startupFailureResponseFields(error2) {
26606
+ if (!error2 || typeof error2 !== "object") return {};
26607
+ let rawFailures;
26608
+ let rawTruncated;
26609
+ try {
26610
+ rawFailures = Reflect.get(error2, "startupFailures");
26611
+ rawTruncated = Reflect.get(error2, "startupFailuresTruncated");
26612
+ } catch {
26613
+ return {};
26614
+ }
26615
+ if (!Array.isArray(rawFailures)) return {};
26616
+ let limitedFailures;
26617
+ let rawFailureCount;
26618
+ try {
26619
+ limitedFailures = rawFailures.slice(0, MAX_CHANNEL_STARTUP_FAILURES);
26620
+ rawFailureCount = rawFailures.length;
26621
+ } catch {
26622
+ return {};
26623
+ }
26624
+ const startupFailures = limitedFailures.flatMap((raw) => {
26625
+ try {
26626
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return [];
26627
+ const failure = raw;
26628
+ if (typeof failure["workspaceCwd"] !== "string" || failure["workspaceCwd"].length === 0 || typeof failure["channel"] !== "string" || failure["channel"].length === 0 || failure["phase"] !== "connect" || typeof failure["message"] !== "string" || failure["message"].length === 0 || failure["code"] !== void 0 && (typeof failure["code"] !== "string" || failure["code"].length === 0)) {
26629
+ return [];
26630
+ }
26631
+ const workspaceCwd = sanitizeControlDiagnostic(
26632
+ failure["workspaceCwd"],
26633
+ MAX_WORKSPACE_PATH_LENGTH
26634
+ );
26635
+ const channel = sanitizeControlDiagnostic(
26636
+ failure["channel"],
26637
+ MAX_CHANNEL_STARTUP_FAILURE_CHANNEL_LENGTH
26638
+ );
26639
+ const message = sanitizeControlDiagnostic(
26640
+ failure["message"],
26641
+ MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH
26642
+ );
26643
+ const code = typeof failure["code"] === "string" ? sanitizeControlDiagnostic(
26644
+ failure["code"],
26645
+ MAX_CHANNEL_STARTUP_FAILURE_CODE_LENGTH
26646
+ ) : void 0;
26647
+ if (!workspaceCwd || !channel || !message) return [];
26648
+ return [
26649
+ {
26650
+ workspaceCwd,
26651
+ channel,
26652
+ phase: "connect",
26653
+ ...code ? { code } : {},
26654
+ message
26655
+ }
26656
+ ];
26657
+ } catch {
26658
+ return [];
26659
+ }
26660
+ });
26661
+ if (startupFailures.length === 0) return {};
26662
+ const truncated = rawTruncated === true || rawFailureCount > MAX_CHANNEL_STARTUP_FAILURES;
26663
+ return {
26664
+ startupFailures,
26665
+ ...truncated ? { startupFailuresTruncated: true } : {}
26666
+ };
26667
+ }
26668
+ __name(startupFailureResponseFields, "startupFailureResponseFields");
25755
26669
  function sendChannelControlError(res, error2, getState) {
25756
26670
  const code = error2 && typeof error2 === "object" && "code" in error2 ? error2.code : void 0;
25757
- const message = redactLogCredentials(
25758
- error2 instanceof Error ? error2.message : String(error2)
25759
- );
26671
+ const rawMessage = error2 instanceof Error ? error2.message : String(error2);
26672
+ const message = code === "channel_worker_start_failed" ? sanitizeControlDiagnostic(
26673
+ rawMessage,
26674
+ MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH
26675
+ ) : redactLogCredentials(rawMessage);
25760
26676
  if (code === "channel_workspace_mismatch" || code === "ambiguous_channel_workspace") {
25761
26677
  res.status(400).json({ error: message, code });
25762
26678
  return true;
@@ -25792,7 +26708,13 @@ function sendChannelControlError(res, error2, getState) {
25792
26708
  error: message,
25793
26709
  code,
25794
26710
  ...typeof controlError.rolledBack === "boolean" ? { rolledBack: controlError.rolledBack } : {},
25795
- ...typeof controlError.rollbackError === "string" && controlError.rollbackError ? { rollbackError: redactLogCredentials(controlError.rollbackError) } : {},
26711
+ ...typeof controlError.rollbackError === "string" && controlError.rollbackError ? {
26712
+ rollbackError: sanitizeControlDiagnostic(
26713
+ controlError.rollbackError,
26714
+ 512
26715
+ )
26716
+ } : {},
26717
+ ...code === "channel_worker_start_failed" ? startupFailureResponseFields(error2) : {},
25796
26718
  state: getState()
25797
26719
  });
25798
26720
  return true;
@@ -26525,6 +27447,12 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
26525
27447
  boundWorkspace,
26526
27448
  persistSettingAvailable: deps.persistSetting !== void 0,
26527
27449
  sessionArtifactsPersistenceAvailable: deps.sessionArtifactsPersistenceAvailable !== false,
27450
+ sessionGenerationAvailable: /* @__PURE__ */ __name(() => {
27451
+ const runtimes = workspaceRegistry.list();
27452
+ return runtimes.length > 0 && runtimes.every(
27453
+ (runtime) => runtime.bridge.generateSessionContent !== void 0
27454
+ );
27455
+ }, "sessionGenerationAvailable"),
26528
27456
  // Registry injection supplies the primary workspace service through the
26529
27457
  // runtime, so it has the same reload surface as legacy deps.workspace.
26530
27458
  reloadAvailable: deps.workspace !== void 0 || injectedWorkspaceRegistry !== void 0,
@@ -26653,6 +27581,8 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
26653
27581
  );
26654
27582
  app.locals.workspaceRegistry = workspaceRegistry;
26655
27583
  const primaryRuntime = workspaceRegistry.primary;
27584
+ const daemonEnv = deps.daemonEnv ?? process.env;
27585
+ const primaryRuntimeEffectiveEnv = getRuntimeEffectiveEnv(primaryRuntime.env) ?? daemonEnv;
26656
27586
  const voiceCoordinator = deps.voiceCoordinator ?? new WorkspaceVoiceCoordinator();
26657
27587
  const primaryBoundWorkspace = primaryRuntime.workspaceCwd;
26658
27588
  const primaryBridge = primaryRuntime.bridge;
@@ -26681,7 +27611,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
26681
27611
  const healthDemoRoutes = createHealthDemoRoutes({
26682
27612
  opts,
26683
27613
  getPort,
26684
- bridge: primaryBridge,
27614
+ workspaceRegistry,
26685
27615
  getActiveSseCount,
26686
27616
  getRateLimiter: /* @__PURE__ */ __name(() => rateLimiter, "getRateLimiter")
26687
27617
  });
@@ -26915,6 +27845,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
26915
27845
  registerWorkspaceSetupGithubRoutes(app, {
26916
27846
  boundWorkspace: primaryBoundWorkspace,
26917
27847
  bridge: primaryBridge,
27848
+ env: primaryRuntimeEffectiveEnv,
26918
27849
  mutate,
26919
27850
  parseClientId: parseClientIdHeader,
26920
27851
  safeBody
@@ -27211,6 +28142,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
27211
28142
  });
27212
28143
  acpHandleRef.current = mountAcpHttp(app, primaryBridge, {
27213
28144
  boundWorkspace: primaryBoundWorkspace,
28145
+ daemonEnv,
27214
28146
  // Phase 4 (issue #6378): pass the registry so `/workspaces/:workspace/acp`
27215
28147
  // mounts a per-runtime ACP dispatcher for each registered workspace.
27216
28148
  workspaceRegistry,