@qwen-code/qwen-code 0.23.1-preview.2 → 0.23.2-nightly.20260909.2e212144d3

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 (335) hide show
  1. package/README.md +35 -15
  2. package/bundled/computer-use/SKILL.md +189 -116
  3. package/bundled/goal-draft/SKILL.md +23 -13
  4. package/bundled/qc-helper/docs/_meta.ts +1 -0
  5. package/bundled/qc-helper/docs/configuration/auth.md +1 -1
  6. package/bundled/qc-helper/docs/configuration/model-providers.md +66 -16
  7. package/bundled/qc-helper/docs/configuration/settings.md +50 -0
  8. package/bundled/qc-helper/docs/conversations-recovery.md +102 -0
  9. package/bundled/qc-helper/docs/features/_meta.ts +1 -0
  10. package/bundled/qc-helper/docs/features/channels/dingtalk.md +1 -1
  11. package/bundled/qc-helper/docs/features/channels/github.md +1 -9
  12. package/bundled/qc-helper/docs/features/channels/overview.md +27 -52
  13. package/bundled/qc-helper/docs/features/channels/qqbot.md +1 -2
  14. package/bundled/qc-helper/docs/features/commands.md +79 -17
  15. package/bundled/qc-helper/docs/features/computer-use.md +9 -7
  16. package/bundled/qc-helper/docs/features/cross-session-protocol.md +291 -0
  17. package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
  18. package/bundled/qc-helper/docs/features/goals.md +17 -3
  19. package/bundled/qc-helper/docs/features/sub-agents.md +8 -0
  20. package/bundled/qc-helper/docs/qwen-serve.md +80 -48
  21. package/chunks/{MaxSizedBox-IYIQ43IZ.js → MaxSizedBox-ZBGWYJZW.js} +29 -28
  22. package/chunks/{StandaloneSessionPicker-AWB2OHX6.js → StandaloneSessionPicker-NR5ACIJZ.js} +48 -47
  23. package/chunks/{acp-startup-profiler-BAL4LJTN.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
  24. package/chunks/{acpAgent-ZC57OLS4.js → acpAgent-DM6XRCDQ.js} +361 -210
  25. package/chunks/{agent-GEBPAEJS.js → agent-EF3IIYE3.js} +20 -20
  26. package/chunks/{agent-headless-63ZEYAJK.js → agent-headless-5J2KFYR4.js} +20 -20
  27. package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-VIW2FG7G.js} +32 -9
  28. package/chunks/{artifact-tool-P52OKKEF.js → artifact-tool-G5LHNECG.js} +1 -1
  29. package/chunks/{askUserQuestion-3KAYLLMM.js → askUserQuestion-R3TXY77M.js} +1 -1
  30. package/chunks/{bridge-MHWO5I5T.js → bridge-LEMQM6QE.js} +32 -31
  31. package/chunks/{channel-management-service-NFRZXQFO.js → channel-management-service-TGF6XFXT.js} +4 -4
  32. package/chunks/{channel-settings-store-T7PMIHKC.js → channel-settings-store-FV365JSF.js} +40 -39
  33. package/chunks/{channel-worker-group-O2BWK5F7.js → channel-worker-group-SQ5FRWOH.js} +7 -7
  34. package/chunks/{channel-worker-manager-4WP7VJOD.js → channel-worker-manager-TU4ZNWOE.js} +7 -7
  35. package/chunks/{channel-worker-supervisor-CCUXD6J5.js → channel-worker-supervisor-EMITFMCP.js} +4 -4
  36. package/chunks/{chunk-3SH53ANB.js → chunk-22GORRNY.js} +12 -0
  37. package/chunks/{chunk-OFB36ZBA.js → chunk-2HYOOFDS.js} +10 -7
  38. package/chunks/chunk-2Z3T52OC.js +82 -0
  39. package/chunks/{chunk-LYHYXJJ3.js → chunk-34VPADLG.js} +3 -3
  40. package/chunks/{chunk-C7M445SS.js → chunk-3A2IMUDH.js} +14 -2
  41. package/chunks/{chunk-P5Z7VD23.js → chunk-3O77M472.js} +294 -87
  42. package/chunks/{chunk-4OCYWXKF.js → chunk-43EUMPKQ.js} +3 -3
  43. package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
  44. package/chunks/{chunk-VMFPZXRT.js → chunk-4DIMJKWU.js} +64 -43
  45. package/chunks/{chunk-ZRVFHLLK.js → chunk-5DQ4YTIZ.js} +1 -1
  46. package/chunks/{chunk-VYCJITND.js → chunk-5HV2HPO7.js} +1 -1
  47. package/chunks/{chunk-22QOQKG4.js → chunk-5WBA3DEF.js} +1 -1
  48. package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
  49. package/chunks/{chunk-I7UNCY24.js → chunk-6GAYNM3F.js} +3 -3
  50. package/chunks/{chunk-2C3XDBGL.js → chunk-6S7YYUUH.js} +4 -4
  51. package/chunks/{chunk-Y3C5COGI.js → chunk-6VIATHL7.js} +1 -1
  52. package/chunks/{chunk-XNC2TCUO.js → chunk-76I36BEM.js} +4 -4
  53. package/chunks/{chunk-B54PFQS5.js → chunk-7CLLH5TI.js} +1 -1
  54. package/chunks/{chunk-RGAQDQ3Z.js → chunk-7IDZFJAV.js} +18 -9
  55. package/chunks/{chunk-5Z4FCEPY.js → chunk-7K4GGN3D.js} +606 -109
  56. package/chunks/{chunk-WLZRMF3C.js → chunk-7KZVXJ4U.js} +353 -11
  57. package/chunks/{chunk-REDVV5NC.js → chunk-7WCJEY3A.js} +7 -7
  58. package/chunks/{chunk-I67KJGM6.js → chunk-A7QZIGRB.js} +3 -3
  59. package/chunks/{chunk-SHX2HIE7.js → chunk-ATBLEXXV.js} +7 -2
  60. package/chunks/{chunk-RH344FKI.js → chunk-AUTUFD5X.js} +1 -1
  61. package/chunks/chunk-AXMWHKXA.js +42 -0
  62. package/chunks/{chunk-WFXD5OZH.js → chunk-AXWTG6R7.js} +2 -5
  63. package/chunks/{chunk-TSLRORQR.js → chunk-BDAVT6K2.js} +1809 -1588
  64. package/chunks/{chunk-HWZOOSEB.js → chunk-BDP3NTWD.js} +3 -3
  65. package/chunks/{chunk-RD3VPM4E.js → chunk-BZUHZCUO.js} +2 -2
  66. package/chunks/{chunk-HPE4LEWX.js → chunk-C24ZDDNY.js} +1 -1
  67. package/chunks/{chunk-R7TKFIQO.js → chunk-CALNF3Z3.js} +1 -1
  68. package/chunks/{chunk-RPFJJ33Z.js → chunk-CALTQWTZ.js} +1 -1
  69. package/chunks/{chunk-BF3RUIVP.js → chunk-CH2YDT6X.js} +36 -38
  70. package/chunks/{chunk-LD53HMPV.js → chunk-CRZBDVP2.js} +1 -0
  71. package/chunks/{chunk-GEV66YGE.js → chunk-D6AGS266.js} +1 -1
  72. package/chunks/{chunk-EPZWBYQI.js → chunk-D7DFZAK2.js} +19 -11
  73. package/chunks/{chunk-5V4B3EWA.js → chunk-DARWOZY6.js} +1 -1
  74. package/chunks/{chunk-XX4MBBFW.js → chunk-DGNRLJ6S.js} +4 -4
  75. package/chunks/{chunk-UTVIIA7N.js → chunk-DVOCOIS5.js} +1 -1
  76. package/chunks/{chunk-RQNAO42A.js → chunk-E4LXNQAK.js} +1 -1
  77. package/chunks/{chunk-EGRFCIXD.js → chunk-EATP5QCN.js} +84 -25
  78. package/chunks/{chunk-3RMVM33U.js → chunk-EDSU3VUG.js} +12 -5
  79. package/chunks/{chunk-733KQL63.js → chunk-EE5ZD4XU.js} +3 -3
  80. package/chunks/{chunk-QQGAR64U.js → chunk-EN3Q2S3J.js} +4 -4
  81. package/chunks/{chunk-PLUAIHZO.js → chunk-EOLGAQ25.js} +17 -16
  82. package/chunks/{chunk-37SOBIA3.js → chunk-ERXNTINK.js} +1 -1
  83. package/chunks/{chunk-L36LLVA5.js → chunk-EYCW6UF2.js} +7 -7
  84. package/chunks/{chunk-ZELCTN6Y.js → chunk-F23YN37B.js} +10 -0
  85. package/chunks/{chunk-FPGTNKCP.js → chunk-F3M6P6IQ.js} +199 -1
  86. package/chunks/{chunk-B44JBZBB.js → chunk-F4SAL7WM.js} +91 -3
  87. package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
  88. package/chunks/{chunk-SI6Q52UI.js → chunk-FEEVHJOR.js} +3 -3
  89. package/chunks/{chunk-75UQFGFE.js → chunk-FN4KHWCL.js} +1 -1
  90. package/chunks/{chunk-WQBR7LN5.js → chunk-FRS3P7MQ.js} +15 -2
  91. package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
  92. package/chunks/{chunk-Z6DDPSGJ.js → chunk-GNY7B3CA.js} +1 -1
  93. package/chunks/{chunk-FDOGGKAA.js → chunk-GSFV5RQW.js} +2 -0
  94. package/chunks/{chunk-XBVNNDPK.js → chunk-GSYD7MYP.js} +8 -3
  95. package/chunks/{chunk-ERMAXPXA.js → chunk-HIXUUCGY.js} +187 -12
  96. package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
  97. package/chunks/{chunk-3K456UJF.js → chunk-HSO6D4KX.js} +93 -28
  98. package/chunks/{chunk-ANVC5CSK.js → chunk-HUJJFSMO.js} +10 -10
  99. package/chunks/{chunk-C4NXRR7T.js → chunk-HW4MRP4V.js} +2 -2
  100. package/chunks/{chunk-PMGWY6ZP.js → chunk-HWLLUDIA.js} +113 -18
  101. package/chunks/{chunk-RCUWMVN3.js → chunk-HZ2HUXX7.js} +1 -1
  102. package/chunks/{chunk-7PMKXGRP.js → chunk-IKK6NNS6.js} +91 -31
  103. package/chunks/{chunk-IMWCUWQT.js → chunk-J3TJH52D.js} +1 -1
  104. package/chunks/{chunk-BNWIX6BM.js → chunk-JFAGT5YG.js} +3 -3
  105. package/chunks/{chunk-RSU3I6UL.js → chunk-JGTMTJSQ.js} +1 -1
  106. package/chunks/{chunk-LTCI6ZOJ.js → chunk-JYGIJA4W.js} +1 -1
  107. package/chunks/{chunk-537SQ2AI.js → chunk-KECCLCXM.js} +146 -24
  108. package/chunks/{chunk-KAZWXVI3.js → chunk-KEPC5BOL.js} +5 -5
  109. package/chunks/{chunk-HZS3JRQW.js → chunk-L5VHJYHH.js} +40 -2
  110. package/chunks/{chunk-KTLT7VCX.js → chunk-LKBOBUA2.js} +2 -2
  111. package/chunks/{chunk-TDHVOZ65.js → chunk-LOBKNYPR.js} +2 -2
  112. package/chunks/{chunk-QW7BUOSI.js → chunk-LOVGQ3HZ.js} +26 -9
  113. package/chunks/{chunk-5FYGZ7E3.js → chunk-MUF4UGPB.js} +2 -2
  114. package/chunks/chunk-N3Z6Q7KC.js +384 -0
  115. package/chunks/{chunk-JOV46WGX.js → chunk-NB3NDQQK.js} +1 -1
  116. package/chunks/chunk-NFXXBWSE.js +463 -0
  117. package/chunks/chunk-NOO4QFXM.js +171 -0
  118. package/chunks/{chunk-PQSCGZT2.js → chunk-NPKCVSXX.js} +26 -2
  119. package/chunks/{chunk-FXYNIZPW.js → chunk-NV4YYXFT.js} +51 -10
  120. package/chunks/{chunk-FWH4736Q.js → chunk-O6BFERWN.js} +3 -3
  121. package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
  122. package/chunks/{chunk-C55CR5I4.js → chunk-OVTPETDL.js} +6 -6
  123. package/chunks/chunk-PLEBBGHL.js +1401 -0
  124. package/chunks/{chunk-Z6KFLEG7.js → chunk-PSPAM24S.js} +1 -0
  125. package/chunks/{chunk-RRCNEW2A.js → chunk-PWR6BQ3U.js} +58 -4
  126. package/chunks/{chunk-SHK2SIR5.js → chunk-QA2B26PL.js} +4 -4
  127. package/chunks/{chunk-NFIDVZND.js → chunk-QB3KS3N3.js} +2 -21
  128. package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
  129. package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
  130. package/chunks/{chunk-MFCWL4LI.js → chunk-SK6VACCM.js} +936 -481
  131. package/chunks/{chunk-SD7Y2PMC.js → chunk-SM66GFKJ.js} +2 -2
  132. package/chunks/{chunk-ADJD4LZF.js → chunk-SNMUO5Z7.js} +1 -1
  133. package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
  134. package/chunks/{chunk-IRKQ4YYX.js → chunk-SVWWF5TZ.js} +29 -1
  135. package/chunks/{chunk-YLFICBYK.js → chunk-SYKPMH2X.js} +3 -3
  136. package/chunks/{chunk-5HBA2Z7V.js → chunk-TGNNLRC3.js} +2 -3
  137. package/chunks/{chunk-AX23QSX3.js → chunk-TRQNRP2H.js} +4 -4
  138. package/chunks/{chunk-AUJOWIT5.js → chunk-UQOP2APG.js} +4 -24
  139. package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
  140. package/chunks/{chunk-IGOIYZBG.js → chunk-VAWM3A5N.js} +2 -2
  141. package/chunks/{chunk-6KYWU726.js → chunk-VJJXG73H.js} +417 -292
  142. package/chunks/{chunk-ZNI3V2XA.js → chunk-VJWJOKOQ.js} +2 -2
  143. package/chunks/{chunk-AWDF462I.js → chunk-VR6Y23FW.js} +2 -2
  144. package/chunks/{chunk-T7TP5UQL.js → chunk-VX2NR3SD.js} +21 -6
  145. package/chunks/{chunk-65GHQ4FX.js → chunk-WDVV3LRM.js} +707 -216
  146. package/chunks/{chunk-KP5QK3FB.js → chunk-WEU6O6VN.js} +397 -54
  147. package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
  148. package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
  149. package/chunks/{chunk-YHDGABDC.js → chunk-XKBFYTCD.js} +1 -1
  150. package/chunks/{chunk-RUMSY4ES.js → chunk-Y7YHAY32.js} +28 -10
  151. package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
  152. package/chunks/{chunk-B5FF3LRF.js → chunk-YIE6REQ5.js} +29 -17
  153. package/chunks/{chunk-E4VX6LXB.js → chunk-YZTGGCEE.js} +10 -2
  154. package/chunks/{chunk-TXAEXF2B.js → chunk-ZEFWBG2C.js} +737 -1136
  155. package/chunks/{chunk-AIMZIXZM.js → chunk-ZM2TCZZ7.js} +5 -7
  156. package/chunks/{chunk-ZT3XUGSU.js → chunk-ZZ7RVOTU.js} +135 -26
  157. package/chunks/{config-utils-F4CFJ4MW.js → config-utils-SXFK3G4X.js} +33 -32
  158. package/chunks/{contextCommand-OIIGGOMU.js → contextCommand-QFPD26QO.js} +31 -30
  159. package/chunks/{core-runtime-JEHLOGMB.js → core-runtime-VXKNBODM.js} +35 -33
  160. package/chunks/{create-sub-session-MVFBE5RA.js → create-sub-session-7WSQETFR.js} +30 -29
  161. package/chunks/{daemon-LCUELM6E.js → daemon-U2456K5H.js} +2 -2
  162. package/chunks/{daemon-git-worktree-guard-5FTKLJOU.js → daemon-git-worktree-guard-I4DCSDUS.js} +29 -28
  163. package/chunks/{daemon-status-provider-P6A5MPMW.js → daemon-status-provider-5UV56RI4.js} +36 -35
  164. package/chunks/{daemon-trust-policy-ZJ3NFYUO.js → daemon-trust-policy-DKIBWTKU.js} +36 -35
  165. package/chunks/{daemon-trust-policy-monitor-6SDLEW7S.js → daemon-trust-policy-monitor-CPSD7UKT.js} +36 -35
  166. package/chunks/{deferred-core-runtime-DWOXIU5S.js → deferred-core-runtime-D2RF35BL.js} +29 -28
  167. package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
  168. package/chunks/{dist-P6YWBITG.js → dist-6YDUH3BB.js} +817 -152
  169. package/chunks/{dist-T4PRA5EZ.js → dist-BNQVF565.js} +2 -8
  170. package/chunks/{dist-AI25RVRA.js → dist-F34J4FZX.js} +1 -1
  171. package/chunks/{dist-3H3WODVS.js → dist-F6JLAJLE.js} +1 -1
  172. package/chunks/{dist-NXW4DUUX.js → dist-K5GHMXIG.js} +2 -2
  173. package/chunks/{dist-YNQU4CKC.js → dist-NP7QKLVG.js} +2 -2
  174. package/chunks/{dist-VCAS67N5.js → dist-UFTFGI6I.js} +1 -1
  175. package/chunks/{dist-I74QLLQS.js → dist-XLV33CLY.js} +1 -2
  176. package/chunks/{dist-XINEKB5A.js → dist-ZDNJK74R.js} +3 -7
  177. package/chunks/{edit-WPVXLL3T.js → edit-4IBADZ3O.js} +20 -20
  178. package/chunks/{enter-worktree-5A6VW6BN.js → enter-worktree-YFTKHXHZ.js} +2 -2
  179. package/chunks/{enterPlanMode-JSODW7E2.js → enterPlanMode-YN3GPQU5.js} +20 -20
  180. package/chunks/{environment-5LLJ3I3W.js → environment-E272IJMF.js} +32 -31
  181. package/chunks/{errors-IQT3YZEP.js → errors-CVAH3RWQ.js} +31 -30
  182. package/chunks/{exit-worktree-QV7E7KP6.js → exit-worktree-NF2XEMES.js} +3 -3
  183. package/chunks/{exitPlanMode-DDVFYNW4.js → exitPlanMode-24J5IHGC.js} +20 -20
  184. package/chunks/{fast-path-PAUQQEVU.js → fast-path-M5IDBMXF.js} +4 -4
  185. package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
  186. package/chunks/{glob-SQ7CTZ7F.js → glob-ERBD7JYP.js} +20 -20
  187. package/chunks/{goal-tools-UWZRCLQB.js → goal-tools-245ULLQT.js} +20 -20
  188. package/chunks/{handleAutoUpdate-RUPZZTSG.js → handleAutoUpdate-JDZHHZKK.js} +32 -31
  189. package/chunks/{i18n-SF5MPWEB.js → i18n-LA4D5IXM.js} +32 -29
  190. package/chunks/{image-gen-Q3RUTVKR.js → image-gen-XP4NNIYG.js} +4 -4
  191. package/chunks/{initializer-CK4WPYZG.js → initializer-SHPTSWUZ.js} +36 -35
  192. package/chunks/{installationInfo-IRPQEYRF.js → installationInfo-QEQEPB3G.js} +29 -28
  193. package/chunks/{list-E3PS3EBJ.js → list-IBHCQWTF.js} +39 -38
  194. package/chunks/{list-agents-I5TRH3J7.js → list-agents-EDPZCGKN.js} +5 -4
  195. package/chunks/{llm-JQKBOYAF.js → llm-JAWCQLA4.js} +81 -75
  196. package/chunks/{llm-content-generator-2QWGBW42.js → llm-content-generator-GOV3A23T.js} +23 -8
  197. package/chunks/{loadedSettingsAdapter-DGXGVYZS.js → loadedSettingsAdapter-RVE2GNVU.js} +36 -35
  198. package/chunks/{loggingContentGenerator-ZYURLJKK.js → loggingContentGenerator-SSHNN5YW.js} +22 -22
  199. package/chunks/{managed-npm-update-HTHR63EA.js → managed-npm-update-BHSTITQO.js} +29 -28
  200. package/chunks/{mcp-I7G2AEWS.js → mcp-6ZZ7P2HU.js} +36 -35
  201. package/chunks/{monitor-4R76BCRZ.js → monitor-RKK6GSHG.js} +20 -20
  202. package/chunks/{nonInteractiveCli-24OQ3VP2.js → nonInteractiveCli-UQHP3G6P.js} +76 -72
  203. package/chunks/{notebook-edit-PPSH7FEX.js → notebook-edit-YM47A7WO.js} +20 -20
  204. package/chunks/{open-with-auth-D6JD6LDS.js → open-with-auth-6MVIHMXB.js} +1 -1
  205. package/chunks/{openaiContentGenerator-K7V5EO7F.js → openaiContentGenerator-FHKDWNI2.js} +11 -11
  206. package/chunks/{pidfile-TGIUY2GG.js → pidfile-SIIEJEEH.js} +32 -29
  207. package/chunks/{processUtils-3USXUQWX.js → processUtils-JF7CWBJC.js} +2 -2
  208. package/chunks/{prompt-terminal-ledger-XHVZRXJI.js → prompt-terminal-ledger-FXXHAEQU.js} +30 -29
  209. package/chunks/{qwenContentGenerator-MPBOQB64.js → qwenContentGenerator-KFJ77JP6.js} +24 -24
  210. package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
  211. package/chunks/{read-file-R256LDWQ.js → read-file-S2NOCBIL.js} +4 -4
  212. package/chunks/{resumeHistoryUtils-S43LTFHD.js → resumeHistoryUtils-QHHPSQWU.js} +33 -32
  213. package/chunks/{ripGrep-L7HPZ75Y.js → ripGrep-F6TNOJUO.js} +5 -5
  214. package/chunks/{run-qwen-serve-CTFL5R6U.js → run-qwen-serve-KYBDQRDD.js} +229 -79
  215. package/chunks/{runtime-FS5TL6P7.js → runtime-3WNOFLCR.js} +43 -40
  216. package/chunks/{scheduled-tasks-QXPV3Q35.js → scheduled-tasks-RNBH56DJ.js} +34 -33
  217. package/chunks/{scheduler-EXU5HMVK.js → scheduler-ERMW7Q7B.js} +31 -30
  218. package/chunks/{send-message-GQKXGMPI.js → send-message-V5T3NMFM.js} +4 -4
  219. package/chunks/{serve-ITJC7WNN.js → serve-7NV46RMP.js} +36 -35
  220. package/chunks/{server-6JQY3PTU.js → server-6RZJR5QF.js} +1358 -932
  221. package/chunks/{session-PJDEKXD4.js → session-Z4EV7NVV.js} +107 -78
  222. package/chunks/{session-attachments-root-L37ORSST.js → session-attachments-root-SG5FC52X.js} +29 -28
  223. package/chunks/{session-pr-refresh-WIFD52YL.js → session-pr-refresh-ILC4Z3ZM.js} +33 -32
  224. package/chunks/{settings-LO6J5SAZ.js → settings-Y47SPE3X.js} +35 -34
  225. package/chunks/{shell-ANAFVYGR.js → shell-YBVCOPVO.js} +20 -20
  226. package/chunks/{skill-SHJWKSPH.js → skill-AXC63EBA.js} +4 -4
  227. package/chunks/{skill-settings-GX3XHZ5Q.js → skill-settings-AFPAYGLO.js} +35 -34
  228. package/chunks/{spawnChannel-WE42VBKM.js → spawnChannel-ZFL4J2V3.js} +29 -28
  229. package/chunks/{standalone-update-CWDIKJRP.js → standalone-update-Y2OZPLNJ.js} +31 -30
  230. package/chunks/{start-opentui-ui-BBHGFOTF.js → start-opentui-ui-G6TKT4LI.js} +2270 -1026
  231. package/chunks/{startInteractiveUI-FQX7LUYP.js → startInteractiveUI-YTNDPW7J.js} +1789 -2211
  232. package/chunks/{task-create-PMAFST2T.js → task-create-MWXJFRRM.js} +3 -3
  233. package/chunks/{task-list-R2HSY2NC.js → task-list-EYO3FE57.js} +2 -2
  234. package/chunks/{task-update-JYC57USF.js → task-update-2JJJRHMT.js} +3 -3
  235. package/chunks/{team-create-WKTPCH6D.js → team-create-BUFLGGSH.js} +20 -20
  236. package/chunks/{team-delete-CBHVBTPB.js → team-delete-IQZ6XGFI.js} +2 -2
  237. package/chunks/{team-plan-approval-Y23DL7WR.js → team-plan-approval-OUWWM42U.js} +20 -20
  238. package/chunks/{terminal-image-renderer-B646HBDW.js → terminal-image-renderer-WH2WV5ES.js} +29 -28
  239. package/chunks/{theme-manager-BNWESY26.js → theme-manager-5UDRARM2.js} +29 -28
  240. package/chunks/{tool-search-PVQ5O5Y2.js → tool-search-MCDIRPHN.js} +4 -4
  241. package/chunks/{total-session-admission-P5Z43KNW.js → total-session-admission-VL27U74Z.js} +33 -32
  242. package/chunks/{trustedFolders-FH2LT2MZ.js → trustedFolders-MSXT4VDD.js} +30 -29
  243. package/chunks/{update-relaunch-WOWTKJSN.js → update-relaunch-JKLEWVCB.js} +5 -5
  244. package/chunks/{updateCheck-3MYFMM35.js → updateCheck-ARTHAJT2.js} +31 -30
  245. package/chunks/{useAutoAcceptIndicator-Q7ZRRRKO.js → useAutoAcceptIndicator-YEAAGYVU.js} +38 -37
  246. package/chunks/{validateNonInterActiveAuth-MYEWJX3G.js → validateNonInterActiveAuth-EMRQKH5S.js} +71 -69
  247. package/chunks/{version-RO2FPO76.js → version-HFQU35WD.js} +3 -1
  248. package/chunks/{web-fetch-QAKY2LUA.js → web-fetch-QBXAO6VF.js} +7 -7
  249. package/chunks/{web-search-XA5Z4ZCD.js → web-search-2URQXA3A.js} +201 -13
  250. package/chunks/{web-shell-static-POZHGGXE.js → web-shell-static-BFDESDD4.js} +5 -4
  251. package/chunks/{workflow-QFIOCMDM.js → workflow-JDD6WDAH.js} +211 -75
  252. package/chunks/{workspace-providers-status-B2UD7RAG.js → workspace-providers-status-B4IKR6YJ.js} +38 -37
  253. package/chunks/{workspace-registration-store-VZLRTI3Q.js → workspace-registration-store-PJ3YHR45.js} +1 -2
  254. package/chunks/{workspace-registry-GYOGG6TM.js → workspace-registry-WVYJ5UGB.js} +33 -32
  255. package/chunks/{workspace-runtime-coordinator-7KRXGQ4V.js → workspace-runtime-coordinator-DXL5YVAG.js} +33 -32
  256. package/chunks/{workspace-service-DJEYGJE4.js → workspace-service-QNGAMVH7.js} +40 -39
  257. package/chunks/{workspace-skills-status-MOKNESUC.js → workspace-skills-status-BEISJIII.js} +36 -35
  258. package/chunks/{workspace-trust-reconciler-AXOSUTQW.js → workspace-trust-reconciler-ORYJF5L4.js} +40 -39
  259. package/chunks/{write-file-QOYVHAKK.js → write-file-DWLKFBTJ.js} +21 -21
  260. package/chunks/{zoom-image-UCCLGFNC.js → zoom-image-BYVIXSNQ.js} +4 -4
  261. package/cli.js +13 -13
  262. package/export-transcript-document.js +123 -119
  263. package/package.json +4 -4
  264. package/web-shell/assets/{abnfDiagram-VCTEODGH-CTstZpXw.js → abnfDiagram-VCTEODGH-C_8kzsly.js} +1 -1
  265. package/web-shell/assets/{arc-DKW0mbPo.js → arc-CDg7Zfpm.js} +1 -1
  266. package/web-shell/assets/{architectureDiagram-5GKGNRK7-DkMpJ42t.js → architectureDiagram-5GKGNRK7-DZzdCWyF.js} +1 -1
  267. package/web-shell/assets/{blockDiagram-NRAW4CY4-7Cp1_4i3.js → blockDiagram-NRAW4CY4-DI3B4gyR.js} +1 -1
  268. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BfaoSlBK.js → c4Diagram-UCG6FXSJ-CfOgwHZW.js} +1 -1
  269. package/web-shell/assets/channel-e4xwS72w.js +1 -0
  270. package/web-shell/assets/{chunk-2Q5K7J3B-_n1qzAio.js → chunk-2Q5K7J3B-B_PUth0g.js} +1 -1
  271. package/web-shell/assets/{chunk-5VM5RSS4-0cira5ZV.js → chunk-5VM5RSS4-CrKtvBIL.js} +1 -1
  272. package/web-shell/assets/{chunk-F27PBJKO-DseRXSHC.js → chunk-F27PBJKO-B4z2n8Py.js} +1 -1
  273. package/web-shell/assets/{chunk-G27WJ6UU-BehQWin0.js → chunk-G27WJ6UU-BUtrFEO8.js} +1 -1
  274. package/web-shell/assets/{chunk-JWPE2WC7-B5ftg1Bb.js → chunk-JWPE2WC7-Cqw3aXW0.js} +1 -1
  275. package/web-shell/assets/{chunk-LCL6LL3I-D7rnbVdk.js → chunk-LCL6LL3I-CZolnvls.js} +1 -1
  276. package/web-shell/assets/{chunk-POPQ4Y6H-2Bp-Orju.js → chunk-POPQ4Y6H-DivgasCa.js} +1 -1
  277. package/web-shell/assets/{chunk-SVP7TREG-CD2goGva.js → chunk-SVP7TREG--seyb1B6.js} +1 -1
  278. package/web-shell/assets/{chunk-XXDRQBXY-DzQt-Rji.js → chunk-XXDRQBXY-D7pHtuVM.js} +1 -1
  279. package/web-shell/assets/classDiagram-DTDB5LWJ-CzXfUUOt.js +1 -0
  280. package/web-shell/assets/classDiagram-v2-JRS7N3AN-CzXfUUOt.js +1 -0
  281. package/web-shell/assets/{cose-bilkent-JH36ORCC-C-BZXSUn.js → cose-bilkent-JH36ORCC-4MWaRF_3.js} +1 -1
  282. package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
  283. package/web-shell/assets/{cynefin-OW5HDTMX-BTcvowe1.js → cynefin-OW5HDTMX-nhJhAjgD.js} +1 -1
  284. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BoUE6K81.js → cynefinDiagram-5FMLGOSQ-NF-PwXlq.js} +1 -1
  285. package/web-shell/assets/{dagre-3AP2YEHR-BHxy9xeB.js → dagre-3AP2YEHR-Bu0ncdWP.js} +1 -1
  286. package/web-shell/assets/{diagram-S7CK7UJ4-DMiJIvDT.js → diagram-S7CK7UJ4-CsvhFHZC.js} +1 -1
  287. package/web-shell/assets/{diagram-UQ7AKVKN-DXV09Aes.js → diagram-UQ7AKVKN-Ck61sIB3.js} +1 -1
  288. package/web-shell/assets/{diagram-VSXAHHWV-CocpRomV.js → diagram-VSXAHHWV-D0171zrb.js} +1 -1
  289. package/web-shell/assets/{diagram-VX7I27RA-DL7nqtb4.js → diagram-VX7I27RA-DvdxY4UL.js} +1 -1
  290. package/web-shell/assets/{diagram-Z3DM3KII-CPZ2Jux_.js → diagram-Z3DM3KII-CGGpseiB.js} +1 -1
  291. package/web-shell/assets/{ebnfDiagram-PWID7BFC-BX-eVNsX.js → ebnfDiagram-PWID7BFC-K8-QMvY8.js} +1 -1
  292. package/web-shell/assets/{erDiagram-SSCWMZ5O-CPy_Ir6y.js → erDiagram-SSCWMZ5O-D316nAem.js} +1 -1
  293. package/web-shell/assets/{flowDiagram-A5DVABFB-eknAOte9.js → flowDiagram-A5DVABFB-B7siy_mn.js} +1 -1
  294. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-crAxw_t7.js → ganttDiagram-EL5Y4UJY-BZQDxzTu.js} +1 -1
  295. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-M29pa3Tc.js → gitGraphDiagram-WWUBYQGX-DZynLCSV.js} +1 -1
  296. package/web-shell/assets/{index-C9R-iojE.js → index-9ie6xLTM.js} +1 -1
  297. package/web-shell/assets/index-DirkXQEg.js +2164 -0
  298. package/web-shell/assets/index-DzdST_7L.css +36 -0
  299. package/web-shell/assets/{infoDiagram-RXCK75RN-XqspXdOU.js → infoDiagram-RXCK75RN-B0gr769A.js} +1 -1
  300. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-C5KFS-7j.js → ishikawaDiagram-5VMMS53U-0pQFfjvX.js} +1 -1
  301. package/web-shell/assets/{journeyDiagram-EYS64GPL-Cc57LVRo.js → journeyDiagram-EYS64GPL-DEGtClWb.js} +1 -1
  302. package/web-shell/assets/{kanban-definition-3QL26DDD-C81OG-AI.js → kanban-definition-3QL26DDD-CnN8gPzw.js} +1 -1
  303. package/web-shell/assets/{layout-CFVu37BB.js → layout-C_70RhaT.js} +1 -1
  304. package/web-shell/assets/{linear-ChBxdtWf.js → linear-BJ2ZLmcq.js} +1 -1
  305. package/web-shell/assets/{mermaid.core-CMLfue0w.js → mermaid.core-RlY0zPNC.js} +6 -6
  306. package/web-shell/assets/{mindmap-definition-FBJOCRG2-DFsvJThp.js → mindmap-definition-FBJOCRG2-CpVAxTNl.js} +1 -1
  307. package/web-shell/assets/{pegDiagram-XKGWAZYB-BzpRzM4F.js → pegDiagram-XKGWAZYB-DmrSv3hD.js} +1 -1
  308. package/web-shell/assets/{pieDiagram-E7YTZNPT-Cv0Kankl.js → pieDiagram-E7YTZNPT-CJmgp8KJ.js} +1 -1
  309. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-Bh2BJ3Ay.js → quadrantDiagram-AXDQQJYC-UsgOyNco.js} +1 -1
  310. package/web-shell/assets/{railroadDiagram-O6MQD6OU-y8rNDdDS.js → railroadDiagram-O6MQD6OU-DQ6gMs_W.js} +1 -1
  311. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-C0m2DKJ_.js → requirementDiagram-EFPCY7ZU-DhqadamF.js} +1 -1
  312. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-BzdGnSF4.js → sankeyDiagram-P5KCCOFB-R4WnURaE.js} +1 -1
  313. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DPzAVmzz.js → sequenceDiagram-WJ2MYXX4-D7BwMi_D.js} +1 -1
  314. package/web-shell/assets/{sizeCapture-X5ZJPWSS-LcHG28Zh.js → sizeCapture-X5ZJPWSS-Bqngz088.js} +1 -1
  315. package/web-shell/assets/{stateDiagram-HBIQ2CUA-C1Bzy3IT.js → stateDiagram-HBIQ2CUA-DwaXPGqn.js} +1 -1
  316. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-8GCQZAvv.js +1 -0
  317. package/web-shell/assets/{swimlanes-XN3QIQJK-Bftk8V64.js → swimlanes-XN3QIQJK-BsaLeRDY.js} +1 -1
  318. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-BoRBF2Yw.js +8 -0
  319. package/web-shell/assets/{timeline-definition-24CTP7MA-BfXHcN1A.js → timeline-definition-24CTP7MA-NJ9G-NUU.js} +1 -1
  320. package/web-shell/assets/{vennDiagram-4TSXK5OY-DRSlI9-V.js → vennDiagram-4TSXK5OY-Ca3W4rSq.js} +1 -1
  321. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CaLmqGau.js → wardleyDiagram-VM6X3IG4-OabvjC-6.js} +1 -1
  322. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-8lgUT6e8.js → xychartDiagram-S5SC5T6Z-C7rbjvpc.js} +1 -1
  323. package/web-shell/index.html +2 -2
  324. package/chunks/chunk-2LD5U7Q3.js +0 -114
  325. package/chunks/chunk-3UMWOKJC.js +0 -78
  326. package/chunks/chunk-IQAFKVXS.js +0 -22
  327. package/chunks/chunk-X35VIWWJ.js +0 -276
  328. package/chunks/chunk-ZJ2LM2SI.js +0 -198
  329. package/web-shell/assets/channel-CQx7VSAp.js +0 -1
  330. package/web-shell/assets/classDiagram-DTDB5LWJ-C-Uz8hHk.js +0 -1
  331. package/web-shell/assets/classDiagram-v2-JRS7N3AN-C-Uz8hHk.js +0 -1
  332. package/web-shell/assets/index-B4TLaxWs.js +0 -2142
  333. package/web-shell/assets/index-CCrkEbzz.css +0 -36
  334. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-LuuL5byY.js +0 -1
  335. 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": {
