@qwen-code/qwen-code 0.21.7 → 0.21.8-nightly.20260810.55e20db328

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 (334) hide show
  1. package/README.md +2 -0
  2. package/bundled/qc-helper/docs/configuration/settings.md +73 -59
  3. package/bundled/qc-helper/docs/extension/introduction.md +15 -1
  4. package/bundled/qc-helper/docs/features/channels/dingtalk.md +40 -2
  5. package/bundled/qc-helper/docs/features/channels/feishu.md +13 -2
  6. package/bundled/qc-helper/docs/features/channels/github.md +13 -11
  7. package/bundled/qc-helper/docs/features/channels/gitlab.md +13 -11
  8. package/bundled/qc-helper/docs/features/channels/overview.md +49 -31
  9. package/bundled/qc-helper/docs/features/channels/plugins.md +2 -2
  10. package/bundled/qc-helper/docs/features/channels/qqbot.md +4 -2
  11. package/bundled/qc-helper/docs/features/channels/telegram.md +4 -2
  12. package/bundled/qc-helper/docs/features/channels/wecom.md +1 -1
  13. package/bundled/qc-helper/docs/features/code-review.md +4 -0
  14. package/bundled/qc-helper/docs/features/commands.md +1 -1
  15. package/bundled/qc-helper/docs/features/hooks.md +52 -0
  16. package/bundled/qc-helper/docs/integration-jetbrains.md +1 -0
  17. package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +1 -1
  18. package/bundled/qc-helper/docs/qwen-serve.md +10 -5
  19. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +50 -36
  20. package/bundled/review/SKILL.md +32 -5
  21. package/chunks/{MaxSizedBox-ANWZBPTS.js → MaxSizedBox-A52T4GEU.js} +29 -25
  22. package/chunks/{StandaloneSessionPicker-XKS3VU3A.js → StandaloneSessionPicker-4J654SOB.js} +48 -44
  23. package/chunks/{acp-startup-profiler-ORIQ2CCQ.js → acp-startup-profiler-B5BYAMYQ.js} +2 -2
  24. package/chunks/{acpAgent-KUAZ3GCZ.js → acpAgent-65AM4AOR.js} +1833 -843
  25. package/chunks/{agent-T6PTGX5R.js → agent-SVQ7U7NJ.js} +28 -24
  26. package/chunks/{agent-headless-PR7YCB7S.js → agent-headless-XXGY2SQO.js} +28 -24
  27. package/chunks/{artifact-tool-U4VOZIK5.js → artifact-tool-N652YE4L.js} +1 -1
  28. package/chunks/{askUserQuestion-XOBQLPFA.js → askUserQuestion-ONW74PKJ.js} +1 -1
  29. package/chunks/{bridge-NU6YEEHK.js → bridge-Y32B5S3G.js} +34 -30
  30. package/chunks/{ca-NYKNH222.js → ca-ZLKAB4K3.js} +6 -0
  31. package/chunks/{channel-management-service-FSQ7SHYI.js → channel-management-service-PHELKOW2.js} +19 -10
  32. package/chunks/{channel-settings-store-35VQVUVV.js → channel-settings-store-OW43U6VB.js} +36 -32
  33. package/chunks/{channel-worker-group-JWQK224X.js → channel-worker-group-MSHT6CWR.js} +7 -7
  34. package/chunks/{channel-worker-manager-77E3OXRQ.js → channel-worker-manager-XXD3GDSK.js} +7 -7
  35. package/chunks/{channel-worker-supervisor-62YWUGP2.js → channel-worker-supervisor-IVSDIMI4.js} +4 -4
  36. package/chunks/{chunk-HYRDKNUY.js → chunk-2545EHZR.js} +1 -1
  37. package/chunks/{chunk-SPMY6CX6.js → chunk-2ASQDZSJ.js} +3 -3
  38. package/chunks/{chunk-CJXIIILK.js → chunk-2FRY5CRX.js} +1 -1
  39. package/chunks/{chunk-CNIID3TV.js → chunk-2UUMVNYT.js} +1 -1
  40. package/chunks/{chunk-KXSDEOFU.js → chunk-3KJQZEN3.js} +1 -1
  41. package/chunks/{chunk-22NBYCPD.js → chunk-3P2LV43B.js} +1 -1
  42. package/chunks/{chunk-Y7E5LNLO.js → chunk-47ZUMGGY.js} +2634 -2114
  43. package/chunks/{chunk-LA7YLSR6.js → chunk-4EOURKA4.js} +839 -153
  44. package/chunks/chunk-4JRM2BSM.js +48 -0
  45. package/chunks/{chunk-BGG4MBYD.js → chunk-4PYCZH2V.js} +4 -187
  46. package/chunks/{chunk-L4N6TIP7.js → chunk-4TRQPFDP.js} +4 -2
  47. package/chunks/{chunk-6XJMFJ4D.js → chunk-5WZL724W.js} +177 -120
  48. package/chunks/{chunk-23RZCH76.js → chunk-5ZTS3OQ3.js} +3 -3
  49. package/chunks/{chunk-VWOVHOTT.js → chunk-67EWJE77.js} +1 -1
  50. package/chunks/{chunk-3K7FH2KQ.js → chunk-67N6HB5H.js} +1310 -171
  51. package/chunks/{chunk-CXE7E23H.js → chunk-6Q5ABMTU.js} +45 -17
  52. package/chunks/{chunk-NG2R4N5O.js → chunk-6ZRFAKXK.js} +1 -1
  53. package/chunks/{chunk-RERATVSK.js → chunk-7XX5IBXL.js} +145 -10
  54. package/chunks/{chunk-S7CV4KO6.js → chunk-AKJQSWV4.js} +4 -4
  55. package/chunks/{chunk-5KH532V7.js → chunk-AUWN7BAG.js} +1 -1
  56. package/chunks/{chunk-DBOFL3LQ.js → chunk-BL65MO72.js} +10 -10
  57. package/chunks/{chunk-AKA24BGO.js → chunk-BT6GQIEJ.js} +1 -1
  58. package/chunks/{chunk-W7U4ESW2.js → chunk-CG3WBKJK.js} +1 -1
  59. package/chunks/{chunk-2M5N3DHY.js → chunk-CMOBWHWW.js} +1 -1
  60. package/chunks/chunk-COBO5EBO.js +135 -0
  61. package/chunks/chunk-CPG6P4GG.js +82 -0
  62. package/chunks/{chunk-3NB7TSE2.js → chunk-D2D7J3EW.js} +1 -1
  63. package/chunks/{chunk-NLREQJFK.js → chunk-DA4HRSBW.js} +15 -0
  64. package/chunks/{chunk-RNVQB725.js → chunk-DPMJLKUP.js} +2 -2
  65. package/chunks/{chunk-DIEFUBV6.js → chunk-DX3RGJMS.js} +218 -37
  66. package/chunks/{chunk-33ACCIIY.js → chunk-DZUO626D.js} +1 -1
  67. package/chunks/chunk-E2FPSSKP.js +244 -0
  68. package/chunks/{chunk-72LNFGUY.js → chunk-E2N554HK.js} +3 -3
  69. package/chunks/{chunk-6EOI4HOK.js → chunk-E2T7FLDU.js} +12 -17
  70. package/chunks/{chunk-EUQTXRKZ.js → chunk-EISUQQPS.js} +6 -6
  71. package/chunks/{chunk-H2UQ2M5Z.js → chunk-EUVOKP6Y.js} +96 -22
  72. package/chunks/{chunk-RMH5OWLD.js → chunk-F3II4BTZ.js} +1 -1
  73. package/chunks/{chunk-P3LEG54R.js → chunk-F6TUUA2U.js} +3 -3
  74. package/chunks/chunk-F6WFNA7U.js +22 -0
  75. package/chunks/{chunk-RZHU3ILK.js → chunk-FAD7OC7V.js} +4 -4
  76. package/chunks/{chunk-OMKQH5C5.js → chunk-FWWQIFDT.js} +6 -23
  77. package/chunks/{chunk-TLV2IMHR.js → chunk-FYB4GIDW.js} +3 -3
  78. package/chunks/{chunk-ZJ3VGYHK.js → chunk-GY24H6IA.js} +40 -22
  79. package/chunks/{chunk-P2AJ7FTI.js → chunk-H4JC7LZX.js} +1 -1
  80. package/chunks/{chunk-55LYDVPU.js → chunk-HDYQYYWB.js} +1 -1
  81. package/chunks/{chunk-PQBHU2IA.js → chunk-HKI3KHAO.js} +11 -11
  82. package/chunks/{chunk-Y4NGLFGJ.js → chunk-HUWENAHO.js} +1 -1
  83. package/chunks/{chunk-3ULCB3NE.js → chunk-HV76SFIA.js} +1 -1
  84. package/chunks/{chunk-CSZEXZBE.js → chunk-HWXGX534.js} +3 -3
  85. package/chunks/{chunk-E33LOKRA.js → chunk-I5VM3SKY.js} +22 -5
  86. package/chunks/{chunk-LZC3B5N2.js → chunk-IA7TGCN2.js} +2 -2
  87. package/chunks/{chunk-RGSBTHSU.js → chunk-KMS57JDD.js} +137 -7
  88. package/chunks/{chunk-VOARQPTA.js → chunk-KP25NJNM.js} +65 -21
  89. package/chunks/{chunk-6M26GBKX.js → chunk-L2AFWWJE.js} +42 -3
  90. package/chunks/{chunk-ZXU5UHMI.js → chunk-LHEC5V6G.js} +2 -2
  91. package/chunks/{chunk-J26HHFI5.js → chunk-LP2QGNSP.js} +32 -2
  92. package/chunks/{chunk-R574ATRM.js → chunk-M2PNLYGY.js} +41 -0
  93. package/chunks/{chunk-MKVZE4ZJ.js → chunk-MFDYOYZZ.js} +3 -2
  94. package/chunks/{chunk-ALGGS7UH.js → chunk-NPQ5ZKRP.js} +82 -1
  95. package/chunks/{chunk-YHEEE624.js → chunk-NV3F44FL.js} +7 -3
  96. package/chunks/{chunk-6GONZVLS.js → chunk-NZMXUSKS.js} +1 -1
  97. package/chunks/{chunk-HQB2KUAN.js → chunk-O277O7U6.js} +1 -1
  98. package/chunks/{chunk-Y4EWSQF7.js → chunk-OBP6QWD5.js} +2 -2
  99. package/chunks/{chunk-CYR3HI5X.js → chunk-OQTXYMKW.js} +2 -2
  100. package/chunks/{chunk-TYKC75AX.js → chunk-OR6R3IUW.js} +2 -2
  101. package/chunks/{chunk-TRLYP7OF.js → chunk-OSVH4SMN.js} +16 -141
  102. package/chunks/{chunk-FPM27XN4.js → chunk-OW2BWT2P.js} +4 -4
  103. package/chunks/{chunk-TDXGKHDN.js → chunk-P5ULXPK5.js} +2 -2
  104. package/chunks/{chunk-24ER7UV4.js → chunk-PBRVUF5B.js} +1 -1
  105. package/chunks/{chunk-LKRMNRSN.js → chunk-PDPFQ2FO.js} +2 -0
  106. package/chunks/{chunk-2VSTGY6M.js → chunk-PJRW65JO.js} +1 -1
  107. package/chunks/{chunk-6HVUFDS2.js → chunk-PNVPFARW.js} +22 -13
  108. package/chunks/{chunk-IC4Z6LX6.js → chunk-PYQADEFD.js} +5 -0
  109. package/chunks/chunk-R4ZA6GBK.js +208 -0
  110. package/chunks/{chunk-KR4ZSC7K.js → chunk-RMPLEWF3.js} +3 -3
  111. package/chunks/{chunk-EORNAQDT.js → chunk-RQ6U2JJQ.js} +1 -1
  112. package/chunks/{chunk-AE77C5ZU.js → chunk-RYQMJCUO.js} +1 -1
  113. package/chunks/{chunk-6UWFTUQL.js → chunk-S5CULOHB.js} +75 -31
  114. package/chunks/{chunk-7UFKAV7Y.js → chunk-S6HYI3MF.js} +2 -2
  115. package/chunks/chunk-SAH4BD2J.js +92 -0
  116. package/chunks/chunk-SR7RZ4MS.js +202 -0
  117. package/chunks/{chunk-QETYKPMG.js → chunk-T2O6NIOY.js} +1 -1
  118. package/chunks/chunk-TQOF5KBL.js +71 -0
  119. package/chunks/{chunk-OHJLEW5J.js → chunk-TWFFY5BP.js} +4 -4
  120. package/chunks/{chunk-SCI7K3GM.js → chunk-TXO5BMR2.js} +19 -10
  121. package/chunks/{chunk-YJQCUTT2.js → chunk-UAB6J2IE.js} +4 -4
  122. package/chunks/{chunk-OFI7IGST.js → chunk-UGUKH3SU.js} +10 -10
  123. package/chunks/{chunk-SHZYHGQH.js → chunk-V2226RFW.js} +1 -1
  124. package/chunks/{chunk-KKJJB5X6.js → chunk-V47QNK5W.js} +1526 -833
  125. package/chunks/{chunk-W4B7UBUS.js → chunk-VHXPSL57.js} +6 -6
  126. package/chunks/{chunk-WUC6ZFXO.js → chunk-VKJ4KTPJ.js} +1 -1
  127. package/chunks/{chunk-MAJS7AT4.js → chunk-VNNWAZSI.js} +2 -2
  128. package/chunks/{chunk-BVWVWGLE.js → chunk-WAUGQKUU.js} +4 -64
  129. package/chunks/{chunk-OH2VKQXH.js → chunk-WH6QMLUW.js} +37 -30
  130. package/chunks/{chunk-PJOBIWUG.js → chunk-WQYWK4DG.js} +1 -1
  131. package/chunks/{chunk-LEMXGVEP.js → chunk-YFRFZCIP.js} +3 -3
  132. package/chunks/{chunk-2U3WZGZG.js → chunk-YGT2AUJ7.js} +103 -135
  133. package/chunks/{chunk-6XU3PH66.js → chunk-YR7ZQ4RD.js} +22 -69
  134. package/chunks/{chunk-OA4JVLSA.js → chunk-Z7VOMGDC.js} +22 -1
  135. package/chunks/{chunk-RUL4S3K3.js → chunk-ZCJBCKL5.js} +175 -60
  136. package/chunks/{chunk-GSS34377.js → chunk-ZI5IH2HP.js} +2 -2
  137. package/chunks/{chunk-CB2464BK.js → chunk-ZIKTCMQF.js} +117 -10
  138. package/chunks/chunk-ZLBIFIMV.js +1099 -0
  139. package/chunks/{chunk-D3UEZIQH.js → chunk-ZSNBQXMZ.js} +48 -55
  140. package/chunks/{chunk-FZBZSYKU.js → chunk-ZV7LTLFE.js} +1 -1
  141. package/chunks/{computer-use-KEAPATUY.js → computer-use-SLN7DV2E.js} +28 -24
  142. package/chunks/{config-utils-K7SCOWHD.js → config-utils-ULCSRMWD.js} +4 -4
  143. package/chunks/{contextCommand-ZJA6A5K5.js → contextCommand-EHFYX6FW.js} +30 -26
  144. package/chunks/{core-runtime-QMJPWHCI.js → core-runtime-FBSP5IIG.js} +33 -29
  145. package/chunks/{create-sub-session-E4PBYXV5.js → create-sub-session-QIDZUOPU.js} +1 -1
  146. package/chunks/{create-sub-session-DJE6XICH.js → create-sub-session-WC7YGVSL.js} +29 -25
  147. package/chunks/{cron-create-GRBWYMIJ.js → cron-create-VONA5JYY.js} +1 -1
  148. package/chunks/{cron-delete-4CMKBR2M.js → cron-delete-5JXSP2MI.js} +1 -1
  149. package/chunks/{cron-list-W7K4ASOA.js → cron-list-KE4F2CIR.js} +1 -1
  150. package/chunks/{daemon-SCTQMM7Z.js → daemon-VSX3FHTY.js} +119 -4
  151. package/chunks/{daemon-status-provider-FSWDPE2G.js → daemon-status-provider-WW2AD2T7.js} +39 -35
  152. package/chunks/{daemon-trust-policy-P5L5VFAY.js → daemon-trust-policy-E4MAYWPI.js} +35 -31
  153. package/chunks/{daemon-trust-policy-monitor-73JYN6ET.js → daemon-trust-policy-monitor-XVIDV6T4.js} +35 -31
  154. package/chunks/{de-VL76CPLV.js → de-LIW4XVLN.js} +5 -0
  155. package/chunks/{deferred-core-runtime-BWRCCFTE.js → deferred-core-runtime-5SVUC6UC.js} +28 -24
  156. package/chunks/{display-image-O2XFPQTC.js → display-image-NQRSIBXM.js} +2 -2
  157. package/chunks/{dist-HVBMEYWK.js → dist-3NTTUAHT.js} +1 -1
  158. package/chunks/{dist-7JGAAQSC.js → dist-6BMOAE3Z.js} +2 -2
  159. package/chunks/{dist-3BMEUGTG.js → dist-B2CGTW6T.js} +1 -1
  160. package/chunks/{dist-C5U4LJKW.js → dist-EWW3J4HQ.js} +5 -4
  161. package/chunks/{dist-K4WWQBHS.js → dist-EZE3V3Q7.js} +55 -15
  162. package/chunks/{dist-DPPHJAVL.js → dist-J47AXBZC.js} +918 -142
  163. package/chunks/{dist-SFQ34F4M.js → dist-OTUO3AS2.js} +8 -1091
  164. package/chunks/{dist-KS4O2NKE.js → dist-Z3CS4OVP.js} +14 -8
  165. package/chunks/{earlyInputCapture-L5ST23A6.js → earlyInputCapture-72FYHYRD.js} +28 -24
  166. package/chunks/{edit-LHHRFNFK.js → edit-SWVVWHXW.js} +28 -24
  167. package/chunks/{en-IRJ2WN5T.js → en-SY5GTIGX.js} +6 -0
  168. package/chunks/{enter-worktree-6NXCRZPF.js → enter-worktree-2HF6WQEO.js} +28 -24
  169. package/chunks/{enterPlanMode-ZVQT4U7D.js → enterPlanMode-OW6S7L4P.js} +28 -24
  170. package/chunks/{environment-GJ2HWJOS.js → environment-LRTBTDXH.js} +32 -28
  171. package/chunks/{errors-6RLH3XXC.js → errors-4CO2DME6.js} +30 -26
  172. package/chunks/{exit-worktree-I2YLUHHY.js → exit-worktree-GHJEIRGL.js} +28 -24
  173. package/chunks/{exitPlanMode-7CCWKO7I.js → exitPlanMode-JVP4FNNK.js} +28 -24
  174. package/chunks/{fast-path-DVFD4HQD.js → fast-path-HCCY7GR2.js} +24 -3
  175. package/chunks/{fast-path-settings-WQJU2LAT.js → fast-path-settings-MN5QQQET.js} +6 -3
  176. package/chunks/{fr-GK3HQYVB.js → fr-RQFO7U4P.js} +5 -0
  177. package/chunks/{gemini-7FWGOYD4.js → gemini-V3YVRKXU.js} +85 -72
  178. package/chunks/{geminiContentGenerator-V2WVLIXU.js → geminiContentGenerator-LVPMQUWX.js} +1 -1
  179. package/chunks/{glob-3N6GGI75.js → glob-7HRXHYDR.js} +28 -24
  180. package/chunks/{goal-tools-APOW6UXL.js → goal-tools-PXWN5VK3.js} +4 -2
  181. package/chunks/{grep-V43ILZVX.js → grep-BITQUON5.js} +28 -24
  182. package/chunks/{handleAutoUpdate-A5WFVWIA.js → handleAutoUpdate-DKFY454S.js} +32 -28
  183. package/chunks/{i18n-PLVQ4FBZ.js → i18n-53BQIQSH.js} +29 -25
  184. package/chunks/{image-gen-7C6IK6DC.js → image-gen-H62FLDFB.js} +7 -5
  185. package/chunks/{initializer-CVAIKZYL.js → initializer-Q7NUQRSU.js} +35 -31
  186. package/chunks/{installationInfo-J6QDHNTK.js → installationInfo-BWFHT7WU.js} +29 -25
  187. package/chunks/{ja-3FA46IKD.js → ja-KOZKHJHZ.js} +5 -0
  188. package/chunks/{list-ZZ4OUUWV.js → list-OWQKR6JK.js} +38 -34
  189. package/chunks/{list-agents-KFFIIS2G.js → list-agents-Z4WABFDZ.js} +1 -1
  190. package/chunks/{loadedSettingsAdapter-QRYRJSWL.js → loadedSettingsAdapter-HNPKQMFA.js} +35 -31
  191. package/chunks/{loggingContentGenerator-OJCO75HM.js → loggingContentGenerator-A5I3VQUC.js} +10 -8
  192. package/chunks/{loop-wakeup-TLMJPMMP.js → loop-wakeup-UZ5RL5Y2.js} +2 -2
  193. package/chunks/{ls-UVVE2XGE.js → ls-TVHDGIES.js} +1 -1
  194. package/chunks/{lsp-QMEA2VLB.js → lsp-CVN6OQPI.js} +1 -1
  195. package/chunks/main-PXAUXNF2.js +8 -0
  196. package/chunks/{managed-npm-update-PCOSCP2N.js → managed-npm-update-CUUJGUTV.js} +29 -25
  197. package/chunks/{mcp-M3WKKWKY.js → mcp-GJSC7ZPO.js} +35 -31
  198. package/chunks/{monitor-GN24FH6C.js → monitor-TZ2II7JM.js} +38 -30
  199. package/chunks/{nonInteractiveCli-KPTU3VSQ.js → nonInteractiveCli-22RS4EVH.js} +72 -66
  200. package/chunks/{notebook-edit-4YM65BBO.js → notebook-edit-YZC3YPY2.js} +36 -24
  201. package/chunks/{openaiContentGenerator-EDQT6GTV.js → openaiContentGenerator-OIGO5XNF.js} +21 -11
  202. package/chunks/{pidfile-JOIIRN2C.js → pidfile-QJQ65RJ2.js} +28 -24
  203. package/chunks/{process-registry-2CHQBXH5.js → process-registry-PMJOA5CO.js} +15 -0
  204. package/chunks/{processUtils-5SV4MX3Q.js → processUtils-V5VSDIKS.js} +2 -2
  205. package/chunks/{pt-3AOBKPIJ.js → pt-U6AOCTMF.js} +5 -0
  206. package/chunks/{qwenContentGenerator-ODRJSUGR.js → qwenContentGenerator-HXM25BGB.js} +35 -30
  207. package/chunks/{qwenOAuth2-NESCMZ47.js → qwenOAuth2-7MTMS2Z5.js} +7 -5
  208. package/chunks/{read-file-HPSODLPK.js → read-file-PMGXB3ZB.js} +8 -6
  209. package/chunks/{read-mcp-resource-2TNSJTC3.js → read-mcp-resource-PZ4ZF6YL.js} +1 -1
  210. package/chunks/{record-artifact-RAON52FC.js → record-artifact-P4HFMS7X.js} +2 -2
  211. package/chunks/{resumeHistoryUtils-TXCOFFMQ.js → resumeHistoryUtils-YUTPLHUH.js} +33 -29
  212. package/chunks/{ripGrep-ZKQGTQAO.js → ripGrep-XUS66YIV.js} +28 -24
  213. package/chunks/{ru-VJRAMC4W.js → ru-CMX4UMYP.js} +5 -0
  214. package/chunks/{run-qwen-serve-ZPKPKECF.js → run-qwen-serve-4NVSU75L.js} +261 -62
  215. package/chunks/{runtime-2FLNNM36.js → runtime-QLRVP6HM.js} +40 -36
  216. package/chunks/{scheduler-365PJHNR.js → scheduler-PBB2NSOP.js} +28 -24
  217. package/chunks/{sdk-exporters-http-KHAB5JSD.js → sdk-exporters-http-XVTZQRCE.js} +2 -2
  218. package/chunks/{sdk-impl-KD7FSTC3.js → sdk-impl-7W7AKCS4.js} +7 -3
  219. package/chunks/{send-message-ZM7MRUGP.js → send-message-CAMSLG2L.js} +4 -3
  220. package/chunks/{serve-QD2RNLKJ.js → serve-BWKTRX72.js} +37 -31
  221. package/chunks/{server-XLJVLTYM.js → server-E7CH7WPK.js} +1437 -593
  222. package/chunks/{session-3VTUHH4Q.js → session-QEKSJ6YU.js} +166 -105
  223. package/chunks/{settings-KULVPCQC.js → settings-BRAOSJIM.js} +34 -30
  224. package/chunks/{shell-3SWW22MH.js → shell-OF3CK4AT.js} +28 -24
  225. package/chunks/{skill-KDHWYS7W.js → skill-HLH2NO2H.js} +9 -7
  226. package/chunks/{skill-settings-NMY4JEJC.js → skill-settings-DRPU7YI5.js} +34 -30
  227. package/chunks/{spawnChannel-ZKS4Q5OU.js → spawnChannel-4KO7YTFM.js} +31 -27
  228. package/chunks/{standalone-update-7CXPGAQ4.js → standalone-update-DJN2R3YW.js} +30 -26
  229. package/chunks/{startInteractiveUI-2QQLEKM6.js → startInteractiveUI-O3WQQ2WC.js} +384 -173
  230. package/chunks/{syntheticOutput-ZLCUTKO2.js → syntheticOutput-PEBJQYJV.js} +2 -2
  231. package/chunks/{task-create-CQP5UEA3.js → task-create-5NWCQSJF.js} +5 -4
  232. package/chunks/{task-list-XLEZOJXP.js → task-list-53265TRZ.js} +1 -1
  233. package/chunks/{task-stop-7ZQM5CFF.js → task-stop-FPCOIRYX.js} +1 -1
  234. package/chunks/{task-update-JA75U2SN.js → task-update-5HN577LS.js} +5 -4
  235. package/chunks/{team-create-2WTNGAOX.js → team-create-2E4ACBJD.js} +28 -24
  236. package/chunks/{team-delete-MHY3UZGY.js → team-delete-MMQB4OSC.js} +1 -1
  237. package/chunks/{team-plan-approval-LZTYLEG4.js → team-plan-approval-LWIDXYOA.js} +28 -24
  238. package/chunks/{terminal-image-renderer-R5HHAFJN.js → terminal-image-renderer-PJM7663W.js} +30 -26
  239. package/chunks/{theme-manager-PAUCSJFF.js → theme-manager-FDQTM3RP.js} +28 -24
  240. package/chunks/{todoWrite-UPVOHYGD.js → todoWrite-JGV6VLOX.js} +1 -1
  241. package/chunks/{tool-search-2BFCGLI6.js → tool-search-TL5ZXBF4.js} +11 -8
  242. package/chunks/{total-session-admission-MK4SINFK.js → total-session-admission-LS6EY5KT.js} +37 -32
  243. package/chunks/{trustedFolders-TJ5S26N7.js → trustedFolders-5RWP5OB7.js} +32 -26
  244. package/chunks/{types-ML3TRJQ5.js → types-WYCFCEHR.js} +5 -3
  245. package/chunks/{update-relaunch-N7AYLARF.js → update-relaunch-HWQ4USKY.js} +5 -5
  246. package/chunks/{updateCheck-QRZ3DVT5.js → updateCheck-EZMBTEIR.js} +31 -27
  247. package/chunks/{useAutoAcceptIndicator-DBJ7Y5AF.js → useAutoAcceptIndicator-JDMI627A.js} +37 -33
  248. package/chunks/{validateNonInterActiveAuth-6ZQWUDS3.js → validateNonInterActiveAuth-RRUHC5RO.js} +67 -63
  249. package/chunks/{version-AJQGQWXC.js → version-XS4UTKUX.js} +1 -1
  250. package/chunks/{web-fetch-QWJYRXFL.js → web-fetch-2JV7H6OM.js} +14 -10
  251. package/chunks/{web-search-2AOXJGHU.js → web-search-RCTN2GAM.js} +10 -7
  252. package/chunks/{workflow-ERH3SJG2.js → workflow-6MKLKQ6R.js} +909 -273
  253. package/chunks/{workspace-providers-status-HZ474RA4.js → workspace-providers-status-YZ2IJ4DK.js} +38 -34
  254. package/chunks/{workspace-registration-store-6EUP4JXG.js → workspace-registration-store-IYN72LBS.js} +1 -1
  255. package/chunks/{workspace-registry-R4APRRNC.js → workspace-registry-7LFBZQLT.js} +37 -32
  256. package/chunks/{workspace-service-HFIFDMU7.js → workspace-service-2EHSPRJB.js} +45 -39
  257. package/chunks/{workspace-skills-status-HAHEIHGK.js → workspace-skills-status-5VJ2D5HN.js} +36 -32
  258. package/chunks/{workspace-trust-reconciler-65GTAGDK.js → workspace-trust-reconciler-X2LZ6XCI.js} +44 -39
  259. package/chunks/{write-file-B34CDELV.js → write-file-CJK6SCCF.js} +28 -24
  260. package/chunks/{zh-ARWDLDLR.js → zh-AGL2FVBI.js} +6 -0
  261. package/chunks/{zh-TW-Y4RGI3P7.js → zh-TW-KI66MHQY.js} +6 -0
  262. package/chunks/{zoom-image-HPRBZHSS.js → zoom-image-BVW4RFYW.js} +8 -6
  263. package/cli.js +13 -13
  264. package/locales/ca.js +10 -0
  265. package/locales/de.js +9 -0
  266. package/locales/en.js +10 -0
  267. package/locales/fr.js +9 -0
  268. package/locales/ja.js +9 -0
  269. package/locales/pt.js +9 -0
  270. package/locales/ru.js +9 -0
  271. package/locales/zh-TW.js +10 -0
  272. package/locales/zh.js +10 -0
  273. package/package.json +3 -3
  274. package/web-shell/assets/{arc-Ip-FFDJ0.js → arc-DDtoJrAW.js} +1 -1
  275. package/web-shell/assets/{architectureDiagram-3BPJPVTR-CChqgwIb.js → architectureDiagram-3BPJPVTR-BAInIW4O.js} +1 -1
  276. package/web-shell/assets/{blockDiagram-GPEHLZMM-BHN-Tfss.js → blockDiagram-GPEHLZMM-ChPDk7fP.js} +1 -1
  277. package/web-shell/assets/{c4Diagram-AAUBKEIU-BhyjzDjN.js → c4Diagram-AAUBKEIU-Cd9BJuUy.js} +1 -1
  278. package/web-shell/assets/channel-0OQklTfP.js +1 -0
  279. package/web-shell/assets/{chunk-2J33WTMH-BB9eyHrx.js → chunk-2J33WTMH-COQkLp56.js} +1 -1
  280. package/web-shell/assets/{chunk-4BX2VUAB-BeV7ce_J.js → chunk-4BX2VUAB-GUJshQ_l.js} +1 -1
  281. package/web-shell/assets/{chunk-55IACEB6-DO7kXDiV.js → chunk-55IACEB6-Boaa7c10.js} +1 -1
  282. package/web-shell/assets/{chunk-727SXJPM-B27MPznD.js → chunk-727SXJPM-CcRXaly2.js} +1 -1
  283. package/web-shell/assets/{chunk-AQP2D5EJ-DHIjqjD_.js → chunk-AQP2D5EJ-BY0OARHh.js} +1 -1
  284. package/web-shell/assets/{chunk-FMBD7UC4-DabMqyN2.js → chunk-FMBD7UC4-DLFQfv0S.js} +1 -1
  285. package/web-shell/assets/{chunk-ND2GUHAM-Dw7Nnnxc.js → chunk-ND2GUHAM-C_S0u-D2.js} +1 -1
  286. package/web-shell/assets/{chunk-QZHKN3VN-DdaZew1Q.js → chunk-QZHKN3VN-DP9m64hw.js} +1 -1
  287. package/web-shell/assets/classDiagram-4FO5ZUOK-CZ4-apsu.js +1 -0
  288. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CZ4-apsu.js +1 -0
  289. package/web-shell/assets/{cose-bilkent-S5V4N54A-CgBpCYH5.js → cose-bilkent-S5V4N54A-CGY6zGE1.js} +1 -1
  290. package/web-shell/assets/{dagre-BM42HDAG-BB4IU8G0.js → dagre-BM42HDAG-yB7whKNn.js} +1 -1
  291. package/web-shell/assets/{diagram-2AECGRRQ-BcUTHU37.js → diagram-2AECGRRQ-Bdlc59La.js} +1 -1
  292. package/web-shell/assets/{diagram-5GNKFQAL-B6Lyihyv.js → diagram-5GNKFQAL-BUClP18L.js} +1 -1
  293. package/web-shell/assets/{diagram-KO2AKTUF-CRIJOjpG.js → diagram-KO2AKTUF-aZm08kjn.js} +1 -1
  294. package/web-shell/assets/{diagram-LMA3HP47-DdNiwWWT.js → diagram-LMA3HP47-7DGwEkxC.js} +1 -1
  295. package/web-shell/assets/{diagram-OG6HWLK6-Dz4b32Do.js → diagram-OG6HWLK6-CAGKayxx.js} +1 -1
  296. package/web-shell/assets/{erDiagram-TEJ5UH35-D-8NGw77.js → erDiagram-TEJ5UH35-CptoHHQi.js} +1 -1
  297. package/web-shell/assets/{flowDiagram-I6XJVG4X-Dun26LyM.js → flowDiagram-I6XJVG4X-CNOH0s7Q.js} +1 -1
  298. package/web-shell/assets/{ganttDiagram-6RSMTGT7-F10Hu1Gc.js → ganttDiagram-6RSMTGT7-CCQuCU3y.js} +1 -1
  299. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Bf8Ez6-D.js → gitGraphDiagram-PVQCEYII-B7gv9f4E.js} +1 -1
  300. package/web-shell/assets/{index-BXqw-nGq.js → index-BoUPVvpf.js} +1 -1
  301. package/web-shell/assets/index-D1YQXYsB.css +5 -0
  302. package/web-shell/assets/index-J4N7zCmU.js +1768 -0
  303. package/web-shell/assets/{infoDiagram-5YYISTIA-DVgTMLvj.js → infoDiagram-5YYISTIA-Bb3KYEbR.js} +1 -1
  304. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-uT-KepvK.js → ishikawaDiagram-YF4QCWOH-DWEzbAGi.js} +1 -1
  305. package/web-shell/assets/{journeyDiagram-JHISSGLW-Vg_XadQf.js → journeyDiagram-JHISSGLW-CmxwEqeb.js} +1 -1
  306. package/web-shell/assets/{kanban-definition-UN3LZRKU-Dyv1ESBE.js → kanban-definition-UN3LZRKU-Ci0gDD8O.js} +1 -1
  307. package/web-shell/assets/{linear-BMIepYX3.js → linear-BqxZqGhS.js} +1 -1
  308. package/web-shell/assets/{mermaid.core-zA8pJ9ag.js → mermaid.core-BDAFffHv.js} +5 -5
  309. package/web-shell/assets/{mindmap-definition-RKZ34NQL-BCW_BZ_5.js → mindmap-definition-RKZ34NQL-Btvx-xvS.js} +1 -1
  310. package/web-shell/assets/{pieDiagram-4H26LBE5-DseNEGp2.js → pieDiagram-4H26LBE5-CKAg7yG7.js} +1 -1
  311. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-6Z7wr1Fi.js → quadrantDiagram-W4KKPZXB-DIt8E1mC.js} +1 -1
  312. package/web-shell/assets/{requirementDiagram-4Y6WPE33-CVOlCRPf.js → requirementDiagram-4Y6WPE33-BA7mQWQJ.js} +1 -1
  313. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-CGhgrUJZ.js → sankeyDiagram-5OEKKPKP-D0JppnVU.js} +1 -1
  314. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-dlqmpLuQ.js → sequenceDiagram-3UESZ5HK-29DIQFjB.js} +1 -1
  315. package/web-shell/assets/{stateDiagram-AJRCARHV-B9EW10Xb.js → stateDiagram-AJRCARHV-iiXMdK--.js} +1 -1
  316. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CEGK3l80.js +1 -0
  317. package/web-shell/assets/{timeline-definition-PNZ67QCA-BBRh0mgZ.js → timeline-definition-PNZ67QCA-CeF7ngSW.js} +1 -1
  318. package/web-shell/assets/{vennDiagram-CIIHVFJN-B8Gs-REP.js → vennDiagram-CIIHVFJN-Beilq8D6.js} +1 -1
  319. package/web-shell/assets/{wardley-L42UT6IY-D_y80Ur7.js → wardley-L42UT6IY-DOYjY4zO.js} +1 -1
  320. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-D-CNfHJ-.js → wardleyDiagram-YWT4CUSO-Dtqp8o18.js} +1 -1
  321. package/web-shell/assets/{xychartDiagram-2RQKCTM6-DQ5CvELo.js → xychartDiagram-2RQKCTM6-cdAc0Dfv.js} +1 -1
  322. package/web-shell/index.html +2 -2
  323. package/chunks/chunk-6PEXNQTX.js +0 -68
  324. package/chunks/chunk-IUFV6FYU.js +0 -81
  325. package/chunks/chunk-RXFQM6FQ.js +0 -42
  326. package/web-shell/assets/channel-Cu8qd6OB.js +0 -1
  327. package/web-shell/assets/classDiagram-4FO5ZUOK-BI3KrXhq.js +0 -1
  328. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BI3KrXhq.js +0 -1
  329. package/web-shell/assets/index-QQlUCJGg.css +0 -5
  330. package/web-shell/assets/index-hcgjV7vS.js +0 -1768
  331. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CJTZJJ5X.js +0 -1
  332. package/chunks/{anthropicContentGenerator-DTMVEL5M.js → anthropicContentGenerator-SSFE2753.js} +9 -9
  333. /package/chunks/{chunk-VXZBKKQR.js → chunk-NTTBXH7U.js} +0 -0
  334. /package/chunks/{chunk-GRC5HGPI.js → chunk-OIBUG24X.js} +0 -0
