@qwen-code/qwen-code 0.23.1-preview.2 → 0.23.2-preview.0

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 (297) hide show
  1. package/bundled/computer-use/SKILL.md +189 -116
  2. package/bundled/goal-draft/SKILL.md +23 -13
  3. package/bundled/qc-helper/docs/_meta.ts +1 -0
  4. package/bundled/qc-helper/docs/configuration/model-providers.md +47 -1
  5. package/bundled/qc-helper/docs/configuration/settings.md +50 -0
  6. package/bundled/qc-helper/docs/conversations-recovery.md +102 -0
  7. package/bundled/qc-helper/docs/features/channels/overview.md +1 -1
  8. package/bundled/qc-helper/docs/features/computer-use.md +9 -7
  9. package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
  10. package/bundled/qc-helper/docs/features/goals.md +15 -3
  11. package/bundled/qc-helper/docs/qwen-serve.md +19 -1
  12. package/chunks/{MaxSizedBox-IYIQ43IZ.js → MaxSizedBox-ZZJT3PJF.js} +20 -20
  13. package/chunks/{StandaloneSessionPicker-AWB2OHX6.js → StandaloneSessionPicker-DIOSZTMX.js} +38 -38
  14. package/chunks/{acp-startup-profiler-BAL4LJTN.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
  15. package/chunks/{acpAgent-ZC57OLS4.js → acpAgent-62JUP5A7.js} +118 -91
  16. package/chunks/{agent-GEBPAEJS.js → agent-NLPEQQDZ.js} +13 -13
  17. package/chunks/{agent-headless-63ZEYAJK.js → agent-headless-Y2GR5F2Q.js} +13 -13
  18. package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-I7LQZH26.js} +30 -7
  19. package/chunks/{askUserQuestion-3KAYLLMM.js → askUserQuestion-I5W5S3D6.js} +1 -1
  20. package/chunks/{bridge-MHWO5I5T.js → bridge-Q66BD62H.js} +23 -23
  21. package/chunks/{channel-management-service-NFRZXQFO.js → channel-management-service-TRTLQTSV.js} +4 -4
  22. package/chunks/{channel-settings-store-T7PMIHKC.js → channel-settings-store-R5STFWUW.js} +31 -31
  23. package/chunks/{channel-worker-group-O2BWK5F7.js → channel-worker-group-PIYPVCTF.js} +6 -6
  24. package/chunks/{channel-worker-manager-4WP7VJOD.js → channel-worker-manager-FQHEDTD2.js} +6 -6
  25. package/chunks/{channel-worker-supervisor-CCUXD6J5.js → channel-worker-supervisor-XJPZZ3VK.js} +3 -3
  26. package/chunks/{chunk-ZJ2LM2SI.js → chunk-2OR32P5M.js} +104 -33
  27. package/chunks/chunk-2Z3T52OC.js +82 -0
  28. package/chunks/{chunk-5FYGZ7E3.js → chunk-33MLFMCL.js} +2 -2
  29. package/chunks/{chunk-RH344FKI.js → chunk-3BTHHXXE.js} +1 -1
  30. package/chunks/{chunk-OFB36ZBA.js → chunk-3LPJ776W.js} +1 -1
  31. package/chunks/{chunk-TSLRORQR.js → chunk-43CI6YWJ.js} +1467 -1323
  32. package/chunks/{chunk-LTCI6ZOJ.js → chunk-45ROPFQY.js} +1 -1
  33. package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
  34. package/chunks/{chunk-RRCNEW2A.js → chunk-4BLTSTF6.js} +58 -4
  35. package/chunks/{chunk-3RMVM33U.js → chunk-4JKLPTV6.js} +5 -5
  36. package/chunks/{chunk-ZRVFHLLK.js → chunk-5DQ4YTIZ.js} +1 -1
  37. package/chunks/{chunk-AWDF462I.js → chunk-5GD7LYOH.js} +2 -2
  38. package/chunks/{chunk-HZS3JRQW.js → chunk-5VZFJTL2.js} +40 -2
  39. package/chunks/{chunk-537SQ2AI.js → chunk-5WC2ECUK.js} +104 -16
  40. package/chunks/{chunk-ZT3XUGSU.js → chunk-63ACHB2H.js} +86 -9
  41. package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
  42. package/chunks/{chunk-REDVV5NC.js → chunk-6GRDHIVI.js} +7 -7
  43. package/chunks/{chunk-2LD5U7Q3.js → chunk-6YEOCHSE.js} +29 -1
  44. package/chunks/{chunk-C4NXRR7T.js → chunk-743XE7N7.js} +2 -2
  45. package/chunks/{chunk-I7UNCY24.js → chunk-7GZCCHJL.js} +3 -3
  46. package/chunks/{chunk-XX4MBBFW.js → chunk-7L35FKPF.js} +3 -3
  47. package/chunks/{chunk-GEV66YGE.js → chunk-7RXOEUFF.js} +1 -1
  48. package/chunks/{chunk-TXAEXF2B.js → chunk-BL6B2QS2.js} +21 -8
  49. package/chunks/{chunk-KAZWXVI3.js → chunk-CABDNUJ4.js} +2 -2
  50. package/chunks/{chunk-R7TKFIQO.js → chunk-CALNF3Z3.js} +1 -1
  51. package/chunks/{chunk-22QOQKG4.js → chunk-CG2PDIGD.js} +1 -1
  52. package/chunks/{chunk-MFCWL4LI.js → chunk-CPJRFFPH.js} +451 -396
  53. package/chunks/{chunk-LD53HMPV.js → chunk-CRZBDVP2.js} +1 -0
  54. package/chunks/{chunk-RSU3I6UL.js → chunk-DCPRCDSR.js} +1 -1
  55. package/chunks/{chunk-PLUAIHZO.js → chunk-DTB5BXRG.js} +6 -6
  56. package/chunks/{chunk-FWH4736Q.js → chunk-EA4NFWVG.js} +3 -3
  57. package/chunks/{chunk-AX23QSX3.js → chunk-EHTKOO6W.js} +4 -4
  58. package/chunks/{chunk-37SOBIA3.js → chunk-ERXNTINK.js} +1 -1
  59. package/chunks/{chunk-EGRFCIXD.js → chunk-EUXF6URV.js} +79 -18
  60. package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
  61. package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
  62. package/chunks/{chunk-C7M445SS.js → chunk-G5QLLD53.js} +1 -1
  63. package/chunks/{chunk-5V4B3EWA.js → chunk-GM44O6F7.js} +1 -1
  64. package/chunks/{chunk-Z6DDPSGJ.js → chunk-GNY7B3CA.js} +1 -1
  65. package/chunks/{chunk-7PMKXGRP.js → chunk-GXIHBIHC.js} +66 -9
  66. package/chunks/{chunk-ERMAXPXA.js → chunk-HIXUUCGY.js} +187 -12
  67. package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
  68. package/chunks/{chunk-RCUWMVN3.js → chunk-HZ2HUXX7.js} +1 -1
  69. package/chunks/{chunk-SHX2HIE7.js → chunk-ISPBBKJN.js} +1 -1
  70. package/chunks/{chunk-QQGAR64U.js → chunk-IUJLW6ZI.js} +4 -4
  71. package/chunks/{chunk-IMWCUWQT.js → chunk-J3TJH52D.js} +1 -1
  72. package/chunks/{chunk-AIMZIXZM.js → chunk-J4ECGDA3.js} +5 -7
  73. package/chunks/{chunk-HPE4LEWX.js → chunk-JDPBJIKI.js} +1 -1
  74. package/chunks/{chunk-Y3C5COGI.js → chunk-L6ZME3W7.js} +1 -1
  75. package/chunks/{chunk-EPZWBYQI.js → chunk-LBKYQ33T.js} +8 -6
  76. package/chunks/{chunk-KTLT7VCX.js → chunk-LN3WBOKU.js} +2 -2
  77. package/chunks/{chunk-FXYNIZPW.js → chunk-LUVXLLMS.js} +51 -10
  78. package/chunks/{chunk-RQNAO42A.js → chunk-M6YLOETP.js} +1 -1
  79. package/chunks/{chunk-6KYWU726.js → chunk-M73KHGNR.js} +13 -66
  80. package/chunks/{chunk-ADJD4LZF.js → chunk-MA5OUNN6.js} +1 -1
  81. package/chunks/{chunk-SI6Q52UI.js → chunk-MMMA36MN.js} +3 -3
  82. package/chunks/{chunk-QW7BUOSI.js → chunk-MWEF5MUK.js} +20 -3
  83. package/chunks/{chunk-JOV46WGX.js → chunk-NB3NDQQK.js} +1 -1
  84. package/chunks/chunk-NOO4QFXM.js +171 -0
  85. package/chunks/{chunk-UTVIIA7N.js → chunk-NVS4Z6GT.js} +1 -1
  86. package/chunks/{chunk-VMFPZXRT.js → chunk-ODBNTMZW.js} +43 -31
  87. package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
  88. package/chunks/{chunk-WQBR7LN5.js → chunk-OIPUQE3S.js} +1 -1
  89. package/chunks/{chunk-2C3XDBGL.js → chunk-ORREXWOM.js} +4 -4
  90. package/chunks/{chunk-RD3VPM4E.js → chunk-PQWM4SX2.js} +2 -2
  91. package/chunks/{chunk-Z6KFLEG7.js → chunk-PSPAM24S.js} +1 -0
  92. package/chunks/{chunk-RUMSY4ES.js → chunk-Q2F43WTJ.js} +8 -7
  93. package/chunks/{chunk-VYCJITND.js → chunk-QJAFSFYA.js} +1 -1
  94. package/chunks/{chunk-L36LLVA5.js → chunk-QLM7D7W3.js} +3 -3
  95. package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
  96. package/chunks/{chunk-XNC2TCUO.js → chunk-QXXBW2G4.js} +4 -4
  97. package/chunks/{chunk-TDHVOZ65.js → chunk-R2266LQ5.js} +2 -2
  98. package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
  99. package/chunks/{chunk-LYHYXJJ3.js → chunk-RDV4NLI3.js} +3 -3
  100. package/chunks/{chunk-733KQL63.js → chunk-RN6V5HKE.js} +3 -3
  101. package/chunks/{chunk-WLZRMF3C.js → chunk-RX3FYFCN.js} +353 -11
  102. package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
  103. package/chunks/{chunk-ZNI3V2XA.js → chunk-TK4XHPKW.js} +2 -2
  104. package/chunks/{chunk-RGAQDQ3Z.js → chunk-UHUT4IDM.js} +18 -9
  105. package/chunks/{chunk-T7TP5UQL.js → chunk-ULY4ISY2.js} +4 -4
  106. package/chunks/{chunk-PMGWY6ZP.js → chunk-UULHYZ4W.js} +13 -10
  107. package/chunks/{chunk-BNWIX6BM.js → chunk-UXDVUFKU.js} +3 -3
  108. package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
  109. package/chunks/{chunk-YLFICBYK.js → chunk-VEQBVJYH.js} +3 -3
  110. package/chunks/{chunk-3K456UJF.js → chunk-VF6D6EGV.js} +12 -4
  111. package/chunks/{chunk-KP5QK3FB.js → chunk-VH764G6B.js} +397 -54
  112. package/chunks/{chunk-IGOIYZBG.js → chunk-VHPG7BH6.js} +2 -2
  113. package/chunks/{chunk-I67KJGM6.js → chunk-W3ONSAYO.js} +3 -3
  114. package/chunks/{chunk-SHK2SIR5.js → chunk-W673V2H3.js} +4 -4
  115. package/chunks/{chunk-C55CR5I4.js → chunk-W7PXLIZJ.js} +6 -6
  116. package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
  117. package/chunks/{chunk-B5FF3LRF.js → chunk-WIRYFL2L.js} +22 -15
  118. package/chunks/{chunk-P5Z7VD23.js → chunk-WZ4YULVF.js} +106 -39
  119. package/chunks/{chunk-WFXD5OZH.js → chunk-WZS3X663.js} +1 -1
  120. package/chunks/{chunk-HWZOOSEB.js → chunk-XAXTQURR.js} +3 -3
  121. package/chunks/{chunk-ANVC5CSK.js → chunk-XBLG564H.js} +10 -10
  122. package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
  123. package/chunks/{chunk-SD7Y2PMC.js → chunk-XI7RST4D.js} +2 -2
  124. package/chunks/{chunk-65GHQ4FX.js → chunk-XVTCSVBK.js} +514 -47
  125. package/chunks/{chunk-4OCYWXKF.js → chunk-Y6ZWXM44.js} +3 -3
  126. package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
  127. package/chunks/{chunk-E4VX6LXB.js → chunk-YZTGGCEE.js} +10 -2
  128. package/chunks/{chunk-75UQFGFE.js → chunk-ZIPYCXQP.js} +1 -1
  129. package/chunks/{chunk-AUJOWIT5.js → chunk-ZUNWKOAP.js} +3 -3
  130. package/chunks/{config-utils-F4CFJ4MW.js → config-utils-37FHWPTP.js} +24 -24
  131. package/chunks/{contextCommand-OIIGGOMU.js → contextCommand-R4JUBV5N.js} +22 -22
  132. package/chunks/{core-runtime-JEHLOGMB.js → core-runtime-6U4OXU5C.js} +20 -20
  133. package/chunks/{create-sub-session-MVFBE5RA.js → create-sub-session-LLUYAGZN.js} +21 -21
  134. package/chunks/{daemon-LCUELM6E.js → daemon-UI6SQSBV.js} +1 -1
  135. package/chunks/{daemon-git-worktree-guard-5FTKLJOU.js → daemon-git-worktree-guard-O2UTNFJC.js} +20 -20
  136. package/chunks/{daemon-status-provider-P6A5MPMW.js → daemon-status-provider-7GMAKSTX.js} +27 -27
  137. package/chunks/{daemon-trust-policy-ZJ3NFYUO.js → daemon-trust-policy-VNP76VMO.js} +27 -27
  138. package/chunks/{daemon-trust-policy-monitor-6SDLEW7S.js → daemon-trust-policy-monitor-TD5O3BZA.js} +27 -27
  139. package/chunks/{deferred-core-runtime-DWOXIU5S.js → deferred-core-runtime-NJM63YJS.js} +20 -20
  140. package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
  141. package/chunks/{dist-NXW4DUUX.js → dist-24TCWK5H.js} +1 -1
  142. package/chunks/{dist-I74QLLQS.js → dist-5I4HLUTO.js} +1 -1
  143. package/chunks/{dist-XINEKB5A.js → dist-FDISN4AK.js} +1 -1
  144. package/chunks/{dist-VCAS67N5.js → dist-M4CBX53H.js} +1 -1
  145. package/chunks/{dist-AI25RVRA.js → dist-NQ2636VT.js} +1 -1
  146. package/chunks/{dist-3H3WODVS.js → dist-OR2ZQTXZ.js} +1 -1
  147. package/chunks/{dist-P6YWBITG.js → dist-STAGIFNB.js} +430 -51
  148. package/chunks/{dist-YNQU4CKC.js → dist-WZTUKIDR.js} +2 -2
  149. package/chunks/{dist-T4PRA5EZ.js → dist-XJ25G6OH.js} +1 -1
  150. package/chunks/{edit-WPVXLL3T.js → edit-GL7OA6RV.js} +13 -13
  151. package/chunks/{enter-worktree-5A6VW6BN.js → enter-worktree-YFTKHXHZ.js} +2 -2
  152. package/chunks/{enterPlanMode-JSODW7E2.js → enterPlanMode-VC4BCSZE.js} +13 -13
  153. package/chunks/{environment-5LLJ3I3W.js → environment-BI6IBAZJ.js} +23 -23
  154. package/chunks/{errors-IQT3YZEP.js → errors-D6G2ZM2R.js} +22 -22
  155. package/chunks/{exit-worktree-QV7E7KP6.js → exit-worktree-NF2XEMES.js} +3 -3
  156. package/chunks/{exitPlanMode-DDVFYNW4.js → exitPlanMode-DX446CA6.js} +13 -13
  157. package/chunks/{fast-path-PAUQQEVU.js → fast-path-MAYDLJIP.js} +3 -3
  158. package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
  159. package/chunks/{glob-SQ7CTZ7F.js → glob-TVKRFY36.js} +13 -13
  160. package/chunks/{goal-tools-UWZRCLQB.js → goal-tools-CA6YANRN.js} +13 -13
  161. package/chunks/{handleAutoUpdate-RUPZZTSG.js → handleAutoUpdate-AW4ZAHON.js} +23 -23
  162. package/chunks/{i18n-SF5MPWEB.js → i18n-IH5CRAY7.js} +23 -21
  163. package/chunks/{image-gen-Q3RUTVKR.js → image-gen-XP4NNIYG.js} +4 -4
  164. package/chunks/{initializer-CK4WPYZG.js → initializer-UBR37ZNM.js} +27 -27
  165. package/chunks/{installationInfo-IRPQEYRF.js → installationInfo-Y52756EC.js} +20 -20
  166. package/chunks/{list-E3PS3EBJ.js → list-7V5JDZPO.js} +30 -30
  167. package/chunks/{llm-JQKBOYAF.js → llm-QDB6JVF5.js} +62 -62
  168. package/chunks/{llm-content-generator-2QWGBW42.js → llm-content-generator-EO6MZCEO.js} +23 -8
  169. package/chunks/{loadedSettingsAdapter-DGXGVYZS.js → loadedSettingsAdapter-I3YQKMC4.js} +27 -27
  170. package/chunks/{loggingContentGenerator-ZYURLJKK.js → loggingContentGenerator-MNXYUGDG.js} +14 -14
  171. package/chunks/{managed-npm-update-HTHR63EA.js → managed-npm-update-EA3EXPTO.js} +20 -20
  172. package/chunks/{mcp-I7G2AEWS.js → mcp-QTAJ544Y.js} +27 -27
  173. package/chunks/{monitor-4R76BCRZ.js → monitor-6FQKQOTP.js} +13 -13
  174. package/chunks/{nonInteractiveCli-24OQ3VP2.js → nonInteractiveCli-MRCTZL5X.js} +64 -61
  175. package/chunks/{notebook-edit-PPSH7FEX.js → notebook-edit-BQQCKI7K.js} +13 -13
  176. package/chunks/{openaiContentGenerator-K7V5EO7F.js → openaiContentGenerator-TTSKXNVH.js} +8 -8
  177. package/chunks/{pidfile-TGIUY2GG.js → pidfile-KPIS6RIT.js} +20 -20
  178. package/chunks/{processUtils-3USXUQWX.js → processUtils-ZCASPKK4.js} +2 -2
  179. package/chunks/{prompt-terminal-ledger-XHVZRXJI.js → prompt-terminal-ledger-D6HM6TV7.js} +21 -21
  180. package/chunks/{qwenContentGenerator-MPBOQB64.js → qwenContentGenerator-GGZEFLBD.js} +16 -16
  181. package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
  182. package/chunks/{read-file-R256LDWQ.js → read-file-VE5GDFLP.js} +2 -2
  183. package/chunks/{resumeHistoryUtils-S43LTFHD.js → resumeHistoryUtils-HSSGMYDC.js} +23 -23
  184. package/chunks/{ripGrep-L7HPZ75Y.js → ripGrep-SEJE7AA6.js} +3 -3
  185. package/chunks/{run-qwen-serve-CTFL5R6U.js → run-qwen-serve-OJYVH7N6.js} +58 -60
  186. package/chunks/{runtime-FS5TL6P7.js → runtime-KGMQQFJD.js} +32 -32
  187. package/chunks/{scheduled-tasks-QXPV3Q35.js → scheduled-tasks-7H5HWHYD.js} +25 -25
  188. package/chunks/{scheduler-EXU5HMVK.js → scheduler-BE42AKDG.js} +22 -22
  189. package/chunks/{send-message-GQKXGMPI.js → send-message-AWKUDJBH.js} +1 -1
  190. package/chunks/{serve-ITJC7WNN.js → serve-KZVKYMSL.js} +27 -27
  191. package/chunks/{server-6JQY3PTU.js → server-PJRALPJQ.js} +1296 -822
  192. package/chunks/{session-PJDEKXD4.js → session-IHITXU2S.js} +63 -62
  193. package/chunks/{session-attachments-root-L37ORSST.js → session-attachments-root-GQ2TUI3Y.js} +20 -20
  194. package/chunks/{session-pr-refresh-WIFD52YL.js → session-pr-refresh-H43LULTE.js} +24 -24
  195. package/chunks/{settings-LO6J5SAZ.js → settings-RKEQQDFC.js} +26 -26
  196. package/chunks/{shell-ANAFVYGR.js → shell-6PJ444U5.js} +13 -13
  197. package/chunks/{skill-SHJWKSPH.js → skill-Q3UP7B5V.js} +2 -2
  198. package/chunks/{skill-settings-GX3XHZ5Q.js → skill-settings-LZR5YRRW.js} +26 -26
  199. package/chunks/{spawnChannel-WE42VBKM.js → spawnChannel-WM3DT2BF.js} +20 -20
  200. package/chunks/{standalone-update-CWDIKJRP.js → standalone-update-E5474IBI.js} +22 -22
  201. package/chunks/{start-opentui-ui-BBHGFOTF.js → start-opentui-ui-WLWZNQ2I.js} +1991 -986
  202. package/chunks/{startInteractiveUI-FQX7LUYP.js → startInteractiveUI-FBQSGWGO.js} +1119 -1478
  203. package/chunks/{team-create-WKTPCH6D.js → team-create-VIGUFUT4.js} +13 -13
  204. package/chunks/{team-plan-approval-Y23DL7WR.js → team-plan-approval-HQVZA3MD.js} +13 -13
  205. package/chunks/{terminal-image-renderer-B646HBDW.js → terminal-image-renderer-LUKNCOVM.js} +20 -20
  206. package/chunks/{theme-manager-BNWESY26.js → theme-manager-LOENKYLY.js} +20 -20
  207. package/chunks/{tool-search-PVQ5O5Y2.js → tool-search-ZIFAQCE2.js} +2 -2
  208. package/chunks/{total-session-admission-P5Z43KNW.js → total-session-admission-FUUJH3QH.js} +24 -24
  209. package/chunks/{trustedFolders-FH2LT2MZ.js → trustedFolders-C76KYROP.js} +21 -21
  210. package/chunks/{update-relaunch-WOWTKJSN.js → update-relaunch-4G2SRXKX.js} +5 -5
  211. package/chunks/{updateCheck-3MYFMM35.js → updateCheck-EIZIO7HI.js} +22 -22
  212. package/chunks/{useAutoAcceptIndicator-Q7ZRRRKO.js → useAutoAcceptIndicator-EAA6KSY4.js} +29 -29
  213. package/chunks/{validateNonInterActiveAuth-MYEWJX3G.js → validateNonInterActiveAuth-BRX22QCN.js} +59 -58
  214. package/chunks/{version-RO2FPO76.js → version-E56RU7PR.js} +1 -1
  215. package/chunks/{web-fetch-QAKY2LUA.js → web-fetch-AAUCD7RM.js} +5 -5
  216. package/chunks/{web-search-XA5Z4ZCD.js → web-search-HFUQF44Q.js} +18 -7
  217. package/chunks/{workflow-QFIOCMDM.js → workflow-3MABM53N.js} +15 -15
  218. package/chunks/{workspace-providers-status-B2UD7RAG.js → workspace-providers-status-2FRLBZ5I.js} +29 -29
  219. package/chunks/{workspace-registration-store-VZLRTI3Q.js → workspace-registration-store-YL7HLYYI.js} +1 -1
  220. package/chunks/{workspace-registry-GYOGG6TM.js → workspace-registry-BNRP2ELW.js} +24 -24
  221. package/chunks/{workspace-runtime-coordinator-7KRXGQ4V.js → workspace-runtime-coordinator-WKGF7VHS.js} +24 -24
  222. package/chunks/{workspace-service-DJEYGJE4.js → workspace-service-4MYO72MM.js} +31 -31
  223. package/chunks/{workspace-skills-status-MOKNESUC.js → workspace-skills-status-SU66TJLZ.js} +27 -27
  224. package/chunks/{workspace-trust-reconciler-AXOSUTQW.js → workspace-trust-reconciler-D5QT7WQB.js} +31 -31
  225. package/chunks/{write-file-QOYVHAKK.js → write-file-NVPQE2AZ.js} +14 -14
  226. package/chunks/{zoom-image-UCCLGFNC.js → zoom-image-RJHC66WG.js} +2 -2
  227. package/cli.js +13 -13
  228. package/export-transcript-document.js +126 -122
  229. package/package.json +3 -3
  230. package/web-shell/assets/{abnfDiagram-VCTEODGH-CTstZpXw.js → abnfDiagram-VCTEODGH-DHc6plZn.js} +1 -1
  231. package/web-shell/assets/{arc-DKW0mbPo.js → arc-BQ9m8TDV.js} +1 -1
  232. package/web-shell/assets/{architectureDiagram-5GKGNRK7-DkMpJ42t.js → architectureDiagram-5GKGNRK7-D5ap3oVB.js} +1 -1
  233. package/web-shell/assets/{blockDiagram-NRAW4CY4-7Cp1_4i3.js → blockDiagram-NRAW4CY4-BIbnyNph.js} +1 -1
  234. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BfaoSlBK.js → c4Diagram-UCG6FXSJ-BRsdx_iG.js} +1 -1
  235. package/web-shell/assets/channel-uMMdTrYk.js +1 -0
  236. package/web-shell/assets/{chunk-2Q5K7J3B-_n1qzAio.js → chunk-2Q5K7J3B-3lf1fNlx.js} +1 -1
  237. package/web-shell/assets/{chunk-5VM5RSS4-0cira5ZV.js → chunk-5VM5RSS4-DP8VNRc4.js} +1 -1
  238. package/web-shell/assets/{chunk-F27PBJKO-DseRXSHC.js → chunk-F27PBJKO-DrohDmZ6.js} +1 -1
  239. package/web-shell/assets/{chunk-G27WJ6UU-BehQWin0.js → chunk-G27WJ6UU-UZ2QhSx6.js} +1 -1
  240. package/web-shell/assets/{chunk-JWPE2WC7-B5ftg1Bb.js → chunk-JWPE2WC7-BIMHVcZK.js} +1 -1
  241. package/web-shell/assets/{chunk-LCL6LL3I-D7rnbVdk.js → chunk-LCL6LL3I-izRxdSDd.js} +1 -1
  242. package/web-shell/assets/{chunk-POPQ4Y6H-2Bp-Orju.js → chunk-POPQ4Y6H-CXADD4PP.js} +1 -1
  243. package/web-shell/assets/{chunk-SVP7TREG-CD2goGva.js → chunk-SVP7TREG-B96d8Y_1.js} +1 -1
  244. package/web-shell/assets/{chunk-XXDRQBXY-DzQt-Rji.js → chunk-XXDRQBXY-CF2sVQpv.js} +1 -1
  245. package/web-shell/assets/classDiagram-DTDB5LWJ-DcY-26Ig.js +1 -0
  246. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DcY-26Ig.js +1 -0
  247. package/web-shell/assets/{cose-bilkent-JH36ORCC-C-BZXSUn.js → cose-bilkent-JH36ORCC-CT6tXVAS.js} +1 -1
  248. package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
  249. package/web-shell/assets/{cynefin-OW5HDTMX-BTcvowe1.js → cynefin-OW5HDTMX-X1NS4vtV.js} +1 -1
  250. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BoUE6K81.js → cynefinDiagram-5FMLGOSQ-DNsKNOT4.js} +1 -1
  251. package/web-shell/assets/{dagre-3AP2YEHR-BHxy9xeB.js → dagre-3AP2YEHR-9-AHKqsb.js} +1 -1
  252. package/web-shell/assets/{diagram-S7CK7UJ4-DMiJIvDT.js → diagram-S7CK7UJ4-Bjgms7j6.js} +1 -1
  253. package/web-shell/assets/{diagram-UQ7AKVKN-DXV09Aes.js → diagram-UQ7AKVKN-h6bCprbE.js} +1 -1
  254. package/web-shell/assets/{diagram-VSXAHHWV-CocpRomV.js → diagram-VSXAHHWV-4SbQXVLt.js} +1 -1
  255. package/web-shell/assets/{diagram-VX7I27RA-DL7nqtb4.js → diagram-VX7I27RA-B5gPCzzB.js} +1 -1
  256. package/web-shell/assets/{diagram-Z3DM3KII-CPZ2Jux_.js → diagram-Z3DM3KII-DFJXIA3A.js} +1 -1
  257. package/web-shell/assets/{ebnfDiagram-PWID7BFC-BX-eVNsX.js → ebnfDiagram-PWID7BFC-FwyaU7VY.js} +1 -1
  258. package/web-shell/assets/{erDiagram-SSCWMZ5O-CPy_Ir6y.js → erDiagram-SSCWMZ5O-8vJQh2te.js} +1 -1
  259. package/web-shell/assets/{flowDiagram-A5DVABFB-eknAOte9.js → flowDiagram-A5DVABFB-BzA_1gMN.js} +1 -1
  260. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-crAxw_t7.js → ganttDiagram-EL5Y4UJY-Co-ABbVX.js} +1 -1
  261. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-M29pa3Tc.js → gitGraphDiagram-WWUBYQGX-DW_FcyrX.js} +1 -1
  262. package/web-shell/assets/{index-C9R-iojE.js → index-BbMXfhNG.js} +1 -1
  263. package/web-shell/assets/{index-B4TLaxWs.js → index-Bu-rZoJ-.js} +462 -454
  264. package/web-shell/assets/index-CsPwZ1ut.css +36 -0
  265. package/web-shell/assets/{infoDiagram-RXCK75RN-XqspXdOU.js → infoDiagram-RXCK75RN-BEgfhUFN.js} +1 -1
  266. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-C5KFS-7j.js → ishikawaDiagram-5VMMS53U-DCsMxQmc.js} +1 -1
  267. package/web-shell/assets/{journeyDiagram-EYS64GPL-Cc57LVRo.js → journeyDiagram-EYS64GPL-DyIEYoHz.js} +1 -1
  268. package/web-shell/assets/{kanban-definition-3QL26DDD-C81OG-AI.js → kanban-definition-3QL26DDD-CkxjqCNr.js} +1 -1
  269. package/web-shell/assets/{layout-CFVu37BB.js → layout-BEWc0Al9.js} +1 -1
  270. package/web-shell/assets/{linear-ChBxdtWf.js → linear-CNuNxirL.js} +1 -1
  271. package/web-shell/assets/{mermaid.core-CMLfue0w.js → mermaid.core-DZBre674.js} +6 -6
  272. package/web-shell/assets/{mindmap-definition-FBJOCRG2-DFsvJThp.js → mindmap-definition-FBJOCRG2-CpafFz_F.js} +1 -1
  273. package/web-shell/assets/{pegDiagram-XKGWAZYB-BzpRzM4F.js → pegDiagram-XKGWAZYB-DfZqk_dq.js} +1 -1
  274. package/web-shell/assets/{pieDiagram-E7YTZNPT-Cv0Kankl.js → pieDiagram-E7YTZNPT-S0UWXlgC.js} +1 -1
  275. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-Bh2BJ3Ay.js → quadrantDiagram-AXDQQJYC-dd37_Ohj.js} +1 -1
  276. package/web-shell/assets/{railroadDiagram-O6MQD6OU-y8rNDdDS.js → railroadDiagram-O6MQD6OU-CH8NJZ7u.js} +1 -1
  277. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-C0m2DKJ_.js → requirementDiagram-EFPCY7ZU-CFdqWYih.js} +1 -1
  278. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-BzdGnSF4.js → sankeyDiagram-P5KCCOFB-CsddcEGD.js} +1 -1
  279. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DPzAVmzz.js → sequenceDiagram-WJ2MYXX4-BZ270mGw.js} +1 -1
  280. package/web-shell/assets/{sizeCapture-X5ZJPWSS-LcHG28Zh.js → sizeCapture-X5ZJPWSS-CGaS4DBV.js} +1 -1
  281. package/web-shell/assets/{stateDiagram-HBIQ2CUA-C1Bzy3IT.js → stateDiagram-HBIQ2CUA-COpIzMu6.js} +1 -1
  282. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-D6qEVAji.js +1 -0
  283. package/web-shell/assets/{swimlanes-XN3QIQJK-Bftk8V64.js → swimlanes-XN3QIQJK-CMF889m3.js} +1 -1
  284. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-mem5Jj4m.js +8 -0
  285. package/web-shell/assets/{timeline-definition-24CTP7MA-BfXHcN1A.js → timeline-definition-24CTP7MA-BelnxYz5.js} +1 -1
  286. package/web-shell/assets/{vennDiagram-4TSXK5OY-DRSlI9-V.js → vennDiagram-4TSXK5OY-CU-NRqIB.js} +1 -1
  287. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CaLmqGau.js → wardleyDiagram-VM6X3IG4-CDNKqWh-.js} +1 -1
  288. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-8lgUT6e8.js → xychartDiagram-S5SC5T6Z-CLqguL5D.js} +1 -1
  289. package/web-shell/index.html +2 -2
  290. package/chunks/chunk-3UMWOKJC.js +0 -78
  291. package/chunks/chunk-IQAFKVXS.js +0 -22
  292. package/web-shell/assets/channel-CQx7VSAp.js +0 -1
  293. package/web-shell/assets/classDiagram-DTDB5LWJ-C-Uz8hHk.js +0 -1
  294. package/web-shell/assets/classDiagram-v2-JRS7N3AN-C-Uz8hHk.js +0 -1
  295. package/web-shell/assets/index-CCrkEbzz.css +0 -36
  296. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-LuuL5byY.js +0 -1
  297. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-COmnNq8s.js +0 -8