@@ -1216,118 +1245,6 @@ init_esbuild_shims();
1216
1245
  import { basename as basename3, join as join5 } from "node:path";
1217
1246
  import { randomUUID as randomUUID3 } from "node:crypto";
1218
1247
 
1219
- // packages/channels/base/dist/BlockStreamer.js
1220
- init_esbuild_shims();
1221
- var BlockStreamer = class {
1222
- static {
1223
- __name(this, "BlockStreamer");
1224
- }
1225
- buffer = "";
1226
- idleTimer = null;
1227
- sending = Promise.resolve();
1228
- opts;
1229
- /** Number of blocks emitted so far. */
1230
- blockCount = 0;
1231
- constructor(opts) {
1232
- this.opts = opts;
1233
- }
1234
- /** Feed a new text chunk from the agent stream. */
1235
- push(chunk) {
1236
- this.buffer += chunk;
1237
- this.clearIdleTimer();
1238
- this.checkEmit();
1239
- if (this.buffer.length > 0 && this.opts.idleMs > 0) {
1240
- this.idleTimer = setTimeout(() => this.onIdle(), this.opts.idleMs);
1241
- }
1242
- }
1243
- /** Flush all remaining buffered text. Awaits all pending sends. */
1244
- async flush() {
1245
- this.clearIdleTimer();
1246
- if (this.buffer.length > 0) {
1247
- this.emitBlock(this.buffer);
1248
- this.buffer = "";
1249
- }
1250
- await this.sending;
1251
- }
1252
- /** Drop buffered text and cancel future idle emission. */
1253
- stop() {
1254
- this.clearIdleTimer();
1255
- this.buffer = "";
1256
- }
1257
- /** Await already-queued sends without emitting the buffered text. */
1258
- async drain() {
1259
- await this.sending;
1260
- }
1261
- // ---------------------------------------------------------------------------
1262
- // Internal
1263
- // ---------------------------------------------------------------------------
1264
- checkEmit() {
1265
- while (this.buffer.length >= this.opts.maxChars) {
1266
- const bp = this.findBreakPoint(this.buffer, this.opts.maxChars);
1267
- this.emitBlock(this.buffer.slice(0, bp));
1268
- this.buffer = this.buffer.slice(bp);
1269
- }
1270
- if (this.buffer.length >= this.opts.minChars) {
1271
- const bp = this.findBlockBoundary(this.buffer);
1272
- if (bp > 0) {
1273
- this.emitBlock(this.buffer.slice(0, bp));
1274
- this.buffer = this.buffer.slice(bp);
1275
- }
1276
- }
1277
- }
1278
- onIdle() {
1279
- this.idleTimer = null;
1280
- if (this.buffer.length >= this.opts.minChars) {
1281
- this.emitBlock(this.buffer);
1282
- this.buffer = "";
1283
- }
1284
- }
1285
- emitBlock(text) {
1286
- const trimmed = text.trim();
1287
- if (!trimmed)
1288
- return;
1289
- const block = /\n[^\S\n]*$/.test(text) ? `${trimmed}
1290
- ` : trimmed;
1291
- this.blockCount++;
1292
- this.sending = this.sending.then(() => this.opts.send(block)).catch(() => {
1293
- });
1294
- }
1295
- /**
1296
- * Find the last paragraph boundary (\n\n) in the buffer.
1297
- * Returns the position after the boundary, or -1 if no suitable boundary
1298
- * exists at or after minChars.
1299
- */
1300
- findBlockBoundary(text) {
1301
- const last = text.lastIndexOf("\n\n");
1302
- if (last < 0 || last < this.opts.minChars)
1303
- return -1;
1304
- return last + 2;
1305
- }
1306
- /**
1307
- * Find the best break point at or before maxPos.
1308
- * Prefers paragraph break > newline > space > maxPos.
1309
- */
1310
- findBreakPoint(text, maxPos) {
1311
- const sub = text.slice(0, maxPos);
1312
- const para = sub.lastIndexOf("\n\n");
1313
- if (para > 0)
1314
- return para + 2;
1315
- const nl = sub.lastIndexOf("\n");
1316
- if (nl > 0)
1317
- return nl + 1;
1318
- const sp = sub.lastIndexOf(" ");
1319
- if (sp > 0)
1320
- return sp + 1;
1321
- return maxPos;
1322
- }
1323
- clearIdleTimer() {
1324
- if (this.idleTimer !== null) {
1325
- clearTimeout(this.idleTimer);
1326
- this.idleTimer = null;
1327
- }
1328
- }
1329
- };
1330
-
1331
1248
  // packages/channels/base/dist/ChannelProactiveDeliveryError.js