@@ -1,5 +1,11 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
+ import {
4
+ deriveWebSocketBase,
5
+ openQwenAsrRealtimeStream,
6
+ openVoiceStream,
7
+ openVoiceStreamWithRetry
8
+ } from "./chunk-Q3JQ7OSU.js";
3
9
  import {
4
10
  GENERATION_MAX_PROMPT_BYTES,
5
11
  LIVE_SESSION_SOURCE_PREFIX,
@@ -11,7 +17,6 @@ import {
11
17
  isCompatibleLiveSessionSource,
12
18
  isReservedLiveSessionSource,
13
19
  isValidServerName,
14
- loadSettingsCached,
15
20
  normalizeChannelDelivery,
16
21
  parseChannelDelivery,
17
22
  readLoadableLiveConversationMetadata,
@@ -21,13 +26,7 @@ import {
21
26
  shouldSuppressRememberErrorDetails,
22
27
  workspaceMemoryFailureCode,
23
28
  workspaceMemoryFailureDiagnostics
24
- } from "./chunk-TRLYP7OF.js";
25
- import {
26
- deriveWebSocketBase,
27
- openQwenAsrRealtimeStream,
28
- openVoiceStream,
29
- openVoiceStreamWithRetry
30
- } from "./chunk-Q3JQ7OSU.js";
29
+ } from "./chunk-OSVH4SMN.js";
31
30
  import {
32
31
  SetupGithubError,
33
32
  collectSessionData,
@@ -39,12 +38,12 @@ import {
39
38
  toJson,
40
39
  toJsonl,
41
40
  toMarkdown
42
- } from "./chunk-6XJMFJ4D.js";
41
+ } from "./chunk-5WZL724W.js";
43
42
  import {
44
43
  OBSERVED_CONTACT_MAX_FRESH_WITHIN_SECONDS,
45
44
  ObservedChannelContactStore
46
45
  } from "./chunk-OWMAZHIX.js";
47
- import "./chunk-KXSDEOFU.js";
46
+ import "./chunk-3KJQZEN3.js";
48
47
  import {
49
48
  escapeAnsiCtrlCodes
50
49
  } from "./chunk-4NFY2S7N.js";
@@ -108,46 +107,13 @@ import {
108
107
  setRateLimiter,
109
108
  unsafeRevealSecret,
110
109
  validateMcpRuntimeServerName
111
- } from "./chunk-RGSBTHSU.js";
110
+ } from "./chunk-KMS57JDD.js";
112
111
  import {
113
- isLoopbackBind
114
- } from "./chunk-RXFQM6FQ.js";
112
+ isLoopbackBind,
113
+ normalizeSessionIdForLookup,
114
+ parseCallerSuppliedSessionId
115
+ } from "./chunk-TQOF5KBL.js";
115
116
  import "./chunk-HGCQ5SE7.js";
116
- import {
117
- createTotalSessionAdmissionController
118
- } from "./chunk-AKA24BGO.js";
119
- import {
120
- WorkspaceGenerationClosedError,
121
- createSingleWorkspaceRegistry,
122
- createWorkspaceSessionOwnerIndex
123
- } from "./chunk-2M5N3DHY.js";
124
- import "./chunk-GRC5HGPI.js";
125
- import {
126
- assertValidChannelSecretUpdates
127
- } from "./chunk-H2UQ2M5Z.js";
128
- import {
129
- createWorkspaceProvidersStatusProvider
130
- } from "./chunk-W4B7UBUS.js";
131
- import {
132
- getAuthTypeFromEnv,
133
- resolveCliGenerationConfig
134
- } from "./chunk-CSZEXZBE.js";
135
- import {
136
- createWorkspaceSkillsStatusProvider
137
- } from "./chunk-P3LEG54R.js";
138
- import "./chunk-BGXZBI5B.js";
139
- import {
140
- isServeDebugMode,
141
- mountWebShellAssets,
142
- mountWebShellSpaFallback
143
- } from "./chunk-SOORFWKY.js";
144
- import {
145
- require_express
146
- } from "./chunk-GDXET5XU.js";
147
- import {
148
- evaluateDaemonWorkspaceTrust,
149
- readDaemonTrustPolicySnapshot
150
- } from "./chunk-OMKQH5C5.js";
151
117
  import {
152
118
  EMPTY_WORKSPACE_VOICE_UPDATE_ERROR,
153
119
  MAX_WORKSPACE_SKILL_NAME_LENGTH,
@@ -161,14 +127,14 @@ import {
161
127
  validateWorkspaceSkillName,
162
128
  validateWorkspaceVoiceState,
163
129
  voiceSettingsScopeToWire
164
- } from "./chunk-RERATVSK.js";
130
+ } from "./chunk-7XX5IBXL.js";
165
131
  import {
166
132
  PermissionRulesValidationError,
167
133
  buildPermissionSettings,
168
134
  isPermissionRuleType,
169
135
  normalizePermissionRules,
170
136
  readPermissionRuleSet
171
- } from "./chunk-6GONZVLS.js";
137
+ } from "./chunk-NZMXUSKS.js";
172
138
  import {
173
139
  assertVoiceBaseUrlNetworkAllowed,
174
140
  isStreamingVoiceModel,
@@ -176,46 +142,92 @@ import {
176
142
  resolveVoiceTranscriptionConfig,
177
143
  sanitizeVoiceErrorMessage,
178
144
  transcribeVoiceAudio
179
- } from "./chunk-AE77C5ZU.js";
145
+ } from "./chunk-RYQMJCUO.js";
180
146
  import {
181
147
  isVoiceEnabled,
182
148
  isVoiceMode,
183
149
  readVoiceModel
184
- } from "./chunk-55LYDVPU.js";
150
+ } from "./chunk-HDYQYYWB.js";
185
151
  import "./chunk-AOHJKPKL.js";
152
+ import {
153
+ createTotalSessionAdmissionController
154
+ } from "./chunk-BT6GQIEJ.js";
155
+ import {
156
+ WorkspaceGenerationClosedError,
157
+ createSingleWorkspaceRegistry,
158
+ createWorkspaceSessionOwnerIndex
159
+ } from "./chunk-CMOBWHWW.js";
160
+ import "./chunk-OIBUG24X.js";
161
+ import {
162
+ MAX_SESSION_RESTORE_TIMEOUT_MS,
163
+ resolveSessionRestoreTimeoutMs,
164
+ restoreRetryAfterSeconds
165
+ } from "./chunk-4JRM2BSM.js";
166
+ import {
167
+ assertValidChannelSecretUpdates
168
+ } from "./chunk-EUVOKP6Y.js";
169
+ import {
170
+ createDaemonStatusProvider
171
+ } from "./chunk-UAB6J2IE.js";
172
+ import "./chunk-NTTBXH7U.js";
173
+ import "./chunk-2ASQDZSJ.js";
174
+ import "./chunk-3SH53ANB.js";
175
+ import {
176
+ createWorkspaceProvidersStatusProvider
177
+ } from "./chunk-VHXPSL57.js";
178
+ import {
179
+ getAuthTypeFromEnv,
180
+ resolveCliGenerationConfig
181
+ } from "./chunk-HWXGX534.js";
182
+ import {
183
+ snapshotProcessEnv
184
+ } from "./chunk-OR6R3IUW.js";
185
+ import {
186
+ createWorkspaceSkillsStatusProvider
187
+ } from "./chunk-F6TUUA2U.js";
188
+ import "./chunk-BGXZBI5B.js";
186
189
  import "./chunk-Z4X5MTRT.js";
187
190
  import {
188
191
  WorkspacePermissionRulesSessionRequiredError,
189
192
  WorkspaceSettingsPartialPersistError,
190
- WorkspaceSkillNotFoundError,
191
- WorkspaceSkillNotToggleableError
192
- } from "./chunk-OA4JVLSA.js";
193
+ mapWorkspaceSkillToggleError
194
+ } from "./chunk-Z7VOMGDC.js";
195
+ import {
196
+ isServeDebugMode,
197
+ mountWebShellAssets,
198
+ mountWebShellSpaFallback
199
+ } from "./chunk-SOORFWKY.js";
200
+ import {
201
+ require_express
202
+ } from "./chunk-GDXET5XU.js";
203
+ import {
204
+ evaluateDaemonWorkspaceTrust,
205
+ readDaemonTrustPolicySnapshot
206
+ } from "./chunk-FWWQIFDT.js";
193
207
  import {
194
208
  daemonObservedContactsPath,
195
209
  loadChannelsConfig
196
- } from "./chunk-EUQTXRKZ.js";
197
- import "./chunk-OHJLEW5J.js";
210
+ } from "./chunk-EISUQQPS.js";
211
+ import "./chunk-TWFFY5BP.js";
198
212
  import "./chunk-57OAHC2Y.js";
213
+ import {
214
+ parseChannelWebhookConfigLenient
215
+ } from "./chunk-LHEC5V6G.js";
216
+ import "./chunk-67EWJE77.js";
217
+ import {
218
+ supportedChannelCatalog
219
+ } from "./chunk-E2FPSSKP.js";
199
220
  import {
200
221
  LIVE_HOST_BUNDLE_ID,
201
222
  LIVE_HOST_PROTOCOL_VERSION,
202
223
  LIVE_INPUT_AUDIO_EPOCH_BYTES
203
224
  } from "./chunk-NKLP3DCK.js";
204
- import {
205
- createDaemonStatusProvider
206
- } from "./chunk-YJQCUTT2.js";
207
- import "./chunk-VXZBKKQR.js";
208
- import "./chunk-SPMY6CX6.js";
209
- import "./chunk-3SH53ANB.js";
210
- import {
211
- snapshotProcessEnv
212
- } from "./chunk-TYKC75AX.js";
213
225
  import {
214
226
  SessionArtifactAuthorizationError,
215
227
  SessionArtifactValidationError,
216
228
  createAcpSessionBridge,
217
229
  parseSessionSource
218
- } from "./chunk-LA7YLSR6.js";
230
+ } from "./chunk-4EOURKA4.js";
219
231
  import {
220
232
  EVENT_SCHEMA_VERSION,
221
233
  EventBus,
@@ -223,22 +235,16 @@ import {
223
235
  } from "./chunk-MZSJ43WV.js";
224
236
  import "./chunk-XCGIMOLN.js";
225
237
  import "./chunk-OCPBI7J5.js";
226
- import "./chunk-E33LOKRA.js";
238
+ import "./chunk-I5VM3SKY.js";
227
239
  import {
228
240
  STATUS_SCHEMA_VERSION,
241
+ SessionRestoreTimeoutError,
229
242
  createIdleWorkspaceMemoryStatus,
230
243
  mapDomainErrorToErrorKind
231
- } from "./chunk-NLREQJFK.js";
244
+ } from "./chunk-DA4HRSBW.js";
232
245
  import "./chunk-K6KS3LTN.js";
233
246
  import "./chunk-FC4KQFCS.js";
234
247
  import "./chunk-T3CHYWJZ.js";
235
- import {
236
- parseChannelWebhookConfigLenient
237
- } from "./chunk-ZXU5UHMI.js";
238
- import "./chunk-VWOVHOTT.js";
239
- import {
240
- supportedChannelCatalog
241
- } from "./chunk-IUFV6FYU.js";
242
248
  import "./chunk-V6WHFGST.js";
243
249
  import {
244
250
  MAX_REGISTERED_WORKSPACES,
@@ -247,10 +253,14 @@ import {
247
253
  WorkspaceRegistrationStoreLimitError,
248
254
  normalizeWorkspaceDisplayName,
249
255
  workspaceRegistrationId
250
- } from "./chunk-P2AJ7FTI.js";
251
- import "./chunk-R574ATRM.js";
256
+ } from "./chunk-H4JC7LZX.js";
257
+ import {
258
+ REQUESTED_SESSION_ID_META_KEY,
259
+ gradeActiveWorkCoverage
260
+ } from "./chunk-M2PNLYGY.js";
252
261
  import {
253
262
  BranchWhilePromptActiveError,
263
+ BridgeChannelQuarantinedError,
254
264
  CancelSentinelCollisionError,
255
265
  CdWhilePromptActiveError,
256
266
  InvalidClientIdError,
@@ -281,7 +291,7 @@ import {
281
291
  WorkspaceInitRaceError,
282
292
  WorkspaceInitSymlinkError,
283
293
  WorkspaceMismatchError
284
- } from "./chunk-J26HHFI5.js";
294
+ } from "./chunk-LP2QGNSP.js";
285
295
  import {
286
296
  MAX_WORKSPACE_PATH_LENGTH,
287
297
  canonicalizeWorkspace,
@@ -300,19 +310,19 @@ import {
300
310
  } from "./chunk-YP5KH5Y7.js";
301
311
  import {
302
312
  normalizeWorkerDiagnostic
303
- } from "./chunk-24ER7UV4.js";
313
+ } from "./chunk-PBRVUF5B.js";
304
314
  import {
305
315
  normalizeServeChannelSelection
306
316
  } from "./chunk-ALMR3E6Q.js";
307
317
  import "./chunk-HIBNSEJE.js";
308
- import "./chunk-BKHCW2BI.js";
309
318
  import {
310
319
  redactLogCredentials
311
320
  } from "./chunk-M5GB774H.js";
321
+ import "./chunk-BKHCW2BI.js";
312
322
  import "./chunk-5HBA2Z7V.js";
313
323
  import {
314
324
  sanitizeLogText
315
- } from "./chunk-DIEFUBV6.js";
325
+ } from "./chunk-DX3RGJMS.js";
316
326
  import "./chunk-UDXSXLER.js";
317
327
  import {
318
328
  getDialogSettingKeys,
@@ -323,7 +333,7 @@ import {
323
333
  getWritableScopes,
324
334
  loadSettings,
325
335
  validateSettingValue
326
- } from "./chunk-PQBHU2IA.js";
336
+ } from "./chunk-HKI3KHAO.js";
327
337
  import "./chunk-RKUWKYED.js";
328
338
  import "./chunk-GOXKNSDZ.js";
329
339
  import "./chunk-IDS7MSUP.js";
@@ -332,15 +342,15 @@ import {
332
342
  detectSystemLanguage,
333
343
  resolveLanguageSetting,
334
344
  resolveSupportedLanguage
335
- } from "./chunk-DBOFL3LQ.js";
336
- import "./chunk-VOARQPTA.js";
337
- import "./chunk-6PEXNQTX.js";
338
- import "./chunk-FZBZSYKU.js";
345
+ } from "./chunk-BL65MO72.js";
346
+ import "./chunk-KP25NJNM.js";
347
+ import "./chunk-R4ZA6GBK.js";
348
+ import "./chunk-ZV7LTLFE.js";
339
349
  import "./chunk-VJNBRRZG.js";
340
350
  import {
341
351
  getWorkspaceTrustStatus
342
- } from "./chunk-6XU3PH66.js";
343
- import "./chunk-ALGGS7UH.js";
352
+ } from "./chunk-YR7ZQ4RD.js";
353
+ import "./chunk-NPQ5ZKRP.js";
344
354
  import {
345
355
  isWithinRoot as isWithinRoot2
346
356
  } from "./chunk-MR3PXB6E.js";
@@ -360,6 +370,7 @@ import {
360
370
  MAX_LOG_LIMIT,
361
371
  ModelsConfig,
362
372
  RUNTIME_MCP_IF_ABSENT_CONFIG_FLAG,
373
+ SESSION_TRANSCRIPT_MAX_EXPANDED_PAGE_BYTES,
363
374
  SESSION_TRANSCRIPT_MAX_INDEX_BYTES,
364
375
  SESSION_TRANSCRIPT_MAX_LIMIT,
365
376
  SESSION_TRANSCRIPT_MAX_PAGE_BYTES,
@@ -418,7 +429,7 @@ import {
418
429
  writeWorkspaceContextFile,
419
430
  writeWorktreeSession,
420
431
  writeWorktreeSessionMarker
421
- } from "./chunk-Y7E5LNLO.js";
432
+ } from "./chunk-47ZUMGGY.js";
422
433
  import "./chunk-GOFAQQZA.js";
423
434
  import "./chunk-5M6IDOMF.js";
424
435
  import "./chunk-TWPJO254.js";
@@ -426,12 +437,12 @@ import "./chunk-H6XPXXMH.js";
426
437
  import {
427
438
  MAX_JOBS,
428
439
  nextDurableFireMs
429
- } from "./chunk-CNIID3TV.js";
440
+ } from "./chunk-2UUMVNYT.js";
430
441
  import "./chunk-MVUQRLOH.js";
431
442
  import "./chunk-XCWO3SMQ.js";
432
443
  import "./chunk-7MH4J33A.js";
433
444
  import "./chunk-6PVPNMXU.js";
