@qwen-code/qwen-code 0.20.0 → 0.20.1-nightly.20260724.7d17c44a3

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 (388) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +1 -1
  2. package/bundled/qc-helper/docs/features/auto-mode.md +19 -16
  3. package/bundled/qc-helper/docs/features/commands.md +54 -0
  4. package/bundled/qc-helper/docs/features/sub-agents.md +16 -7
  5. package/bundled/qc-helper/docs/integration-github-action.md +1 -1
  6. package/bundled/qc-helper/docs/qwen-serve.md +2 -1
  7. package/bundled/review/DESIGN.md +2 -2
  8. package/bundled/review/SKILL.md +7 -5
  9. package/chunks/MaxSizedBox-LGRTXB47.js +84 -0
  10. package/chunks/{StandaloneSessionPicker-CEGO2AZX.js → StandaloneSessionPicker-H3TBU3C3.js} +68 -56
  11. package/chunks/{acp-startup-profiler-N3RHHXJ3.js → acp-startup-profiler-RV3IV562.js} +2 -2
  12. package/chunks/{acpAgent-YUR43TLG.js → acpAgent-5D7P4BB5.js} +2061 -556
  13. package/chunks/agent-W7UAHCCI.js +80 -0
  14. package/chunks/agent-headless-KTBMPRSC.js +74 -0
  15. package/chunks/{anthropicContentGenerator-HVKLXOOU.js → anthropicContentGenerator-ZLQ3X2HI.js} +112 -45
  16. package/chunks/{artifact-tool-WBCAMD3O.js → artifact-tool-OKMWONT6.js} +3 -3
  17. package/chunks/{askUserQuestion-6DZC4UV5.js → askUserQuestion-V6FUS23G.js} +3 -3
  18. package/chunks/bridge-FFC4C6VD.js +89 -0
  19. package/chunks/{build-SSCNEHZZ.js → build-RV63TIRH.js} +2 -3
  20. package/chunks/{ca-2SL2BXTK.js → ca-GKRQZ7AM.js} +612 -201
  21. package/chunks/{channel-worker-group-53CMOPFT.js → channel-worker-group-MA3WXWYX.js} +7 -6
  22. package/chunks/{channel-worker-manager-UTXILKC2.js → channel-worker-manager-TIYYYBCT.js} +189 -29
  23. package/chunks/{channel-worker-supervisor-ZGO2W2MD.js → channel-worker-supervisor-CXRCDA4Y.js} +6 -5
  24. package/chunks/{chunk-TYQMGACW.js → chunk-22C7BQ6D.js} +508 -10967
  25. package/chunks/{chunk-4EP2PYYL.js → chunk-2G6QIHYL.js} +5 -5
  26. package/chunks/{chunk-H2XVO6NE.js → chunk-2MIN6GRR.js} +1 -1
  27. package/chunks/chunk-2RFKHEXL.js +74 -0
  28. package/chunks/{chunk-7SXZC7ID.js → chunk-2WTVWAKT.js} +7 -6
  29. package/chunks/{chunk-TIH2ZTOC.js → chunk-32A4PI3E.js} +2 -2
  30. package/chunks/chunk-36HSVBBU.js +469 -0
  31. package/chunks/{chunk-IR46U7RB.js → chunk-3FB2Y2OE.js} +3 -3
  32. package/chunks/{chunk-QR6U5QPP.js → chunk-3SJ43L4W.js} +4 -0
  33. package/chunks/chunk-3Z43GZUQ.js +32 -0
  34. package/chunks/chunk-43T5WDQ7.js +127 -0
  35. package/chunks/chunk-46UV252V.js +128 -0
  36. package/chunks/{chunk-JD3MKVKL.js → chunk-4K56OJFJ.js} +1 -1
  37. package/chunks/{chunk-KTUQMDEP.js → chunk-4K7VDKAD.js} +1 -1
  38. package/chunks/{chunk-QKYTTBYW.js → chunk-4LVZNIDO.js} +1 -1
  39. package/chunks/{chunk-OWCALFEG.js → chunk-54R2CV2G.js} +1 -1
  40. package/chunks/{chunk-ZEOZL37W.js → chunk-57FIIFJN.js} +1 -1
  41. package/chunks/chunk-5BS3KLRP.js +6194 -0
  42. package/chunks/{chunk-NEEB7UEN.js → chunk-6GMVPFB2.js} +153 -72
  43. package/chunks/{chunk-GMGDLUC7.js → chunk-6IL7KRLE.js} +1 -1
  44. package/chunks/chunk-6PVPNMXU.js +29 -0
  45. package/chunks/chunk-6QHAUJUE.js +293 -0
  46. package/chunks/chunk-6VK3IRTX.js +10017 -0
  47. package/chunks/{chunk-BDBMYST4.js → chunk-6X4GWOPW.js} +1 -1
  48. package/chunks/{chunk-AYCDXHZB.js → chunk-7Z6JQEL6.js} +1 -1
  49. package/chunks/{chunk-FSL5W5TI.js → chunk-AFFGGOF6.js} +4 -4
  50. package/chunks/chunk-AMDSOFFV.js +10860 -0
  51. package/chunks/chunk-AXUW635Q.js +934 -0
  52. package/chunks/{chunk-A5LYNIW7.js → chunk-BJBUDCM3.js} +8 -8
  53. package/chunks/chunk-BK2UNYWD.js +29 -0
  54. package/chunks/{chunk-6RLROE6G.js → chunk-BLFVGB7D.js} +30 -4
  55. package/chunks/chunk-BPJSQIJX.js +100 -0
  56. package/chunks/{chunk-FLSVD6BS.js → chunk-BRTR7S7O.js} +3 -3
  57. package/chunks/{chunk-KG3XV6FH.js → chunk-BSNWBC33.js} +32 -2
  58. package/chunks/chunk-BULDBTYC.js +153 -0
  59. package/chunks/{chunk-PBWEWI4N.js → chunk-BW5Z5NOG.js} +83 -74
  60. package/chunks/{chunk-EIAK6Q2B.js → chunk-C3VHAXP2.js} +20 -3
  61. package/chunks/{chunk-6AFUCL3D.js → chunk-CEZB3XFD.js} +1 -1
  62. package/chunks/chunk-CHMENNJV.js +1832 -0
  63. package/chunks/{chunk-TMQ6XQCX.js → chunk-CK3IEEHR.js} +416 -291
  64. package/chunks/{chunk-OYZWQNWG.js → chunk-CK6UABV2.js} +2 -2
  65. package/chunks/{chunk-VZQUV7VK.js → chunk-CKTMY3EP.js} +1 -1
  66. package/chunks/{chunk-VDWBQ5AW.js → chunk-CUPAVLRY.js} +5 -2
  67. package/chunks/{chunk-I2PYAYFM.js → chunk-CXUFILV3.js} +3 -3
  68. package/chunks/chunk-DP3IHZGG.js +1498 -0
  69. package/chunks/{chunk-BMWMT5Y2.js → chunk-DP5GT2MW.js} +7 -375
  70. package/chunks/{chunk-D22SX43D.js → chunk-DWNZ6PVQ.js} +1 -1
  71. package/chunks/{chunk-5SCI6E3E.js → chunk-E4IMU4Y5.js} +1 -1
  72. package/chunks/{chunk-DP5GXXNZ.js → chunk-EL2IQ2S5.js} +5 -1
  73. package/chunks/{chunk-EZVDJFZ7.js → chunk-ERLGR7GI.js} +1 -1
  74. package/chunks/{chunk-IVPSS6EL.js → chunk-F5MBYZSU.js} +4 -4
  75. package/chunks/{chunk-AQIEINAY.js → chunk-F6IYL66A.js} +28 -1766
  76. package/chunks/{chunk-FEOZBUMT.js → chunk-FODK6UMO.js} +0 -27
  77. package/chunks/{chunk-PGEPSDJI.js → chunk-FWNZ7CVN.js} +24 -20
  78. package/chunks/{chunk-5JBR5XIK.js → chunk-G7EFBBVF.js} +220 -141
  79. package/chunks/chunk-GLNBDYUX.js +38 -0
  80. package/chunks/{chunk-ANPINBOF.js → chunk-H4YKEV2X.js} +5 -5
  81. package/chunks/{chunk-TDKQP3M6.js → chunk-HIJQF5B5.js} +1 -1
  82. package/chunks/{chunk-FQD7GFSV.js → chunk-HJJDKFL5.js} +3 -3
  83. package/chunks/{chunk-4N3KMAIL.js → chunk-HPWHDJID.js} +152 -35
  84. package/chunks/{chunk-KQNM4EO7.js → chunk-HQCSRJ3P.js} +138 -6
  85. package/chunks/chunk-HTR4WV6U.js +327 -0
  86. package/chunks/{chunk-YWEW33JY.js → chunk-HVO55LUD.js} +7 -7
  87. package/chunks/{chunk-MJ6S23WZ.js → chunk-HZEWYOVI.js} +5 -5
  88. package/chunks/chunk-IFG6TYJ2.js +16577 -0
  89. package/chunks/{chunk-B3KGZCQN.js → chunk-IJTOWOD7.js} +322 -202
  90. package/chunks/{chunk-RS7MT2QG.js → chunk-IPUUTYMV.js} +2 -4
  91. package/chunks/{chunk-4ILMYHEI.js → chunk-IRDZJSCL.js} +3 -3
  92. package/chunks/{chunk-XU457J4V.js → chunk-IRH27ZC2.js} +2 -2
  93. package/chunks/{chunk-33XUAINQ.js → chunk-J5UKQEFG.js} +69 -9
  94. package/chunks/{chunk-G45X5TRN.js → chunk-JCW2R7WC.js} +1 -72
  95. package/chunks/{chunk-S2XVRHDN.js → chunk-JDFBBGRD.js} +1 -1
  96. package/chunks/{chunk-4XNLIGVA.js → chunk-JKCALGYN.js} +1023 -383
  97. package/chunks/{chunk-TJTKSVIV.js → chunk-JLU636DO.js} +5 -1
  98. package/chunks/{chunk-VEXFOTEO.js → chunk-JYUSL2V4.js} +3 -3
  99. package/chunks/{chunk-S2PD3EZD.js → chunk-KJEMJWNH.js} +1 -1
  100. package/chunks/{chunk-E2UVIFI2.js → chunk-KRXPRVGL.js} +0 -1
  101. package/chunks/{chunk-CZF3E5GF.js → chunk-LA5H3LM5.js} +1 -1
  102. package/chunks/{chunk-NDMQLV4Y.js → chunk-LBAO2XRA.js} +4 -4
  103. package/chunks/{chunk-7RMOXZTC.js → chunk-LDPP5VTZ.js} +4 -4
  104. package/chunks/{chunk-KDC6GNQR.js → chunk-LEEWLFHW.js} +4 -4
  105. package/chunks/{chunk-KX6UK4VJ.js → chunk-LI4I37W4.js} +22152 -18007
  106. package/chunks/{chunk-OOCI5VVU.js → chunk-LIZRAKPB.js} +1 -1
  107. package/chunks/{chunk-AJSJ5TTU.js → chunk-LP2E4MQG.js} +1 -1
  108. package/chunks/chunk-LS77BEZP.js +405 -0
  109. package/chunks/{chunk-BRRF37CO.js → chunk-LYTBLSSW.js} +5 -5
  110. package/chunks/{chunk-DBE4QFZS.js → chunk-MB7ENXPR.js} +39 -37
  111. package/chunks/{chunk-GKY2OJ7R.js → chunk-MOHAWVLH.js} +4 -4
  112. package/chunks/chunk-NABLFI57.js +82 -0
  113. package/chunks/chunk-NBQDBANR.js +411 -0
  114. package/chunks/{chunk-EAUYY7SS.js → chunk-NOAAFNTJ.js} +43 -10
  115. package/chunks/chunk-NXS53EA7.js +1462 -0
  116. package/chunks/{chunk-C27BYUX6.js → chunk-OQB4EXO4.js} +14 -11
  117. package/chunks/{chunk-NHDKSOEY.js → chunk-P3QQPMQA.js} +5 -5
  118. package/chunks/{chunk-OP4MOGXF.js → chunk-P5RRUHL7.js} +23 -1
  119. package/chunks/{chunk-KOR3XKCA.js → chunk-PBII2NFX.js} +12 -6
  120. package/chunks/{chunk-O3OCNYY5.js → chunk-PDYB7HG2.js} +2 -2
  121. package/chunks/{chunk-2HOVDT7W.js → chunk-PFSUKTZH.js} +1 -1
  122. package/chunks/chunk-PKL3HGNZ.js +2299 -0
  123. package/chunks/{chunk-5DTTYNB7.js → chunk-PQNHRFJC.js} +16 -3
  124. package/chunks/{chunk-OLMETXLX.js → chunk-PXHK5ONM.js} +41 -9
  125. package/chunks/{chunk-PF4CHQOJ.js → chunk-Q6GU6TKM.js} +11 -10
  126. package/chunks/{chunk-4ODB7WIB.js → chunk-QAFKR7WR.js} +1 -1
  127. package/chunks/{chunk-PBATSWUQ.js → chunk-QBUDF33N.js} +1 -1
  128. package/chunks/{chunk-BVLROR2T.js → chunk-QLJUC7TG.js} +1 -1
  129. package/chunks/{chunk-UEY4AYUL.js → chunk-QNLNLENL.js} +2 -2
  130. package/chunks/{chunk-333CXMNJ.js → chunk-QXZTZJLX.js} +5 -5
  131. package/chunks/chunk-R6D2CTQR.js +289 -0
  132. package/chunks/{chunk-7PZ2ATFZ.js → chunk-R6SKHK3T.js} +54 -29
  133. package/chunks/{chunk-OONJNQ42.js → chunk-RGG6M2WF.js} +4 -4
  134. package/chunks/{chunk-RFIAR4YL.js → chunk-RV4C2ZFG.js} +1 -1
  135. package/chunks/{chunk-O3Z73NBP.js → chunk-RW2NEXYJ.js} +15 -11
  136. package/chunks/{chunk-HZPN55E5.js → chunk-SJEDL7DI.js} +1 -1
  137. package/chunks/{chunk-AKX4WPPP.js → chunk-SWBJRDYC.js} +866 -183
  138. package/chunks/{chunk-NBMIC7DR.js → chunk-SX4PK3FC.js} +145 -5
  139. package/chunks/chunk-T3452DP5.js +246 -0
  140. package/chunks/{chunk-TB6UDU4T.js → chunk-THJNPLI4.js} +16 -16
  141. package/chunks/{chunk-T4TZQJ7W.js → chunk-TWPJO254.js} +5 -16
  142. package/chunks/chunk-U7ZFW55U.js +2098 -0
  143. package/chunks/{chunk-JNWZQ27S.js → chunk-UCOJC6EB.js} +72 -23
  144. package/chunks/{chunk-W7H223ZZ.js → chunk-UGYMA4EI.js} +1 -1
  145. package/chunks/{chunk-X6YQWCIJ.js → chunk-UH3WSE5L.js} +13 -1
  146. package/chunks/{chunk-2LL7TXB4.js → chunk-UH7242DI.js} +3 -3
  147. package/chunks/{chunk-CB2HFGRV.js → chunk-UJV643E2.js} +31 -6
  148. package/chunks/chunk-UO7DCGEV.js +121 -0
  149. package/chunks/{chunk-Y2ENGUD6.js → chunk-UPF7PTBI.js} +79 -2
  150. package/chunks/chunk-UW5EOVUN.js +249 -0
  151. package/chunks/{chunk-SJMV7ZBK.js → chunk-VLVO52KC.js} +8 -8
  152. package/chunks/{chunk-R3VWUU2E.js → chunk-VYPFXUCB.js} +1 -1
  153. package/chunks/{chunk-S2W2LVDU.js → chunk-WHFK6G6U.js} +8 -9
  154. package/chunks/chunk-WI3KCKZ5.js +391 -0
  155. package/chunks/{chunk-NGFEPAE6.js → chunk-WLEFWSSC.js} +8 -6
  156. package/chunks/{chunk-XVVH63JG.js → chunk-WUJXJ34P.js} +3 -3
  157. package/chunks/{chunk-MAQQGNQ5.js → chunk-WYLPWQHJ.js} +56 -717
  158. package/chunks/{chunk-D2VIDMVM.js → chunk-X6N25LXS.js} +2 -2
  159. package/chunks/chunk-XAWJ2526.js +1049 -0
  160. package/chunks/{chunk-CV63PP6U.js → chunk-YCIM6O3I.js} +1 -1
  161. package/chunks/{chunk-OEO2ERWK.js → chunk-Z44CVEUF.js} +54 -33
  162. package/chunks/{chunk-TKLLK6XQ.js → chunk-ZT4POVWC.js} +11 -11
  163. package/chunks/{chunk-NIJEXGV6.js → chunk-ZXYUQXY5.js} +148 -10
  164. package/chunks/{computer-use-NIWQNUZF.js → computer-use-UJ5T34TE.js} +50 -37
  165. package/chunks/{config-utils-AHQ6YZ66.js → config-utils-XQRXHAN3.js} +3 -3
  166. package/chunks/contextCommand-CSCB4E5M.js +79 -0
  167. package/chunks/{create-sub-session-MGNX52P3.js → create-sub-session-55F3GOLK.js} +46 -33
  168. package/chunks/{create-sub-session-P26FE5GG.js → create-sub-session-JPCSYZAJ.js} +3 -3
  169. package/chunks/{cron-create-JWFHBDRQ.js → cron-create-CUMELMPL.js} +6 -6
  170. package/chunks/{cron-delete-GDX4E26G.js → cron-delete-QZFV6U3P.js} +5 -5
  171. package/chunks/{cron-list-USMAIWPT.js → cron-list-IDKO7ZO2.js} +5 -5
  172. package/chunks/{daemon-RG2MAI6T.js → daemon-7LP7R6IU.js} +500 -133
  173. package/chunks/daemon-status-provider-6YNZ3UAE.js +88 -0
  174. package/chunks/{de-I7ZIYXZC.js → de-4IBXM7CN.js} +5 -1
  175. package/chunks/{dist-WGTQO7F2.js → dist-376652EZ.js} +114 -28
  176. package/chunks/{dist-53PZYC5B.js → dist-3YCTE6HD.js} +2 -2
  177. package/chunks/{dist-2BHAYBKP.js → dist-D7Z3HOO7.js} +14 -2
  178. package/chunks/{dist-FUTEXY6A.js → dist-MEGJFGAI.js} +40 -9
  179. package/chunks/{dist-2MIU4UUH.js → dist-NQ436QEX.js} +1 -1
  180. package/chunks/{dist-AU7NQQRP.js → dist-NQNTOIEN.js} +26 -2
  181. package/chunks/earlyInputCapture-HPUVJ2KH.js +81 -0
  182. package/chunks/{edit-3QV3JZJL.js → edit-7CMAN3F4.js} +50 -39
  183. package/chunks/{en-XE34GKAA.js → en-SALLIJS7.js} +6 -1
  184. package/chunks/{enter-worktree-4GMMF7EG.js → enter-worktree-3PH4YTY2.js} +49 -36
  185. package/chunks/{enterPlanMode-L5UWBAUC.js → enterPlanMode-MSXLSWLI.js} +55 -37
  186. package/chunks/{environment-3OV7UQOT.js → environment-KS36ZHBE.js} +48 -35
  187. package/chunks/errors-LCPFS62A.js +87 -0
  188. package/chunks/{exit-worktree-DDP57JLV.js → exit-worktree-ARA4C3CK.js} +49 -36
  189. package/chunks/{exitPlanMode-CJBLGPIP.js → exitPlanMode-GCDIQPB7.js} +49 -36
  190. package/chunks/{fast-path-M6RP2ING.js → fast-path-IDHBVIT6.js} +3 -2
  191. package/chunks/{fr-X7KDVZIY.js → fr-WVHEBDDB.js} +5 -1
  192. package/chunks/{gemini-H4PHBJTL.js → gemini-2AFQJMX5.js} +141 -105
  193. package/chunks/{geminiContentGenerator-VURJYPWP.js → geminiContentGenerator-UDIH3YI6.js} +9 -8
  194. package/chunks/{getMachineId-bsd-EXV7SWPA.js → getMachineId-bsd-QFVLPUPT.js} +1 -1
  195. package/chunks/{getMachineId-darwin-IUOMFXU3.js → getMachineId-darwin-DGMQQE2E.js} +1 -1
  196. package/chunks/{getMachineId-linux-K7XJYFHL.js → getMachineId-linux-R4Z6CSWC.js} +1 -1
  197. package/chunks/{getMachineId-unsupported-EA5FDRJ6.js → getMachineId-unsupported-Z3SBVBUV.js} +1 -1
  198. package/chunks/{getMachineId-win-KBA6RAI5.js → getMachineId-win-SCK5UFDT.js} +1 -1
  199. package/chunks/{glob-2KUSRAVQ.js → glob-HCL7HZ67.js} +49 -36
  200. package/chunks/{grep-B5RXVESV.js → grep-CJLBSCTV.js} +49 -36
  201. package/chunks/handleAutoUpdate-Q572P3FL.js +80 -0
  202. package/chunks/i18n-OBB4R7SR.js +96 -0
  203. package/chunks/initializer-LXEY6V3C.js +85 -0
  204. package/chunks/installationInfo-XUAOVMEE.js +79 -0
  205. package/chunks/{ja-2ICT3KXF.js → ja-KY4ROZTE.js} +5 -1
  206. package/chunks/{keychain-token-storage-DWRJMNH3.js → keychain-token-storage-6ACJDYIB.js} +3 -3
  207. package/chunks/{kittyProtocolDetector-HCNNKJTI.js → kittyProtocolDetector-MBRTDRBK.js} +5 -3
  208. package/chunks/list-WAXY7QOU.js +88 -0
  209. package/chunks/list-agents-AH3P5NB7.js +80 -0
  210. package/chunks/loadedSettingsAdapter-OZFNBRHE.js +82 -0
  211. package/chunks/loggingContentGenerator-7WDTTE6G.js +1068 -0
  212. package/chunks/{loop-wakeup-5GLTUBHA.js → loop-wakeup-IHRW6TNB.js} +7 -7
  213. package/chunks/{ls-FHBY3Y7I.js → ls-ZAXZ2G2W.js} +5 -5
  214. package/chunks/{lsp-B6VMEW6Y.js → lsp-R4ZG3UGQ.js} +3 -3
  215. package/chunks/managed-npm-update-N42DO5QW.js +339 -0
  216. package/chunks/mcp-6SOORKTY.js +82 -0
  217. package/chunks/{monitor-GLJZDNPS.js → monitor-4PSVNVU4.js} +51 -37
  218. package/chunks/node-UUDY34IG.js +305 -0
  219. package/chunks/nonInteractiveCli-FBR5S7IZ.js +140 -0
  220. package/chunks/{notebook-edit-AVCIWS4F.js → notebook-edit-QK26632S.js} +50 -39
  221. package/chunks/{openaiContentGenerator-B7W24G3D.js → openaiContentGenerator-IXJS6C2U.js} +33 -20
  222. package/chunks/pidfile-UCFCJOAP.js +85 -0
  223. package/chunks/{processUtils-XZPY2PBB.js → processUtils-YL2LXON2.js} +2 -2
  224. package/chunks/{pt-JJ4XPIBP.js → pt-OK455PLH.js} +5 -1
  225. package/chunks/{qwenContentGenerator-6GUTWJIC.js → qwenContentGenerator-H6WZPJKC.js} +56 -36
  226. package/chunks/{qwenOAuth2-GASEEWGU.js → qwenOAuth2-HTROHKXO.js} +10 -23
  227. package/chunks/read-file-FOYTMUNL.js +31 -0
  228. package/chunks/{read-mcp-resource-AKCL7I43.js → read-mcp-resource-65BWNF3F.js} +3 -3
  229. package/chunks/{record-artifact-PEUB7727.js → record-artifact-2RLSOP6U.js} +3 -3
  230. package/chunks/resumeHistoryUtils-ZNHTWBXS.js +90 -0
  231. package/chunks/ripGrep-K4K4QLNJ.js +72 -0
  232. package/chunks/{ru-STR4KTW7.js → ru-7SPDGMGD.js} +5 -1
  233. package/chunks/{run-qwen-serve-OZGR3FQA.js → run-qwen-serve-XI4MCAFV.js} +343 -88
  234. package/chunks/runtime-4CTBU5WX.js +115 -0
  235. package/chunks/{scheduler-Z7QLMUWA.js → scheduler-TTEITHBF.js} +46 -33
  236. package/chunks/sdk-exporters-grpc-N3OLDF63.js +23214 -0
  237. package/chunks/sdk-exporters-http-AOHAEOMC.js +563 -0
  238. package/chunks/sdk-impl-TLQOC7P4.js +9193 -0
  239. package/chunks/{send-message-3RHE7HSM.js → send-message-GEY4CNPS.js} +47 -8
  240. package/chunks/serve-W7UKJTQT.js +88 -0
  241. package/chunks/{server-SO64U3X5.js → server-JD5PIE7A.js} +3069 -517
  242. package/chunks/{session-2KL2WQAH.js → session-R4BDHLYR.js} +112 -177
  243. package/chunks/{settings-KITVOUSV.js → settings-BXZHA6TZ.js} +50 -37
  244. package/chunks/shell-XYMFCGN5.js +82 -0
  245. package/chunks/{skill-SOQHY455.js → skill-YKXYEPOF.js} +25 -20
  246. package/chunks/spawnChannel-IO4HQLFS.js +81 -0
  247. package/chunks/{src-43LM7JLB.js → src-LKKTJ4NG.js} +382 -235
  248. package/chunks/standalone-update-76JG7DVN.js +91 -0
  249. package/chunks/{startInteractiveUI-3RGTGEX5.js → startInteractiveUI-BXWQUXAS.js} +1314 -958
  250. package/chunks/{syntheticOutput-FG5PQKIR.js → syntheticOutput-2WNMXEU5.js} +4 -4
  251. package/chunks/task-create-R5H74Y76.js +25 -0
  252. package/chunks/{task-list-QWSY4ZIU.js → task-list-WXAFDSRY.js} +7 -7
  253. package/chunks/{task-stop-GWC6UWAL.js → task-stop-CHFZP23W.js} +4 -4
  254. package/chunks/{task-update-NCTAB73Q.js → task-update-Z44A4GAR.js} +11 -9
  255. package/chunks/{team-create-FXN3PEBP.js → team-create-5Y3MCAIM.js} +49 -36
  256. package/chunks/{team-delete-KK37HTOG.js → team-delete-YDCMRSI4.js} +7 -7
  257. package/chunks/{team-plan-approval-GEIZ356Q.js → team-plan-approval-HYJJZ76T.js} +49 -36
  258. package/chunks/theme-manager-3YF2SUZL.js +76 -0
  259. package/chunks/{todoWrite-ERCAMLFS.js → todoWrite-ED2IVZJL.js} +5 -5
  260. package/chunks/{tool-search-XKK7DNOK.js → tool-search-3ZO2XMEP.js} +21 -17
  261. package/chunks/total-session-admission-NDF7EVG7.js +83 -0
  262. package/chunks/trustedFolders-Q7RALK4T.js +92 -0
  263. package/chunks/{chunk-6EFTQYW7.js → undici-3FJYTMOF.js} +24 -399
  264. package/chunks/{chunk-L573Z2QZ.js → undici-PYHBDDPN.js} +1 -5
  265. package/chunks/{update-relaunch-FMVZK6XF.js → update-relaunch-BTW5XGVT.js} +17 -17
  266. package/chunks/updateCheck-MXIU6DWQ.js +91 -0
  267. package/chunks/useAutoAcceptIndicator-BJXHJW77.js +92 -0
  268. package/chunks/{validateNonInterActiveAuth-PRVEB6GG.js → validateNonInterActiveAuth-FLEPF3QQ.js} +90 -76
  269. package/chunks/{version-AZMG6KWL.js → version-75VRONIL.js} +1 -1
  270. package/chunks/{web-fetch-EPGJ5OQQ.js → web-fetch-5X27LYHB.js} +101 -41
  271. package/chunks/web-search-IDMTBJUP.js +718 -0
  272. package/chunks/{workflow-UTNVPW22.js → workflow-JOD2OPFQ.js} +54 -40
  273. package/chunks/workspace-providers-status-WDLBDLPG.js +85 -0
  274. package/chunks/{workspace-registration-store-F3ZX3YHT.js → workspace-registration-store-26Z6J6P5.js} +9 -3
  275. package/chunks/workspace-registry-IABDATX3.js +87 -0
  276. package/chunks/workspace-service-BI4KDYPD.js +97 -0
  277. package/chunks/workspace-skills-status-OVB4LPHA.js +84 -0
  278. package/chunks/write-file-276AJ7KE.js +72 -0
  279. package/chunks/{zh-6ANG2HTL.js → zh-Q54GA5SV.js} +6 -1
  280. package/chunks/{zh-TW-4RR3YHNN.js → zh-TW-VOBNFOPU.js} +6 -1
  281. package/cli-entry.js +164 -12
  282. package/cli.js +19 -12
  283. package/locales/ca.js +773 -203
  284. package/locales/de.js +8 -2
  285. package/locales/en.js +9 -2
  286. package/locales/fr.js +8 -2
  287. package/locales/ja.js +8 -2
  288. package/locales/pt.js +8 -2
  289. package/locales/ru.js +8 -2
  290. package/locales/zh-TW.js +9 -2
  291. package/locales/zh.js +9 -2
  292. package/package.json +3 -3
  293. package/web-shell/assets/{arc-Buk1besA.js → arc-CMb7lr2P.js} +1 -1
  294. package/web-shell/assets/{architectureDiagram-3BPJPVTR-B1aUKYDC.js → architectureDiagram-3BPJPVTR-D6KQ5Kwm.js} +1 -1
  295. package/web-shell/assets/{blockDiagram-GPEHLZMM-CRTdg3Zx.js → blockDiagram-GPEHLZMM-Ce7YYSf8.js} +1 -1
  296. package/web-shell/assets/{c4Diagram-AAUBKEIU-DFdRMp5g.js → c4Diagram-AAUBKEIU-DaStHfor.js} +1 -1
  297. package/web-shell/assets/channel-Dg4f-Kry.js +1 -0
  298. package/web-shell/assets/{chunk-2J33WTMH-4rYQdkEI.js → chunk-2J33WTMH-CPaqadg9.js} +1 -1
  299. package/web-shell/assets/{chunk-4BX2VUAB-Coi-pQJy.js → chunk-4BX2VUAB-Veh9ZGKg.js} +1 -1
  300. package/web-shell/assets/{chunk-55IACEB6-BtBjz02t.js → chunk-55IACEB6-BPTX5n4q.js} +1 -1
  301. package/web-shell/assets/{chunk-727SXJPM-CGYOWorl.js → chunk-727SXJPM-CtXsE_ca.js} +1 -1
  302. package/web-shell/assets/{chunk-AQP2D5EJ-CH5AKhqx.js → chunk-AQP2D5EJ-D8DDCJ8h.js} +1 -1
  303. package/web-shell/assets/{chunk-FMBD7UC4-Cd50-w85.js → chunk-FMBD7UC4-cjMDGzHz.js} +1 -1
  304. package/web-shell/assets/{chunk-ND2GUHAM-C2wF3KCK.js → chunk-ND2GUHAM-BaZ1hNhV.js} +1 -1
  305. package/web-shell/assets/{chunk-QZHKN3VN-pCeRTaWi.js → chunk-QZHKN3VN-C7w-9w5-.js} +1 -1
  306. package/web-shell/assets/classDiagram-4FO5ZUOK-CT7Fo2aW.js +1 -0
  307. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CT7Fo2aW.js +1 -0
  308. package/web-shell/assets/{cose-bilkent-S5V4N54A-B-_fAB6D.js → cose-bilkent-S5V4N54A-DqvBEEIe.js} +1 -1
  309. package/web-shell/assets/{dagre-BM42HDAG-ChSPNHpL.js → dagre-BM42HDAG-RkPyoMAk.js} +1 -1
  310. package/web-shell/assets/{diagram-2AECGRRQ-BX7cFOF3.js → diagram-2AECGRRQ-D9b6nNyg.js} +1 -1
  311. package/web-shell/assets/{diagram-5GNKFQAL-BQUTW92n.js → diagram-5GNKFQAL-CiiNKUIy.js} +1 -1
  312. package/web-shell/assets/{diagram-KO2AKTUF-BkYPh3e4.js → diagram-KO2AKTUF-CP1qizXd.js} +1 -1
  313. package/web-shell/assets/{diagram-LMA3HP47-Cl6jsNyx.js → diagram-LMA3HP47-BGe30TWx.js} +1 -1
  314. package/web-shell/assets/{diagram-OG6HWLK6-DRWoHz8n.js → diagram-OG6HWLK6-CvoEPARH.js} +1 -1
  315. package/web-shell/assets/{erDiagram-TEJ5UH35-CGvFcZco.js → erDiagram-TEJ5UH35-DWfLzVkV.js} +1 -1
  316. package/web-shell/assets/{flowDiagram-I6XJVG4X-vms6oVdv.js → flowDiagram-I6XJVG4X-D-dTQmo6.js} +1 -1
  317. package/web-shell/assets/{ganttDiagram-6RSMTGT7-ukT_sfmi.js → ganttDiagram-6RSMTGT7-CYPHKaGY.js} +1 -1
  318. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Bn2ZE2Ut.js → gitGraphDiagram-PVQCEYII-DA7_aQYD.js} +1 -1
  319. package/web-shell/assets/index-B0i-TOYM.css +5 -0
  320. package/web-shell/assets/index-CgCHD46L.js +1225 -0
  321. package/web-shell/assets/{index-wFXp7W68.js → index-DqHNAB8C.js} +1 -1
  322. package/web-shell/assets/{infoDiagram-5YYISTIA-DHJdSi7x.js → infoDiagram-5YYISTIA-B87ljDPa.js} +1 -1
  323. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-DOvd2Wph.js → ishikawaDiagram-YF4QCWOH-CYSpyjaN.js} +1 -1
  324. package/web-shell/assets/{journeyDiagram-JHISSGLW-CH_urMCT.js → journeyDiagram-JHISSGLW-DAL6Js6f.js} +1 -1
  325. package/web-shell/assets/{kanban-definition-UN3LZRKU-FKiBdgbH.js → kanban-definition-UN3LZRKU-_zufKGJv.js} +1 -1
  326. package/web-shell/assets/{linear-0ZVQFVKf.js → linear-DidhMgku.js} +1 -1
  327. package/web-shell/assets/{mermaid.core-DJ05ZZIK.js → mermaid.core-DAkX3h3a.js} +5 -5
  328. package/web-shell/assets/{mindmap-definition-RKZ34NQL-BPuUhkUm.js → mindmap-definition-RKZ34NQL-DbZxUBEH.js} +1 -1
  329. package/web-shell/assets/{pieDiagram-4H26LBE5-yLFKcXyG.js → pieDiagram-4H26LBE5-Du9uoqrf.js} +1 -1
  330. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-irWqc1pE.js → quadrantDiagram-W4KKPZXB-DwjELuKm.js} +1 -1
  331. package/web-shell/assets/{requirementDiagram-4Y6WPE33-B_4uMoIV.js → requirementDiagram-4Y6WPE33-BAqfVtBL.js} +1 -1
  332. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-ciA4GPwk.js → sankeyDiagram-5OEKKPKP--hm2VpmK.js} +1 -1
  333. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CRdZvy0U.js → sequenceDiagram-3UESZ5HK-R5MUQaIt.js} +1 -1
  334. package/web-shell/assets/{stateDiagram-AJRCARHV-DaYIkCCn.js → stateDiagram-AJRCARHV-VsX032xQ.js} +1 -1
  335. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-uPWLcSfy.js +1 -0
  336. package/web-shell/assets/{timeline-definition-PNZ67QCA-oBUKv6iH.js → timeline-definition-PNZ67QCA-BqjVRXzg.js} +1 -1
  337. package/web-shell/assets/{vennDiagram-CIIHVFJN-CGW9Sdmb.js → vennDiagram-CIIHVFJN-i2tkvlkg.js} +1 -1
  338. package/web-shell/assets/{wardley-L42UT6IY-CvwKJOCm.js → wardley-L42UT6IY-Ch8G49EM.js} +1 -1
  339. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-Ipc260sN.js → wardleyDiagram-YWT4CUSO-bYpWeQNy.js} +1 -1
  340. package/web-shell/assets/{xychartDiagram-2RQKCTM6-D6-CM7pK.js → xychartDiagram-2RQKCTM6-C9NhuBqB.js} +1 -1
  341. package/web-shell/index.html +17 -13
  342. package/chunks/MaxSizedBox-B5YGZSYE.js +0 -72
  343. package/chunks/agent-H4JIDL7S.js +0 -67
  344. package/chunks/agent-headless-TTBEREQV.js +0 -61
  345. package/chunks/bridge-VL7ITBU5.js +0 -75
  346. package/chunks/chunk-542SK7KV.js +0 -8293
  347. package/chunks/chunk-CPCVCKKF.js +0 -358
  348. package/chunks/chunk-SEKHYHMS.js +0 -45
  349. package/chunks/chunk-W7FJ3N32.js +0 -49
  350. package/chunks/chunk-ZFKNWQGQ.js +0 -74639
  351. package/chunks/contextCommand-L2COEUHS.js +0 -66
  352. package/chunks/daemon-status-provider-NL4IAG7B.js +0 -74
  353. package/chunks/earlyInputCapture-L6I2A22T.js +0 -68
  354. package/chunks/errors-LEOF5QG4.js +0 -74
  355. package/chunks/handleAutoUpdate-QQVIWXKT.js +0 -67
  356. package/chunks/i18n-N6OBDORT.js +0 -83
  357. package/chunks/initializer-6WCFNDLL.js +0 -72
  358. package/chunks/installationInfo-6J3WPXNS.js +0 -64
  359. package/chunks/list-HOWQSWP6.js +0 -75
  360. package/chunks/loadedSettingsAdapter-AO4YBRXZ.js +0 -69
  361. package/chunks/mcp-QH7QNXOH.js +0 -69
  362. package/chunks/nonInteractiveCli-TI7EMPXD.js +0 -126
  363. package/chunks/pidfile-UEHAT6DH.js +0 -72
  364. package/chunks/read-file-SQJONF6A.js +0 -29
  365. package/chunks/resumeHistoryUtils-PFQ2A23X.js +0 -78
  366. package/chunks/ripGrep-QCK22GDU.js +0 -59
  367. package/chunks/runtime-SNVAP6EH.js +0 -100
  368. package/chunks/serve-BT7KS6SC.js +0 -75
  369. package/chunks/shell-BITUVH2R.js +0 -69
  370. package/chunks/spawnChannel-2BU3AULL.js +0 -68
  371. package/chunks/standalone-update-YG5JUYCM.js +0 -78
  372. package/chunks/task-create-HX32YXO7.js +0 -23
  373. package/chunks/theme-manager-IAETOI25.js +0 -63
  374. package/chunks/total-session-admission-BJLDHKJN.js +0 -69
  375. package/chunks/trustedFolders-5XCVNEUU.js +0 -79
  376. package/chunks/updateCheck-YZZB7YBU.js +0 -70
  377. package/chunks/useAutoAcceptIndicator-ZSQX4I2H.js +0 -80
  378. package/chunks/workspace-providers-status-EADV364W.js +0 -72
  379. package/chunks/workspace-registry-W6VMFYZU.js +0 -73
  380. package/chunks/workspace-service-F3KIN2UN.js +0 -84
  381. package/chunks/workspace-skills-status-YVICUR5Y.js +0 -71
  382. package/chunks/write-file-CVGF2OKV.js +0 -596
  383. package/web-shell/assets/channel-04R0vLbG.js +0 -1
  384. package/web-shell/assets/classDiagram-4FO5ZUOK-Bw9SOwAV.js +0 -1
  385. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-Bw9SOwAV.js +0 -1
  386. package/web-shell/assets/index-DgkKrjw3.js +0 -1187
  387. package/web-shell/assets/index-Rv6mOAN9.css +0 -5
  388. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DWBoO4UY.js +0 -1