1332
1249
  init_esbuild_shims();
1333
1250
  var CHANNEL_PROACTIVE_DELIVERY_ERROR_CODE = "channel_proactive_delivery_error";
@@ -1763,6 +1680,49 @@ init_esbuild_shims();
1763
1680
  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
1681
  import { dirname as dirname3, isAbsolute, join as join4 } from "node:path";
1765
1682
  import process2 from "node:process";
1683
+ function readDaemonHttpErrorCode(error) {
1684
+ let current = error;
1685
+ for (let depth = 0; depth < 5; depth++) {
1686
+ if (typeof current !== "object" && typeof current !== "function" || current === null) {
1687
+ return void 0;
1688
+ }
1689
+ const record = current;
1690
+ if (record["name"] === "DaemonHttpError" && record["status"] === 409) {
1691
+ const body = record["body"];
1692
+ if (typeof body === "object" && body !== null && !Array.isArray(body)) {
1693
+ const code = body["code"];
1694
+ if (typeof code === "string" && code.length > 0)
1695
+ return code;
1696
+ }
1697
+ }
1698
+ current = record["cause"];
1699
+ }
1700
+ return void 0;
1701
+ }
1702
+ __name(readDaemonHttpErrorCode, "readDaemonHttpErrorCode");
1703
+ function readSupersededReplacementId(error) {
1704
+ let current = error;
1705
+ for (let depth = 0; depth < 5; depth++) {
1706
+ if (typeof current !== "object" && typeof current !== "function" || current === null) {
1707
+ return void 0;
1708
+ }
1709
+ const record = current;
1710
+ if (record["name"] === "DaemonHttpError" && record["status"] === 409) {
1711
+ const body = record["body"];
1712
+ if (typeof body === "object" && body !== null && !Array.isArray(body)) {
1713
+ const typedBody = body;
1714
+ if (typedBody["code"] !== "worktree_session_superseded") {
1715
+ return void 0;
1716
+ }
1717
+ const replacement = typedBody["replacementSessionId"];
1718
+ return typeof replacement === "string" && replacement.length > 0 ? replacement : void 0;
1719
+ }
1720
+ }
1721
+ current = record["cause"];
1722
+ }
1723
+ return void 0;
1724
+ }
1725
+ __name(readSupersededReplacementId, "readSupersededReplacementId");
1766
1726
  var SessionRouter = class {
1767
1727
  static {
1768
1728
  __name(this, "SessionRouter");
@@ -1773,9 +1733,11 @@ var SessionRouter = class {
1773
1733
  // session ID → target
1774
1734
  toCwd = /* @__PURE__ */ new Map();
1775
1735
  // session ID → cwd
1736
+ toManagedMeta = /* @__PURE__ */ new Map();
1776
1737
  creatingSessions = /* @__PURE__ */ new Map();
1777
1738
  sessionLoadWindows = /* @__PURE__ */ new Set();
1778
1739
  liveSessionIds = /* @__PURE__ */ new Set();
1740
+ staleBridgeBindings = /* @__PURE__ */ new Set();
1779
1741
  routeTokens = /* @__PURE__ */ new Map();
1780
1742
  lifecycleGeneration = 0;
1781
1743
  bridge;
@@ -1797,6 +1759,7 @@ var SessionRouter = class {
1797
1759
  setBridge(bridge) {
1798
1760
  this.bridge = bridge;
1799
1761
  this.liveSessionIds.clear();
1762
+ this.staleBridgeBindings.clear();
1800
1763
  }
1801
1764
  /** Set scope override for a specific channel. */
1802
1765
  setChannelScope(channelName, scope) {
@@ -2072,12 +2035,12 @@ var SessionRouter = class {
2072
2035
  this.endSessionLoad(loadWindow);
2073
2036
  }
2074
2037
  }
2075
- async loadManagedSession(sessionId, target, workspaceCwd, expectedCwd = workspaceCwd, isolation = "shared") {
2038
+ async loadManagedSession(sessionId, target, workspaceCwd, expectedCwd = workspaceCwd, isolation = "shared", allowSupersededRedirect = true) {
2076
2039
  if (this.liveSessionIds.has(sessionId)) {
2077
2040
  const actualCwd = this.validateManagedSessionIdentity(this.bridge, sessionId, workspaceCwd, expectedCwd, isolation);
2078
2041
  this.toTarget.set(sessionId, target);
2079
2042
  this.toCwd.set(sessionId, actualCwd);
2080
- return { loaded: false };
2043
+ return { loaded: false, sessionId };
2081
2044
  }
2082
2045
  const loadWindow = this.beginSessionLoad();
2083
2046
  const lifecycleGeneration = this.lifecycleGeneration;
@@ -2085,6 +2048,9 @@ var SessionRouter = class {
2085
2048
  const bindingToken = {};
2086
2049
  let loadedSessionId;
2087
2050
  try {
2051
+ if (this.staleBridgeBindings.delete(sessionId)) {
2052
+ await bridge.discardSession?.(sessionId).catch(() => void 0);
2053
+ }
2088
2054
  loadedSessionId = await bridge.loadSession(sessionId, workspaceCwd, this.sessionOptions(target.channelName), bindingToken);
2089
2055
  if (lifecycleGeneration !== this.lifecycleGeneration || bridge !== this.bridge) {
2090
2056
  this.scheduleManagedDiscard(bridge, loadedSessionId, bindingToken);
@@ -2104,11 +2070,100 @@ var SessionRouter = class {
2104
2070
  this.toTarget.set(sessionId, target);
2105
2071
  this.toCwd.set(sessionId, actualCwd);
2106
2072
  this.liveSessionIds.add(sessionId);
2107
- return { loaded: true };
2073
+ return { loaded: true, sessionId };
2108
2074
  } catch (error) {
2109
2075
  if (loadedSessionId) {
2110
2076
  await bridge.discardSession?.(loadedSessionId, bindingToken).catch(() => void 0);
2077
+ throw error;
2078
+ }
2079
+ const replacementId = readSupersededReplacementId(error);
2080
+ if (allowSupersededRedirect && replacementId !== void 0 && replacementId !== sessionId) {
2081
+ const redirected = await this.loadManagedSession(replacementId, target, workspaceCwd, expectedCwd, isolation, false);
2082
+ this.healSupersededRoute(sessionId, redirected.sessionId);
2083
+ return {
2084
+ loaded: redirected.loaded,
2085
+ sessionId: redirected.sessionId,
2086
+ redirectedFrom: sessionId
2087
+ };
2088
+ }
2089
+ throw error;
2090
+ } finally {
2091
+ this.endSessionLoad(loadWindow);
2092
+ }
2093
+ }
2094
+ /**
2095
+ * Remap every route that still points at a superseded session to its
2096
+ * replacement, and drop the superseded id's bookkeeping. The manager's
2097
+ * own task registry heals separately (it owns the task-name mapping).
2098
+ */
2099
+ healSupersededRoute(oldSessionId, newSessionId) {
2100
+ let changed = false;
2101
+ for (const [key, mappedSessionId] of this.toSession) {
2102
+ if (mappedSessionId !== oldSessionId)
2103
+ continue;
2104
+ this.invalidateRouteOperation(key);
2105
+ this.toSession.set(key, newSessionId);
2106
+ changed = true;
2107
+ }
2108
+ changed = this.toTarget.delete(oldSessionId) || changed;
2109
+ changed = this.toCwd.delete(oldSessionId) || changed;
2110
+ const managedMeta = this.toManagedMeta.get(oldSessionId);
2111
+ if (managedMeta !== void 0) {
2112
+ this.toManagedMeta.set(newSessionId, managedMeta);
2113
+ this.toManagedMeta.delete(oldSessionId);
2114
+ changed = true;
2115
+ }
2116
+ this.liveSessionIds.delete(oldSessionId);
2117
+ this.staleBridgeBindings.delete(oldSessionId);
2118
+ if (changed)
2119
+ this.persist();
2120
+ }
2121
+ /**
2122
+ * Worktree reset: transfer the task session's checkout ownership to a
2123
+ * fresh replacement session on the daemon, validate the replacement's
2124
+ * attestation, and route it. The task registry itself is swapped by the
2125
+ * named-session manager (it owns the task-name mapping); this call only
2126
+ * wires the router's session bookkeeping.
2127
+ *
2128
+ * A failure past the daemon's marker flip rolls nothing back: the
2129
+ * registry keeps pointing at the old id, and the next selection's load
2130
+ * heals it through the superseded redirect — the failed reset drops the
2131
+ * old id from the live set so that load consults the daemon again.
2132
+ */
2133
+ async replaceManagedWorktreeSession(sessionId, target, workspaceCwd, expectedCwd) {
2134
+ const bridge = this.bridge;
2135
+ if (!bridge.resetWorktreeSession) {
2136
+ throw new Error("Worktree reset is not supported by this bridge");
2137
+ }
2138
+ const loadWindow = this.beginSessionLoad();
2139
+ const lifecycleGeneration = this.lifecycleGeneration;
2140
+ const bindingToken = {};
2141
+ let replacementId;
2142
+ try {
2143
+ replacementId = await bridge.resetWorktreeSession(sessionId, workspaceCwd, this.sessionOptions(target.channelName), bindingToken);
2144
+ if (lifecycleGeneration !== this.lifecycleGeneration || bridge !== this.bridge) {
2145
+ this.scheduleManagedDiscard(bridge, replacementId, bindingToken);
2146
+ throw new Error("Managed session reset was invalidated");
2147
+ }
2148
+ if (typeof replacementId !== "string" || replacementId.length === 0) {
2149
+ throw new Error("Invalid session ID from bridge");
2150
+ }
2151
+ if (loadWindow.delete(replacementId)) {
2152
+ await bridge.discardSession?.(replacementId, bindingToken);
2153
+ throw new Error(`Managed session ${replacementId} died before reset completed`);
2111
2154
  }
2155
+ const actualCwd = this.validateManagedSessionIdentity(bridge, replacementId, workspaceCwd, expectedCwd, "worktree");
2156
+ this.toTarget.set(replacementId, target);
2157
+ this.toCwd.set(replacementId, actualCwd);
2158
+ this.liveSessionIds.add(replacementId);
2159
+ this.forgetManagedSession(sessionId);
2160
+ return replacementId;
2161
+ } catch (error) {
2162
+ if (replacementId !== void 0) {
2163
+ await bridge.discardSession?.(replacementId, bindingToken).catch(() => void 0);
2164
+ }
2165
+ this.staleBridgeBindings.add(sessionId);
2166
+ this.liveSessionIds.delete(sessionId);
2112
2167
  throw error;
2113
2168
  } finally {
2114
2169
  this.endSessionLoad(loadWindow);
@@ -2126,10 +2181,26 @@ var SessionRouter = class {
2126
2181
  }
2127
2182
  return canonicalWorktree;
2128
2183
  }
2129
- activateManagedSession(sessionId, target, cwd) {
2184
+ activateManagedSession(sessionId, target, cwd, managed) {
2185
+ if (managed?.isolation === "worktree" && !managed.workspaceCwd) {
2186
+ throw new Error("A worktree managed session requires its workspace cwd.");
2187
+ }
2188
+ const previousMeta = this.toManagedMeta.get(sessionId);
2189
+ if (managed?.isolation === "worktree") {
2190
+ this.toManagedMeta.set(sessionId, {
2191
+ isolation: "worktree",
2192
+ workspaceCwd: managed.workspaceCwd
2193
+ });
2194
+ } else {
2195
+ this.toManagedMeta.delete(sessionId);
2196
+ }
2197
+ const metaChanged = managed?.isolation === "worktree" ? previousMeta?.workspaceCwd !== managed.workspaceCwd : previousMeta !== void 0;
2130
2198
  const key = this.routingKey(target.channelName, target.senderId, target.chatId, target.threadId);
2131
- if (this.toSession.get(key) === sessionId)
2199
+ if (this.toSession.get(key) === sessionId) {
2200
+ if (metaChanged)
2201
+ this.persist();
2132
2202
  return;
2203
+ }
2133
2204
  this.invalidateRouteOperation(key);
2134
2205
  this.toSession.set(key, sessionId);
2135
2206
  this.toTarget.set(sessionId, target);
@@ -2147,17 +2218,18 @@ var SessionRouter = class {
2147
2218
  }
2148
2219
  changed = this.toTarget.delete(sessionId) || changed;
2149
2220
  changed = this.toCwd.delete(sessionId) || changed;
2221
+ changed = this.toManagedMeta.delete(sessionId) || changed;
2150
2222
  changed = this.liveSessionIds.delete(sessionId) || changed;
2223
+ this.staleBridgeBindings.delete(sessionId);
2151
2224
  if (changed)
2152
2225
  this.persist();
2153
2226
  }
2154
2227
  async detachManagedSession(sessionId) {
2155
2228
  try {
2156
- if (this.liveSessionIds.has(sessionId)) {
2157
- if (!this.bridge.discardSession) {
2158
- throw new Error("Managed session detach is not supported");
2159
- }
2229
+ if (this.bridge.discardSession) {
2160
2230
  await this.bridge.discardSession(sessionId);
2231
+ } else if (this.liveSessionIds.has(sessionId)) {
2232
+ throw new Error("Managed session detach is not supported");
2161
2233
  }
2162
2234
  } finally {
2163
2235
  this.forgetManagedSession(sessionId);
@@ -2213,6 +2285,9 @@ var SessionRouter = class {
2213
2285
  if (this.toCwd.delete(sessionId)) {
2214
2286
  removed = true;
2215
2287
  }
2288
+ if (this.toManagedMeta.delete(sessionId)) {
2289
+ removed = true;
2290
+ }
2216
2291
  this.liveSessionIds.delete(sessionId);
2217
2292
  if (!removed && this.sessionLoadWindows.size > 0) {
2218
2293
  for (const loadWindow of this.sessionLoadWindows) {
@@ -2242,6 +2317,7 @@ var SessionRouter = class {
2242
2317
  this.toSession.delete(key);
2243
2318
  this.toTarget.delete(sessionId);
2244
2319
  this.toCwd.delete(sessionId);
2320
+ this.toManagedMeta.delete(sessionId);
2245
2321
  this.liveSessionIds.delete(sessionId);
2246
2322
  return sessionId;
2247
2323
  }
@@ -2278,6 +2354,12 @@ var SessionRouter = class {
2278
2354
  this.toSession.set(key, entry.sessionId);
2279
2355
  this.toTarget.set(entry.sessionId, entry.target);
2280
2356
  this.toCwd.set(entry.sessionId, entry.cwd);
2357
+ if (entry.isolation === "worktree" && entry.workspaceCwd !== void 0) {
2358
+ this.toManagedMeta.set(entry.sessionId, {
2359
+ isolation: "worktree",
2360
+ workspaceCwd: entry.workspaceCwd
2361
+ });
2362
+ }
2281
2363
  restored++;
2282
2364
  }
2283
2365
  if (persisted.dropped > 0)
@@ -2321,6 +2403,32 @@ var SessionRouter = class {
2321
2403
  try {
2322
2404
  this.assertOperationCurrent(operation);
2323
2405
  const options = this.sessionOptions(entry.target.channelName);
2406
+ if (entry.isolation === "worktree" && entry.workspaceCwd !== void 0) {
2407
+ const managed = await this.loadManagedSession(entry.sessionId, entry.target, entry.workspaceCwd, entry.cwd, "worktree");
2408
+ try {
2409
+ this.assertOperationCurrent(operation);
2410
+ } catch (error) {
2411
+ if (![...this.toSession.values()].includes(managed.sessionId)) {
2412
+ void this.bridge.discardSession?.(managed.sessionId).catch(() => void 0);
2413
+ this.toTarget.delete(managed.sessionId);
2414
+ this.toCwd.delete(managed.sessionId);
2415
+ this.toManagedMeta.delete(managed.sessionId);
2416
+ this.liveSessionIds.delete(managed.sessionId);
2417
+ }
2418
+ throw error;
2419
+ }
2420
+ this.toSession.set(key, managed.sessionId);
2421
+ this.toManagedMeta.set(managed.sessionId, {
2422
+ isolation: "worktree",
2423
+ workspaceCwd: entry.workspaceCwd
2424
+ });
2425
+ reservation.resolve(managed.sessionId);
2426
+ if (managed.sessionId !== entry.sessionId) {
2427
+ changed = true;
2428
+ }
2429
+ restored++;
2430
+ continue;
2431
+ }
2324
2432
  const sessionId = await this.bridge.loadSession(entry.sessionId, entry.cwd, options, operation);
2325
2433
  try {
2326
2434
  this.assertOperationCurrent(operation);
@@ -2373,9 +2481,11 @@ var SessionRouter = class {
2373
2481
  this.toSession.clear();
2374
2482
  this.toTarget.clear();
2375
2483
  this.toCwd.clear();
2484
+ this.toManagedMeta.clear();
2376
2485
  this.creatingSessions.clear();
2377
2486
  this.sessionLoadWindows.clear();
2378
2487
  this.liveSessionIds.clear();
2488
+ this.staleBridgeBindings.clear();
2379
2489
  this.routeTokens.clear();
2380
2490
  }
2381
2491
  /** Clear in-memory state and delete persist file. Used on clean shutdown. */
@@ -2433,7 +2543,12 @@ var SessionRouter = class {
2433
2543
  if (typeof target !== "object" || target === null)
2434
2544
  return false;
2435
2545
  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");
2546
+ 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");
2547
+ if (!wellFormed)
2548
+ return false;
2549
+ if (entry["isolation"] === void 0)
2550
+ return true;
2551
+ return entry["isolation"] === "worktree" && typeof entry["workspaceCwd"] === "string" && entry["workspaceCwd"].length > 0;
2437
2552
  }
2438
2553
  persist() {
2439
2554
  if (!this.persistPath)
@@ -2446,7 +2561,8 @@ var SessionRouter = class {
2446
2561
  data[key] = {
2447
2562
  sessionId,
2448
2563
  target,
2449
- cwd: this.toCwd.get(sessionId) ?? this.defaultCwd
2564
+ cwd: this.toCwd.get(sessionId) ?? this.defaultCwd,
2565
+ ...this.toManagedMeta.get(sessionId) ?? {}
2450
2566
  };
2451
2567
  }
2452
2568
  const dir = dirname3(this.persistPath);
@@ -2594,6 +2710,16 @@ import process3 from "node:process";
2594
2710
  var REGISTRY_VERSION = 1;
2595
2711
  var MAX_OPEN_TASKS = 8;
2596
2712
  var TASK_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/;
2713
+ var NamedSessionTaskError = class extends Error {
2714
+ static {
2715
+ __name(this, "NamedSessionTaskError");
2716
+ }
2717
+ taskName;
2718
+ constructor(message, taskName, options) {
2719
+ super(message, options);
2720
+ this.taskName = taskName;
2721
+ }
2722
+ };
2597
2723
  var NamedSessionManager = class {
2598
2724
  static {
2599
2725
  __name(this, "NamedSessionManager");
@@ -2608,6 +2734,12 @@ var NamedSessionManager = class {
2608
2734
  registry;
2609
2735
  taskBySessionId;
2610
2736
  ownerOperations = /* @__PURE__ */ new Map();
2737
+ /**
2738
+ * Superseded session id → the replacement its task moved onto. A queued turn
2739
+ * stays bound to the id it reserved, so the reservation lookup has to follow
2740
+ * the task or every turn after the first one is stranded on the old id.
2741
+ */
2742
+ supersededSessionIds = /* @__PURE__ */ new Map();
2611
2743
  constructor(options) {
2612
2744
  this.channelName = options.channelName;
2613
2745
  this.cwd = options.cwd;
@@ -2706,14 +2838,20 @@ var NamedSessionManager = class {
2706
2838
  return task ? this.selection(owner, task) : void 0;
2707
2839
  });
2708
2840
  }
2841
+ /**
2842
+ * Reload a task a queued turn is already bound to. Resolves to the session
2843
+ * id the caller must dispatch on — the healed replacement when a superseded
2844
+ * redirect fired — or undefined when the task is no longer reservable.
2845
+ */
2709
2846
  resumeReserved(input, sessionId) {
2710
2847
  return this.withOwnerLock(input, async () => {
2711
2848
  const owner = await this.ensureOwner(input, false);
2712
- const task = owner?.tasks.find((candidate) => candidate.sessionId === sessionId && candidate.status === "open");
2849
+ const reservedSessionId = this.supersededSessionIds.get(sessionId) ?? sessionId;
2850
+ const task = owner?.tasks.find((candidate) => candidate.sessionId === reservedSessionId && candidate.status === "open");
2713
2851
  if (!task)
2714
- return false;
2715
- await this.loadTask(task, `Could not reload reserved task "${task.name}".`);
2716
- return true;
2852
+ return void 0;
2853
+ const result = await this.loadTask(task, `Could not reload reserved task "${task.name}".`);
2854
+ return result.sessionId;
2717
2855
  });
2718
2856
  }
2719
2857
  create(input, name, isolation = "shared") {
@@ -2757,7 +2895,10 @@ var NamedSessionManager = class {
2757
2895
  await this.router.detachManagedSession(sessionId).catch(() => void 0);
2758
2896
  throw error;
2759
2897
  }
2760
- this.router.activateManagedSession(sessionId, target, task.cwd);
2898
+ this.router.activateManagedSession(sessionId, target, task.cwd, {
2899
+ isolation: task.isolation,
2900
+ workspaceCwd: this.cwd
2901
+ });
2761
2902
  return this.selection(nextOwner, task);
2762
2903
  });
2763
2904
  }
@@ -2773,9 +2914,10 @@ var NamedSessionManager = class {
2773
2914
  throw new Error("You already have eight open tasks. Close one before reopening another.");
2774
2915
  }
2775
2916
  const timestamp = this.nextTimestamp(owner);
2776
- const loaded = await this.loadTask(task, `Could not load task "${task.name}". The current task was not changed.`);
2917
+ const loadResult = await this.loadTask(task, `Could not load task "${task.name}". The current task was not changed.`);
2777
2918
  const updatedTask = {
2778
2919
  ...task,
2920
+ sessionId: loadResult.sessionId,
2779
2921
  status: "open",
2780
2922
  updatedAt: timestamp,
2781
2923
  lastSelectedAt: timestamp
@@ -2784,12 +2926,12 @@ var NamedSessionManager = class {
2784
2926
  try {
2785
2927
  this.commitOwner(nextOwner);
2786
2928
  } catch (error) {
2787
- if (loaded) {
2788
- await this.router.detachManagedSession(task.sessionId).catch(() => void 0);
2929
+ if (loadResult.loaded) {
2930
+ await this.router.detachManagedSession(loadResult.sessionId).catch(() => void 0);
2789
2931
  }
2790
2932
  throw error;
2791
2933
  }
2792
- this.router.activateManagedSession(task.sessionId, task.target, task.cwd);
2934
+ this.router.activateManagedSession(loadResult.sessionId, updatedTask.target, updatedTask.cwd, { isolation: updatedTask.isolation, workspaceCwd: this.cwd });
2793
2935
  return this.selection(nextOwner, updatedTask);
2794
2936
  });
2795
2937
  }
@@ -2811,8 +2953,11 @@ var NamedSessionManager = class {
2811
2953
  const timestamp = this.nextTimestamp(owner);
2812
2954
  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
2955
  let replacementLoaded = false;
2956
+ let replacementSessionId;
2814
2957
  if (replacement) {
2815
- replacementLoaded = await this.loadTask(replacement, `Could not load fallback task "${replacement.name}". Task "${task.name}" was not closed.`);
2958
+ const replacementLoad = await this.loadTask(replacement, `Could not load fallback task "${replacement.name}". Task "${task.name}" was not closed.`);
2959
+ replacementLoaded = replacementLoad.loaded;
2960
+ replacementSessionId = replacementLoad.sessionId;
2816
2961
  }
2817
2962
  const closedTask = {
2818
2963
  ...task,
@@ -2822,6 +2967,7 @@ var NamedSessionManager = class {
2822
2967
  let nextOwner = this.replaceTask(owner, closedTask, wasActive ? replacement?.name ?? null : owner.activeTaskName);
2823
2968
  const selectedReplacement = replacement ? {
2824
2969
  ...replacement,
2970
+ sessionId: replacementSessionId ?? replacement.sessionId,
2825
2971
  updatedAt: timestamp,
2826
2972
  lastSelectedAt: timestamp
2827
2973
  } : void 0;
@@ -2832,21 +2978,22 @@ var NamedSessionManager = class {
2832
2978
  this.commitOwner(nextOwner);
2833
2979
  } catch (error) {
2834
2980
  if (replacement && replacementLoaded) {
2835
- await this.router.detachManagedSession(replacement.sessionId).catch(() => void 0);
2981
+ await this.router.detachManagedSession(replacementSessionId ?? replacement.sessionId).catch(() => void 0);
2836
2982
  }
2837
2983
  throw error;
2838
2984
  }
2839
2985
  if (replacement) {
2840
- this.router.activateManagedSession(replacement.sessionId, replacement.target, replacement.cwd);
2986
+ this.router.activateManagedSession(replacementSessionId ?? replacement.sessionId, replacement.target, replacement.cwd, { isolation: replacement.isolation, workspaceCwd: this.cwd });
2841
2987
  }
2842
2988
  try {
2843
2989
  await this.router.detachManagedSession(task.sessionId);
2844
2990
  } catch (error) {
2845
- this.commitOwner(owner);
2991
+ const healedReplacement = replacement !== void 0 && replacementSessionId !== void 0 && replacementSessionId !== replacement.sessionId ? { ...replacement, sessionId: replacementSessionId } : void 0;
2992
+ this.commitOwner(healedReplacement ? this.replaceTask(owner, healedReplacement, owner.activeTaskName) : owner);
2846
2993
  this.router.forgetManagedSession(task.sessionId);
2847
- await this.loadTask(task, `Task "${task.name}" could not be restored after close failed.`);
2994
+ const restored = await this.loadTask(task, `Task "${task.name}" could not be restored after close failed.`);
2848
2995
  if (wasActive) {
2849
- this.router.activateManagedSession(task.sessionId, task.target, task.cwd);
2996
+ this.router.activateManagedSession(restored.sessionId, task.target, task.cwd, { isolation: task.isolation, workspaceCwd: this.cwd });
2850
2997
  }
2851
2998
  throw new Error(`Failed to close task "${task.name}".`, {
2852
2999
  cause: error
@@ -2867,10 +3014,36 @@ var NamedSessionManager = class {
2867
3014
  const task = this.findTask(owner, owner.activeTaskName);
2868
3015
  if (!task || task.status !== "open")
2869
3016
  return void 0;
3017
+ const timestamp = this.nextTimestamp(owner);
2870
3018
  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.`);
3019
+ if (this.isBusy(task.sessionId)) {
3020
+ throw new Error(`Task "${task.name}" is busy. Wait for the running prompt to finish (or cancel it), then try again.`);
3021
+ }
3022
+ const sessionId2 = await this.resetWorktreeSession(task);
3023
+ const updatedTask2 = {
3024
+ ...task,
3025
+ sessionId: sessionId2,
3026
+ updatedAt: timestamp,
3027
+ lastSelectedAt: timestamp
3028
+ };
3029
+ const nextOwner2 = this.replaceTask(owner, updatedTask2, task.name);
3030
+ try {
3031
+ this.commitOwner(nextOwner2);
3032
+ } catch (error) {
3033
+ await this.router.detachManagedSession(sessionId2).catch(() => void 0);
3034
+ throw error;
3035
+ }
3036
+ this.router.activateManagedSession(sessionId2, updatedTask2.target, updatedTask2.cwd, { isolation: updatedTask2.isolation, workspaceCwd: this.cwd });
3037
+ this.router.forgetManagedSession(task.sessionId);
3038
+ this.repointSupersededSessionIds(task.sessionId, sessionId2);
3039
+ this.supersededSessionIds.delete(task.sessionId);
3040
+ return {
3041
+ name: task.name,
3042
+ previousSessionId: task.sessionId,
3043
+ sessionId: sessionId2,
3044
+ worktreeKept: true
3045
+ };
2872
3046
  }
2873
- const timestamp = this.nextTimestamp(owner);
2874
3047
  const sessionId = await this.createSession(task.target, task.isolation, `Could not reset task "${task.name}".`);
2875
3048
  const updatedTask = {
2876
3049
  ...task,
@@ -2885,12 +3058,15 @@ var NamedSessionManager = class {
2885
3058
  await this.router.detachManagedSession(sessionId).catch(() => void 0);
2886
3059
  throw error;
2887
3060
  }
2888
- this.router.activateManagedSession(sessionId, updatedTask.target, updatedTask.cwd);
3061
+ this.router.activateManagedSession(sessionId, updatedTask.target, updatedTask.cwd, { isolation: updatedTask.isolation, workspaceCwd: this.cwd });
2889
3062
  this.router.forgetManagedSession(task.sessionId);
3063
+ this.repointSupersededSessionIds(task.sessionId, sessionId);
3064
+ this.supersededSessionIds.delete(task.sessionId);
2890
3065
  return {
2891
3066
  name: task.name,
2892
3067
  previousSessionId: task.sessionId,
2893
- sessionId
3068
+ sessionId,
3069
+ worktreeKept: false
2894
3070
  };
2895
3071
  });
2896
3072
  }
@@ -2960,12 +3136,17 @@ var NamedSessionManager = class {
2960
3136
  throw new Error("The selected Channel task is unavailable.");
2961
3137
  }
2962
3138
  const release = reserve?.(task.sessionId);
3139
+ let activeRelease = release;
2963
3140
  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;
3141
+ const result = await this.loadTask(task, `Could not load task "${task.name}". No replacement session was created.`);
3142
+ if (result.sessionId !== task.sessionId && reserve) {
3143
+ release?.();
3144
+ activeRelease = reserve(result.sessionId);
3145
+ }
3146
+ this.router.activateManagedSession(result.sessionId, task.target, task.cwd, { isolation: task.isolation, workspaceCwd: this.cwd });
3147
+ return result.sessionId;
2967
3148
  } catch (error) {
2968
- release?.();
3149
+ activeRelease?.();
2969
3150
  throw error;
2970
3151
  }
2971
3152
  }
@@ -2998,9 +3179,55 @@ var NamedSessionManager = class {
2998
3179
  }
2999
3180
  async loadTask(task, failureMessage) {
3000
3181
  try {
3001
- return (await this.router.loadManagedSession(task.sessionId, task.target, this.cwd, task.cwd, task.isolation)).loaded;
3182
+ const result = await this.router.loadManagedSession(task.sessionId, task.target, this.cwd, task.cwd, task.isolation);
3183
+ if (result.redirectedFrom !== void 0 && result.sessionId !== task.sessionId) {
3184
+ try {
3185
+ this.healSupersededTask(task, result.sessionId);
3186
+ } catch {
3187
+ }
3188
+ }
3189
+ return result;
3002
3190
  } catch (error) {
3003
- throw new Error(failureMessage, { cause: error });
3191
+ throw new NamedSessionTaskError(failureMessage, task.name, {
3192
+ cause: error
3193
+ });
3194
+ }
3195
+ }
3196
+ /**
3197
+ * Point a task at its replacement session after a superseded redirect
3198
+ * healed the route. No-op when the registry entry already moved on (a
3199
+ * concurrent reset under the same owner lock cannot interleave, but a
3200
+ * stale in-memory snapshot could).
3201
+ */
3202
+ healSupersededTask(task, sessionId) {
3203
+ const owner = this.getOwner(task.target);
3204
+ if (!owner)
3205
+ return;
3206
+ const current = this.findTask(owner, task.name);
3207
+ if (!current || current.sessionId !== task.sessionId)
3208
+ return;
3209
+ const timestamp = this.nextTimestamp(owner);
3210
+ this.commitOwner(this.replaceTask(owner, { ...current, sessionId, updatedAt: timestamp }, owner.activeTaskName));
3211
+ this.repointSupersededSessionIds(task.sessionId, sessionId);
3212
+ this.supersededSessionIds.set(task.sessionId, sessionId);
3213
+ }
3214
+ /**
3215
+ * Follow every id that still resolves to `oldSessionId` onto its
3216
+ * replacement, so a task superseded more than once stays reachable from the
3217
+ * oldest id a turn is bound to and the map does not grow once per reset.
3218
+ */
3219
+ repointSupersededSessionIds(oldSessionId, newSessionId) {
3220
+ for (const boundSessionId of [...this.supersededSessionIds.keys()]) {
3221
+ if (this.supersededSessionIds.get(boundSessionId) === oldSessionId) {
3222
+ this.supersededSessionIds.set(boundSessionId, newSessionId);
3223
+ }
3224
+ }
3225
+ }
3226
+ async resetWorktreeSession(task) {
3227
+ try {
3228
+ return await this.router.replaceManagedWorktreeSession(task.sessionId, task.target, this.cwd, task.cwd);
3229
+ } catch (error) {
3230
+ throw new NamedSessionTaskError(`Could not reset task "${task.name}".`, task.name, { cause: error });
3004
3231
  }
3005
3232
  }
3006
3233
  async createSession(target, isolation, failureMessage) {
@@ -3991,6 +4218,45 @@ function isRecord2(value) {
3991
4218
  return value !== null && typeof value === "object" && !Array.isArray(value);
3992
4219
  }
3993
4220
  __name(isRecord2, "isRecord");
4221
+ var PERMISSION_COPY = {
4222
+ en: {
4223
+ toolUse: "Tool use",
4224
+ allowOnce: "Allow once",
4225
+ allowAlwaysProject: "always allow for this project",
4226
+ allowAlwaysUser: "always allow for this user",
4227
+ allowAlways: "always allow",
4228
+ deny: "Deny",
4229
+ required: "Permission required to run a tool",
4230
+ request: "Request:",
4231
+ tool: "Tool:",
4232
+ action: "Action:",
4233
+ parameters: "Parameters:",
4234
+ replyWith: "Reply with:"
4235
+ },
4236
+ zh: {
4237
+ toolUse: "\u5DE5\u5177\u8C03\u7528",
4238
+ allowOnce: "\u4EC5\u5141\u8BB8\u672C\u6B21",
4239
+ allowAlwaysProject: "\u59CB\u7EC8\u5141\u8BB8\u6B64\u9879\u76EE",
4240
+ allowAlwaysUser: "\u59CB\u7EC8\u5141\u8BB8\u6B64\u7528\u6237",
4241
+ allowAlways: "\u59CB\u7EC8\u5141\u8BB8",
4242
+ deny: "\u62D2\u7EDD",
4243
+ required: "\u8FD0\u884C\u5DE5\u5177\u9700\u8981\u6388\u6743",
4244
+ request: "\u8BF7\u6C42\uFF1A",
4245
+ tool: "\u5DE5\u5177\uFF1A",
4246
+ action: "\u64CD\u4F5C\uFF1A",
4247
+ parameters: "\u53C2\u6570\uFF1A",
4248
+ replyWith: "\u56DE\u590D\u4EE5\u4E0B\u547D\u4EE4\uFF1A"
4249
+ }
4250
+ };
4251
+ function localizedScopedAlwaysLabel(label, stockLabel, localizedLabel) {
4252
+ if (label === stockLabel)
4253
+ return localizedLabel;
4254
+ const scopeSeparator = ": ";
4255
+ if (!label.startsWith(stockLabel + scopeSeparator))
4256
+ return void 0;
4257
+ return `${localizedLabel}\uFF1A${label.slice(stockLabel.length + scopeSeparator.length)}`;
4258
+ }
4259
+ __name(localizedScopedAlwaysLabel, "localizedScopedAlwaysLabel");
3994
4260
  var COMMAND_TOKEN_CHARS = "a-zA-Z0-9_:-";
3995
4261
  var PARSE_COMMAND_RE = new RegExp(`^\\/([${COMMAND_TOKEN_CHARS}]+)(?:@\\S+)?\\s*(.*)`, "s");
3996
4262
  var COMMAND_TOKEN_RE = new RegExp(`^[${COMMAND_TOKEN_CHARS}]+(?:@\\S+)?$`);
@@ -4034,6 +4300,7 @@ var ChannelBase = class {
4034
4300
  proxy;
4035
4301
  /** Adapter-owned persistent state directory, when supplied by the runtime. */
4036
4302
  stateDir;
4303
+ locale;
4037
4304
  channelMemory;
4038
4305
  memoryIntentClassifier;
4039
4306
  channelMemoryRecallObserver;
@@ -4088,6 +4355,9 @@ var ChannelBase = class {
4088
4355
  bridgeSessionDiedListener = /* @__PURE__ */ __name((event) => {
4089
4356
  this.onSessionDied(event.sessionId);
4090
4357
  }, "bridgeSessionDiedListener");
4358
+ bridgeDisconnectedListener = /* @__PURE__ */ __name(() => {
4359
+ this.onBridgeDisconnected();
4360
+ }, "bridgeDisconnectedListener");
4091
4361
  bridgePermissionRequestListener = /* @__PURE__ */ __name((event) => {
4092
4362
  void this.dispatchPermissionRequest(event).catch((err) => {
4093
4363
  process.stderr.write(`[${this.name}] permission relay failed for request ${sanitizeLogText(event.requestId, 128)}: ${this.lifecycleError(err)}
@@ -4364,6 +4634,10 @@ No answer is available from the current conversation context.`;
4364
4634
  if (presentation && await presentation) {
4365
4635
  return;
4366
4636
  }
4637
+ const permissionPresentation = this.tryPresentPermission(pending);
4638
+ if (permissionPresentation && await permissionPresentation) {
4639
+ return;
4640
+ }
4367
4641
  const text = this.formatPermissionRequest(pending);
4368
4642
  if (target.threadId !== void 0 && this.supportsProactiveSend() && this.supportsProactiveTarget(target)) {
4369
4643
  await this.pushProactive(target, text, pending.sourceLabel);
@@ -4444,6 +4718,103 @@ No answer is available from the current conversation context.`;
4444
4718
  }
4445
4719
  })();
4446
4720
  }
4721
+ tryPresentPermission(pending) {
4722
+ const active = this.activePrompts.get(pending.sessionId);
4723
+ const toolCall = pending.request.toolCall;
4724
+ const meta = isRecord2(toolCall["_meta"]) ? toolCall["_meta"] : void 0;
4725
+ const isUserQuestion = meta?.["qwenInteractionKind"] === "user_question" || meta?.["toolName"] === "ask_user_question" || toolCall["kind"] === "ask_user_question";
4726
+ const decisions = this.permissionPresentationDecisions(pending);
4727
+ if (!active || active.loopPrompt || !active.owner || isUserQuestion || !decisions) {
4728
+ return void 0;
4729
+ }
4730
+ const precedingSegment = this.closeOutputSegment(pending.sessionId, active, pending.target);
4731
+ let respondInvoked = false;
4732
+ const context = {
4733
+ requestId: pending.requestId,
4734
+ sessionId: pending.sessionId,
4735
+ runId: active.runId,
4736
+ owner: active.owner,
4737
+ target: pending.target,
4738
+ ...precedingSegment ? { precedingSegmentId: precedingSegment.segmentId } : {},
4739
+ title: this.permissionTitle(pending.request.toolCall),
4740
+ decisions,
4741
+ onSettled: /* @__PURE__ */ __name((listener) => {
4742
+ if (pending.settled) {
4743
+ listener(pending.settled);
4744
+ return () => {
4745
+ };
4746
+ }
4747
+ pending.settlementListeners.add(listener);
4748
+ return () => {
4749
+ pending.settlementListeners.delete(listener);
4750
+ };
4751
+ }, "onSettled"),
4752
+ respond: /* @__PURE__ */ __name((decision) => {
4753
+ const response = this.permissionPresentationResponse(pending, decision);
4754
+ if (!response)
4755
+ return Promise.resolve(false);
4756
+ respondInvoked = true;
4757
+ return this.respondToUserInput(pending, response);
4758
+ }, "respond")
4759
+ };
4760
+ pending.permissionPresented = true;
4761
+ return (async () => {
4762
+ try {
4763
+ if (precedingSegment) {
4764
+ await this.notifyOutputSegmentEnd(pending.target.chatId, pending.sessionId, precedingSegment, "input_requested");
4765
+ }
4766
+ if (this.pendingPermissions.get(pending.requestId) !== pending) {
4767
+ return true;
4768
+ }
4769
+ const result = await this.presentPermissionRequest(context);
4770
+ if (this.pendingPermissions.get(pending.requestId) !== pending) {
4771
+ return true;
4772
+ }
4773
+ if (result.kind === "presented" || result.kind === "handled" && respondInvoked) {
4774
+ return true;
4775
+ }
4776
+ pending.permissionPresented = false;
4777
+ return false;
4778
+ } catch (err) {
4779
+ process.stderr.write(`[${this.name}] permission presentation failed for request ${sanitizeLogText(pending.requestId, 128)}: ${this.lifecycleError(err)}
4780
+ `);
4781
+ if (this.pendingPermissions.get(pending.requestId) !== pending) {
4782
+ return true;
4783
+ }
4784
+ pending.permissionPresented = false;
4785
+ return false;
4786
+ }
4787
+ })();
4788
+ }
4789
+ permissionPresentationDecisions(pending) {
4790
+ const allowOnce = this.approvalOption(pending);
4791
+ if (!allowOnce)
4792
+ return void 0;
4793
+ const copy = PERMISSION_COPY[this.locale];
4794
+ const allowAlways = this.approvalAlwaysOption(pending);
4795
+ return [
4796
+ {
4797
+ kind: "allow_once",
4798
+ label: sanitizeQuotedText(this.permissionOptionLabel(allowOnce, copy.allowOnce), 80)
4799
+ },
4800
+ ...allowAlways ? [
4801
+ {
4802
+ kind: "allow_always",
4803
+ label: sanitizeQuotedText(allowAlways.label, 80)
4804
+ }
4805
+ ] : [],
4806
+ {
4807
+ kind: "deny",
4808
+ label: sanitizeQuotedText(this.permissionOptionLabel(this.denialOption(pending), copy.deny), 80)
4809
+ }
4810
+ ];
4811
+ }
4812
+ permissionPresentationResponse(pending, decision) {
4813
+ if (decision === "deny")
4814
+ return this.denialResponse(pending);
4815
+ const optionId = decision === "allow_once" ? this.approvalOptionId(pending) : this.approvalAlwaysOption(pending)?.optionId;
4816
+ return optionId ? { outcome: { outcome: "selected", optionId } } : void 0;
4817
+ }
4447
4818
  normalizeUserQuestions(pending) {
4448
4819
  const toolCall = pending.request.toolCall;
4449
4820
  const meta = isRecord2(toolCall["_meta"]) ? toolCall["_meta"] : void 0;
@@ -4488,7 +4859,8 @@ No answer is available from the current conversation context.`;
4488
4859
  }
4489
4860
  async respondToUserInput(pending, response) {
4490
4861
  if (pending.responsePromise) {
4491
- return pending.responsePromise;
4862
+ await pending.responsePromise;
4863
+ return false;
4492
4864
  }
4493
4865
  if (this.pendingPermissions.get(pending.requestId) !== pending || !this.bridge.respondToPermission) {
4494
4866
  return false;
@@ -4541,6 +4913,7 @@ No answer is available from the current conversation context.`;
4541
4913
  this.config = config;
4542
4914
  this.messagePrefix = config.messagePrefix?.trim() || void 0;
4543
4915
  this.bridge = bridge;
4916
+ this.locale = options?.locale ?? "en";
4544
4917
  this.proxy = options?.proxy;
4545
4918
  this.stateDir = options?.stateDir;
4546
4919
  this.identity = Object.freeze(this.resolveIdentity(name, config));
@@ -4603,6 +4976,9 @@ No answer is available from the current conversation context.`;
4603
4976
  async presentUserInputRequest(_context) {
4604
4977
  return { kind: "unsupported" };
4605
4978
  }
4979
+ async presentPermissionRequest(_context) {
4980
+ return { kind: "unsupported" };
4981
+ }
4606
4982
  emitTaskLifecycle(event) {
4607
4983
  try {
4608
4984
  const result = this.onTaskLifecycle(event);
@@ -5495,7 +5871,6 @@ ${promptText}` : promptText;
5495
5871
  return false;
5496
5872
  }
5497
5873
  active.cancelled = true;
5498
- this.stopActiveStreaming(active, sessionId, reason);
5499
5874
  this.dropCollectBuffer(sessionId);
5500
5875
  this.removePendingPermissionsForSession(sessionId, "run_cancelled");
5501
5876
  this.emitTaskCancellation(active, sessionId, reason);
@@ -5570,12 +5945,21 @@ ${promptText}` : promptText;
5570
5945
  this.unattendedMemorySessions.delete(sessionId);
5571
5946
  this.removePendingPermissionsForSession(sessionId);
5572
5947
  }
5948
+ /**
5949
+ * Called when the standalone ACP bridge process exits. Its in-flight turns
5950
+ * never settle, but crash recovery restores the sessions on a fresh bridge,
5951
+ * so overrides must clear only turn-scoped transient state (never session
5952
+ * routing) and must not fabricate terminal outcomes for interrupted turns.
5953
+ */
5954
+ onBridgeDisconnected() {
5955
+ }
5573
5956
  onSessionRetiring(_sessionId) {
5574
5957
  }
5575
5958
  attachBridgeEvents(bridge) {
5576
5959
  bridge.on("toolCall", this.bridgeToolCallListener);
5577
5960
  bridge.on("backgroundResponse", this.bridgeBackgroundResponseListener);
5578
5961
  bridge.on("sessionDied", this.bridgeSessionDiedListener);
5962
+ bridge.on("disconnected", this.bridgeDisconnectedListener);
5579
5963
  bridge.on("permissionRequest", this.bridgePermissionRequestListener);
5580
5964
  bridge.on("permissionResolved", this.bridgePermissionResolvedListener);
5581
5965
  }
@@ -5583,6 +5967,7 @@ ${promptText}` : promptText;
5583
5967
  bridge.off("toolCall", this.bridgeToolCallListener);
5584
5968
  bridge.off("backgroundResponse", this.bridgeBackgroundResponseListener);
5585
5969
  bridge.off("sessionDied", this.bridgeSessionDiedListener);
5970
+ bridge.off("disconnected", this.bridgeDisconnectedListener);
5586
5971
  bridge.off("permissionRequest", this.bridgePermissionRequestListener);
5587
5972
  bridge.off("permissionResolved", this.bridgePermissionResolvedListener);
5588
5973
  }
@@ -5792,14 +6177,15 @@ ${promptText}` : promptText;
5792
6177
  return { kind: "found", pending: matching[0] };
5793
6178
  }
5794
6179
  canEnvelopeAnswerPendingPermission(envelope, pending) {
5795
- return pending.target.chatId === envelope.chatId && pending.target.threadId === envelope.threadId && (!pending.userInputPresented || pending.target.senderId === envelope.senderId) && (this.isSharedSessionTarget(pending.target) || pending.target.senderId === envelope.senderId);
6180
+ return pending.target.chatId === envelope.chatId && pending.target.threadId === envelope.threadId && (!pending.userInputPresented && !pending.permissionPresented || pending.target.senderId === envelope.senderId) && (this.isSharedSessionTarget(pending.target) || pending.target.senderId === envelope.senderId);
5796
6181
  }
5797
6182
  formatPermissionRequest(pending) {
5798
6183
  const { toolCall } = pending.request;
6184
+ const copy = PERMISSION_COPY[this.locale];
5799
6185
  const parameters = this.permissionParameterSummary(toolCall);
5800
- const approveLabel = this.permissionOptionLabel(this.approvalOption(pending), "allow once");
6186
+ const approveLabel = this.permissionOptionLabel(this.approvalOption(pending), copy.allowOnce.toLocaleLowerCase(this.locale));
5801
6187
  const alwaysOption = this.approvalAlwaysOption(pending);
5802
- const denyLabel = this.permissionOptionLabel(this.denialOption(pending), "deny");
6188
+ const denyLabel = this.permissionOptionLabel(this.denialOption(pending), copy.deny.toLocaleLowerCase(this.locale));
5803
6189
  const requestSuffix = pending.taskName ? ` ${pending.requestId}` : "";
5804
6190
  const replyPadding = pending.taskName ? { approve: " ", always: " ", deny: " " } : { approve: " ", always: " ", deny: " " };
5805
6191
  const replies = [
@@ -5810,14 +6196,14 @@ ${promptText}` : promptText;
5810
6196
  `${this.prefixedCommand(`/deny${requestSuffix}`)}${replyPadding.deny}${denyLabel}`
5811
6197
  ];
5812
6198
  return [
5813
- "Permission required to run a tool",
5814
- ...pending.taskName ? [`Request: ${pending.requestId}`] : [],
6199
+ copy.required,
6200
+ ...pending.taskName ? [`${copy.request} ${pending.requestId}`] : [],
5815
6201
  "",
5816
- `Tool: ${this.permissionToolName(toolCall)}`,
5817
- `Action: ${this.permissionTitle(toolCall)}`,
5818
- ...parameters ? [`Parameters: ${parameters}`] : [],
6202
+ `${copy.tool} ${this.permissionToolName(toolCall)}`,
6203
+ `${copy.action} ${this.permissionTitle(toolCall)}`,
6204
+ ...parameters ? [`${copy.parameters} ${parameters}`] : [],
5819
6205
  "",
5820
- "Reply with:",
6206
+ copy.replyWith,
5821
6207
  ...replies
5822
6208
  ].join("\n");
5823
6209
  }
@@ -5829,7 +6215,7 @@ ${promptText}` : promptText;
5829
6215
  }
5830
6216
  permissionTitle(toolCall) {
5831
6217
  const rawTitle = typeof toolCall.title === "string" ? toolCall.title : void 0;
5832
- return sanitizeQuotedText(rawTitle || "", 160).trim() || "Tool use";
6218
+ return sanitizeQuotedText(rawTitle || "", 160).trim() || PERMISSION_COPY[this.locale].toolUse;
5833
6219
  }
5834
6220
  permissionToolName(toolCall) {
5835
6221
  const rawToolCall = toolCall;
@@ -5869,7 +6255,31 @@ ${promptText}` : promptText;
5869
6255
  permissionOptionLabel(option, fallback) {
5870
6256
  const rawLabel = typeof option?.name === "string" ? option.name : "";
5871
6257
  const label = sanitizeQuotedText(rawLabel, 160).trim();
5872
- return label || fallback;
6258
+ if (!label)
6259
+ return fallback;
6260
+ return this.localizedPermissionOptionLabel(option, label) ?? label;
6261
+ }
6262
+ localizedPermissionOptionLabel(option, label) {
6263
+ if (this.locale !== "zh")
6264
+ return void 0;
6265
+ const copy = PERMISSION_COPY[this.locale];
6266
+ if (option?.kind === "allow_always") {
6267
+ if (option.optionId === "proceed_always_project") {
6268
+ return localizedScopedAlwaysLabel(label, "Always Allow in project", copy.allowAlwaysProject);
6269
+ }
6270
+ if (option.optionId === "proceed_always_user") {
6271
+ return localizedScopedAlwaysLabel(label, "Always Allow for user", copy.allowAlwaysUser);
6272
+ }
6273
+ if (option.optionId === "proceed_always" && label === "Allow All Edits") {
6274
+ return copy.allowAlways;
6275
+ }
6276
+ return void 0;
6277
+ }
6278
+ if (label === "Allow" || label === "Allow once")
6279
+ return copy.allowOnce;
6280
+ if (label === "Deny" || label === "Reject")
6281
+ return copy.deny;
6282
+ return void 0;
5873
6283
  }
5874
6284
  approvalOption(pending) {
5875
6285
  const options = pending.request.options;
@@ -5893,13 +6303,14 @@ ${promptText}` : promptText;
5893
6303
  return options.find((option) => option.optionId === `proceed_always_${scope}`);
5894
6304
  }
5895
6305
  approvalAlwaysLabel(option) {
6306
+ const copy = PERMISSION_COPY[this.locale];
5896
6307
  if (option.optionId === "proceed_always_project") {
5897
- return "always allow for this project";
6308
+ return copy.allowAlwaysProject;
5898
6309
  }
5899
6310
  if (option.optionId === "proceed_always_user") {
5900
- return "always allow for this user";
6311
+ return copy.allowAlwaysUser;
5901
6312
  }
5902
- return "always allow";
6313
+ return copy.allowAlways;
5903
6314
  }
5904
6315
  denialResponse(pending) {
5905
6316
  const option = this.denialOption(pending);
@@ -5965,7 +6376,7 @@ ${requestList}`);
5965
6376
  }
5966
6377
  let accepted;
5967
6378
  try {
5968
- accepted = pending.userInputPresented ? await this.respondToUserInput(pending, response) : await this.bridge.respondToPermission(pending.requestId, response);
6379
+ accepted = pending.userInputPresented || pending.permissionPresented ? await this.respondToUserInput(pending, response) : await this.bridge.respondToPermission(pending.requestId, response);
5969
6380
  } catch (err) {
5970
6381
  this.removePendingPermission(pending.requestId);
5971
6382
  process.stderr.write(`[${this.name}] permission response failed for request ${sanitizeLogText(pending.requestId, 128)}: ${this.lifecycleError(err)}
@@ -6020,6 +6431,21 @@ ${requestList}`);
6020
6431
  binding.released = true;
6021
6432
  this.releaseQueuedTurn(binding.sessionId);
6022
6433
  }
6434
+ /**
6435
+ * Follow a task onto the session its reload healed to (a superseded
6436
+ * redirect). The queue reservation and the staleness generation are keyed
6437
+ * by session id, so both must move with the binding: leaving them behind
6438
+ * keeps the stale id "busy" forever and drops the turn on a generation the
6439
+ * replacement never had.
6440
+ */
6441
+ moveNamedTurnBinding(binding, sessionId) {
6442
+ if (binding.sessionId !== null) {
6443
+ this.releaseQueuedTurn(binding.sessionId);
6444
+ }
6445
+ binding.sessionId = sessionId;
6446
+ binding.generation = this.sessionGenerations.get(sessionId) ?? 0;
6447
+ this.reserveQueuedTurn(sessionId);
6448
+ }
6023
6449
  finishNamedTurnBinding(envelope) {
6024
6450
  const binding = this.namedTurnBindings.get(envelope);
6025
6451
  if (!binding)
@@ -6075,12 +6501,51 @@ ${requestList}`);
6075
6501
  return true;
6076
6502
  }
6077
6503
  }
6504
+ /**
6505
+ * The actionable recovery message for a worktree task whose ownership state
6506
+ * the daemon refused to restore. Both codes come from the load/resume route
6507
+ * — the reset route resumes an interrupted transfer itself and reports a
6508
+ * broken marker as invalid state — so they surface on selection and on a
6509
+ * message, wrapped in the manager's generic load failure.
6510
+ *
6511
+ * Clearing always acts on the *selected* task, so pointing the user at a
6512
+ * clear is only safe when the task that failed is the selected one. Aimed at
6513
+ * any other task it would run a full ownership transfer against a healthy
6514
+ * one and destroy that conversation, so the alternative points at the close
6515
+ * that works on the broken task without loading it. Both name that task.
6516
+ */
6517
+ async worktreeRecoveryMessage(envelope, error) {
6518
+ const code = readDaemonHttpErrorCode(error);
6519
+ if (code !== "worktree_reset_interrupted" && code !== "worktree_marker_missing") {
6520
+ return void 0;
6521
+ }
6522
+ const interrupted = code === "worktree_reset_interrupted";
6523
+ const failedTaskName = error instanceof NamedSessionTaskError ? error.taskName : void 0;
6524
+ const safeTaskName = failedTaskName === void 0 ? void 0 : sanitizeDisplayText(failedTaskName, 32);
6525
+ const subject = safeTaskName === void 0 ? "The task" : `Task "${safeTaskName}"`;
6526
+ const problem = interrupted ? "was interrupted while being reset" : "cannot verify its worktree because its ownership marker is missing";
6527
+ if (safeTaskName !== void 0 && failedTaskName === await this.selectedTaskName(envelope)) {
6528
+ 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."}`;
6529
+ }
6530
+ 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}`)}`;
6531
+ return `${subject} ${problem}. Its files were not changed. Clearing now would reset the selected task instead, so ${remedy}.`;
6532
+ }
6533
+ async selectedTaskName(envelope) {
6534
+ const namedSessions = this.namedSessions;
6535
+ if (!namedSessions)
6536
+ return void 0;
6537
+ try {
6538
+ return (await namedSessions.current(this.namedSessionOwner(envelope)))?.name;
6539
+ } catch {
6540
+ return void 0;
6541
+ }
6542
+ }
6078
6543
  async sendNamedSessionError(envelope, error) {
6079
6544
  if (error instanceof Error && error.cause !== void 0) {
6080
6545
  process.stderr.write(`[${sanitizeLogText(this.name, 64)}] named-session operation failed: ${this.lifecycleError(error)} | cause: ${this.lifecycleError(error.cause)}
6081
6546
  `);
6082
6547
  }
6083
- const message = error instanceof Error ? sanitizeDisplayText(error.message, 500) : "Named-session operation failed.";
6548
+ const message = await this.worktreeRecoveryMessage(envelope, error) ?? (error instanceof Error ? sanitizeDisplayText(error.message, 500) : "Named-session operation failed.");
6084
6549
  await this.sendThreadMessage(envelope.chatId, envelope.threadId, message || "Named-session operation failed.");
6085
6550
  }
6086
6551
  async handleNamedSessionsCommand(envelope, args) {
@@ -6125,7 +6590,7 @@ ${requestList}`);
6125
6590
  }
6126
6591
  case "new": {
6127
6592
  const isolation = parts.length === 2 && parts[1] === "--worktree" ? "worktree" : "shared";
6128
- if (isolation === "shared" && parts.length !== 1 || isolation === "worktree" && parts.length !== 2) {
6593
+ if (isolation === "shared" && parts.length !== 1 || isolation === "worktree" && parts.length !== 2 || parts[0]?.startsWith("-")) {
6129
6594
  break;
6130
6595
  }
6131
6596
  const created = await namedSessions.create(owner, parts[0], isolation);
@@ -6186,6 +6651,7 @@ ${requestList}`);
6186
6651
  registerSharedCommands() {
6187
6652
  const doClear = /* @__PURE__ */ __name(async (envelope) => {
6188
6653
  let resetTaskName;
6654
+ let resetWorktreeKept = false;
6189
6655
  let removedIds;
6190
6656
  const retiringSessionId = this.namedSessions ? void 0 : this.router.getSession(this.name, envelope.senderId, envelope.chatId, envelope.threadId);
6191
6657
  if (retiringSessionId)
@@ -6194,8 +6660,18 @@ ${requestList}`);
6194
6660
  try {
6195
6661
  const reset = await this.namedSessions.reset(this.namedSessionOwner(envelope));
6196
6662
  resetTaskName = reset?.name;
6663
+ resetWorktreeKept = reset?.worktreeKept ?? false;
6197
6664
  removedIds = reset ? [reset.previousSessionId] : [];
6198
6665
  } catch (error) {
6666
+ const code = readDaemonHttpErrorCode(error);
6667
+ if (code !== void 0) {
6668
+ process.stderr.write(`[${sanitizeLogText(this.name, 64)}] worktree reset failed (${sanitizeLogText(code, 64)}): ${this.lifecycleError(error)}
6669
+ `);
6670
+ }
6671
+ if (code === "worktree_reset_active") {
6672
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Task is busy. Wait for the running prompt to finish (or cancel it), then try again.");
6673
+ return;
6674
+ }
6199
6675
  await this.sendNamedSessionError(envelope, error);
6200
6676
  return;
6201
6677
  }
@@ -6250,7 +6726,7 @@ ${requestList}`);
6250
6726
  }
6251
6727
  this.discardRetiredSession(this.bridge, id, "cleared");
6252
6728
  }
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.");
6729
+ 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
6730
  } else {
6255
6731
  await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No active session to clear.");
6256
6732
  }
@@ -7212,17 +7688,8 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
7212
7688
  const active = this.activePrompts.get(sessionId);
7213
7689
  return active?.senderName || active?.senderId || target.senderId || "agent";
7214
7690
  }
7215
- stopActiveStreaming(active, sessionId, reason) {
7216
- try {
7217
- active.stopStreaming?.();
7218
- } catch (err) {
7219
- process.stderr.write(`[${this.name}] stopStreaming threw during ${reason} for session ${sessionId}: ${err instanceof Error ? err.message : err}
7220
- `);
7221
- }
7222
- }
7223
7691
  /**
7224
- * Cancel the active turn and wait (bounded) for it to wind down. Stops the
7225
- * BlockStreamer so buffered text can't leak via the idle timer, then fires a
7692
+ * Cancel the active turn and wait (bounded) for it to wind down. Fires a
7226
7693
  * best-effort cancelSession (NOT awaited — a wedged child/daemon can leave the
7227
7694
  * request pending forever). Returns true if active.done settled first, false
7228
7695
  * if the CLEAR_CANCEL_TIMEOUT_MS bound won (the turn never wound down). Used by
@@ -7233,7 +7700,6 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
7233
7700
  */
7234
7701
  async cancelAndAwaitActive(active, sessionId) {
7235
7702
  active.cancelled = true;
7236
- this.stopActiveStreaming(active, sessionId, "cancel");
7237
7703
  void this.bridge.cancelSession(sessionId).catch((err) => {
7238
7704
  process.stderr.write(`[${this.name}] cancelSession failed for session=${sessionId} (clear/await): ${err instanceof Error ? err.message : err}
7239
7705
  `);
@@ -7775,8 +8241,10 @@ ${text}`;
7775
8241
  return;
7776
8242
  }
7777
8243
  try {
7778
- const resumed = await this.namedSessions.resumeReserved(this.namedSessionOwner(envelope), namedTurn.sessionId);
7779
- sessionId = resumed ? namedTurn.sessionId : void 0;
8244
+ sessionId = await this.namedSessions.resumeReserved(this.namedSessionOwner(envelope), namedTurn.sessionId);
8245
+ if (sessionId && sessionId !== namedTurn.sessionId) {
8246
+ this.moveNamedTurnBinding(namedTurn, sessionId);
8247
+ }
7780
8248
  } catch (error) {
7781
8249
  await this.sendNamedSessionError(envelope, error);
7782
8250
  return;
@@ -7921,7 +8389,6 @@ ${promptText}`;
7921
8389
  if (firstCancellation) {
7922
8390
  process.stderr.write(`[${this.name}] steer: cancelled active turn for ${envelope.senderId} in session ${sessionId}
7923
8391
  `);
7924
- this.stopActiveStreaming(active, sessionId, "steer");
7925
8392
  void this.bridge.cancelSession(sessionId).catch((err) => {
7926
8393
  process.stderr.write(`[${this.name}] cancelSession failed for session=${sessionId} (steer): ${err instanceof Error ? err.message : err}
7927
8394
  `);
@@ -7956,7 +8423,6 @@ ${promptText}`;
7956
8423
  }
7957
8424
  const prev = this.sessionQueues.get(sessionId) ?? Promise.resolve();
7958
8425
  const generation = namedTurn?.generation ?? this.sessionGenerations.get(sessionId) ?? 0;
7959
- const useBlockStreaming = this.config.blockStreaming === "on";
7960
8426
  if (namedTurn) {
7961
8427
  namedTurn.claimed = true;
7962
8428
  } else {
@@ -8059,18 +8525,9 @@ ${promptToSend}`;
8059
8525
  process.stderr.write(`[${this.name}] onPromptStart threw for session ${sessionId}: ${this.lifecycleError(err)}
8060
8526
  `);
8061
8527
  }
8062
- const streamer = useBlockStreaming ? new BlockStreamer({
8063
- minChars: this.config.blockStreamingChunk?.minChars ?? 400,
8064
- maxChars: this.config.blockStreamingChunk?.maxChars ?? 1e3,
8065
- idleMs: this.config.blockStreamingCoalesce?.idleMs ?? 1500,
8066
- send: /* @__PURE__ */ __name((text) => this.sendResponseMessage(envelope.chatId, text, sessionId, sourceLabel), "send")
8067
- }) : null;
8068
- promptState.stopStreaming = () => streamer?.stop();
8069
8528
  const heldChunks = [];
8070
- let hasStreamedText = false;
8071
8529
  const releaseHeldChunks = /* @__PURE__ */ __name(() => {
8072
8530
  for (const held of heldChunks.splice(0)) {
8073
- hasStreamedText = true;
8074
8531
  const segment = this.ensureOutputSegment(sessionId, promptState);
8075
8532
  this.emitTaskLifecycle({
8076
8533
  ...this.lifecycleBase(envelope.chatId, sessionId, envelope.messageId),
@@ -8078,7 +8535,6 @@ ${promptToSend}`;
8078
8535
  chunk: held
8079
8536
  });
8080
8537
  this.onResponseChunk(envelope.chatId, held, sessionId, segment);
8081
- streamer?.push(held);
8082
8538
  }
8083
8539
  }, "releaseHeldChunks");
8084
8540
  const onChunk = /* @__PURE__ */ __name((sid, chunk) => {
@@ -8095,10 +8551,8 @@ ${promptToSend}`;
8095
8551
  return;
8096
8552
  }
8097
8553
  heldChunks.length = 0;
8098
- hasStreamedText = false;
8099
8554
  const segment = this.closeOutputSegment(sessionId, promptState);
8100
8555
  void this.notifyOutputSegmentEnd(envelope.chatId, sessionId, segment, "response_boundary");
8101
- streamer?.stop();
8102
8556
  }, "onResponseBoundary");
8103
8557
  await this.waitForBridgeRecovery();
8104
8558
  const promptBridge = this.bridge;
@@ -8117,17 +8571,10 @@ ${promptToSend}`;
8117
8571
  }
8118
8572
  if (!promptState.cancelled && response) {
8119
8573
  promptState.deliveryStarted = true;
8120
- if (streamer) {
8121
- if (!hasStreamedText) {
8122
- streamer.push(response);
8123
- }
8124
- await streamer.flush();
8125
- } else {
8126
- const segment = this.ensureOutputSegment(sessionId, promptState);
8127
- await this.onResponseComplete(envelope.chatId, response, sessionId, segment);
8128
- if (segment && promptState.activeSegmentId === segment.segmentId) {
8129
- promptState.activeSegmentId = void 0;
8130
- }
8574
+ const segment = this.ensureOutputSegment(sessionId, promptState);
8575
+ await this.onResponseComplete(envelope.chatId, response, sessionId, segment);
8576
+ if (segment && promptState.activeSegmentId === segment.segmentId) {
8577
+ promptState.activeSegmentId = void 0;
8131
8578
  }
8132
8579
  }
8133
8580
  if (!promptState.deliveryStarted) {
@@ -8172,10 +8619,6 @@ ${promptToSend}`;
8172
8619
  } finally {
8173
8620
  promptBridge.off("textChunk", onChunk);
8174
8621
  promptBridge.off("responseBoundary", onResponseBoundary);
8175
- if (streamer) {
8176
- streamer.stop();
8177
- await streamer.drain();
8178
- }
8179
8622
  const stillCurrent = this.activePrompts.get(sessionId) === promptState;
8180
8623
  if (!promptState.clearEvicted) {
8181
8624
  try {
@@ -8489,6 +8932,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
8489
8932
  activePrompts = /* @__PURE__ */ new Set();
8490
8933
  activePromptControllers = /* @__PURE__ */ new Map();
8491
8934
  availableCommandsBySession = /* @__PURE__ */ new Map();
8935
+ toolCallKindsBySession = /* @__PURE__ */ new Map();
8492
8936
  turnBarriers = /* @__PURE__ */ new Map();
8493
8937
  channelLoopToolHandlers = [];
8494
8938
  channelLoopDisabledSessions = /* @__PURE__ */ new Set();
@@ -8595,6 +9039,38 @@ var DaemonChannelBridge = class extends EventEmitter2 {
8595
9039
  }
8596
9040
  return session.sessionId;
8597
9041
  }
9042
+ /**
9043
+ * Transfer a worktree session's checkout ownership to a fresh replacement
9044
+ * session (daemon `session_worktree_reset_v1`). The returned id is the
9045
+ * replacement's; the superseded session's clients stay bound to it (and
9046
+ * are forgotten by the caller). Gated on the capability flag so a daemon
9047
+ * without reset support fails before any session is created.
9048
+ */
9049
+ async resetWorktreeSession(sessionId, cwd, options, bindingToken) {
9050
+ if (!this.options.sessionWorktreeReset) {
9051
+ throw new Error("The daemon does not support worktree reset for Channel tasks.");
9052
+ }
9053
+ const lifecycleGeneration = this.lifecycleGeneration;
9054
+ const session = await this.options.sessionFactory({
9055
+ workspaceCwd: cwd || this.options.cwd,
9056
+ modelServiceId: this.options.modelServiceId,
9057
+ sessionScope: this.options.sessionScope ?? "thread",
9058
+ ...options?.approvalMode ? { approvalMode: options.approvalMode } : {},
9059
+ ...options?.sourceId ? { sourceId: options.sourceId } : {},
9060
+ worktreeReset: { sessionId }
9061
+ });
9062
+ if (lifecycleGeneration !== this.lifecycleGeneration) {
9063
+ await this.rejectStaleSession(session);
9064
+ }
9065
+ this.attachSession(session, bindingToken);
9066
+ if (options?.enableChannelLoops === false) {
9067
+ this.channelLoopDisabledSessions.add(session.sessionId);
9068
+ void this.reconcileChannelLoopMcpForSession(session.sessionId);
9069
+ } else {
9070
+ await this.reconcileChannelLoopMcpForSession(session.sessionId);
9071
+ }
9072
+ return session.sessionId;
9073
+ }
8598
9074
  registerChannelLoopToolHandler(handler) {
8599
9075
  if (!this.channelLoopToolHandlers.includes(handler)) {
8600
9076
  this.channelLoopToolHandlers.push(handler);
@@ -9001,15 +9477,23 @@ var DaemonChannelBridge = class extends EventEmitter2 {
9001
9477
  case "tool_call":
9002
9478
  case "tool_call_update": {
9003
9479
  const toolCallId = getString(update["toolCallId"]);
9004
- const kind = getString(update["kind"]);
9480
+ const explicitKind = getString(update["kind"]);
9005
9481
  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)) {
9482
+ if (!explicitKind && toolCallId && getString(update["status"]) === "in_progress" && (meta?.["shellProgress"] !== void 0 || meta?.["subagentProgress"] === true)) {
9007
9483
  break;
9008
9484
  }
9485
+ let sessionKinds = this.toolCallKindsBySession.get(sessionId);
9486
+ const kind = explicitKind || sessionKinds?.get(toolCallId ?? "");
9009
9487
  if (!toolCallId || !kind) {
9010
9488
  this.emitProtocolError(`Malformed daemon ${type} event`, update);
9011
9489
  break;
9012
9490
  }
9491
+ if (type === "tool_call" || explicitKind) {
9492
+ const kinds = sessionKinds ?? /* @__PURE__ */ new Map();
9493
+ kinds.set(toolCallId, kind);
9494
+ this.toolCallKindsBySession.set(sessionId, kinds);
9495
+ sessionKinds = kinds;
9496
+ }
9013
9497
  const event = {
9014
9498
  sessionId,
9015
9499
  toolCallId,
@@ -9022,6 +9506,12 @@ var DaemonChannelBridge = class extends EventEmitter2 {
9022
9506
  this.emitResponseBoundary(sessionId);
9023
9507
  }
9024
9508
  this.emit("toolCall", event);
9509
+ if (event.status === "completed" || event.status === "failed") {
9510
+ sessionKinds?.delete(toolCallId);
9511
+ if (sessionKinds?.size === 0) {
9512
+ this.toolCallKindsBySession.delete(sessionId);
9513
+ }
9514
+ }
9025
9515
  break;
9026
9516
  }
9027
9517
  case "plan": {
@@ -9149,6 +9639,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
9149
9639
  this.abortActivePrompts(sessionId);
9150
9640
  this.activePrompts.delete(sessionId);
9151
9641
  this.availableCommandsBySession.delete(sessionId);
9642
+ this.toolCallKindsBySession.delete(sessionId);
9152
9643
  if (this.latestAvailableCommandsSessionId === sessionId) {
9153
9644
  this.latestAvailableCommandsSessionId = Array.from(this.availableCommandsBySession.keys()).at(-1);
9154
9645
  }