@@ -698,6 +698,7 @@ var AcpBridge = class extends EventEmitter {
698
698
  channelLoopToolHandlers = [];
699
699
  knownSessionIds = /* @__PURE__ */ new Set();
700
700
  sessionBindingTokens = /* @__PURE__ */ new Map();
701
+ toolCallKindsBySession = /* @__PURE__ */ new Map();
701
702
  channelLoopMcpRegistered = false;
702
703
  channelLoopMcpRegistration = null;
703
704
  pendingPermissions = /* @__PURE__ */ new Map();
@@ -743,6 +744,7 @@ var AcpBridge = class extends EventEmitter {
743
744
  this.resolvePendingPermissions();
744
745
  this.knownSessionIds.clear();
745
746
  this.sessionBindingTokens.clear();
747
+ this.toolCallKindsBySession.clear();
746
748
  this.connection = null;
747
749
  this.child = null;
748
750
  this.emit("disconnected", code, signal);
@@ -906,6 +908,7 @@ var AcpBridge = class extends EventEmitter {
906
908
  if (!this.knownSessionIds.delete(sessionId))
907
909
  return;
908
910
  this.sessionBindingTokens.delete(sessionId);
911
+ this.toolCallKindsBySession.delete(sessionId);
909
912
  this.resolvePendingPermissions(sessionId);
910
913
  const conn = this.connection;
911
914
  if (!conn || !this.isConnected)
@@ -930,6 +933,7 @@ var AcpBridge = class extends EventEmitter {
930
933
  this.resolvePendingPermissions();
931
934
  this.knownSessionIds.clear();
932
935
  this.sessionBindingTokens.clear();
936
+ this.toolCallKindsBySession.clear();
933
937
  if (this.child) {
934
938
  this.child.kill();
935
939
  this.child = null;
@@ -968,19 +972,44 @@ var AcpBridge = class extends EventEmitter {
968
972
  }
969
973
  break;
970
974
  }
971
- case "tool_call": {
975
+ case "tool_call":
976
+ case "tool_call_update": {
977
+ const toolCallId = update["toolCallId"] || "";
978
+ if (!toolCallId)
979
+ break;
980
+ const explicitKind = typeof update["kind"] === "string" ? update["kind"] : "";
981
+ const meta = update["_meta"];
982
+ if (type === "tool_call_update" && !explicitKind && update["status"] === "in_progress" && (meta?.["shellProgress"] !== void 0 || meta?.["subagentProgress"] === true)) {
983
+ break;
984
+ }
985
+ let sessionKinds = this.toolCallKindsBySession.get(sessionId);
986
+ const kind = explicitKind || sessionKinds?.get(toolCallId);
987
+ if (!kind)
988
+ break;
989
+ if (type === "tool_call" || explicitKind) {
990
+ const kinds = sessionKinds ?? /* @__PURE__ */ new Map();
991
+ kinds.set(toolCallId, kind);
992
+ this.toolCallKindsBySession.set(sessionId, kinds);
993
+ sessionKinds = kinds;
994
+ }
972
995
  const event = {
973
996
  sessionId,
974
- toolCallId: update["toolCallId"],
975
- kind: update["kind"] || "",
997
+ toolCallId,
998
+ kind,
976
999
  title: update["title"] || "",
977
1000
  status: update["status"] || "pending",
978
1001
  rawInput: update["rawInput"]
979
1002
  };
980
- if (event.status === "pending" || event.status === "in_progress") {
1003
+ if (type === "tool_call" && (event.status === "pending" || event.status === "in_progress")) {
981
1004
  this.emitResponseBoundary(sessionId);
982
1005
  }
983
1006
  this.emit("toolCall", event);
1007
+ if (event.status === "completed" || event.status === "failed") {
1008
+ sessionKinds?.delete(toolCallId);
1009
+ if (sessionKinds?.size === 0) {
1010
+ this.toolCallKindsBySession.delete(sessionId);
1011
+ }
1012
+ }
984
1013
  break;
985
1014
  }
986
1015
  case "plan": {
@@ -1763,6 +1792,49 @@ init_esbuild_shims();
1763
1792
  import { chmodSync as chmodSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync as renameSync3, rmSync, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
1764
1793
  import { dirname as dirname3, isAbsolute, join as join4 } from "node:path";
1765
1794
  import process2 from "node:process";
1795
+ function readDaemonHttpErrorCode(error) {
1796
+ let current = error;
1797
+ for (let depth = 0; depth < 5; depth++) {
1798
+ if (typeof current !== "object" && typeof current !== "function" || current === null) {
1799
+ return void 0;
1800
+ }
1801
+ const record = current;
1802
+ if (record["name"] === "DaemonHttpError" && record["status"] === 409) {
1803
+ const body = record["body"];
1804
+ if (typeof body === "object" && body !== null && !Array.isArray(body)) {
1805
+ const code = body["code"];
1806
+ if (typeof code === "string" && code.length > 0)
1807
+ return code;
1808
+ }
1809
+ }
1810
+ current = record["cause"];
1811
+ }
1812
+ return void 0;
1813
+ }
1814
+ __name(readDaemonHttpErrorCode, "readDaemonHttpErrorCode");
1815
+ function readSupersededReplacementId(error) {
1816
+ let current = error;
1817
+ for (let depth = 0; depth < 5; depth++) {
1818
+ if (typeof current !== "object" && typeof current !== "function" || current === null) {
1819
+ return void 0;
1820
+ }
1821
+ const record = current;
1822
+ if (record["name"] === "DaemonHttpError" && record["status"] === 409) {
1823
+ const body = record["body"];
1824
+ if (typeof body === "object" && body !== null && !Array.isArray(body)) {
1825
+ const typedBody = body;
1826
+ if (typedBody["code"] !== "worktree_session_superseded") {
1827
+ return void 0;
1828
+ }
1829
+ const replacement = typedBody["replacementSessionId"];
1830
+ return typeof replacement === "string" && replacement.length > 0 ? replacement : void 0;
1831
+ }
1832
+ }
1833
+ current = record["cause"];
1834
+ }
1835
+ return void 0;
1836
+ }
1837
+ __name(readSupersededReplacementId, "readSupersededReplacementId");
1766
1838
  var SessionRouter = class {
1767
1839
  static {
1768
1840
  __name(this, "SessionRouter");
@@ -1773,9 +1845,11 @@ var SessionRouter = class {
1773
1845
  // session ID → target
1774
1846
  toCwd = /* @__PURE__ */ new Map();
1775
1847
  // session ID → cwd
1848
+ toManagedMeta = /* @__PURE__ */ new Map();
1776
1849
  creatingSessions = /* @__PURE__ */ new Map();
1777
1850
  sessionLoadWindows = /* @__PURE__ */ new Set();
1778
1851
  liveSessionIds = /* @__PURE__ */ new Set();
1852
+ staleBridgeBindings = /* @__PURE__ */ new Set();
1779
1853
  routeTokens = /* @__PURE__ */ new Map();
1780
1854
  lifecycleGeneration = 0;
1781
1855
  bridge;
@@ -1797,6 +1871,7 @@ var SessionRouter = class {
1797
1871
  setBridge(bridge) {
1798
1872
  this.bridge = bridge;
1799
1873
  this.liveSessionIds.clear();
1874
+ this.staleBridgeBindings.clear();
1800
1875
  }
1801
1876
  /** Set scope override for a specific channel. */
1802
1877
  setChannelScope(channelName, scope) {
@@ -2072,12 +2147,12 @@ var SessionRouter = class {
2072
2147
  this.endSessionLoad(loadWindow);
2073
2148
  }
2074
2149
  }
2075
- async loadManagedSession(sessionId, target, workspaceCwd, expectedCwd = workspaceCwd, isolation = "shared") {
2150
+ async loadManagedSession(sessionId, target, workspaceCwd, expectedCwd = workspaceCwd, isolation = "shared", allowSupersededRedirect = true) {
2076
2151
  if (this.liveSessionIds.has(sessionId)) {
2077
2152
  const actualCwd = this.validateManagedSessionIdentity(this.bridge, sessionId, workspaceCwd, expectedCwd, isolation);
2078
2153
  this.toTarget.set(sessionId, target);
2079
2154
  this.toCwd.set(sessionId, actualCwd);
2080
- return { loaded: false };
2155
+ return { loaded: false, sessionId };
2081
2156
  }
2082
2157
  const loadWindow = this.beginSessionLoad();
2083
2158
  const lifecycleGeneration = this.lifecycleGeneration;
@@ -2085,6 +2160,9 @@ var SessionRouter = class {
2085
2160
  const bindingToken = {};
2086
2161
  let loadedSessionId;
2087
2162
  try {
2163
+ if (this.staleBridgeBindings.delete(sessionId)) {
2164
+ await bridge.discardSession?.(sessionId).catch(() => void 0);
2165
+ }
2088
2166
  loadedSessionId = await bridge.loadSession(sessionId, workspaceCwd, this.sessionOptions(target.channelName), bindingToken);
2089
2167
  if (lifecycleGeneration !== this.lifecycleGeneration || bridge !== this.bridge) {
2090
2168
  this.scheduleManagedDiscard(bridge, loadedSessionId, bindingToken);
@@ -2104,16 +2182,105 @@ var SessionRouter = class {
2104
2182
  this.toTarget.set(sessionId, target);
2105
2183
  this.toCwd.set(sessionId, actualCwd);
2106
2184
  this.liveSessionIds.add(sessionId);
2107
- return { loaded: true };
2185
+ return { loaded: true, sessionId };
2108
2186
  } catch (error) {
2109
2187
  if (loadedSessionId) {
2110
2188
  await bridge.discardSession?.(loadedSessionId, bindingToken).catch(() => void 0);
2189
+ throw error;
2190
+ }
2191
+ const replacementId = readSupersededReplacementId(error);
2192
+ if (allowSupersededRedirect && replacementId !== void 0 && replacementId !== sessionId) {
2193
+ const redirected = await this.loadManagedSession(replacementId, target, workspaceCwd, expectedCwd, isolation, false);
2194
+ this.healSupersededRoute(sessionId, redirected.sessionId);
2195
+ return {
2196
+ loaded: redirected.loaded,
2197
+ sessionId: redirected.sessionId,
2198
+ redirectedFrom: sessionId
2199
+ };
2111
2200
  }
2112
2201
  throw error;
2113
2202
  } finally {
2114
2203
  this.endSessionLoad(loadWindow);
2115
2204
  }
2116
2205
  }
2206
+ /**
2207
+ * Remap every route that still points at a superseded session to its
2208
+ * replacement, and drop the superseded id's bookkeeping. The manager's
2209
+ * own task registry heals separately (it owns the task-name mapping).
2210
+ */
2211
+ healSupersededRoute(oldSessionId, newSessionId) {
2212
+ let changed = false;
2213
+ for (const [key, mappedSessionId] of this.toSession) {
2214
+ if (mappedSessionId !== oldSessionId)
2215
+ continue;
2216
+ this.invalidateRouteOperation(key);
2217
+ this.toSession.set(key, newSessionId);
2218
+ changed = true;
2219
+ }
2220
+ changed = this.toTarget.delete(oldSessionId) || changed;
2221
+ changed = this.toCwd.delete(oldSessionId) || changed;
2222
+ const managedMeta = this.toManagedMeta.get(oldSessionId);
2223
+ if (managedMeta !== void 0) {
2224
+ this.toManagedMeta.set(newSessionId, managedMeta);
2225
+ this.toManagedMeta.delete(oldSessionId);
2226
+ changed = true;
2227
+ }
2228
+ this.liveSessionIds.delete(oldSessionId);
2229
+ this.staleBridgeBindings.delete(oldSessionId);
2230
+ if (changed)
2231
+ this.persist();
2232
+ }
2233
+ /**
2234
+ * Worktree reset: transfer the task session's checkout ownership to a
2235
+ * fresh replacement session on the daemon, validate the replacement's
2236
+ * attestation, and route it. The task registry itself is swapped by the
2237
+ * named-session manager (it owns the task-name mapping); this call only
2238
+ * wires the router's session bookkeeping.
2239
+ *
2240
+ * A failure past the daemon's marker flip rolls nothing back: the
2241
+ * registry keeps pointing at the old id, and the next selection's load
2242
+ * heals it through the superseded redirect — the failed reset drops the
2243
+ * old id from the live set so that load consults the daemon again.
2244
+ */
2245
+ async replaceManagedWorktreeSession(sessionId, target, workspaceCwd, expectedCwd) {
2246
+ const bridge = this.bridge;
2247
+ if (!bridge.resetWorktreeSession) {
2248
+ throw new Error("Worktree reset is not supported by this bridge");
2249
+ }
2250
+ const loadWindow = this.beginSessionLoad();
2251
+ const lifecycleGeneration = this.lifecycleGeneration;
2252
+ const bindingToken = {};
2253
+ let replacementId;
2254
+ try {
2255
+ replacementId = await bridge.resetWorktreeSession(sessionId, workspaceCwd, this.sessionOptions(target.channelName), bindingToken);
2256
+ if (lifecycleGeneration !== this.lifecycleGeneration || bridge !== this.bridge) {
2257
+ this.scheduleManagedDiscard(bridge, replacementId, bindingToken);
2258
+ throw new Error("Managed session reset was invalidated");
2259
+ }
2260
+ if (typeof replacementId !== "string" || replacementId.length === 0) {
2261
+ throw new Error("Invalid session ID from bridge");
2262
+ }
2263
+ if (loadWindow.delete(replacementId)) {
2264
+ await bridge.discardSession?.(replacementId, bindingToken);
2265
+ throw new Error(`Managed session ${replacementId} died before reset completed`);
2266
+ }
2267
+ const actualCwd = this.validateManagedSessionIdentity(bridge, replacementId, workspaceCwd, expectedCwd, "worktree");
2268
+ this.toTarget.set(replacementId, target);
2269
+ this.toCwd.set(replacementId, actualCwd);
2270
+ this.liveSessionIds.add(replacementId);
2271
+ this.forgetManagedSession(sessionId);
2272
+ return replacementId;
2273
+ } catch (error) {
2274
+ if (replacementId !== void 0) {
2275
+ await bridge.discardSession?.(replacementId, bindingToken).catch(() => void 0);
2276
+ }
2277
+ this.staleBridgeBindings.add(sessionId);
2278
+ this.liveSessionIds.delete(sessionId);
2279
+ throw error;
2280
+ } finally {
2281
+ this.endSessionLoad(loadWindow);
2282
+ }
2283
+ }
2117
2284
  validateManagedSessionIdentity(bridge, sessionId, workspaceCwd, expectedCwd, isolation) {
2118
2285
  if (isolation === "shared") {
2119
2286
  return workspaceCwd;
@@ -2126,10 +2293,26 @@ var SessionRouter = class {
2126
2293
  }
2127
2294
  return canonicalWorktree;
2128
2295
  }
2129
- activateManagedSession(sessionId, target, cwd) {
2296
+ activateManagedSession(sessionId, target, cwd, managed) {
2297
+ if (managed?.isolation === "worktree" && !managed.workspaceCwd) {
2298
+ throw new Error("A worktree managed session requires its workspace cwd.");
2299
+ }
2300
+ const previousMeta = this.toManagedMeta.get(sessionId);
2301
+ if (managed?.isolation === "worktree") {
2302
+ this.toManagedMeta.set(sessionId, {
2303
+ isolation: "worktree",
2304
+ workspaceCwd: managed.workspaceCwd
2305
+ });
2306
+ } else {
2307
+ this.toManagedMeta.delete(sessionId);
2308
+ }
2309
+ const metaChanged = managed?.isolation === "worktree" ? previousMeta?.workspaceCwd !== managed.workspaceCwd : previousMeta !== void 0;
2130
2310
  const key = this.routingKey(target.channelName, target.senderId, target.chatId, target.threadId);
2131
- if (this.toSession.get(key) === sessionId)
2311
+ if (this.toSession.get(key) === sessionId) {
2312
+ if (metaChanged)
2313
+ this.persist();
2132
2314
  return;
2315
+ }
2133
2316
  this.invalidateRouteOperation(key);
2134
2317
  this.toSession.set(key, sessionId);
2135
2318
  this.toTarget.set(sessionId, target);
@@ -2147,17 +2330,18 @@ var SessionRouter = class {
2147
2330
  }
2148
2331
  changed = this.toTarget.delete(sessionId) || changed;
2149
2332
  changed = this.toCwd.delete(sessionId) || changed;
2333
+ changed = this.toManagedMeta.delete(sessionId) || changed;
2150
2334
  changed = this.liveSessionIds.delete(sessionId) || changed;
2335
+ this.staleBridgeBindings.delete(sessionId);
2151
2336
  if (changed)
2152
2337
  this.persist();
2153
2338
  }
2154
2339
  async detachManagedSession(sessionId) {
2155
2340
  try {
2156
- if (this.liveSessionIds.has(sessionId)) {
2157
- if (!this.bridge.discardSession) {
2158
- throw new Error("Managed session detach is not supported");
2159
- }
2341
+ if (this.bridge.discardSession) {
2160
2342
  await this.bridge.discardSession(sessionId);
2343
+ } else if (this.liveSessionIds.has(sessionId)) {
2344
+ throw new Error("Managed session detach is not supported");
2161
2345
  }
2162
2346
  } finally {
2163
2347
  this.forgetManagedSession(sessionId);
@@ -2213,6 +2397,9 @@ var SessionRouter = class {
2213
2397
  if (this.toCwd.delete(sessionId)) {
2214
2398
  removed = true;
2215
2399
  }
2400
+ if (this.toManagedMeta.delete(sessionId)) {
2401
+ removed = true;
2402
+ }
2216
2403
  this.liveSessionIds.delete(sessionId);
2217
2404
  if (!removed && this.sessionLoadWindows.size > 0) {
2218
2405
  for (const loadWindow of this.sessionLoadWindows) {
@@ -2242,6 +2429,7 @@ var SessionRouter = class {
2242
2429
  this.toSession.delete(key);
2243
2430
  this.toTarget.delete(sessionId);
2244
2431
  this.toCwd.delete(sessionId);
2432
+ this.toManagedMeta.delete(sessionId);
2245
2433
  this.liveSessionIds.delete(sessionId);
2246
2434
  return sessionId;
2247
2435
  }
@@ -2278,6 +2466,12 @@ var SessionRouter = class {
2278
2466
  this.toSession.set(key, entry.sessionId);
2279
2467
  this.toTarget.set(entry.sessionId, entry.target);
2280
2468
  this.toCwd.set(entry.sessionId, entry.cwd);
2469
+ if (entry.isolation === "worktree" && entry.workspaceCwd !== void 0) {
2470
+ this.toManagedMeta.set(entry.sessionId, {
2471
+ isolation: "worktree",
2472
+ workspaceCwd: entry.workspaceCwd
2473
+ });
2474
+ }
2281
2475
  restored++;
2282
2476
  }
2283
2477
  if (persisted.dropped > 0)
@@ -2321,6 +2515,32 @@ var SessionRouter = class {
2321
2515
  try {
2322
2516
  this.assertOperationCurrent(operation);
2323
2517
  const options = this.sessionOptions(entry.target.channelName);
2518
+ if (entry.isolation === "worktree" && entry.workspaceCwd !== void 0) {
2519
+ const managed = await this.loadManagedSession(entry.sessionId, entry.target, entry.workspaceCwd, entry.cwd, "worktree");
2520
+ try {
2521
+ this.assertOperationCurrent(operation);
2522
+ } catch (error) {
2523
+ if (![...this.toSession.values()].includes(managed.sessionId)) {
2524
+ void this.bridge.discardSession?.(managed.sessionId).catch(() => void 0);
2525
+ this.toTarget.delete(managed.sessionId);
2526
+ this.toCwd.delete(managed.sessionId);
2527
+ this.toManagedMeta.delete(managed.sessionId);
2528
+ this.liveSessionIds.delete(managed.sessionId);
2529
+ }
2530
+ throw error;
2531
+ }
2532
+ this.toSession.set(key, managed.sessionId);
2533
+ this.toManagedMeta.set(managed.sessionId, {
2534
+ isolation: "worktree",
2535
+ workspaceCwd: entry.workspaceCwd
2536
+ });
2537
+ reservation.resolve(managed.sessionId);
2538
+ if (managed.sessionId !== entry.sessionId) {
2539
+ changed = true;
2540
+ }
2541
+ restored++;
2542
+ continue;
2543
+ }
2324
2544
  const sessionId = await this.bridge.loadSession(entry.sessionId, entry.cwd, options, operation);
2325
2545
  try {
2326
2546
  this.assertOperationCurrent(operation);
@@ -2373,9 +2593,11 @@ var SessionRouter = class {
2373
2593
  this.toSession.clear();
2374
2594
  this.toTarget.clear();
2375
2595
  this.toCwd.clear();
2596
+ this.toManagedMeta.clear();
2376
2597
  this.creatingSessions.clear();
2377
2598
  this.sessionLoadWindows.clear();
2378
2599
  this.liveSessionIds.clear();
2600
+ this.staleBridgeBindings.clear();
2379
2601
  this.routeTokens.clear();
2380
2602
  }
2381
2603
  /** Clear in-memory state and delete persist file. Used on clean shutdown. */
@@ -2433,7 +2655,12 @@ var SessionRouter = class {
2433
2655
  if (typeof target !== "object" || target === null)
2434
2656
  return false;
2435
2657
  const typedTarget = target;
2436
- return typeof entry["sessionId"] === "string" && entry["sessionId"].length > 0 && typeof entry["cwd"] === "string" && entry["cwd"].length > 0 && typeof typedTarget["channelName"] === "string" && typeof typedTarget["senderId"] === "string" && typeof typedTarget["chatId"] === "string" && (typedTarget["threadId"] === void 0 || typeof typedTarget["threadId"] === "string") && (typedTarget["isGroup"] === void 0 || typeof typedTarget["isGroup"] === "boolean");
2658
+ const wellFormed = typeof entry["sessionId"] === "string" && entry["sessionId"].length > 0 && typeof entry["cwd"] === "string" && entry["cwd"].length > 0 && typeof typedTarget["channelName"] === "string" && typeof typedTarget["senderId"] === "string" && typeof typedTarget["chatId"] === "string" && (typedTarget["threadId"] === void 0 || typeof typedTarget["threadId"] === "string") && (typedTarget["isGroup"] === void 0 || typeof typedTarget["isGroup"] === "boolean");
2659
+ if (!wellFormed)
2660
+ return false;
2661
+ if (entry["isolation"] === void 0)
2662
+ return true;
2663
+ return entry["isolation"] === "worktree" && typeof entry["workspaceCwd"] === "string" && entry["workspaceCwd"].length > 0;
2437
2664
  }
2438
2665
  persist() {
2439
2666
  if (!this.persistPath)
@@ -2446,7 +2673,8 @@ var SessionRouter = class {
2446
2673
  data[key] = {
2447
2674
  sessionId,
2448
2675
  target,
2449
- cwd: this.toCwd.get(sessionId) ?? this.defaultCwd
2676
+ cwd: this.toCwd.get(sessionId) ?? this.defaultCwd,
2677
+ ...this.toManagedMeta.get(sessionId) ?? {}
2450
2678
  };
2451
2679
  }
2452
2680
  const dir = dirname3(this.persistPath);
@@ -2594,6 +2822,16 @@ import process3 from "node:process";
2594
2822
  var REGISTRY_VERSION = 1;
2595
2823
  var MAX_OPEN_TASKS = 8;
2596
2824
  var TASK_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/;
2825
+ var NamedSessionTaskError = class extends Error {
2826
+ static {
2827
+ __name(this, "NamedSessionTaskError");
2828
+ }
2829
+ taskName;
2830
+ constructor(message, taskName, options) {
2831
+ super(message, options);
2832
+ this.taskName = taskName;
2833
+ }
2834
+ };
2597
2835
  var NamedSessionManager = class {
2598
2836
  static {
2599
2837
  __name(this, "NamedSessionManager");
@@ -2608,6 +2846,12 @@ var NamedSessionManager = class {
2608
2846
  registry;
2609
2847
  taskBySessionId;
2610
2848
  ownerOperations = /* @__PURE__ */ new Map();
2849
+ /**
2850
+ * Superseded session id → the replacement its task moved onto. A queued turn
2851
+ * stays bound to the id it reserved, so the reservation lookup has to follow
2852
+ * the task or every turn after the first one is stranded on the old id.
2853
+ */
2854
+ supersededSessionIds = /* @__PURE__ */ new Map();
2611
2855
  constructor(options) {
2612
2856
  this.channelName = options.channelName;
2613
2857
  this.cwd = options.cwd;
@@ -2706,14 +2950,20 @@ var NamedSessionManager = class {
2706
2950
  return task ? this.selection(owner, task) : void 0;
2707
2951
  });
2708
2952
  }
2953
+ /**
2954
+ * Reload a task a queued turn is already bound to. Resolves to the session
2955
+ * id the caller must dispatch on — the healed replacement when a superseded
2956
+ * redirect fired — or undefined when the task is no longer reservable.
2957
+ */
2709
2958
  resumeReserved(input, sessionId) {
2710
2959
  return this.withOwnerLock(input, async () => {
2711
2960
  const owner = await this.ensureOwner(input, false);
2712
- const task = owner?.tasks.find((candidate) => candidate.sessionId === sessionId && candidate.status === "open");
2961
+ const reservedSessionId = this.supersededSessionIds.get(sessionId) ?? sessionId;
2962
+ const task = owner?.tasks.find((candidate) => candidate.sessionId === reservedSessionId && candidate.status === "open");
2713
2963
  if (!task)
2714
- return false;
2715
- await this.loadTask(task, `Could not reload reserved task "${task.name}".`);
2716
- return true;
2964
+ return void 0;
2965
+ const result = await this.loadTask(task, `Could not reload reserved task "${task.name}".`);
2966
+ return result.sessionId;
2717
2967
  });
2718
2968
  }
2719
2969
  create(input, name, isolation = "shared") {
@@ -2757,7 +3007,10 @@ var NamedSessionManager = class {
2757
3007
  await this.router.detachManagedSession(sessionId).catch(() => void 0);
2758
3008
  throw error;
2759
3009
  }
2760
- this.router.activateManagedSession(sessionId, target, task.cwd);
3010
+ this.router.activateManagedSession(sessionId, target, task.cwd, {
3011
+ isolation: task.isolation,
3012
+ workspaceCwd: this.cwd
3013
+ });
2761
3014
  return this.selection(nextOwner, task);
2762
3015
  });
2763
3016
  }
@@ -2773,9 +3026,10 @@ var NamedSessionManager = class {
2773
3026
  throw new Error("You already have eight open tasks. Close one before reopening another.");
2774
3027
  }
2775
3028
  const timestamp = this.nextTimestamp(owner);
2776
- const loaded = await this.loadTask(task, `Could not load task "${task.name}". The current task was not changed.`);
3029
+ const loadResult = await this.loadTask(task, `Could not load task "${task.name}". The current task was not changed.`);
2777
3030
  const updatedTask = {
2778
3031
  ...task,
3032
+ sessionId: loadResult.sessionId,
2779
3033
  status: "open",
2780
3034
  updatedAt: timestamp,
2781
3035
  lastSelectedAt: timestamp
@@ -2784,12 +3038,12 @@ var NamedSessionManager = class {
2784
3038
  try {
2785
3039
  this.commitOwner(nextOwner);
2786
3040
  } catch (error) {
2787
- if (loaded) {
2788
- await this.router.detachManagedSession(task.sessionId).catch(() => void 0);
3041
+ if (loadResult.loaded) {
3042
+ await this.router.detachManagedSession(loadResult.sessionId).catch(() => void 0);
2789
3043
  }
2790
3044
  throw error;
2791
3045
  }
2792
- this.router.activateManagedSession(task.sessionId, task.target, task.cwd);
3046
+ this.router.activateManagedSession(loadResult.sessionId, updatedTask.target, updatedTask.cwd, { isolation: updatedTask.isolation, workspaceCwd: this.cwd });
2793
3047
  return this.selection(nextOwner, updatedTask);
2794
3048
  });
2795
3049
  }
@@ -2811,8 +3065,11 @@ var NamedSessionManager = class {
2811
3065
  const timestamp = this.nextTimestamp(owner);
2812
3066
  const replacement = wasActive ? owner.tasks.filter((candidate) => candidate.status === "open" && !this.sameName(candidate.name, task.name)).sort((a, b) => b.lastSelectedAt - a.lastSelectedAt)[0] : void 0;
2813
3067
  let replacementLoaded = false;
3068
+ let replacementSessionId;
2814
3069
  if (replacement) {
2815
- replacementLoaded = await this.loadTask(replacement, `Could not load fallback task "${replacement.name}". Task "${task.name}" was not closed.`);
3070
+ const replacementLoad = await this.loadTask(replacement, `Could not load fallback task "${replacement.name}". Task "${task.name}" was not closed.`);
3071
+ replacementLoaded = replacementLoad.loaded;
3072
+ replacementSessionId = replacementLoad.sessionId;
2816
3073
  }
2817
3074
  const closedTask = {
2818
3075
  ...task,
@@ -2822,6 +3079,7 @@ var NamedSessionManager = class {
2822
3079
  let nextOwner = this.replaceTask(owner, closedTask, wasActive ? replacement?.name ?? null : owner.activeTaskName);
2823
3080
  const selectedReplacement = replacement ? {
2824
3081
  ...replacement,
3082
+ sessionId: replacementSessionId ?? replacement.sessionId,
2825
3083
  updatedAt: timestamp,
2826
3084
  lastSelectedAt: timestamp
2827
3085
  } : void 0;
@@ -2832,21 +3090,22 @@ var NamedSessionManager = class {
2832
3090
  this.commitOwner(nextOwner);
2833
3091
  } catch (error) {
2834
3092
  if (replacement && replacementLoaded) {
2835
- await this.router.detachManagedSession(replacement.sessionId).catch(() => void 0);
3093
+ await this.router.detachManagedSession(replacementSessionId ?? replacement.sessionId).catch(() => void 0);
2836
3094
  }
2837
3095
  throw error;
2838
3096
  }
2839
3097
  if (replacement) {
2840
- this.router.activateManagedSession(replacement.sessionId, replacement.target, replacement.cwd);
3098
+ this.router.activateManagedSession(replacementSessionId ?? replacement.sessionId, replacement.target, replacement.cwd, { isolation: replacement.isolation, workspaceCwd: this.cwd });
2841
3099
  }
2842
3100
  try {
2843
3101
  await this.router.detachManagedSession(task.sessionId);
2844
3102
  } catch (error) {
2845
- this.commitOwner(owner);
3103
+ const healedReplacement = replacement !== void 0 && replacementSessionId !== void 0 && replacementSessionId !== replacement.sessionId ? { ...replacement, sessionId: replacementSessionId } : void 0;
3104
+ this.commitOwner(healedReplacement ? this.replaceTask(owner, healedReplacement, owner.activeTaskName) : owner);
2846
3105
  this.router.forgetManagedSession(task.sessionId);
2847
- await this.loadTask(task, `Task "${task.name}" could not be restored after close failed.`);
3106
+ const restored = await this.loadTask(task, `Task "${task.name}" could not be restored after close failed.`);
2848
3107
  if (wasActive) {
2849
- this.router.activateManagedSession(task.sessionId, task.target, task.cwd);
3108
+ this.router.activateManagedSession(restored.sessionId, task.target, task.cwd, { isolation: task.isolation, workspaceCwd: this.cwd });
2850
3109
  }
2851
3110
  throw new Error(`Failed to close task "${task.name}".`, {
2852
3111
  cause: error
@@ -2867,10 +3126,36 @@ var NamedSessionManager = class {
2867
3126
  const task = this.findTask(owner, owner.activeTaskName);
2868
3127
  if (!task || task.status !== "open")
2869
3128
  return void 0;
3129
+ const timestamp = this.nextTimestamp(owner);
2870
3130
  if (task.isolation === "worktree") {
2871
- throw new Error(`Task "${task.name}" uses a worktree and cannot be cleared or reset yet. Continue using the task or close it. Its files were not changed.`);
3131
+ if (this.isBusy(task.sessionId)) {
3132
+ throw new Error(`Task "${task.name}" is busy. Wait for the running prompt to finish (or cancel it), then try again.`);
3133
+ }
3134
+ const sessionId2 = await this.resetWorktreeSession(task);
3135
+ const updatedTask2 = {
3136
+ ...task,
3137
+ sessionId: sessionId2,
3138
+ updatedAt: timestamp,
3139
+ lastSelectedAt: timestamp
3140
+ };
3141
+ const nextOwner2 = this.replaceTask(owner, updatedTask2, task.name);
3142
+ try {
3143
+ this.commitOwner(nextOwner2);
3144
+ } catch (error) {
3145
+ await this.router.detachManagedSession(sessionId2).catch(() => void 0);
3146
+ throw error;
3147
+ }
3148
+ this.router.activateManagedSession(sessionId2, updatedTask2.target, updatedTask2.cwd, { isolation: updatedTask2.isolation, workspaceCwd: this.cwd });
3149
+ this.router.forgetManagedSession(task.sessionId);
3150
+ this.repointSupersededSessionIds(task.sessionId, sessionId2);
3151
+ this.supersededSessionIds.delete(task.sessionId);
3152
+ return {
3153
+ name: task.name,
3154
+ previousSessionId: task.sessionId,
3155
+ sessionId: sessionId2,
3156
+ worktreeKept: true
3157
+ };
2872
3158
  }
2873
- const timestamp = this.nextTimestamp(owner);
2874
3159
  const sessionId = await this.createSession(task.target, task.isolation, `Could not reset task "${task.name}".`);
2875
3160
  const updatedTask = {
2876
3161
  ...task,
@@ -2885,12 +3170,15 @@ var NamedSessionManager = class {
2885
3170
  await this.router.detachManagedSession(sessionId).catch(() => void 0);
2886
3171
  throw error;
2887
3172
  }
2888
- this.router.activateManagedSession(sessionId, updatedTask.target, updatedTask.cwd);
3173
+ this.router.activateManagedSession(sessionId, updatedTask.target, updatedTask.cwd, { isolation: updatedTask.isolation, workspaceCwd: this.cwd });
2889
3174
  this.router.forgetManagedSession(task.sessionId);
3175
+ this.repointSupersededSessionIds(task.sessionId, sessionId);
3176
+ this.supersededSessionIds.delete(task.sessionId);
2890
3177
  return {
2891
3178
  name: task.name,
2892
3179
  previousSessionId: task.sessionId,
2893
- sessionId
3180
+ sessionId,
3181
+ worktreeKept: false
2894
3182
  };
2895
3183
  });
2896
3184
  }
@@ -2960,12 +3248,17 @@ var NamedSessionManager = class {
2960
3248
  throw new Error("The selected Channel task is unavailable.");
2961
3249
  }
2962
3250
  const release = reserve?.(task.sessionId);
3251
+ let activeRelease = release;
2963
3252
  try {
2964
- await this.loadTask(task, `Could not load task "${task.name}". No replacement session was created.`);
2965
- this.router.activateManagedSession(task.sessionId, task.target, task.cwd);
2966
- return task.sessionId;
3253
+ const result = await this.loadTask(task, `Could not load task "${task.name}". No replacement session was created.`);
3254
+ if (result.sessionId !== task.sessionId && reserve) {
3255
+ release?.();
3256
+ activeRelease = reserve(result.sessionId);
3257
+ }
3258
+ this.router.activateManagedSession(result.sessionId, task.target, task.cwd, { isolation: task.isolation, workspaceCwd: this.cwd });
3259
+ return result.sessionId;
2967
3260
  } catch (error) {
2968
- release?.();
3261
+ activeRelease?.();
2969
3262
  throw error;
2970
3263
  }
2971
3264
  }
@@ -2998,9 +3291,55 @@ var NamedSessionManager = class {
2998
3291
  }
2999
3292
  async loadTask(task, failureMessage) {
3000
3293
  try {
3001
- return (await this.router.loadManagedSession(task.sessionId, task.target, this.cwd, task.cwd, task.isolation)).loaded;
3294
+ const result = await this.router.loadManagedSession(task.sessionId, task.target, this.cwd, task.cwd, task.isolation);
3295
+ if (result.redirectedFrom !== void 0 && result.sessionId !== task.sessionId) {
3296
+ try {
3297
+ this.healSupersededTask(task, result.sessionId);
3298
+ } catch {
3299
+ }
3300
+ }
3301
+ return result;
3002
3302
  } catch (error) {
3003
- throw new Error(failureMessage, { cause: error });
3303
+ throw new NamedSessionTaskError(failureMessage, task.name, {
3304
+ cause: error
3305
+ });
3306
+ }
3307
+ }
3308
+ /**
3309
+ * Point a task at its replacement session after a superseded redirect
3310
+ * healed the route. No-op when the registry entry already moved on (a
3311
+ * concurrent reset under the same owner lock cannot interleave, but a
3312
+ * stale in-memory snapshot could).
3313
+ */
3314
+ healSupersededTask(task, sessionId) {
3315
+ const owner = this.getOwner(task.target);
3316
+ if (!owner)
3317
+ return;
3318
+ const current = this.findTask(owner, task.name);
3319
+ if (!current || current.sessionId !== task.sessionId)
3320
+ return;
3321
+ const timestamp = this.nextTimestamp(owner);
3322
+ this.commitOwner(this.replaceTask(owner, { ...current, sessionId, updatedAt: timestamp }, owner.activeTaskName));
3323
+ this.repointSupersededSessionIds(task.sessionId, sessionId);
3324
+ this.supersededSessionIds.set(task.sessionId, sessionId);
3325
+ }
3326
+ /**
3327
+ * Follow every id that still resolves to `oldSessionId` onto its
3328
+ * replacement, so a task superseded more than once stays reachable from the
3329
+ * oldest id a turn is bound to and the map does not grow once per reset.
3330
+ */
3331
+ repointSupersededSessionIds(oldSessionId, newSessionId) {
3332
+ for (const boundSessionId of [...this.supersededSessionIds.keys()]) {
3333
+ if (this.supersededSessionIds.get(boundSessionId) === oldSessionId) {
3334
+ this.supersededSessionIds.set(boundSessionId, newSessionId);
3335
+ }
3336
+ }
3337
+ }
3338
+ async resetWorktreeSession(task) {
3339
+ try {
3340
+ return await this.router.replaceManagedWorktreeSession(task.sessionId, task.target, this.cwd, task.cwd);
3341
+ } catch (error) {
3342
+ throw new NamedSessionTaskError(`Could not reset task "${task.name}".`, task.name, { cause: error });
3004
3343
  }
3005
3344
  }
3006
3345
  async createSession(target, isolation, failureMessage) {
@@ -4088,6 +4427,9 @@ var ChannelBase = class {
4088
4427
  bridgeSessionDiedListener = /* @__PURE__ */ __name((event) => {
4089
4428
  this.onSessionDied(event.sessionId);
4090
4429
  }, "bridgeSessionDiedListener");
4430
+ bridgeDisconnectedListener = /* @__PURE__ */ __name(() => {
4431
+ this.onBridgeDisconnected();
4432
+ }, "bridgeDisconnectedListener");
4091
4433
  bridgePermissionRequestListener = /* @__PURE__ */ __name((event) => {
4092
4434
  void this.dispatchPermissionRequest(event).catch((err) => {
4093
4435
  process.stderr.write(`[${this.name}] permission relay failed for request ${sanitizeLogText(event.requestId, 128)}: ${this.lifecycleError(err)}
@@ -5570,12 +5912,21 @@ ${promptText}` : promptText;
5570
5912
  this.unattendedMemorySessions.delete(sessionId);
5571
5913
  this.removePendingPermissionsForSession(sessionId);
5572
5914
  }
5915
+ /**
5916
+ * Called when the standalone ACP bridge process exits. Its in-flight turns
5917
+ * never settle, but crash recovery restores the sessions on a fresh bridge,
5918
+ * so overrides must clear only turn-scoped transient state (never session
5919
+ * routing) and must not fabricate terminal outcomes for interrupted turns.
5920
+ */
5921
+ onBridgeDisconnected() {
5922
+ }
5573
5923
  onSessionRetiring(_sessionId) {
5574
5924
  }
5575
5925
  attachBridgeEvents(bridge) {
5576
5926
  bridge.on("toolCall", this.bridgeToolCallListener);
5577
5927
  bridge.on("backgroundResponse", this.bridgeBackgroundResponseListener);
5578
5928
  bridge.on("sessionDied", this.bridgeSessionDiedListener);
5929
+ bridge.on("disconnected", this.bridgeDisconnectedListener);
5579
5930
  bridge.on("permissionRequest", this.bridgePermissionRequestListener);
5580
5931
  bridge.on("permissionResolved", this.bridgePermissionResolvedListener);
5581
5932
  }
@@ -5583,6 +5934,7 @@ ${promptText}` : promptText;
5583
5934
  bridge.off("toolCall", this.bridgeToolCallListener);
5584
5935
  bridge.off("backgroundResponse", this.bridgeBackgroundResponseListener);
5585
5936
  bridge.off("sessionDied", this.bridgeSessionDiedListener);
5937
+ bridge.off("disconnected", this.bridgeDisconnectedListener);
5586
5938
  bridge.off("permissionRequest", this.bridgePermissionRequestListener);
5587
5939
  bridge.off("permissionResolved", this.bridgePermissionResolvedListener);
5588
5940
  }
@@ -6020,6 +6372,21 @@ ${requestList}`);
6020
6372
  binding.released = true;
6021
6373
  this.releaseQueuedTurn(binding.sessionId);
6022
6374
  }
6375
+ /**
6376
+ * Follow a task onto the session its reload healed to (a superseded
6377
+ * redirect). The queue reservation and the staleness generation are keyed
6378
+ * by session id, so both must move with the binding: leaving them behind
6379
+ * keeps the stale id "busy" forever and drops the turn on a generation the
6380
+ * replacement never had.
6381
+ */
6382
+ moveNamedTurnBinding(binding, sessionId) {
6383
+ if (binding.sessionId !== null) {
6384
+ this.releaseQueuedTurn(binding.sessionId);
6385
+ }
6386
+ binding.sessionId = sessionId;
6387
+ binding.generation = this.sessionGenerations.get(sessionId) ?? 0;
6388
+ this.reserveQueuedTurn(sessionId);
6389
+ }
6023
6390
  finishNamedTurnBinding(envelope) {
6024
6391
  const binding = this.namedTurnBindings.get(envelope);
6025
6392
  if (!binding)
@@ -6075,12 +6442,51 @@ ${requestList}`);
6075
6442
  return true;
6076
6443
  }
6077
6444
  }
6445
+ /**
6446
+ * The actionable recovery message for a worktree task whose ownership state
6447
+ * the daemon refused to restore. Both codes come from the load/resume route
6448
+ * — the reset route resumes an interrupted transfer itself and reports a
6449
+ * broken marker as invalid state — so they surface on selection and on a
6450
+ * message, wrapped in the manager's generic load failure.
6451
+ *
6452
+ * Clearing always acts on the *selected* task, so pointing the user at a
6453
+ * clear is only safe when the task that failed is the selected one. Aimed at
6454
+ * any other task it would run a full ownership transfer against a healthy
6455
+ * one and destroy that conversation, so the alternative points at the close
6456
+ * that works on the broken task without loading it. Both name that task.
6457
+ */
6458
+ async worktreeRecoveryMessage(envelope, error) {
6459
+ const code = readDaemonHttpErrorCode(error);
6460
+ if (code !== "worktree_reset_interrupted" && code !== "worktree_marker_missing") {
6461
+ return void 0;
6462
+ }
6463
+ const interrupted = code === "worktree_reset_interrupted";
6464
+ const failedTaskName = error instanceof NamedSessionTaskError ? error.taskName : void 0;
6465
+ const safeTaskName = failedTaskName === void 0 ? void 0 : sanitizeDisplayText(failedTaskName, 32);
6466
+ const subject = safeTaskName === void 0 ? "The task" : `Task "${safeTaskName}"`;
6467
+ const problem = interrupted ? "was interrupted while being reset" : "cannot verify its worktree because its ownership marker is missing";
6468
+ if (safeTaskName !== void 0 && failedTaskName === await this.selectedTaskName(envelope)) {
6469
+ return `${subject} ${problem}. Its files were not changed. ${interrupted ? "Clear the task again to finish the reset." : "Clear the task to restart it in the same worktree, or close it."}`;
6470
+ }
6471
+ const remedy = safeTaskName === void 0 ? "select this task first or close it" : `select this task first or close it with ${this.prefixedCommand(`/session close ${safeTaskName}`)}`;
6472
+ return `${subject} ${problem}. Its files were not changed. Clearing now would reset the selected task instead, so ${remedy}.`;
6473
+ }
6474
+ async selectedTaskName(envelope) {
6475
+ const namedSessions = this.namedSessions;
6476
+ if (!namedSessions)
6477
+ return void 0;
6478
+ try {
6479
+ return (await namedSessions.current(this.namedSessionOwner(envelope)))?.name;
6480
+ } catch {
6481
+ return void 0;
6482
+ }
6483
+ }
6078
6484
  async sendNamedSessionError(envelope, error) {
6079
6485
  if (error instanceof Error && error.cause !== void 0) {
6080
6486
  process.stderr.write(`[${sanitizeLogText(this.name, 64)}] named-session operation failed: ${this.lifecycleError(error)} | cause: ${this.lifecycleError(error.cause)}
6081
6487
  `);
6082
6488
  }
6083
- const message = error instanceof Error ? sanitizeDisplayText(error.message, 500) : "Named-session operation failed.";
6489
+ const message = await this.worktreeRecoveryMessage(envelope, error) ?? (error instanceof Error ? sanitizeDisplayText(error.message, 500) : "Named-session operation failed.");
6084
6490
  await this.sendThreadMessage(envelope.chatId, envelope.threadId, message || "Named-session operation failed.");
6085
6491
  }
6086
6492
  async handleNamedSessionsCommand(envelope, args) {
@@ -6125,7 +6531,7 @@ ${requestList}`);
6125
6531
  }
6126
6532
  case "new": {
6127
6533
  const isolation = parts.length === 2 && parts[1] === "--worktree" ? "worktree" : "shared";
6128
- if (isolation === "shared" && parts.length !== 1 || isolation === "worktree" && parts.length !== 2) {
6534
+ if (isolation === "shared" && parts.length !== 1 || isolation === "worktree" && parts.length !== 2 || parts[0]?.startsWith("-")) {
6129
6535
  break;
6130
6536
  }
6131
6537
  const created = await namedSessions.create(owner, parts[0], isolation);
@@ -6186,6 +6592,7 @@ ${requestList}`);
6186
6592
  registerSharedCommands() {
6187
6593
  const doClear = /* @__PURE__ */ __name(async (envelope) => {
6188
6594
  let resetTaskName;
6595
+ let resetWorktreeKept = false;
6189
6596
  let removedIds;
6190
6597
  const retiringSessionId = this.namedSessions ? void 0 : this.router.getSession(this.name, envelope.senderId, envelope.chatId, envelope.threadId);
6191
6598
  if (retiringSessionId)
@@ -6194,8 +6601,18 @@ ${requestList}`);
6194
6601
  try {
6195
6602
  const reset = await this.namedSessions.reset(this.namedSessionOwner(envelope));
6196
6603
  resetTaskName = reset?.name;
6604
+ resetWorktreeKept = reset?.worktreeKept ?? false;
6197
6605
  removedIds = reset ? [reset.previousSessionId] : [];
6198
6606
  } catch (error) {
6607
+ const code = readDaemonHttpErrorCode(error);
6608
+ if (code !== void 0) {
6609
+ process.stderr.write(`[${sanitizeLogText(this.name, 64)}] worktree reset failed (${sanitizeLogText(code, 64)}): ${this.lifecycleError(error)}
6610
+ `);
6611
+ }
6612
+ if (code === "worktree_reset_active") {
6613
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Task is busy. Wait for the running prompt to finish (or cancel it), then try again.");
6614
+ return;
6615
+ }
6199
6616
  await this.sendNamedSessionError(envelope, error);
6200
6617
  return;
6201
6618
  }
@@ -6250,7 +6667,7 @@ ${requestList}`);
6250
6667
  }
6251
6668
  this.discardRetiredSession(this.bridge, id, "cleared");
6252
6669
  }
6253
- await this.sendThreadMessage(envelope.chatId, envelope.threadId, resetTaskName ? `Task "${resetTaskName}" reset with a fresh conversation.` : "Session cleared. The next message starts a fresh conversation.");
6670
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, resetTaskName ? resetWorktreeKept ? `Task "${resetTaskName}" reset with a fresh conversation; its worktree and files were kept.` : `Task "${resetTaskName}" reset with a fresh conversation.` : "Session cleared. The next message starts a fresh conversation.");
6254
6671
  } else {
6255
6672
  await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No active session to clear.");
6256
6673
  }
@@ -7775,8 +8192,10 @@ ${text}`;
7775
8192
  return;
7776
8193
  }
7777
8194
  try {
7778
- const resumed = await this.namedSessions.resumeReserved(this.namedSessionOwner(envelope), namedTurn.sessionId);
7779
- sessionId = resumed ? namedTurn.sessionId : void 0;
8195
+ sessionId = await this.namedSessions.resumeReserved(this.namedSessionOwner(envelope), namedTurn.sessionId);
8196
+ if (sessionId && sessionId !== namedTurn.sessionId) {
8197
+ this.moveNamedTurnBinding(namedTurn, sessionId);
8198
+ }
7780
8199
  } catch (error) {
7781
8200
  await this.sendNamedSessionError(envelope, error);
7782
8201
  return;
@@ -8489,6 +8908,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
8489
8908
  activePrompts = /* @__PURE__ */ new Set();
8490
8909
  activePromptControllers = /* @__PURE__ */ new Map();
8491
8910
  availableCommandsBySession = /* @__PURE__ */ new Map();
8911
+ toolCallKindsBySession = /* @__PURE__ */ new Map();
8492
8912
  turnBarriers = /* @__PURE__ */ new Map();
8493
8913
  channelLoopToolHandlers = [];
8494
8914
  channelLoopDisabledSessions = /* @__PURE__ */ new Set();
@@ -8595,6 +9015,38 @@ var DaemonChannelBridge = class extends EventEmitter2 {
8595
9015
  }
8596
9016
  return session.sessionId;
8597
9017
  }
9018
+ /**
9019
+ * Transfer a worktree session's checkout ownership to a fresh replacement
9020
+ * session (daemon `session_worktree_reset_v1`). The returned id is the
9021
+ * replacement's; the superseded session's clients stay bound to it (and
9022
+ * are forgotten by the caller). Gated on the capability flag so a daemon
9023
+ * without reset support fails before any session is created.
9024
+ */
9025
+ async resetWorktreeSession(sessionId, cwd, options, bindingToken) {
9026
+ if (!this.options.sessionWorktreeReset) {
9027
+ throw new Error("The daemon does not support worktree reset for Channel tasks.");
9028
+ }
9029
+ const lifecycleGeneration = this.lifecycleGeneration;
9030
+ const session = await this.options.sessionFactory({
9031
+ workspaceCwd: cwd || this.options.cwd,
9032
+ modelServiceId: this.options.modelServiceId,
9033
+ sessionScope: this.options.sessionScope ?? "thread",
9034
+ ...options?.approvalMode ? { approvalMode: options.approvalMode } : {},
9035
+ ...options?.sourceId ? { sourceId: options.sourceId } : {},
9036
+ worktreeReset: { sessionId }
9037
+ });
9038
+ if (lifecycleGeneration !== this.lifecycleGeneration) {
9039
+ await this.rejectStaleSession(session);
9040
+ }
9041
+ this.attachSession(session, bindingToken);
9042
+ if (options?.enableChannelLoops === false) {
9043
+ this.channelLoopDisabledSessions.add(session.sessionId);
9044
+ void this.reconcileChannelLoopMcpForSession(session.sessionId);
9045
+ } else {
9046
+ await this.reconcileChannelLoopMcpForSession(session.sessionId);
9047
+ }
9048
+ return session.sessionId;
9049
+ }
8598
9050
  registerChannelLoopToolHandler(handler) {
8599
9051
  if (!this.channelLoopToolHandlers.includes(handler)) {
8600
9052
  this.channelLoopToolHandlers.push(handler);
@@ -9001,15 +9453,23 @@ var DaemonChannelBridge = class extends EventEmitter2 {
9001
9453
  case "tool_call":
9002
9454
  case "tool_call_update": {
9003
9455
  const toolCallId = getString(update["toolCallId"]);
9004
- const kind = getString(update["kind"]);
9456
+ const explicitKind = getString(update["kind"]);
9005
9457
  const meta = isRecord3(update["_meta"]) ? update["_meta"] : void 0;
9006
- if (!kind && toolCallId && getString(update["status"]) === "in_progress" && (meta?.["shellProgress"] !== void 0 || meta?.["subagentProgress"] === true)) {
9458
+ if (!explicitKind && toolCallId && getString(update["status"]) === "in_progress" && (meta?.["shellProgress"] !== void 0 || meta?.["subagentProgress"] === true)) {
9007
9459
  break;
9008
9460
  }
9461
+ let sessionKinds = this.toolCallKindsBySession.get(sessionId);
9462
+ const kind = explicitKind || sessionKinds?.get(toolCallId ?? "");
9009
9463
  if (!toolCallId || !kind) {
9010
9464
  this.emitProtocolError(`Malformed daemon ${type} event`, update);
9011
9465
  break;
9012
9466
  }
9467
+ if (type === "tool_call" || explicitKind) {
9468
+ const kinds = sessionKinds ?? /* @__PURE__ */ new Map();
9469
+ kinds.set(toolCallId, kind);
9470
+ this.toolCallKindsBySession.set(sessionId, kinds);
9471
+ sessionKinds = kinds;
9472
+ }
9013
9473
  const event = {
9014
9474
  sessionId,
9015
9475
  toolCallId,
@@ -9022,6 +9482,12 @@ var DaemonChannelBridge = class extends EventEmitter2 {
9022
9482
  this.emitResponseBoundary(sessionId);
9023
9483
  }
9024
9484
  this.emit("toolCall", event);
9485
+ if (event.status === "completed" || event.status === "failed") {
9486
+ sessionKinds?.delete(toolCallId);
9487
+ if (sessionKinds?.size === 0) {
9488
+ this.toolCallKindsBySession.delete(sessionId);
9489
+ }
9490
+ }
9025
9491
  break;
9026
9492
  }
9027
9493
  case "plan": {
@@ -9149,6 +9615,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
9149
9615
  this.abortActivePrompts(sessionId);
9150
9616
  this.activePrompts.delete(sessionId);
9151
9617
  this.availableCommandsBySession.delete(sessionId);
9618
+ this.toolCallKindsBySession.delete(sessionId);
9152
9619
  if (this.latestAvailableCommandsSessionId === sessionId) {
9153
9620
  this.latestAvailableCommandsSessionId = Array.from(this.availableCommandsBySession.keys()).at(-1);
9154
9621
  }