@@ -1,28 +1,5 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
- import {
4
- DEFAULT_RING_SIZE,
5
- EVENT_SCHEMA_VERSION,
6
- EventBus,
7
- serializedBridgeEventByteLength
8
- } from "./chunk-6RLROE6G.js";
9
- import {
10
- normalizeCompactedReplayMaxBytes
11
- } from "./chunk-COH43MRJ.js";
12
- import {
13
- CHANNEL_STARTUP_PROFILE_META_KEY,
14
- CHANNEL_STARTUP_PROFILE_VERSION,
15
- LOAD_REPLAY_BULK_MODE,
16
- LOAD_REPLAY_META_KEY,
17
- LOAD_REPLAY_MODE_META_KEY,
18
- LOAD_REPLAY_PAGE_SIZE_META_KEY,
19
- LOAD_REPLAY_VERSION,
20
- MID_TURN_QUEUE_DRAIN_METHOD,
21
- TODO_STOP_GUARD_QUEUE_RELEASE_METHOD
22
- } from "./chunk-QR6U5QPP.js";
23
- import {
24
- defaultSpawnChannelFactory
25
- } from "./chunk-CV63PP6U.js";
26
3
  import {
27
4
  BranchWhilePromptActiveError,
28
5
  CancelSentinelCollisionError,
@@ -34,6 +11,7 @@ import {
34
11
  InvalidSessionScopeError,
35
12
  MCP_RESTART_SERVER_DEADLINE_MS,
36
13
  PermissionForbiddenError,
14
+ PromptDeadlineExceededError,
37
15
  PromptQueueFullError,
38
16
  RestoreInProgressError,
39
17
  SessionBusyError,
@@ -43,7 +21,32 @@ import {
43
21
  SessionShellDisabledError,
44
22
  WorkspaceMismatchError,
45
23
  isNotCurrentlyGeneratingCancelError
46
- } from "./chunk-X6YQWCIJ.js";
24
+ } from "./chunk-UH3WSE5L.js";
25
+ import {
26
+ CHANNEL_STARTUP_PROFILE_META_KEY,
27
+ CHANNEL_STARTUP_PROFILE_VERSION,
28
+ DAEMON_CHANNEL_DELIVERY_META_KEY,
29
+ LOAD_REPLAY_BULK_MODE,
30
+ LOAD_REPLAY_META_KEY,
31
+ LOAD_REPLAY_MODE_META_KEY,
32
+ LOAD_REPLAY_PAGE_SIZE_META_KEY,
33
+ LOAD_REPLAY_VERSION,
34
+ MID_TURN_QUEUE_DRAIN_METHOD,
35
+ PROMPT_CANCEL_METHOD,
36
+ TODO_STOP_GUARD_QUEUE_RELEASE_METHOD
37
+ } from "./chunk-3SJ43L4W.js";
38
+ import {
39
+ DEFAULT_RING_SIZE,
40
+ EVENT_SCHEMA_VERSION,
41
+ EventBus,
42
+ serializedBridgeEventByteLength
43
+ } from "./chunk-BLFVGB7D.js";
44
+ import {
45
+ normalizeCompactedReplayMaxBytes
46
+ } from "./chunk-COH43MRJ.js";
47
+ import {
48
+ defaultSpawnChannelFactory
49
+ } from "./chunk-YCIM6O3I.js";
47
50
  import {
48
51
  BridgeChannelClosedError,
49
52
  BridgeTimeoutError,
@@ -52,10 +55,16 @@ import {
52
55
  STATUS_SCHEMA_VERSION,
53
56
  createIdleWorkspaceExtensionsStatus,
54
57
  createIdleWorkspaceHooksStatus
55
- } from "./chunk-VDWBQ5AW.js";
58
+ } from "./chunk-CUPAVLRY.js";
56
59
  import {
57
- canonicalizeWorkspace
58
- } from "./chunk-W7FJ3N32.js";
60
+ canonicalizeWorkspace,
61
+ translateAndCheckAbsoluteWorkspacePath
62
+ } from "./chunk-2RFKHEXL.js";
63
+ import {
64
+ CHANNEL_DELIVERY_ERROR_CODES,
65
+ MAX_SUB_SESSION_NAME_CHARS,
66
+ MAX_SUB_SESSION_PROMPT_CHARS
67
+ } from "./chunk-BK2UNYWD.js";
59
68
  import {
60
69
  ClientSideConnection,
61
70
  PROTOCOL_VERSION,
@@ -72,11 +81,16 @@ import {
72
81
  metadataBudgetBytes,
73
82
  normalizeSnapshotPayload,
74
83
  stableSessionArtifactId
75
- } from "./chunk-KX6UK4VJ.js";
84
+ } from "./chunk-LI4I37W4.js";
76
85
  import {
77
86
  DAEMON_TRACEPARENT_META_KEY,
78
87
  DAEMON_TRACESTATE_META_KEY
79
- } from "./chunk-ZFKNWQGQ.js";
88
+ } from "./chunk-AXUW635Q.js";
89
+ import {
90
+ INVOCATION_CONTEXT_META_KEY,
91
+ PRIVATE_ACP_CAPABILITY_ENV,
92
+ PRIVATE_PARENT_CAPABILITY_META_KEY
93
+ } from "./chunk-IFG6TYJ2.js";
80
94
  import {
81
95
  init_esbuild_shims
82
96
  } from "./chunk-5O2XNYP6.js";