434
- import "./chunk-RMH5OWLD.js";
445
+ import "./chunk-F3II4BTZ.js";
435
446
  import {
436
447
  nextFireTime,
437
448
  parseCron
@@ -445,7 +456,7 @@ import {
445
456
  taskHasLegacyCondition,
446
457
  updateCronTasks
447
458
  } from "./chunk-GNPNYXJB.js";
448
- import "./chunk-Y4NGLFGJ.js";
459
+ import "./chunk-HUWENAHO.js";
449
460
  import "./chunk-O6GEWCJA.js";
450
461
  import "./chunk-T26EAKDL.js";
451
462
  import "./chunk-ZPJWUGCS.js";
@@ -454,22 +465,37 @@ import "./chunk-J6SZID63.js";
454
465
  import "./chunk-KRXPRVGL.js";
455
466
  import "./chunk-GM463R2B.js";
456
467
  import "./chunk-SEZ556DZ.js";
457
- import "./chunk-CJXIIILK.js";
458
- import "./chunk-3K7FH2KQ.js";
468
+ import "./chunk-2FRY5CRX.js";
469
+ import "./chunk-67N6HB5H.js";
459
470
  import {
460
471
  APPROVAL_MODES
461
- } from "./chunk-BVWVWGLE.js";
472
+ } from "./chunk-WAUGQKUU.js";
473
+ import "./chunk-DZUO626D.js";
474
+ import {
475
+ addDaemonRequestAttribute,
476
+ captureDaemonTelemetryContext,
477
+ emitDaemonLog,
478
+ hashDaemonWorkspace,
479
+ recordDaemonBridgeError,
480
+ recordDaemonError,
481
+ recordDaemonHttpRequest,
482
+ recordDaemonHttpResponse,
483
+ runWithDaemonTelemetryContext,
484
+ withDaemonRequestSpan
485
+ } from "./chunk-4TRQPFDP.js";
486
+ import "./chunk-SAH4BD2J.js";
487
+ import "./chunk-CPG6P4GG.js";
462
488
  import "./chunk-S6LOFUVP.js";
489
+ import "./chunk-2J3OJGTL.js";
463
490
  import {
464
491
  SubagentError,
465
492
  SubagentErrorCode
466
- } from "./chunk-LZC3B5N2.js";
493
+ } from "./chunk-IA7TGCN2.js";
467
494
  import "./chunk-K623ENWT.js";
468
495
  import {
469
496
  escapeXml
470
497
  } from "./chunk-AQ37AY7B.js";
471
498
  import "./chunk-EQL65XGA.js";
472
- import "./chunk-IIJEYBNH.js";
473
499
  import {
474
500
  QwenOAuth2Client,
475
501
  QwenOAuthPollError,
@@ -478,31 +504,18 @@ import {
478
504
  isDeviceAuthorizationSuccess,
479
505
  isDeviceTokenPending,
480
506
  isDeviceTokenSuccess
481
- } from "./chunk-22NBYCPD.js";
507
+ } from "./chunk-3P2LV43B.js";
482
508
  import "./chunk-NAVJD2PQ.js";
483
- import "./chunk-3ULCB3NE.js";
484
- import "./chunk-BGG4MBYD.js";
509
+ import "./chunk-HV76SFIA.js";
510
+ import "./chunk-4PYCZH2V.js";
511
+ import "./chunk-P3QQPMQA.js";
512
+ import "./chunk-SR7RZ4MS.js";
513
+ import "./chunk-M6HMMKVG.js";
485
514
  import "./chunk-DGEIYUC3.js";
486
515
  import "./chunk-MPHPFVKK.js";
487
516
  import "./chunk-AXMWHKXA.js";
488
- import "./chunk-DJ2GSRLV.js";
489
- import "./chunk-33ACCIIY.js";
490
- import {
491
- addDaemonRequestAttribute,
492
- captureDaemonTelemetryContext,
493
- emitDaemonLog,
494
- hashDaemonWorkspace,
495
- recordDaemonBridgeError,
496
- recordDaemonError,
497
- recordDaemonHttpRequest,
498
- recordDaemonHttpResponse,
499
- runWithDaemonTelemetryContext,
500
- withDaemonRequestSpan
501
- } from "./chunk-L4N6TIP7.js";
502
- import "./chunk-2J3OJGTL.js";
503
- import "./chunk-P3QQPMQA.js";
504
- import "./chunk-M6HMMKVG.js";
505
517
  import "./chunk-GLCZKT5V.js";
518
+ import "./chunk-DJ2GSRLV.js";
506
519
  import "./chunk-EI3HZX6C.js";
507
520
  import "./chunk-CR3C7WXL.js";
508
521
  import "./chunk-XWRJCPHC.js";
@@ -516,25 +529,28 @@ import {
516
529
  isWithinRoot,
517
530
  parseLineTolerant,
518
531
  read
519
- } from "./chunk-2U3WZGZG.js";
532
+ } from "./chunk-YGT2AUJ7.js";
520
533
  import "./chunk-WOJZWRAZ.js";
521
534
  import "./chunk-VGC4I5JJ.js";
522
535
  import "./chunk-FVKHVJZQ.js";
523
- import "./chunk-NG2R4N5O.js";
524
- import "./chunk-IC4Z6LX6.js";
525
- import "./chunk-6EOI4HOK.js";
536
+ import "./chunk-COBO5EBO.js";
537
+ import "./chunk-6ZRFAKXK.js";
538
+ import "./chunk-PYQADEFD.js";
539
+ import "./chunk-E2T7FLDU.js";
540
+ import "./chunk-F6WFNA7U.js";
526
541
  import "./chunk-46UV252V.js";
527
542
  import "./chunk-ZBVS26BY.js";
528
543
  import "./chunk-KKBPOU75.js";
529
544
  import "./chunk-EUNWC2VS.js";
530
545
  import "./chunk-FOGU3LJX.js";
531
- import "./chunk-6M26GBKX.js";
546
+ import "./chunk-L2AFWWJE.js";
532
547
  import "./chunk-W4RQUHY3.js";
533
- import "./chunk-LKRMNRSN.js";
548
+ import "./chunk-PDPFQ2FO.js";
534
549
  import {
535
550
  FatalConfigError,
536
551
  Storage,
537
552
  createDebugLogger,
553
+ getErrorMessage,
538
554
  runWithoutDebugLogSession
539
555
  } from "./chunk-OIVKILPI.js";
540
556
  import "./chunk-VOQXFAY5.js";