@@ -86,7 +100,7 @@ import {
86
100
 
87
101
  // packages/acp-bridge/src/bridge.ts
88
102
  init_esbuild_shims();
89
- import { randomUUID as randomUUID2 } from "node:crypto";
103
+ import { randomBytes, randomUUID as randomUUID2 } from "node:crypto";
90
104
  import * as path3 from "node:path";
91
105
 
92
106
  // packages/acp-bridge/src/compactionEngine.ts
@@ -310,6 +324,8 @@ var TurnBoundaryCompactionEngine = class {
310
324
  if (event.id !== void 0) slot.lastEventId = event.id;
311
325
  slot.lastMeta = meta ?? slot.lastMeta;
312
326
  slot.lastEnvelopeMeta = event._meta ?? slot.lastEnvelopeMeta;
327
+ slot.lastTurn = captureTurnFields(event, slot.lastTurn);
328
+ slot.lastSessionId = captureSessionId(event) ?? slot.lastSessionId;
313
329
  } else {
314
330
  entries.push({ sourceRecordIds, index: this.slots.length });
315
331
  this.textSlotIndex[kind].set(parentToolCallId, entries);
@@ -320,7 +336,9 @@ var TurnBoundaryCompactionEngine = class {
320
336
  sourceRecordIds,
321
337
  lastEventId: event.id ?? 0,
322
338
  lastMeta: meta,
323
- lastEnvelopeMeta: event._meta
339
+ lastEnvelopeMeta: event._meta,
340
+ lastTurn: captureTurnFields(event),
341
+ lastSessionId: captureSessionId(event)
324
342
  });
325
343
  }
326
344
  } else {
@@ -330,6 +348,8 @@ var TurnBoundaryCompactionEngine = class {
330
348
  if (event.id !== void 0) lastSlot.lastEventId = event.id;
331
349
  lastSlot.lastMeta = meta ?? lastSlot.lastMeta;
332
350
  lastSlot.lastEnvelopeMeta = event._meta ?? lastSlot.lastEnvelopeMeta;
351
+ lastSlot.lastTurn = captureTurnFields(event, lastSlot.lastTurn);
352
+ lastSlot.lastSessionId = captureSessionId(event) ?? lastSlot.lastSessionId;
333
353
  } else {
334
354
  this.slots.push({
335
355
  kind,
@@ -338,7 +358,9 @@ var TurnBoundaryCompactionEngine = class {
338
358
  sourceRecordIds,
339
359
  lastEventId: event.id ?? 0,
340
360
  lastMeta: meta,
341
- lastEnvelopeMeta: event._meta
361
+ lastEnvelopeMeta: event._meta,
362
+ lastTurn: captureTurnFields(event),
363
+ lastSessionId: captureSessionId(event)
342
364
  });
343
365
  }
344
366
  }
@@ -355,7 +377,9 @@ var TurnBoundaryCompactionEngine = class {
355
377
  slot.chunks.join(""),
356
378
  slot.lastEventId,
357
379
  slot.lastMeta,
358
- slot.lastEnvelopeMeta
380
+ slot.lastEnvelopeMeta,
381
+ slot.lastTurn,
382
+ slot.lastSessionId
359
383
  )
360
384
  );
361
385
  break;
@@ -462,13 +486,20 @@ var TurnBoundaryCompactionEngine = class {
462
486
  this.textSlotIndex.thought.clear();
463
487
  }
464
488
  };
465
- function makeMergedSessionUpdateEvent(sessionUpdate, text, eventId, meta, envelopeMeta) {
489
+ function makeMergedSessionUpdateEvent(sessionUpdate, text, eventId, meta, envelopeMeta, turn, sessionId) {
466
490
  return {
467
491
  id: eventId || void 0,
468
492
  v: EVENT_SCHEMA_VERSION,
469
493
  type: "session_update",
494
+ // Re-stamp prompt/originator attribution captured from the source
495
+ // chunks — clients rebuilding state from a compacted snapshot need
496
+ // them for prompt correlation and originator filtering. Present only
497
+ // when the source events carried them ("present only if set" style).
498
+ ...turn?.promptId !== void 0 ? { promptId: turn.promptId } : {},
499
+ ...turn?.originatorClientId !== void 0 ? { originatorClientId: turn.originatorClientId } : {},
470
500
  ...envelopeMeta !== void 0 ? { _meta: envelopeMeta } : {},
471
501
  data: {
502
+ ...sessionId !== void 0 ? { sessionId } : {},
472
503
  update: {
473
504
  sessionUpdate,
474
505
  content: { type: "text", text },
@@ -478,6 +509,23 @@ function makeMergedSessionUpdateEvent(sessionUpdate, text, eventId, meta, envelo
478
509
  };
479
510
  }
480
511
  __name(makeMergedSessionUpdateEvent, "makeMergedSessionUpdateEvent");
512
+ function captureTurnFields(event, previous) {
513
+ const promptId = event.promptId ?? previous?.promptId;
514
+ const originatorClientId = event.originatorClientId ?? previous?.originatorClientId;
515
+ if (promptId === void 0 && originatorClientId === void 0) {
516
+ return void 0;
517
+ }
518
+ return {
519
+ ...promptId !== void 0 ? { promptId } : {},
520
+ ...originatorClientId !== void 0 ? { originatorClientId } : {}
521
+ };
522
+ }
523
+ __name(captureTurnFields, "captureTurnFields");
524
+ function captureSessionId(event) {
525
+ const sessionId = event.data?.sessionId;
526
+ return typeof sessionId === "string" ? sessionId : void 0;
527
+ }
528
+ __name(captureSessionId, "captureSessionId");
481
529
  function normalizeToolCallType(event) {
482
530
  const data = event.data;
483
531
  if (data?.update?.sessionUpdate === "tool_call_update") {
@@ -540,10 +588,14 @@ function mergeToolCallEvent(existing, incoming) {
540
588
  if (updateMeta !== void 0) merged["_meta"] = updateMeta;
541
589
  merged["sessionUpdate"] = "tool_call";
542
590
  const mergedMeta = existing._meta || incoming._meta ? { ...existing._meta ?? {}, ...incoming._meta ?? {} } : void 0;
591
+ const promptId = incoming.promptId ?? existing.promptId;
592
+ const originatorClientId = incoming.originatorClientId ?? existing.originatorClientId;
543
593
  return {
544
594
  id: incoming.id ?? existing.id,
545
595
  v: EVENT_SCHEMA_VERSION,
546
596
  type: "session_update",
597
+ ...promptId !== void 0 ? { promptId } : {},
598
+ ...originatorClientId !== void 0 ? { originatorClientId } : {},
547
599
  ...mergedMeta ? { _meta: mergedMeta } : {},
548
600
  data: {
549
601
  ...existingData,
@@ -715,11 +767,6 @@ import * as path from "node:path";
715
767
  init_esbuild_shims();
716
768
  var MID_TURN_MESSAGE_INJECTED_EVENT = "mid_turn_message_injected";
717
769
 
718
- // packages/acp-bridge/src/bridgeOptions.ts
719
- init_esbuild_shims();
720
- var MAX_SUB_SESSION_PROMPT_CHARS = 1e5;
721
- var MAX_SUB_SESSION_NAME_CHARS = 200;
722
-
723
770
  // packages/acp-bridge/src/permissionMediator.ts
724
771
  init_esbuild_shims();
725
772
 
@@ -1405,6 +1452,9 @@ var MultiClientPermissionMediator = class {
1405
1452
 
1406
1453
  // packages/acp-bridge/src/bridgeClient.ts
1407
1454
  var PUBLISH_ARTIFACT_TOOL_NAME = "artifact";
1455
+ var MAX_CHANNEL_DELIVERY_TEXT_CHARS = 1e5;
1456
+ var MAX_CHANNEL_DELIVERY_FIELD_CHARS = 2048;
1457
+ var MAX_CHANNEL_DELIVERY_ERROR_CHARS = 500;
1408
1458
  function isFsErrorShape(err) {
1409
1459
  return err instanceof Error && err.name === "FsError" && typeof err.kind === "string";
1410
1460
  }
@@ -1413,6 +1463,25 @@ function isRecord2(value) {
1413
1463
  return typeof value === "object" && value !== null && !Array.isArray(value);
1414
1464
  }
1415
1465
  __name(isRecord2, "isRecord");
1466
+ function isBoundedChannelDeliveryString(value) {
1467
+ return typeof value === "string" && value.trim().length > 0 && value.length <= MAX_CHANNEL_DELIVERY_FIELD_CHARS;
1468
+ }
1469
+ __name(isBoundedChannelDeliveryString, "isBoundedChannelDeliveryString");
1470
+ function isChannelDeliveryTarget(value) {
1471
+ if (!isRecord2(value)) return false;
1472
+ return isBoundedChannelDeliveryString(value["channelName"]) && (value["type"] === "user" || value["type"] === "chat") && isBoundedChannelDeliveryString(value["id"]) && Object.keys(value).every(
1473
+ (key) => key === "channelName" || key === "type" || key === "id"
1474
+ );
1475
+ }
1476
+ __name(isChannelDeliveryTarget, "isChannelDeliveryTarget");
1477
+ function normalizeChannelDeliveryHostResult(value) {
1478
+ if (value.status === "delivered") return { status: "delivered" };
1479
+ if (value.status === "skipped") return { status: "skipped" };
1480
+ const code = CHANNEL_DELIVERY_ERROR_CODES.has(value.code) ? value.code : "channel_delivery_failed";
1481
+ const error = typeof value.error === "string" && value.error.length > 0 ? value.error.slice(0, MAX_CHANNEL_DELIVERY_ERROR_CHARS) : "Channel delivery failed.";
1482
+ return { status: "failed", code, error };
1483
+ }
1484
+ __name(normalizeChannelDeliveryHostResult, "normalizeChannelDeliveryHostResult");
1416
1485
  function pendingInteractionOptions(options) {
1417
1486
  return options.map((option) => ({
1418
1487
  optionId: String(option.optionId ?? ""),
@@ -1623,7 +1692,7 @@ function sliceLineRange(content, startLine, endLine) {
1623
1692
  }
1624
1693
  __name(sliceLineRange, "sliceLineRange");
1625
1694
  var BridgeClient = class {
1626
- constructor(resolveEntry, resolvePendingRestoreEvents, mediator, permissionTimeoutMs, maxPendingPerSession, fileSystem, onModelPromoted, onModePromoted, clientMcpSender, ownsSession = () => true, onTokenUsage, onCreateSubSession, onGenerationEvent) {
1695
+ constructor(resolveEntry, resolvePendingRestoreEvents, mediator, permissionTimeoutMs, maxPendingPerSession, fileSystem, onModelPromoted, onModePromoted, clientMcpSender, ownsSession = () => true, onTokenUsage, onCreateSubSession, onGenerationEvent, onWorkspaceGenerationEvent, onChannelDelivery) {
1627
1696
  this.resolveEntry = resolveEntry;
1628
1697
  this.resolvePendingRestoreEvents = resolvePendingRestoreEvents;
1629
1698
  this.mediator = mediator;
@@ -1637,6 +1706,8 @@ var BridgeClient = class {
1637
1706
  this.onTokenUsage = onTokenUsage;
1638
1707
  this.onCreateSubSession = onCreateSubSession;
1639
1708
  this.onGenerationEvent = onGenerationEvent;
1709
+ this.onWorkspaceGenerationEvent = onWorkspaceGenerationEvent;
1710
+ this.onChannelDelivery = onChannelDelivery;
1640
1711
  }
1641
1712
  static {
1642
1713
  __name(this, "BridgeClient");
@@ -1914,6 +1985,9 @@ var BridgeClient = class {
1914
1985
  if (method === SERVE_CONTROL_EXT_METHODS.createSubSession) {
1915
1986
  return this.handleCreateSubSession(params);
1916
1987
  }
1988
+ if (method === SERVE_CONTROL_EXT_METHODS.channelDelivery) {
1989
+ return this.handleChannelDelivery(params);
1990
+ }
1917
1991
  if (method !== MID_TURN_QUEUE_DRAIN_METHOD) {
1918
1992
  throw RequestError.methodNotFound(method);
1919
1993
  }
@@ -1950,6 +2024,98 @@ var BridgeClient = class {
1950
2024
  }
1951
2025
  return { messages, hasQueuedPrompt };
1952
2026
  }
2027
+ async handleChannelDelivery(params) {
2028
+ if (!this.onChannelDelivery) {
2029
+ throw RequestError.methodNotFound(
2030
+ SERVE_CONTROL_EXT_METHODS.channelDelivery
2031
+ );
2032
+ }
2033
+ const sessionId = params["sessionId"];
2034
+ if (typeof sessionId !== "string" || sessionId.length === 0 || !this.ownsSession(sessionId)) {
2035
+ throw RequestError.invalidParams(
2036
+ void 0,
2037
+ "`sessionId` must name a session owned by this connection"
2038
+ );
2039
+ }
2040
+ const entry = this.resolveEntry(sessionId);
2041
+ if (!entry) {
2042
+ throw RequestError.invalidParams(void 0, "Unknown `sessionId`");
2043
+ }
2044
+ const deliveryId = params["deliveryId"];
2045
+ const source = params["source"];
2046
+ const text = params["text"];
2047
+ const rawTarget = params["target"];
2048
+ if (!isBoundedChannelDeliveryString(deliveryId) || source !== "prompt" && source !== "scheduled" || typeof text !== "string" || text.length > MAX_CHANNEL_DELIVERY_TEXT_CHARS || !isChannelDeliveryTarget(rawTarget)) {
2049
+ throw RequestError.invalidParams(
2050
+ void 0,
2051
+ "Invalid channel delivery request"
2052
+ );
2053
+ }
2054
+ const promptId = params["promptId"];
2055
+ const taskId = params["taskId"];
2056
+ const firedAt = params["firedAt"];
2057
+ const allowedKeys = source === "prompt" ? /* @__PURE__ */ new Set([
2058
+ "sessionId",
2059
+ "deliveryId",
2060
+ "source",
2061
+ "target",
2062
+ "text",
2063
+ "promptId"
2064
+ ]) : /* @__PURE__ */ new Set([
2065
+ "sessionId",
2066
+ "deliveryId",
2067
+ "source",
2068
+ "target",
2069
+ "text",
2070
+ "taskId",
2071
+ "firedAt"
2072
+ ]);
2073
+ const correlationValid = source === "prompt" ? isBoundedChannelDeliveryString(promptId) && promptId === deliveryId : isBoundedChannelDeliveryString(taskId) && typeof firedAt === "number" && Number.isFinite(firedAt) && deliveryId === `${taskId}:${firedAt}`;
2074
+ if (!correlationValid || !Object.keys(params).every((key) => allowedKeys.has(key))) {
2075
+ throw RequestError.invalidParams(
2076
+ void 0,
2077
+ "Invalid channel delivery correlation"
2078
+ );
2079
+ }
2080
+ const info = {
2081
+ sessionId,
2082
+ deliveryId,
2083
+ source,
2084
+ target: rawTarget,
2085
+ text,
2086
+ ...source === "prompt" ? { promptId } : {},
2087
+ ...source === "scheduled" ? { taskId, firedAt } : {}
2088
+ };
2089
+ let result;
2090
+ try {
2091
+ result = normalizeChannelDeliveryHostResult(
2092
+ await this.onChannelDelivery(info)
2093
+ );
2094
+ } catch {
2095
+ result = {
2096
+ status: "failed",
2097
+ code: "channel_delivery_failed",
2098
+ error: "Channel delivery failed."
2099
+ };
2100
+ }
2101
+ try {
2102
+ entry.events.publish({
2103
+ type: "channel_delivery_result",
2104
+ ...source === "prompt" ? { promptId } : {},
2105
+ data: {
2106
+ sessionId,
2107
+ deliveryId,
2108
+ source,
2109
+ status: result.status,
2110
+ ...source === "prompt" ? { promptId } : {},
2111
+ ...source === "scheduled" ? { taskId, firedAt } : {},
2112
+ ...result.status === "failed" ? { code: result.code, error: result.error } : {}
2113
+ }
2114
+ });
2115
+ } catch {
2116
+ }
2117
+ return result;
2118
+ }
1953
2119
  /**
1954
2120
  * Reverse tool channel (issue #5626, Phase 2) — answer the child's
1955
2121
  * `qwen/control/client_mcp/message` ext-method. The child's session
@@ -2117,6 +2283,47 @@ var BridgeClient = class {
2117
2283
  }
2118
2284
  return;
2119
2285
  }
2286
+ if (method === "qwen/notify/workspace/generation/event") {
2287
+ const requestId = params["requestId"];
2288
+ const event = params["event"];
2289
+ if (params["v"] !== 1 || typeof requestId !== "string" || !event || typeof event !== "object" || Array.isArray(event)) {
2290
+ return;
2291
+ }
2292
+ const record = event;
2293
+ if (record["type"] === "started") {
2294
+ const model = record["model"];
2295
+ const modelSource = record["modelSource"];
2296
+ if (typeof model !== "string" || modelSource !== "fast" && modelSource !== "main") {
2297
+ return;
2298
+ }
2299
+ this.onWorkspaceGenerationEvent?.({
2300
+ type: "started",
2301
+ requestId,
2302
+ model,
2303
+ modelSource
2304
+ });
2305
+ return;
2306
+ }
2307
+ if (record["type"] === "thinking") {
2308
+ this.onWorkspaceGenerationEvent?.({ type: "thinking", requestId });
2309
+ return;
2310
+ }
2311
+ if (record["type"] === "delta") {
2312
+ const seq = record["seq"];
2313
+ const text = record["text"];
2314
+ if (typeof seq !== "number" || !Number.isSafeInteger(seq) || seq < 0 || typeof text !== "string" || text.length === 0) {
2315
+ return;
2316
+ }
2317
+ this.onWorkspaceGenerationEvent?.({
2318
+ type: "delta",
2319
+ requestId,
2320
+ seq,
2321
+ text
2322
+ });
2323
+ return;
2324
+ }
2325
+ return;
2326
+ }
2120
2327
  if (method === "qwen/notify/session/model-update") {
2121
2328
  this.handleInSessionModelUpdate(params);
2122
2329
  return;
@@ -5040,6 +5247,12 @@ function isRecord3(value) {
5040
5247
  return typeof value === "object" && value !== null && !Array.isArray(value);
5041
5248
  }
5042
5249
  __name(isRecord3, "isRecord");
5250
+ function isDefinitiveAcpRequestError(error) {
5251
+ if (error instanceof RequestError) return true;
5252
+ if (!isRecord3(error)) return false;
5253
+ return typeof error["code"] === "number" && Number.isInteger(error["code"]) && typeof error["message"] === "string";
5254
+ }
5255
+ __name(isDefinitiveAcpRequestError, "isDefinitiveAcpRequestError");
5043
5256
  function getCanonicalModelId(response, fallback) {
5044
5257
  if (!isRecord3(response) || !isRecord3(response["_meta"])) return fallback;
5045
5258
  const modelSwitch = response["_meta"]["qwenModelSwitch"];
@@ -5295,13 +5508,15 @@ function broadcastPromptCancelled(entry, sessionId, promptId, originatorClientId
5295
5508
  }
5296
5509
  __name(broadcastPromptCancelled, "broadcastPromptCancelled");
5297
5510
  function broadcastPromptCancelledOnce(entry, sessionId, promptId, originatorClientId, reason) {
5298
- if (entry.cancelBroadcast) {
5511
+ if (promptId !== void 0 && entry.cancelBroadcastPromptId === promptId) {
5299
5512
  writeStderrLine(
5300
- `broadcastPromptCancelledOnce: suppressed duplicate cancel for session ${sessionId} (latch already set)`
5513
+ `broadcastPromptCancelledOnce: suppressed duplicate cancel for session ${sessionId} prompt=${promptId}`
5301
5514
  );
5302
5515
  return;
5303
5516
  }
5304
- entry.cancelBroadcast = true;
5517
+ if (promptId !== void 0) {
5518
+ entry.cancelBroadcastPromptId = promptId;
5519
+ }
5305
5520
  broadcastPromptCancelled(
5306
5521
  entry,
5307
5522
  sessionId,
@@ -5367,7 +5582,7 @@ function classifyTurnErrorKind(message) {
5367
5582
  return message.trim().toLowerCase() === "terminated" ? "model_stream_interrupted" : void 0;
5368
5583
  }
5369
5584
  __name(classifyTurnErrorKind, "classifyTurnErrorKind");
5370
- function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId) {
5585
+ function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId, mutateTurnState) {
5371
5586
  const message = extractErrorMessage(err);
5372
5587
  const code = extractErrorCode(err);
5373
5588
  const errorKind = classifyTurnErrorKind(message);
@@ -5376,12 +5591,14 @@ function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId)
5376
5591
  `turn_error classified session=${JSON.stringify(sessionId)} message=${JSON.stringify(message)} errorKind=${JSON.stringify(errorKind)}` + (code ? ` code=${JSON.stringify(code)}` : "") + (promptId ? ` promptId=${JSON.stringify(promptId)}` : "")
5377
5592
  );
5378
5593
  }
5379
- entry.retryAllowed = true;
5380
- entry.turnError = {
5381
- message,
5382
- ...code ? { code } : {},
5383
- ...errorKind ? { errorKind } : {}
5384
- };
5594
+ if (mutateTurnState) {
5595
+ entry.retryAllowed = true;
5596
+ entry.turnError = {
5597
+ message,
5598
+ ...code ? { code } : {},
5599
+ ...errorKind ? { errorKind } : {}
5600
+ };
5601
+ }
5385
5602
  try {
5386
5603
  entry.events.publish({
5387
5604
  type: "turn_error",
@@ -5399,6 +5616,64 @@ function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId)
5399
5616
  }
5400
5617
  }
5401
5618
  __name(broadcastTurnError, "broadcastTurnError");
5619
+ function publishPromptTerminal(entry, pendingEntry, terminal) {
5620
+ if (pendingEntry.terminalPublished) {
5621
+ writeServeDebugLine(
5622
+ `publishPromptTerminal: suppressed duplicate ${terminal.kind} terminal for prompt ${pendingEntry.promptId} (session ${entry.sessionId})`
5623
+ );
5624
+ return;
5625
+ }
5626
+ pendingEntry.terminalPublished = true;
5627
+ const originatorClientId = pendingEntry.originatorClientId;
5628
+ if (terminal.kind === "complete") {
5629
+ broadcastTurnComplete(
5630
+ entry,
5631
+ entry.sessionId,
5632
+ terminal.result,
5633
+ pendingEntry.promptId,
5634
+ originatorClientId
5635
+ );
5636
+ } else if (terminal.kind === "cancelled") {
5637
+ broadcastTurnComplete(
5638
+ entry,
5639
+ entry.sessionId,
5640
+ { stopReason: "cancelled" },
5641
+ pendingEntry.promptId,
5642
+ originatorClientId
5643
+ );
5644
+ } else {
5645
+ broadcastTurnError(
5646
+ entry,
5647
+ entry.sessionId,
5648
+ terminal.err,
5649
+ pendingEntry.promptId,
5650
+ originatorClientId,
5651
+ // Only a running prompt's failure is the active turn's failure. The
5652
+ // `state === 'running'` gate (not `activePromptId`) is deliberate:
5653
+ // on the normal settle path `settleActivePromptState` runs in
5654
+ // `promptPromise.finally` BEFORE the terminal is published, so
5655
+ // `activePromptId` is already cleared when a genuine active failure
5656
+ // lands here.
5657
+ pendingEntry.state === "running"
5658
+ );
5659
+ }
5660
+ }
5661
+ __name(publishPromptTerminal, "publishPromptTerminal");
5662
+ function flushPromptTerminals(entry, code, message) {
5663
+ for (const pending of [...entry.pendingPromptList]) {
5664
+ publishPromptTerminal(entry, pending, {
5665
+ kind: "error",
5666
+ err: { code, message }
5667
+ });
5668
+ try {
5669
+ pending.abortController.abort(
5670
+ new DOMException("Prompt aborted", "AbortError")
5671
+ );
5672
+ } catch {
5673
+ }
5674
+ }
5675
+ }
5676
+ __name(flushPromptTerminals, "flushPromptTerminals");
5402
5677
  function hasControlCharacter2(value) {
5403
5678
  for (let i = 0; i < value.length; i += 1) {
5404
5679
  const code = value.charCodeAt(i);
@@ -5558,6 +5833,18 @@ function createAcpSessionBridge(opts) {
5558
5833
  lastActivityTimestamp = Date.now();
5559
5834
  }
5560
5835
  __name(touchActivity, "touchActivity");
5836
+ function settleActivePromptState(entry, promptId) {
5837
+ if (entry.activePromptId !== promptId) return;
5838
+ delete entry.activePromptId;
5839
+ delete entry.activePromptOriginatorClientId;
5840
+ if (entry.promptActive) {
5841
+ entry.promptActive = false;
5842
+ activePromptCounter--;
5843
+ entry.sessionLastSeenAt = Date.now();
5844
+ touchActivity();
5845
+ }
5846
+ }
5847
+ __name(settleActivePromptState, "settleActivePromptState");
5561
5848
  function resolvePositiveFiniteMs(raw, fallback) {
5562
5849
  if (raw === void 0) return fallback;
5563
5850
  return raw > 0 && Number.isFinite(raw) ? Math.min(raw, 2147483647) : 0;
@@ -5674,7 +5961,7 @@ function createAcpSessionBridge(opts) {
5674
5961
  if (shuttingDown) return;
5675
5962
  const now = Date.now();
5676
5963
  for (const [id, entry] of byId) {
5677
- if (entry.promptActive) continue;
5964
+ if (entry.pendingPromptCount > 0) continue;
5678
5965
  if (entry.events.subscriberCount > 0) continue;
5679
5966
  const lastActive = entry.sessionLastSeenAt ?? Date.parse(entry.createdAt);
5680
5967
  const idle = now - lastActive;
@@ -5704,7 +5991,54 @@ function createAcpSessionBridge(opts) {
5704
5991
  const aliveChannels = /* @__PURE__ */ new Set();
5705
5992
  let inFlightChannelSpawn;
5706
5993
  const byId = /* @__PURE__ */ new Map();
5994
+ const forwardRunningPromptCancel = /* @__PURE__ */ __name(async (entry, pending, notification) => {
5995
+ if (pending.cancelForwardInitial) {
5996
+ return pending.cancelForwardInitial;
5997
+ }
5998
+ const initial = (async () => {
5999
+ try {
6000
+ const extension = entry.connection.extMethod(PROMPT_CANCEL_METHOD, notification).then((result2) => ({ kind: "result", result: result2 }));
6001
+ const outcome = await Promise.race([
6002
+ extension,
6003
+ getTransportClosedReject(entry),
6004
+ ...pending.cancelForwardDeadline ? [
6005
+ pending.cancelForwardDeadline.then(() => ({
6006
+ kind: "deadline"
6007
+ }))
6008
+ ] : []
6009
+ ]);
6010
+ if (outcome.kind === "deadline") return;
6011
+ const { result } = outcome;
6012
+ if (typeof result["cancelled"] !== "boolean") {
6013
+ throw new Error(
6014
+ `${PROMPT_CANCEL_METHOD} returned an invalid acknowledgement`
6015
+ );
6016
+ }
6017
+ } catch (error) {
6018
+ if (typeof error === "object" && error !== null && "code" in error && error.code === -32601 || isNotCurrentlyGeneratingCancelError(error)) {
6019
+ await Promise.race([
6020
+ entry.connection.cancel(notification),
6021
+ getTransportClosedReject(entry),
6022
+ ...pending.cancelForwardDeadline ? [pending.cancelForwardDeadline] : []
6023
+ ]);
6024
+ return;
6025
+ }
6026
+ throw error;
6027
+ }
6028
+ })().catch((error) => {
6029
+ if (pending.cancelForwardInitial === initial) {
6030
+ delete pending.cancelForwardInitial;
6031
+ }
6032
+ throw error;
6033
+ });
6034
+ pending.cancelForwardInitial = initial;
6035
+ pending.cancelForwardDrain = initial;
6036
+ void initial.catch(() => {
6037
+ });
6038
+ return initial;
6039
+ }, "forwardRunningPromptCancel");
5707
6040
  const generationRequests = /* @__PURE__ */ new Map();
6041
+ const workspaceGenerationRequests = /* @__PURE__ */ new Map();
5708
6042
  const inFlightExtensionRefreshes = /* @__PURE__ */ new Map();
5709
6043
  const toSessionSummary = /* @__PURE__ */ __name((entry) => {
5710
6044
  let isWaitingForPermission = false;
@@ -5731,7 +6065,8 @@ function createAcpSessionBridge(opts) {
5731
6065
  pendingInteractionCount: entry.pendingInteractions.size,
5732
6066
  hasTurnError: entry.turnError !== void 0,
5733
6067
  ...entry.turnError !== void 0 ? { turnError: entry.turnError } : {},
5734
- pendingInteractions: [...entry.pendingInteractions.values()]
6068
+ pendingInteractions: [...entry.pendingInteractions.values()],
6069
+ ...entry.worktree ? { worktree: entry.worktree } : {}
5735
6070
  };
5736
6071
  }, "toSessionSummary");
5737
6072
  const permissionConsensusQuorum = opts.permissionConsensusQuorum;
@@ -5793,13 +6128,30 @@ function createAcpSessionBridge(opts) {
5793
6128
  entry.clientIds.set(clientId, count - 1);
5794
6129
  }
5795
6130
  }, "unregisterClient");
6131
+ const recordAttachRef = /* @__PURE__ */ __name((entry, clientId) => {
6132
+ entry.attachRefs.set(clientId, (entry.attachRefs.get(clientId) ?? 0) + 1);
6133
+ }, "recordAttachRef");
6134
+ const releaseAttachRef = /* @__PURE__ */ __name((entry, clientId) => {
6135
+ const refs = entry.attachRefs.get(clientId);
6136
+ if (refs === void 0 || refs <= 0) return false;
6137
+ if (refs === 1) {
6138
+ entry.attachRefs.delete(clientId);
6139
+ } else {
6140
+ entry.attachRefs.set(clientId, refs - 1);
6141
+ }
6142
+ return true;
6143
+ }, "releaseAttachRef");
5796
6144
  const rollbackAttachRegistration = /* @__PURE__ */ __name(async (entry, clientId, attachCountDelta = 1) => {
5797
- entry.attachCount = Math.max(0, entry.attachCount - attachCountDelta);
6145
+ const released = releaseAttachRef(entry, clientId) ? 1 : 0;
6146
+ entry.attachCount = Math.max(
6147
+ 0,
6148
+ entry.attachCount - (released + (attachCountDelta - 1))
6149
+ );
5798
6150
  unregisterClient(entry, clientId);
5799
6151
  if (entry.spawnOwnerWantedKill && entry.attachCount === 0 && entry.events.subscriberCount === 0) {
5800
6152
  await bridgeApi.killSession(entry.sessionId).catch(() => {
5801
6153
  });
5802
- } else if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && !entry.promptActive) {
6154
+ } else if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && entry.pendingPromptCount === 0) {
5803
6155
  await closeSessionImpl(entry.sessionId, void 0, {
5804
6156
  reason: "last_client_detached"
5805
6157
  }).catch((err) => {
@@ -5821,6 +6173,7 @@ function createAcpSessionBridge(opts) {
5821
6173
  if (channelInfo && !channelInfo.isDying) return channelInfo;
5822
6174
  if (inFlightChannelSpawn) return await inFlightChannelSpawn;
5823
6175
  const promise = (async () => {
6176
+ const privateParentCapability = randomBytes(32).toString("base64url");
5824
6177
  const acpChannelId = randomUUID2();
5825
6178
  const channel = await telemetry.withSpan(
5826
6179
  "channel.spawn",
@@ -5829,7 +6182,10 @@ function createAcpSessionBridge(opts) {
5829
6182
  "qwen-code.daemon.channel.reused": false,
5830
6183
  "qwen-code.daemon.acp_channel.id": acpChannelId
5831
6184
  },
5832
- async () => await channelFactory(boundWorkspace, childEnvOverrides)
6185
+ async () => await channelFactory(boundWorkspace, {
6186
+ ...childEnvOverrides,
6187
+ [PRIVATE_ACP_CAPABILITY_ENV]: privateParentCapability
6188
+ })
5833
6189
  );
5834
6190
  const sessionIds = /* @__PURE__ */ new Set();
5835
6191
  const client = new BridgeClient(
@@ -5909,7 +6265,19 @@ function createAcpSessionBridge(opts) {
5909
6265
  sessionId,
5910
6266
  requestId: event.requestId
5911
6267
  }).catch(() => void 0);
5912
- }
6268
+ },
6269
+ (event) => {
6270
+ const request = workspaceGenerationRequests.get(event.requestId);
6271
+ if (!request) return;
6272
+ if (request.queue.push(event)) return;
6273
+ request.settled = true;
6274
+ workspaceGenerationRequests.delete(event.requestId);
6275
+ request.queue.fail(new Error("Generation stream consumer too slow"));
6276
+ void request.connection?.extMethod(SERVE_CONTROL_EXT_METHODS.workspaceGenerationCancel, {
6277
+ requestId: event.requestId
6278
+ }).catch(() => void 0);
6279
+ },
6280
+ opts.onChannelDelivery
5913
6281
  );
5914
6282
  const connection = new ClientSideConnection(() => client, channel.stream);
5915
6283
  const info = {
@@ -5968,6 +6336,11 @@ function createAcpSessionBridge(opts) {
5968
6336
  const sessEntry = byId.get(sid);
5969
6337
  if (!sessEntry) continue;
5970
6338
  cancelPendingForSession(sid);
6339
+ flushPromptTerminals(
6340
+ sessEntry,
6341
+ "channel_closed",
6342
+ "agent channel exited before the prompt completed"
6343
+ );
5971
6344
  try {
5972
6345
  sessEntry.events.publish({
5973
6346
  type: "session_died",
@@ -6013,7 +6386,8 @@ function createAcpSessionBridge(opts) {
6013
6386
  _meta: {
6014
6387
  [CHANNEL_STARTUP_PROFILE_META_KEY]: {
6015
6388
  v: CHANNEL_STARTUP_PROFILE_VERSION
6016
- }
6389
+ },
6390
+ [PRIVATE_PARENT_CAPABILITY_META_KEY]: privateParentCapability
6017
6391
  },
6018
6392
  clientCapabilities: {
6019
6393
  fs: { readTextFile: true, writeTextFile: true }
@@ -6062,7 +6436,7 @@ function createAcpSessionBridge(opts) {
6062
6436
  }
6063
6437
  }
6064
6438
  __name(ensureChannel, "ensureChannel");
6065
- async function doSpawn(modelServiceId, effectiveScope, approvalMode, requestedClientId, onSessionRegistered, parentSessionId, sourceType, sourceId) {
6439
+ async function doSpawn(modelServiceId, effectiveScope, approvalMode, requestedClientId, onSessionRegistered, parentSessionId, sourceType, sourceId, worktree) {
6066
6440
  const channelPath = channelInfo && !channelInfo.isDying ? "reused" : inFlightChannelSpawn ? "joined" : "spawned_on_request";
6067
6441
  const ci = await telemetry.withSpan(
6068
6442
  "channel.wait",
@@ -6123,7 +6497,7 @@ function createAcpSessionBridge(opts) {
6123
6497
  newSessionResp.sessionId,
6124
6498
  boundWorkspace,
6125
6499
  void 0,
6126
- { parentSessionId, sourceType, sourceId }
6500
+ { parentSessionId, sourceType, sourceId, worktree }
6127
6501
  );
6128
6502
  initializedSessionId = entry.sessionId;
6129
6503
  sessionRegistered = true;
@@ -6237,7 +6611,8 @@ function createAcpSessionBridge(opts) {
6237
6611
  ...entry.sourceType ? { sourceType: entry.sourceType } : {},
6238
6612
  ...entry.sourceId !== void 0 ? { sourceId: entry.sourceId } : {},
6239
6613
  ...entry.sourceType ? { sourcePersisted: sourcePersisted === true } : {},
6240
- ...entry.parentSessionId ? { parentSessionPersisted: parentSessionPersisted === true } : {}
6614
+ ...entry.parentSessionId ? { parentSessionPersisted: parentSessionPersisted === true } : {},
6615
+ ...entry.worktree ? { worktree: entry.worktree } : {}
6241
6616
  };
6242
6617
  } finally {
6243
6618
  ci.sessionSpawnsInFlight = Math.max(0, ci.sessionSpawnsInFlight - 1);
@@ -6447,10 +6822,11 @@ function createAcpSessionBridge(opts) {
6447
6822
  }
6448
6823
  return entry.transportClosedReject;
6449
6824
  }, "getTransportClosedReject");
6450
- const resolveWorkspaceKey = /* @__PURE__ */ __name((workspaceCwd) => {
6451
- if (!path3.isAbsolute(workspaceCwd)) {
6825
+ const resolveWorkspaceKey = /* @__PURE__ */ __name((rawWorkspaceCwd) => {
6826
+ const workspaceCwd = translateAndCheckAbsoluteWorkspacePath(rawWorkspaceCwd);
6827
+ if (workspaceCwd === null) {
6452
6828
  throw new Error(
6453
- `workspaceCwd must be an absolute path; got "${workspaceCwd}"`
6829
+ `workspaceCwd must be an absolute path; got "${rawWorkspaceCwd}"`
6454
6830
  );
6455
6831
  }
6456
6832
  const workspaceKey = workspaceCwd === boundWorkspace ? boundWorkspace : canonicalizeWorkspace(workspaceCwd);
@@ -6689,12 +7065,18 @@ function createAcpSessionBridge(opts) {
6689
7065
  return;
6690
7066
  }
6691
7067
  try {
7068
+ const closeRequest = entry.connection.extMethod(
7069
+ SERVE_CONTROL_EXT_METHODS.sessionClose,
7070
+ {
7071
+ sessionId: entry.sessionId,
7072
+ drainTimeoutMs: Math.max(1, Math.floor(initTimeoutMs * 0.8)),
7073
+ ...opts2?.requireFlush === true ? { requireFlush: true } : {}
7074
+ }
7075
+ );
7076
+ const observedCloseRequest = opts2?.timeoutMs ? withTimeout(closeRequest, opts2.timeoutMs, label) : closeRequest;
6692
7077
  await Promise.race([
6693
- withTimeout(
6694
- entry.connection.extMethod(SERVE_CONTROL_EXT_METHODS.sessionClose, {
6695
- sessionId: entry.sessionId,
6696
- ...opts2?.requireFlush === true ? { requireFlush: true } : {}
6697
- }),
7078
+ opts2?.throwOnFailure === true ? observedCloseRequest : withTimeout(
7079
+ observedCloseRequest,
6698
7080
  initTimeoutMs,
6699
7081
  SERVE_CONTROL_EXT_METHODS.sessionClose
6700
7082
  ),
@@ -6748,7 +7130,7 @@ function createAcpSessionBridge(opts) {
6748
7130
  );
6749
7131
  }
6750
7132
  }, "broadcastWorkspaceEvent");
6751
- const createSessionEventBus = /* @__PURE__ */ __name(() => new EventBus(
7133
+ const createSessionEventBus = /* @__PURE__ */ __name((sessionId) => new EventBus(
6752
7134
  eventRingSize,
6753
7135
  void 0,
6754
7136
  new TurnBoundaryCompactionEngine({
@@ -6758,7 +7140,17 @@ function createAcpSessionBridge(opts) {
6758
7140
  `replay window evicted ${JSON.stringify(eviction)}`
6759
7141
  );
6760
7142
  }, "onReplayWindowEviction")
6761
- })
7143
+ }),
7144
+ {
7145
+ // Fired once, on the FIRST ingest/seed failure (the bus keeps the
7146
+ // degraded flag set silently afterwards). The bus doesn't know its
7147
+ // session, so the sessionId context is injected here.
7148
+ onCompactionError: /* @__PURE__ */ __name((err) => {
7149
+ writeStderrLine(
7150
+ `qwen serve: compaction degraded for session=${sessionId}; replay snapshot may lag behind live events: ${err instanceof Error ? err.message : String(err)}`
7151
+ );
7152
+ }, "onCompactionError")
7153
+ }
6762
7154
  ), "createSessionEventBus");
6763
7155
  const publishModelSwitched = /* @__PURE__ */ __name((entry, modelId, originatorClientId) => {
6764
7156
  entry.currentModelId = modelId;
@@ -6842,7 +7234,7 @@ function createAcpSessionBridge(opts) {
6842
7234
  if (rerun) void reconcileAfterRoundtrip(entry, target);
6843
7235
  }
6844
7236
  }, "reconcileAfterRoundtrip");
6845
- const createSessionEntry = /* @__PURE__ */ __name((ci, sessionId, workspaceCwd, events = createSessionEventBus(), options = {}) => {
7237
+ const createSessionEntry = /* @__PURE__ */ __name((ci, sessionId, workspaceCwd, events = createSessionEventBus(sessionId), options = {}) => {
6846
7238
  const entry = {
6847
7239
  sessionId,
6848
7240
  workspaceCwd,
@@ -6850,6 +7242,7 @@ function createAcpSessionBridge(opts) {
6850
7242
  ...options.parentSessionId ? { parentSessionId: options.parentSessionId } : {},
6851
7243
  ...options.sourceType ? { sourceType: options.sourceType } : {},
6852
7244
  ...options.sourceId !== void 0 ? { sourceId: options.sourceId } : {},
7245
+ ...options.worktree ? { worktree: options.worktree } : {},
6853
7246
  channel: ci.channel,
6854
7247
  connection: ci.connection,
6855
7248
  events,
@@ -6859,6 +7252,7 @@ function createAcpSessionBridge(opts) {
6859
7252
  persistence: createSessionArtifactPersistence(ci.connection, sessionId)
6860
7253
  }),
6861
7254
  recordingDegraded: false,
7255
+ closing: false,
6862
7256
  promptQueue: Promise.resolve(),
6863
7257
  pendingPromptCount: 0,
6864
7258
  pendingPromptList: [],
@@ -6872,6 +7266,7 @@ function createAcpSessionBridge(opts) {
6872
7266
  clientIds: /* @__PURE__ */ new Map(),
6873
7267
  clientLastSeenAt: /* @__PURE__ */ new Map(),
6874
7268
  attachCount: 0,
7269
+ attachRefs: /* @__PURE__ */ new Map(),
6875
7270
  spawnOwnerWantedKill: false,
6876
7271
  promptActive: false,
6877
7272
  retryAllowed: false
@@ -7015,20 +7410,27 @@ function createAcpSessionBridge(opts) {
7015
7410
  partial: true,
7016
7411
  ...typeof entry.restoreReplayError === "string" ? { replayError: entry.restoreReplayError } : {}
7017
7412
  } : {};
7413
+ const eventEpoch = entry.events.epoch;
7018
7414
  const snapshot = entry.events.snapshotReplay();
7019
7415
  if (!snapshot) {
7020
- return { lastEventId: entry.events.lastEventId, ...replayStatus };
7416
+ return {
7417
+ lastEventId: entry.events.lastEventId,
7418
+ eventEpoch,
7419
+ ...replayStatus
7420
+ };
7021
7421
  }
7022
7422
  if (action === "load") {
7023
7423
  return {
7024
7424
  compactedReplay: snapshot.compactedTurns,
7025
7425
  liveJournal: snapshot.liveJournal,
7026
7426
  lastEventId: snapshot.lastEventId,
7427
+ eventEpoch,
7027
7428
  ...replayStatus,
7429
+ ...snapshot.degraded ? { replayDegraded: true } : {},
7028
7430
  ...entry.restoreHistoryHasMore === true ? { historyHasMore: true } : {}
7029
7431
  };
7030
7432
  }
7031
- return { lastEventId: snapshot.lastEventId, ...replayStatus };
7433
+ return { lastEventId: snapshot.lastEventId, eventEpoch, ...replayStatus };
7032
7434
  }, "replayFieldsFor");
7033
7435
  const restoredArtifactSnapshotFromState = /* @__PURE__ */ __name((state) => {
7034
7436
  const candidate = state.artifactSnapshot;
@@ -7061,6 +7463,62 @@ function createAcpSessionBridge(opts) {
7061
7463
  } = state;
7062
7464
  return publicState;
7063
7465
  }, "publicRestoreState");
7466
+ async function requestSessionTranscriptPage(req) {
7467
+ const info = await ensureChannel();
7468
+ try {
7469
+ const response = await withWorkspaceControl(
7470
+ info,
7471
+ () => withTimeout(
7472
+ Promise.race([
7473
+ info.connection.extMethod(
7474
+ SERVE_STATUS_EXT_METHODS.sessionTranscript,
7475
+ { ...req, cwd: boundWorkspace }
7476
+ ),
7477
+ getChannelClosedReject(info)
7478
+ ]),
7479
+ Math.max(initTimeoutMs, SESSION_TRANSCRIPT_TIMEOUT_MS),
7480
+ SERVE_STATUS_EXT_METHODS.sessionTranscript
7481
+ )
7482
+ );
7483
+ return response;
7484
+ } catch (err) {
7485
+ if (isAcpSessionResourceNotFound(err, req.sessionId)) {
7486
+ throw new SessionNotFoundError(req.sessionId);
7487
+ }
7488
+ throw err;
7489
+ } finally {
7490
+ if (hasNoChannelWork(info)) {
7491
+ await startIdleTimer(info, "session transcript");
7492
+ }
7493
+ }
7494
+ }
7495
+ __name(requestSessionTranscriptPage, "requestSessionTranscriptPage");
7496
+ async function refreshedReplayFieldsFor(entry, historyPageSize) {
7497
+ for (let attempt = 0; attempt < 2; attempt++) {
7498
+ try {
7499
+ const lastEventId = entry.events.lastEventId;
7500
+ const page = await requestSessionTranscriptPage({
7501
+ sessionId: entry.sessionId,
7502
+ direction: "backward",
7503
+ limit: historyPageSize
7504
+ });
7505
+ if (byId.get(entry.sessionId) === entry && !entry.promptActive && entry.events.lastEventId === lastEventId) {
7506
+ return {
7507
+ compactedReplay: page.events,
7508
+ liveJournal: [],
7509
+ lastEventId,
7510
+ ...page.partial === true ? { partial: true } : {},
7511
+ ...page.replayError !== void 0 ? { replayError: page.replayError } : {},
7512
+ ...page.hasMore ? { historyHasMore: true } : {}
7513
+ };
7514
+ }
7515
+ } catch {
7516
+ break;
7517
+ }
7518
+ }
7519
+ return replayFieldsFor(entry, "load");
7520
+ }
7521
+ __name(refreshedReplayFieldsFor, "refreshedReplayFieldsFor");
7064
7522
  async function restoreSession(action, req, options = {}) {
7065
7523
  if (shuttingDown) {
7066
7524
  throw new Error("AcpSessionBridge is shutting down");
@@ -7074,8 +7532,19 @@ function createAcpSessionBridge(opts) {
7074
7532
  const historyReplay = action === "load" ? req.historyReplay ?? "stream" : "stream";
7075
7533
  const existing = byId.get(req.sessionId);
7076
7534
  if (existing) {
7535
+ if (existing.closing) {
7536
+ throw new SessionNotFoundError(
7537
+ req.sessionId,
7538
+ "The session is closing; retry after close completes"
7539
+ );
7540
+ }
7541
+ const replayFields = action === "load" && req.historyPageSize !== void 0 ? await refreshedReplayFieldsFor(existing, req.historyPageSize) : replayFieldsFor(existing, action);
7542
+ if (byId.get(req.sessionId) !== existing || existing.closing) {
7543
+ throw new SessionNotFoundError(req.sessionId);
7544
+ }
7077
7545
  existing.attachCount++;
7078
7546
  const clientId = registerClient(existing, req.clientId);
7547
+ recordAttachRef(existing, clientId);
7079
7548
  if (req.approvalMode) {
7080
7549
  await applyApprovalModeForAttach(existing, req.approvalMode, clientId);
7081
7550
  }
@@ -7091,7 +7560,7 @@ function createAcpSessionBridge(opts) {
7091
7560
  // caller saw; spawn-only sessions don't carry a state payload.
7092
7561
  state: existing.restoreState ?? {},
7093
7562
  hasActivePrompt: existing.promptActive,
7094
- ...replayFieldsFor(existing, action)
7563
+ ...replayFields
7095
7564
  };
7096
7565
  }
7097
7566
  const inFlight = inFlightRestores.get(req.sessionId);
@@ -7120,6 +7589,7 @@ function createAcpSessionBridge(opts) {
7120
7589
  );
7121
7590
  }
7122
7591
  const clientId = registerClient(entry, req.clientId);
7592
+ recordAttachRef(entry, clientId);
7123
7593
  if (req.approvalMode) {
7124
7594
  await applyApprovalModeForAttach(entry, req.approvalMode, clientId);
7125
7595
  }
@@ -7134,7 +7604,7 @@ function createAcpSessionBridge(opts) {
7134
7604
  if (byId.size + inFlightSpawns.size + inFlightRestores.size >= maxSessions) {
7135
7605
  throw new SessionLimitExceededError(maxSessions);
7136
7606
  }
7137
- const restoreEvents = createSessionEventBus();
7607
+ const restoreEvents = createSessionEventBus(req.sessionId);
7138
7608
  let registeredEntry;
7139
7609
  let ci;
7140
7610
  const coalesceState = { count: 0 };
@@ -7241,6 +7711,7 @@ function createAcpSessionBridge(opts) {
7241
7711
  restoreEvents.close();
7242
7712
  racedEntry.attachCount += 1 + coalesceState.count;
7243
7713
  const clientId2 = registerClient(racedEntry, req.clientId);
7714
+ recordAttachRef(racedEntry, clientId2);
7244
7715
  if (req.approvalMode) {
7245
7716
  try {
7246
7717
  await applyApprovalMode(
@@ -7387,10 +7858,17 @@ function createAcpSessionBridge(opts) {
7387
7858
  async function closeSessionImpl(sessionId, context, closeOpts) {
7388
7859
  const entry = byId.get(sessionId);
7389
7860
  if (!entry) throw new SessionNotFoundError(sessionId);
7861
+ if (entry.closing) {
7862
+ throw new SessionNotFoundError(
7863
+ sessionId,
7864
+ "The session is already closing"
7865
+ );
7866
+ }
7390
7867
  let originatorClientId;
7391
7868
  if (context?.clientId !== void 0) {
7392
7869
  originatorClientId = resolveTrustedClientId(entry, context.clientId);
7393
7870
  }
7871
+ entry.closing = true;
7394
7872
  const reason = closeOpts?.reason ?? "client_close";
7395
7873
  writeStderrLine(
7396
7874
  `qwen serve: closing session ${JSON.stringify(sessionId)} (reason: ${reason})` + (originatorClientId ? ` by client ${JSON.stringify(originatorClientId)}` : "")
@@ -7400,26 +7878,37 @@ function createAcpSessionBridge(opts) {
7400
7878
  "session.id": sessionId,
7401
7879
  "session.close.reason": reason
7402
7880
  });
7403
- if (defaultEntry === entry) defaultEntry = void 0;
7404
7881
  const ci = channelInfoForEntry(entry);
7405
7882
  if (!ci) {
7406
7883
  writeStderrLine(
7407
7884
  `qwen serve: closeSession channelInfoForEntry returned undefined for session ${JSON.stringify(sessionId)} \u2014 channel cleanup skipped (entry's channel already torn down)`
7408
7885
  );
7409
7886
  }
7410
- const requireAgentClose = closeOpts?.requireAgentClose === true;
7411
- if (requireAgentClose) {
7887
+ try {
7888
+ permissionMediator.forgetSession(sessionId);
7889
+ entry.pendingPermissionIds.clear();
7890
+ entry.pendingInteractions.clear();
7412
7891
  await notifyAgentSessionClose(entry, ci, "closeSession", {
7413
7892
  throwOnFailure: true,
7414
- requireFlush: true
7893
+ requireFlush: closeOpts?.requireAgentClose === true
7415
7894
  });
7895
+ } catch (error) {
7896
+ if (isDefinitiveAcpRequestError(error)) {
7897
+ entry.closing = false;
7898
+ } else if (ci) {
7899
+ await killChannelWithLog(
7900
+ ci,
7901
+ `recover unknown close outcome for session ${JSON.stringify(sessionId)}`
7902
+ );
7903
+ } else {
7904
+ entry.closing = false;
7905
+ }
7906
+ throw error;
7416
7907
  }
7908
+ if (defaultEntry === entry) defaultEntry = void 0;
7417
7909
  if (ci && ci.channel === entry.channel) {
7418
7910
  ci.sessionIds.delete(sessionId);
7419
7911
  }
7420
- permissionMediator.forgetSession(sessionId);
7421
- entry.pendingPermissionIds.clear();
7422
- entry.pendingInteractions.clear();
7423
7912
  if (entry.promptActive) {
7424
7913
  entry.promptActive = false;
7425
7914
  activePromptCounter--;
@@ -7434,6 +7923,11 @@ function createAcpSessionBridge(opts) {
7434
7923
  reason
7435
7924
  });
7436
7925
  ci?.client.markSessionClosed(sessionId);
7926
+ flushPromptTerminals(
7927
+ entry,
7928
+ "session_closed",
7929
+ "session closed before the prompt completed"
7930
+ );
7437
7931
  try {
7438
7932
  entry.events.publish({
7439
7933
  type: "session_closed",
@@ -7451,9 +7945,6 @@ function createAcpSessionBridge(opts) {
7451
7945
  } catch {
7452
7946
  }
7453
7947
  entry.events.close();
7454
- if (!requireAgentClose) {
7455
- await notifyAgentSessionClose(entry, ci, "closeSession");
7456
- }
7457
7948
  try {
7458
7949
  await telemetry.withSpan(
7459
7950
  "session.close.cancel_active_prompt",
@@ -7568,8 +8059,15 @@ function createAcpSessionBridge(opts) {
7568
8059
  if (effectiveScope === "single") {
7569
8060
  const existing = defaultEntry;
7570
8061
  if (existing) {
8062
+ if (existing.closing) {
8063
+ throw new SessionNotFoundError(
8064
+ existing.sessionId,
8065
+ "The session is closing; retry after close completes"
8066
+ );
8067
+ }
7571
8068
  existing.attachCount++;
7572
8069
  const clientId = registerClient(existing, req.clientId);
8070
+ recordAttachRef(existing, clientId);
7573
8071
  if (req.modelServiceId) {
7574
8072
  await applyModelServiceId(
7575
8073
  existing,
@@ -7609,6 +8107,7 @@ function createAcpSessionBridge(opts) {
7609
8107
  );
7610
8108
  }
7611
8109
  const clientId = registerClient(attachedEntry, req.clientId);
8110
+ recordAttachRef(attachedEntry, clientId);
7612
8111
  if (req.modelServiceId) {
7613
8112
  await applyModelServiceId(
7614
8113
  attachedEntry,
@@ -7654,7 +8153,8 @@ function createAcpSessionBridge(opts) {
7654
8153
  releaseAdmissionOnce,
7655
8154
  req.parentSessionId,
7656
8155
  source.sourceType,
7657
- source.sourceId
8156
+ source.sourceId,
8157
+ req.worktree
7658
8158
  );
7659
8159
  const tracker = effectiveScope === "single" ? workspaceKey : `${workspaceKey}#${randomUUID2()}`;
7660
8160
  inFlightSpawns.set(tracker, promise);
@@ -7676,6 +8176,14 @@ function createAcpSessionBridge(opts) {
7676
8176
  const queuedAt = Date.now();
7677
8177
  const entry = byId.get(sessionId);
7678
8178
  if (!entry) return Promise.reject(new SessionNotFoundError(sessionId));
8179
+ if (entry.closing) {
8180
+ return Promise.reject(
8181
+ new SessionNotFoundError(
8182
+ sessionId,
8183
+ "The session is closing; retry after close completes"
8184
+ )
8185
+ );
8186
+ }
7679
8187
  const originatorClientId = resolveTrustedClientId(
7680
8188
  entry,
7681
8189
  context?.clientId
@@ -7698,6 +8206,12 @@ function createAcpSessionBridge(opts) {
7698
8206
  entry.pendingPromptCount = Math.max(0, entry.pendingPromptCount - 1);
7699
8207
  }, "releasePromptSlot");
7700
8208
  const promptId = context?.promptId ?? randomUUID2();
8209
+ const invocationContext = Object.freeze({
8210
+ version: 1,
8211
+ sessionId,
8212
+ promptId,
8213
+ ...originatorClientId ? { originatorClientId } : {}
8214
+ });
7701
8215
  const isQueued = entry.pendingPromptCount > 1;
7702
8216
  const pendingAbort = new AbortController();
7703
8217
  if (signal) {
@@ -7720,6 +8234,41 @@ function createAcpSessionBridge(opts) {
7720
8234
  state: isQueued ? "queued" : "running"
7721
8235
  };
7722
8236
  entry.pendingPromptList.push(pendingEntry);
8237
+ const deadlineMs = context?.deadlineMs;
8238
+ const hasDeadline = typeof deadlineMs === "number" && Number.isFinite(deadlineMs) && deadlineMs > 0;
8239
+ let deadlineReject;
8240
+ let deadlinePromise;
8241
+ let deadlineTimer;
8242
+ if (hasDeadline) {
8243
+ deadlinePromise = new Promise((_resolve, reject) => {
8244
+ deadlineReject = reject;
8245
+ });
8246
+ deadlinePromise.catch(() => {
8247
+ });
8248
+ pendingEntry.cancelForwardDeadline = deadlinePromise.then(
8249
+ () => void 0,
8250
+ () => void 0
8251
+ );
8252
+ const onDeadline = /* @__PURE__ */ __name(() => {
8253
+ if (pendingEntry.terminalPublished) return;
8254
+ const deadlineErr = new PromptDeadlineExceededError(deadlineMs);
8255
+ writeStderrLine(
8256
+ `sendPrompt: prompt ${promptId} exceeded ${deadlineMs}ms deadline for session ${sessionId}; agent may still be executing`
8257
+ );
8258
+ publishPromptTerminal(entry, pendingEntry, {
8259
+ kind: "error",
8260
+ err: {
8261
+ code: "prompt_deadline_exceeded",
8262
+ message: deadlineErr.message
8263
+ }
8264
+ });
8265
+ settleActivePromptState(entry, pendingEntry.promptId);
8266
+ deadlineReject?.(deadlineErr);
8267
+ pendingAbort.abort(deadlineErr);
8268
+ }, "onDeadline");
8269
+ deadlineTimer = setTimeout(onDeadline, deadlineMs);
8270
+ deadlineTimer.unref();
8271
+ }
7723
8272
  if (isQueued) {
7724
8273
  pendingAbort.signal.addEventListener(
7725
8274
  "abort",
@@ -7756,6 +8305,9 @@ function createAcpSessionBridge(opts) {
7756
8305
  const queueWaitMs = Date.now() - queuedAt;
7757
8306
  telemetry.metrics?.promptQueueWait(queueWaitMs);
7758
8307
  if (pendingAbort.signal.aborted) {
8308
+ if (pendingAbort.signal.reason instanceof PromptDeadlineExceededError) {
8309
+ throw pendingAbort.signal.reason;
8310
+ }
7759
8311
  throw new DOMException("Prompt aborted", "AbortError");
7760
8312
  }
7761
8313
  if (pendingEntry.state === "queued") {
@@ -7799,15 +8351,23 @@ function createAcpSessionBridge(opts) {
7799
8351
  ...normalized
7800
8352
  };
7801
8353
  delete copy.retry;
8354
+ delete copy.delivery;
7802
8355
  const meta = copy._meta && typeof copy._meta === "object" ? { ...copy._meta } : {};
7803
8356
  delete meta[DAEMON_RETRY_META_KEY];
8357
+ delete meta[INVOCATION_CONTEXT_META_KEY];
8358
+ delete meta[PRIVATE_PARENT_CAPABILITY_META_KEY];
7804
8359
  delete meta[DAEMON_CONTINUE_META_KEY];
8360
+ delete meta[DAEMON_CHANNEL_DELIVERY_META_KEY];
7805
8361
  if (isRetry) {
7806
8362
  meta[DAEMON_RETRY_META_KEY] = true;
7807
8363
  }
7808
8364
  if (isContinue) {
7809
8365
  meta[DAEMON_CONTINUE_META_KEY] = true;
7810
8366
  }
8367
+ if (context?.channelDelivery) {
8368
+ meta[DAEMON_CHANNEL_DELIVERY_META_KEY] = context.channelDelivery;
8369
+ }
8370
+ meta[INVOCATION_CONTEXT_META_KEY] = invocationContext;
7811
8371
  if (Object.keys(meta).length > 0) {
7812
8372
  copy._meta = meta;
7813
8373
  } else {
@@ -7827,7 +8387,6 @@ function createAcpSessionBridge(opts) {
7827
8387
  entry.activePromptOriginatorClientId = originatorClientId;
7828
8388
  }
7829
8389
  try {
7830
- entry.cancelBroadcast = false;
7831
8390
  if (!isRetry && !isContinue) {
7832
8391
  echoPromptToSessionBus(
7833
8392
  entry,
@@ -7837,35 +8396,18 @@ function createAcpSessionBridge(opts) {
7837
8396
  );
7838
8397
  }
7839
8398
  } catch (echoErr) {
7840
- delete entry.activePromptId;
7841
- delete entry.activePromptOriginatorClientId;
7842
- if (entry.promptActive) {
7843
- entry.promptActive = false;
7844
- activePromptCounter--;
7845
- touchActivity();
7846
- }
8399
+ settleActivePromptState(entry, pendingEntry.promptId);
7847
8400
  throw echoErr;
7848
8401
  }
8402
+ pendingEntry.dispatched = true;
7849
8403
  const promptPromise = entry.connection.prompt(promptRequest).finally(() => {
7850
- if (entry.promptActive) {
7851
- entry.promptActive = false;
7852
- activePromptCounter--;
7853
- entry.sessionLastSeenAt = Date.now();
7854
- touchActivity();
7855
- }
7856
- delete entry.activePromptId;
7857
- delete entry.activePromptOriginatorClientId;
7858
- if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && byId.has(sessionId)) {
7859
- void closeSessionImpl(sessionId, void 0, {
7860
- reason: "last_client_detached"
7861
- }).catch((err) => {
7862
- writeStderrLine(
7863
- `qwen serve: deferred close-on-prompt-complete failed for ${JSON.stringify(sessionId)}: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
7864
- );
7865
- });
7866
- }
8404
+ settleActivePromptState(entry, pendingEntry.promptId);
7867
8405
  });
7868
- const racedPromise = Promise.race([
8406
+ const racedPromise = deadlinePromise ? Promise.race([
8407
+ promptPromise,
8408
+ getTransportClosedReject(entry),
8409
+ deadlinePromise
8410
+ ]) : Promise.race([
7869
8411
  promptPromise,
7870
8412
  getTransportClosedReject(entry)
7871
8413
  ]);
@@ -7873,6 +8415,9 @@ function createAcpSessionBridge(opts) {
7873
8415
  () => {
7874
8416
  },
7875
8417
  (err) => {
8418
+ if (err instanceof PromptDeadlineExceededError) {
8419
+ return;
8420
+ }
7876
8421
  if (err instanceof DOMException && err.name === "AbortError" && pendingEntry.state === "queued") {
7877
8422
  writeStderrLine(
7878
8423
  `sendPrompt: queued prompt removed before agent forward for session ${sessionId}`
@@ -7890,11 +8435,6 @@ function createAcpSessionBridge(opts) {
7890
8435
  "forward_failed"
7891
8436
  );
7892
8437
  cancelPendingForSession(sessionId);
7893
- entry.connection.cancel({ sessionId }).catch((err2) => {
7894
- writeStderrLine(
7895
- `[pending-prompt] cancel forward failed after prompt abort session=${sessionId}: ${extractErrorMessage(err2)}`
7896
- );
7897
- });
7898
8438
  }
7899
8439
  ).catch(() => {
7900
8440
  });
@@ -7907,11 +8447,15 @@ function createAcpSessionBridge(opts) {
7907
8447
  originatorClientId
7908
8448
  );
7909
8449
  cancelPendingForSession(sessionId);
7910
- entry.connection.cancel({ sessionId }).catch((err) => {
7911
- writeStderrLine(
7912
- `[pending-prompt] cancel forward failed after removePendingPrompt session=${sessionId}: ${extractErrorMessage(err)}`
7913
- );
7914
- });
8450
+ if (byId.get(sessionId) === entry) {
8451
+ void forwardRunningPromptCancel(entry, pendingEntry, {
8452
+ sessionId
8453
+ }).catch((err) => {
8454
+ writeStderrLine(
8455
+ `[pending-prompt] cancel forward failed after removePendingPrompt session=${sessionId}: ${extractErrorMessage(err)}`
8456
+ );
8457
+ });
8458
+ }
7915
8459
  }, "onAbort");
7916
8460
  if (abortSignal.aborted) {
7917
8461
  onAbort();
@@ -7935,34 +8479,35 @@ function createAcpSessionBridge(opts) {
7935
8479
  );
7936
8480
  result.then(
7937
8481
  (promptResult) => {
7938
- broadcastTurnComplete(
7939
- entry,
7940
- sessionId,
7941
- promptResult,
7942
- pendingEntry.promptId,
7943
- originatorClientId
7944
- );
8482
+ publishPromptTerminal(entry, pendingEntry, {
8483
+ kind: "complete",
8484
+ result: promptResult
8485
+ });
7945
8486
  },
7946
8487
  (err) => {
7947
- if (err instanceof DOMException && err.name === "AbortError") return;
7948
- broadcastTurnError(
7949
- entry,
7950
- sessionId,
7951
- err,
7952
- pendingEntry.promptId,
7953
- originatorClientId
7954
- );
8488
+ if (err instanceof DOMException && err.name === "AbortError") {
8489
+ publishPromptTerminal(entry, pendingEntry, { kind: "cancelled" });
8490
+ return;
8491
+ }
8492
+ publishPromptTerminal(entry, pendingEntry, { kind: "error", err });
7955
8493
  }
7956
8494
  );
8495
+ const drainCancelForwarding = /* @__PURE__ */ __name(async () => {
8496
+ try {
8497
+ await pendingEntry.cancelForwardDrain;
8498
+ } catch {
8499
+ }
8500
+ }, "drainCancelForwarding");
7957
8501
  entry.promptQueue = result.then(
7958
- () => void 0,
7959
- () => void 0
8502
+ drainCancelForwarding,
8503
+ drainCancelForwarding
7960
8504
  );
7961
8505
  result.finally(() => {
8506
+ if (deadlineTimer !== void 0) clearTimeout(deadlineTimer);
7962
8507
  const listIdx = entry.pendingPromptList.indexOf(pendingEntry);
7963
8508
  if (listIdx !== -1) {
7964
8509
  entry.pendingPromptList.splice(listIdx, 1);
7965
- if (isQueued) {
8510
+ if (isQueued && !pendingEntry.removed) {
7966
8511
  try {
7967
8512
  entry.events.publish({
7968
8513
  type: "pending_prompt_completed",
@@ -7985,6 +8530,15 @@ function createAcpSessionBridge(opts) {
7985
8530
  );
7986
8531
  entry.midTurnMessageQueue.length = 0;
7987
8532
  }
8533
+ if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && entry.pendingPromptCount === 0 && byId.get(sessionId) === entry) {
8534
+ void closeSessionImpl(sessionId, void 0, {
8535
+ reason: "last_client_detached"
8536
+ }).catch((err) => {
8537
+ writeStderrLine(
8538
+ `qwen serve: deferred close-on-prompt-complete failed for ${JSON.stringify(sessionId)}: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
8539
+ );
8540
+ });
8541
+ }
7988
8542
  }).catch(() => {
7989
8543
  });
7990
8544
  return result;
@@ -8000,10 +8554,13 @@ function createAcpSessionBridge(opts) {
8000
8554
  entry,
8001
8555
  context?.clientId
8002
8556
  );
8557
+ const runningPrompt = entry.pendingPromptList.find(
8558
+ (pending) => pending.state === "running" && !pending.terminalPublished
8559
+ );
8003
8560
  broadcastPromptCancelledOnce(
8004
8561
  entry,
8005
8562
  sessionId,
8006
- entry.activePromptId,
8563
+ entry.activePromptId ?? runningPrompt?.promptId,
8007
8564
  cancelOriginatorClientId
8008
8565
  );
8009
8566
  cancelPendingForSession(sessionId);
@@ -8016,6 +8573,17 @@ function createAcpSessionBridge(opts) {
8016
8573
  "session.id": sessionId
8017
8574
  },
8018
8575
  async () => {
8576
+ if (runningPrompt) {
8577
+ const forwarding = runningPrompt.dispatched === true && entry.activePromptId === runningPrompt.promptId ? forwardRunningPromptCancel(entry, runningPrompt, notif) : Promise.resolve();
8578
+ runningPrompt.abortController.abort(
8579
+ new DOMException(
8580
+ "Prompt cancelled before dispatch",
8581
+ "AbortError"
8582
+ )
8583
+ );
8584
+ await forwarding;
8585
+ return;
8586
+ }
8019
8587
  try {
8020
8588
  await entry.connection.cancel(notif);
8021
8589
  } catch (err) {
@@ -8062,6 +8630,11 @@ function createAcpSessionBridge(opts) {
8062
8630
  if (!entry) throw new SessionNotFoundError(sessionId);
8063
8631
  return entry.events.lastEventId;
8064
8632
  },
8633
+ getSessionEventEpoch(sessionId) {
8634
+ const entry = byId.get(sessionId);
8635
+ if (!entry) throw new SessionNotFoundError(sessionId);
8636
+ return entry.events.epoch;
8637
+ },
8065
8638
  getSessionReplaySnapshot(sessionId) {
8066
8639
  const entry = byId.get(sessionId);
8067
8640
  if (!entry) throw new SessionNotFoundError(sessionId);
@@ -8260,7 +8833,8 @@ function createAcpSessionBridge(opts) {
8260
8833
  SERVE_CONTROL_EXT_METHODS.sessionCd,
8261
8834
  {
8262
8835
  sessionId,
8263
- path: req.path
8836
+ path: req.path,
8837
+ ...req.allowedRoots ? { allowedRoots: req.allowedRoots } : {}
8264
8838
  }
8265
8839
  );
8266
8840
  const extResult = raw;
@@ -8296,6 +8870,12 @@ function createAcpSessionBridge(opts) {
8296
8870
  );
8297
8871
  return { sessionId, ...result };
8298
8872
  },
8873
+ setSessionWorktree(sessionId, worktree) {
8874
+ const entry = byId.get(sessionId);
8875
+ if (entry) {
8876
+ entry.worktree = worktree;
8877
+ }
8878
+ },
8299
8879
  async closeSession(sessionId, context, closeOpts) {
8300
8880
  return closeSessionImpl(sessionId, context, closeOpts);
8301
8881
  },
@@ -8699,33 +9279,7 @@ function createAcpSessionBridge(opts) {
8699
9279
  );
8700
9280
  },
8701
9281
  async getSessionTranscriptPage(req) {
8702
- const info = await ensureChannel();
8703
- try {
8704
- const response = await withWorkspaceControl(
8705
- info,
8706
- () => withTimeout(
8707
- Promise.race([
8708
- info.connection.extMethod(
8709
- SERVE_STATUS_EXT_METHODS.sessionTranscript,
8710
- { ...req, cwd: boundWorkspace }
8711
- ),
8712
- getChannelClosedReject(info)
8713
- ]),
8714
- Math.max(initTimeoutMs, SESSION_TRANSCRIPT_TIMEOUT_MS),
8715
- SERVE_STATUS_EXT_METHODS.sessionTranscript
8716
- )
8717
- );
8718
- return response;
8719
- } catch (err) {
8720
- if (isAcpSessionResourceNotFound(err, req.sessionId)) {
8721
- throw new SessionNotFoundError(req.sessionId);
8722
- }
8723
- throw err;
8724
- } finally {
8725
- if (hasNoChannelWork(info)) {
8726
- await startIdleTimer(info, "session transcript");
8727
- }
8728
- }
9282
+ return requestSessionTranscriptPage(req);
8729
9283
  },
8730
9284
  async cancelSessionTask(sessionId, taskId, taskKind) {
8731
9285
  return requestSessionStatus(
@@ -8757,6 +9311,7 @@ function createAcpSessionBridge(opts) {
8757
9311
  const liveEntry = byId.get(sessionId);
8758
9312
  if (!liveEntry) throw new SessionNotFoundError(sessionId);
8759
9313
  const lastEventId = liveEntry.events.lastEventId;
9314
+ const eventEpoch = liveEntry.events.epoch;
8760
9315
  const promptId = context?.promptId;
8761
9316
  const promptPromise = bridgeApi.sendPrompt(
8762
9317
  sessionId,
@@ -8776,7 +9331,8 @@ function createAcpSessionBridge(opts) {
8776
9331
  return {
8777
9332
  ...decision,
8778
9333
  ...promptId !== void 0 ? { promptId } : {},
8779
- lastEventId
9334
+ lastEventId,
9335
+ eventEpoch
8780
9336
  };
8781
9337
  },
8782
9338
  async getSessionStatsStatus(sessionId) {
@@ -9093,7 +9649,7 @@ function createAcpSessionBridge(opts) {
9093
9649
  const entry = byId.get(sessionId);
9094
9650
  if (!entry) throw new SessionNotFoundError(sessionId);
9095
9651
  resolveTrustedClientId(entry, context?.clientId);
9096
- return entry.pendingPromptList.map((p) => ({
9652
+ return entry.pendingPromptList.filter((p) => !p.removed).map((p) => ({
9097
9653
  promptId: p.promptId,
9098
9654
  text: p.text,
9099
9655
  queuedAt: p.queuedAt,
@@ -9110,13 +9666,18 @@ function createAcpSessionBridge(opts) {
9110
9666
  );
9111
9667
  if (idx === -1) return { removed: false };
9112
9668
  const target = entry.pendingPromptList[idx];
9669
+ if (target.removed) return { removed: false };
9113
9670
  writeStderrLine(
9114
9671
  `[pending-prompt] session=${sessionId} removing promptId=${promptId} state=${target.state}`
9115
9672
  );
9116
9673
  target.abortController.abort(
9117
9674
  new DOMException("Prompt removed by user", "AbortError")
9118
9675
  );
9119
- entry.pendingPromptList.splice(idx, 1);
9676
+ if (target.state === "queued") {
9677
+ entry.pendingPromptList.splice(idx, 1);
9678
+ } else {
9679
+ target.removed = true;
9680
+ }
9120
9681
  try {
9121
9682
  entry.events.publish({
9122
9683
  type: "pending_prompt_completed",
@@ -9126,6 +9687,9 @@ function createAcpSessionBridge(opts) {
9126
9687
  });
9127
9688
  } catch {
9128
9689
  }
9690
+ if (target.state === "queued") {
9691
+ publishPromptTerminal(entry, target, { kind: "cancelled" });
9692
+ }
9129
9693
  return { removed: true };
9130
9694
  },
9131
9695
  enqueueMidTurnMessage(sessionId, message, context) {
@@ -9373,6 +9937,9 @@ function createAcpSessionBridge(opts) {
9373
9937
  async rewindSession(sessionId, req, context) {
9374
9938
  const entry = byId.get(sessionId);
9375
9939
  if (!entry) throw new SessionNotFoundError(sessionId);
9940
+ if (entry.closing) {
9941
+ throw new SessionNotFoundError(sessionId, "The session is closing");
9942
+ }
9376
9943
  const info = channelInfoForEntry(entry);
9377
9944
  if (!info || info.isDying) throw new SessionNotFoundError(sessionId);
9378
9945
  const originatorClientId = resolveTrustedClientId(
@@ -9564,7 +10131,7 @@ function createAcpSessionBridge(opts) {
9564
10131
  }
9565
10132
  }
9566
10133
  },
9567
- async reloadWorkspaceMcp() {
10134
+ async reloadWorkspaceMcp(options) {
9568
10135
  const info = await ensureChannel();
9569
10136
  info.workspaceMcpDiscoveryRequested = true;
9570
10137
  try {
@@ -9572,7 +10139,7 @@ function createAcpSessionBridge(opts) {
9572
10139
  withTimeout(
9573
10140
  info.connection.extMethod(
9574
10141
  SERVE_CONTROL_EXT_METHODS.workspaceMcpReload,
9575
- { cwd: boundWorkspace }
10142
+ { cwd: boundWorkspace, ...options }
9576
10143
  ),
9577
10144
  initTimeoutMs,
9578
10145
  SERVE_CONTROL_EXT_METHODS.workspaceMcpReload
@@ -9606,6 +10173,85 @@ function createAcpSessionBridge(opts) {
9606
10173
  getChannelClosedReject(info)
9607
10174
  ]);
9608
10175
  },
10176
+ generateWorkspaceContent(prompt, signal, _originatorClientId) {
10177
+ const requestId = randomUUID2();
10178
+ const queue = new GenerationStreamQueue(
10179
+ GENERATION_STREAM_QUEUE_CAPACITY
10180
+ );
10181
+ const request = {
10182
+ connection: void 0,
10183
+ queue,
10184
+ settled: false
10185
+ };
10186
+ const cancel = /* @__PURE__ */ __name(() => {
10187
+ if (request.settled) return;
10188
+ request.settled = true;
10189
+ workspaceGenerationRequests.delete(requestId);
10190
+ queue.close();
10191
+ void request.connection?.extMethod(SERVE_CONTROL_EXT_METHODS.workspaceGenerationCancel, {
10192
+ requestId
10193
+ }).catch(() => void 0);
10194
+ }, "cancel");
10195
+ signal.addEventListener("abort", cancel, { once: true });
10196
+ if (signal.aborted) {
10197
+ cancel();
10198
+ return queue;
10199
+ }
10200
+ void (async () => {
10201
+ let info;
10202
+ try {
10203
+ const channelInfo2 = await ensureChannel();
10204
+ info = channelInfo2;
10205
+ request.connection = channelInfo2.connection;
10206
+ await withWorkspaceControl(channelInfo2, async () => {
10207
+ if (request.settled) return;
10208
+ workspaceGenerationRequests.set(requestId, request);
10209
+ const raw = await Promise.race([
10210
+ withTimeout(
10211
+ channelInfo2.connection.extMethod(
10212
+ SERVE_CONTROL_EXT_METHODS.workspaceGenerationStart,
10213
+ {
10214
+ requestId,
10215
+ prompt,
10216
+ purpose: "text"
10217
+ }
10218
+ ),
10219
+ SESSION_GENERATION_TIMEOUT_MS,
10220
+ SERVE_CONTROL_EXT_METHODS.workspaceGenerationStart
10221
+ ),
10222
+ getChannelClosedReject(channelInfo2)
10223
+ ]);
10224
+ if (request.settled) return;
10225
+ const response = raw;
10226
+ const model = response["model"];
10227
+ const modelSource = response["modelSource"];
10228
+ if (typeof model !== "string" || modelSource !== "fast" && modelSource !== "main") {
10229
+ throw new Error("Malformed workspace generation completion");
10230
+ }
10231
+ const accepted = queue.push({
10232
+ type: "done",
10233
+ requestId,
10234
+ model,
10235
+ modelSource,
10236
+ ...typeof response["inputTokens"] === "number" ? { inputTokens: response["inputTokens"] } : {},
10237
+ ...typeof response["outputTokens"] === "number" ? { outputTokens: response["outputTokens"] } : {}
10238
+ });
10239
+ if (accepted) queue.close();
10240
+ else queue.fail(new Error("Generation stream consumer too slow"));
10241
+ });
10242
+ } catch (error) {
10243
+ if (!request.settled) queue.fail(error);
10244
+ } finally {
10245
+ request.settled = true;
10246
+ signal.removeEventListener("abort", cancel);
10247
+ workspaceGenerationRequests.delete(requestId);
10248
+ if (info && hasNoChannelWork(info) && !info.isDying) {
10249
+ await startIdleTimer(info, "workspace generation");
10250
+ }
10251
+ }
10252
+ })().catch(() => void 0);
10253
+ return queue;
10254
+ },
9609
10255
  async addRuntimeMcpServer(name, config, originatorClientId) {
9610
10256
  const info = liveChannelInfo();
9611
10257
  if (!info) {
@@ -9684,9 +10330,41 @@ function createAcpSessionBridge(opts) {
9684
10330
  entry.spawnOwnerWantedKill = true;
9685
10331
  return false;
9686
10332
  }
10333
+ if (entry.closing) {
10334
+ const closingChannel = channelInfoForEntry(entry);
10335
+ if (!closingChannel) return false;
10336
+ await killChannelWithLog(
10337
+ closingChannel,
10338
+ `force kill closing session ${JSON.stringify(sessionId)}`
10339
+ );
10340
+ return true;
10341
+ }
10342
+ entry.closing = true;
10343
+ const ci = channelInfoForEntry(entry);
10344
+ if (!ci) {
10345
+ writeStderrLine(
10346
+ `qwen serve: killSession channelInfoForEntry returned undefined for session ${JSON.stringify(sessionId)} \u2014 channel cleanup skipped (entry's channel already torn down)`
10347
+ );
10348
+ }
9687
10349
  permissionMediator.forgetSession(sessionId);
9688
10350
  entry.pendingPermissionIds.clear();
9689
10351
  entry.pendingInteractions.clear();
10352
+ try {
10353
+ await notifyAgentSessionClose(entry, ci, "killSession", {
10354
+ throwOnFailure: true,
10355
+ timeoutMs: initTimeoutMs
10356
+ });
10357
+ } catch (error) {
10358
+ if (ci) {
10359
+ await killChannelWithLog(
10360
+ ci,
10361
+ `force kill session ${JSON.stringify(sessionId)}`
10362
+ );
10363
+ return true;
10364
+ }
10365
+ entry.closing = false;
10366
+ throw error;
10367
+ }
9690
10368
  if (entry.promptActive) {
9691
10369
  entry.promptActive = false;
9692
10370
  activePromptCounter--;
@@ -9701,17 +10379,15 @@ function createAcpSessionBridge(opts) {
9701
10379
  workspaceCwd: entry.workspaceCwd,
9702
10380
  reason: "killed"
9703
10381
  });
9704
- const ci = channelInfoForEntry(entry);
9705
- if (!ci) {
9706
- writeStderrLine(
9707
- `qwen serve: killSession channelInfoForEntry returned undefined for session ${JSON.stringify(sessionId)} \u2014 channel cleanup skipped (entry's channel already torn down)`
9708
- );
9709
- }
9710
10382
  if (ci && ci.channel === entry.channel) {
9711
10383
  ci.sessionIds.delete(sessionId);
9712
10384
  }
9713
- await notifyAgentSessionClose(entry, ci, "killSession");
9714
10385
  ci?.client.markSessionClosed(sessionId);
10386
+ flushPromptTerminals(
10387
+ entry,
10388
+ "session_killed",
10389
+ "session killed before the prompt completed"
10390
+ );
9715
10391
  try {
9716
10392
  entry.events.publish({
9717
10393
  type: "session_died",
@@ -9731,12 +10407,14 @@ function createAcpSessionBridge(opts) {
9731
10407
  async detachClient(sessionId, clientId) {
9732
10408
  const entry = byId.get(sessionId);
9733
10409
  if (!entry) return;
9734
- if (entry.attachCount > 0) entry.attachCount--;
10410
+ if (clientId !== void 0 && releaseAttachRef(entry, clientId)) {
10411
+ if (entry.attachCount > 0) entry.attachCount--;
10412
+ }
9735
10413
  unregisterClient(entry, clientId);
9736
10414
  if (entry.spawnOwnerWantedKill && entry.attachCount === 0 && entry.events.subscriberCount === 0) {
9737
10415
  await this.killSession(sessionId).catch(() => {
9738
10416
  });
9739
- } else if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && !entry.promptActive) {
10417
+ } else if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && entry.pendingPromptCount === 0) {
9740
10418
  await closeSessionImpl(sessionId, void 0, {
9741
10419
  reason: "last_client_detached"
9742
10420
  }).catch((err) => {
@@ -9800,6 +10478,11 @@ function createAcpSessionBridge(opts) {
9800
10478
  workspaceCwd: e.workspaceCwd,
9801
10479
  reason: shutdownReason
9802
10480
  });
10481
+ flushPromptTerminals(
10482
+ e,
10483
+ "daemon_shutdown",
10484
+ "daemon shut down before the prompt completed"
10485
+ );
9803
10486
  try {
9804
10487
  e.events.publish({
9805
10488
  type: "session_died",