@@ -563,7 +579,7 @@ import {
563
579
 
564
580
  // packages/cli/src/serve/server.ts
565
581
  init_esbuild_shims();
566
- var import_express4 = __toESM(require_express(), 1);
582
+ var import_express5 = __toESM(require_express(), 1);
567
583
 
568
584
  // packages/cli/src/serve/acp-http/index.ts
569
585
  init_esbuild_shims();
@@ -1180,11 +1196,11 @@ function decodeTextCursor(cursor) {
1180
1196
  return { off, size, dev, ino };
1181
1197
  }
1182
1198
  __name(decodeTextCursor, "decodeTextCursor");
1183
- function assertCursorMatchesFile(cursor, stats, path14) {
1199
+ function assertCursorMatchesFile(cursor, stats, path15) {
1184
1200
  if (String(stats.dev) !== cursor.dev || String(stats.ino) !== cursor.ino || stats.size < cursor.size) {
1185
1201
  throw new FsError(
1186
1202
  "hash_mismatch",
1187
- `cursor no longer matches the file it was issued for: ${path14}`,
1203
+ `cursor no longer matches the file it was issued for: ${path15}`,
1188
1204
  { hint: "re-read the file from the beginning to get a fresh cursor" }
1189
1205
  );
1190
1206
  }
@@ -1946,17 +1962,17 @@ var WorkspaceFileSystemImpl = class {
1946
1962
  if (err instanceof Error && "code" in err && err.code === "workspace_generation_closed") {
1947
1963
  return err;
1948
1964
  }
1949
- const fs7 = wrapAsFsError(err);
1965
+ const fs8 = wrapAsFsError(err);
1950
1966
  this.deps.audit.recordDenied(this.deps.ctx, {
1951
1967
  intent,
1952
1968
  input,
1953
- errorKind: fs7.kind,
1954
- hint: fs7.hint,
1969
+ errorKind: fs8.kind,
1970
+ hint: fs8.hint,
1955
1971
  // Quote the underlying OS / FsError message so audit
1956
1972
  // consumers debugging a production incident can see the
1957
1973
  // actual cause (errno text, byte counts, glob pattern,
1958
1974
  // etc.) rather than just `errorKind` + `hint`.
1959
- message: fs7.message,
1975
+ message: fs8.message,
1960
1976
  // For glob denials (parse_error pattern rejection,
1961
1977
  // catastrophic walk failures) the input IS the pattern
1962
1978
  // already; surfacing it on the dedicated `pattern` field
@@ -1965,7 +1981,7 @@ var WorkspaceFileSystemImpl = class {
1965
1981
  // branching on intent.
1966
1982
  pattern: intent === "glob" ? input : void 0
1967
1983
  });
1968
- return fs7;
1984
+ return fs8;
1969
1985
  }
1970
1986
  };
1971
1987
  var CONTENT_HASH_RE = /^sha256:[0-9a-f]{64}$/;
@@ -3041,12 +3057,12 @@ function sendFsError(res, err, route) {
3041
3057
  applyReadHeaders(res);
3042
3058
  if (sendGenerationClosedError(res, err)) return;
3043
3059
  if (isFsError(err)) {
3044
- const fs7 = err;
3045
- res.status(fs7.status).json({
3046
- errorKind: fs7.kind,
3047
- error: fs7.message,
3048
- hint: fs7.hint,
3049
- status: fs7.status
3060
+ const fs8 = err;
3061
+ res.status(fs8.status).json({
3062
+ errorKind: fs8.kind,
3063
+ error: fs8.message,
3064
+ hint: fs8.hint,
3065
+ status: fs8.status
3050
3066
  });
3051
3067
  return;
3052
3068
  }
@@ -3159,13 +3175,13 @@ async function handleGetFile(req, res, deps) {
3159
3175
  return;
3160
3176
  }
3161
3177
  const cursor = rawCursor;
3162
- const fs7 = factory.forRequest({
3178
+ const fs8 = factory.forRequest({
3163
3179
  originatorClientId: clientId ?? void 0,
3164
3180
  route: ROUTE2
3165
3181
  });
3166
3182
  try {
3167
- const resolved = await fs7.resolve(queryPath, "read");
3168
- const out = await fs7.readText(resolved, {
3183
+ const resolved = await fs8.resolve(queryPath, "read");
3184
+ const out = await fs8.readText(resolved, {
3169
3185
  maxBytes,
3170
3186
  line,
3171
3187
  limit,
@@ -3226,13 +3242,13 @@ async function handleGetFileBytes(req, res, deps) {
3226
3242
  });
3227
3243
  return;
3228
3244
  }
3229
- const fs7 = factory.forRequest({
3245
+ const fs8 = factory.forRequest({
3230
3246
  originatorClientId: clientId ?? void 0,
3231
3247
  route: ROUTE2
3232
3248
  });
3233
3249
  try {
3234
- const resolved = await fs7.resolve(queryPath, "read");
3235
- const out = await fs7.readBytesWindow(resolved, {
3250
+ const resolved = await fs8.resolve(queryPath, "read");
3251
+ const out = await fs8.readBytesWindow(resolved, {
3236
3252
  offset: offset ?? 0,
3237
3253
  maxBytes: maxBytes ?? DEFAULT_FILE_BYTES_MAX_BYTES
3238
3254
  });
@@ -3260,13 +3276,13 @@ async function handleGetStat(req, res, deps) {
3260
3276
  if (clientId === null) return;
3261
3277
  const queryPath = requireStringQuery(res, req.query["path"], "path", ROUTE2);
3262
3278
  if (queryPath === null) return;
3263
- const fs7 = factory.forRequest({
3279
+ const fs8 = factory.forRequest({
3264
3280
  originatorClientId: clientId ?? void 0,
3265
3281
  route: ROUTE2
3266
3282
  });
3267
3283
  try {
3268
- const resolved = await fs7.resolve(queryPath, "stat");
3269
- const st = await fs7.stat(resolved);
3284
+ const resolved = await fs8.resolve(queryPath, "stat");
3285
+ const st = await fs8.stat(resolved);
3270
3286
  applyReadHeaders(res);
3271
3287
  res.status(200).json({
3272
3288
  kind: "stat",
@@ -3289,13 +3305,13 @@ async function handleGetList(req, res, deps) {
3289
3305
  const queryPath = requireStringQuery(res, req.query["path"], "path", ROUTE2);
3290
3306
  if (queryPath === null) return;
3291
3307
  const includeIgnored = parseBoolFlag(req.query["includeIgnored"]);
3292
- const fs7 = factory.forRequest({
3308
+ const fs8 = factory.forRequest({
3293
3309
  originatorClientId: clientId ?? void 0,
3294
3310
  route: ROUTE2
3295
3311
  });
3296
3312
  try {
3297
- const resolved = await fs7.resolve(queryPath, "list");
3298
- const entries = await fs7.list(resolved, {
3313
+ const resolved = await fs8.resolve(queryPath, "list");
3314
+ const entries = await fs8.list(resolved, {
3299
3315
  includeIgnored,
3300
3316
  maxEntries: MAX_LIST_ENTRIES + 1
3301
3317
  });
@@ -3348,15 +3364,15 @@ async function handleGetGlob(req, res, deps) {
3348
3364
  }
3349
3365
  const cwdRaw = req.query["cwd"];
3350
3366
  const cwdString = typeof cwdRaw === "string" && cwdRaw.length > 0 ? cwdRaw : void 0;
3351
- const fs7 = factory.forRequest({
3367
+ const fs8 = factory.forRequest({
3352
3368
  originatorClientId: clientId ?? void 0,
3353
3369
  route: ROUTE2
3354
3370
  });
3355
3371
  const start = performance.now();
3356
3372
  try {
3357
- const cwdResolved = cwdString ? await fs7.resolve(cwdString, "list") : void 0;
3373
+ const cwdResolved = cwdString ? await fs8.resolve(cwdString, "list") : void 0;
3358
3374
  const cap = maxResults ?? DEFAULT_GLOB_MAX_RESULTS;
3359
- const probe = await fs7.glob(pattern, {
3375
+ const probe = await fs8.glob(pattern, {
3360
3376
  cwd: cwdResolved,
3361
3377
  includeIgnored,
3362
3378
  maxResults: cap + 1
@@ -3544,7 +3560,7 @@ function validateClientId(clientId, deps, res) {
3544
3560
  }
3545
3561
  __name(validateClientId, "validateClientId");
3546
3562
  function createSetupGithubFileOps(factory, route, originatorClientId, assertGenerationOpen) {
3547
- const fs7 = factory.forRequest({
3563
+ const fs8 = factory.forRequest({
3548
3564
  route,
3549
3565
  ...originatorClientId ? { originatorClientId } : {}
3550
3566
  });
@@ -3572,14 +3588,14 @@ function createSetupGithubFileOps(factory, route, originatorClientId, assertGene
3572
3588
  );
3573
3589
  },
3574
3590
  async writeTextFile(_gitRepoRoot, relativePath, content) {
3575
- const resolved = await fs7.resolve(relativePath, "write");
3576
- const out = await fs7.writeTextOverwrite(resolved, content);
3591
+ const resolved = await fs8.resolve(relativePath, "write");
3592
+ const out = await fs8.writeTextOverwrite(resolved, content);
3577
3593
  return { sizeBytes: out.sizeBytes };
3578
3594
  },
3579
3595
  async readTextFile(_gitRepoRoot, relativePath) {
3580
3596
  try {
3581
- const resolved = await fs7.resolve(relativePath, "read");
3582
- const out = await fs7.readText(resolved);
3597
+ const resolved = await fs8.resolve(relativePath, "read");
3598
+ const out = await fs8.readText(resolved);
3583
3599
  return out.content;
3584
3600
  } catch (error2) {
3585
3601
  if (isFsError(error2) && error2.kind === "path_not_found") {
@@ -5160,6 +5176,214 @@ function mountWorkspaceQualifiedMemoryRememberRoutes(app, deps) {
5160
5176
  }
5161
5177
  __name(mountWorkspaceQualifiedMemoryRememberRoutes, "mountWorkspaceQualifiedMemoryRememberRoutes");
5162
5178
 
5179
+ // packages/cli/src/serve/session-id-admission.ts
5180
+ init_esbuild_shims();
5181
+ import { access } from "node:fs/promises";
5182
+ var RequestedSessionIdAdmissionError = class extends Error {
5183
+ constructor(code, sessionId, message, details = {}) {
5184
+ super(message);
5185
+ this.code = code;
5186
+ this.sessionId = sessionId;
5187
+ this.details = details;
5188
+ }
5189
+ static {
5190
+ __name(this, "RequestedSessionIdAdmissionError");
5191
+ }
5192
+ name = "RequestedSessionIdAdmissionError";
5193
+ };
5194
+ async function persistedSessionExists(sessionService, sessionId) {
5195
+ if (await sessionService.getSessionLocation(sessionId) !== void 0) {
5196
+ return true;
5197
+ }
5198
+ if (await sessionService.findSessionIdIgnoringCase?.(sessionId) !== void 0) {
5199
+ return true;
5200
+ }
5201
+ for (const state of ["active", "archived"]) {
5202
+ try {
5203
+ await access(
5204
+ sessionService.getWorktreeSessionPathForArchiveState(sessionId, state)
5205
+ );
5206
+ return true;
5207
+ } catch (error2) {
5208
+ if (error2.code !== "ENOENT") throw error2;
5209
+ }
5210
+ }
5211
+ return false;
5212
+ }
5213
+ __name(persistedSessionExists, "persistedSessionExists");
5214
+ function createRequestedSessionIdAdmission({
5215
+ archiveCoordinator,
5216
+ getBridges,
5217
+ getPersistenceTargets,
5218
+ getBridgeWorkspaceId
5219
+ }) {
5220
+ const pending = /* @__PURE__ */ new Map();
5221
+ const liveOwners = /* @__PURE__ */ __name((sessionId) => {
5222
+ const owners = [];
5223
+ let bridges;
5224
+ try {
5225
+ bridges = getBridges();
5226
+ } catch {
5227
+ throw new RequestedSessionIdAdmissionError(
5228
+ "session_id_admission_unavailable",
5229
+ sessionId,
5230
+ `Unable to enumerate live bridges for session "${sessionId}".`,
5231
+ { retryable: true }
5232
+ );
5233
+ }
5234
+ for (const bridge of new Set(bridges)) {
5235
+ try {
5236
+ const summary = bridge.getSessionSummary(sessionId);
5237
+ owners.push({
5238
+ bridge,
5239
+ workspaceCwd: summary.workspaceCwd,
5240
+ workspaceId: getBridgeWorkspaceId?.(bridge)
5241
+ });
5242
+ } catch (error2) {
5243
+ if (error2 instanceof SessionNotFoundError) continue;
5244
+ throw new RequestedSessionIdAdmissionError(
5245
+ "session_id_admission_unavailable",
5246
+ sessionId,
5247
+ `Unable to verify whether session "${sessionId}" is already live.`,
5248
+ { retryable: true }
5249
+ );
5250
+ }
5251
+ }
5252
+ return owners;
5253
+ }, "liveOwners");
5254
+ const conflict = /* @__PURE__ */ __name((sessionId, conflictKind, workspaceCwd) => new RequestedSessionIdAdmissionError(
5255
+ "session_id_conflict",
5256
+ sessionId,
5257
+ `Session "${sessionId}" already exists or is being created.`,
5258
+ {
5259
+ conflict: conflictKind,
5260
+ ...workspaceCwd ? { liveWorkspaceCwd: workspaceCwd } : {}
5261
+ }
5262
+ ), "conflict");
5263
+ const workspaceConflict = /* @__PURE__ */ __name((sessionId, target, conflictKind, liveWorkspaceCwd, liveWorkspaceId) => new RequestedSessionIdAdmissionError(
5264
+ "session_workspace_conflict",
5265
+ sessionId,
5266
+ `Session "${sessionId}" is already live or restoring in another workspace runtime.`,
5267
+ {
5268
+ conflict: conflictKind,
5269
+ workspaceCwd: target.workspaceCwd,
5270
+ ...target.workspaceId ? { workspaceId: target.workspaceId } : {},
5271
+ ...liveWorkspaceCwd ? { liveWorkspaceCwd } : {},
5272
+ ...liveWorkspaceId ? { liveWorkspaceId } : {}
5273
+ }
5274
+ ), "workspaceConflict");
5275
+ const createReservation = /* @__PURE__ */ __name((sessionId, state) => {
5276
+ let released = false;
5277
+ return {
5278
+ release() {
5279
+ if (released) return;
5280
+ released = true;
5281
+ if (pending.get(sessionId) !== state) return;
5282
+ if (state.kind === "restore" && state.count > 1) {
5283
+ state.count--;
5284
+ return;
5285
+ }
5286
+ pending.delete(sessionId);
5287
+ }
5288
+ };
5289
+ }, "createReservation");
5290
+ return {
5291
+ async reserveCreate(rawSessionId, target) {
5292
+ const sessionId = normalizeSessionIdForLookup(rawSessionId);
5293
+ const live = liveOwners(sessionId)[0];
5294
+ if (live) throw conflict(sessionId, "live", live.workspaceCwd);
5295
+ if (pending.has(sessionId)) throw conflict(sessionId, "pending");
5296
+ const state = { kind: "create", target };
5297
+ pending.set(sessionId, state);
5298
+ const reservation = createReservation(sessionId, state);
5299
+ try {
5300
+ let persisted;
5301
+ try {
5302
+ persisted = await archiveCoordinator.runSharedMany(
5303
+ [sessionId],
5304
+ async () => {
5305
+ const targets = [
5306
+ ...new Map(
5307
+ getPersistenceTargets().map((entry) => [
5308
+ `${entry.runtimeBaseDir}\0${entry.workspaceCwd}`,
5309
+ entry
5310
+ ])
5311
+ ).values()
5312
+ ];
5313
+ const results = await Promise.all(
5314
+ targets.map(async (entry) => {
5315
+ const sessionService = new SessionService(
5316
+ entry.workspaceCwd,
5317
+ { runtimeBaseDir: entry.runtimeBaseDir }
5318
+ );
5319
+ return {
5320
+ entry,
5321
+ exists: await persistedSessionExists(
5322
+ sessionService,
5323
+ sessionId
5324
+ )
5325
+ };
5326
+ })
5327
+ );
5328
+ return results.find((result) => result.exists)?.entry;
5329
+ }
5330
+ );
5331
+ } catch {
5332
+ throw new RequestedSessionIdAdmissionError(
5333
+ "session_id_admission_unavailable",
5334
+ sessionId,
5335
+ `Unable to verify persisted state for session "${sessionId}".`,
5336
+ { retryable: true }
5337
+ );
5338
+ }
5339
+ if (persisted) {
5340
+ throw conflict(sessionId, "persisted", persisted.workspaceCwd);
5341
+ }
5342
+ return reservation;
5343
+ } catch (error2) {
5344
+ reservation.release();
5345
+ throw error2;
5346
+ }
5347
+ },
5348
+ reserveRestore(rawSessionId, target) {
5349
+ const sessionId = normalizeSessionIdForLookup(rawSessionId);
5350
+ const foreignLive = liveOwners(sessionId).find(
5351
+ (owner) => owner.bridge !== target.bridge
5352
+ );
5353
+ if (foreignLive) {
5354
+ throw workspaceConflict(
5355
+ sessionId,
5356
+ target,
5357
+ "live",
5358
+ foreignLive.workspaceCwd,
5359
+ foreignLive.workspaceId
5360
+ );
5361
+ }
5362
+ const existing = pending.get(sessionId);
5363
+ if (existing?.kind === "create") {
5364
+ throw conflict(sessionId, "pending");
5365
+ }
5366
+ if (existing?.kind === "restore") {
5367
+ if (existing.target.bridge !== target.bridge) {
5368
+ throw workspaceConflict(
5369
+ sessionId,
5370
+ target,
5371
+ "pending",
5372
+ existing.target.workspaceCwd,
5373
+ existing.target.workspaceId
5374
+ );
5375
+ }
5376
+ existing.count++;
5377
+ return createReservation(sessionId, existing);
5378
+ }
5379
+ const state = { kind: "restore", target, count: 1 };
5380
+ pending.set(sessionId, state);
5381
+ return createReservation(sessionId, state);
5382
+ }
5383
+ };
5384
+ }
5385
+ __name(createRequestedSessionIdAdmission, "createRequestedSessionIdAdmission");
5386
+
5163
5387
  // packages/cli/src/serve/workspace-memory.ts
5164
5388
  init_esbuild_shims();
5165
5389
  import { promises as fs2 } from "node:fs";
@@ -8207,6 +8431,9 @@ var TRUSTED_WORKSPACE_METHODS = /* @__PURE__ */ new Set([
8207
8431
  `${QWEN_METHOD_NS}workspace/session_groups/delete`
8208
8432
  ]);
8209
8433
  var WORKSPACE_GENERATION_MUTATION_METHODS = /* @__PURE__ */ new Set([
8434
+ "session/new",
8435
+ "session/load",
8436
+ "session/resume",
8210
8437
  `${QWEN_METHOD_NS}workspace/init`,
8211
8438
  `${QWEN_METHOD_NS}workspace/trust/request`,
8212
8439
  `${QWEN_METHOD_NS}workspace/permissions/set`,
@@ -8255,6 +8482,23 @@ var AcpParamError = class extends Error {
8255
8482
  __name(this, "AcpParamError");
8256
8483
  }
8257
8484
  };
8485
+ var InvalidRequestedSessionIdError = class extends Error {
8486
+ static {
8487
+ __name(this, "InvalidRequestedSessionIdError");
8488
+ }
8489
+ };
8490
+ var RequestedSessionIdNotHonoredError = class extends Error {
8491
+ constructor(requestedSessionId, actualSessionId) {
8492
+ super(
8493
+ `The ACP agent returned session "${actualSessionId}" instead of requested session "${requestedSessionId}".`
8494
+ );
8495
+ this.requestedSessionId = requestedSessionId;
8496
+ this.actualSessionId = actualSessionId;
8497
+ }
8498
+ static {
8499
+ __name(this, "RequestedSessionIdNotHonoredError");
8500
+ }
8501
+ };
8258
8502
  function parseOptionalPositiveInteger(value, fallback, max) {
8259
8503
  if (value === void 0) return fallback;
8260
8504
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > max) {
@@ -8365,6 +8609,38 @@ function pickSessionArtifactInput(params) {
8365
8609
  }
8366
8610
  __name(pickSessionArtifactInput, "pickSessionArtifactInput");
8367
8611
  function toRpcError(err) {
8612
+ if (err instanceof InvalidRequestedSessionIdError) {
8613
+ return {
8614
+ code: RPC.INVALID_PARAMS,
8615
+ message: err.message,
8616
+ data: { httpStatus: 400, errorKind: "invalid_session_id" }
8617
+ };
8618
+ }
8619
+ if (err instanceof RequestedSessionIdAdmissionError) {
8620
+ const unavailable = err.code === "session_id_admission_unavailable";
8621
+ return {
8622
+ code: unavailable ? RPC.INTERNAL_ERROR : RPC.INVALID_PARAMS,
8623
+ message: err.message,
8624
+ data: {
8625
+ httpStatus: unavailable ? 503 : 409,
8626
+ errorKind: err.code,
8627
+ sessionId: err.sessionId,
8628
+ ...err.details
8629
+ }
8630
+ };
8631
+ }
8632
+ if (err instanceof RequestedSessionIdNotHonoredError) {
8633
+ return {
8634
+ code: RPC.INTERNAL_ERROR,
8635
+ message: err.message,
8636
+ data: {
8637
+ httpStatus: 500,
8638
+ errorKind: "session_id_not_honored",
8639
+ requestedSessionId: err.requestedSessionId,
8640
+ actualSessionId: err.actualSessionId
8641
+ }
8642
+ };
8643
+ }
8368
8644
  if (err instanceof DaemonDrainingError) {
8369
8645
  return {
8370
8646
  code: RPC.INTERNAL_ERROR,
@@ -8487,6 +8763,56 @@ function toRpcError(err) {
8487
8763
  }
8488
8764
  const name = err instanceof Error ? err.name : "";
8489
8765
  switch (name) {
8766
+ case "SessionRestoreTimeoutError": {
8767
+ const restoreError = err;
8768
+ return {
8769
+ code: RPC.INTERNAL_ERROR,
8770
+ message: restoreError.message,
8771
+ data: {
8772
+ code: "session_restore_timeout",
8773
+ errorKind: "restore_timeout",
8774
+ httpStatus: 504,
8775
+ retryable: true,
8776
+ retryAfterSeconds: restoreRetryAfterSeconds(restoreError.timeoutMs),
8777
+ sessionId: restoreError.sessionId,
8778
+ action: restoreError.action,
8779
+ timeoutMs: restoreError.timeoutMs
8780
+ }
8781
+ };
8782
+ }
8783
+ case "RestoreInProgressError": {
8784
+ const fenceError = err;
8785
+ return {
8786
+ code: RPC.INTERNAL_ERROR,
8787
+ message: fenceError.message,
8788
+ data: {
8789
+ code: "restore_in_progress",
8790
+ errorKind: "restore_in_progress",
8791
+ httpStatus: 409,
8792
+ retryable: true,
8793
+ reason: fenceError.reason,
8794
+ retryAfterSeconds: fenceError.retryAfterSeconds,
8795
+ sessionId: fenceError.sessionId,
8796
+ activeAction: fenceError.activeAction,
8797
+ requestedAction: fenceError.requestedAction
8798
+ }
8799
+ };
8800
+ }
8801
+ case "BridgeChannelQuarantinedError": {
8802
+ const unavailableError = err;
8803
+ return {
8804
+ code: RPC.INTERNAL_ERROR,
8805
+ message: unavailableError.message,
8806
+ data: {
8807
+ code: "acp_channel_unavailable",
8808
+ errorKind: "acp_channel_unavailable",
8809
+ httpStatus: 503,
8810
+ retryable: true,
8811
+ reason: unavailableError.reason,
8812
+ retryAfterSeconds: unavailableError.retryAfterSeconds
8813
+ }
8814
+ };
8815
+ }
8490
8816
  case "SessionArchivedError":
8491
8817
  return {
8492
8818
  code: RPC.INTERNAL_ERROR,
@@ -8580,12 +8906,16 @@ function rpcErrorFrame(id, err) {
8580
8906
  __name(rpcErrorFrame, "rpcErrorFrame");
8581
8907
  var ACP_PROTOCOL_VERSION = 1;
8582
8908
  var AcpDispatcher = class {
8583
- constructor(bridge, boundWorkspace, getEnv, workspace, workspaceRememberLane, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator(), isWorkspaceTrusted = () => true, captureGenerationAssertion = () => void 0, liveSessionIsolation, sessionRuntimeBaseDir = Storage.getRuntimeBaseDir()) {
8909
+ constructor(bridge, boundWorkspace, getEnv, workspace, workspaceRememberLane, requestedSessionIdAdmission, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator(), isWorkspaceTrusted = () => true, captureGenerationAssertion = () => void 0, liveSessionIsolation, sessionRuntimeBaseDir = Storage.getRuntimeBaseDir(), getSessionRuntimeContext = () => ({
8910
+ bridge,
8911
+ sessionRuntimeBaseDir
8912
+ })) {
8584
8913
  this.bridge = bridge;
8585
8914
  this.boundWorkspace = boundWorkspace;
8586
8915
  this.getEnv = getEnv;
8587
8916
  this.workspace = workspace;
8588
8917
  this.workspaceRememberLane = workspaceRememberLane;
8918
+ this.requestedSessionIdAdmission = requestedSessionIdAdmission;
8589
8919
  this.fsFactory = fsFactory;
8590
8920
  this.deviceFlowRegistry = deviceFlowRegistry;
8591
8921
  this.sessionShellCommandEnabled = sessionShellCommandEnabled;
@@ -8595,26 +8925,31 @@ var AcpDispatcher = class {
8595
8925
  this.captureGenerationAssertion = captureGenerationAssertion;
8596
8926
  this.liveSessionIsolation = liveSessionIsolation;
8597
8927
  this.sessionRuntimeBaseDir = sessionRuntimeBaseDir;
8928
+ this.getSessionRuntimeContext = getSessionRuntimeContext;
8598
8929
  this.agentManager = createDaemonSubagentManager(boundWorkspace);
8599
8930
  }
8600
8931
  static {
8601
8932
  __name(this, "AcpDispatcher");
8602
8933
  }
8603
8934
  agentManager;
8604
- killOrphanSession(sessionId, removePersistedSession = false) {
8935
+ removeOrphanSession(sessionId, removePersistedSession = false, runtime = this.getSessionRuntimeContext()) {
8605
8936
  const cleanup = removePersistedSession ? deleteDaemonSessionIfOrphan({
8606
8937
  sessionId,
8607
8938
  service: new SessionService(this.boundWorkspace, {
8608
- runtimeBaseDir: this.sessionRuntimeBaseDir
8939
+ runtimeBaseDir: runtime.sessionRuntimeBaseDir
8609
8940
  }),
8610
- bridge: this.bridge,
8941
+ bridge: runtime.bridge,
8611
8942
  coordinator: this.archiveCoordinator
8612
- }) : this.bridge.killSession(sessionId, { requireZeroAttaches: true });
8613
- void cleanup.catch(
8614
- (err) => writeStderrLine(
8943
+ }) : runtime.bridge.killSession(sessionId, { requireZeroAttaches: true });
8944
+ return cleanup.catch((err) => {
8945
+ writeStderrLine(
8615
8946
  `qwen serve: /acp orphan killSession(${logSafe(sessionId)}) failed: ${logSafe(errMsg(err))}`
8616
- )
8617
- );
8947
+ );
8948
+ return void 0;
8949
+ });
8950
+ }
8951
+ killOrphanSession(sessionId, removePersistedSession = false, runtime) {
8952
+ void this.removeOrphanSession(sessionId, removePersistedSession, runtime);
8618
8953
  }
8619
8954
  /**
8620
8955
  * Build the `WorkspaceRequestContext` for workspace-scoped operations
@@ -8718,9 +9053,9 @@ var AcpDispatcher = class {
8718
9053
  * child's own session state. Returned in `session/new` and as the result
8719
9054
  * of `session/set_config_option`. Best-effort — `undefined` on error.
8720
9055
  */
8721
- async configOptionsFor(sessionId) {
9056
+ async configOptionsFor(sessionId, bridge = this.bridge) {
8722
9057
  try {
8723
- const ctx = await this.bridge.getSessionContextStatus(sessionId);
9058
+ const ctx = await bridge.getSessionContextStatus(sessionId);
8724
9059
  const co = ctx?.state?.configOptions;
8725
9060
  return Array.isArray(co) ? co : void 0;
8726
9061
  } catch (err) {
@@ -8914,7 +9249,13 @@ var AcpDispatcher = class {
8914
9249
  }
8915
9250
  if (!isRequest(msg) && !isNotification(msg)) return;
8916
9251
  const method = msg.method;
8917
- const params = isObject(msg.params) ? msg.params : {};
9252
+ const params = {
9253
+ ...isObject(msg.params) ? msg.params : {}
9254
+ };
9255
+ if (typeof params["sessionId"] === "string") {
9256
+ params["sessionId"] = normalizeSessionIdForLookup(params["sessionId"]);
9257
+ }
9258
+ const normalizedSessionHeader = sessionHeader ? normalizeSessionIdForLookup(sessionHeader) : void 0;
8918
9259
  const id = isRequest(msg) ? msg.id : void 0;
8919
9260
  const generationScoped = TRUSTED_WORKSPACE_METHODS.has(method) || WORKSPACE_GENERATION_MUTATION_METHODS.has(method);
8920
9261
  const assertGenerationOpen = generationScoped ? this.captureGenerationAssertion() : void 0;
@@ -8937,7 +9278,7 @@ var AcpDispatcher = class {
8937
9278
  }
8938
9279
  return;
8939
9280
  }
8940
- if (sessionHeader && typeof params["sessionId"] === "string" && params["sessionId"] !== sessionHeader) {
9281
+ if (normalizedSessionHeader && typeof params["sessionId"] === "string" && params["sessionId"] !== normalizedSessionHeader) {
8941
9282
  if (id !== void 0) {
8942
9283
  conn.sendConn(
8943
9284
  error(
@@ -8955,6 +9296,16 @@ var AcpDispatcher = class {
8955
9296
  this.replyConn(conn, id, {});
8956
9297
  return;
8957
9298
  case "session/new": {
9299
+ const meta = isObject(params["_meta"]) ? params["_meta"] : void 0;
9300
+ const parsedSessionId = parseCallerSuppliedSessionId(
9301
+ meta?.[REQUESTED_SESSION_ID_META_KEY]
9302
+ );
9303
+ if (parsedSessionId.kind === "invalid") {
9304
+ throw new InvalidRequestedSessionIdError(
9305
+ `\`_meta["${REQUESTED_SESSION_ID_META_KEY}"]\` must be an RFC UUID v1-v5`
9306
+ );
9307
+ }
9308
+ const requestedSessionId = parsedSessionId.kind === "valid" ? parsedSessionId.sessionId : void 0;
8958
9309
  const cwd = this.parseSessionWorkspaceCwd(params);
8959
9310
  if (this.liveSessionIsolation) {
8960
9311
  if (id !== void 0) {
@@ -8969,6 +9320,7 @@ var AcpDispatcher = class {
8969
9320
  }
8970
9321
  return;
8971
9322
  }
9323
+ const sessionRuntime = this.getSessionRuntimeContext();
8972
9324
  const source = parseSessionSource(
8973
9325
  params["sourceType"],
8974
9326
  params["sourceId"]
@@ -8991,39 +9343,89 @@ var AcpDispatcher = class {
8991
9343
  }
8992
9344
  return;
8993
9345
  }
8994
- const session = await this.bridge.spawnOrAttach({
8995
- workspaceCwd: cwd,
8996
- clientId: conn.clientId,
8997
- sessionScope: "thread",
8998
- ...source
8999
- });
9000
- if (conn.destroyed) {
9001
- this.killOrphanSession(session.sessionId, true);
9002
- return;
9003
- }
9004
- conn.getOrCreateSession(session.sessionId).clientId = session.clientId;
9005
- conn.ownSession(session.sessionId);
9006
- const configOptions = await this.configOptionsFor(session.sessionId);
9007
- if (conn.destroyed) {
9008
- this.killOrphanSession(session.sessionId, true);
9346
+ const reservation = requestedSessionId ? await this.requestedSessionIdAdmission.reserveCreate(
9347
+ requestedSessionId,
9348
+ {
9349
+ bridge: sessionRuntime.bridge,
9350
+ workspaceCwd: cwd,
9351
+ ...sessionRuntime.workspaceId ? { workspaceId: sessionRuntime.workspaceId } : {}
9352
+ }
9353
+ ) : void 0;
9354
+ try {
9355
+ assertGenerationOpen?.();
9356
+ const session = await sessionRuntime.bridge.spawnOrAttach({
9357
+ workspaceCwd: cwd,
9358
+ clientId: conn.clientId,
9359
+ sessionScope: "thread",
9360
+ ...source,
9361
+ ...requestedSessionId ? { sessionId: requestedSessionId } : {}
9362
+ });
9363
+ const rollbackSession = /* @__PURE__ */ __name(async () => {
9364
+ if (session.attached) {
9365
+ await sessionRuntime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
9366
+ });
9367
+ } else {
9368
+ await this.removeOrphanSession(
9369
+ session.sessionId,
9370
+ true,
9371
+ sessionRuntime
9372
+ );
9373
+ }
9374
+ }, "rollbackSession");
9375
+ try {
9376
+ assertGenerationOpen?.();
9377
+ } catch (error2) {
9378
+ await rollbackSession();
9379
+ throw error2;
9380
+ }
9381
+ if (requestedSessionId !== void 0 && session.sessionId !== requestedSessionId) {
9382
+ await rollbackSession();
9383
+ throw new RequestedSessionIdNotHonoredError(
9384
+ requestedSessionId,
9385
+ session.sessionId
9386
+ );
9387
+ }
9388
+ if (conn.destroyed) {
9389
+ this.killOrphanSession(session.sessionId, true, sessionRuntime);
9390
+ return;
9391
+ }
9392
+ const configOptions = await this.configOptionsFor(
9393
+ session.sessionId,
9394
+ sessionRuntime.bridge
9395
+ );
9396
+ try {
9397
+ assertGenerationOpen?.();
9398
+ } catch (error2) {
9399
+ await rollbackSession();
9400
+ throw error2;
9401
+ }
9402
+ if (conn.destroyed) {
9403
+ this.killOrphanSession(session.sessionId, true, sessionRuntime);
9404
+ return;
9405
+ }
9406
+ conn.getOrCreateSession(session.sessionId).clientId = session.clientId;
9407
+ conn.ownSession(session.sessionId);
9408
+ const models = this.extractModelState(configOptions);
9409
+ const modes = this.extractModeState(configOptions);
9410
+ this.replyConn(conn, id, {
9411
+ sessionId: session.sessionId,
9412
+ ...session.sourceType ? { sourceType: session.sourceType } : {},
9413
+ ...session.sourceId !== void 0 ? { sourceId: session.sourceId } : {},
9414
+ ...session.sourcePersisted !== void 0 ? { sourcePersisted: session.sourcePersisted } : {},
9415
+ ...configOptions ? { configOptions } : {},
9416
+ ...models ? { models } : {},
9417
+ ...modes ? { modes } : {}
9418
+ });
9009
9419
  return;
9420
+ } finally {
9421
+ reservation?.release();
9010
9422
  }
9011
- const models = this.extractModelState(configOptions);
9012
- const modes = this.extractModeState(configOptions);
9013
- this.replyConn(conn, id, {
9014
- sessionId: session.sessionId,
9015
- ...session.sourceType ? { sourceType: session.sourceType } : {},
9016
- ...session.sourceId !== void 0 ? { sourceId: session.sourceId } : {},
9017
- ...session.sourcePersisted !== void 0 ? { sourcePersisted: session.sourcePersisted } : {},
9018
- ...configOptions ? { configOptions } : {},
9019
- ...models ? { models } : {},
9020
- ...modes ? { modes } : {}
9021
- });
9022
- return;
9023
9423
  }
9024
9424
  case "session/load":
9025
9425
  case "session/resume": {
9026
- const sessionId = String(params["sessionId"] ?? "");
9426
+ const sessionId = normalizeSessionIdForLookup(
9427
+ String(params["sessionId"] ?? "")
9428
+ );
9027
9429
  if (!sessionId) {
9028
9430
  if (id !== void 0) {
9029
9431
  conn.sendConn(
@@ -9045,134 +9447,183 @@ var AcpDispatcher = class {
9045
9447
  return;
9046
9448
  }
9047
9449
  const cwd = this.parseSessionWorkspaceCwd(params);
9048
- const restored = await this.archiveCoordinator.runSharedMany(
9049
- [sessionId],
9050
- async () => {
9051
- await assertSessionLoadable(cwd, sessionId);
9052
- const sessionService = new SessionService(cwd);
9053
- const metadata = this.liveSessionIsolation ? await readLoadableLiveConversationMetadata(
9054
- sessionId,
9055
- (candidateId) => sessionService.readCreationMetadata(candidateId)
9056
- ) : await sessionService.readCreationMetadata(sessionId);
9057
- if (metadata === void 0) {
9058
- throw new SessionNotFoundError(sessionId);
9059
- }
9060
- const liveConversationCwd = this.liveSessionIsolation ? await this.liveSessionIsolation.materializeConversationDirectory(
9061
- sessionId
9062
- ) : void 0;
9063
- const session = method === "session/load" ? await this.bridge.loadSession({
9064
- sessionId,
9065
- workspaceCwd: cwd,
9066
- clientId: conn.clientId,
9067
- historyReplay: "response",
9068
- ...metadata
9069
- }) : await this.bridge.resumeSession({
9070
- sessionId,
9071
- workspaceCwd: cwd,
9072
- clientId: conn.clientId,
9073
- ...metadata
9074
- });
9075
- if (liveConversationCwd === void 0) {
9076
- return session;
9077
- }
9078
- if (session.hasActivePrompt) {
9079
- if (session.currentCwd === liveConversationCwd) return session;
9080
- try {
9081
- if (session.clientId) {
9082
- await this.bridge.detachClient(
9083
- session.sessionId,
9084
- session.clientId
9085
- );
9086
- }
9087
- } catch {
9088
- }
9089
- throw new Error(
9090
- "Active Live session is outside its isolated conversation directory."
9450
+ const sessionRuntime = this.getSessionRuntimeContext();
9451
+ const reservation = this.requestedSessionIdAdmission.reserveRestore(
9452
+ sessionId,
9453
+ {
9454
+ bridge: sessionRuntime.bridge,
9455
+ workspaceCwd: cwd,
9456
+ ...sessionRuntime.workspaceId ? { workspaceId: sessionRuntime.workspaceId } : {}
9457
+ }
9458
+ );
9459
+ try {
9460
+ const restored = await this.archiveCoordinator.runSharedMany(
9461
+ [sessionId],
9462
+ async () => {
9463
+ assertGenerationOpen?.();
9464
+ await assertSessionLoadable(
9465
+ cwd,
9466
+ sessionId,
9467
+ sessionRuntime.sessionRuntimeBaseDir
9091
9468
  );
9092
- }
9093
- try {
9094
- const changed = await this.bridge.changeSessionCwd(sessionId, {
9095
- path: liveConversationCwd,
9096
- allowedRoots: [cwd],
9097
- managedRelocation: "live-conversation"
9469
+ const sessionService = new SessionService(cwd, {
9470
+ runtimeBaseDir: sessionRuntime.sessionRuntimeBaseDir
9471
+ });
9472
+ const metadata = this.liveSessionIsolation ? await readLoadableLiveConversationMetadata(
9473
+ sessionId,
9474
+ (candidateId) => sessionService.readCreationMetadata(candidateId)
9475
+ ) : await sessionService.readCreationMetadata(sessionId);
9476
+ if (metadata === void 0) {
9477
+ throw new SessionNotFoundError(sessionId);
9478
+ }
9479
+ const liveConversationCwd = this.liveSessionIsolation ? await this.liveSessionIsolation.materializeConversationDirectory(
9480
+ sessionId
9481
+ ) : void 0;
9482
+ assertGenerationOpen?.();
9483
+ const session = method === "session/load" ? await sessionRuntime.bridge.loadSession({
9484
+ sessionId,
9485
+ workspaceCwd: cwd,
9486
+ clientId: conn.clientId,
9487
+ historyReplay: "response",
9488
+ ...metadata
9489
+ }) : await sessionRuntime.bridge.resumeSession({
9490
+ sessionId,
9491
+ workspaceCwd: cwd,
9492
+ clientId: conn.clientId,
9493
+ ...metadata
9098
9494
  });
9099
- if (changed.newCwd !== liveConversationCwd) {
9495
+ if (liveConversationCwd === void 0) {
9496
+ return session;
9497
+ }
9498
+ if (session.hasActivePrompt) {
9499
+ if (session.currentCwd === liveConversationCwd)
9500
+ return session;
9501
+ try {
9502
+ if (session.clientId) {
9503
+ await sessionRuntime.bridge.detachClient(
9504
+ session.sessionId,
9505
+ session.clientId
9506
+ );
9507
+ }
9508
+ } catch {
9509
+ }
9100
9510
  throw new Error(
9101
- "Live conversation directory relocation was rejected."
9511
+ "Active Live session is outside its isolated conversation directory."
9102
9512
  );
9103
9513
  }
9104
- session.currentCwd = changed.newCwd;
9105
- } catch (error2) {
9106
9514
  try {
9107
- if (session.attached && session.clientId) {
9108
- await this.bridge.detachClient(
9109
- session.sessionId,
9110
- session.clientId
9515
+ const changed = await sessionRuntime.bridge.changeSessionCwd(
9516
+ sessionId,
9517
+ {
9518
+ path: liveConversationCwd,
9519
+ allowedRoots: [cwd],
9520
+ managedRelocation: "live-conversation"
9521
+ }
9522
+ );
9523
+ if (changed.newCwd !== liveConversationCwd) {
9524
+ throw new Error(
9525
+ "Live conversation directory relocation was rejected."
9111
9526
  );
9112
- } else if (!session.attached) {
9113
- await this.bridge.killSession(session.sessionId, {
9114
- requireZeroAttaches: true
9115
- });
9116
9527
  }
9117
- } catch {
9528
+ session.currentCwd = changed.newCwd;
9529
+ } catch (error2) {
9530
+ try {
9531
+ if (session.attached && session.clientId) {
9532
+ await sessionRuntime.bridge.detachClient(
9533
+ session.sessionId,
9534
+ session.clientId
9535
+ );
9536
+ } else if (!session.attached) {
9537
+ await sessionRuntime.bridge.killSession(
9538
+ session.sessionId,
9539
+ {
9540
+ requireZeroAttaches: true
9541
+ }
9542
+ );
9543
+ }
9544
+ } catch {
9545
+ }
9546
+ throw error2;
9118
9547
  }
9119
- throw error2;
9548
+ return session;
9549
+ }
9550
+ );
9551
+ const rollbackRestore = /* @__PURE__ */ __name(async () => {
9552
+ if (restored.attached) {
9553
+ await sessionRuntime.bridge.detachClient(sessionId, restored.clientId).catch(() => {
9554
+ });
9555
+ } else {
9556
+ await sessionRuntime.bridge.killSession(sessionId, { requireZeroAttaches: true }).catch(() => {
9557
+ });
9120
9558
  }
9121
- return session;
9559
+ }, "rollbackRestore");
9560
+ try {
9561
+ assertGenerationOpen?.();
9562
+ } catch (error2) {
9563
+ await rollbackRestore();
9564
+ throw error2;
9122
9565
  }
9123
- );
9124
- const closeRaced = conn.closingSessions.has(sessionId);
9125
- if (conn.destroyed || closeRaced) {
9126
- const cleanup = restored.attached ? this.bridge.detachClient(sessionId, restored.clientId) : this.bridge.killSession(sessionId, {
9127
- requireZeroAttaches: true
9128
- });
9129
- void cleanup.catch(
9130
- (err) => writeStderrLine(
9131
- `qwen serve: /acp orphan ${restored.attached ? "detach" : "kill"}(${logSafe(sessionId)}) teardown-race: ${logSafe(errMsg(err))}`
9132
- )
9566
+ const loadConfigOptions = await this.configOptionsFor(
9567
+ sessionId,
9568
+ sessionRuntime.bridge
9133
9569
  );
9134
- if (closeRaced && !conn.destroyed && id !== void 0) {
9135
- conn.sendConn(
9136
- error(
9137
- id,
9138
- RPC.INTERNAL_ERROR,
9139
- `session ${sessionId} was closed during load; retry`
9570
+ const loadModels = this.extractModelState(loadConfigOptions);
9571
+ const loadModes = this.extractModeState(loadConfigOptions);
9572
+ const loadState = restored.state ?? {};
9573
+ const loadMeta = isObject(loadState._meta) ? loadState._meta : void 0;
9574
+ const loadQwenMeta = isObject(loadMeta?.[QWEN_META_KEY]) ? loadMeta[QWEN_META_KEY] : void 0;
9575
+ const replayStatus = method === "session/load" && restored.partial === true ? {
9576
+ partial: true,
9577
+ ...typeof restored.replayError === "string" ? { replayError: restored.replayError } : {}
9578
+ } : void 0;
9579
+ try {
9580
+ assertGenerationOpen?.();
9581
+ } catch (error2) {
9582
+ await rollbackRestore();
9583
+ throw error2;
9584
+ }
9585
+ const closeRaced = conn.closingSessions.has(sessionId);
9586
+ if (conn.destroyed || closeRaced) {
9587
+ void rollbackRestore().catch(
9588
+ (err) => writeStderrLine(
9589
+ `qwen serve: /acp orphan ${restored.attached ? "detach" : "kill"}(${logSafe(sessionId)}) teardown-race: ${logSafe(errMsg(err))}`
9140
9590
  )
9141
9591
  );
9592
+ if (closeRaced && !conn.destroyed && id !== void 0) {
9593
+ conn.sendConn(
9594
+ error(
9595
+ id,
9596
+ RPC.INTERNAL_ERROR,
9597
+ `session ${sessionId} was closed during load; retry`
9598
+ )
9599
+ );
9600
+ }
9601
+ return;
9602
+ }
9603
+ conn.getOrCreateSession(sessionId).clientId = restored.clientId;
9604
+ if (method === "session/load") {
9605
+ conn.markInitialReplayPending(sessionId);
9142
9606
  }
9607
+ conn.ownSession(sessionId);
9608
+ this.replyConn(conn, id, {
9609
+ ...loadState,
9610
+ ...replayStatus ? {
9611
+ _meta: {
9612
+ ...loadMeta ?? {},
9613
+ [QWEN_META_KEY]: {
9614
+ ...loadQwenMeta ?? {},
9615
+ sessionLoadReplay: replayStatus
9616
+ }
9617
+ }
9618
+ } : {},
9619
+ ...loadConfigOptions ? { configOptions: loadConfigOptions } : {},
9620
+ ...loadModels ? { models: loadModels } : {},
9621
+ ...loadModes ? { modes: loadModes } : {}
9622
+ });
9143
9623
  return;
9624
+ } finally {
9625
+ reservation.release();
9144
9626
  }
9145
- conn.getOrCreateSession(sessionId).clientId = restored.clientId;
9146
- if (method === "session/load") {
9147
- conn.markInitialReplayPending(sessionId);
9148
- }
9149
- conn.ownSession(sessionId);
9150
- const loadConfigOptions = await this.configOptionsFor(sessionId);
9151
- const loadModels = this.extractModelState(loadConfigOptions);
9152
- const loadModes = this.extractModeState(loadConfigOptions);
9153
- const loadState = restored.state ?? {};
9154
- const loadMeta = isObject(loadState._meta) ? loadState._meta : void 0;
9155
- const loadQwenMeta = isObject(loadMeta?.[QWEN_META_KEY]) ? loadMeta[QWEN_META_KEY] : void 0;
9156
- const replayStatus = method === "session/load" && restored.partial === true ? {
9157
- partial: true,
9158
- ...typeof restored.replayError === "string" ? { replayError: restored.replayError } : {}
9159
- } : void 0;
9160
- this.replyConn(conn, id, {
9161
- ...loadState,
9162
- ...replayStatus ? {
9163
- _meta: {
9164
- ...loadMeta ?? {},
9165
- [QWEN_META_KEY]: {
9166
- ...loadQwenMeta ?? {},
9167
- sessionLoadReplay: replayStatus
9168
- }
9169
- }
9170
- } : {},
9171
- ...loadConfigOptions ? { configOptions: loadConfigOptions } : {},
9172
- ...loadModels ? { models: loadModels } : {},
9173
- ...loadModes ? { modes: loadModes } : {}
9174
- });
9175
- return;
9176
9627
  }
9177
9628
  case "session/list": {
9178
9629
  const workspaceCwd = this.parseBoundWorkspaceParam(params);
@@ -10791,7 +11242,7 @@ var AcpDispatcher = class {
10791
11242
  );
10792
11243
  return;
10793
11244
  }
10794
- const fs7 = this.fsFactory.forRequest({
11245
+ const fs8 = this.fsFactory.forRequest({
10795
11246
  originatorClientId: conn.clientId,
10796
11247
  route: `ACP ${method}`
10797
11248
  });
@@ -10856,8 +11307,8 @@ var AcpDispatcher = class {
10856
11307
  return;
10857
11308
  }
10858
11309
  const cursor = rawCursor;
10859
- const resolved = await fs7.resolve(p, "read");
10860
- const out = await fs7.readText(resolved, {
11310
+ const resolved = await fs8.resolve(p, "read");
11311
+ const out = await fs8.readText(resolved, {
10861
11312
  maxBytes,
10862
11313
  line,
10863
11314
  limit,
@@ -10884,7 +11335,7 @@ var AcpDispatcher = class {
10884
11335
  conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
10885
11336
  return;
10886
11337
  }
10887
- const fs7 = this.fsFactory.forRequest({
11338
+ const fs8 = this.fsFactory.forRequest({
10888
11339
  originatorClientId: conn.clientId,
10889
11340
  route: `ACP ${method}`
10890
11341
  });
@@ -10920,8 +11371,8 @@ var AcpDispatcher = class {
10920
11371
  );
10921
11372
  return;
10922
11373
  }
10923
- const resolved = await fs7.resolve(p, "read");
10924
- const buf = await fs7.readBytesWindow(resolved, { offset, maxBytes });
11374
+ const resolved = await fs8.resolve(p, "read");
11375
+ const buf = await fs8.readBytesWindow(resolved, { offset, maxBytes });
10925
11376
  this.replyConn(conn, id, { path: p, ...buf });
10926
11377
  return;
10927
11378
  }
@@ -10939,12 +11390,12 @@ var AcpDispatcher = class {
10939
11390
  conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
10940
11391
  return;
10941
11392
  }
10942
- const fs7 = this.fsFactory.forRequest({
11393
+ const fs8 = this.fsFactory.forRequest({
10943
11394
  originatorClientId: conn.clientId,
10944
11395
  route: `ACP ${method}`
10945
11396
  });
10946
- const resolved = await fs7.resolve(p, "read");
10947
- const result = await fs7.stat(resolved);
11397
+ const resolved = await fs8.resolve(p, "read");
11398
+ const result = await fs8.stat(resolved);
10948
11399
  this.replyConn(conn, id, { path: p, ...result });
10949
11400
  return;
10950
11401
  }
@@ -10962,13 +11413,13 @@ var AcpDispatcher = class {
10962
11413
  conn.sendConn(error(id, RPC.INVALID_PARAMS, "`path` required"));
10963
11414
  return;
10964
11415
  }
10965
- const fs7 = this.fsFactory.forRequest({
11416
+ const fs8 = this.fsFactory.forRequest({
10966
11417
  originatorClientId: conn.clientId,
10967
11418
  route: `ACP ${method}`
10968
11419
  });
10969
- const resolved = await fs7.resolve(p, "read");
11420
+ const resolved = await fs8.resolve(p, "read");
10970
11421
  const MAX_LIST = 2e3;
10971
- const entries = await fs7.list(resolved, { maxEntries: MAX_LIST + 1 });
11422
+ const entries = await fs8.list(resolved, { maxEntries: MAX_LIST + 1 });
10972
11423
  const truncated = entries.length > MAX_LIST;
10973
11424
  this.replyConn(conn, id, {
10974
11425
  path: p,
@@ -10993,7 +11444,7 @@ var AcpDispatcher = class {
10993
11444
  );
10994
11445
  return;
10995
11446
  }
10996
- const fs7 = this.fsFactory.forRequest({
11447
+ const fs8 = this.fsFactory.forRequest({
10997
11448
  originatorClientId: conn.clientId,
10998
11449
  route: `ACP ${method}`
10999
11450
  });
@@ -11013,7 +11464,7 @@ var AcpDispatcher = class {
11013
11464
  );
11014
11465
  return;
11015
11466
  }
11016
- const matches = await fs7.glob(pattern, {
11467
+ const matches = await fs8.glob(pattern, {
11017
11468
  maxResults: maxResults + 1
11018
11469
  });
11019
11470
  const truncated = matches.length > maxResults;
@@ -11045,11 +11496,11 @@ var AcpDispatcher = class {
11045
11496
  );
11046
11497
  return;
11047
11498
  }
11048
- const fs7 = this.fsFactory.forRequest({
11499
+ const fs8 = this.fsFactory.forRequest({
11049
11500
  originatorClientId: conn.clientId,
11050
11501
  route: `ACP ${method}`
11051
11502
  });
11052
- const resolved = await fs7.resolve(p, "write");
11503
+ const resolved = await fs8.resolve(p, "write");
11053
11504
  if (Buffer.byteLength(params["content"], "utf8") > 10 * 1024 * 1024) {
11054
11505
  if (id !== void 0)
11055
11506
  conn.sendConn(
@@ -11057,7 +11508,7 @@ var AcpDispatcher = class {
11057
11508
  );
11058
11509
  return;
11059
11510
  }
11060
- await fs7.writeTextOverwrite(resolved, params["content"]);
11511
+ await fs8.writeTextOverwrite(resolved, params["content"]);
11061
11512
  assertGenerationOpen?.();
11062
11513
  this.replyConn(conn, id, { ok: true, path: p });
11063
11514
  return;
@@ -11087,12 +11538,12 @@ var AcpDispatcher = class {
11087
11538
  );
11088
11539
  return;
11089
11540
  }
11090
- const fs7 = this.fsFactory.forRequest({
11541
+ const fs8 = this.fsFactory.forRequest({
11091
11542
  originatorClientId: conn.clientId,
11092
11543
  route: `ACP ${method}`
11093
11544
  });
11094
- const resolved = await fs7.resolve(p, "write");
11095
- const result = await fs7.edit(
11545
+ const resolved = await fs8.resolve(p, "write");
11546
+ const result = await fs8.edit(
11096
11547
  resolved,
11097
11548
  params["oldText"],
11098
11549
  params["newText"]
@@ -13757,7 +14208,7 @@ function isActiveDrainCorrelation(registry, conn, message) {
13757
14208
  return false;
13758
14209
  }
13759
14210
  const params = message.params !== null && typeof message.params === "object" ? message.params : void 0;
13760
- return typeof params?.sessionId === "string" && conn.ownsSession(params.sessionId);
14211
+ return typeof params?.sessionId === "string" && conn.ownsSession(normalizeSessionIdForLookup(params.sessionId));
13761
14212
  }
13762
14213
  __name(isActiveDrainCorrelation, "isActiveDrainCorrelation");
13763
14214
  var PLURAL_WS_PREFIX = "/workspaces/";
@@ -13934,8 +14385,11 @@ function mountAcpHttp(app, bridge, opts) {
13934
14385
  const enabled = opts.enabled ?? resolveAcpHttpEnabled();
13935
14386
  if (!enabled) return void 0;
13936
14387
  const daemonEnv = opts.daemonEnv ?? process.env;
14388
+ const primarySessionRuntimeBaseDir = opts.workspaceRegistry?.primary.sessionRuntimeBaseDir ?? Storage.getRuntimeBaseDir();
14389
+ const archiveCoordinator = opts.archiveCoordinator ?? new SessionArchiveCoordinator();
14390
+ const requestedSessionIdAdmission = opts.requestedSessionIdAdmission;
13937
14391
  const getPrimaryEnv = /* @__PURE__ */ __name(() => opts.workspaceRegistry ? runtimeEffectiveEnv(opts.workspaceRegistry.primary, daemonEnv) : daemonEnv, "getPrimaryEnv");
13938
- const path14 = opts.path ?? "/acp";
14392
+ const path15 = opts.path ?? "/acp";
13939
14393
  const dispatcherRef = {};
13940
14394
  let disposed = false;
13941
14395
  const rejectIfDisposed = /* @__PURE__ */ __name((res) => {
@@ -14087,11 +14541,12 @@ function mountAcpHttp(app, bridge, opts) {
14087
14541
  getPrimaryEnv,
14088
14542
  opts.workspace,
14089
14543
  opts.workspaceRememberLane,
14544
+ requestedSessionIdAdmission,
14090
14545
  opts.fsFactory,
14091
14546
  opts.deviceFlowRegistry,
14092
14547
  opts.sessionShellCommandEnabled === true,
14093
14548
  registry,
14094
- opts.archiveCoordinator ?? new SessionArchiveCoordinator(),
14549
+ archiveCoordinator,
14095
14550
  opts.isPrimaryWorkspaceTrusted ?? (() => {
14096
14551
  const entry = opts.workspaceRegistry?.primaryEntry;
14097
14552
  return entry ? entry.state === "active" && entry.current?.runtime.trusted === true : true;
@@ -14101,13 +14556,24 @@ function mountAcpHttp(app, bridge, opts) {
14101
14556
  return guard ? () => guard.assertOpen() : void 0;
14102
14557
  },
14103
14558
  void 0,
14104
- opts.workspaceRegistry?.primary.sessionRuntimeBaseDir ?? Storage.getRuntimeBaseDir()
14559
+ primarySessionRuntimeBaseDir,
14560
+ () => {
14561
+ const runtime = opts.workspaceRegistry?.primary;
14562
+ return runtime ? {
14563
+ bridge: runtime.bridge,
14564
+ sessionRuntimeBaseDir: runtime.sessionRuntimeBaseDir,
14565
+ workspaceId: runtime.workspaceId
14566
+ } : {
14567
+ bridge,
14568
+ sessionRuntimeBaseDir: primarySessionRuntimeBaseDir
14569
+ };
14570
+ }
14105
14571
  );
14106
14572
  dispatcherRef.current = dispatcher;
14107
14573
  const primaryMount = {
14108
14574
  primary: true,
14109
14575
  workspaceCwd: opts.boundWorkspace,
14110
- routeLabel: logSafe(path14),
14576
+ routeLabel: logSafe(path15),
14111
14577
  rateLimitScope: opts.workspaceRegistry?.primary.workspaceId ?? "primary",
14112
14578
  registry,
14113
14579
  dispatcher,
@@ -14261,7 +14727,7 @@ function mountAcpHttp(app, bridge, opts) {
14261
14727
  });
14262
14728
  }, "handleAcpPost");
14263
14729
  app.post(
14264
- path14,
14730
+ path15,
14265
14731
  (req, res) => handleAcpPost(primaryMount, req, res)
14266
14732
  );
14267
14733
  const handleAcpGet = /* @__PURE__ */ __name((mount, req, res) => {
@@ -14281,7 +14747,8 @@ function mountAcpHttp(app, bridge, opts) {
14281
14747
  res.status(404).json({ error: "Unknown Acp-Connection-Id" });
14282
14748
  return;
14283
14749
  }
14284
- const sessionId = headerOf(req, ACP_SESSION_HEADER);
14750
+ const rawSessionId = headerOf(req, ACP_SESSION_HEADER);
14751
+ const sessionId = rawSessionId ? normalizeSessionIdForLookup(rawSessionId) : void 0;
14285
14752
  if (!sessionId) {
14286
14753
  const connId = conn.connectionId;
14287
14754
  const stream2 = new SseStream(
@@ -14359,10 +14826,10 @@ function mountAcpHttp(app, bridge, opts) {
14359
14826
  onPumpSettled();
14360
14827
  });
14361
14828
  }, "handleAcpGet");
14362
- app.get(path14, (req, res) => {
14829
+ app.get(path15, (req, res) => {
14363
14830
  handleAcpGet(primaryMount, req, res);
14364
14831
  });
14365
- app.delete(path14, (req, res) => {
14832
+ app.delete(path15, (req, res) => {
14366
14833
  handleAcpDelete(primaryMount, req, res);
14367
14834
  });
14368
14835
  const createSecondaryAcpMount = /* @__PURE__ */ __name((rt) => {
@@ -14388,12 +14855,17 @@ function mountAcpHttp(app, bridge, opts) {
14388
14855
  rt.bridge,
14389
14856
  rt.workspaceCwd
14390
14857
  );
14858
+ const registeredGeneration = opts.workspaceRegistry?.getEntryByWorkspaceId(
14859
+ rt.workspaceId
14860
+ )?.current;
14861
+ const generationGuard = registeredGeneration?.runtime === rt ? registeredGeneration.guard : rt.generationGuard;
14391
14862
  const secondaryDispatcher = new AcpDispatcher(
14392
14863
  rt.bridge,
14393
14864
  rt.workspaceCwd,
14394
14865
  () => runtimeEffectiveEnv(rt, daemonEnv),
14395
14866
  rt.workspaceService,
14396
14867
  workspaceRememberLane,
14868
+ requestedSessionIdAdmission,
14397
14869
  rt.routeFileSystemFactory,
14398
14870
  // Phase 4: secondary mounts share the daemon-global device-flow registry
14399
14871
  // (single instance per daemon; OAuth credentials are global state). The
@@ -14403,14 +14875,16 @@ function mountAcpHttp(app, bridge, opts) {
14403
14875
  opts.deviceFlowRegistry,
14404
14876
  opts.sessionShellCommandEnabled === true,
14405
14877
  secondaryRegistry,
14406
- opts.archiveCoordinator ?? new SessionArchiveCoordinator(),
14878
+ archiveCoordinator,
14407
14879
  () => rt.trusted,
14408
- () => {
14409
- const guard = rt.generationGuard;
14410
- return guard ? () => guard.assertOpen() : void 0;
14411
- },
14880
+ () => generationGuard ? () => generationGuard.assertOpen() : void 0,
14412
14881
  rt.provenance === "live-conversation" ? opts.liveSessionIsolation : void 0,
14413
- rt.sessionRuntimeBaseDir
14882
+ rt.sessionRuntimeBaseDir,
14883
+ () => ({
14884
+ bridge: rt.bridge,
14885
+ sessionRuntimeBaseDir: rt.sessionRuntimeBaseDir,
14886
+ workspaceId: rt.workspaceId
14887
+ })
14414
14888
  );
14415
14889
  secondaryDispatcherRef.current = secondaryDispatcher;
14416
14890
  return {
@@ -14564,7 +15038,7 @@ function mountAcpHttp(app, bridge, opts) {
14564
15038
  const isPluralAcpShape = pluralRawSelector !== null;
14565
15039
  const pluralVoiceRawSelector = opts.workspaceVoiceConnection ? pluralWorkspaceRawSelector(rawPath, PLURAL_VOICE_WS_SUFFIX) : null;
14566
15040
  const isPluralVoiceShape = pluralVoiceRawSelector !== null;
14567
- if (rawPath !== path14 && !isCdpPath && !extraRoute && !isPluralAcpShape && !isPluralVoiceShape) {
15041
+ if (rawPath !== path15 && !isCdpPath && !extraRoute && !isPluralAcpShape && !isPluralVoiceShape) {
14568
15042
  logReject(`unknown-path ${logSafe(rawPath)}`);
14569
15043
  socket.destroy();
14570
15044
  return;
@@ -15048,7 +15522,8 @@ function mountAcpHttp(app, bridge, opts) {
15048
15522
  return;
15049
15523
  }
15050
15524
  if (isRequest(message) && message.params && typeof message.params === "object") {
15051
- const sid = message.params["sessionId"];
15525
+ const rawSid = message.params["sessionId"];
15526
+ const sid = typeof rawSid === "string" ? normalizeSessionIdForLookup(rawSid) : rawSid;
15052
15527
  if (typeof sid === "string" && conn.ownsSession(sid)) {
15053
15528
  const binding = conn.sessions.get(sid);
15054
15529
  if (binding && !binding.stream && conn.connStream && !conn.connStream.isClosed) {
@@ -15101,7 +15576,7 @@ function mountAcpHttp(app, bridge, opts) {
15101
15576
  });
15102
15577
  }, "upgradeListener");
15103
15578
  httpServer.on("upgrade", upgradeListener);
15104
- writeStderrLine(`qwen serve: /acp WebSocket transport enabled on ${path14}`);
15579
+ writeStderrLine(`qwen serve: /acp WebSocket transport enabled on ${path15}`);
15105
15580
  }
15106
15581
  __name(setupWebSocket, "setupWebSocket");
15107
15582
  return {
@@ -15930,7 +16405,8 @@ function registerDaemonStatusRoutes(app, deps) {
15930
16405
  getChannelWorkerSnapshots: deps.getChannelWorkerSnapshots,
15931
16406
  getPerfSnapshot: deps.getPerfSnapshot,
15932
16407
  getMetricsSeries: deps.getMetricsSeries,
15933
- getTotalSessionAdmissionSnapshot: deps.getTotalSessionAdmissionSnapshot
16408
+ getTotalSessionAdmissionSnapshot: deps.getTotalSessionAdmissionSnapshot,
16409
+ getChildHeapPolicySnapshot: deps.getChildHeapPolicySnapshot
15934
16410
  })
15935
16411
  );
15936
16412
  } catch (err) {
@@ -16041,6 +16517,7 @@ function getDemoHtml(_port) {
16041
16517
  <div class="session-info" id="sessionInfo" style="display:none">
16042
16518
  Session: <span id="sessionIdDisplay"></span>
16043
16519
  </div>
16520
+ <div class="session-info" id="contextUsage" style="display:none"></div>
16044
16521
  </div>
16045
16522
 
16046
16523
  <div class="panel">
@@ -16128,6 +16605,8 @@ function getDemoHtml(_port) {
16128
16605
  const requestLog = $('#requestLog');
16129
16606
  const sessionInfo = $('#sessionInfo');
16130
16607
  const sessionIdDisplay = $('#sessionIdDisplay');
16608
+ const contextUsage = $('#contextUsage');
16609
+ let lastLoggedContextPct = -1;
16131
16610
  const permissionPanel = $('#permissionPanel');
16132
16611
  const permissionList = $('#permissionList');
16133
16612
 
@@ -16251,6 +16730,8 @@ function getDemoHtml(_port) {
16251
16730
  sessionId = r.data.sessionId;
16252
16731
  sessionInfo.style.display = 'block';
16253
16732
  sessionIdDisplay.textContent = sessionId;
16733
+ contextUsage.style.display = 'none';
16734
+ lastLoggedContextPct = -1;
16254
16735
  enablePrompt(true);
16255
16736
  chatArea.innerHTML = '';
16256
16737
  currentAssistantBubble = null;
@@ -16368,6 +16849,24 @@ function getDemoHtml(_port) {
16368
16849
  const text = update.content?.text || '';
16369
16850
  currentThought += text;
16370
16851
  logEvent('THINK', text);
16852
+ } else if (kind === 'usage_update') {
16853
+ // One frame per model round: a long agentic turn (/review) emits
16854
+ // hundreds, and the raw-JSON fallthrough below turned the Events tab
16855
+ // into a scroll of identical lines. Render an in-place meter instead,
16856
+ // and log only when the integer percentage moves \u2014 the transitions
16857
+ // stay on record without the flood.
16858
+ const used = update.used;
16859
+ const size = update.size;
16860
+ if (typeof used === 'number' && typeof size === 'number' && size > 0) {
16861
+ const pct = Math.round((used / size) * 100);
16862
+ const label = used + ' / ' + size + ' (' + pct + '%)';
16863
+ contextUsage.style.display = 'block';
16864
+ contextUsage.textContent = 'Context: ' + label;
16865
+ if (pct !== lastLoggedContextPct) {
16866
+ lastLoggedContextPct = pct;
16867
+ logEvent('CTX', label);
16868
+ }
16869
+ }
16371
16870
  } else {
16372
16871
  logEvent(kind || type, JSON.stringify(update));
16373
16872
  }
@@ -16625,19 +17124,32 @@ function createHealthDemoRoutes(deps) {
16625
17124
  let sessions = 0;
16626
17125
  let pendingPermissions = 0;
16627
17126
  let activePrompts = 0;
17127
+ let activeWork = false;
16628
17128
  let channelAlive = false;
16629
17129
  let lastActivity = null;
17130
+ let coveredSessions = 0;
17131
+ let sessionsOnNegotiatedChannel = 0;
17132
+ let oldestReportAt = null;
16630
17133
  for (const runtime of runtimes) {
16631
17134
  failedWorkspaceId = runtime.workspaceId;
16632
17135
  const bridge = runtime.bridge;
16633
17136
  const runtimeSessions = bridge.sessionCount;
16634
17137
  const runtimePendingPermissions = bridge.pendingPermissionCount;
16635
17138
  const runtimeActivePrompts = bridge.activePromptCount;
17139
+ const runtimeActiveWork = bridge.activeWork;
17140
+ const runtimeCoverage = bridge.activeWorkCoverage;
17141
+ const runtimeOldestReportAt = runtimeCoverage.oldestCoveredReportAt;
16636
17142
  const runtimeChannelAlive = bridge.isChannelLive();
16637
17143
  const runtimeLastActivity = bridge.lastActivityAt;
16638
17144
  sessions += runtimeSessions;
16639
17145
  pendingPermissions += runtimePendingPermissions;
16640
17146
  activePrompts += runtimeActivePrompts;
17147
+ activeWork = activeWork || runtimeActiveWork;
17148
+ coveredSessions += runtimeCoverage.covered;
17149
+ sessionsOnNegotiatedChannel += runtimeCoverage.onNegotiatedChannel;
17150
+ if (runtimeOldestReportAt !== null && (oldestReportAt === null || runtimeOldestReportAt < oldestReportAt)) {
17151
+ oldestReportAt = runtimeOldestReportAt;
17152
+ }
16641
17153
  channelAlive = channelAlive || runtimeChannelAlive;
16642
17154
  if (runtimeLastActivity !== null && (lastActivity === null || runtimeLastActivity > lastActivity)) {
16643
17155
  lastActivity = runtimeLastActivity;
@@ -16652,6 +17164,17 @@ function createHealthDemoRoutes(deps) {
16652
17164
  sessions,
16653
17165
  pendingPermissions,
16654
17166
  activePrompts,
17167
+ activeWork,
17168
+ activeWorkReporting: gradeActiveWorkCoverage({
17169
+ total: sessions,
17170
+ covered: coveredSessions,
17171
+ onNegotiatedChannel: sessionsOnNegotiatedChannel
17172
+ }),
17173
+ // 0 rather than null when nothing is covered: an idle daemon with no
17174
+ // sessions must not read as infinitely stale to a controller applying
17175
+ // its own freshness floor. `oldestReportAt` is the oldest *covered*
17176
+ // report, so this never disagrees with the grade above.
17177
+ activeWorkStaleMs: oldestReportAt === null ? 0 : now - oldestReportAt,
16655
17178
  connectedClients: getActiveSseCount2(),
16656
17179
  channelAlive,
16657
17180
  lastActivityAt: lastActivity !== null ? new Date(lastActivity).toISOString() : null,
@@ -17177,6 +17700,10 @@ __name(registerWorkspaceAuthRoutes, "registerWorkspaceAuthRoutes");
17177
17700
  // packages/cli/src/serve/routes/workspace-extensions.ts
17178
17701
  init_esbuild_shims();
17179
17702
  import * as crypto2 from "node:crypto";
17703
+ import * as fs4 from "node:fs/promises";
17704
+ import * as os from "node:os";
17705
+ import * as path9 from "node:path";
17706
+ var import_express2 = __toESM(require_express(), 1);
17180
17707
 
17181
17708
  // packages/cli/src/serve/extension-operation-scheduler.ts
17182
17709
  init_esbuild_shims();
@@ -17258,6 +17785,7 @@ var MAX_UNFINISHED_EXTENSION_OPERATIONS = 10;
17258
17785
  var sanitizeDaemonMessage = /* @__PURE__ */ __name((message) => redactUrlCredentials(stripAnsiAndControl(message)), "sanitizeDaemonMessage");
17259
17786
  var redactExtensionDisplaySource = /* @__PURE__ */ __name((source) => {
17260
17787
  const redacted = redactUrlCredentials(source);
17788
+ if (redacted.startsWith("upload:")) return redacted;
17261
17789
  if (/^[A-Za-z]:[\\/]/.test(redacted)) return redacted;
17262
17790
  try {
17263
17791
  const url = new URL(redacted);
@@ -17947,6 +18475,39 @@ var EXTENSION_PREPARE_DEADLINE_MS = 10 * 6e4;
17947
18475
  var EXTENSION_INTERACTION_DEADLINE_MS = 10 * 6e4;
17948
18476
  var EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS = EXTENSION_PREPARE_DEADLINE_MS + EXTENSION_INTERACTION_DEADLINE_MS;
17949
18477
  var EXTENSION_UPDATE_CHECK_DEADLINE_MS = 2 * 6e4;
18478
+ var EXTENSION_ARCHIVE_UPLOAD_LIMIT = "10mb";
18479
+ var extensionArchiveBodyParser = import_express2.default.raw({
18480
+ type: "application/octet-stream",
18481
+ limit: EXTENSION_ARCHIVE_UPLOAD_LIMIT
18482
+ });
18483
+ var parseExtensionArchiveFilename = /* @__PURE__ */ __name((value) => {
18484
+ const invalidCharacter = typeof value === "string" && Array.from(value).some((character) => {
18485
+ const code = character.charCodeAt(0);
18486
+ return character === "/" || character === "\\" || code < 32 || code === 127;
18487
+ });
18488
+ if (typeof value !== "string" || value.length === 0 || Buffer.byteLength(value, "utf8") > 255 || invalidCharacter) {
18489
+ return null;
18490
+ }
18491
+ const lower = value.toLowerCase();
18492
+ if (lower.endsWith(".tar.gz")) return { filename: value, suffix: ".tar.gz" };
18493
+ if (lower.endsWith(".zip")) return { filename: value, suffix: ".zip" };
18494
+ return null;
18495
+ }, "parseExtensionArchiveFilename");
18496
+ var extensionArchiveUploadMetadata = /* @__PURE__ */ __name((req, res, next) => {
18497
+ if (req.query["consent"] !== "true") {
18498
+ res.status(400).json({
18499
+ error: "Extension installation requires explicit consent"
18500
+ });
18501
+ return;
18502
+ }
18503
+ if (!parseExtensionArchiveFilename(req.query["filename"])) {
18504
+ res.status(400).json({
18505
+ error: "`filename` must name a .zip or .tar.gz archive"
18506
+ });
18507
+ return;
18508
+ }
18509
+ next();
18510
+ }, "extensionArchiveUploadMetadata");
17950
18511
  var parseExtensionScope = /* @__PURE__ */ __name((body, res) => {
17951
18512
  const scope = body["scope"];
17952
18513
  if (scope !== "user" && scope !== "workspace") {
@@ -18388,6 +18949,127 @@ function registerWorkspaceExtensionRoutes(app, deps) {
18388
18949
  }
18389
18950
  }
18390
18951
  );
18952
+ app.post(
18953
+ `${base}/install-archive`,
18954
+ mutate({ strict: true }),
18955
+ extensionArchiveUploadMetadata,
18956
+ extensionArchiveBodyParser,
18957
+ async (req, res) => {
18958
+ const ctrl = resolve5(req, res, true);
18959
+ if (!ctrl) return;
18960
+ try {
18961
+ if (!ctrl.validateExtensionMutationClient(req, res, {
18962
+ requireClientId: false
18963
+ })) {
18964
+ return;
18965
+ }
18966
+ const archiveName = parseExtensionArchiveFilename(
18967
+ req.query["filename"]
18968
+ );
18969
+ if (!req.is("application/octet-stream")) {
18970
+ res.status(415).json({
18971
+ error: "Extension archive uploads require application/octet-stream"
18972
+ });
18973
+ return;
18974
+ }
18975
+ if (!Buffer.isBuffer(req.body) || req.body.length === 0) {
18976
+ res.status(400).json({ error: "Extension archive is empty" });
18977
+ return;
18978
+ }
18979
+ let archive = req.body;
18980
+ const source = `upload:v1:${crypto2.randomUUID()}:${archiveName.filename}`;
18981
+ ctrl.runQueuedExtensionMutation(
18982
+ "install",
18983
+ { source },
18984
+ res,
18985
+ async (extensionManager, _signal, context, operationId) => {
18986
+ let uploadDir;
18987
+ const sanitizeUploadError = /* @__PURE__ */ __name((error2) => {
18988
+ const sanitized = new Error(
18989
+ uploadDir ? getErrorMessage(error2).replaceAll(
18990
+ uploadDir,
18991
+ "<extension-upload-dir>"
18992
+ ) : "Could not create the temporary extension upload directory"
18993
+ );
18994
+ const code = typeof error2 === "object" && error2 !== null && "code" in error2 && typeof error2.code === "string" ? error2.code : void 0;
18995
+ if (code) Object.assign(sanitized, { code });
18996
+ return sanitized;
18997
+ }, "sanitizeUploadError");
18998
+ let result;
18999
+ let failure;
19000
+ try {
19001
+ uploadDir = await fs4.mkdtemp(
19002
+ path9.join(os.tmpdir(), "qwen-extension-upload-")
19003
+ );
19004
+ const archivePath = path9.join(
19005
+ uploadDir,
19006
+ `extension${archiveName.suffix}`
19007
+ );
19008
+ await fs4.writeFile(archivePath, archive);
19009
+ archive = void 0;
19010
+ const prepared = await context.prepare(async (signal) => {
19011
+ supersedeActiveInstallOperations(ctrl, operationId);
19012
+ return await extensionManager.prepareExtensionInstall({
19013
+ installMetadata: { type: "local", source },
19014
+ localSourcePath: archivePath,
19015
+ initialActivation: { scope: "user" },
19016
+ requestConsent: /* @__PURE__ */ __name(() => Promise.resolve(), "requestConsent"),
19017
+ signal
19018
+ });
19019
+ });
19020
+ try {
19021
+ const committed = await context.commit(
19022
+ async (onCommitted) => await extensionManager.commitPreparedExtension(
19023
+ prepared,
19024
+ onCommitted
19025
+ )
19026
+ );
19027
+ result = {
19028
+ status: "installed",
19029
+ source,
19030
+ name: committed.identity.name,
19031
+ version: committed.version
19032
+ };
19033
+ } finally {
19034
+ await extensionManager.disposePreparedExtension(prepared);
19035
+ }
19036
+ } catch (error2) {
19037
+ failure = sanitizeUploadError(error2);
19038
+ }
19039
+ if (uploadDir) {
19040
+ try {
19041
+ await fs4.rm(uploadDir, { recursive: true, force: true });
19042
+ } catch (error2) {
19043
+ failure ??= sanitizeUploadError(error2);
19044
+ }
19045
+ }
19046
+ if (failure) throw failure;
19047
+ return result;
19048
+ },
19049
+ {
19050
+ createManager: /* @__PURE__ */ __name((operationId) => ctrl.createExtensionManager(
19051
+ void 0,
19052
+ void 0,
19053
+ extensionInteractionHandlers(ctrl, operationId)
19054
+ ), "createManager"),
19055
+ onSettled: /* @__PURE__ */ __name((operationId) => {
19056
+ supersededInstallOperations.delete(operationId);
19057
+ cancelPendingExtensionInteraction(
19058
+ operationId,
19059
+ "Extension operation ended"
19060
+ );
19061
+ }, "onSettled"),
19062
+ deadlineMs: EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS,
19063
+ ...globalReconciliationOptions()
19064
+ }
19065
+ );
19066
+ } catch (err) {
19067
+ sendBridgeError2(res, err, {
19068
+ route: `POST ${base}/install-archive`
19069
+ });
19070
+ }
19071
+ }
19072
+ );
18391
19073
  app.post(`${base}/install`, mutate({ strict: true }), async (req, res) => {
18392
19074
  const ctrl = resolve5(req, res, true);
18393
19075
  if (!ctrl) return;
@@ -19621,13 +20303,13 @@ async function handlePostFileWrite(req, res, deps) {
19621
20303
  req
19622
20304
  );
19623
20305
  if (originatorClientId === null) return;
19624
- const fs7 = factory.forRequest({
20306
+ const fs8 = factory.forRequest({
19625
20307
  originatorClientId,
19626
20308
  route: ROUTE2
19627
20309
  });
19628
20310
  try {
19629
- const resolved = await fs7.resolve(queryPath, "write");
19630
- const out = await fs7.writeTextAtomic(resolved, content, {
20311
+ const resolved = await fs8.resolve(queryPath, "write");
20312
+ const out = await fs8.writeTextAtomic(resolved, content, {
19631
20313
  mode,
19632
20314
  ...expectedHash ? { expectedHash } : {},
19633
20315
  ...bom !== void 0 ? { bom } : {},
@@ -19680,13 +20362,13 @@ async function handlePostFileEdit(req, res, deps) {
19680
20362
  req
19681
20363
  );
19682
20364
  if (originatorClientId === null) return;
19683
- const fs7 = factory.forRequest({
20365
+ const fs8 = factory.forRequest({
19684
20366
  originatorClientId,
19685
20367
  route: ROUTE2
19686
20368
  });
19687
20369
  try {
19688
- const resolved = await fs7.resolve(queryPath, "edit");
19689
- const out = await fs7.editAtomic(resolved, oldText, newText, {
20370
+ const resolved = await fs8.resolve(queryPath, "edit");
20371
+ const out = await fs8.editAtomic(resolved, oldText, newText, {
19690
20372
  expectedHash
19691
20373
  });
19692
20374
  applyReadHeaders(res);
@@ -20337,8 +21019,8 @@ function decodePathSegment(value) {
20337
21019
  }
20338
21020
  __name(decodePathSegment, "decodePathSegment");
20339
21021
  function matchLegacySessionTelemetryRoute(method, requestPath) {
20340
- const path14 = requestPath.length > 1 && requestPath.endsWith("/") ? requestPath.slice(0, -1) : requestPath;
20341
- const requestSegments = path14.split("/").slice(1);
21022
+ const path15 = requestPath.length > 1 && requestPath.endsWith("/") ? requestPath.slice(0, -1) : requestPath;
21023
+ const requestSegments = path15.split("/").slice(1);
20342
21024
  const prefix = requestSegments[0]?.toLowerCase();
20343
21025
  if (prefix !== "session" && prefix !== "sessions" && prefix !== "permission") {
20344
21026
  return void 0;
@@ -20390,23 +21072,23 @@ __name(setDaemonTelemetryWorkspace, "setDaemonTelemetryWorkspace");
20390
21072
  function resolveDaemonTelemetryRoute(req) {
20391
21073
  const legacyRoute = matchLegacySessionTelemetryRoute(req.method, req.path);
20392
21074
  if (legacyRoute) return legacyRoute;
20393
- const path14 = req.path.replace(/\/$/, "") || "/";
20394
- if (req.method === "GET" && path14 === "/daemon/status") {
21075
+ const path15 = req.path.replace(/\/$/, "") || "/";
21076
+ if (req.method === "GET" && path15 === "/daemon/status") {
20395
21077
  return { route: "GET /daemon/status" };
20396
21078
  }
20397
- if (req.method === "GET" && /^\/workspace\/[^/]+\/sessions$/.test(path14)) {
21079
+ if (req.method === "GET" && /^\/workspace\/[^/]+\/sessions$/.test(path15)) {
20398
21080
  return { route: "GET /workspace/:id/sessions" };
20399
21081
  }
20400
- if (req.method === "GET" && /^\/workspaces\/[^/]+\/sessions$/.test(path14)) {
21082
+ if (req.method === "GET" && /^\/workspaces\/[^/]+\/sessions$/.test(path15)) {
20401
21083
  return { route: "GET /workspace/:id/sessions" };
20402
21084
  }
20403
- if (req.method === "GET" && /^\/workspace\/[^/]+\/session-info$/.test(path14)) {
21085
+ if (req.method === "GET" && /^\/workspace\/[^/]+\/session-info$/.test(path15)) {
20404
21086
  return { route: "GET /workspace/:id/session-info" };
20405
21087
  }
20406
- if (req.method === "GET" && /^\/workspaces\/[^/]+\/session-info$/.test(path14)) {
21088
+ if (req.method === "GET" && /^\/workspaces\/[^/]+\/session-info$/.test(path15)) {
20407
21089
  return { route: "GET /workspace/:id/session-info" };
20408
21090
  }
20409
- const workspaceTranscript = path14.match(
21091
+ const workspaceTranscript = path15.match(
20410
21092
  /^\/workspaces\/[^/]+\/session\/([^/]+)\/transcript$/
20411
21093
  );
20412
21094
  if (workspaceTranscript?.[1] && req.method === "GET") {
@@ -20415,7 +21097,7 @@ function resolveDaemonTelemetryRoute(req) {
20415
21097
  sessionId: decodePathSegment(workspaceTranscript[1])
20416
21098
  };
20417
21099
  }
20418
- const workspaceExport = path14.match(
21100
+ const workspaceExport = path15.match(
20419
21101
  /^\/workspaces\/[^/]+\/session\/([^/]+)\/export$/
20420
21102
  );
20421
21103
  if (workspaceExport?.[1] && req.method === "GET") {
@@ -20424,7 +21106,7 @@ function resolveDaemonTelemetryRoute(req) {
20424
21106
  sessionId: decodePathSegment(workspaceExport[1])
20425
21107
  };
20426
21108
  }
20427
- const workspaceArchivedExport = path14.match(
21109
+ const workspaceArchivedExport = path15.match(
20428
21110
  /^\/workspaces\/[^/]+\/session\/([^/]+)\/archive\/export$/
20429
21111
  );
20430
21112
  if (workspaceArchivedExport?.[1] && req.method === "GET") {
@@ -20434,8 +21116,8 @@ function resolveDaemonTelemetryRoute(req) {
20434
21116
  };
20435
21117
  }
20436
21118
  const pluralWorkspacePrefix = /^\/workspaces\/[^/]+/;
20437
- if (pluralWorkspacePrefix.test(path14)) {
20438
- const suffix = path14.replace(pluralWorkspacePrefix, "/workspace");
21119
+ if (pluralWorkspacePrefix.test(path15)) {
21120
+ const suffix = path15.replace(pluralWorkspacePrefix, "/workspace");
20439
21121
  if (req.method === "GET") {
20440
21122
  if (suffix === "/workspace/mcp" || suffix === "/workspace/skills" || suffix === "/workspace/tools" || suffix === "/workspace/providers" || suffix === "/workspace/env" || suffix === "/workspace/preflight" || suffix === "/workspace/hooks" || suffix === "/workspace/settings" || suffix === "/workspace/voice" || suffix === "/workspace/permissions" || suffix === "/workspace/trust" || suffix === "/workspace/memory" || suffix === "/workspace/agents") {
20441
21123
  return { route: `GET ${suffix}` };
@@ -20494,58 +21176,58 @@ function resolveDaemonTelemetryRoute(req) {
20494
21176
  return { route: "DELETE /workspace/session-groups/:groupId" };
20495
21177
  }
20496
21178
  }
20497
- if (req.method === "POST" && path14 === "/workspace/init") {
21179
+ if (req.method === "POST" && path15 === "/workspace/init") {
20498
21180
  return { route: "POST /workspace/init" };
20499
21181
  }
20500
- if (req.method === "POST" && path14 === "/workspace/setup-github") {
21182
+ if (req.method === "POST" && path15 === "/workspace/setup-github") {
20501
21183
  return { route: "POST /workspace/setup-github" };
20502
21184
  }
20503
- if (req.method === "POST" && path14 === "/workspace/reload") {
21185
+ if (req.method === "POST" && path15 === "/workspace/reload") {
20504
21186
  return { route: "POST /workspace/reload" };
20505
21187
  }
20506
- const mcpRestart = path14.match(/^\/workspace\/mcp\/([^/]+)\/restart$/);
21188
+ const mcpRestart = path15.match(/^\/workspace\/mcp\/([^/]+)\/restart$/);
20507
21189
  if (mcpRestart?.[1] && req.method === "POST") {
20508
21190
  return { route: "POST /workspace/mcp/:server/restart" };
20509
21191
  }
20510
- if (req.method === "POST" && path14 === "/workspace/mcp/servers") {
21192
+ if (req.method === "POST" && path15 === "/workspace/mcp/servers") {
20511
21193
  return { route: "POST /workspace/mcp/servers" };
20512
21194
  }
20513
- const mcpDelete = path14.match(/^\/workspace\/mcp\/servers\/([^/]+)$/);
21195
+ const mcpDelete = path15.match(/^\/workspace\/mcp\/servers\/([^/]+)$/);
20514
21196
  if (mcpDelete?.[1] && req.method === "DELETE") {
20515
21197
  return { route: "DELETE /workspace/mcp/servers/:name" };
20516
21198
  }
20517
- if (req.method === "POST" && path14 === "/workspace/auth/device-flow") {
21199
+ if (req.method === "POST" && path15 === "/workspace/auth/device-flow") {
20518
21200
  return { route: "POST /workspace/auth/device-flow" };
20519
21201
  }
20520
- const deviceFlowDelete = path14.match(
21202
+ const deviceFlowDelete = path15.match(
20521
21203
  /^\/workspace\/auth\/device-flow\/([^/]+)$/
20522
21204
  );
20523
21205
  if (deviceFlowDelete?.[1] && req.method === "DELETE") {
20524
21206
  return { route: "DELETE /workspace/auth/device-flow/:id" };
20525
21207
  }
20526
- const toolEnable = path14.match(/^\/workspace\/tools\/([^/]+)\/enable$/);
21208
+ const toolEnable = path15.match(/^\/workspace\/tools\/([^/]+)\/enable$/);
20527
21209
  if (toolEnable?.[1] && req.method === "POST") {
20528
21210
  return { route: "POST /workspace/tools/:name/enable" };
20529
21211
  }
20530
- if (path14 === "/workspace/settings") {
21212
+ if (path15 === "/workspace/settings") {
20531
21213
  if (req.method === "GET") return { route: "GET /workspace/settings" };
20532
21214
  if (req.method === "POST") return { route: "POST /workspace/settings" };
20533
21215
  }
20534
- if (path14 === "/workspace/permissions") {
21216
+ if (path15 === "/workspace/permissions") {
20535
21217
  if (req.method === "GET") return { route: "GET /workspace/permissions" };
20536
21218
  if (req.method === "POST") return { route: "POST /workspace/permissions" };
20537
21219
  }
20538
- if (path14 === "/workspace/trust") {
21220
+ if (path15 === "/workspace/trust") {
20539
21221
  if (req.method === "GET") return { route: "GET /workspace/trust" };
20540
21222
  }
20541
- if (req.method === "POST" && path14 === "/workspace/trust/request") {
21223
+ if (req.method === "POST" && path15 === "/workspace/trust/request") {
20542
21224
  return { route: "POST /workspace/trust/request" };
20543
21225
  }
20544
- if (path14 === "/workspace/voice") {
21226
+ if (path15 === "/workspace/voice") {
20545
21227
  if (req.method === "GET") return { route: "GET /workspace/voice" };
20546
21228
  if (req.method === "POST") return { route: "POST /workspace/voice" };
20547
21229
  }
20548
- if (req.method === "POST" && path14 === "/workspace/voice/transcribe") {
21230
+ if (req.method === "POST" && path15 === "/workspace/voice/transcribe") {
20549
21231
  return { route: "POST /workspace/voice/transcribe" };
20550
21232
  }
20551
21233
  return void 0;
@@ -20813,8 +21495,8 @@ __name(registerPermissionRoutes, "registerPermissionRoutes");
20813
21495
  // packages/cli/src/serve/routes/session.ts
20814
21496
  init_esbuild_shims();
20815
21497
  import * as crypto3 from "node:crypto";
20816
- import * as fs5 from "node:fs";
20817
- import * as path9 from "node:path";
21498
+ import * as fs6 from "node:fs";
21499
+ import * as path10 from "node:path";
20818
21500
 
20819
21501
  // packages/cli/src/serve/server/prompt-deadline.ts
20820
21502
  init_esbuild_shims();
@@ -21505,7 +22187,7 @@ __name(deleteBranch, "deleteBranch");
21505
22187
 
21506
22188
  // packages/cli/src/serve/virtual-subagent-sessions.ts
21507
22189
  init_esbuild_shims();
21508
- import * as fs4 from "node:fs/promises";
22190
+ import * as fs5 from "node:fs/promises";
21509
22191
  import { createReadStream } from "node:fs";
21510
22192
  import readline from "node:readline";
21511
22193
  var PREFIX = "subagent.";
@@ -21699,7 +22381,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
21699
22381
  async readNewRecords(endOffset) {
21700
22382
  let handle;
21701
22383
  try {
21702
- handle = await fs4.open(this.task.outputFile, "r");
22384
+ handle = await fs5.open(this.task.outputFile, "r");
21703
22385
  const stat3 = await handle.stat();
21704
22386
  const identity = `${stat3.dev}:${stat3.ino}`;
21705
22387
  if (this.transcriptIdentity !== void 0 && this.transcriptIdentity !== identity || stat3.size < this.offset) {
@@ -21743,7 +22425,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
21743
22425
  const filePath = `${this.task.outputFile}.stream`;
21744
22426
  let handle;
21745
22427
  try {
21746
- handle = await fs4.open(filePath, "r");
22428
+ handle = await fs5.open(filePath, "r");
21747
22429
  const stat3 = await handle.stat();
21748
22430
  const identity = `${stat3.dev}:${stat3.ino}`;
21749
22431
  if (this.streamIdentity !== void 0 && this.streamIdentity !== identity) {
@@ -21908,7 +22590,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
21908
22590
  async captureReadBounds() {
21909
22591
  const size = /* @__PURE__ */ __name(async (filePath) => {
21910
22592
  try {
21911
- return (await fs4.stat(filePath)).size;
22593
+ return (await fs5.stat(filePath)).size;
21912
22594
  } catch (error2) {
21913
22595
  if (error2.code === "ENOENT") return 0;
21914
22596
  throw error2;
@@ -22037,7 +22719,7 @@ var VirtualSubagentSessions = class {
22037
22719
  const sessionDir = getSubagentSessionDir(projectDir, parentSessionId);
22038
22720
  let names;
22039
22721
  try {
22040
- names = await fs4.readdir(sessionDir);
22722
+ names = await fs5.readdir(sessionDir);
22041
22723
  } catch (error2) {
22042
22724
  if (error2.code === "ENOENT") return void 0;
22043
22725
  throw error2;
@@ -22093,7 +22775,7 @@ var VirtualSubagentSessions = class {
22093
22775
  const sessionDir = getSubagentSessionDir(projectDir, parentSessionId);
22094
22776
  let names;
22095
22777
  try {
22096
- names = await fs4.readdir(sessionDir);
22778
+ names = await fs5.readdir(sessionDir);
22097
22779
  } catch (error2) {
22098
22780
  if (error2.code === "ENOENT") return void 0;
22099
22781
  throw error2;
@@ -22238,8 +22920,7 @@ __name(createWorkspaceRuntimeSessionService, "createWorkspaceRuntimeSessionServi
22238
22920
  var GIT_RESERVED_BRANCH = "HEAD";
22239
22921
  var MAX_BRANCH_NAME_BYTES = 1e3;
22240
22922
  var MAX_BRANCH_COMPONENT_BYTES = 200;
22241
- var HTTP_SESSION_ID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
22242
- var WORKSPACE_TRANSCRIPT_RESPONSE_MAX_BYTES = 32 * 1024 * 1024;
22923
+ var WORKSPACE_TRANSCRIPT_RESPONSE_MAX_BYTES = 2 * SESSION_TRANSCRIPT_MAX_EXPANDED_PAGE_BYTES;
22243
22924
  var WORKSPACE_TRANSCRIPT_CURSOR_MAX_BYTES = 64 * 1024;
22244
22925
  var TRANSCRIPT_CURSOR_TOO_LARGE_REPLAY_ERROR = "Transcript pagination state exceeds the safe limit";
22245
22926
  var CHANNEL_DELIVERY_AUTHORIZATION_GRACE_MS = 6e4;
@@ -22398,15 +23079,6 @@ function shouldPreserveTranscriptResolutionError(err) {
22398
23079
  return err instanceof SessionArchivedError || err instanceof SessionConflictError || err instanceof SessionNotFoundError;
22399
23080
  }
22400
23081
  __name(shouldPreserveTranscriptResolutionError, "shouldPreserveTranscriptResolutionError");
22401
- function isSessionLive(bridge, sessionId) {
22402
- try {
22403
- bridge.getSessionSummary(sessionId);
22404
- return true;
22405
- } catch (err) {
22406
- return !(err instanceof SessionNotFoundError);
22407
- }
22408
- }
22409
- __name(isSessionLive, "isSessionLive");
22410
23082
  function parseOptionalApprovalMode(body, res) {
22411
23083
  const rawApprovalMode = body["approvalMode"];
22412
23084
  if (rawApprovalMode === void 0) {
@@ -22436,12 +23108,27 @@ function registerSessionRoutes(app, deps) {
22436
23108
  sessionShellCommandEnabled,
22437
23109
  virtualSubagentSessions
22438
23110
  } = deps;
23111
+ const requestedSessionIdAdmission = deps.requestedSessionIdAdmission ?? createRequestedSessionIdAdmission({
23112
+ archiveCoordinator,
23113
+ getBridges: /* @__PURE__ */ __name(() => workspaceRegistry.listManaged().map((runtime) => runtime.bridge), "getBridges"),
23114
+ getPersistenceTargets: /* @__PURE__ */ __name(() => workspaceRegistry.listManaged().map((runtime) => ({
23115
+ workspaceCwd: runtime.workspaceCwd,
23116
+ runtimeBaseDir: runtime.sessionRuntimeBaseDir
23117
+ })), "getPersistenceTargets"),
23118
+ getBridgeWorkspaceId: /* @__PURE__ */ __name((bridge2) => workspaceRegistry.listEntries().find((entry) => entry.current?.runtime.bridge === bridge2)?.workspaceId, "getBridgeWorkspaceId")
23119
+ });
23120
+ const captureRuntimeGenerationAssertion = /* @__PURE__ */ __name((runtime) => {
23121
+ const registeredGeneration = workspaceRegistry.getEntryByWorkspaceId(
23122
+ runtime.workspaceId
23123
+ )?.current;
23124
+ const guard = registeredGeneration?.runtime === runtime ? registeredGeneration.guard : runtime.generationGuard;
23125
+ return guard ? () => guard.assertOpen() : void 0;
23126
+ }, "captureRuntimeGenerationAssertion");
22439
23127
  const LANGUAGE_CODES = deps.languageCodes;
22440
23128
  const transcriptCursorMasterKey = crypto3.randomBytes(32);
22441
23129
  const transcriptCursorCodecs = /* @__PURE__ */ new Map();
22442
23130
  const activeBranchSessions = /* @__PURE__ */ new Map();
22443
23131
  const inFlightBranchWorkspaces = /* @__PURE__ */ new Set();
22444
- const inFlightSessionIds = /* @__PURE__ */ new Set();
22445
23132
  const clearBranchSessionEntry = /* @__PURE__ */ __name((sessionId) => {
22446
23133
  for (const [cwd, sid] of activeBranchSessions) {
22447
23134
  if (sid === sessionId) {
@@ -22503,6 +23190,20 @@ function registerSessionRoutes(app, deps) {
22503
23190
  ...details
22504
23191
  });
22505
23192
  }, "logSessionRoutingFailure");
23193
+ const sendRequestedSessionIdAdmissionError = /* @__PURE__ */ __name((res, error2, route) => {
23194
+ const resolutionKind = error2.code === "session_workspace_conflict" ? "workspace_conflict" : error2.code;
23195
+ logSessionRoutingFailure(route, resolutionKind, {
23196
+ sessionId: error2.sessionId,
23197
+ ...error2.details
23198
+ });
23199
+ const status = error2.code === "session_id_admission_unavailable" ? 503 : 409;
23200
+ res.status(status).json({
23201
+ error: error2.message,
23202
+ code: error2.code,
23203
+ sessionId: error2.sessionId,
23204
+ ...error2.details
23205
+ });
23206
+ }, "sendRequestedSessionIdAdmissionError");
22506
23207
  const sendWorkspaceMismatch2 = /* @__PURE__ */ __name((res, requestedWorkspace) => {
22507
23208
  const runtimes = workspaceRegistry.list();
22508
23209
  if (runtimes.length > 1) {
@@ -22582,7 +23283,7 @@ function registerSessionRoutes(app, deps) {
22582
23283
  const workspaceParam = req.params[paramName] ?? "";
22583
23284
  const byId = workspaceRegistry.getByWorkspaceId(workspaceParam);
22584
23285
  if (byId) return byId;
22585
- if (!path9.isAbsolute(workspaceParam)) {
23286
+ if (!path10.isAbsolute(workspaceParam)) {
22586
23287
  res.status(400).json({
22587
23288
  error: `\`:${paramName}\` must decode to a workspace id or absolute path`
22588
23289
  });
@@ -22767,7 +23468,6 @@ function registerSessionRoutes(app, deps) {
22767
23468
  sendUntrustedSessionOwner(res, route, sessionId, runtime);
22768
23469
  return false;
22769
23470
  }, "assertTrustedSessionOwner");
22770
- const inFlightRestoreOwners = /* @__PURE__ */ new Map();
22771
23471
  const sendSessionWorkspaceConflict = /* @__PURE__ */ __name((res, route, sessionId, runtime, liveRuntime) => {
22772
23472
  logSessionRoutingFailure(route, "workspace_conflict", {
22773
23473
  sessionId,
@@ -22786,33 +23486,6 @@ function registerSessionRoutes(app, deps) {
22786
23486
  liveWorkspaceId: liveRuntime.workspaceId
22787
23487
  });
22788
23488
  }, "sendSessionWorkspaceConflict");
22789
- const enterRestoreOwner = /* @__PURE__ */ __name((res, route, sessionId, runtime) => {
22790
- const existing = inFlightRestoreOwners.get(sessionId);
22791
- if (existing && existing.workspaceCwd !== runtime.workspaceCwd) {
22792
- sendSessionWorkspaceConflict(res, route, sessionId, runtime, existing);
22793
- return void 0;
22794
- }
22795
- if (existing) {
22796
- existing.count += 1;
22797
- } else {
22798
- inFlightRestoreOwners.set(sessionId, {
22799
- workspaceId: runtime.workspaceId,
22800
- workspaceCwd: runtime.workspaceCwd,
22801
- count: 1
22802
- });
22803
- }
22804
- let released = false;
22805
- return () => {
22806
- if (released) return;
22807
- released = true;
22808
- const current = inFlightRestoreOwners.get(sessionId);
22809
- if (!current || current.workspaceCwd !== runtime.workspaceCwd) return;
22810
- current.count -= 1;
22811
- if (current.count <= 0) {
22812
- inFlightRestoreOwners.delete(sessionId);
22813
- }
22814
- };
22815
- }, "enterRestoreOwner");
22816
23489
  const resolveRuntimeForSessionRestore = /* @__PURE__ */ __name((body, res, route, sessionId) => {
22817
23490
  const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
22818
23491
  if (cwd === void 0) return void 0;
@@ -23063,6 +23736,7 @@ function registerSessionRoutes(app, deps) {
23063
23736
  });
23064
23737
  return;
23065
23738
  }
23739
+ const assertRuntimeGenerationOpen = captureRuntimeGenerationAssertion(runtime);
23066
23740
  const modelServiceId = typeof body["modelServiceId"] === "string" ? body["modelServiceId"] : void 0;
23067
23741
  const rawSessionScope = body["sessionScope"];
23068
23742
  let sessionScope;
@@ -23095,52 +23769,39 @@ function registerSessionRoutes(app, deps) {
23095
23769
  }
23096
23770
  const clientId = parseClientIdHeader(req, res);
23097
23771
  if (clientId === null) return;
23098
- const rawSessionId = body["sessionId"];
23099
- let requestedSessionId;
23100
- if (rawSessionId !== void 0 && rawSessionId !== null) {
23101
- if (typeof rawSessionId !== "string" || !HTTP_SESSION_ID_REGEX.test(rawSessionId)) {
23102
- res.status(400).json({
23103
- error: '`sessionId` must be a UUID (e.g. "550e8400-e29b-41d4-a716-446655440000")',
23104
- code: "invalid_session_id"
23105
- });
23106
- return;
23107
- }
23108
- requestedSessionId = rawSessionId.toLowerCase();
23109
- const sessionIdToCheck = requestedSessionId;
23110
- if (isSessionLive(runtime.bridge, sessionIdToCheck)) {
23111
- res.status(409).json({
23112
- error: `Session "${requestedSessionId}" already exists`,
23113
- code: "session_id_conflict"
23114
- });
23115
- return;
23116
- }
23117
- const runtimeOutputDir = loadSettingsCached(workspaceCwd).merged.advanced?.runtimeOutputDir;
23118
- if (await Storage.runWithRuntimeBaseDir(
23119
- runtimeOutputDir,
23120
- workspaceCwd,
23121
- () => new SessionService(workspaceCwd).sessionExistsInAnyState(
23122
- sessionIdToCheck
23123
- )
23124
- )) {
23125
- res.status(409).json({
23126
- error: `Session "${requestedSessionId}" already exists`,
23127
- code: "session_id_conflict"
23128
- });
23129
- return;
23130
- }
23131
- if (inFlightSessionIds.has(requestedSessionId)) {
23132
- res.status(409).json({
23133
- error: `Session "${requestedSessionId}" creation already in progress`,
23134
- code: "session_id_conflict"
23135
- });
23136
- return;
23772
+ const parsedSessionId = parseCallerSuppliedSessionId(body["sessionId"]);
23773
+ if (parsedSessionId.kind === "invalid") {
23774
+ res.status(400).json({
23775
+ error: '`sessionId` must be an RFC UUID v1-v5 (e.g. "550e8400-e29b-41d4-a716-446655440000")',
23776
+ code: "invalid_session_id"
23777
+ });
23778
+ return;
23779
+ }
23780
+ const requestedSessionId = parsedSessionId.kind === "valid" ? parsedSessionId.sessionId : void 0;
23781
+ let sessionIdReservation;
23782
+ if (requestedSessionId !== void 0) {
23783
+ try {
23784
+ sessionIdReservation = await requestedSessionIdAdmission.reserveCreate(
23785
+ requestedSessionId,
23786
+ {
23787
+ bridge: runtime.bridge,
23788
+ workspaceCwd,
23789
+ workspaceId: runtime.workspaceId
23790
+ }
23791
+ );
23792
+ } catch (error2) {
23793
+ if (error2 instanceof RequestedSessionIdAdmissionError) {
23794
+ sendRequestedSessionIdAdmissionError(res, error2, "POST /session");
23795
+ return;
23796
+ }
23797
+ throw error2;
23137
23798
  }
23138
- inFlightSessionIds.add(requestedSessionId);
23139
23799
  }
23140
23800
  let branchMeta;
23141
23801
  let branchBaseCommit;
23142
23802
  let worktreeMeta;
23143
23803
  try {
23804
+ assertRuntimeGenerationOpen?.();
23144
23805
  const rawBranch = body["branch"];
23145
23806
  if (rawBranch !== void 0 && rawBranch !== null) {
23146
23807
  if (body["worktree"] !== void 0 && body["worktree"] !== null) {
@@ -23248,6 +23909,7 @@ function registerSessionRoutes(app, deps) {
23248
23909
  });
23249
23910
  return;
23250
23911
  }
23912
+ assertRuntimeGenerationOpen?.();
23251
23913
  inFlightBranchWorkspaces.add(workspaceCwd);
23252
23914
  try {
23253
23915
  await createBranch(workspaceCwd, branchName);
@@ -23317,6 +23979,7 @@ function registerSessionRoutes(app, deps) {
23317
23979
  return;
23318
23980
  }
23319
23981
  const baseBranch = await wtService.getCurrentBranch().catch(() => void 0);
23982
+ assertRuntimeGenerationOpen?.();
23320
23983
  const wtResult = await wtService.createUserWorktree(slug, baseBranch);
23321
23984
  if (!wtResult.success || !wtResult.worktree) {
23322
23985
  res.status(500).json({
@@ -23335,6 +23998,7 @@ function registerSessionRoutes(app, deps) {
23335
23998
  if (requestedSessionId !== void 0) {
23336
23999
  sessionScope = "thread";
23337
24000
  }
24001
+ assertRuntimeGenerationOpen?.();
23338
24002
  const session = await runtime.bridge.spawnOrAttach({
23339
24003
  workspaceCwd,
23340
24004
  modelServiceId,
@@ -23364,6 +24028,9 @@ function registerSessionRoutes(app, deps) {
23364
24028
  coordinator: archiveCoordinator
23365
24029
  })
23366
24030
  ).catch(() => false);
24031
+ } else {
24032
+ await runtime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
24033
+ });
23367
24034
  }
23368
24035
  if (worktreeMeta) {
23369
24036
  await new GitWorktreeService(workspaceCwd).removeUserWorktree(worktreeMeta.slug, { deleteBranch: true }).catch(() => {
@@ -23384,7 +24051,7 @@ function registerSessionRoutes(app, deps) {
23384
24051
  return;
23385
24052
  }
23386
24053
  try {
23387
- runtime.generationGuard?.assertOpen();
24054
+ assertRuntimeGenerationOpen?.();
23388
24055
  } catch (error2) {
23389
24056
  if (!session.attached) {
23390
24057
  try {
@@ -23473,7 +24140,7 @@ function registerSessionRoutes(app, deps) {
23473
24140
  if (worktreeMeta) {
23474
24141
  try {
23475
24142
  const createAllowedRoots = [
23476
- path9.join(workspaceCwd, ".qwen", "worktrees")
24143
+ path10.join(workspaceCwd, ".qwen", "worktrees")
23477
24144
  ];
23478
24145
  let createRepoTop = null;
23479
24146
  try {
@@ -23484,7 +24151,7 @@ function registerSessionRoutes(app, deps) {
23484
24151
  }
23485
24152
  if (createRepoTop && createRepoTop !== workspaceCwd) {
23486
24153
  createAllowedRoots.push(
23487
- path9.join(createRepoTop, ".qwen", "worktrees")
24154
+ path10.join(createRepoTop, ".qwen", "worktrees")
23488
24155
  );
23489
24156
  }
23490
24157
  await runtime.bridge.changeSessionCwd(session.sessionId, {
@@ -23555,9 +24222,7 @@ function registerSessionRoutes(app, deps) {
23555
24222
  }
23556
24223
  sendBridgeError2(res, err, { route: "POST /session" });
23557
24224
  } finally {
23558
- if (requestedSessionId !== void 0) {
23559
- inFlightSessionIds.delete(requestedSessionId);
23560
- }
24225
+ sessionIdReservation?.release();
23561
24226
  }
23562
24227
  });
23563
24228
  const restoreSessionHandler = /* @__PURE__ */ __name((action) => async (req, res) => {
@@ -23628,27 +24293,29 @@ function registerSessionRoutes(app, deps) {
23628
24293
  }
23629
24294
  if (resolvedRuntime === void 0) return;
23630
24295
  const { runtime, workspaceCwd } = resolvedRuntime;
23631
- const releaseRestoreOwner = enterRestoreOwner(
23632
- res,
23633
- route,
23634
- sessionId,
23635
- runtime
23636
- );
23637
- if (!releaseRestoreOwner) return;
24296
+ const assertRuntimeGenerationOpen = captureRuntimeGenerationAssertion(runtime);
23638
24297
  const approvalMode = parseOptionalApprovalMode(body, res);
23639
- if (approvalMode === null) {
23640
- releaseRestoreOwner();
23641
- return;
23642
- }
24298
+ if (approvalMode === null) return;
23643
24299
  const historyPageSize = action === "load" ? parseHistoryPageSize(body ?? {}, res) : void 0;
23644
- if (historyPageSize === null) {
23645
- releaseRestoreOwner();
23646
- return;
23647
- }
24300
+ if (historyPageSize === null) return;
23648
24301
  const clientId = parseClientIdHeader(req, res);
23649
- if (clientId === null) {
23650
- releaseRestoreOwner();
23651
- return;
24302
+ if (clientId === null) return;
24303
+ let sessionIdReservation;
24304
+ try {
24305
+ sessionIdReservation = requestedSessionIdAdmission.reserveRestore(
24306
+ sessionId,
24307
+ {
24308
+ bridge: runtime.bridge,
24309
+ workspaceCwd,
24310
+ workspaceId: runtime.workspaceId
24311
+ }
24312
+ );
24313
+ } catch (error2) {
24314
+ if (error2 instanceof RequestedSessionIdAdmissionError) {
24315
+ sendRequestedSessionIdAdmissionError(res, error2, route);
24316
+ return;
24317
+ }
24318
+ throw error2;
23652
24319
  }
23653
24320
  try {
23654
24321
  const session = await archiveCoordinator.runSharedMany(
@@ -23675,7 +24342,7 @@ function registerSessionRoutes(app, deps) {
23675
24342
  }
23676
24343
  liveConversationCwd = await materialize(sessionId);
23677
24344
  }
23678
- runtime.generationGuard?.assertOpen();
24345
+ assertRuntimeGenerationOpen?.();
23679
24346
  const restored = action === "load" ? await runtime.bridge.loadSession({
23680
24347
  sessionId,
23681
24348
  workspaceCwd,
@@ -23747,7 +24414,7 @@ function registerSessionRoutes(app, deps) {
23747
24414
  }
23748
24415
  );
23749
24416
  try {
23750
- runtime.generationGuard?.assertOpen();
24417
+ assertRuntimeGenerationOpen?.();
23751
24418
  } catch (error2) {
23752
24419
  if (!session.attached) {
23753
24420
  await runtime.bridge.killSession(session.sessionId, { requireZeroAttaches: true }).catch(() => {
@@ -23783,10 +24450,10 @@ function registerSessionRoutes(app, deps) {
23783
24450
  if (sidecar) {
23784
24451
  let realTarget;
23785
24452
  const candidateRoots = [
23786
- path9.join(workspaceCwd, ".qwen", "worktrees")
24453
+ path10.join(workspaceCwd, ".qwen", "worktrees")
23787
24454
  ];
23788
24455
  try {
23789
- realTarget = fs5.realpathSync(sidecar.worktreePath);
24456
+ realTarget = fs6.realpathSync(sidecar.worktreePath);
23790
24457
  let repoTop = null;
23791
24458
  try {
23792
24459
  repoTop = await new GitWorktreeService(
@@ -23795,13 +24462,13 @@ function registerSessionRoutes(app, deps) {
23795
24462
  } catch {
23796
24463
  }
23797
24464
  if (repoTop && repoTop !== workspaceCwd) {
23798
- candidateRoots.push(path9.join(repoTop, ".qwen", "worktrees"));
24465
+ candidateRoots.push(path10.join(repoTop, ".qwen", "worktrees"));
23799
24466
  }
23800
24467
  const contained = candidateRoots.some((root) => {
23801
24468
  try {
23802
- const realRoot = fs5.realpathSync(root);
23803
- const rel = path9.relative(realRoot, realTarget);
23804
- return !rel.startsWith("..") && !path9.isAbsolute(rel);
24469
+ const realRoot = fs6.realpathSync(root);
24470
+ const rel = path10.relative(realRoot, realTarget);
24471
+ return !rel.startsWith("..") && !path10.isAbsolute(rel);
23805
24472
  } catch {
23806
24473
  return false;
23807
24474
  }
@@ -23849,7 +24516,7 @@ function registerSessionRoutes(app, deps) {
23849
24516
  sessionId
23850
24517
  });
23851
24518
  } finally {
23852
- releaseRestoreOwner();
24519
+ sessionIdReservation.release();
23853
24520
  }
23854
24521
  }, "restoreSessionHandler");
23855
24522
  app.post("/session/:id/load", mutate(), restoreSessionHandler("load"));
@@ -24117,7 +24784,7 @@ function registerSessionRoutes(app, deps) {
24117
24784
  async (req, res, sessionId, runtime) => {
24118
24785
  const body = safeBody(req);
24119
24786
  const targetPath = body["path"];
24120
- if (typeof targetPath !== "string" || targetPath.length === 0 || !path9.isAbsolute(targetPath)) {
24787
+ if (typeof targetPath !== "string" || targetPath.length === 0 || !path10.isAbsolute(targetPath)) {
24121
24788
  res.status(400).json({
24122
24789
  error: "`path` is required and must be an absolute path",
24123
24790
  code: "invalid_path"
@@ -27151,7 +27818,7 @@ __name(registerUsageStatsRoutes, "registerUsageStatsRoutes");
27151
27818
  // packages/cli/src/serve/scheduled-task-keepalive.ts
27152
27819
  init_esbuild_shims();
27153
27820
  import * as fsSync from "node:fs";
27154
- import * as path10 from "node:path";
27821
+ import * as path11 from "node:path";
27155
27822
  var log = createDebugLogger("SCHED_KEEPALIVE");
27156
27823
  function collectBoundSessionIds(tasks) {
27157
27824
  const seen = /* @__PURE__ */ new Set();
@@ -27169,7 +27836,7 @@ function collectBoundSessionIds(tasks) {
27169
27836
  return ids;
27170
27837
  }
27171
27838
  __name(collectBoundSessionIds, "collectBoundSessionIds");
27172
- var KEEPALIVE_REVIVE_TIMEOUT_MS = 3e4;
27839
+ var KEEPALIVE_REVIVE_TIMEOUT_MS = 7e4;
27173
27840
  var KEEPALIVE_SPAWN_TIMEOUT_MS = 3e4;
27174
27841
  var MAX_REVIVE_BACKOFF_MS = 30 * 6e4;
27175
27842
  async function bindAndNameSessions(bridge, boundWorkspace, tasks, renamed, spawnTimeoutMs, binding, cleanupSession) {
@@ -27377,8 +28044,8 @@ function startScheduledTaskKeepalive(opts) {
27377
28044
  opts.runtimeBaseDir,
27378
28045
  () => getCronFilePath(boundWorkspace)
27379
28046
  );
27380
- const cronDir = path10.dirname(cronFilePath);
27381
- const cronFileName = path10.basename(cronFilePath);
28047
+ const cronDir = path11.dirname(cronFilePath);
28048
+ const cronFileName = path11.basename(cronFilePath);
27382
28049
  let fileWatcher;
27383
28050
  try {
27384
28051
  fsSync.mkdirSync(cronDir, { recursive: true });
@@ -27415,7 +28082,7 @@ function startScheduledTaskKeepalive(opts) {
27415
28082
  };
27416
28083
  }
27417
28084
  __name(startScheduledTaskKeepalive, "startScheduledTaskKeepalive");
27418
- var REHYDRATE_LOAD_TIMEOUT_MS = 3e4;
28085
+ var REHYDRATE_LOAD_TIMEOUT_MS = 7e4;
27419
28086
  var REHYDRATE_MAX_CONCURRENCY = 4;
27420
28087
  async function rehydrateScheduledTaskSessions(deps) {
27421
28088
  const { bridge, boundWorkspace } = deps;
@@ -27474,6 +28141,7 @@ async function rehydrateScheduledTaskSessions(deps) {
27474
28141
  }
27475
28142
  __name(rehydrateScheduledTaskSessions, "rehydrateScheduledTaskSessions");
27476
28143
  function withTimeout(p, ms, label) {
28144
+ if (ms > MAX_SESSION_RESTORE_TIMEOUT_MS) return p;
27477
28145
  return new Promise((resolve5, reject) => {
27478
28146
  const timer = setTimeout(() => {
27479
28147
  reject(new Error(`${label} timed out after ${ms}ms`));
@@ -28040,6 +28708,7 @@ function registerCapabilitiesRoutes(app, deps) {
28040
28708
  maxPendingPromptsPerSession: advertisedMaxPendingPromptsPerSession(
28041
28709
  deps.maxPendingPromptsPerSession
28042
28710
  ),
28711
+ sessionRestoreTimeoutMs: deps.sessionRestoreTimeoutMs,
28043
28712
  ...multiWorkspace ? {
28044
28713
  maxSessionsPerWorkspace: advertisedMaxSessions(
28045
28714
  deps.maxSessionsPerWorkspace
@@ -28864,6 +29533,25 @@ function bridgeErrorExtraContext(ctx) {
28864
29533
  return extra;
28865
29534
  }
28866
29535
  __name(bridgeErrorExtraContext, "bridgeErrorExtraContext");
29536
+ function recordExpectedBridgeError(err, ctx, daemonLog) {
29537
+ recordDaemonBridgeError(err);
29538
+ recordDaemonError(void 0, err, {
29539
+ ...ctx?.route ? { "http.route": ctx.route } : {},
29540
+ ...ctx?.sessionId ? { "session.id": ctx.sessionId } : {}
29541
+ });
29542
+ emitDaemonLog("Daemon bridge request failed.", {
29543
+ ...ctx?.route ? { "http.route": ctx.route } : {},
29544
+ ...ctx?.sessionId ? { "session.id": ctx.sessionId } : {},
29545
+ "error.type": err.name,
29546
+ "error.message": err.message.slice(0, 1024)
29547
+ });
29548
+ daemonLog?.warn(err.message, {
29549
+ ...ctx?.route ? { route: ctx.route } : {},
29550
+ ...ctx?.sessionId ? { sessionId: ctx.sessionId } : {},
29551
+ errorType: err.name
29552
+ });
29553
+ }
29554
+ __name(recordExpectedBridgeError, "recordExpectedBridgeError");
28867
29555
  function sendPermissionVoteError(res, err, ctx, daemonLog) {
28868
29556
  if (err instanceof InvalidPermissionOptionError) {
28869
29557
  res.status(400).json({
@@ -28905,6 +29593,33 @@ function sendPermissionVoteError(res, err, ctx, daemonLog) {
28905
29593
  }
28906
29594
  __name(sendPermissionVoteError, "sendPermissionVoteError");
28907
29595
  function sendBridgeError(res, err, ctx, daemonLog) {
29596
+ if (err instanceof SessionRestoreTimeoutError) {
29597
+ recordExpectedBridgeError(err, ctx, daemonLog);
29598
+ res.set("Retry-After", String(restoreRetryAfterSeconds(err.timeoutMs)));
29599
+ res.status(504).json({
29600
+ error: err.message,
29601
+ code: "session_restore_timeout",
29602
+ errorKind: "restore_timeout",
29603
+ retryable: true,
29604
+ sessionId: err.sessionId,
29605
+ action: err.action,
29606
+ timeoutMs: err.timeoutMs
29607
+ });
29608
+ return;
29609
+ }
29610
+ if (err instanceof BridgeChannelQuarantinedError) {
29611
+ recordExpectedBridgeError(err, ctx, daemonLog);
29612
+ res.set("Retry-After", String(err.retryAfterSeconds));
29613
+ res.status(503).json({
29614
+ error: err.message,
29615
+ code: "acp_channel_unavailable",
29616
+ errorKind: "acp_channel_unavailable",
29617
+ retryable: true,
29618
+ reason: err.reason,
29619
+ retryAfterSeconds: err.retryAfterSeconds
29620
+ });
29621
+ return;
29622
+ }
28908
29623
  if (err instanceof DaemonDrainingError) {
28909
29624
  res.status(503).json({
28910
29625
  error: err.message,
@@ -28922,22 +29637,9 @@ function sendBridgeError(res, err, ctx, daemonLog) {
28922
29637
  });
28923
29638
  return;
28924
29639
  }
28925
- if (err instanceof WorkspaceSkillNotFoundError) {
28926
- res.status(404).json({
28927
- error: err.message,
28928
- code: "skill_not_found",
28929
- skillName: err.skillName
28930
- });
28931
- return;
28932
- }
28933
- if (err instanceof WorkspaceSkillNotToggleableError) {
28934
- res.status(409).json({
28935
- error: err.message,
28936
- code: err.reason === "inactive_extension" ? "skill_inactive_extension" : "skill_not_toggleable",
28937
- skillName: err.skillName,
28938
- reason: err.reason,
28939
- ...err.lockedScope ? { lockedScope: err.lockedScope } : {}
28940
- });
29640
+ const skillError = mapWorkspaceSkillToggleError(err);
29641
+ if (skillError) {
29642
+ res.status(skillError.code === "skill_not_found" ? 404 : 409).json(skillError);
28941
29643
  return;
28942
29644
  }
28943
29645
  if (err instanceof InvalidSessionTranscriptCursorError) {
@@ -29203,10 +29905,12 @@ function sendBridgeError(res, err, ctx, daemonLog) {
29203
29905
  return;
29204
29906
  }
29205
29907
  if (err instanceof RestoreInProgressError) {
29206
- res.set("Retry-After", "5");
29908
+ res.set("Retry-After", String(err.retryAfterSeconds));
29207
29909
  res.status(409).json({
29208
29910
  error: err.message,
29209
29911
  code: "restore_in_progress",
29912
+ reason: err.reason,
29913
+ retryable: true,
29210
29914
  sessionId: err.sessionId,
29211
29915
  activeAction: err.activeAction,
29212
29916
  requestedAction: err.requestedAction
@@ -30323,7 +31027,7 @@ __name(registerWorkspaceModelsRoutes, "registerWorkspaceModelsRoutes");
30323
31027
  // packages/cli/src/serve/routes/a2ui-action.ts
30324
31028
  init_esbuild_shims();
30325
31029
  import * as fsp4 from "node:fs/promises";
30326
- import * as path11 from "node:path";
31030
+ import * as path12 from "node:path";
30327
31031
  var A2UI_MIME = "application/a2ui+json";
30328
31032
  var ACTION_TOOL = "action";
30329
31033
  var CALL_TIMEOUT_MS = 15e3;
@@ -30346,7 +31050,7 @@ __name(usableServerConfig, "usableServerConfig");
30346
31050
  async function findFromSettingsFile(workspaceCwd) {
30347
31051
  try {
30348
31052
  const raw = await fsp4.readFile(
30349
- path11.join(workspaceCwd, ".qwen", "settings.json"),
31053
+ path12.join(workspaceCwd, ".qwen", "settings.json"),
30350
31054
  "utf8"
30351
31055
  );
30352
31056
  const settings = JSON.parse(raw);
@@ -30507,7 +31211,7 @@ __name(registerA2uiActionRoutes, "registerA2uiActionRoutes");
30507
31211
 
30508
31212
  // packages/cli/src/serve/server/fs-factory.ts
30509
31213
  init_esbuild_shims();
30510
- import * as path12 from "node:path";
31214
+ import * as path13 from "node:path";
30511
31215
  var IDE_WORKSPACE_PATH_ENV_VAR = "QWEN_CODE_IDE_WORKSPACE_PATH";
30512
31216
  function createDefaultFsAuditEmit() {
30513
31217
  const WARN_EVERY = 100;
@@ -30582,14 +31286,14 @@ function parseIdeWorkspacePathEnv(value) {
30582
31286
  const parsed = JSON.parse(value);
30583
31287
  if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
30584
31288
  return parsed.filter(
30585
- (workspace) => workspace.length > 0 && path12.isAbsolute(workspace)
31289
+ (workspace) => workspace.length > 0 && path13.isAbsolute(workspace)
30586
31290
  );
30587
31291
  }
30588
31292
  throw new Error("IDE workspace path JSON must be a string array");
30589
31293
  } catch {
30590
31294
  }
30591
31295
  }
30592
- return value.split(path12.delimiter).filter((workspace) => workspace.length > 0 && path12.isAbsolute(workspace));
31296
+ return value.split(path13.delimiter).filter((workspace) => workspace.length > 0 && path13.isAbsolute(workspace));
30593
31297
  }
30594
31298
  __name(parseIdeWorkspacePathEnv, "parseIdeWorkspacePathEnv");
30595
31299
  function dropNestedWorkspacesPreservingPrimary(workspaces) {
@@ -30858,9 +31562,9 @@ __name(setupDeviceFlowRegistry, "setupDeviceFlowRegistry");
30858
31562
 
30859
31563
  // packages/cli/src/serve/server/error-handlers.ts
30860
31564
  init_esbuild_shims();
30861
- var import_express2 = __toESM(require_express(), 1);
31565
+ var import_express3 = __toESM(require_express(), 1);
30862
31566
  function installJsonBodyParser(app) {
30863
- app.use(import_express2.default.json({ limit: "10mb" }));
31567
+ app.use(import_express3.default.json({ limit: "10mb" }));
30864
31568
  app.use((err, _req, res, next) => {
30865
31569
  if (sendJsonBodyParserError(res, err)) return;
30866
31570
  next(err);
@@ -30914,10 +31618,10 @@ function installRateLimiter(app, opts, daemonLog, options = {}) {
30914
31618
  { tier, key: key.slice(0, 64) }
30915
31619
  );
30916
31620
  } : void 0,
30917
- onError: daemonLog ? (err, path14) => {
31621
+ onError: daemonLog ? (err, path15) => {
30918
31622
  daemonLog.warn(
30919
31623
  `rate limiter error (fail-open): ${err instanceof Error ? err.message : String(err)}`,
30920
- { path: path14 }
31624
+ { path: path15 }
30921
31625
  );
30922
31626
  } : void 0
30923
31627
  });
@@ -31113,7 +31817,7 @@ __name(registerWorkspaceQualifiedLifecycleRoutes, "registerWorkspaceQualifiedLif
31113
31817
  init_esbuild_shims();
31114
31818
  import { readdir as readdir2, stat as stat2 } from "node:fs/promises";
31115
31819
  import { realpathSync as realpathSync3 } from "node:fs";
31116
- import { basename as basename4, dirname as dirname4, isAbsolute as isAbsolute7, join as join7, resolve as resolve4, sep as sep3 } from "node:path";
31820
+ import { basename as basename4, dirname as dirname4, isAbsolute as isAbsolute7, join as join8, resolve as resolve4, sep as sep3 } from "node:path";
31117
31821
 
31118
31822
  // packages/cli/src/serve/native-directory-picker.ts
31119
31823
  init_esbuild_shims();
@@ -31499,7 +32203,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
31499
32203
  return;
31500
32204
  }
31501
32205
  const endsWithSep = prefix.endsWith("/") || process.platform === "win32" && prefix.endsWith("\\");
31502
- const dir = endsWithSep ? join7(prefix, ".") : dirname4(prefix);
32206
+ const dir = endsWithSep ? join8(prefix, ".") : dirname4(prefix);
31503
32207
  const filter = endsWithSep ? "" : basename4(prefix);
31504
32208
  const filterLower = filter.toLowerCase();
31505
32209
  const suggestions = [];
@@ -31515,7 +32219,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
31515
32219
  let isDir = entry.isDirectory();
31516
32220
  if (!isDir && entry.isSymbolicLink()) {
31517
32221
  try {
31518
- isDir = (await stat2(join7(dir, entry.name))).isDirectory();
32222
+ isDir = (await stat2(join8(dir, entry.name))).isDirectory();
31519
32223
  } catch {
31520
32224
  continue;
31521
32225
  }
@@ -31525,7 +32229,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
31525
32229
  truncated = true;
31526
32230
  break;
31527
32231
  }
31528
- suggestions.push({ name: entry.name, path: join7(dir, entry.name) });
32232
+ suggestions.push({ name: entry.name, path: join8(dir, entry.name) });
31529
32233
  }
31530
32234
  } catch {
31531
32235
  }
@@ -31545,11 +32249,11 @@ function registerWorkspaceManagementRoutes(app, deps) {
31545
32249
  const controller = new AbortController();
31546
32250
  res.on("close", () => controller.abort());
31547
32251
  try {
31548
- const path14 = await pickWorkspaceDirectory(controller.signal);
32252
+ const path15 = await pickWorkspaceDirectory(controller.signal);
31549
32253
  res.status(200).json({
31550
32254
  kind: "workspace-directory-picker",
31551
- selected: path14 !== void 0,
31552
- ...path14 === void 0 ? {} : { path: path14 }
32255
+ selected: path15 !== void 0,
32256
+ ...path15 === void 0 ? {} : { path: path15 }
31553
32257
  });
31554
32258
  } catch (error2) {
31555
32259
  const detail = error2 instanceof Error ? error2.message : String(error2);
@@ -32606,8 +33310,8 @@ function buildDiffList(workspaceCwd, result) {
32606
33310
  hiddenCount: 0
32607
33311
  };
32608
33312
  }
32609
- const files = [...result.perFileStats.entries()].map(([path14, s]) => ({
32610
- path: path14,
33313
+ const files = [...result.perFileStats.entries()].map(([path15, s]) => ({
33314
+ path: path15,
32611
33315
  oldPath: s.oldPath,
32612
33316
  added: s.added,
32613
33317
  removed: s.removed,
@@ -34696,18 +35400,43 @@ function parsePairingCode(body, res) {
34696
35400
  return code.trim().toUpperCase();
34697
35401
  }
34698
35402
  __name(parsePairingCode, "parsePairingCode");
34699
- function parsePairingSenderId(body, res) {
35403
+ function parsePairingApprovalSubject(body, res) {
34700
35404
  const senderId = body["senderId"];
34701
- if (typeof senderId !== "string" || senderId.length === 0) {
35405
+ const groupId = body["groupId"];
35406
+ if (senderId !== void 0 && groupId !== void 0) {
35407
+ res.status(400).json({
35408
+ error: "Provide exactly one of `senderId` or `groupId`.",
35409
+ code: "invalid_channel_pairing_subject"
35410
+ });
35411
+ return void 0;
35412
+ }
35413
+ if (senderId !== void 0) {
35414
+ if (typeof senderId === "string" && senderId.length > 0) {
35415
+ return { type: "user", id: senderId };
35416
+ }
34702
35417
  res.status(400).json({
34703
35418
  error: "`senderId` must be a non-empty string.",
34704
35419
  code: "invalid_channel_pairing_sender_id"
34705
35420
  });
34706
35421
  return void 0;
34707
35422
  }
34708
- return senderId;
35423
+ if (groupId !== void 0) {
35424
+ if (typeof groupId === "string" && groupId.length > 0) {
35425
+ return { type: "group", id: groupId };
35426
+ }
35427
+ res.status(400).json({
35428
+ error: "`groupId` must be a non-empty string.",
35429
+ code: "invalid_channel_pairing_group_id"
35430
+ });
35431
+ return void 0;
35432
+ }
35433
+ res.status(400).json({
35434
+ error: "Provide exactly one of `senderId` or `groupId`.",
35435
+ code: "invalid_channel_pairing_subject"
35436
+ });
35437
+ return void 0;
34709
35438
  }
34710
- __name(parsePairingSenderId, "parsePairingSenderId");
35439
+ __name(parsePairingApprovalSubject, "parsePairingApprovalSubject");
34711
35440
  function errorCode2(error2) {
34712
35441
  if (!error2 || typeof error2 !== "object") return void 0;
34713
35442
  try {
@@ -34881,11 +35610,11 @@ function registerWorkspaceChannelManagementRoutes(app, deps) {
34881
35610
  if (!resolved || !validateClient(req, res, resolved.runtime)) return;
34882
35611
  const name = parseInstanceName(req, res);
34883
35612
  if (!name) return;
34884
- const senderId = parsePairingSenderId(deps.safeBody(req), res);
34885
- if (!senderId) return;
35613
+ const subject = parsePairingApprovalSubject(deps.safeBody(req), res);
35614
+ if (!subject) return;
34886
35615
  try {
34887
35616
  noStore(res);
34888
- res.status(200).json(await resolved.service.revokePairingApproval(name, senderId));
35617
+ res.status(200).json(await resolved.service.revokePairingApproval(name, subject));
34889
35618
  } catch (error2) {
34890
35619
  sendManagementError(res, error2);
34891
35620
  }
@@ -35191,6 +35920,26 @@ __name(registerWorkspaceQualifiedToolsRoutes, "registerWorkspaceQualifiedToolsRo
35191
35920
 
35192
35921
  // packages/cli/src/serve/routes/workspace-skills.ts
35193
35922
  init_esbuild_shims();
35923
+ var MAX_WORKSPACE_SKILL_BATCH_SIZE = 100;
35924
+ function rejectSkillNameTooLong(skillName, res) {
35925
+ if (skillName.length <= MAX_WORKSPACE_SKILL_NAME_LENGTH) return false;
35926
+ res.status(400).json({
35927
+ error: `Skill name exceeds ${MAX_WORKSPACE_SKILL_NAME_LENGTH}-character limit`,
35928
+ code: "invalid_skill_name"
35929
+ });
35930
+ return true;
35931
+ }
35932
+ __name(rejectSkillNameTooLong, "rejectSkillNameTooLong");
35933
+ function parseEnabledFlag(body, res) {
35934
+ const enabled = body["enabled"];
35935
+ if (typeof enabled === "boolean") return { enabled };
35936
+ res.status(400).json({
35937
+ error: "`enabled` is required and must be a boolean",
35938
+ code: "invalid_enabled_flag"
35939
+ });
35940
+ return void 0;
35941
+ }
35942
+ __name(parseEnabledFlag, "parseEnabledFlag");
35194
35943
  function parseSkillToggleRequest(req, res, safeBody2) {
35195
35944
  const rawSkillName = req.params["name"];
35196
35945
  if (!rawSkillName || typeof rawSkillName !== "string") {
@@ -35208,24 +35957,42 @@ function parseSkillToggleRequest(req, res, safeBody2) {
35208
35957
  });
35209
35958
  return void 0;
35210
35959
  }
35211
- if (skillName.length > MAX_WORKSPACE_SKILL_NAME_LENGTH) {
35960
+ if (rejectSkillNameTooLong(skillName, res)) return void 0;
35961
+ const flag = parseEnabledFlag(safeBody2(req), res);
35962
+ return flag ? { skillName, enabled: flag.enabled } : void 0;
35963
+ }
35964
+ __name(parseSkillToggleRequest, "parseSkillToggleRequest");
35965
+ function parseSkillBatchToggleRequest(req, res, safeBody2) {
35966
+ const body = safeBody2(req);
35967
+ const rawSkillNames = body["skillNames"];
35968
+ if (!Array.isArray(rawSkillNames) || rawSkillNames.length === 0 || rawSkillNames.length > MAX_WORKSPACE_SKILL_BATCH_SIZE || !rawSkillNames.every((name) => typeof name === "string")) {
35212
35969
  res.status(400).json({
35213
- error: `Skill name exceeds ${MAX_WORKSPACE_SKILL_NAME_LENGTH}-character limit`,
35214
- code: "invalid_skill_name"
35970
+ error: `\`skillNames\` must be a non-empty string array (max ${MAX_WORKSPACE_SKILL_BATCH_SIZE})`,
35971
+ code: "invalid_skill_names"
35215
35972
  });
35216
35973
  return void 0;
35217
35974
  }
35218
- const enabled = safeBody2(req)["enabled"];
35219
- if (typeof enabled !== "boolean") {
35220
- res.status(400).json({
35221
- error: "`enabled` is required and must be a boolean",
35222
- code: "invalid_enabled_flag"
35223
- });
35224
- return void 0;
35975
+ const skillNames = [];
35976
+ const seen = /* @__PURE__ */ new Set();
35977
+ for (const rawSkillName of rawSkillNames) {
35978
+ const skillName = rawSkillName.trim();
35979
+ if (skillName.length === 0) {
35980
+ res.status(400).json({
35981
+ error: "Skill names must not be empty",
35982
+ code: "invalid_skill_name"
35983
+ });
35984
+ return void 0;
35985
+ }
35986
+ if (rejectSkillNameTooLong(skillName, res)) return void 0;
35987
+ const normalizedName = skillName.toLowerCase();
35988
+ if (seen.has(normalizedName)) continue;
35989
+ seen.add(normalizedName);
35990
+ skillNames.push(skillName);
35225
35991
  }
35226
- return { skillName, enabled };
35992
+ const flag = parseEnabledFlag(body, res);
35993
+ return flag ? { skillNames, enabled: flag.enabled } : void 0;
35227
35994
  }
35228
- __name(parseSkillToggleRequest, "parseSkillToggleRequest");
35995
+ __name(parseSkillBatchToggleRequest, "parseSkillBatchToggleRequest");
35229
35996
  function parseSkillScope(value, res) {
35230
35997
  if (value === "workspace" || value === "global") return value;
35231
35998
  res.status(400).json({
@@ -35245,13 +36012,7 @@ function parseSkillInstallRequest(req, res, safeBody2) {
35245
36012
  });
35246
36013
  return void 0;
35247
36014
  }
35248
- if (name.trim().length > MAX_WORKSPACE_SKILL_NAME_LENGTH) {
35249
- res.status(400).json({
35250
- error: `Skill name exceeds ${MAX_WORKSPACE_SKILL_NAME_LENGTH}-character limit`,
35251
- code: "invalid_skill_name"
35252
- });
35253
- return void 0;
35254
- }
36015
+ if (rejectSkillNameTooLong(name.trim(), res)) return void 0;
35255
36016
  const scope = parseSkillScope(body["scope"], res);
35256
36017
  if (!scope) return void 0;
35257
36018
  const rawSource = body["source"];
@@ -35305,6 +36066,7 @@ function registerWorkspaceSkillsRoutes(app, deps) {
35305
36066
  deps.workspaceRuntime.workspaceCwd
35306
36067
  );
35307
36068
  const route = "POST /workspace/skills/:name/enable";
36069
+ const batchRoute = "POST /workspace/skills/enable";
35308
36070
  app.post(
35309
36071
  "/workspace/skills/install",
35310
36072
  deps.mutate({ strict: true }),
@@ -35358,6 +36120,27 @@ function registerWorkspaceSkillsRoutes(app, deps) {
35358
36120
  }
35359
36121
  }
35360
36122
  );
36123
+ app.post(
36124
+ "/workspace/skills/enable",
36125
+ deps.mutate({ strict: true }),
36126
+ async (req, res) => {
36127
+ if (!requireTrustedWorkspaceRuntime(deps.workspaceRuntime, res)) return;
36128
+ const input = parseSkillBatchToggleRequest(req, res, deps.safeBody);
36129
+ if (!input) return;
36130
+ const clientId = deps.parseAndValidateClientId(req, res);
36131
+ if (clientId === null) return;
36132
+ try {
36133
+ const result = await deps.workspaceRuntime.workspaceService.setWorkspaceSkillsEnabled(
36134
+ buildWorkspaceCtx(batchRoute, clientId),
36135
+ input.skillNames,
36136
+ input.enabled
36137
+ );
36138
+ res.status(200).json(result);
36139
+ } catch (err) {
36140
+ deps.sendBridgeError(res, err, { route: batchRoute });
36141
+ }
36142
+ }
36143
+ );
35361
36144
  app.post(
35362
36145
  "/workspace/skills/:name/enable",
35363
36146
  deps.mutate({ strict: true }),
@@ -35383,6 +36166,7 @@ function registerWorkspaceSkillsRoutes(app, deps) {
35383
36166
  __name(registerWorkspaceSkillsRoutes, "registerWorkspaceSkillsRoutes");
35384
36167
  function registerWorkspaceQualifiedSkillsRoutes(app, deps) {
35385
36168
  const route = "POST /workspaces/:workspace/skills/:name/enable";
36169
+ const batchRoute = "POST /workspaces/:workspace/skills/enable";
35386
36170
  app.post(
35387
36171
  "/workspaces/:workspace/skills/install",
35388
36172
  deps.mutate({ strict: true }),
@@ -35454,6 +36238,36 @@ function registerWorkspaceQualifiedSkillsRoutes(app, deps) {
35454
36238
  }
35455
36239
  }
35456
36240
  );
36241
+ app.post(
36242
+ "/workspaces/:workspace/skills/enable",
36243
+ deps.mutate({ strict: true }),
36244
+ async (req, res) => {
36245
+ const runtime = resolveWorkspaceRuntimeFromParam(
36246
+ deps.workspaceRegistry,
36247
+ req,
36248
+ res
36249
+ );
36250
+ if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
36251
+ const input = parseSkillBatchToggleRequest(req, res, deps.safeBody);
36252
+ if (!input) return;
36253
+ const clientId = parseAndValidateWorkspaceClientId(
36254
+ req,
36255
+ res,
36256
+ runtime.bridge
36257
+ );
36258
+ if (clientId === null) return;
36259
+ try {
36260
+ const result = await runtime.workspaceService.setWorkspaceSkillsEnabled(
36261
+ createBuildWorkspaceCtx(runtime.workspaceCwd)(batchRoute, clientId),
36262
+ input.skillNames,
36263
+ input.enabled
36264
+ );
36265
+ res.status(200).json(result);
36266
+ } catch (err) {
36267
+ deps.sendBridgeError(res, err, { route: batchRoute });
36268
+ }
36269
+ }
36270
+ );
35457
36271
  app.post(
35458
36272
  "/workspaces/:workspace/skills/:name/enable",
35459
36273
  deps.mutate({ strict: true }),
@@ -35489,7 +36303,7 @@ __name(registerWorkspaceQualifiedSkillsRoutes, "registerWorkspaceQualifiedSkills
35489
36303
 
35490
36304
  // packages/cli/src/serve/routes/channel-webhooks.ts
35491
36305
  init_esbuild_shims();
35492
- var import_express3 = __toESM(require_express(), 1);
36306
+ var import_express4 = __toESM(require_express(), 1);
35493
36307
  import { createHash as createHash4, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
35494
36308
  var PROTOTYPE_POLLUTION_KEYS = /* @__PURE__ */ new Set([
35495
36309
  "__proto__",
@@ -35538,7 +36352,7 @@ function registerChannelWebhookRoutes(app, deps) {
35538
36352
  locals.channelWebhook = { channelName, source, sourceConfig };
35539
36353
  next();
35540
36354
  },
35541
- import_express3.default.json({ limit: "1mb" }),
36355
+ import_express4.default.json({ limit: "1mb" }),
35542
36356
  async (req, res) => {
35543
36357
  const locals = res.locals;
35544
36358
  const webhook = locals.channelWebhook;
@@ -39037,10 +39851,10 @@ __name(registerLiveSetupRoutes, "registerLiveSetupRoutes");
39037
39851
  init_esbuild_shims();
39038
39852
  import { execFile as execFile3 } from "node:child_process";
39039
39853
  import { createHash as createHash5, randomUUID as randomUUID11 } from "node:crypto";
39040
- import * as fs6 from "node:fs";
39854
+ import * as fs7 from "node:fs";
39041
39855
  import * as fsp5 from "node:fs/promises";
39042
- import * as os from "node:os";
39043
- import * as path13 from "node:path";
39856
+ import * as os2 from "node:os";
39857
+ import * as path14 from "node:path";
39044
39858
  import { Readable, Transform } from "node:stream";
39045
39859
  import { pipeline } from "node:stream/promises";
39046
39860
  import { promisify as promisify3 } from "node:util";
@@ -39118,7 +39932,7 @@ async function readBundleValue(appPath, key) {
39118
39932
  "raw",
39119
39933
  "-o",
39120
39934
  "-",
39121
- path13.join(appPath, "Contents", "Info.plist")
39935
+ path14.join(appPath, "Contents", "Info.plist")
39122
39936
  ]);
39123
39937
  }
39124
39938
  __name(readBundleValue, "readBundleValue");
@@ -39213,7 +40027,7 @@ async function downloadAsset(asset, destination, onProgress) {
39213
40027
  await pipeline(
39214
40028
  Readable.fromWeb(response.body),
39215
40029
  guard,
39216
- fs6.createWriteStream(destination, { flags: "wx", mode: 384 })
40030
+ fs7.createWriteStream(destination, { flags: "wx", mode: 384 })
39217
40031
  );
39218
40032
  if (received !== asset.size || hash.digest("hex") !== asset.sha256) {
39219
40033
  throw new Error("Live Host checksum verification failed.");
@@ -39224,11 +40038,11 @@ async function installLatestHost(currentArchitecture, onStatus) {
39224
40038
  const manifest = await fetchManifest();
39225
40039
  const asset = manifest.assets[currentArchitecture];
39226
40040
  const temporaryDirectory = await fsp5.mkdtemp(
39227
- path13.join(os.tmpdir(), "qwen-live-host-")
40041
+ path14.join(os2.tmpdir(), "qwen-live-host-")
39228
40042
  );
39229
- const archivePath = path13.join(temporaryDirectory, asset.name);
39230
- const extractedPath = path13.join(temporaryDirectory, "extracted");
39231
- const candidatePath = path13.join(extractedPath, LIVE_HOST_APP_NAME);
40043
+ const archivePath = path14.join(temporaryDirectory, asset.name);
40044
+ const extractedPath = path14.join(temporaryDirectory, "extracted");
40045
+ const candidatePath = path14.join(extractedPath, LIVE_HOST_APP_NAME);
39232
40046
  const stagingPath = `/Applications/.Qwen Live Host.install-${randomUUID11()}.app`;
39233
40047
  const backupPath = `/Applications/.Qwen Live Host.backup-${randomUUID11()}.app`;
39234
40048
  let movedExisting = false;
@@ -39376,13 +40190,13 @@ var LiveHostInstaller = class {
39376
40190
  init_esbuild_shims();
39377
40191
  import { createHash as createHash6, randomUUID as randomUUID12 } from "node:crypto";
39378
40192
  import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync2 } from "node:fs";
39379
- import { join as join10 } from "node:path";
40193
+ import { join as join11 } from "node:path";
39380
40194
 
39381
40195
  // packages/cli/src/serve/live/realtime-startup-context.ts
39382
40196
  init_esbuild_shims();
39383
40197
  import { readdirSync } from "node:fs";
39384
40198
  import { homedir } from "node:os";
39385
- import { basename as basename5, join as join9 } from "node:path";
40199
+ import { basename as basename5, join as join10 } from "node:path";
39386
40200
  var STARTUP_CONTEXT_HEADER = "Startup context from Qwen Code.\nThis is background context about recent work and machine/workspace layout. It may be incomplete or stale. Use it to inform responses, and do not repeat it back unless relevant.";
39387
40201
  var CURRENT_THREAD_SECTION_TOKEN_BUDGET = 1200;
39388
40202
  var RECENT_WORK_SECTION_TOKEN_BUDGET = 2200;
@@ -39624,7 +40438,7 @@ function collectTreeLines(directory, depth, lines) {
39624
40438
  const indent = " ".repeat(depth);
39625
40439
  lines.push(`${indent}- ${entry.name}${entry.isDirectory() ? "/" : ""}`);
39626
40440
  if (entry.isDirectory()) {
39627
- collectTreeLines(join9(directory, entry.name), depth + 1, lines);
40441
+ collectTreeLines(join10(directory, entry.name), depth + 1, lines);
39628
40442
  }
39629
40443
  }
39630
40444
  if (entries.length > DIR_ENTRY_LIMIT) {
@@ -39743,13 +40557,13 @@ function openLiveAudioCapture(source, identifier) {
39743
40557
  try {
39744
40558
  mkdirSync2(directory, { recursive: true, mode: 448 });
39745
40559
  const safeIdentifier = identifier.replace(/[^A-Za-z0-9_-]/g, "_");
39746
- const path14 = join10(
40560
+ const path15 = join11(
39747
40561
  directory,
39748
40562
  `${source}-${Date.now()}-${safeIdentifier}.pcm`
39749
40563
  );
39750
- const stream = createWriteStream2(path14, { flags: "wx", mode: 384 });
40564
+ const stream = createWriteStream2(path15, { flags: "wx", mode: 384 });
39751
40565
  stream.on("error", () => void 0);
39752
- return { source, path: path14, stream, hash: createHash6("sha256"), bytes: 0 };
40566
+ return { source, path: path15, stream, hash: createHash6("sha256"), bytes: 0 };
39753
40567
  } catch {
39754
40568
  return void 0;
39755
40569
  }
@@ -42069,6 +42883,7 @@ function getRuntimeEffectiveEnv(metadata) {
42069
42883
  }
42070
42884
  __name(getRuntimeEffectiveEnv, "getRuntimeEffectiveEnv");
42071
42885
  var DEFAULT_SESSION_IDLE_TIMEOUT_MS = 30 * 6e4;
42886
+ var SCHEDULED_TASK_RESTORE_HEADROOM_MS = 1e4;
42072
42887
  var KEEPALIVE_MIN_INTERVAL_MS = 3e4;
42073
42888
  var KEEPALIVE_MAX_INTERVAL_MS = 10 * 6e4;
42074
42889
  function computeKeepaliveIntervalMs(idleTimeoutMs) {
@@ -42110,12 +42925,19 @@ function createLiveWorkspaceDelegate(getTarget) {
42110
42925
  }
42111
42926
  __name(createLiveWorkspaceDelegate, "createLiveWorkspaceDelegate");
42112
42927
  function createServeApp(opts, getPort = () => opts.port, deps = {}) {
42928
+ const sessionRestoreTimeoutMs = resolveSessionRestoreTimeoutMs(opts);
42929
+ const scheduledTaskRestoreTimeoutMs = sessionRestoreTimeoutMs + SCHEDULED_TASK_RESTORE_HEADROOM_MS > MAX_SESSION_RESTORE_TIMEOUT_MS ? MAX_SESSION_RESTORE_TIMEOUT_MS + 1 : sessionRestoreTimeoutMs + SCHEDULED_TASK_RESTORE_HEADROOM_MS;
42113
42930
  if (deps.workspaceRuntimeRemoval && !deps.voiceCoordinator) {
42114
42931
  throw new Error(
42115
42932
  "createServeApp: deps.workspaceRuntimeRemoval requires the matching deps.voiceCoordinator."
42116
42933
  );
42117
42934
  }
42118
- const app = (0, import_express4.default)();
42935
+ if ((deps.workspaceTrustHotReloadAvailable === true || deps.workspaceRuntimeRemoval !== void 0) && deps.getSessionBridges === void 0) {
42936
+ throw new Error(
42937
+ "createServeApp: runtime replacement/removal requires deps.getSessionBridges so session-id admission can inspect draining generations."
42938
+ );
42939
+ }
42940
+ const app = (0, import_express5.default)();
42119
42941
  const injectedWorkspaceRegistry = deps.workspaceRegistry;
42120
42942
  const boundWorkspace = injectedWorkspaceRegistry?.primary.workspaceCwd ?? deps.boundWorkspace ?? canonicalizeWorkspace(opts.workspace ?? process.cwd());
42121
42943
  if (injectedWorkspaceRegistry) {
@@ -42286,14 +43108,16 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
42286
43108
  maxJournalEvents: opts.maxJournalEvents,
42287
43109
  maxJournalBytes: opts.maxJournalBytes,
42288
43110
  initializeTimeoutMs: opts.initializeTimeoutMs,
43111
+ sessionRestoreTimeoutMs,
42289
43112
  permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs,
42290
43113
  boundWorkspace,
42291
43114
  sessionShellCommandEnabled,
42292
43115
  // Wire the production status provider so direct embeds / tests
42293
43116
  // that don't inject `deps.bridge` get daemon env + preflight cells.
42294
43117
  statusProvider,
42295
- // Wire the WorkspaceFileSystem adapter so ACP writeTextFile /
42296
- // readTextFile pick up trust / TOCTOU / audit.
43118
+ delegateReadTextFileToClient: false,
43119
+ // Final ACP text writes remain delegated through WorkspaceFileSystem.
43120
+ // Unexpected delegated reads still fail closed at the WFS boundary.
42297
43121
  fileSystem: createBridgeFileSystemAdapter(fsFactory),
42298
43122
  // Reverse tool channel: answer the child's `client_mcp/message`
42299
43123
  // ext-method by reaching the WS connection that hosts the named server.
@@ -42360,6 +43184,11 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
42360
43184
  "setWorkspaceSkillEnabled requires persistDisabledSkills in ServeAppDeps"
42361
43185
  );
42362
43186
  }),
43187
+ persistDisabledSkillsBatch: deps.persistDisabledSkillsBatch ?? (async () => {
43188
+ throw new Error(
43189
+ "setWorkspaceSkillsEnabled requires persistDisabledSkillsBatch in ServeAppDeps"
43190
+ );
43191
+ }),
42363
43192
  queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => bridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
42364
43193
  invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => bridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
42365
43194
  preheatAcpChild: /* @__PURE__ */ __name(() => bridge.preheat(), "preheatAcpChild"),
@@ -42395,6 +43224,15 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
42395
43224
  } : {}
42396
43225
  );
42397
43226
  app.locals.workspaceRegistry = workspaceRegistry;
43227
+ const requestedSessionIdAdmission = createRequestedSessionIdAdmission({
43228
+ archiveCoordinator,
43229
+ getBridges: deps.getSessionBridges ?? (() => workspaceRegistry.listManaged().map((runtime) => runtime.bridge)),
43230
+ getPersistenceTargets: /* @__PURE__ */ __name(() => workspaceRegistry.listManaged().map((runtime) => ({
43231
+ workspaceCwd: runtime.workspaceCwd,
43232
+ runtimeBaseDir: runtime.sessionRuntimeBaseDir
43233
+ })), "getPersistenceTargets"),
43234
+ getBridgeWorkspaceId: /* @__PURE__ */ __name((bridge2) => workspaceRegistry.listEntries().find((entry) => entry.current?.runtime.bridge === bridge2)?.workspaceId, "getBridgeWorkspaceId")
43235
+ });
42398
43236
  primaryTrustRegistry = workspaceRegistry;
42399
43237
  const primaryRuntime = createLiveWorkspaceDelegate(
42400
43238
  () => workspaceRegistry.primary
@@ -42830,7 +43668,8 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
42830
43668
  getChannelWorkerSnapshots: deps.getChannelWorkerSnapshots,
42831
43669
  getPerfSnapshot: deps.getPerfSnapshot,
42832
43670
  getMetricsSeries: deps.getMetricsSeries,
42833
- getTotalSessionAdmissionSnapshot: deps.getTotalSessionAdmissionSnapshot ?? totalSessionAdmission?.snapshot
43671
+ getTotalSessionAdmissionSnapshot: deps.getTotalSessionAdmissionSnapshot ?? totalSessionAdmission?.snapshot,
43672
+ getChildHeapPolicySnapshot: deps.getChildHeapPolicySnapshot
42834
43673
  });
42835
43674
  if (liveVoiceEnabled) {
42836
43675
  app.use("/capabilities", (_req, _res, next) => {
@@ -42847,6 +43686,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
42847
43686
  maxSessionsPerWorkspace: opts.maxSessions,
42848
43687
  maxTotalSessions: opts.maxTotalSessions,
42849
43688
  maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession,
43689
+ sessionRestoreTimeoutMs,
42850
43690
  languageCodes
42851
43691
  });
42852
43692
  if (liveVoiceSurfaceAvailable) {
@@ -43258,6 +44098,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
43258
44098
  bridge: primaryBridge,
43259
44099
  workspaceRegistry,
43260
44100
  archiveCoordinator,
44101
+ requestedSessionIdAdmission,
43261
44102
  mutate,
43262
44103
  sendBridgeError: sendBridgeError2,
43263
44104
  daemonLog,
@@ -43424,6 +44265,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
43424
44265
  () => rehydrateScheduledTaskSessions({
43425
44266
  bridge: runtime.bridge,
43426
44267
  boundWorkspace: runtime.workspaceCwd,
44268
+ loadTimeoutMs: scheduledTaskRestoreTimeoutMs,
43427
44269
  onTasksRead: /* @__PURE__ */ __name((tasks) => registerScheduledTaskAuthorizations(runtime.workspaceCwd, tasks), "onTasksRead"),
43428
44270
  onError: /* @__PURE__ */ __name((sessionId, err) => {
43429
44271
  process.stderr.write(
@@ -43454,6 +44296,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
43454
44296
  bridge: runtime.bridge,
43455
44297
  boundWorkspace: runtime.workspaceCwd,
43456
44298
  intervalMs: keepaliveIntervalMs,
44299
+ reviveTimeoutMs: scheduledTaskRestoreTimeoutMs,
43457
44300
  runtimeBaseDir: runtime.sessionRuntimeBaseDir,
43458
44301
  cleanupSession: /* @__PURE__ */ __name((sessionId) => cleanupSession(runtime, sessionId), "cleanupSession"),
43459
44302
  onTasksRead: /* @__PURE__ */ __name((tasks) => registerScheduledTaskAuthorizations(runtime.workspaceCwd, tasks), "onTasksRead")
@@ -43498,6 +44341,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
43498
44341
  workspaceRegistry,
43499
44342
  isPrimaryWorkspaceTrusted,
43500
44343
  archiveCoordinator,
44344
+ requestedSessionIdAdmission,
43501
44345
  workspace: primaryWorkspace,
43502
44346
  fsFactory: primaryRouteFileSystemFactory,
43503
44347
  deviceFlowRegistry,