@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
@@ -20,7 +20,7 @@ import {
20
20
  shouldSuppressRememberErrorDetails,
21
21
  workspaceMemoryFailureCode,
22
22
  workspaceMemoryFailureDiagnostics
23
- } from "./chunk-SI6Q52UI.js";
23
+ } from "./chunk-FEEVHJOR.js";
24
24
  import {
25
25
  SetupGithubError,
26
26
  collectSessionData,
@@ -32,13 +32,13 @@ import {
32
32
  toJson,
33
33
  toJsonl,
34
34
  toMarkdown
35
- } from "./chunk-PMGWY6ZP.js";
35
+ } from "./chunk-HWLLUDIA.js";
36
36
  import {
37
37
  OBSERVED_CONTACT_MAX_FRESH_WITHIN_SECONDS,
38
38
  ObservedChannelContactStore
39
39
  } from "./chunk-M3JGHRMQ.js";
40
40
  import "./chunk-VFFQAOPR.js";
41
- import "./chunk-37SOBIA3.js";
41
+ import "./chunk-ERXNTINK.js";
42
42
  import {
43
43
  escapeAnsiCtrlCodes
44
44
  } from "./chunk-47ECGEJC.js";
@@ -52,18 +52,20 @@ import {
52
52
  ACP_PRE_ATTACH_MAX_PAYLOAD_BYTES_GLOBAL,
53
53
  ACP_PRE_ATTACH_MAX_PAYLOAD_BYTES_PER_CONNECTION,
54
54
  AcpPreAttachBudget,
55
+ AmbiguousLanInterfaceError,
55
56
  CAPABILITIES_SCHEMA_VERSION,
56
57
  ClientMcpSenderRegistry,
57
- ConversationRuntimeOwnershipError,
58
58
  CredentialStore,
59
59
  DeviceFlowRegistry,
60
60
  LocalPathOpenUnavailableError,
61
61
  MAX_CONCURRENT_VOICE_SESSIONS,
62
62
  MutableOriginAllowlist,
63
63
  NativeDirectoryPickerUnavailableError,
64
+ NoLanInterfaceError,
64
65
  PathMutexRegistry,
65
66
  QWEN_CDP_MCP_COMMAND_ENV,
66
67
  TooManyActiveDeviceFlowsError,
68
+ UnknownLanInterfaceError,
67
69
  UnsupportedDeviceFlowProviderError,
68
70
  UpstreamDeviceFlowError,
69
71
  VoiceLeaseAbortError,
@@ -73,10 +75,6 @@ import {
73
75
  bearerAuth,
74
76
  brandSecret,
75
77
  buildDaemonStatusResponse,
76
- conversationRootCompromisedError,
77
- conversationRuntimeInUseError,
78
- conversationRuntimeOwnershipCompromisedError,
79
- conversationRuntimeUnavailableError,
80
78
  createBridgeFileSystemAdapter,
81
79
  createClientMcpServerProvider,
82
80
  createManagedScratchDirectory,
@@ -89,6 +87,7 @@ import {
89
87
  getServeProtocolVersions,
90
88
  hostAllowlist,
91
89
  installAccessLogMiddleware,
90
+ installRemoteSelfOriginMiddleware,
92
91
  installSelfOriginStripMiddleware,
93
92
  installServeAppLifecycle,
94
93
  isBrowserAutomationMcpAvailable,
@@ -98,6 +97,7 @@ import {
98
97
  isNativeDirectoryPickerAvailable,
99
98
  isScratchRootCompatible,
100
99
  isTrustedLoopbackMode,
100
+ listLanCandidates,
101
101
  listenerIdentityOf,
102
102
  listenerIdentityOfSocket,
103
103
  openPathLocally,
@@ -109,12 +109,13 @@ import {
109
109
  resolveAcpHttpEnabled,
110
110
  resolveCdpMcpCommand,
111
111
  sanitizeForStderr,
112
+ selectLanAddress,
112
113
  setDeviceFlowRegistry,
113
114
  setRateLimiter,
114
115
  singleTokenCredentials,
115
116
  tagListener,
116
117
  unsafeRevealSecret
117
- } from "./chunk-6KYWU726.js";
118
+ } from "./chunk-VJJXG73H.js";
118
119
  import {
119
120
  ConversationDirectoryIdentityError,
120
121
  getConversationDirectoryName,
@@ -125,15 +126,16 @@ import {
125
126
  import "./chunk-UXEO7E3V.js";
126
127
  import {
127
128
  createTotalSessionAdmissionController
128
- } from "./chunk-7IKXTGZT.js";
129
+ } from "./chunk-YI2YCNSP.js";
129
130
  import {
130
131
  assertValidChannelSecretUpdates
131
- } from "./chunk-AUJOWIT5.js";
132
+ } from "./chunk-UQOP2APG.js";
132
133
  import {
133
134
  AONE_MAX_MR_VIEW_CALLS_PER_RUN,
134
135
  DaemonDrainingError,
135
136
  InvalidCursorError,
136
137
  SessionArchiveCoordinator,
138
+ acquireWorktreeOwnershipOp,
137
139
  archiveDaemonSessions,
138
140
  assertSessionArchived,
139
141
  assertSessionLoadable,
@@ -156,7 +158,7 @@ import {
156
158
  runWithWorkspaceRuntimeStorage,
157
159
  searchWorkspaceSessionsForResponse,
158
160
  unarchiveDaemonSessions
159
- } from "./chunk-WLZRMF3C.js";
161
+ } from "./chunk-7KZVXJ4U.js";
160
162
  import {
161
163
  LIVE_SESSION_SOURCE_PREFIX,
162
164
  isCompatibleLiveSessionSource,
@@ -196,10 +198,10 @@ import {
196
198
  isServeDebugMode,
197
199
  mountWebShellAssets,
198
200
  mountWebShellSpaFallback
199
- } from "./chunk-NFIDVZND.js";
201
+ } from "./chunk-QB3KS3N3.js";
200
202
  import {
201
203
  require_express
202
- } from "./chunk-IRKQ4YYX.js";
204
+ } from "./chunk-SVWWF5TZ.js";
203
205
  import "./chunk-FBX2SDQ4.js";
204
206
  import {
205
207
  formatHostForAuthority,
@@ -208,17 +210,17 @@ import {
208
210
  import {
209
211
  evaluateDaemonWorkspaceTrust,
210
212
  readDaemonTrustPolicySnapshot
211
- } from "./chunk-733KQL63.js";
213
+ } from "./chunk-EE5ZD4XU.js";
212
214
  import {
213
215
  readRecentPromptTerminals,
214
216
  reconcileDanglingPromptTerminals,
215
217
  withPromptTerminals
216
- } from "./chunk-RD3VPM4E.js";
218
+ } from "./chunk-BZUHZCUO.js";
217
219
  import {
218
220
  WorkspaceGenerationClosedError,
219
221
  createSingleWorkspaceRegistry,
220
222
  createWorkspaceSessionOwnerIndex
221
- } from "./chunk-QJVZLILI.js";
223
+ } from "./chunk-R7OO56VZ.js";
222
224
  import {
223
225
  sessionAttachmentsRoots
224
226
  } from "./chunk-XWJFDJZK.js";
@@ -244,11 +246,11 @@ import {
244
246
  sendUntrustedWorkspaceResponse,
245
247
  sendWorkspaceRuntimeUnavailable,
246
248
  setWorkspaceRouteContext
247
- } from "./chunk-QQGAR64U.js";
249
+ } from "./chunk-EN3Q2S3J.js";
248
250
  import {
249
251
  normalizeChannelDelivery,
250
252
  parseChannelDelivery
251
- } from "./chunk-ZNI3V2XA.js";
253
+ } from "./chunk-VJWJOKOQ.js";
252
254
  import {
253
255
  isValidSessionId,
254
256
  normalizeSessionIdForLookup,
@@ -263,7 +265,7 @@ import {
263
265
  getWorkspaceRuntimeCoordinator,
264
266
  getWorkspaceRuntimeCoordinatorIfSupported,
265
267
  supportsWorkspaceRuntimeLifecycle
266
- } from "./chunk-RCUWMVN3.js";
268
+ } from "./chunk-HZ2HUXX7.js";
267
269
  import "./chunk-OIBUG24X.js";
268
270
  import {
269
271
  MAX_SESSION_RESTORE_TIMEOUT_MS,
@@ -285,14 +287,14 @@ import {
285
287
  validateWorkspaceSkillName,
286
288
  validateWorkspaceVoiceState,
287
289
  voiceSettingsScopeToWire
288
- } from "./chunk-REDVV5NC.js";
290
+ } from "./chunk-7WCJEY3A.js";
289
291
  import {
290
292
  PermissionRulesValidationError,
291
293
  buildPermissionSettings,
292
294
  isPermissionRuleType,
293
295
  normalizePermissionRules,
294
296
  readPermissionRuleSet
295
- } from "./chunk-75UQFGFE.js";
297
+ } from "./chunk-FN4KHWCL.js";
296
298
  import {
297
299
  assertVoiceBaseUrlNetworkAllowed,
298
300
  isStreamingVoiceModel,
@@ -300,18 +302,18 @@ import {
300
302
  resolveVoiceTranscriptionConfig,
301
303
  sanitizeVoiceErrorMessage,
302
304
  transcribeVoiceAudio
303
- } from "./chunk-Z6DDPSGJ.js";
305
+ } from "./chunk-GNY7B3CA.js";
304
306
  import {
305
307
  isVoiceEnabled,
306
308
  isVoiceMode,
307
309
  readVoiceModel
308
- } from "./chunk-JOV46WGX.js";
310
+ } from "./chunk-NB3NDQQK.js";
309
311
  import "./chunk-Y53DG2HA.js";
310
312
  import {
311
313
  createDaemonStatusProvider
312
- } from "./chunk-RQNAO42A.js";
313
- import "./chunk-FWH4736Q.js";
314
- import "./chunk-TDHVOZ65.js";
314
+ } from "./chunk-E4LXNQAK.js";
315
+ import "./chunk-O6BFERWN.js";
316
+ import "./chunk-LOBKNYPR.js";
315
317
  import "./chunk-JS73NNWF.js";
316
318
  import {
317
319
  SessionArtifactAuthorizationError,
@@ -320,7 +322,7 @@ import {
320
322
  extractErrorCode,
321
323
  extractErrorMessage,
322
324
  parseSessionSource
323
- } from "./chunk-ZT3XUGSU.js";
325
+ } from "./chunk-ZZ7RVOTU.js";
324
326
  import {
325
327
  EVENT_SCHEMA_VERSION,
326
328
  EventBus,
@@ -333,21 +335,21 @@ import {
333
335
  } from "./chunk-KA5HR3G2.js";
334
336
  import {
335
337
  createWorkspaceProvidersStatusProvider
336
- } from "./chunk-EPZWBYQI.js";
338
+ } from "./chunk-D7DFZAK2.js";
337
339
  import {
338
340
  PERSIST_REASONING_SELECTION_META_KEY,
339
341
  REASONING_SELECTION_PERSISTED_META_KEY
340
- } from "./chunk-ZJ2LM2SI.js";
342
+ } from "./chunk-N3Z6Q7KC.js";
341
343
  import {
342
344
  getAuthTypeFromEnv,
343
345
  resolveCliGenerationConfig
344
- } from "./chunk-I7UNCY24.js";
346
+ } from "./chunk-6GAYNM3F.js";
345
347
  import {
346
348
  snapshotProcessEnv
347
349
  } from "./chunk-6RZX2HIH.js";
348
350
  import {
349
351
  createWorkspaceSkillsStatusProvider
350
- } from "./chunk-5FYGZ7E3.js";
352
+ } from "./chunk-MUF4UGPB.js";
351
353
  import "./chunk-BHTYRHJF.js";
352
354
  import {
353
355
  BridgeTimeoutError,
@@ -366,29 +368,35 @@ import {
366
368
  WorkspaceSkillNotFoundError,
367
369
  mapWorkspaceSkillToggleError
368
370
  } from "./chunk-FTJMWDND.js";
369
- import "./chunk-537SQ2AI.js";
371
+ import "./chunk-KECCLCXM.js";
370
372
  import {
371
373
  daemonObservedContactsPath,
372
374
  loadChannelsConfig
373
- } from "./chunk-3RMVM33U.js";
374
- import "./chunk-2C3XDBGL.js";
375
+ } from "./chunk-EDSU3VUG.js";
376
+ import "./chunk-6S7YYUUH.js";
375
377
  import "./chunk-57OAHC2Y.js";
376
378
  import {
377
379
  parseChannelWebhookConfigLenient
378
- } from "./chunk-BNWIX6BM.js";
380
+ } from "./chunk-JFAGT5YG.js";
379
381
  import {
380
382
  supportedChannelCatalog
381
- } from "./chunk-RGAQDQ3Z.js";
382
- import "./chunk-RH344FKI.js";
383
+ } from "./chunk-7IDZFJAV.js";
384
+ import "./chunk-AUTUFD5X.js";
383
385
  import "./chunk-V6WHFGST.js";
384
386
  import {
387
+ assertLiveDiscoveryPublisher,
385
388
  getStableLiveDiscoveryBaseDir
386
- } from "./chunk-OHOO527W.js";
389
+ } from "./chunk-WG7BL3FY.js";
387
390
  import {
391
+ ConversationRuntimeOwnershipError,
388
392
  LIVE_HOST_BUNDLE_ID,
389
393
  LIVE_HOST_PROTOCOL_VERSION,
390
- LIVE_INPUT_AUDIO_EPOCH_BYTES
391
- } from "./chunk-IQAFKVXS.js";
394
+ LIVE_INPUT_AUDIO_EPOCH_BYTES,
395
+ conversationRootCompromisedError,
396
+ conversationRuntimeInUseError,
397
+ conversationRuntimeOwnershipCompromisedError,
398
+ conversationRuntimeUnavailableError
399
+ } from "./chunk-2Z3T52OC.js";
392
400
  import "./chunk-ZL4HFSL6.js";
393
401
  import "./chunk-K6KS3LTN.js";
394
402
  import "./chunk-OSHQMOBS.js";
@@ -399,13 +407,13 @@ import {
399
407
  WorkspaceRegistrationStoreLimitError,
400
408
  normalizeWorkspaceDisplayName,
401
409
  workspaceRegistrationId
402
- } from "./chunk-WFXD5OZH.js";
410
+ } from "./chunk-AXWTG6R7.js";
403
411
  import {
404
412
  CHANNEL_PROMPT_META_KEY,
405
413
  DAEMON_PROMPT_DISPLAY_TEXT_META_KEY,
406
414
  REQUESTED_SESSION_ID_META_KEY,
407
415
  gradeActiveWorkCoverage
408
- } from "./chunk-Z6KFLEG7.js";
416
+ } from "./chunk-PSPAM24S.js";
409
417
  import {
410
418
  BranchWhilePromptActiveError,
411
419
  BridgeChannelQuarantinedError,
@@ -431,6 +439,7 @@ import {
431
439
  SessionLimitExceededError,
432
440
  SessionNotArchivedError,
433
441
  SessionNotFoundError,
442
+ SessionResetPendingError,
434
443
  SessionShellClientRequiredError,
435
444
  SessionShellDisabledError,
436
445
  StandaloneSessionSpawnError,
@@ -441,7 +450,7 @@ import {
441
450
  WorkspaceInitRaceError,
442
451
  WorkspaceInitSymlinkError,
443
452
  WorkspaceMismatchError
444
- } from "./chunk-F47DITLZ.js";
453
+ } from "./chunk-FAWTMDX7.js";
445
454
  import {
446
455
  MAX_WORKSPACE_PATH_LENGTH,
447
456
  canonicalizeWorkspace,
@@ -461,7 +470,7 @@ import {
461
470
  } from "./chunk-STUJ7IMZ.js";
462
471
  import {
463
472
  normalizeWorkerDiagnostic
464
- } from "./chunk-5V4B3EWA.js";
473
+ } from "./chunk-DARWOZY6.js";
465
474
  import {
466
475
  QWEN_SERVER_TOKEN_ENV
467
476
  } from "./chunk-GYTKQYDB.js";
@@ -477,11 +486,11 @@ import {
477
486
  redactLogCredentials
478
487
  } from "./chunk-M5GB774H.js";
479
488
  import "./chunk-3VUENPWF.js";
489
+ import "./chunk-TGNNLRC3.js";
480
490
  import {
481
491
  sanitizeLogText
482
- } from "./chunk-65GHQ4FX.js";
492
+ } from "./chunk-WDVV3LRM.js";
483
493
  import "./chunk-IW6RQPQB.js";
484
- import "./chunk-5HBA2Z7V.js";
485
494
  import {
486
495
  WORKSPACE_RESTRICTED_SETTING_KEYS,
487
496
  getDialogSettingKeys,
@@ -494,8 +503,8 @@ import {
494
503
  resolveOutputLanguageOrPreserveAuto,
495
504
  updateOutputLanguageFile,
496
505
  validateSettingValue
497
- } from "./chunk-RUMSY4ES.js";
498
- import "./chunk-QW7BUOSI.js";
506
+ } from "./chunk-Y7YHAY32.js";
507
+ import "./chunk-LOVGQ3HZ.js";
499
508
  import "./chunk-RKUWKYED.js";
500
509
  import "./chunk-BW4333PP.js";
501
510
  import "./chunk-IDS7MSUP.js";
@@ -504,24 +513,23 @@ import {
504
513
  getCurrentLanguage,
505
514
  resolveLanguageSetting,
506
515
  setLanguageAsync
507
- } from "./chunk-LD53HMPV.js";
516
+ } from "./chunk-CRZBDVP2.js";
508
517
  import {
509
518
  SUPPORTED_LANGUAGES,
510
519
  resolveSupportedLanguage
511
520
  } from "./chunk-5EJZE3FP.js";
512
- import "./chunk-4OCYWXKF.js";
513
- import "./chunk-NUQFUXOG.js";
514
- import "./chunk-SHX2HIE7.js";
521
+ import "./chunk-43EUMPKQ.js";
522
+ import "./chunk-QTNCGZHQ.js";
523
+ import "./chunk-ATBLEXXV.js";
515
524
  import "./chunk-W3N5XAZ6.js";
516
525
  import {
517
526
  getWorkspaceTrustStatus
518
- } from "./chunk-GEV66YGE.js";
527
+ } from "./chunk-D6AGS266.js";
519
528
  import "./chunk-NPQ5ZKRP.js";
520
529
  import {
521
530
  isWithinRoot as isWithinRoot2
522
531
  } from "./chunk-MR3PXB6E.js";
523
532
  import {
524
- ALL_PROVIDERS,
525
533
  BTW_MAX_INPUT_LENGTH,
526
534
  ClientMcpRegistrar,
527
535
  IMAGE_CAPABILITY,
@@ -530,26 +538,30 @@ import {
530
538
  WorkspaceMemoryWriteTimeoutError,
531
539
  buildUsageDashboard,
532
540
  loadIgnoreRules,
533
- shouldShowStep,
534
541
  writeWorkspaceContextFile
535
- } from "./chunk-TXAEXF2B.js";
542
+ } from "./chunk-ZEFWBG2C.js";
536
543
  import "./chunk-GELRJXE2.js";
537
544
  import "./chunk-32CM56LO.js";
538
- import "./chunk-C7M445SS.js";
545
+ import "./chunk-3A2IMUDH.js";
539
546
  import "./chunk-2EKVPSIJ.js";
540
547
  import "./chunk-LJZSMWOH.js";
541
548
  import {
549
+ clearWorktreeSession,
542
550
  readWorktreeSession,
543
551
  readWorktreeSessionStrict,
544
552
  writeWorktreeSession
545
- } from "./chunk-E4VX6LXB.js";
546
- import "./chunk-RSU3I6UL.js";
553
+ } from "./chunk-YZTGGCEE.js";
554
+ import {
555
+ ALL_PROVIDERS,
556
+ shouldShowStep
557
+ } from "./chunk-PLEBBGHL.js";
558
+ import "./chunk-JGTMTJSQ.js";
547
559
  import "./chunk-DJXSOEFB.js";
548
- import "./chunk-KTLT7VCX.js";
560
+ import "./chunk-LKBOBUA2.js";
549
561
  import "./chunk-J3VZF2AL.js";
550
562
  import "./chunk-OWCFKIFQ.js";
551
563
  import "./chunk-ZPJWUGCS.js";
552
- import "./chunk-5Z4FCEPY.js";
564
+ import "./chunk-7K4GGN3D.js";
553
565
  import "./chunk-BUQN5LTI.js";
554
566
  import {
555
567
  QwenOAuth2Client,
@@ -559,8 +571,8 @@ import {
559
571
  isDeviceAuthorizationSuccess,
560
572
  isDeviceTokenPending,
561
573
  isDeviceTokenSuccess
562
- } from "./chunk-VU7O7CGQ.js";
563
- import "./chunk-SD7Y2PMC.js";
574
+ } from "./chunk-XDNFODER.js";
575
+ import "./chunk-SM66GFKJ.js";
564
576
  import "./chunk-VNOVK4I7.js";
565
577
  import {
566
578
  BuiltinAgentRegistry,
@@ -644,23 +656,25 @@ import {
644
656
  toSessionPrInfo,
645
657
  upsertSessionPr,
646
658
  watchRepoBranch
647
- } from "./chunk-TSLRORQR.js";
659
+ } from "./chunk-BDAVT6K2.js";
648
660
  import "./chunk-GOFAQQZA.js";
649
- import "./chunk-3K65MUKD.js";
661
+ import "./chunk-65I7S4Z3.js";
650
662
  import "./chunk-6HUXPLB5.js";
651
663
  import "./chunk-TWPJO254.js";
652
664
  import "./chunk-CQ35AJ4Z.js";
653
- import "./chunk-YHDGABDC.js";
665
+ import "./chunk-XKBFYTCD.js";
654
666
  import "./chunk-LYT2OU7D.js";
655
- import "./chunk-B54PFQS5.js";
667
+ import "./chunk-7CLLH5TI.js";
656
668
  import {
657
669
  GitWorktreeService,
670
+ WorktreeMarkerCommittedError,
658
671
  createWorktreeSessionMarkerExclusive,
659
- readWorktreeSessionMarkerStrict
660
- } from "./chunk-ERMAXPXA.js";
672
+ readWorktreeSessionMarkerStrict,
673
+ transferWorktreeSessionMarkerOwner
674
+ } from "./chunk-HIXUUCGY.js";
661
675
  import "./chunk-6PVPNMXU.js";
662
676
  import "./chunk-565U2ANU.js";
663
- import "./chunk-FDOGGKAA.js";
677
+ import "./chunk-GSFV5RQW.js";
664
678
  import "./chunk-IRH27ZC2.js";
665
679
  import "./chunk-QHWCP53L.js";
666
680
  import {
@@ -677,8 +691,8 @@ import "./chunk-N6S3NUYJ.js";
677
691
  import "./chunk-O6GEWCJA.js";
678
692
  import "./chunk-CHEIIBT3.js";
679
693
  import "./chunk-QAZ2MGYT.js";
680
- import "./chunk-B44JBZBB.js";
681
- import "./chunk-BF3RUIVP.js";
694
+ import "./chunk-F4SAL7WM.js";
695
+ import "./chunk-CH2YDT6X.js";
682
696
  import {
683
697
  APPROVAL_MODES
684
698
  } from "./chunk-JX6XHPTX.js";
@@ -688,25 +702,25 @@ import {
688
702
  validateSkillName
689
703
  } from "./chunk-CLKE4IY3.js";
690
704
  import "./chunk-ZSTCM3MX.js";
691
- import "./chunk-NXWYCSPL.js";
705
+ import "./chunk-SOA4HKRJ.js";
692
706
  import "./chunk-MLXTMF7H.js";
693
- import "./chunk-OFB36ZBA.js";
707
+ import "./chunk-2HYOOFDS.js";
694
708
  import {
695
709
  findGitRoot
696
710
  } from "./chunk-3CZ2BQV6.js";
697
711
  import "./chunk-PQEISIKS.js";
698
- import "./chunk-3K456UJF.js";
712
+ import "./chunk-HSO6D4KX.js";
699
713
  import "./chunk-H3Q3RSKZ.js";
700
714
  import "./chunk-S6LOFUVP.js";
701
715
  import "./chunk-NAVJD2PQ.js";
702
- import "./chunk-UKADFFL2.js";
703
- import "./chunk-EJNYBDYC.js";
716
+ import "./chunk-OFVAS4AR.js";
717
+ import "./chunk-HNLMYDQE.js";
704
718
  import "./chunk-QHMLYMMS.js";
705
719
  import "./chunk-CFKIH3D3.js";
706
- import "./chunk-2LD5U7Q3.js";
720
+ import "./chunk-AXMWHKXA.js";
707
721
  import "./chunk-DJ2GSRLV.js";
708
- import "./chunk-W4LL5RZO.js";
709
- import "./chunk-3UMWOKJC.js";
722
+ import "./chunk-4ALNJDHL.js";
723
+ import "./chunk-NOO4QFXM.js";
710
724
  import "./chunk-KFFCDLKV.js";
711
725
  import {
712
726
  addDaemonRequestAttribute,
@@ -724,9 +738,9 @@ import "./chunk-XWRJCPHC.js";
724
738
  import {
725
739
  parseLineTolerant,
726
740
  read
727
- } from "./chunk-WQBR7LN5.js";
741
+ } from "./chunk-FRS3P7MQ.js";
728
742
  import "./chunk-5ETULJLP.js";
729
- import "./chunk-XBVNNDPK.js";
743
+ import "./chunk-GSYD7MYP.js";
730
744
  import "./chunk-VGC4I5JJ.js";
731
745
  import {
732
746
  CursorNotAtLineBoundaryError,
@@ -740,9 +754,9 @@ import {
740
754
  import "./chunk-EDIDYZBT.js";
741
755
  import "./chunk-HD7O6WLV.js";
742
756
  import "./chunk-WZAD4ZNJ.js";
743
- import "./chunk-FPGTNKCP.js";
757
+ import "./chunk-F3M6P6IQ.js";
744
758
  import "./chunk-TIGXX4PA.js";
745
- import "./chunk-PLUAIHZO.js";
759
+ import "./chunk-EOLGAQ25.js";
746
760
  import "./chunk-XFFRI3WM.js";
747
761
  import "./chunk-4HOEU2OR.js";
748
762
  import "./chunk-HHJLM3WQ.js";
@@ -802,93 +816,6 @@ import * as path18 from "node:path";
802
816
  // packages/cli/src/serve/local-control/index.ts
803
817
  init_esbuild_shims();
804
818
 
805
- // packages/cli/src/serve/local-control/lan-interfaces.ts
806
- init_esbuild_shims();
807
- import { networkInterfaces } from "node:os";
808
- function isLanIpv4(address) {
809
- const octets = address.split(".").map((part) => Number(part));
810
- if (octets.length !== 4 || octets.some((o) => !Number.isInteger(o))) {
811
- return false;
812
- }
813
- const [a, b] = octets;
814
- if (a === 10) return true;
815
- if (a === 172 && b >= 16 && b <= 31) return true;
816
- if (a === 192 && b === 168) return true;
817
- if (a === 169 && b === 254) return true;
818
- return false;
819
- }
820
- __name(isLanIpv4, "isLanIpv4");
821
- function isSoftwareNetwork(interfaceName) {
822
- if (/vpn/i.test(interfaceName)) return true;
823
- return /(^|[\s_.-])(utun|tun|tap|ppp|ipsec|wg|wireguard|tailscale|zerotier|zt[a-z0-9]*|hamachi|nordlynx|proton|wintun|docker|veth[0-9a-f]+|vmnet|vboxnet|vethernet|virtualbox|host[- ]only|podman|cni|lxcbr|lxdbr|flannel|virbr|br-[0-9a-f]+|bridge\d|anyconnect|globalprotect|pulse[\s-]secure|forticlient|fortinet|ivanti|cisco[\s_-]secure|citrix|sonicwall|cloudflare)(\d|[\s_.-]|$)/i.test(
824
- interfaceName
825
- );
826
- }
827
- __name(isSoftwareNetwork, "isSoftwareNetwork");
828
- function listLanCandidates(interfaces = networkInterfaces()) {
829
- const candidates = [];
830
- for (const [interfaceName, addresses] of Object.entries(interfaces).sort()) {
831
- if (isSoftwareNetwork(interfaceName)) continue;
832
- for (const address of addresses ?? []) {
833
- if (address.family !== "IPv4" || address.internal) continue;
834
- if (!isLanIpv4(address.address)) continue;
835
- candidates.push({ interfaceName, address: address.address });
836
- }
837
- }
838
- return candidates;
839
- }
840
- __name(listLanCandidates, "listLanCandidates");
841
- var NoLanInterfaceError = class extends Error {
842
- static {
843
- __name(this, "NoLanInterfaceError");
844
- }
845
- code = "no_lan_interface";
846
- constructor() {
847
- super(
848
- "No private IPv4 address is available. Local Control needs the host to be on a local network (Wi-Fi or Ethernet)."
849
- );
850
- this.name = "NoLanInterfaceError";
851
- }
852
- };
853
- var AmbiguousLanInterfaceError = class extends Error {
854
- static {
855
- __name(this, "AmbiguousLanInterfaceError");
856
- }
857
- code = "ambiguous_lan_interface";
858
- candidates;
859
- constructor(candidates) {
860
- super(
861
- "Multiple local networks are available; choose which one to expose: " + candidates.map((c) => `${c.interfaceName} (${c.address})`).join(", ")
862
- );
863
- this.name = "AmbiguousLanInterfaceError";
864
- this.candidates = candidates;
865
- }
866
- };
867
- var UnknownLanInterfaceError = class extends Error {
868
- static {
869
- __name(this, "UnknownLanInterfaceError");
870
- }
871
- code = "unknown_lan_interface";
872
- constructor(requested) {
873
- super(
874
- `${requested} is not a private IPv4 address on this host right now. The network may have changed since the list was fetched.`
875
- );
876
- this.name = "UnknownLanInterfaceError";
877
- }
878
- };
879
- function selectLanAddress(preferredAddress, interfaces = networkInterfaces()) {
880
- const candidates = listLanCandidates(interfaces);
881
- if (candidates.length === 0) throw new NoLanInterfaceError();
882
- if (preferredAddress !== void 0) {
883
- const match = candidates.find((c) => c.address === preferredAddress);
884
- if (!match) throw new UnknownLanInterfaceError(preferredAddress);
885
- return match;
886
- }
887
- if (candidates.length > 1) throw new AmbiguousLanInterfaceError(candidates);
888
- return candidates[0];
889
- }
890
- __name(selectLanAddress, "selectLanAddress");
891
-
892
819
  // packages/cli/src/serve/local-control/service.ts
893
820
  init_esbuild_shims();
894
821
  import { randomBytes, randomUUID } from "node:crypto";
@@ -6220,7 +6147,7 @@ __name(createRequestedSessionIdAdmission, "createRequestedSessionIdAdmission");
6220
6147
 
6221
6148
  // packages/cli/src/serve/conversations/standalone-session-service.ts
6222
6149
  init_esbuild_shims();
6223
- import { randomUUID as randomUUID5 } from "node:crypto";
6150
+ import { randomUUID as randomUUID4 } from "node:crypto";
6224
6151
 
6225
6152
  // packages/cli/src/serve/server/session-export.ts
6226
6153
  init_esbuild_shims();
@@ -6289,473 +6216,10 @@ __name(exportSessionTranscript, "exportSessionTranscript");
6289
6216
 
6290
6217
  // packages/cli/src/serve/conversations/standalone-deletion-journal.ts
6291
6218
  init_esbuild_shims();
6292
- import { randomUUID as randomUUID4 } from "node:crypto";
6293
- import { constants as fsConstants3 } from "node:fs";
6294
- import * as fs2 from "node:fs/promises";
6295
- import * as path8 from "node:path";
6296
-
6297
- // packages/cli/src/serve/conversations/conversation-runtime-ownership.ts
6298
- init_esbuild_shims();
6299
6219
  import { randomUUID as randomUUID3 } from "node:crypto";
6300
6220
  import { constants as fsConstants2 } from "node:fs";
6301
6221
  import * as fs from "node:fs/promises";
6302
6222
  import * as path7 from "node:path";
6303
- var OWNER_DIRECTORY = "conversations";
6304
- var OWNER_FILE = "runtime-owner.json";
6305
- var OWNER_LOCK = ".runtime-owner.lock";
6306
- var MAX_OWNER_BYTES = 4 * 1024;
6307
- var NONCE_PATTERN = /^[A-Za-z0-9_-]{16,256}$/;
6308
- var DEFAULT_HANDOFF_GRACE_MS = 1e3;
6309
- var UnsafeOwnershipStateError = class extends Error {
6310
- static {
6311
- __name(this, "UnsafeOwnershipStateError");
6312
- }
6313
- };
6314
- function getConversationRuntimeOwnerPath(stableBaseDir) {
6315
- return path7.join(stableBaseDir, OWNER_DIRECTORY, OWNER_FILE);
6316
- }
6317
- __name(getConversationRuntimeOwnerPath, "getConversationRuntimeOwnerPath");
6318
- function processIsAlive(pid) {
6319
- try {
6320
- process.kill(pid, 0);
6321
- return true;
6322
- } catch (error2) {
6323
- return error2.code !== "ESRCH";
6324
- }
6325
- }
6326
- __name(processIsAlive, "processIsAlive");
6327
- function delay(milliseconds) {
6328
- return new Promise((resolve7) => {
6329
- setTimeout(resolve7, milliseconds);
6330
- });
6331
- }
6332
- __name(delay, "delay");
6333
- function isMissing(error2) {
6334
- return error2.code === "ENOENT";
6335
- }
6336
- __name(isMissing, "isMissing");
6337
- function assertOwnerRecord(value) {
6338
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
6339
- throw new UnsafeOwnershipStateError();
6340
- }
6341
- const keys = Object.keys(value).sort();
6342
- if (keys.length !== 3 || keys[0] !== "instanceNonce" || keys[1] !== "pid" || keys[2] !== "version") {
6343
- throw new UnsafeOwnershipStateError();
6344
- }
6345
- const record = value;
6346
- if (record["version"] !== 1 || !Number.isSafeInteger(record["pid"]) || record["pid"] <= 0 || typeof record["instanceNonce"] !== "string" || !NONCE_PATTERN.test(record["instanceNonce"])) {
6347
- throw new UnsafeOwnershipStateError();
6348
- }
6349
- return {
6350
- version: 1,
6351
- pid: record["pid"],
6352
- instanceNonce: record["instanceNonce"]
6353
- };
6354
- }
6355
- __name(assertOwnerRecord, "assertOwnerRecord");
6356
- function sameRecord(left, right) {
6357
- return left.version === right.version && left.pid === right.pid && left.instanceNonce === right.instanceNonce;
6358
- }
6359
- __name(sameRecord, "sameRecord");
6360
- async function inspectDirectory(directory, requirePrivateMode) {
6361
- const stat3 = await fs.lstat(directory);
6362
- if (!stat3.isDirectory() || stat3.isSymbolicLink()) {
6363
- throw new UnsafeOwnershipStateError();
6364
- }
6365
- if (process.platform !== "win32" && (typeof process.getuid === "function" && stat3.uid !== process.getuid() || requirePrivateMode && (stat3.mode & 511) !== 448)) {
6366
- throw new UnsafeOwnershipStateError();
6367
- }
6368
- return { dev: stat3.dev, ino: stat3.ino };
6369
- }
6370
- __name(inspectDirectory, "inspectDirectory");
6371
- async function ensureDirectory(directory, requirePrivateMode) {
6372
- try {
6373
- return await inspectDirectory(directory, requirePrivateMode);
6374
- } catch (error2) {
6375
- if (error2 instanceof UnsafeOwnershipStateError || !isMissing(error2)) {
6376
- throw error2;
6377
- }
6378
- }
6379
- const parent = path7.dirname(directory);
6380
- if (parent === directory) throw new UnsafeOwnershipStateError();
6381
- const parentIdentity = await ensureDirectory(parent, false);
6382
- await assertDirectoryIdentity(parent, parentIdentity, false);
6383
- let created = false;
6384
- try {
6385
- await fs.mkdir(directory, { mode: 448 });
6386
- created = true;
6387
- } catch (error2) {
6388
- if (error2.code !== "EEXIST") throw error2;
6389
- }
6390
- if (created && process.platform !== "win32") {
6391
- await fs.chmod(directory, 448);
6392
- }
6393
- await assertDirectoryIdentity(parent, parentIdentity, false);
6394
- return inspectDirectory(directory, requirePrivateMode);
6395
- }
6396
- __name(ensureDirectory, "ensureDirectory");
6397
- async function assertDirectoryIdentity(directory, expected, requirePrivateMode = true) {
6398
- const current = await inspectDirectory(directory, requirePrivateMode);
6399
- if (current.dev !== expected.dev || current.ino !== expected.ino) {
6400
- throw new UnsafeOwnershipStateError();
6401
- }
6402
- }
6403
- __name(assertDirectoryIdentity, "assertDirectoryIdentity");
6404
- async function assertLockShapeIfPresent(lockPath) {
6405
- let stat3;
6406
- try {
6407
- stat3 = await fs.lstat(lockPath);
6408
- } catch (error2) {
6409
- if (isMissing(error2)) return;
6410
- throw error2;
6411
- }
6412
- if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && typeof process.getuid === "function" && stat3.uid !== process.getuid()) {
6413
- throw new UnsafeOwnershipStateError();
6414
- }
6415
- }
6416
- __name(assertLockShapeIfPresent, "assertLockShapeIfPresent");
6417
- async function readOwnerRecord(ownerPath) {
6418
- let pathStat;
6419
- try {
6420
- pathStat = await fs.lstat(ownerPath);
6421
- } catch (error2) {
6422
- if (isMissing(error2)) return void 0;
6423
- throw error2;
6424
- }
6425
- if (!pathStat.isFile() || pathStat.isSymbolicLink() || pathStat.nlink !== 1 || pathStat.size <= 0 || pathStat.size > MAX_OWNER_BYTES || process.platform !== "win32" && ((pathStat.mode & 511) !== 384 || typeof process.getuid === "function" && pathStat.uid !== process.getuid())) {
6426
- throw new UnsafeOwnershipStateError();
6427
- }
6428
- let handle;
6429
- try {
6430
- handle = await fs.open(
6431
- ownerPath,
6432
- process.platform === "win32" ? fsConstants2.O_RDONLY : fsConstants2.O_RDONLY | fsConstants2.O_NOFOLLOW
6433
- );
6434
- } catch (error2) {
6435
- if (error2.code === "ELOOP") {
6436
- throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
6437
- }
6438
- throw error2;
6439
- }
6440
- try {
6441
- const handleStat = await handle.stat();
6442
- if (!handleStat.isFile() || handleStat.nlink !== 1 || handleStat.dev !== pathStat.dev || handleStat.ino !== pathStat.ino || handleStat.size !== pathStat.size || process.platform !== "win32" && ((handleStat.mode & 511) !== 384 || typeof process.getuid === "function" && handleStat.uid !== process.getuid())) {
6443
- throw new UnsafeOwnershipStateError();
6444
- }
6445
- const serialized = await handle.readFile("utf8");
6446
- let parsed;
6447
- try {
6448
- parsed = JSON.parse(serialized);
6449
- } catch (error2) {
6450
- throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
6451
- }
6452
- return assertOwnerRecord(parsed);
6453
- } finally {
6454
- await handle.close();
6455
- }
6456
- }
6457
- __name(readOwnerRecord, "readOwnerRecord");
6458
- async function syncDirectory(directory) {
6459
- if (process.platform === "win32") return;
6460
- const handle = await fs.open(directory, fsConstants2.O_RDONLY);
6461
- try {
6462
- await handle.sync();
6463
- } finally {
6464
- await handle.close();
6465
- }
6466
- }
6467
- __name(syncDirectory, "syncDirectory");
6468
- var FileConversationRuntimeOwnership = class {
6469
- static {
6470
- __name(this, "FileConversationRuntimeOwnership");
6471
- }
6472
- stableBaseDir;
6473
- ownerDirectory;
6474
- ownerPath;
6475
- lockPath;
6476
- current;
6477
- isProcessAlive;
6478
- wait;
6479
- handoffGraceMs;
6480
- lockOptions;
6481
- state = "unclaimed";
6482
- terminalError;
6483
- acquirePending;
6484
- releasePending;
6485
- constructor(options) {
6486
- this.stableBaseDir = options.stableBaseDir;
6487
- this.ownerDirectory = path7.dirname(
6488
- getConversationRuntimeOwnerPath(options.stableBaseDir)
6489
- );
6490
- this.ownerPath = getConversationRuntimeOwnerPath(options.stableBaseDir);
6491
- this.lockPath = path7.join(this.ownerDirectory, OWNER_LOCK);
6492
- this.current = {
6493
- version: 1,
6494
- pid: options.pid,
6495
- instanceNonce: options.instanceNonce
6496
- };
6497
- this.isProcessAlive = options.isProcessAlive ?? processIsAlive;
6498
- this.wait = options.wait ?? delay;
6499
- this.handoffGraceMs = options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS;
6500
- this.lockOptions = options.lockOptions ?? {
6501
- stale: 5e3,
6502
- update: 1e3,
6503
- retries: {
6504
- retries: 40,
6505
- minTimeout: 10,
6506
- maxTimeout: 50,
6507
- factor: 1.2,
6508
- randomize: true
6509
- }
6510
- };
6511
- }
6512
- acquire() {
6513
- if (this.acquirePending) return this.acquirePending;
6514
- const pending = this.acquireOnce().finally(() => {
6515
- if (this.acquirePending === pending) this.acquirePending = void 0;
6516
- });
6517
- this.acquirePending = pending;
6518
- return pending;
6519
- }
6520
- release() {
6521
- if (this.releasePending) return this.releasePending;
6522
- const pending = this.releaseOnce().finally(() => {
6523
- if (this.releasePending === pending) this.releasePending = void 0;
6524
- });
6525
- this.releasePending = pending;
6526
- return pending;
6527
- }
6528
- async acquireOnce() {
6529
- if (this.terminalError) throw this.terminalError;
6530
- if (this.state === "released") {
6531
- throw this.compromise();
6532
- }
6533
- if (this.releasePending) {
6534
- await this.releasePending.catch(() => void 0);
6535
- throw this.compromise();
6536
- }
6537
- const identity = await this.prepareOwnerDirectory();
6538
- let releaseLock;
6539
- let operationError;
6540
- let reclaimed = false;
6541
- let lockCompromise;
6542
- try {
6543
- await assertLockShapeIfPresent(this.lockPath);
6544
- const lockfile = (await import("./proper-lockfile-3LHWIM44.js")).default;
6545
- releaseLock = await lockfile.lock(this.ownerDirectory, {
6546
- realpath: false,
6547
- lockfilePath: this.lockPath,
6548
- ...this.lockOptions,
6549
- onCompromised: /* @__PURE__ */ __name((error2) => {
6550
- lockCompromise = error2;
6551
- }, "onCompromised")
6552
- });
6553
- await assertLockShapeIfPresent(this.lockPath);
6554
- await assertDirectoryIdentity(this.ownerDirectory, identity);
6555
- if (lockCompromise) throw new UnsafeOwnershipStateError();
6556
- const existing = await readOwnerRecord(this.ownerPath);
6557
- const commitOwner = /* @__PURE__ */ __name(async () => {
6558
- if (this.state === "owned") {
6559
- if (!existing || !sameRecord(existing, this.current)) {
6560
- throw new UnsafeOwnershipStateError();
6561
- }
6562
- } else if (existing && sameRecord(existing, this.current)) {
6563
- this.state = "provisional";
6564
- } else if (existing) {
6565
- if (existing.pid === this.current.pid || this.isProcessAlive(existing.pid)) {
6566
- throw conversationRuntimeInUseError();
6567
- }
6568
- reclaimed = true;
6569
- await this.commitRecord(identity, existing);
6570
- } else {
6571
- await this.commitRecord(identity, void 0);
6572
- }
6573
- }, "commitOwner");
6574
- const liveDiscovery = await import("./discovery-TUM3ZQ6U.js");
6575
- const handoff = await liveDiscovery.handoffLiveDiscoveryOwner(
6576
- this.stableBaseDir,
6577
- this.current,
6578
- commitOwner,
6579
- {
6580
- isProcessAlive: this.isProcessAlive,
6581
- waitForHandoffGrace: false
6582
- }
6583
- );
6584
- reclaimed ||= handoff.reclaimed;
6585
- } catch (error2) {
6586
- operationError = error2;
6587
- }
6588
- let releaseError;
6589
- if (releaseLock) {
6590
- try {
6591
- await releaseLock();
6592
- } catch (error2) {
6593
- releaseError = error2;
6594
- }
6595
- }
6596
- if (lockCompromise || releaseError) {
6597
- throw this.compromise(lockCompromise ?? releaseError);
6598
- }
6599
- if (operationError) {
6600
- throw this.mapAcquireError(operationError);
6601
- }
6602
- if (reclaimed) {
6603
- try {
6604
- await this.wait(this.handoffGraceMs);
6605
- } catch (error2) {
6606
- throw this.compromise(error2);
6607
- }
6608
- }
6609
- if (this.state === "provisional") this.state = "owned";
6610
- return { reclaimed };
6611
- }
6612
- async releaseOnce() {
6613
- if (this.acquirePending) {
6614
- await this.acquirePending.catch(() => void 0);
6615
- }
6616
- if (this.state === "unclaimed" || this.state === "released") return false;
6617
- if (this.state === "provisional" || this.terminalError) {
6618
- throw this.terminalError ?? this.compromise();
6619
- }
6620
- const identity = await this.prepareOwnerDirectory();
6621
- let releaseLock;
6622
- let operationError;
6623
- let lockCompromise;
6624
- try {
6625
- await assertLockShapeIfPresent(this.lockPath);
6626
- const lockfile = (await import("./proper-lockfile-3LHWIM44.js")).default;
6627
- releaseLock = await lockfile.lock(this.ownerDirectory, {
6628
- realpath: false,
6629
- lockfilePath: this.lockPath,
6630
- ...this.lockOptions,
6631
- onCompromised: /* @__PURE__ */ __name((error2) => {
6632
- lockCompromise = error2;
6633
- }, "onCompromised")
6634
- });
6635
- await assertLockShapeIfPresent(this.lockPath);
6636
- await assertDirectoryIdentity(this.ownerDirectory, identity);
6637
- const existing = await readOwnerRecord(this.ownerPath);
6638
- if (lockCompromise || !existing || !sameRecord(existing, this.current)) {
6639
- throw new UnsafeOwnershipStateError();
6640
- }
6641
- await assertDirectoryIdentity(this.ownerDirectory, identity);
6642
- await fs.unlink(this.ownerPath);
6643
- this.state = "released";
6644
- await syncDirectory(this.ownerDirectory);
6645
- } catch (error2) {
6646
- operationError = error2;
6647
- }
6648
- let releaseError;
6649
- if (releaseLock) {
6650
- try {
6651
- await releaseLock();
6652
- } catch (error2) {
6653
- releaseError = error2;
6654
- }
6655
- }
6656
- if (lockCompromise || releaseError) {
6657
- if (this.state !== "released") this.compromise(lockCompromise);
6658
- throw conversationRuntimeOwnershipCompromisedError(
6659
- lockCompromise ?? releaseError
6660
- );
6661
- }
6662
- if (operationError) {
6663
- if (this.state === "released") {
6664
- throw conversationRuntimeOwnershipCompromisedError(operationError);
6665
- }
6666
- if (operationError instanceof UnsafeOwnershipStateError) {
6667
- throw this.compromise(operationError);
6668
- }
6669
- throw conversationRuntimeUnavailableError(operationError);
6670
- }
6671
- return true;
6672
- }
6673
- async prepareOwnerDirectory() {
6674
- try {
6675
- if (this.state === "unclaimed") {
6676
- await ensureDirectory(this.stableBaseDir, false);
6677
- return await ensureDirectory(this.ownerDirectory, true);
6678
- }
6679
- await inspectDirectory(this.stableBaseDir, false);
6680
- return await inspectDirectory(this.ownerDirectory, true);
6681
- } catch (error2) {
6682
- if (error2 instanceof UnsafeOwnershipStateError || this.state !== "unclaimed" && isMissing(error2)) {
6683
- throw this.compromise(error2);
6684
- }
6685
- throw conversationRuntimeUnavailableError(error2);
6686
- }
6687
- }
6688
- async commitRecord(identity, expected) {
6689
- const temporaryPath = path7.join(
6690
- this.ownerDirectory,
6691
- `.runtime-owner.${this.current.pid}.${randomUUID3()}.tmp`
6692
- );
6693
- let handle;
6694
- let renamed = false;
6695
- try {
6696
- handle = await fs.open(temporaryPath, "wx", 384);
6697
- await handle.writeFile(`${JSON.stringify(this.current)}
6698
- `, "utf8");
6699
- await handle.sync();
6700
- if (process.platform !== "win32") await handle.chmod(384);
6701
- await handle.close();
6702
- handle = void 0;
6703
- await assertDirectoryIdentity(this.ownerDirectory, identity);
6704
- const observed = await readOwnerRecord(this.ownerPath);
6705
- if (expected === void 0 && observed !== void 0 || expected !== void 0 && (!observed || !sameRecord(observed, expected))) {
6706
- throw new UnsafeOwnershipStateError();
6707
- }
6708
- await assertDirectoryIdentity(this.ownerDirectory, identity);
6709
- if (process.platform === "win32" && observed) {
6710
- await fs.unlink(this.ownerPath);
6711
- try {
6712
- await fs.rename(temporaryPath, this.ownerPath);
6713
- } catch (error2) {
6714
- await this.wait(this.handoffGraceMs);
6715
- throw error2;
6716
- }
6717
- } else {
6718
- await fs.rename(temporaryPath, this.ownerPath);
6719
- }
6720
- renamed = true;
6721
- this.state = "provisional";
6722
- await syncDirectory(this.ownerDirectory);
6723
- } finally {
6724
- await handle?.close().catch(() => void 0);
6725
- if (!renamed) {
6726
- await fs.unlink(temporaryPath).catch(() => void 0);
6727
- }
6728
- }
6729
- }
6730
- mapAcquireError(error2) {
6731
- if (error2 instanceof ConversationRuntimeOwnershipError) return error2;
6732
- if (error2 instanceof Error && error2.name === "LiveDiscoveryOwnerActiveError") {
6733
- return conversationRuntimeInUseError();
6734
- }
6735
- if (error2 instanceof UnsafeOwnershipStateError) {
6736
- return this.compromise(error2);
6737
- }
6738
- if (this.state === "provisional" || error2 instanceof Error && error2.name === "LiveDiscoveryStateError") {
6739
- return this.compromise(error2);
6740
- }
6741
- const code = error2.code;
6742
- if (code === "ECOMPROMISED") return this.compromise(error2);
6743
- return conversationRuntimeUnavailableError(error2);
6744
- }
6745
- compromise(cause) {
6746
- this.terminalError ??= conversationRuntimeOwnershipCompromisedError(cause);
6747
- return this.terminalError;
6748
- }
6749
- };
6750
- function createConversationRuntimeOwnership(options) {
6751
- if (!path7.isAbsolute(options.stableBaseDir) || !Number.isSafeInteger(options.pid) || options.pid <= 0 || !NONCE_PATTERN.test(options.instanceNonce) || !Number.isSafeInteger(options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS) || (options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS) < 0) {
6752
- throw new TypeError("Invalid Conversations runtime ownership options.");
6753
- }
6754
- return new FileConversationRuntimeOwnership(options);
6755
- }
6756
- __name(createConversationRuntimeOwnership, "createConversationRuntimeOwnership");
6757
-
6758
- // packages/cli/src/serve/conversations/standalone-deletion-journal.ts
6759
6223
  var JOURNAL_DIRECTORY = "deletions";
6760
6224
  var MAX_RECORD_BYTES = 8 * 1024;
6761
6225
  var STORAGE_SESSION_ID_PATTERN = /^[0-9a-fA-F-]{32,36}$/;
@@ -6770,10 +6234,10 @@ var StandaloneDeletionJournalError = class extends Error {
6770
6234
  }
6771
6235
  name = "StandaloneDeletionJournalError";
6772
6236
  };
6773
- function isMissing2(error2) {
6237
+ function isMissing(error2) {
6774
6238
  return error2.code === "ENOENT";
6775
6239
  }
6776
- __name(isMissing2, "isMissing");
6240
+ __name(isMissing, "isMissing");
6777
6241
  function parseSessionId(value) {
6778
6242
  const parsed = parseCallerSuppliedSessionId(value);
6779
6243
  if (parsed.kind !== "valid") {
@@ -6804,7 +6268,7 @@ function parseIdentity(value, pathField) {
6804
6268
  if (!isIdentityNumber(value["device"]) || !isIdentityNumber(value["inode"]) || typeof value["inodeVerifiable"] !== "boolean" || (value["inodeVerifiable"] ? value["inode"] === 0 : value["inode"] !== 0)) {
6805
6269
  return void 0;
6806
6270
  }
6807
- if (pathField && (typeof value["canonicalPath"] !== "string" || value["canonicalPath"].length === 0 || value["canonicalPath"].length > 4096 || !path8.isAbsolute(value["canonicalPath"]))) {
6271
+ if (pathField && (typeof value["canonicalPath"] !== "string" || value["canonicalPath"].length === 0 || value["canonicalPath"].length > 4096 || !path7.isAbsolute(value["canonicalPath"]))) {
6808
6272
  return void 0;
6809
6273
  }
6810
6274
  return {
@@ -6899,25 +6363,26 @@ function sameImmutableRecord(prepared, staged) {
6899
6363
  }
6900
6364
  __name(sameImmutableRecord, "sameImmutableRecord");
6901
6365
  var StandaloneDeletionJournal = class {
6366
+ constructor(stableBaseDir) {
6367
+ this.stableBaseDir = stableBaseDir;
6368
+ if (!path7.isAbsolute(stableBaseDir)) {
6369
+ throw new TypeError("Standalone deletion journal base must be absolute.");
6370
+ }
6371
+ this.stateDirectory = path7.join(stableBaseDir, "conversations");
6372
+ this.journalDirectory = path7.join(this.stateDirectory, JOURNAL_DIRECTORY);
6373
+ }
6902
6374
  static {
6903
6375
  __name(this, "StandaloneDeletionJournal");
6904
6376
  }
6905
- ownerDirectory;
6377
+ stateDirectory;
6906
6378
  journalDirectory;
6379
+ directoryIdentities = /* @__PURE__ */ new Map();
6380
+ canonicalBaseDir;
6907
6381
  pendingClears = /* @__PURE__ */ new Map();
6908
- constructor(stableBaseDir) {
6909
- if (!path8.isAbsolute(stableBaseDir)) {
6910
- throw new TypeError("Standalone deletion journal base must be absolute.");
6911
- }
6912
- this.ownerDirectory = path8.dirname(
6913
- getConversationRuntimeOwnerPath(stableBaseDir)
6914
- );
6915
- this.journalDirectory = path8.join(this.ownerDirectory, JOURNAL_DIRECTORY);
6916
- }
6917
6382
  async hasRecord(rawSessionId) {
6918
6383
  const sessionId = parseSessionId(rawSessionId);
6919
- if (this.pendingClears.has(sessionId)) return true;
6920
6384
  const identity = await this.inspectJournalDirectory();
6385
+ if (this.pendingClears.has(sessionId)) return true;
6921
6386
  if (!identity) return false;
6922
6387
  const exists = await this.pathExists(this.recordPath(sessionId, "prepared")) || await this.pathExists(this.recordPath(sessionId, "staged"));
6923
6388
  await this.assertDirectoryIdentity(this.journalDirectory, identity);
@@ -6931,9 +6396,9 @@ var StandaloneDeletionJournal = class {
6931
6396
  }
6932
6397
  let names;
6933
6398
  try {
6934
- names = await fs2.readdir(this.journalDirectory);
6399
+ names = await fs.readdir(this.journalDirectory);
6935
6400
  } catch (error2) {
6936
- if (isMissing2(error2)) {
6401
+ if (isMissing(error2)) {
6937
6402
  return [...ids].sort().slice(0, Math.max(0, limit));
6938
6403
  }
6939
6404
  throw error2;
@@ -6947,11 +6412,11 @@ var StandaloneDeletionJournal = class {
6947
6412
  }
6948
6413
  async read(rawSessionId, currentRoot) {
6949
6414
  const sessionId = parseSessionId(rawSessionId);
6415
+ const identity = await this.inspectJournalDirectory();
6950
6416
  const pending = this.pendingClears.get(sessionId);
6951
6417
  if (pending) {
6952
6418
  return this.validatePendingEntry(pending.entry, currentRoot);
6953
6419
  }
6954
- const identity = await this.inspectJournalDirectory();
6955
6420
  if (!identity) return void 0;
6956
6421
  const prepared = await this.readPhase(sessionId, "prepared", currentRoot);
6957
6422
  const staged = await this.readPhase(sessionId, "staged", currentRoot);
@@ -6994,6 +6459,7 @@ var StandaloneDeletionJournal = class {
6994
6459
  }
6995
6460
  async clear(rawSessionId, currentRoot) {
6996
6461
  const sessionId = parseSessionId(rawSessionId);
6462
+ await this.inspectJournalDirectory();
6997
6463
  const pending = this.pendingClears.get(sessionId);
6998
6464
  if (pending) {
6999
6465
  this.validatePendingEntry(pending.entry, currentRoot);
@@ -7045,7 +6511,7 @@ var StandaloneDeletionJournal = class {
7045
6511
  return { prepared, ...staged ? { staged } : {} };
7046
6512
  }
7047
6513
  recordPath(sessionId, phase) {
7048
- return path8.join(
6514
+ return path7.join(
7049
6515
  this.journalDirectory,
7050
6516
  `delete-${sessionId}.${phase}.json`
7051
6517
  );
@@ -7054,17 +6520,17 @@ var StandaloneDeletionJournal = class {
7054
6520
  const filePath = this.recordPath(sessionId, phase);
7055
6521
  let pathStat;
7056
6522
  try {
7057
- pathStat = await fs2.lstat(filePath);
6523
+ pathStat = await fs.lstat(filePath);
7058
6524
  } catch (error2) {
7059
- if (isMissing2(error2)) return void 0;
6525
+ if (isMissing(error2)) return void 0;
7060
6526
  throw error2;
7061
6527
  }
7062
6528
  this.assertRecordFile(pathStat);
7063
6529
  let handle;
7064
6530
  try {
7065
- handle = await fs2.open(
6531
+ handle = await fs.open(
7066
6532
  filePath,
7067
- fsConstants3.O_RDONLY | (process.platform === "win32" ? 0 : fsConstants3.O_NOFOLLOW ?? 0)
6533
+ fsConstants2.O_RDONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0)
7068
6534
  );
7069
6535
  } catch (error2) {
7070
6536
  if (error2.code === "ELOOP") {
@@ -7099,9 +6565,9 @@ var StandaloneDeletionJournal = class {
7099
6565
  const identity = await this.ensureJournalDirectory();
7100
6566
  const target = this.recordPath(record.sessionId, record.phase);
7101
6567
  await this.assertPathAbsent(target);
7102
- const temporary = path8.join(
6568
+ const temporary = path7.join(
7103
6569
  this.journalDirectory,
7104
- `.${path8.basename(target)}.${randomUUID4()}.tmp`
6570
+ `.${path7.basename(target)}.${randomUUID3()}.tmp`
7105
6571
  );
7106
6572
  const directory = await this.openDurableDirectory(
7107
6573
  this.journalDirectory,
@@ -7110,9 +6576,9 @@ var StandaloneDeletionJournal = class {
7110
6576
  let handle;
7111
6577
  try {
7112
6578
  await this.assertDirectoryIdentity(this.journalDirectory, identity);
7113
- handle = await fs2.open(
6579
+ handle = await fs.open(
7114
6580
  temporary,
7115
- fsConstants3.O_CREAT | fsConstants3.O_EXCL | fsConstants3.O_WRONLY | (process.platform === "win32" ? 0 : fsConstants3.O_NOFOLLOW ?? 0),
6581
+ fsConstants2.O_CREAT | fsConstants2.O_EXCL | fsConstants2.O_WRONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0),
7116
6582
  384
7117
6583
  );
7118
6584
  await handle.writeFile(serialized, "utf8");
@@ -7121,12 +6587,12 @@ var StandaloneDeletionJournal = class {
7121
6587
  handle = void 0;
7122
6588
  await this.assertDirectoryIdentity(this.journalDirectory, identity);
7123
6589
  await this.assertPathAbsent(target);
7124
- await fs2.rename(temporary, target);
7125
- if (process.platform !== "win32") await fs2.chmod(target, 384);
6590
+ await fs.rename(temporary, target);
6591
+ if (process.platform !== "win32") await fs.chmod(target, 384);
7126
6592
  await this.syncDurableDirectory(directory);
7127
6593
  } catch (error2) {
7128
6594
  await handle?.close().catch(() => void 0);
7129
- await fs2.unlink(temporary).catch(() => void 0);
6595
+ await fs.unlink(temporary).catch(() => void 0);
7130
6596
  if (error2.code === "EEXIST") {
7131
6597
  throw new StandaloneDeletionJournalError("conflict");
7132
6598
  }
@@ -7136,48 +6602,107 @@ var StandaloneDeletionJournal = class {
7136
6602
  }
7137
6603
  }
7138
6604
  async ensureJournalDirectory() {
7139
- const owner = await this.inspectPrivateDirectory(this.ownerDirectory);
6605
+ await this.ensureStateDirectory(this.stableBaseDir, false);
6606
+ const owner = await this.ensureStateDirectory(this.stateDirectory, true);
7140
6607
  const ownerHandle = await this.openDurableDirectory(
7141
- this.ownerDirectory,
6608
+ this.stateDirectory,
7142
6609
  owner
7143
6610
  );
7144
6611
  try {
7145
6612
  let created = false;
7146
6613
  try {
7147
- await fs2.mkdir(this.journalDirectory, { mode: 448 });
6614
+ await fs.mkdir(this.journalDirectory, { mode: 448 });
7148
6615
  created = true;
7149
6616
  } catch (error2) {
7150
6617
  if (error2.code !== "EEXIST") throw error2;
7151
6618
  }
7152
6619
  if (created && process.platform !== "win32") {
7153
- await fs2.chmod(this.journalDirectory, 448);
6620
+ await fs.chmod(this.journalDirectory, 448);
7154
6621
  }
7155
6622
  await this.syncDurableDirectory(ownerHandle);
7156
6623
  } finally {
7157
6624
  await ownerHandle.handle.close().catch(() => void 0);
7158
6625
  }
7159
- return this.inspectPrivateDirectory(this.journalDirectory);
6626
+ return await this.inspectJournalDirectory();
6627
+ }
6628
+ async ensureStateDirectory(directory, requirePrivate) {
6629
+ try {
6630
+ return await this.inspectPrivateDirectory(directory, requirePrivate);
6631
+ } catch (error2) {
6632
+ if (!isMissing(error2)) throw error2;
6633
+ }
6634
+ const parent = path7.dirname(directory);
6635
+ if (parent === directory)
6636
+ throw new StandaloneDeletionJournalError("compromised");
6637
+ const before = await this.ensureStateDirectory(parent, false);
6638
+ let created = false;
6639
+ try {
6640
+ await fs.mkdir(directory, { mode: 448 });
6641
+ created = true;
6642
+ } catch (error2) {
6643
+ if (error2.code !== "EEXIST") throw error2;
6644
+ }
6645
+ if (created && process.platform !== "win32")
6646
+ await fs.chmod(directory, 448);
6647
+ const after = await this.inspectPrivateDirectory(parent, false);
6648
+ if (!sameDirectoryIdentity(before, after)) {
6649
+ throw new StandaloneDeletionJournalError("compromised");
6650
+ }
6651
+ const handle = await fs.open(parent, fsConstants2.O_RDONLY);
6652
+ try {
6653
+ if (process.platform !== "win32") await handle.sync();
6654
+ } finally {
6655
+ await handle.close();
6656
+ }
6657
+ return this.inspectPrivateDirectory(directory, requirePrivate);
6658
+ }
6659
+ async inspectStateParent() {
6660
+ await this.inspectPrivateDirectory(this.stableBaseDir, false);
6661
+ const canonical = await fs.realpath(this.stableBaseDir);
6662
+ if (this.canonicalBaseDir !== void 0 && this.canonicalBaseDir !== canonical) {
6663
+ throw new StandaloneDeletionJournalError("compromised");
6664
+ }
6665
+ this.canonicalBaseDir = canonical;
6666
+ await this.inspectPrivateDirectory(this.stateDirectory);
7160
6667
  }
7161
6668
  async inspectJournalDirectory() {
7162
6669
  try {
6670
+ await this.inspectStateParent();
7163
6671
  return await this.inspectPrivateDirectory(this.journalDirectory);
7164
6672
  } catch (error2) {
7165
- if (isMissing2(error2)) return void 0;
6673
+ if (isMissing(error2)) return void 0;
7166
6674
  throw error2;
7167
6675
  }
7168
6676
  }
7169
- async inspectPrivateDirectory(directory) {
7170
- const stat3 = await fs2.lstat(directory);
7171
- if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && ((stat3.mode & 511) !== 448 || typeof process.getuid === "function" && stat3.uid !== process.getuid())) {
6677
+ async inspectPrivateDirectory(directory, requirePrivate = true) {
6678
+ let stat3;
6679
+ try {
6680
+ stat3 = await fs.lstat(directory);
6681
+ } catch (error2) {
6682
+ if (isMissing(error2) && this.directoryIdentities.has(directory)) {
6683
+ throw new StandaloneDeletionJournalError("compromised");
6684
+ }
6685
+ throw error2;
6686
+ }
6687
+ if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && (requirePrivate && (stat3.mode & 511) !== 448 || typeof process.getuid === "function" && stat3.uid !== process.getuid())) {
7172
6688
  throw new StandaloneDeletionJournalError("compromised");
7173
6689
  }
7174
- return {
6690
+ const identity = {
7175
6691
  device: stat3.dev,
7176
6692
  inode: normalizedInode(stat3.ino),
7177
6693
  inodeVerifiable: hasVerifiableInode(stat3.ino)
7178
6694
  };
6695
+ if (directory === this.stableBaseDir || directory === this.stateDirectory || directory === this.journalDirectory) {
6696
+ const expected = this.directoryIdentities.get(directory);
6697
+ if (expected && !sameDirectoryIdentity(identity, expected)) {
6698
+ throw new StandaloneDeletionJournalError("compromised");
6699
+ }
6700
+ this.directoryIdentities.set(directory, identity);
6701
+ }
6702
+ return identity;
7179
6703
  }
7180
6704
  async assertDirectoryIdentity(directory, expected) {
6705
+ await this.inspectStateParent();
7181
6706
  const current = await this.inspectPrivateDirectory(directory);
7182
6707
  if (!sameDirectoryIdentity(current, expected)) {
7183
6708
  throw new StandaloneDeletionJournalError("compromised");
@@ -7190,35 +6715,35 @@ var StandaloneDeletionJournal = class {
7190
6715
  }
7191
6716
  async assertPathAbsent(filePath) {
7192
6717
  try {
7193
- await fs2.lstat(filePath);
6718
+ await fs.lstat(filePath);
7194
6719
  } catch (error2) {
7195
- if (isMissing2(error2)) return;
6720
+ if (isMissing(error2)) return;
7196
6721
  throw error2;
7197
6722
  }
7198
6723
  throw new StandaloneDeletionJournalError("conflict");
7199
6724
  }
7200
6725
  async pathExists(filePath) {
7201
6726
  try {
7202
- await fs2.lstat(filePath);
6727
+ await fs.lstat(filePath);
7203
6728
  return true;
7204
6729
  } catch (error2) {
7205
- if (isMissing2(error2)) return false;
6730
+ if (isMissing(error2)) return false;
7206
6731
  throw error2;
7207
6732
  }
7208
6733
  }
7209
6734
  async unlinkIfExists(filePath) {
7210
6735
  try {
7211
- await fs2.unlink(filePath);
6736
+ await fs.unlink(filePath);
7212
6737
  } catch (error2) {
7213
- if (!isMissing2(error2)) throw error2;
6738
+ if (!isMissing(error2)) throw error2;
7214
6739
  }
7215
6740
  }
7216
6741
  async openDurableDirectory(directory, expected) {
7217
6742
  let handle;
7218
6743
  try {
7219
- handle = await fs2.open(
6744
+ handle = await fs.open(
7220
6745
  directory,
7221
- fsConstants3.O_RDONLY | (process.platform === "win32" ? 0 : fsConstants3.O_NOFOLLOW ?? 0)
6746
+ fsConstants2.O_RDONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0)
7222
6747
  );
7223
6748
  const opened = await handle.stat();
7224
6749
  const openedIdentity = {
@@ -7375,6 +6900,7 @@ function mergeLiveStandaloneSummary(persisted, live) {
7375
6900
  updatedAt: laterTimestamp(live.updatedAt, persisted.updatedAt),
7376
6901
  clientCount: live.clientCount,
7377
6902
  hasActivePrompt: live.hasActivePrompt,
6903
+ ...live.activeWorkState !== void 0 ? { activeWorkState: live.activeWorkState } : {},
7378
6904
  ...live.isWaitingForPermission !== void 0 ? { isWaitingForPermission: live.isWaitingForPermission } : {},
7379
6905
  ...live.isWaitingForUserQuestion !== void 0 ? { isWaitingForUserQuestion: live.isWaitingForUserQuestion } : {},
7380
6906
  ...live.pendingInteractionCount !== void 0 ? { pendingInteractionCount: live.pendingInteractionCount } : {},
@@ -7586,7 +7112,7 @@ var StandaloneSessionService = class {
7586
7112
  });
7587
7113
  }
7588
7114
  async repairDirectory(rawSessionId) {
7589
- const clientId = randomUUID5();
7115
+ const clientId = randomUUID4();
7590
7116
  const restored = await this.restore("resume", rawSessionId, { clientId });
7591
7117
  try {
7592
7118
  await this.cleanupDisconnectedRestore(restored);
@@ -9058,7 +8584,7 @@ var StandaloneSessionService = class {
9058
8584
  }
9059
8585
  return { ...created, initialPrompt: created.initialPrompt };
9060
8586
  }
9061
- async createInternal(request2, prompt, parentSessionId, promptId = randomUUID5()) {
8587
+ async createInternal(request2, prompt, parentSessionId, promptId = randomUUID4()) {
9062
8588
  const { sessionId } = parseRequiredSessionId(request2.sessionId);
9063
8589
  let entry;
9064
8590
  try {
@@ -9601,8 +9127,8 @@ var StandaloneSessionService = class {
9601
9127
 
9602
9128
  // packages/cli/src/serve/workspace-memory.ts
9603
9129
  init_esbuild_shims();
9604
- import { promises as fs3 } from "node:fs";
9605
- import * as path9 from "node:path";
9130
+ import { promises as fs2 } from "node:fs";
9131
+ import * as path8 from "node:path";
9606
9132
  function requireTrustedWorkspace2(deps, res) {
9607
9133
  if (deps.isWorkspaceTrusted?.() !== false) return true;
9608
9134
  res.status(403).json({
@@ -9925,9 +9451,9 @@ async function collectWorkspaceMemoryStatus(boundWorkspace) {
9925
9451
  files.push(...workspaceFiles);
9926
9452
  const globalDir = Storage.getGlobalQwenDir();
9927
9453
  for (const filename of filenames) {
9928
- const candidate = path9.join(globalDir, filename);
9454
+ const candidate = path8.join(globalDir, filename);
9929
9455
  try {
9930
- const stat3 = await fs3.stat(candidate);
9456
+ const stat3 = await fs2.stat(candidate);
9931
9457
  if (stat3.isFile()) {
9932
9458
  files.push({
9933
9459
  absolutePath: candidate,
@@ -9974,9 +9500,9 @@ __name(collectWorkspaceMemoryStatus, "collectWorkspaceMemoryStatus");
9974
9500
  async function walkWorkspaceForMemory(start, filenames, errors) {
9975
9501
  const out = [];
9976
9502
  for (const filename of filenames) {
9977
- const candidate = path9.join(start, filename);
9503
+ const candidate = path8.join(start, filename);
9978
9504
  try {
9979
- const stat3 = await fs3.stat(candidate);
9505
+ const stat3 = await fs2.stat(candidate);
9980
9506
  if (stat3.isFile()) {
9981
9507
  out.push({
9982
9508
  absolutePath: candidate,
@@ -10006,7 +9532,7 @@ __name(isEnoent, "isEnoent");
10006
9532
 
10007
9533
  // packages/cli/src/serve/workspace-agents.ts
10008
9534
  init_esbuild_shims();
10009
- import { promises as fs4 } from "node:fs";
9535
+ import { promises as fs3 } from "node:fs";
10010
9536
  import { isDeepStrictEqual } from "node:util";
10011
9537
  var AGENT_TYPE_PATTERN = /^[\p{L}\p{N}_-]+$/u;
10012
9538
  var AGENT_TYPE_MAX_LENGTH = 64;
@@ -10459,7 +9985,7 @@ function mountWorkspaceAgentsRoutes(app, deps) {
10459
9985
  continue;
10460
9986
  }
10461
9987
  try {
10462
- await fs4.access(found.filePath);
9988
+ await fs3.access(found.filePath);
10463
9989
  remaining.push(found);
10464
9990
  } catch {
10465
9991
  removed.push(found);
@@ -10808,7 +10334,7 @@ function mountWorkspaceQualifiedAgentsRoutes(app, deps) {
10808
10334
  }
10809
10335
  if (existing?.filePath) {
10810
10336
  try {
10811
- await fs4.access(existing.filePath);
10337
+ await fs3.access(existing.filePath);
10812
10338
  writeStderrLine(
10813
10339
  `qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} partial \u2014 remaining=${existing.level}:${existing.filePath}`
10814
10340
  );
@@ -13383,6 +12909,7 @@ var AcpDispatcher = class {
13383
12909
  ...s.sourceId !== void 0 ? { sourceId: s.sourceId } : {},
13384
12910
  clientCount: s.clientCount,
13385
12911
  hasActivePrompt: s.hasActivePrompt,
12912
+ ...s.activeWorkState !== void 0 ? { activeWorkState: s.activeWorkState } : {},
13386
12913
  isArchived: s.isArchived === true,
13387
12914
  ...s.isPinned !== void 0 ? { isPinned: s.isPinned } : {},
13388
12915
  ...s.pinnedAt !== void 0 ? { pinnedAt: s.pinnedAt } : {},
@@ -15704,6 +15231,7 @@ var AcpDispatcher = class {
15704
15231
  bridge: this.bridge,
15705
15232
  coordinator: this.archiveCoordinator,
15706
15233
  assertCanMutate: assertGenerationOpen,
15234
+ runtimeWorkspaceCwd: this.boundWorkspace,
15707
15235
  onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
15708
15236
  const safeSessionId = logSafe(sessionId.slice(0, 8));
15709
15237
  const safeMessage = logSafe(error2);
@@ -16382,7 +15910,7 @@ var AcpDispatcher = class {
16382
15910
 
16383
15911
  // packages/cli/src/serve/acp-http/connection-registry.ts
16384
15912
  init_esbuild_shims();
16385
- import { randomUUID as randomUUID6 } from "node:crypto";
15913
+ import { randomUUID as randomUUID5 } from "node:crypto";
16386
15914
  var DEFAULT_MAX_CONNECTIONS = 64;
16387
15915
  var AcpConnection = class {
16388
15916
  constructor(connectionId, fromLoopback, onAbandonPending, onDetachSession, preAttachBudget = new AcpPreAttachBudget(), onFatalConnection, maxFramesPerConnection = ACP_PRE_ATTACH_MAX_FRAMES_PER_CONNECTION, maxPayloadBytesPerConnection = ACP_PRE_ATTACH_MAX_PAYLOAD_BYTES_PER_CONNECTION, onPreAttachGuardFailure) {
@@ -16393,8 +15921,8 @@ var AcpConnection = class {
16393
15921
  this.maxFramesPerConnection = maxFramesPerConnection;
16394
15922
  this.maxPayloadBytesPerConnection = maxPayloadBytesPerConnection;
16395
15923
  this.onPreAttachGuardFailure = onPreAttachGuardFailure;
16396
- this.connectionId = connectionId ?? randomUUID6();
16397
- this.clientId = randomUUID6();
15924
+ this.connectionId = connectionId ?? randomUUID5();
15925
+ this.clientId = randomUUID5();
16398
15926
  this.fromLoopback = fromLoopback;
16399
15927
  }
16400
15928
  static {
@@ -18445,6 +17973,23 @@ var CdpBrowserEmulator = class {
18445
17973
  });
18446
17974
  case "Target.getDevToolsTarget":
18447
17975
  return this.cb.reply({ id, result: {} });
17976
+ // Target mutations the tunnel cannot perform: behind it is ONE tab the
17977
+ // user already has open, so there is nothing to create, close, or
17978
+ // isolate. These must not fall through to the empty ack below — a CDP
17979
+ // client reads `targetId` out of the createTarget result and then waits
17980
+ // for a target that never appears, so a fake success turns "open a new
17981
+ // page" into a protocol timeout instead of an immediate refusal.
17982
+ case "Target.createTarget":
17983
+ case "Target.closeTarget":
17984
+ case "Target.createBrowserContext":
17985
+ case "Target.disposeBrowserContext":
17986
+ return this.cb.reply({
17987
+ id,
17988
+ error: {
17989
+ code: SERVER_ERROR,
17990
+ message: `${method} is not supported by the CDP tunnel: it drives a single existing tab`
17991
+ }
17992
+ });
18448
17993
  case "Target.attachToTarget": {
18449
17994
  const targetId = params?.["targetId"];
18450
17995
  if (targetId !== PAGE_TARGET_ID) {
@@ -18804,10 +18349,10 @@ function isAcpChannelUnavailable(err) {
18804
18349
  return err?.data?.errorKind === "acp_channel_unavailable";
18805
18350
  }
18806
18351
  __name(isAcpChannelUnavailable, "isAcpChannelUnavailable");
18807
- function delay2(ms) {
18352
+ function delay(ms) {
18808
18353
  return new Promise((resolve7) => setTimeout(resolve7, ms));
18809
18354
  }
18810
- __name(delay2, "delay");
18355
+ __name(delay, "delay");
18811
18356
  function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname, env) {
18812
18357
  if (localPort === void 0 || !Number.isInteger(localPort) || localPort <= 0) {
18813
18358
  return void 0;
@@ -19068,7 +18613,7 @@ function mountAcpHttp(app, bridge, opts) {
19068
18613
  if (!isAcpChannelUnavailable(err) || attempt >= RUNTIME_MCP_RETRY_ATTEMPTS || !opts.cdpTunnelRegistry?.hasActive()) {
19069
18614
  throw err;
19070
18615
  }
19071
- await delay2(RUNTIME_MCP_RETRY_DELAY_MS);
18616
+ await delay(RUNTIME_MCP_RETRY_DELAY_MS);
19072
18617
  }
19073
18618
  }
19074
18619
  if (result.skipped) {
@@ -22061,9 +21606,9 @@ __name(registerWorkspaceAuthRoutes, "registerWorkspaceAuthRoutes");
22061
21606
  // packages/cli/src/serve/routes/workspace-extensions.ts
22062
21607
  init_esbuild_shims();
22063
21608
  import * as crypto2 from "node:crypto";
22064
- import * as fs5 from "node:fs/promises";
21609
+ import * as fs4 from "node:fs/promises";
22065
21610
  import * as os from "node:os";
22066
- import * as path10 from "node:path";
21611
+ import * as path9 from "node:path";
22067
21612
  var import_express2 = __toESM(require_express(), 1);
22068
21613
 
22069
21614
  // packages/cli/src/serve/extension-operation-scheduler.ts
@@ -22431,14 +21976,18 @@ function createExtensionsController(deps) {
22431
21976
  async (release) => {
22432
21977
  assertGenerationOpen?.();
22433
21978
  return await task((generation) => {
22434
- reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
21979
+ if (!options.skipRefresh) {
21980
+ reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
21981
+ }
22435
21982
  committedGeneration = generation;
22436
21983
  release();
22437
21984
  });
22438
21985
  }
22439
21986
  );
22440
21987
  if (committedGeneration === void 0) {
22441
- reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
21988
+ if (!options.skipRefresh) {
21989
+ reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
21990
+ }
22442
21991
  committedGeneration = result.generation;
22443
21992
  }
22444
21993
  for (const warning of result.warnings ?? []) {
@@ -22846,7 +22395,7 @@ var extensionArchiveBodyParser = import_express2.default.raw({
22846
22395
  });
22847
22396
  var assertDaemonExtensionInstallSource = /* @__PURE__ */ __name((installMetadata, source, ref, autoUpdate) => {
22848
22397
  if (installMetadata.type === "local") {
22849
- if (!path10.isAbsolute(source)) {
22398
+ if (!path9.isAbsolute(source)) {
22850
22399
  throw new Error(
22851
22400
  "Local extension sources must be absolute daemon-host paths; relative paths are not supported over the daemon endpoint."
22852
22401
  );
@@ -23302,11 +22851,6 @@ function registerWorkspaceExtensionRoutes(app, deps) {
23302
22851
  reserveRuntimeReconciliation,
23303
22852
  onRuntimeReconciled
23304
22853
  } : {}, "globalReconciliationOptions");
23305
- const workspaceReconciliationOptions = /* @__PURE__ */ __name(() => workspaceRegistry ? {
23306
- refreshRuntimes: [workspaceRegistry.primary],
23307
- reserveRuntimeReconciliation,
23308
- onRuntimeReconciled
23309
- } : {}, "workspaceReconciliationOptions");
23310
22854
  const mutationClientBridges = /* @__PURE__ */ __name((runtimes) => (typeof runtimes === "function" ? runtimes() : runtimes ?? workspaceRegistry?.listAll())?.map((runtime) => runtime.bridge) ?? [bridge], "mutationClientBridges");
23311
22855
  if (workspaceRegistry) {
23312
22856
  let observedGeneration;
@@ -23558,14 +23102,14 @@ function registerWorkspaceExtensionRoutes(app, deps) {
23558
23102
  let result;
23559
23103
  let failure;
23560
23104
  try {
23561
- uploadDir = await fs5.mkdtemp(
23562
- path10.join(os.tmpdir(), "qwen-extension-upload-")
23105
+ uploadDir = await fs4.mkdtemp(
23106
+ path9.join(os.tmpdir(), "qwen-extension-upload-")
23563
23107
  );
23564
- const archivePath = path10.join(
23108
+ const archivePath = path9.join(
23565
23109
  uploadDir,
23566
23110
  `extension${archiveName.suffix}`
23567
23111
  );
23568
- await fs5.writeFile(archivePath, archive);
23112
+ await fs4.writeFile(archivePath, archive);
23569
23113
  archive = void 0;
23570
23114
  const prepared = await context.prepare(async (signal) => {
23571
23115
  supersedeActiveInstallOperations(ctrl, operationId);
@@ -23598,7 +23142,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
23598
23142
  }
23599
23143
  if (uploadDir) {
23600
23144
  try {
23601
- await fs5.rm(uploadDir, { recursive: true, force: true });
23145
+ await fs4.rm(uploadDir, { recursive: true, force: true });
23602
23146
  } catch (error2) {
23603
23147
  failure ??= sanitizeUploadError(error2);
23604
23148
  }
@@ -23962,7 +23506,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
23962
23506
  return { status: "enabled", name: extension.name };
23963
23507
  },
23964
23508
  {
23965
- ...scope === "User" /* User */ ? globalReconciliationOptions() : workspaceReconciliationOptions()
23509
+ skipRefresh: true
23966
23510
  }
23967
23511
  );
23968
23512
  } catch (err) {
@@ -24009,7 +23553,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
24009
23553
  return { status: "disabled", name: extension.name };
24010
23554
  },
24011
23555
  {
24012
- ...scope === "User" /* User */ ? globalReconciliationOptions() : workspaceReconciliationOptions()
23556
+ skipRefresh: true
24013
23557
  }
24014
23558
  );
24015
23559
  } catch (err) {
@@ -24298,6 +23842,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
24298
23842
  };
24299
23843
  },
24300
23844
  {
23845
+ skipRefresh: true,
24301
23846
  ...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.listAll(), "refreshRuntimes") } : {}
24302
23847
  }
24303
23848
  );
@@ -24338,6 +23883,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
24338
23883
  };
24339
23884
  },
24340
23885
  {
23886
+ skipRefresh: true,
24341
23887
  ...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.listAll(), "refreshRuntimes") } : {}
24342
23888
  }
24343
23889
  );
@@ -24858,6 +24404,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
24858
24404
  };
24859
24405
  },
24860
24406
  {
24407
+ skipRefresh: true,
24861
24408
  refreshRuntimes: [runtime],
24862
24409
  assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
24863
24410
  }
@@ -24904,6 +24451,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
24904
24451
  };
24905
24452
  },
24906
24453
  {
24454
+ skipRefresh: true,
24907
24455
  refreshRuntimes: [runtime],
24908
24456
  assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
24909
24457
  }
@@ -24949,6 +24497,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
24949
24497
  return { status: activation.effective, name: extension.name };
24950
24498
  },
24951
24499
  {
24500
+ skipRefresh: true,
24952
24501
  refreshRuntimes: [runtime],
24953
24502
  assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
24954
24503
  }
@@ -24987,7 +24536,7 @@ __name(registerWorkspaceExtensionRoutes, "registerWorkspaceExtensionRoutes");
24987
24536
  // packages/cli/src/serve/routes/workspace-file-write.ts
24988
24537
  init_esbuild_shims();
24989
24538
  var import_express3 = __toESM(require_express(), 1);
24990
- import * as path11 from "node:path";
24539
+ import * as path10 from "node:path";
24991
24540
  function getFsFactory3(req, res) {
24992
24541
  const context = getWorkspaceRouteContext(req);
24993
24542
  if (context) return context.runtime.routeFileSystemFactory;
@@ -25420,8 +24969,8 @@ function fileUploadAdmission(deps, opts) {
25420
24969
  sendParseError(res, ROUTE2, "`path` query parameter is required");
25421
24970
  return;
25422
24971
  }
25423
- const dir = path11.dirname(queryPath);
25424
- const basename9 = path11.basename(queryPath);
24972
+ const dir = path10.dirname(queryPath);
24973
+ const basename9 = path10.basename(queryPath);
25425
24974
  if (queryPath.endsWith("/") || basename9.length === 0 || basename9 === "." || basename9 === "..") {
25426
24975
  sendParseError(res, ROUTE2, "`path` must name a file");
25427
24976
  return;
@@ -25542,11 +25091,11 @@ async function handlePostFileUpload(req, res) {
25542
25091
  );
25543
25092
  return;
25544
25093
  }
25545
- const candidateAbs = path11.join(resolvedDir, candidateBasename);
25094
+ const candidateAbs = path10.join(resolvedDir, candidateBasename);
25546
25095
  let resolved;
25547
25096
  try {
25548
25097
  resolved = await fs10.resolve(
25549
- path11.join(queryDir, candidateBasename),
25098
+ path10.join(queryDir, candidateBasename),
25550
25099
  "write"
25551
25100
  );
25552
25101
  } catch (err) {
@@ -25901,6 +25450,12 @@ var legacySessionTelemetryRoutes = [
25901
25450
  attribution: "handler_resolved",
25902
25451
  route: "POST /session/:id/resume"
25903
25452
  },
25453
+ {
25454
+ method: "POST",
25455
+ path: "/session/:id/worktree-reset",
25456
+ attribution: "handler_resolved",
25457
+ route: "POST /session/:id/worktree-reset"
25458
+ },
25904
25459
  {
25905
25460
  method: "POST",
25906
25461
  path: "/session/:id/branch",
@@ -26876,11 +26431,92 @@ __name(registerPermissionRoutes, "registerPermissionRoutes");
26876
26431
  // packages/cli/src/serve/routes/session.ts
26877
26432
  init_esbuild_shims();
26878
26433
  import * as crypto3 from "node:crypto";
26879
- import * as fs7 from "node:fs";
26880
- import * as path12 from "node:path";
26434
+ import * as fs6 from "node:fs";
26435
+ import * as path11 from "node:path";
26881
26436
  import { inspect } from "node:util";
26882
26437
  var import_express4 = __toESM(require_express(), 1);
26883
26438
 
26439
+ // packages/cli/src/serve/server/worktree-reset-errors.ts
26440
+ init_esbuild_shims();
26441
+ var WorktreeSessionSupersededError = class extends Error {
26442
+ static {
26443
+ __name(this, "WorktreeSessionSupersededError");
26444
+ }
26445
+ sessionId;
26446
+ replacementSessionId;
26447
+ constructor(sessionId, replacementSessionId) {
26448
+ super(
26449
+ `Session ${sessionId} was superseded by a worktree reset; restore the replacement session instead`
26450
+ );
26451
+ this.name = "WorktreeSessionSupersededError";
26452
+ this.sessionId = sessionId;
26453
+ this.replacementSessionId = replacementSessionId;
26454
+ }
26455
+ };
26456
+ var WorktreeMarkerMissingError = class extends Error {
26457
+ static {
26458
+ __name(this, "WorktreeMarkerMissingError");
26459
+ }
26460
+ sessionId;
26461
+ constructor(sessionId) {
26462
+ super(
26463
+ `Worktree ownership marker for session ${sessionId} is missing; reset the task to recreate it`
26464
+ );
26465
+ this.name = "WorktreeMarkerMissingError";
26466
+ this.sessionId = sessionId;
26467
+ }
26468
+ };
26469
+ var WorktreeResetInterruptedError = class extends Error {
26470
+ static {
26471
+ __name(this, "WorktreeResetInterruptedError");
26472
+ }
26473
+ sessionId;
26474
+ constructor(sessionId) {
26475
+ super(
26476
+ "A previous worktree reset was interrupted; retry the reset against the superseded session to finish or roll it back"
26477
+ );
26478
+ this.name = "WorktreeResetInterruptedError";
26479
+ this.sessionId = sessionId;
26480
+ }
26481
+ };
26482
+ var WorktreeResetActiveError = class extends Error {
26483
+ static {
26484
+ __name(this, "WorktreeResetActiveError");
26485
+ }
26486
+ sessionId;
26487
+ constructor(sessionId) {
26488
+ super(
26489
+ `Session ${sessionId} has a prompt in progress; wait for it to finish before resetting`
26490
+ );
26491
+ this.name = "WorktreeResetActiveError";
26492
+ this.sessionId = sessionId;
26493
+ }
26494
+ };
26495
+ var WorktreeResetUnsupportedError = class extends Error {
26496
+ static {
26497
+ __name(this, "WorktreeResetUnsupportedError");
26498
+ }
26499
+ sessionId;
26500
+ constructor(sessionId) {
26501
+ super(`Session ${sessionId} is not a worktree session`);
26502
+ this.name = "WorktreeResetUnsupportedError";
26503
+ this.sessionId = sessionId;
26504
+ }
26505
+ };
26506
+ var WorktreeResetInvalidStateError = class extends Error {
26507
+ static {
26508
+ __name(this, "WorktreeResetInvalidStateError");
26509
+ }
26510
+ sessionId;
26511
+ constructor(sessionId) {
26512
+ super(
26513
+ `Session ${sessionId}'s worktree ownership state is invalid; the reset made no destructive change`
26514
+ );
26515
+ this.name = "WorktreeResetInvalidStateError";
26516
+ this.sessionId = sessionId;
26517
+ }
26518
+ };
26519
+
26884
26520
  // packages/cli/src/serve/server/prompt-deadline.ts
26885
26521
  init_esbuild_shims();
26886
26522
  function resolvePromptDeadlineMs(serverMs, requestMs) {
@@ -27005,7 +26641,7 @@ __name(deleteBranch, "deleteBranch");
27005
26641
 
27006
26642
  // packages/cli/src/serve/virtual-subagent-sessions.ts
27007
26643
  init_esbuild_shims();
27008
- import * as fs6 from "node:fs/promises";
26644
+ import * as fs5 from "node:fs/promises";
27009
26645
  import { createReadStream } from "node:fs";
27010
26646
  import readline from "node:readline";
27011
26647
  var PREFIX = "subagent.";
@@ -27215,7 +26851,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
27215
26851
  async readNewRecords(endOffset) {
27216
26852
  let handle;
27217
26853
  try {
27218
- handle = await fs6.open(this.task.outputFile, "r");
26854
+ handle = await fs5.open(this.task.outputFile, "r");
27219
26855
  const stat3 = await handle.stat();
27220
26856
  const identity = `${stat3.dev}:${stat3.ino}`;
27221
26857
  if (this.transcriptIdentity !== void 0 && this.transcriptIdentity !== identity || stat3.size < this.offset) {
@@ -27259,7 +26895,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
27259
26895
  const filePath = `${this.task.outputFile}.stream`;
27260
26896
  let handle;
27261
26897
  try {
27262
- handle = await fs6.open(filePath, "r");
26898
+ handle = await fs5.open(filePath, "r");
27263
26899
  const stat3 = await handle.stat();
27264
26900
  const identity = `${stat3.dev}:${stat3.ino}`;
27265
26901
  if (this.streamIdentity !== void 0 && this.streamIdentity !== identity) {
@@ -27424,7 +27060,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
27424
27060
  async captureReadBounds() {
27425
27061
  const size = /* @__PURE__ */ __name(async (filePath) => {
27426
27062
  try {
27427
- return (await fs6.stat(filePath)).size;
27063
+ return (await fs5.stat(filePath)).size;
27428
27064
  } catch (error2) {
27429
27065
  if (error2.code === "ENOENT") return 0;
27430
27066
  throw error2;
@@ -27553,7 +27189,7 @@ var VirtualSubagentSessions = class {
27553
27189
  const sessionDir = getSubagentSessionDir(projectDir, parentSessionId);
27554
27190
  let names;
27555
27191
  try {
27556
- names = await fs6.readdir(sessionDir);
27192
+ names = await fs5.readdir(sessionDir);
27557
27193
  } catch (error2) {
27558
27194
  if (error2.code === "ENOENT") return void 0;
27559
27195
  throw error2;
@@ -27609,7 +27245,7 @@ var VirtualSubagentSessions = class {
27609
27245
  const sessionDir = getSubagentSessionDir(projectDir, parentSessionId);
27610
27246
  let names;
27611
27247
  try {
27612
- names = await fs6.readdir(sessionDir);
27248
+ names = await fs5.readdir(sessionDir);
27613
27249
  } catch (error2) {
27614
27250
  if (error2.code === "ENOENT") return void 0;
27615
27251
  throw error2;
@@ -28134,34 +27770,6 @@ function registerSessionRoutes(app, deps) {
28134
27770
  const LANGUAGE_CODES = deps.languageCodes;
28135
27771
  const transcriptCursorMasterKey = crypto3.randomBytes(32);
28136
27772
  const transcriptCursorCodecs = /* @__PURE__ */ new Map();
28137
- const worktreeRestoreTails = /* @__PURE__ */ new WeakMap();
28138
- const acquireWorktreeRestore = /* @__PURE__ */ __name(async (bridge, sessionId) => {
28139
- let tails = worktreeRestoreTails.get(bridge);
28140
- if (!tails) {
28141
- tails = /* @__PURE__ */ new Map();
28142
- worktreeRestoreTails.set(bridge, tails);
28143
- }
28144
- const key = normalizeSessionIdForLookup(sessionId);
28145
- const previous = tails.get(key);
28146
- let releaseGate;
28147
- const gate = new Promise((resolve7) => {
28148
- releaseGate = resolve7;
28149
- });
28150
- const tail = (previous ?? Promise.resolve()).then(() => gate);
28151
- tails.set(key, tail);
28152
- if (previous) {
28153
- await previous;
28154
- }
28155
- let released = false;
28156
- return () => {
28157
- if (released) return;
28158
- released = true;
28159
- releaseGate();
28160
- if (tails.get(key) === tail) {
28161
- tails.delete(key);
28162
- }
28163
- };
28164
- }, "acquireWorktreeRestore");
28165
27773
  const activeBranchSessions = /* @__PURE__ */ new Map();
28166
27774
  const inFlightBranchWorkspaces = /* @__PURE__ */ new Set();
28167
27775
  const clearBranchSessionEntry = /* @__PURE__ */ __name((sessionId) => {
@@ -28270,28 +27878,28 @@ function registerSessionRoutes(app, deps) {
28270
27878
  const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
28271
27879
  if (cwd === void 0) return void 0;
28272
27880
  const isWithinConversationRoot = /* @__PURE__ */ __name((root, candidate) => {
28273
- const relative5 = path12.relative(root, candidate);
28274
- return relative5 === "" || relative5 !== ".." && !relative5.startsWith(`..${path12.sep}`) && !path12.isAbsolute(relative5);
27881
+ const relative5 = path11.relative(root, candidate);
27882
+ return relative5 === "" || relative5 !== ".." && !relative5.startsWith(`..${path11.sep}`) && !path11.isAbsolute(relative5);
28275
27883
  }, "isWithinConversationRoot");
28276
27884
  const canonicalizeIfPresent = /* @__PURE__ */ __name((candidate) => {
28277
- const resolved = path12.resolve(candidate);
27885
+ const resolved = path11.resolve(candidate);
28278
27886
  try {
28279
- return fs7.realpathSync.native(resolved);
27887
+ return fs6.realpathSync.native(resolved);
28280
27888
  } catch {
28281
27889
  return resolved;
28282
27890
  }
28283
27891
  }, "canonicalizeIfPresent");
28284
27892
  const canonicalizeExistingAncestor = /* @__PURE__ */ __name((candidate) => {
28285
- let ancestor = path12.resolve(candidate);
27893
+ let ancestor = path11.resolve(candidate);
28286
27894
  const missingTail = [];
28287
27895
  while (true) {
28288
27896
  try {
28289
- return path12.join(fs7.realpathSync.native(ancestor), ...missingTail);
27897
+ return path11.join(fs6.realpathSync.native(ancestor), ...missingTail);
28290
27898
  } catch (error2) {
28291
27899
  if (error2.code !== "ENOENT") throw error2;
28292
- const parent = path12.dirname(ancestor);
27900
+ const parent = path11.dirname(ancestor);
28293
27901
  if (parent === ancestor) throw error2;
28294
- missingTail.unshift(path12.basename(ancestor));
27902
+ missingTail.unshift(path11.basename(ancestor));
28295
27903
  ancestor = parent;
28296
27904
  }
28297
27905
  }
@@ -28304,8 +27912,8 @@ function registerSessionRoutes(app, deps) {
28304
27912
  return void 0;
28305
27913
  }, "rejectReservedConversationRoot");
28306
27914
  if ("cwd" in body && deps.liveConversationRootPath && isWithinConversationRoot(
28307
- path12.resolve(deps.liveConversationRootPath),
28308
- path12.resolve(cwd)
27915
+ path11.resolve(deps.liveConversationRootPath),
27916
+ path11.resolve(cwd)
28309
27917
  )) {
28310
27918
  return rejectReservedConversationRoot();
28311
27919
  }
@@ -28328,7 +27936,7 @@ function registerSessionRoutes(app, deps) {
28328
27936
  const liveRoots = [
28329
27937
  ...workspaceRegistry.listAllEntries().filter((entry2) => entry2.internal).map((entry2) => entry2.workspaceCwd),
28330
27938
  ...deps.liveConversationRootPath ? [
28331
- path12.resolve(deps.liveConversationRootPath),
27939
+ path11.resolve(deps.liveConversationRootPath),
28332
27940
  canonicalizeIfPresent(deps.liveConversationRootPath)
28333
27941
  ] : []
28334
27942
  ];
@@ -28378,7 +27986,7 @@ function registerSessionRoutes(app, deps) {
28378
27986
  const workspaceParam = req.params[paramName] ?? "";
28379
27987
  const byId = workspaceRegistry.getByWorkspaceId(workspaceParam);
28380
27988
  if (byId) return byId;
28381
- if (!path12.isAbsolute(workspaceParam)) {
27989
+ if (!path11.isAbsolute(workspaceParam)) {
28382
27990
  res.status(400).json({
28383
27991
  error: `\`:${paramName}\` must decode to a workspace id or absolute path`
28384
27992
  });
@@ -28431,11 +28039,11 @@ function registerSessionRoutes(app, deps) {
28431
28039
  }
28432
28040
  const selector = req.params[paramName] ?? "";
28433
28041
  let entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector);
28434
- if (!entry && path12.isAbsolute(selector)) {
28042
+ if (!entry && path11.isAbsolute(selector)) {
28435
28043
  entry = workspaceRegistry.getManagedEntryByWorkspaceCwd(selector);
28436
28044
  }
28437
- const configuredRoot = deps.liveConversationRootPath ? path12.resolve(deps.liveConversationRootPath) : void 0;
28438
- const matchesConfiguredRoot = configuredRoot !== void 0 && selector === configuredRoot && path12.resolve(selector) === selector;
28045
+ const configuredRoot = deps.liveConversationRootPath ? path11.resolve(deps.liveConversationRootPath) : void 0;
28046
+ const matchesConfiguredRoot = configuredRoot !== void 0 && selector === configuredRoot && path11.resolve(selector) === selector;
28439
28047
  if ((!entry || !entry.internal) && !matchesConfiguredRoot) {
28440
28048
  return void 0;
28441
28049
  }
@@ -28464,7 +28072,7 @@ function registerSessionRoutes(app, deps) {
28464
28072
  }, "resolveLiveCatalogRuntime");
28465
28073
  const resolveQualifiedSessionTarget = /* @__PURE__ */ __name((req, res, options = {}) => {
28466
28074
  const selector = req.params["workspace"] ?? "";
28467
- const entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector) ?? (path12.isAbsolute(selector) ? workspaceRegistry.getManagedEntryByWorkspaceCwd(selector) : void 0);
28075
+ const entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector) ?? (path11.isAbsolute(selector) ? workspaceRegistry.getManagedEntryByWorkspaceCwd(selector) : void 0);
28468
28076
  if (entry?.internal) return { kind: "internal", entry };
28469
28077
  const runtime = resolveWorkspaceRuntimeFromParam(
28470
28078
  workspaceRegistry,
@@ -28741,8 +28349,8 @@ function registerSessionRoutes(app, deps) {
28741
28349
  const resolveRuntimeForSessionRestore = /* @__PURE__ */ __name(async (body, res, route, sessionId) => {
28742
28350
  const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
28743
28351
  if (cwd === void 0) return void 0;
28744
- const configuredRoot = deps.liveConversationRootPath ? path12.resolve(deps.liveConversationRootPath) : void 0;
28745
- const bootstrappedRuntime = "cwd" in body && configuredRoot !== void 0 && path12.isAbsolute(cwd) && path12.resolve(cwd) === configuredRoot && deps.ensureConversationRuntime ? await deps.ensureConversationRuntime() : void 0;
28352
+ const configuredRoot = deps.liveConversationRootPath ? path11.resolve(deps.liveConversationRootPath) : void 0;
28353
+ const bootstrappedRuntime = "cwd" in body && configuredRoot !== void 0 && path11.isAbsolute(cwd) && path11.resolve(cwd) === configuredRoot && deps.ensureConversationRuntime ? await deps.ensureConversationRuntime() : void 0;
28746
28354
  let key;
28747
28355
  try {
28748
28356
  key = canonicalizeWorkspace(cwd);
@@ -29451,6 +29059,7 @@ function registerSessionRoutes(app, deps) {
29451
29059
  coordinator: archiveCoordinator,
29452
29060
  coordinatorLockHeld,
29453
29061
  assertCanMutate,
29062
+ runtimeWorkspaceCwd: runtime.workspaceCwd,
29454
29063
  onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
29455
29064
  writeStderrLine(
29456
29065
  `qwen serve: ${phase}Session failed for ${safeLogValue(sessionId)}: ${safeLogValue(error2)}`
@@ -29901,7 +29510,7 @@ function registerSessionRoutes(app, deps) {
29901
29510
  } catch (error2) {
29902
29511
  if (!session.attached) {
29903
29512
  try {
29904
- const removed = await runWithWorkspaceRuntimeStorage(
29513
+ await runWithWorkspaceRuntimeStorage(
29905
29514
  runtime,
29906
29515
  () => deleteDaemonSessionIfOrphan({
29907
29516
  sessionId: session.sessionId,
@@ -29910,18 +29519,25 @@ function registerSessionRoutes(app, deps) {
29910
29519
  coordinator: archiveCoordinator
29911
29520
  })
29912
29521
  );
29913
- if (removed) {
29914
- if (worktreeMeta) {
29915
- await new GitWorktreeService(workspaceCwd).removeUserWorktree(worktreeMeta.slug, { deleteBranch: true }).catch(() => {
29916
- });
29917
- }
29918
- }
29919
29522
  } catch {
29920
29523
  }
29921
29524
  } else {
29922
29525
  await runtime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
29923
29526
  });
29924
29527
  }
29528
+ if (worktreeMeta) {
29529
+ const rollbackSlug = worktreeMeta.slug;
29530
+ await new GitWorktreeService(workspaceCwd).removeUserWorktree(rollbackSlug, { deleteBranch: true }).catch((removalError) => {
29531
+ daemonLog?.warn(
29532
+ "worktree removal failed during generation-closed rollback",
29533
+ {
29534
+ sessionId: session.sessionId,
29535
+ slug: rollbackSlug,
29536
+ error: removalError instanceof Error ? removalError.message : String(removalError)
29537
+ }
29538
+ );
29539
+ });
29540
+ }
29925
29541
  throw error2;
29926
29542
  }
29927
29543
  if (daemonLog) {
@@ -29986,7 +29602,7 @@ function registerSessionRoutes(app, deps) {
29986
29602
  if (worktreeMeta) {
29987
29603
  try {
29988
29604
  const createAllowedRoots = [
29989
- path12.join(workspaceCwd, ".qwen", "worktrees")
29605
+ path11.join(workspaceCwd, ".qwen", "worktrees")
29990
29606
  ];
29991
29607
  let createRepoTop = null;
29992
29608
  try {
@@ -29997,10 +29613,10 @@ function registerSessionRoutes(app, deps) {
29997
29613
  }
29998
29614
  if (createRepoTop && createRepoTop !== workspaceCwd) {
29999
29615
  createAllowedRoots.push(
30000
- path12.join(createRepoTop, ".qwen", "worktrees")
29616
+ path11.join(createRepoTop, ".qwen", "worktrees")
30001
29617
  );
30002
29618
  }
30003
- const expectedWorktreePath = fs7.realpathSync(worktreeMeta.path);
29619
+ const expectedWorktreePath = fs6.realpathSync(worktreeMeta.path);
30004
29620
  const changed = await runtime.bridge.changeSessionCwd(
30005
29621
  session.sessionId,
30006
29622
  {
@@ -30350,21 +29966,42 @@ function registerSessionRoutes(app, deps) {
30350
29966
  };
30351
29967
  const isChannelRestore = restoreRequestMetadata.sourceType === "channel";
30352
29968
  let isPart4AWorktreeRestore = false;
30353
- if (isChannelRestore && runtime.provenance !== "live-conversation") {
29969
+ let part4AWorktreeKey;
29970
+ if (runtime.provenance !== "live-conversation") {
30354
29971
  const sidecarBeforeRestore = await readWorktreeSessionStrict(
30355
29972
  sessionService.getWorktreeSessionPath(restoredStorageSessionId)
30356
29973
  );
29974
+ if (isChannelRestore) {
29975
+ suppressWorktreeContextRestore = !(sidecarBeforeRestore.state === "valid" && sidecarBeforeRestore.session.workspaceCwd === void 0);
29976
+ }
30357
29977
  isPart4AWorktreeRestore = sidecarBeforeRestore.state === "valid" && sidecarBeforeRestore.session.workspaceCwd !== void 0;
30358
- suppressWorktreeContextRestore = !(sidecarBeforeRestore.state === "valid" && sidecarBeforeRestore.session.workspaceCwd === void 0);
29978
+ if (isPart4AWorktreeRestore && sidecarBeforeRestore.state === "valid") {
29979
+ const recordedPath = sidecarBeforeRestore.session.worktreePath;
29980
+ try {
29981
+ part4AWorktreeKey = fs6.realpathSync(recordedPath);
29982
+ } catch {
29983
+ part4AWorktreeKey = recordedPath;
29984
+ }
29985
+ }
30359
29986
  } else {
30360
29987
  suppressWorktreeContextRestore = isChannelRestore;
30361
29988
  }
30362
29989
  deferRestoreAskUserQuestionPrompt = suppressWorktreeContextRestore && runtime.bridge.fireDeferredRestoreAskUserQuestionPrompt !== void 0 && runtime.bridge.discardDeferredRestoreAskUserQuestionPrompt !== void 0;
30363
- if (deferRestoreAskUserQuestionPrompt && isPart4AWorktreeRestore) {
30364
- releaseWorktreeRestore = await acquireWorktreeRestore(
30365
- runtime.bridge,
30366
- sessionId
30367
- );
29990
+ if (isPart4AWorktreeRestore && part4AWorktreeKey !== void 0) {
29991
+ releaseWorktreeRestore = await acquireWorktreeOwnershipOp(part4AWorktreeKey);
29992
+ if (isChannelRestore) {
29993
+ const sidecarUnderLock = await readWorktreeSessionStrict(
29994
+ sessionService.getWorktreeSessionPath(
29995
+ restoredStorageSessionId
29996
+ )
29997
+ );
29998
+ if (sidecarUnderLock.state === "valid" && sidecarUnderLock.session.supersededBy !== void 0) {
29999
+ throw new WorktreeSessionSupersededError(
30000
+ restoredStorageSessionId,
30001
+ sidecarUnderLock.session.supersededBy
30002
+ );
30003
+ }
30004
+ }
30368
30005
  }
30369
30006
  assertRuntimeGenerationOpen?.();
30370
30007
  if (isInternalWorkspaceRuntime(runtime)) {
@@ -30511,7 +30148,7 @@ function registerSessionRoutes(app, deps) {
30511
30148
  let candidateRoots = [];
30512
30149
  let validationError;
30513
30150
  try {
30514
- const workspaceRoots = [fs7.realpathSync(workspaceCwd)];
30151
+ const workspaceRoots = [fs6.realpathSync(workspaceCwd)];
30515
30152
  let repoTop = null;
30516
30153
  try {
30517
30154
  repoTop = await new GitWorktreeService(
@@ -30520,24 +30157,24 @@ function registerSessionRoutes(app, deps) {
30520
30157
  } catch {
30521
30158
  }
30522
30159
  if (repoTop) {
30523
- const realRepoTop = fs7.realpathSync(repoTop);
30160
+ const realRepoTop = fs6.realpathSync(repoTop);
30524
30161
  if (!workspaceRoots.includes(realRepoTop)) {
30525
30162
  workspaceRoots.push(realRepoTop);
30526
30163
  }
30527
30164
  }
30528
- const realOriginalCwd = fs7.realpathSync(sidecar.originalCwd);
30165
+ const realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
30529
30166
  if (!workspaceRoots.includes(realOriginalCwd)) {
30530
30167
  throw new Error("legacy sidecar belongs to another workspace");
30531
30168
  }
30532
30169
  candidateRoots = workspaceRoots.map(
30533
- (root) => path12.join(root, ".qwen", "worktrees")
30170
+ (root) => path11.join(root, ".qwen", "worktrees")
30534
30171
  );
30535
- realTarget = fs7.realpathSync(sidecar.worktreePath);
30172
+ realTarget = fs6.realpathSync(sidecar.worktreePath);
30536
30173
  const contained = candidateRoots.some((root) => {
30537
30174
  try {
30538
- const realRoot = fs7.realpathSync(root);
30539
- const relative5 = path12.relative(realRoot, realTarget);
30540
- return relative5.length > 0 && !relative5.startsWith("..") && !path12.isAbsolute(relative5);
30175
+ const realRoot = fs6.realpathSync(root);
30176
+ const relative5 = path11.relative(realRoot, realTarget);
30177
+ return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
30541
30178
  } catch {
30542
30179
  return false;
30543
30180
  }
@@ -30584,11 +30221,17 @@ function registerSessionRoutes(app, deps) {
30584
30221
  throw new Error("Worktree sidecar is missing or invalid");
30585
30222
  }
30586
30223
  const sidecar = sidecarResult.session;
30587
- const realWorkspace = fs7.realpathSync(workspaceCwd);
30224
+ if (sidecar.supersededBy !== void 0) {
30225
+ throw new WorktreeSessionSupersededError(
30226
+ restoredStorageSessionId,
30227
+ sidecar.supersededBy
30228
+ );
30229
+ }
30230
+ const realWorkspace = fs6.realpathSync(workspaceCwd);
30588
30231
  if (sidecar.workspaceCwd !== void 0) {
30589
30232
  let realSidecarWorkspace;
30590
30233
  try {
30591
- realSidecarWorkspace = fs7.realpathSync(sidecar.workspaceCwd);
30234
+ realSidecarWorkspace = fs6.realpathSync(sidecar.workspaceCwd);
30592
30235
  } catch {
30593
30236
  throw new Error(
30594
30237
  "Worktree sidecar workspace is missing or inaccessible"
@@ -30609,11 +30252,11 @@ function registerSessionRoutes(app, deps) {
30609
30252
  } catch {
30610
30253
  }
30611
30254
  if (repoTop && repoTop !== realWorkspace) {
30612
- workspaceRoots.push(fs7.realpathSync(repoTop));
30255
+ workspaceRoots.push(fs6.realpathSync(repoTop));
30613
30256
  }
30614
30257
  let realOriginalCwd;
30615
30258
  try {
30616
- realOriginalCwd = fs7.realpathSync(sidecar.originalCwd);
30259
+ realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
30617
30260
  } catch {
30618
30261
  throw new Error(
30619
30262
  "Worktree sidecar workspace is missing or inaccessible"
@@ -30625,19 +30268,19 @@ function registerSessionRoutes(app, deps) {
30625
30268
  );
30626
30269
  }
30627
30270
  const candidateRoots = workspaceRoots.map(
30628
- (root) => path12.join(root, ".qwen", "worktrees")
30271
+ (root) => path11.join(root, ".qwen", "worktrees")
30629
30272
  );
30630
30273
  let realTarget;
30631
30274
  try {
30632
- realTarget = fs7.realpathSync(sidecar.worktreePath);
30275
+ realTarget = fs6.realpathSync(sidecar.worktreePath);
30633
30276
  } catch {
30634
30277
  throw new Error("Worktree checkout is missing or inaccessible");
30635
30278
  }
30636
30279
  const contained = candidateRoots.some((root) => {
30637
30280
  try {
30638
- const realRoot = fs7.realpathSync(root);
30639
- const relative5 = path12.relative(realRoot, realTarget);
30640
- return relative5.length > 0 && !relative5.startsWith("..") && !path12.isAbsolute(relative5);
30281
+ const realRoot = fs6.realpathSync(root);
30282
+ const relative5 = path11.relative(realRoot, realTarget);
30283
+ return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
30641
30284
  } catch {
30642
30285
  return false;
30643
30286
  }
@@ -30647,6 +30290,30 @@ function registerSessionRoutes(app, deps) {
30647
30290
  }
30648
30291
  const marker = await readWorktreeSessionMarkerStrict(realTarget);
30649
30292
  if (marker.state !== "valid" || marker.sessionId !== restoredStorageSessionId) {
30293
+ if (sidecar.supersedes !== void 0 && (marker.state === "missing" || marker.state === "valid" && marker.sessionId === sidecar.supersedes)) {
30294
+ const oldSidecar = await readWorktreeSessionStrict(
30295
+ createWorkspaceRuntimeSessionService(
30296
+ runtime
30297
+ ).getWorktreeSessionPath(sidecar.supersedes)
30298
+ );
30299
+ if (oldSidecar.state === "valid" && oldSidecar.session.supersededBy === restoredStorageSessionId) {
30300
+ daemonLog?.warn(
30301
+ "worktree restore found an interrupted reset",
30302
+ {
30303
+ sessionId: restoredStorageSessionId,
30304
+ supersedesSessionId: sidecar.supersedes
30305
+ }
30306
+ );
30307
+ throw new WorktreeResetInterruptedError(
30308
+ restoredStorageSessionId
30309
+ );
30310
+ }
30311
+ }
30312
+ if (marker.state === "missing") {
30313
+ throw new WorktreeMarkerMissingError(
30314
+ restoredStorageSessionId
30315
+ );
30316
+ }
30650
30317
  throw new Error("Worktree marker ownership is invalid");
30651
30318
  }
30652
30319
  const worktree = {
@@ -30654,28 +30321,28 @@ function registerSessionRoutes(app, deps) {
30654
30321
  path: realTarget,
30655
30322
  branch: sidecar.worktreeBranch
30656
30323
  };
30657
- const hasUnlocatedRestoredPrompt = session.hasActivePrompt && !session.attached && session.currentCwd === void 0;
30324
+ const hasUnlocatedRestoredPrompt = session.hasActivePrompt && !session.attached && session.currentCwd === void 0 && !deferRestoreAskUserQuestionPrompt;
30658
30325
  if (hasUnlocatedRestoredPrompt) {
30659
30326
  runtime.bridge.setSessionWorktree(sessionId, worktree);
30660
30327
  session.worktree = worktree;
30661
- } else if (session.hasActivePrompt) {
30662
- if (session.currentCwd !== realTarget) {
30663
- throw new Error("Active session is outside its worktree");
30664
- }
30665
30328
  } else {
30666
- const changed = await runtime.bridge.changeSessionCwd(
30667
- sessionId,
30668
- {
30669
- path: realTarget,
30670
- allowedRoots: candidateRoots
30329
+ if (session.hasActivePrompt) {
30330
+ if (session.currentCwd !== realTarget) {
30331
+ throw new Error("Active session is outside its worktree");
30671
30332
  }
30672
- );
30673
- if (changed.newCwd !== realTarget) {
30674
- throw new Error("Worktree relocation was rejected");
30333
+ } else {
30334
+ const changed = await runtime.bridge.changeSessionCwd(
30335
+ sessionId,
30336
+ {
30337
+ path: realTarget,
30338
+ allowedRoots: candidateRoots
30339
+ }
30340
+ );
30341
+ if (changed.newCwd !== realTarget) {
30342
+ throw new Error("Worktree relocation was rejected");
30343
+ }
30344
+ session.currentCwd = changed.newCwd;
30675
30345
  }
30676
- session.currentCwd = changed.newCwd;
30677
- }
30678
- if (!hasUnlocatedRestoredPrompt) {
30679
30346
  runtime.bridge.setSessionWorktree(sessionId, worktree);
30680
30347
  assertRuntimeGenerationOpen?.();
30681
30348
  session.worktree = worktree;
@@ -30750,6 +30417,448 @@ function registerSessionRoutes(app, deps) {
30750
30417
  }, "restoreSessionHandler");
30751
30418
  app.post("/session/:id/load", mutate(), restoreSessionHandler("load"));
30752
30419
  app.post("/session/:id/resume", mutate(), restoreSessionHandler("resume"));
30420
+ const resolveWorktreeOwnershipTarget = /* @__PURE__ */ __name(async (runtime, workspaceCwd, sidecar, sessionId) => {
30421
+ const invalidState = /* @__PURE__ */ __name((reason) => {
30422
+ daemonLog?.warn("worktree reset rejected sidecar state", {
30423
+ sessionId,
30424
+ reason
30425
+ });
30426
+ return new WorktreeResetInvalidStateError(sessionId);
30427
+ }, "invalidState");
30428
+ const realWorkspace = fs6.realpathSync(workspaceCwd);
30429
+ if (sidecar.workspaceCwd !== void 0) {
30430
+ let realSidecarWorkspace;
30431
+ try {
30432
+ realSidecarWorkspace = fs6.realpathSync(sidecar.workspaceCwd);
30433
+ } catch {
30434
+ throw invalidState("sidecar workspace is missing or inaccessible");
30435
+ }
30436
+ if (realSidecarWorkspace !== realWorkspace) {
30437
+ throw invalidState("sidecar belongs to another workspace");
30438
+ }
30439
+ }
30440
+ const workspaceRoots = [realWorkspace];
30441
+ let repoTop = null;
30442
+ try {
30443
+ repoTop = await new GitWorktreeService(realWorkspace).getRepoTopLevel();
30444
+ } catch {
30445
+ }
30446
+ if (repoTop && repoTop !== realWorkspace) {
30447
+ workspaceRoots.push(fs6.realpathSync(repoTop));
30448
+ }
30449
+ let realOriginalCwd;
30450
+ try {
30451
+ realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
30452
+ } catch {
30453
+ throw invalidState("sidecar original cwd is missing or inaccessible");
30454
+ }
30455
+ if (!workspaceRoots.includes(realOriginalCwd)) {
30456
+ throw invalidState("sidecar original cwd is outside the accepted roots");
30457
+ }
30458
+ const candidateRoots = workspaceRoots.map(
30459
+ (root) => path11.join(root, ".qwen", "worktrees")
30460
+ );
30461
+ let realTarget;
30462
+ try {
30463
+ realTarget = fs6.realpathSync(sidecar.worktreePath);
30464
+ } catch {
30465
+ throw invalidState("worktree checkout is missing or inaccessible");
30466
+ }
30467
+ const contained = candidateRoots.some((root) => {
30468
+ try {
30469
+ const realRoot = fs6.realpathSync(root);
30470
+ const relative5 = path11.relative(realRoot, realTarget);
30471
+ return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
30472
+ } catch {
30473
+ return false;
30474
+ }
30475
+ });
30476
+ if (!contained) {
30477
+ throw invalidState("worktree path failed containment");
30478
+ }
30479
+ return { realTarget, candidateRoots };
30480
+ }, "resolveWorktreeOwnershipTarget");
30481
+ const worktreeResetHandler = /* @__PURE__ */ __name(async (req, res) => {
30482
+ const route = "POST /session/:id/worktree-reset";
30483
+ const sessionId = requireSessionId(req, res);
30484
+ if (!sessionId) return;
30485
+ if (parseVirtualSubagentSessionId(sessionId)) {
30486
+ res.status(400).json({
30487
+ error: "Virtual subagent sessions do not support worktree reset",
30488
+ code: "unsupported_action",
30489
+ sessionId
30490
+ });
30491
+ return;
30492
+ }
30493
+ const body = safeBody(req);
30494
+ let resolvedRuntime;
30495
+ try {
30496
+ resolvedRuntime = await resolveRuntimeForSessionRestore(
30497
+ body,
30498
+ res,
30499
+ route,
30500
+ sessionId
30501
+ );
30502
+ } catch (err) {
30503
+ if (sendConversationRuntimeError(res, err)) return;
30504
+ sendBridgeError2(res, err, { route, sessionId });
30505
+ return;
30506
+ }
30507
+ if (resolvedRuntime === void 0) return;
30508
+ const { runtime, workspaceCwd } = resolvedRuntime;
30509
+ const approvalMode = parseOptionalApprovalMode(body, res);
30510
+ if (approvalMode === null) return;
30511
+ const source = parseRequestedSessionSource(body, res);
30512
+ if (source === null) return;
30513
+ const modelServiceId = typeof body["modelServiceId"] === "string" ? body["modelServiceId"] : void 0;
30514
+ const assertRuntimeGenerationOpen = captureRuntimeGenerationAssertion(runtime);
30515
+ try {
30516
+ await runOwnerRuntimeActivity(
30517
+ runtime,
30518
+ () => archiveCoordinator.runSharedMany([sessionId], async () => {
30519
+ const sessionService = createWorkspaceRuntimeSessionService(runtime);
30520
+ const storageSessionId = await resolveSessionIdForRestore(
30521
+ sessionService,
30522
+ sessionId
30523
+ );
30524
+ if (storageSessionId === void 0) {
30525
+ throw new SessionNotFoundError(sessionId);
30526
+ }
30527
+ const oldSidecarPath = sessionService.getWorktreeSessionPath(storageSessionId);
30528
+ if (runtime.bridge.setSessionResetPending === void 0 || runtime.bridge.clearSessionResetPending === void 0 || runtime.bridge.clearSessionWorktree === void 0 || runtime.bridge.severSessionClients === void 0) {
30529
+ throw new Error("Bridge does not support worktree reset");
30530
+ }
30531
+ const preRead = await readWorktreeSessionStrict(oldSidecarPath);
30532
+ if (preRead.state === "missing" || preRead.state === "valid" && preRead.session.workspaceCwd === void 0) {
30533
+ throw new WorktreeResetUnsupportedError(sessionId);
30534
+ }
30535
+ if (preRead.state !== "valid") {
30536
+ daemonLog?.warn("worktree reset rejected invalid sidecar", {
30537
+ sessionId,
30538
+ reason: preRead.reason
30539
+ });
30540
+ throw new WorktreeResetInvalidStateError(sessionId);
30541
+ }
30542
+ const preTarget = await resolveWorktreeOwnershipTarget(
30543
+ runtime,
30544
+ workspaceCwd,
30545
+ preRead.session,
30546
+ sessionId
30547
+ );
30548
+ const releaseOwnership = await acquireWorktreeOwnershipOp(
30549
+ preTarget.realTarget
30550
+ );
30551
+ try {
30552
+ const lockedRead = await readWorktreeSessionStrict(oldSidecarPath);
30553
+ if (lockedRead.state === "missing" || lockedRead.state === "valid" && lockedRead.session.workspaceCwd === void 0) {
30554
+ throw new WorktreeResetUnsupportedError(sessionId);
30555
+ }
30556
+ if (lockedRead.state !== "valid") {
30557
+ daemonLog?.warn("worktree reset rejected invalid sidecar", {
30558
+ sessionId,
30559
+ reason: lockedRead.reason
30560
+ });
30561
+ throw new WorktreeResetInvalidStateError(sessionId);
30562
+ }
30563
+ const oldSidecar = lockedRead.session;
30564
+ const { realTarget, candidateRoots } = await resolveWorktreeOwnershipTarget(
30565
+ runtime,
30566
+ workspaceCwd,
30567
+ oldSidecar,
30568
+ sessionId
30569
+ );
30570
+ if (realTarget !== preTarget.realTarget) {
30571
+ daemonLog?.warn("worktree reset rejected: sidecar moved", {
30572
+ sessionId
30573
+ });
30574
+ throw new WorktreeResetInvalidStateError(sessionId);
30575
+ }
30576
+ const readSummary = /* @__PURE__ */ __name((id) => {
30577
+ try {
30578
+ return runtime.bridge.getSessionSummary(id);
30579
+ } catch (error2) {
30580
+ if (error2 instanceof SessionNotFoundError) return void 0;
30581
+ throw error2;
30582
+ }
30583
+ }, "readSummary");
30584
+ runtime.bridge.setSessionResetPending(sessionId);
30585
+ let barrierArmed = true;
30586
+ try {
30587
+ let effectiveOldSidecar = oldSidecar;
30588
+ if (oldSidecar.supersededBy !== void 0) {
30589
+ const replacementId = oldSidecar.supersededBy;
30590
+ const newSidecarPath = sessionService.getWorktreeSessionPath(replacementId);
30591
+ const newRead = await readWorktreeSessionStrict(newSidecarPath);
30592
+ const linksAgree = newRead.state === "valid" && newRead.session.supersedes === storageSessionId;
30593
+ const marker = await readWorktreeSessionMarkerStrict(realTarget);
30594
+ if (marker.state === "invalid") {
30595
+ daemonLog?.warn("worktree reset resume rejected marker", {
30596
+ sessionId,
30597
+ reason: marker.reason
30598
+ });
30599
+ throw new WorktreeResetInvalidStateError(sessionId);
30600
+ }
30601
+ if (marker.state === "missing" || marker.state === "valid" && marker.sessionId === storageSessionId) {
30602
+ if (!linksAgree) {
30603
+ daemonLog?.warn(
30604
+ "worktree reset resume found inconsistent links",
30605
+ { sessionId, replacementSessionId: replacementId }
30606
+ );
30607
+ throw new WorktreeResetInvalidStateError(sessionId);
30608
+ }
30609
+ if (marker.state === "missing" && readSummary(replacementId) !== void 0) {
30610
+ daemonLog?.warn(
30611
+ "worktree reset resume found a live replacement with no marker",
30612
+ { sessionId, replacementSessionId: replacementId }
30613
+ );
30614
+ throw new WorktreeResetInvalidStateError(sessionId);
30615
+ }
30616
+ const { supersededBy: _drop, ...restoredOld } = oldSidecar;
30617
+ const removed = await runWithWorkspaceRuntimeStorage(
30618
+ runtime,
30619
+ () => deleteDaemonSessionIfOrphan({
30620
+ sessionId: replacementId,
30621
+ service: sessionService,
30622
+ bridge: runtime.bridge,
30623
+ coordinator: archiveCoordinator
30624
+ })
30625
+ ).catch(() => false);
30626
+ if (!removed) {
30627
+ daemonLog?.warn(
30628
+ "worktree reset could not remove the interrupted replacement",
30629
+ { sessionId, replacementSessionId: replacementId }
30630
+ );
30631
+ throw new WorktreeResetInvalidStateError(sessionId);
30632
+ }
30633
+ await clearWorktreeSession(newSidecarPath);
30634
+ await writeWorktreeSession(oldSidecarPath, restoredOld);
30635
+ daemonLog?.warn(
30636
+ "worktree reset rolled back an interrupted transfer",
30637
+ { sessionId, replacementSessionId: replacementId }
30638
+ );
30639
+ effectiveOldSidecar = restoredOld;
30640
+ } else if (marker.state === "valid" && marker.sessionId === replacementId) {
30641
+ barrierArmed = false;
30642
+ if (!linksAgree) {
30643
+ daemonLog?.warn(
30644
+ "worktree reset resume found inconsistent links",
30645
+ { sessionId, replacementSessionId: replacementId }
30646
+ );
30647
+ throw new WorktreeResetInvalidStateError(sessionId);
30648
+ }
30649
+ const newSummary = readSummary(replacementId);
30650
+ if (newSummary && (newSummary.hasActivePrompt || (newSummary.pendingInteractionCount ?? 0) > 0)) {
30651
+ throw new WorktreeResetActiveError(replacementId);
30652
+ }
30653
+ runtime.bridge.clearSessionWorktree(sessionId);
30654
+ const severCompleted = await runtime.bridge.severSessionClients(sessionId);
30655
+ if (severCompleted) {
30656
+ runtime.bridge.clearSessionResetPending(sessionId);
30657
+ } else {
30658
+ daemonLog?.warn(
30659
+ "worktree reset left the superseded session live",
30660
+ { sessionId, replacementSessionId: replacementId }
30661
+ );
30662
+ }
30663
+ assertRuntimeGenerationOpen?.();
30664
+ daemonLog?.info(
30665
+ "worktree session reset resumed after interruption",
30666
+ { sessionId, replacementSessionId: replacementId }
30667
+ );
30668
+ res.status(200).json({
30669
+ sessionId: replacementId,
30670
+ workspaceCwd,
30671
+ currentCwd: realTarget,
30672
+ worktree: {
30673
+ slug: oldSidecar.slug,
30674
+ path: realTarget,
30675
+ branch: oldSidecar.worktreeBranch
30676
+ },
30677
+ worktreeState: "persisted-v1",
30678
+ attached: false,
30679
+ ...severCompleted ? {} : { supersededSessionLive: true }
30680
+ });
30681
+ return;
30682
+ } else {
30683
+ daemonLog?.warn(
30684
+ "worktree reset resume found a marker naming another session",
30685
+ { sessionId }
30686
+ );
30687
+ throw new WorktreeResetInvalidStateError(sessionId);
30688
+ }
30689
+ }
30690
+ const oldSummary = readSummary(sessionId);
30691
+ if (oldSummary && (oldSummary.hasActivePrompt || (oldSummary.pendingInteractionCount ?? 0) > 0)) {
30692
+ throw new WorktreeResetActiveError(sessionId);
30693
+ }
30694
+ let spawnedNew;
30695
+ let newSidecarWritten = false;
30696
+ let oldSupersededWritten = false;
30697
+ let markerTransferred = false;
30698
+ try {
30699
+ assertRuntimeGenerationOpen?.();
30700
+ const spawned = await runtime.bridge.spawnOrAttach({
30701
+ workspaceCwd,
30702
+ modelServiceId,
30703
+ sessionScope: "thread",
30704
+ ...approvalMode !== void 0 ? { approvalMode } : {},
30705
+ ...source.sourceType !== void 0 ? { sourceType: source.sourceType } : {},
30706
+ ...source.sourceId !== void 0 ? { sourceId: source.sourceId } : {}
30707
+ });
30708
+ spawnedNew = { sessionId: spawned.sessionId };
30709
+ const changed = await runtime.bridge.changeSessionCwd(
30710
+ spawned.sessionId,
30711
+ { path: realTarget, allowedRoots: candidateRoots }
30712
+ );
30713
+ if (changed.newCwd !== realTarget) {
30714
+ throw new Error("Worktree relocation was rejected");
30715
+ }
30716
+ await writeWorktreeSession(oldSidecarPath, {
30717
+ ...effectiveOldSidecar,
30718
+ supersededBy: spawned.sessionId
30719
+ });
30720
+ oldSupersededWritten = true;
30721
+ const newSidecarPath = sessionService.getWorktreeSessionPath(
30722
+ spawned.sessionId
30723
+ );
30724
+ const {
30725
+ supersededBy: _dropOld,
30726
+ supersedes: _dropOldLink,
30727
+ ...oldSidecarCore
30728
+ } = effectiveOldSidecar;
30729
+ await writeWorktreeSession(newSidecarPath, {
30730
+ ...oldSidecarCore,
30731
+ supersedes: storageSessionId
30732
+ });
30733
+ newSidecarWritten = true;
30734
+ if (res.destroyed || res.socket?.writable === false) {
30735
+ throw new Error(
30736
+ "Client disconnected before the worktree ownership flip"
30737
+ );
30738
+ }
30739
+ const windingDown = readSummary(sessionId);
30740
+ if (windingDown && (windingDown.hasActivePrompt || (windingDown.pendingInteractionCount ?? 0) > 0)) {
30741
+ throw new WorktreeResetActiveError(sessionId);
30742
+ }
30743
+ const markerBeforeFlip = await readWorktreeSessionMarkerStrict(realTarget);
30744
+ try {
30745
+ await transferWorktreeSessionMarkerOwner(
30746
+ realTarget,
30747
+ markerBeforeFlip.state === "missing" ? null : storageSessionId,
30748
+ spawned.sessionId
30749
+ );
30750
+ } catch (markerError) {
30751
+ daemonLog?.warn("worktree marker transfer failed", {
30752
+ sessionId,
30753
+ replacementSessionId: spawned.sessionId,
30754
+ error: markerError instanceof Error ? markerError.message : String(markerError)
30755
+ });
30756
+ if (markerError instanceof WorktreeMarkerCommittedError) {
30757
+ markerTransferred = true;
30758
+ barrierArmed = false;
30759
+ throw new Error(
30760
+ "Worktree ownership moved to the replacement, but the marker commit did not finish cleanly; retry the reset to complete the transfer"
30761
+ );
30762
+ }
30763
+ throw new WorktreeResetInvalidStateError(sessionId);
30764
+ }
30765
+ markerTransferred = true;
30766
+ barrierArmed = false;
30767
+ const newWorktree = {
30768
+ slug: effectiveOldSidecar.slug,
30769
+ path: realTarget,
30770
+ branch: effectiveOldSidecar.worktreeBranch
30771
+ };
30772
+ runtime.bridge.setSessionWorktree(
30773
+ spawned.sessionId,
30774
+ newWorktree
30775
+ );
30776
+ assertRuntimeGenerationOpen?.();
30777
+ runtime.bridge.clearSessionWorktree(sessionId);
30778
+ const severCompleted = await runtime.bridge.severSessionClients(sessionId);
30779
+ if (severCompleted) {
30780
+ runtime.bridge.clearSessionResetPending(sessionId);
30781
+ } else {
30782
+ daemonLog?.warn(
30783
+ "worktree reset left the superseded session live",
30784
+ {
30785
+ sessionId,
30786
+ replacementSessionId: spawned.sessionId
30787
+ }
30788
+ );
30789
+ }
30790
+ daemonLog?.info("worktree session reset", {
30791
+ sessionId,
30792
+ replacementSessionId: spawned.sessionId
30793
+ });
30794
+ res.status(200).json({
30795
+ ...spawned,
30796
+ currentCwd: realTarget,
30797
+ worktree: newWorktree,
30798
+ worktreeState: "persisted-v1",
30799
+ ...severCompleted ? {} : { supersededSessionLive: true }
30800
+ });
30801
+ } catch (transferError) {
30802
+ if (markerTransferred) {
30803
+ daemonLog?.warn(
30804
+ "worktree reset failed after the ownership flip",
30805
+ {
30806
+ sessionId,
30807
+ replacementSessionId: spawnedNew?.sessionId,
30808
+ error: transferError instanceof Error ? transferError.message : String(transferError)
30809
+ }
30810
+ );
30811
+ throw transferError;
30812
+ }
30813
+ if (spawnedNew) {
30814
+ const orphanSessionId = spawnedNew.sessionId;
30815
+ const removed = await runWithWorkspaceRuntimeStorage(
30816
+ runtime,
30817
+ () => deleteDaemonSessionIfOrphan({
30818
+ sessionId: orphanSessionId,
30819
+ service: sessionService,
30820
+ bridge: runtime.bridge,
30821
+ coordinator: archiveCoordinator
30822
+ })
30823
+ ).catch(() => false);
30824
+ if (!removed) {
30825
+ daemonLog?.warn(
30826
+ "worktree reset could not remove the spawned replacement",
30827
+ { sessionId, replacementSessionId: orphanSessionId }
30828
+ );
30829
+ throw transferError;
30830
+ }
30831
+ }
30832
+ if (newSidecarWritten && spawnedNew) {
30833
+ await clearWorktreeSession(
30834
+ sessionService.getWorktreeSessionPath(spawnedNew.sessionId)
30835
+ );
30836
+ }
30837
+ if (oldSupersededWritten) {
30838
+ await writeWorktreeSession(
30839
+ oldSidecarPath,
30840
+ effectiveOldSidecar
30841
+ );
30842
+ }
30843
+ throw transferError;
30844
+ }
30845
+ } finally {
30846
+ if (barrierArmed) {
30847
+ runtime.bridge.clearSessionResetPending(sessionId);
30848
+ }
30849
+ }
30850
+ } finally {
30851
+ releaseOwnership();
30852
+ }
30853
+ })
30854
+ );
30855
+ } catch (err) {
30856
+ if (!res.headersSent) {
30857
+ sendBridgeError2(res, err, { route, sessionId });
30858
+ }
30859
+ }
30860
+ }, "worktreeResetHandler");
30861
+ app.post("/session/:id/worktree-reset", mutate(), worktreeResetHandler);
30753
30862
  app.get("/session/:id/subagents/:subagentRef", async (req, res) => {
30754
30863
  const route = "GET /session/:id/subagents/:subagentRef";
30755
30864
  const sessionId = requireSessionId(req, res);
@@ -31018,7 +31127,7 @@ function registerSessionRoutes(app, deps) {
31018
31127
  async (req, res, sessionId, runtime) => {
31019
31128
  const body = safeBody(req);
31020
31129
  const targetPath = body["path"];
31021
- if (typeof targetPath !== "string" || targetPath.length === 0 || !path12.isAbsolute(targetPath)) {
31130
+ if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
31022
31131
  res.status(400).json({
31023
31132
  error: "`path` is required and must be an absolute path",
31024
31133
  code: "invalid_path"
@@ -33486,6 +33595,7 @@ function registerSessionRoutes(app, deps) {
33486
33595
  sessionId: session.sessionId,
33487
33596
  clientCount: session.clientCount,
33488
33597
  hasActivePrompt: session.hasActivePrompt,
33598
+ ...session.activeWorkState !== void 0 ? { activeWorkState: session.activeWorkState } : {},
33489
33599
  isWaitingForPermission: session.isWaitingForPermission ?? false,
33490
33600
  isWaitingForUserQuestion: session.isWaitingForUserQuestion ?? false,
33491
33601
  // Bridge-local activity watermark, absent until a running prompt in
@@ -34011,6 +34121,7 @@ function registerSessionRoutes(app, deps) {
34011
34121
  const body = safeBody(req);
34012
34122
  const mode = body["mode"];
34013
34123
  const persist = body["persist"];
34124
+ const planMode = body["planMode"];
34014
34125
  if (typeof mode !== "string" || !APPROVAL_MODES.includes(mode)) {
34015
34126
  res.status(400).json({
34016
34127
  error: "`mode` is required and must be one of the allowed values",
@@ -34026,12 +34137,22 @@ function registerSessionRoutes(app, deps) {
34026
34137
  });
34027
34138
  return;
34028
34139
  }
34140
+ if (planMode !== void 0 && (typeof planMode !== "boolean" || mode === "plan")) {
34141
+ res.status(400).json({
34142
+ error: "`planMode` must be a boolean with a non-plan execution mode",
34143
+ code: "invalid_plan_mode"
34144
+ });
34145
+ return;
34146
+ }
34029
34147
  const clientId = parseClientIdHeader(req, res);
34030
34148
  if (clientId === null) return;
34031
34149
  const response = await runtime.bridge.setSessionApprovalMode(
34032
34150
  sessionId,
34033
34151
  mode,
34034
- { persist: persist === true },
34152
+ {
34153
+ persist: persist === true,
34154
+ ...typeof planMode === "boolean" ? { planMode } : {}
34155
+ },
34035
34156
  clientId !== void 0 ? { clientId } : void 0
34036
34157
  );
34037
34158
  res.status(200).json(response);
@@ -34083,8 +34204,8 @@ __name(registerSessionRoutes, "registerSessionRoutes");
34083
34204
  // packages/cli/src/serve/routes/session-pr-backfill.ts
34084
34205
  init_esbuild_shims();
34085
34206
  import { existsSync } from "node:fs";
34086
- import * as fs8 from "node:fs/promises";
34087
- import * as path13 from "node:path";
34207
+ import * as fs7 from "node:fs/promises";
34208
+ import * as path12 from "node:path";
34088
34209
  var SLUG_PR_PATTERN = /^pr-([1-9]\d{0,8})$/;
34089
34210
  var BRANCH_PR_PATTERN = /^worktree-pr-([1-9]\d{0,8})$/;
34090
34211
  function parsePrNumberFromWorktree(slug, branch) {
@@ -34173,7 +34294,7 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
34173
34294
  for (const sessionId of sessionIds) {
34174
34295
  if (!isValidSessionId(sessionId)) continue;
34175
34296
  result.scanned += 1;
34176
- const dir = path13.dirname(
34297
+ const dir = path12.dirname(
34177
34298
  sessionService.getWorktreeSessionPathForArchiveState(
34178
34299
  sessionId,
34179
34300
  archiveState
@@ -34182,15 +34303,15 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
34182
34303
  let worktree;
34183
34304
  try {
34184
34305
  worktree = await readWorktreeSession(
34185
- path13.join(dir, `${sessionId}.worktree.json`)
34306
+ path12.join(dir, `${sessionId}.worktree.json`)
34186
34307
  );
34187
34308
  } catch {
34188
34309
  worktree = null;
34189
34310
  }
34190
34311
  let transcriptRaw;
34191
34312
  try {
34192
- transcriptRaw = await fs8.readFile(
34193
- path13.join(dir, `${sessionId}.jsonl`),
34313
+ transcriptRaw = await fs7.readFile(
34314
+ path12.join(dir, `${sessionId}.jsonl`),
34194
34315
  "utf8"
34195
34316
  );
34196
34317
  } catch {
@@ -34210,7 +34331,7 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
34210
34331
  candidates.push({
34211
34332
  sessionId,
34212
34333
  archiveState,
34213
- transcriptPath: path13.join(dir, `${sessionId}.jsonl`),
34334
+ transcriptPath: path12.join(dir, `${sessionId}.jsonl`),
34214
34335
  conventionNumber,
34215
34336
  mentions: reviewed.mentions,
34216
34337
  reviewedUrlForms: reviewed.reviewedUrlForms
@@ -34342,8 +34463,8 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
34342
34463
  candidate.sessionId,
34343
34464
  archiveState
34344
34465
  );
34345
- const transcriptPath = path13.join(
34346
- path13.dirname(prPath),
34466
+ const transcriptPath = path12.join(
34467
+ path12.dirname(prPath),
34347
34468
  `${candidate.sessionId}.jsonl`
34348
34469
  );
34349
34470
  const snapshotAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -34986,7 +35107,7 @@ __name(registerStandaloneSessionRoutes, "registerStandaloneSessionRoutes");
34986
35107
 
34987
35108
  // packages/cli/src/serve/routes/channel-notify.ts
34988
35109
  init_esbuild_shims();
34989
- import { randomUUID as randomUUID10 } from "node:crypto";
35110
+ import { randomUUID as randomUUID9 } from "node:crypto";
34990
35111
  function sendDeliveryError(res, error2) {
34991
35112
  if (!isChannelDeliveryError(error2)) {
34992
35113
  res.status(502).json({
@@ -35007,7 +35128,7 @@ function parseNotifyBody(body) {
35007
35128
  );
35008
35129
  }
35009
35130
  return normalizeChannelDelivery(
35010
- randomUUID10(),
35131
+ randomUUID9(),
35011
35132
  parseChannelDelivery(body["delivery"]),
35012
35133
  body["text"]
35013
35134
  );
@@ -35210,7 +35331,7 @@ __name(registerUsageStatsRoutes, "registerUsageStatsRoutes");
35210
35331
  // packages/cli/src/serve/scheduled-task-keepalive.ts
35211
35332
  init_esbuild_shims();
35212
35333
  import * as fsSync from "node:fs";
35213
- import * as path14 from "node:path";
35334
+ import * as path13 from "node:path";
35214
35335
  var log = createDebugLogger("SCHED_KEEPALIVE");
35215
35336
  function collectBoundSessionIds(tasks) {
35216
35337
  const seen = /* @__PURE__ */ new Set();
@@ -35442,8 +35563,8 @@ function startScheduledTaskKeepalive(opts) {
35442
35563
  opts.runtimeBaseDir,
35443
35564
  () => getCronFilePath(boundWorkspace)
35444
35565
  );
35445
- const cronDir = path14.dirname(cronFilePath);
35446
- const cronFileName = path14.basename(cronFilePath);
35566
+ const cronDir = path13.dirname(cronFilePath);
35567
+ const cronFileName = path13.basename(cronFilePath);
35447
35568
  let fileWatcher;
35448
35569
  try {
35449
35570
  fsSync.mkdirSync(cronDir, { recursive: true });
@@ -36166,6 +36287,10 @@ function workflowsEnabledForRuntime(runtime, daemonEnv) {
36166
36287
  }
36167
36288
  __name(workflowsEnabledForRuntime, "workflowsEnabledForRuntime");
36168
36289
  function registerCapabilitiesRoutes(app, deps) {
36290
+ const configuredPollIntervalMs = Number(
36291
+ deps.daemonEnv["QWEN_SESSION_LIVE_STATE_POLL_INTERVAL_MS"]
36292
+ );
36293
+ const sessionLiveStatePollIntervalMs = Number.isSafeInteger(configuredPollIntervalMs) && configuredPollIntervalMs >= 1e3 && configuredPollIntervalMs <= 2147483647 ? configuredPollIntervalMs : 5e3;
36169
36294
  app.get("/capabilities", (_req, res) => {
36170
36295
  const entries = deps.workspaceRegistry.listAllEntries().filter(
36171
36296
  (entry) => !entry.internal || entry.state === "active" && entry.current !== void 0
@@ -36182,6 +36307,7 @@ function registerCapabilitiesRoutes(app, deps) {
36182
36307
  ...deps.qwenCodeVersion ? { qwenCodeVersion: deps.qwenCodeVersion } : {},
36183
36308
  mode: deps.mode,
36184
36309
  features,
36310
+ sessionLiveStatePollIntervalMs,
36185
36311
  modelServices: [],
36186
36312
  // Surface the primary workspace so clients can omit `cwd` on
36187
36313
  // `POST /session`; multi-workspace clients use `workspaces[]`.
@@ -37242,7 +37368,7 @@ __name(registerUserLanguageRoutes, "registerUserLanguageRoutes");
37242
37368
 
37243
37369
  // packages/cli/src/serve/routes/sse-events.ts
37244
37370
  init_esbuild_shims();
37245
- import { randomUUID as randomUUID11 } from "node:crypto";
37371
+ import { randomUUID as randomUUID10 } from "node:crypto";
37246
37372
  import { performance as performance3 } from "node:perf_hooks";
37247
37373
 
37248
37374
  // packages/cli/src/serve/server/error-response.ts
@@ -37623,6 +37749,63 @@ function sendBridgeError(res, err, ctx, daemonLog) {
37623
37749
  });
37624
37750
  return;
37625
37751
  }
37752
+ if (err instanceof SessionResetPendingError) {
37753
+ res.status(409).json({
37754
+ error: err.message,
37755
+ code: "worktree_reset_active",
37756
+ sessionId: err.sessionId
37757
+ });
37758
+ return;
37759
+ }
37760
+ if (err instanceof WorktreeSessionSupersededError) {
37761
+ res.status(409).json({
37762
+ error: err.message,
37763
+ code: "worktree_session_superseded",
37764
+ sessionId: err.sessionId,
37765
+ replacementSessionId: err.replacementSessionId
37766
+ });
37767
+ return;
37768
+ }
37769
+ if (err instanceof WorktreeMarkerMissingError) {
37770
+ res.status(409).json({
37771
+ error: err.message,
37772
+ code: "worktree_marker_missing",
37773
+ sessionId: err.sessionId
37774
+ });
37775
+ return;
37776
+ }
37777
+ if (err instanceof WorktreeResetInterruptedError) {
37778
+ res.status(409).json({
37779
+ error: err.message,
37780
+ code: "worktree_reset_interrupted",
37781
+ sessionId: err.sessionId
37782
+ });
37783
+ return;
37784
+ }
37785
+ if (err instanceof WorktreeResetActiveError) {
37786
+ res.status(409).json({
37787
+ error: err.message,
37788
+ code: "worktree_reset_active",
37789
+ sessionId: err.sessionId
37790
+ });
37791
+ return;
37792
+ }
37793
+ if (err instanceof WorktreeResetUnsupportedError) {
37794
+ res.status(409).json({
37795
+ error: err.message,
37796
+ code: "worktree_reset_unsupported",
37797
+ sessionId: err.sessionId
37798
+ });
37799
+ return;
37800
+ }
37801
+ if (err instanceof WorktreeResetInvalidStateError) {
37802
+ res.status(409).json({
37803
+ error: err.message,
37804
+ code: "worktree_reset_invalid_state",
37805
+ sessionId: err.sessionId
37806
+ });
37807
+ return;
37808
+ }
37626
37809
  if (err instanceof TrustGateError) {
37627
37810
  res.status(403).json({
37628
37811
  error: err.message,
@@ -38088,7 +38271,7 @@ function registerSseEventsRoutes(app, deps) {
38088
38271
  app.get("/session/:id/events", async (req, res) => {
38089
38272
  const sessionId = req.params["id"];
38090
38273
  const diagnosticSessionId = boundedDiagnosticString(sessionId);
38091
- const streamId = randomUUID11();
38274
+ const streamId = randomUUID10();
38092
38275
  const clientId = parseSseClientId(req.headers["x-qwen-client-id"]);
38093
38276
  const connectReason = parseSseConnectReason(req.query["connectReason"]);
38094
38277
  const previousStreamId = parsePreviousSseStreamId(
@@ -38116,6 +38299,8 @@ function registerSseEventsRoutes(app, deps) {
38116
38299
  }, "emitLifecycleLog");
38117
38300
  let slowWarningCount = 0;
38118
38301
  let eventBusEvictionReason;
38302
+ let closeReason;
38303
+ let terminalEventType;
38119
38304
  const onSubscriberDiagnostic = /* @__PURE__ */ __name((diagnostic) => {
38120
38305
  const triggerEventType = boundedDiagnosticString(
38121
38306
  diagnostic.data.triggerEventType
@@ -38212,6 +38397,22 @@ function registerSseEventsRoutes(app, deps) {
38212
38397
  } : {}
38213
38398
  }
38214
38399
  );
38400
+ closeReason = "event_bus_evicted";
38401
+ terminalEventType = "client_evicted";
38402
+ const evictionData = { ...diagnostic.data };
38403
+ Reflect.deleteProperty(evictionData, "triggerEventType");
38404
+ Reflect.deleteProperty(evictionData, "triggerEventBytes");
38405
+ try {
38406
+ res.write(
38407
+ formatSseFrame({
38408
+ v: 1,
38409
+ type: "client_evicted",
38410
+ data: evictionData
38411
+ })
38412
+ );
38413
+ } catch {
38414
+ }
38415
+ res.destroy();
38215
38416
  }
38216
38417
  return handled;
38217
38418
  }, "onSubscriberDiagnostic");
@@ -38297,9 +38498,7 @@ function registerSseEventsRoutes(app, deps) {
38297
38498
  return;
38298
38499
  }
38299
38500
  const openedAt = performance3.now();
38300
- let closeReason;
38301
38501
  let terminalCandidate;
38302
- let terminalEventType;
38303
38502
  let eventFramesWriteSettled = 0;
38304
38503
  let lastEventIdWritten;
38305
38504
  let backpressureCount = 0;
@@ -38693,7 +38892,7 @@ function registerSseEventsRoutes(app, deps) {
38693
38892
  }
38694
38893
  } finally {
38695
38894
  cleanup();
38696
- if (!res.writableEnded) res.end();
38895
+ if (!res.destroyed && !res.writableEnded) res.end();
38697
38896
  }
38698
38897
  })();
38699
38898
  });
@@ -38980,7 +39179,7 @@ __name(registerWorkspaceModelsRoutes, "registerWorkspaceModelsRoutes");
38980
39179
  // packages/cli/src/serve/routes/a2ui-action.ts
38981
39180
  init_esbuild_shims();
38982
39181
  import * as fsp4 from "node:fs/promises";
38983
- import * as path15 from "node:path";
39182
+ import * as path14 from "node:path";
38984
39183
  var A2UI_MIME = "application/a2ui+json";
38985
39184
  var ACTION_TOOL = "action";
38986
39185
  var CALL_TIMEOUT_MS = 15e3;
@@ -39003,7 +39202,7 @@ __name(usableServerConfig, "usableServerConfig");
39003
39202
  async function findFromSettingsFile(workspaceCwd) {
39004
39203
  try {
39005
39204
  const raw = await fsp4.readFile(
39006
- path15.join(workspaceCwd, ".qwen", "settings.json"),
39205
+ path14.join(workspaceCwd, ".qwen", "settings.json"),
39007
39206
  "utf8"
39008
39207
  );
39009
39208
  const settings = JSON.parse(raw);
@@ -39164,7 +39363,7 @@ __name(registerA2uiActionRoutes, "registerA2uiActionRoutes");
39164
39363
 
39165
39364
  // packages/cli/src/serve/server/fs-factory.ts
39166
39365
  init_esbuild_shims();
39167
- import * as path16 from "node:path";
39366
+ import * as path15 from "node:path";
39168
39367
  var IDE_WORKSPACE_PATH_ENV_VAR = "QWEN_CODE_IDE_WORKSPACE_PATH";
39169
39368
  var NEW_FILE_MODE_ENV_VAR = "QWEN_SERVE_NEW_FILE_MODE";
39170
39369
  function parseNewFileModePolicy(env = process.env) {
@@ -39253,14 +39452,14 @@ function parseIdeWorkspacePathEnv(value) {
39253
39452
  const parsed = JSON.parse(value);
39254
39453
  if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
39255
39454
  return parsed.filter(
39256
- (workspace) => workspace.length > 0 && path16.isAbsolute(workspace)
39455
+ (workspace) => workspace.length > 0 && path15.isAbsolute(workspace)
39257
39456
  );
39258
39457
  }
39259
39458
  throw new Error("IDE workspace path JSON must be a string array");
39260
39459
  } catch {
39261
39460
  }
39262
39461
  }
39263
- return value.split(path16.delimiter).filter((workspace) => workspace.length > 0 && path16.isAbsolute(workspace));
39462
+ return value.split(path15.delimiter).filter((workspace) => workspace.length > 0 && path15.isAbsolute(workspace));
39264
39463
  }
39265
39464
  __name(parseIdeWorkspacePathEnv, "parseIdeWorkspacePathEnv");
39266
39465
  function dropNestedWorkspacesPreservingPrimary(workspaces) {
@@ -39749,7 +39948,7 @@ __name(registerWorkspaceQualifiedLifecycleRoutes, "registerWorkspaceQualifiedLif
39749
39948
  init_esbuild_shims();
39750
39949
  import { readdir as readdir3, stat as stat2 } from "node:fs/promises";
39751
39950
  import { realpathSync as realpathSync2 } from "node:fs";
39752
- import { basename as basename7, dirname as dirname9, isAbsolute as isAbsolute10, join as join12, resolve as resolve5, sep as sep4 } from "node:path";
39951
+ import { basename as basename7, dirname as dirname8, isAbsolute as isAbsolute9, join as join11, resolve as resolve5, sep as sep4 } from "node:path";
39753
39952
  var MAX_PATH_SUGGESTIONS = 50;
39754
39953
  function registerWorkspaceManagementRoutes(app, deps) {
39755
39954
  const {
@@ -40138,7 +40337,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
40138
40337
  });
40139
40338
  return;
40140
40339
  }
40141
- if (!isAbsolute10(prefix)) {
40340
+ if (!isAbsolute9(prefix)) {
40142
40341
  res.status(400).json({
40143
40342
  error: "`prefix` must be an absolute path",
40144
40343
  code: "invalid_prefix"
@@ -40146,7 +40345,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
40146
40345
  return;
40147
40346
  }
40148
40347
  const endsWithSep = prefix.endsWith("/") || process.platform === "win32" && prefix.endsWith("\\");
40149
- const dir = endsWithSep ? join12(prefix, ".") : dirname9(prefix);
40348
+ const dir = endsWithSep ? join11(prefix, ".") : dirname8(prefix);
40150
40349
  const filter = endsWithSep ? "" : basename7(prefix);
40151
40350
  const filterLower = filter.toLowerCase();
40152
40351
  const suggestions = [];
@@ -40162,7 +40361,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
40162
40361
  let isDir = entry.isDirectory();
40163
40362
  if (!isDir && entry.isSymbolicLink()) {
40164
40363
  try {
40165
- isDir = (await stat2(join12(dir, entry.name))).isDirectory();
40364
+ isDir = (await stat2(join11(dir, entry.name))).isDirectory();
40166
40365
  } catch {
40167
40366
  continue;
40168
40367
  }
@@ -40172,7 +40371,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
40172
40371
  truncated = true;
40173
40372
  break;
40174
40373
  }
40175
- suggestions.push({ name: entry.name, path: join12(dir, entry.name) });
40374
+ suggestions.push({ name: entry.name, path: join11(dir, entry.name) });
40176
40375
  }
40177
40376
  } catch {
40178
40377
  }
@@ -45646,7 +45845,7 @@ init_esbuild_shims();
45646
45845
 
45647
45846
  // packages/cli/src/serve/live/live-host-coordinator.ts
45648
45847
  init_esbuild_shims();
45649
- import { randomUUID as randomUUID12, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
45848
+ import { randomUUID as randomUUID11, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
45650
45849
  var DEFAULT_HELLO_TIMEOUT_MS = 5e3;
45651
45850
  var DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
45652
45851
  var DEFAULT_HEARTBEAT_TIMEOUT_MS = 15e3;
@@ -45829,7 +46028,7 @@ __name(projectStatusForHost, "projectStatusForHost");
45829
46028
  var LiveHostCoordinator = class {
45830
46029
  constructor(options) {
45831
46030
  this.options = options;
45832
- this.daemonInstanceNonce = options.daemonInstanceNonce ?? randomUUID12();
46031
+ this.daemonInstanceNonce = options.daemonInstanceNonce ?? randomUUID11();
45833
46032
  this.handlers = options.handlers ?? {};
45834
46033
  this.now = options.now ?? Date.now;
45835
46034
  this.helloTimeoutMs = options.helloTimeoutMs ?? DEFAULT_HELLO_TIMEOUT_MS;
@@ -45860,6 +46059,7 @@ var LiveHostCoordinator = class {
45860
46059
  };
45861
46060
  call;
45862
46061
  pendingStartMode;
46062
+ actionGeneration = 0;
45863
46063
  nextEpoch = 0;
45864
46064
  inputMuted = false;
45865
46065
  outputMuted = false;
@@ -45880,6 +46080,7 @@ var LiveHostCoordinator = class {
45880
46080
  return this.getStatus();
45881
46081
  }
45882
46082
  async deactivate() {
46083
+ ++this.actionGeneration;
45883
46084
  this.pendingStartMode = void 0;
45884
46085
  if (this.call) {
45885
46086
  const stopped = new Promise((resolve7) => {
@@ -45995,6 +46196,18 @@ var LiveHostCoordinator = class {
45995
46196
  } : {}
45996
46197
  };
45997
46198
  }
46199
+ async requestStart(mode) {
46200
+ const generation = ++this.actionGeneration;
46201
+ this.pendingStartMode = void 0;
46202
+ try {
46203
+ await this.handlers.beforeStart?.();
46204
+ } catch (error2) {
46205
+ if (generation !== this.actionGeneration) return this.getStatus();
46206
+ throw error2;
46207
+ }
46208
+ if (generation !== this.actionGeneration) return this.getStatus();
46209
+ return this.start(mode).status;
46210
+ }
45998
46211
  start(mode) {
45999
46212
  const status = this.getStatus();
46000
46213
  if (!status.available) throw new LiveUnavailableError(status);
@@ -46021,7 +46234,7 @@ var LiveHostCoordinator = class {
46021
46234
  startCall(mode) {
46022
46235
  const call = {
46023
46236
  epoch: ++this.nextEpoch,
46024
- callId: randomUUID12(),
46237
+ callId: randomUUID11(),
46025
46238
  mode,
46026
46239
  state: "starting",
46027
46240
  pendingPermission: false,
@@ -46046,6 +46259,7 @@ var LiveHostCoordinator = class {
46046
46259
  return { epoch: call.epoch, callId: call.callId, status: this.getStatus() };
46047
46260
  }
46048
46261
  stop() {
46262
+ ++this.actionGeneration;
46049
46263
  this.pendingStartMode = void 0;
46050
46264
  if (this.call) this.beginCallStop(this.call);
46051
46265
  return this.getStatus();
@@ -46080,7 +46294,7 @@ var LiveHostCoordinator = class {
46080
46294
  new Error("Qwen Live Host must be connected to change the shortcut.")
46081
46295
  );
46082
46296
  }
46083
- const requestId = randomUUID12();
46297
+ const requestId = randomUUID11();
46084
46298
  return new Promise((resolve7, reject) => {
46085
46299
  const timer = setTimeout(() => {
46086
46300
  this.rejectPendingShortcut(
@@ -46170,7 +46384,7 @@ var LiveHostCoordinator = class {
46170
46384
  )
46171
46385
  );
46172
46386
  }
46173
- const requestId = randomUUID12();
46387
+ const requestId = randomUUID11();
46174
46388
  return new Promise((resolve7, reject) => {
46175
46389
  const timer = setTimeout(() => {
46176
46390
  this.pendingAppshots.delete(requestId);
@@ -46235,6 +46449,7 @@ var LiveHostCoordinator = class {
46235
46449
  this.sendHost({ type: "host.clear_output", epoch });
46236
46450
  }
46237
46451
  dispose() {
46452
+ ++this.actionGeneration;
46238
46453
  this.pendingStartMode = void 0;
46239
46454
  if (this.call) this.finishCall(this.call);
46240
46455
  if (this.host) {
@@ -46459,19 +46674,14 @@ var LiveHostCoordinator = class {
46459
46674
  }
46460
46675
  }
46461
46676
  startFromHost(mode) {
46462
- try {
46463
- this.start(mode);
46464
- } catch (error2) {
46677
+ void this.requestStart(mode).catch((error2) => {
46465
46678
  if (error2 instanceof LiveUnavailableError) {
46466
46679
  this.sendState(error2.status);
46467
46680
  return;
46468
46681
  }
46469
- this.sendState({
46470
- ...this.getStatus(),
46471
- state: "error",
46472
- message: "Live Voice failed to start."
46473
- });
46474
- }
46682
+ this.lastCallError = error2 instanceof ConversationRuntimeOwnershipError ? error2.message : "Live Voice failed to start.";
46683
+ this.sendState(this.buildStatus(false));
46684
+ });
46475
46685
  }
46476
46686
  handleAudioFrame(lease, data) {
46477
46687
  if (!lease.hello) {
@@ -46513,7 +46723,7 @@ var LiveHostCoordinator = class {
46513
46723
  this.disconnectHost(lease, 4008, "Live Host heartbeat timed out.");
46514
46724
  return;
46515
46725
  }
46516
- const pingId = randomUUID12();
46726
+ const pingId = randomUUID11();
46517
46727
  lease.pingId = pingId;
46518
46728
  this.sendHost({ type: "host.ping", pingId });
46519
46729
  }
@@ -46598,9 +46808,10 @@ var LiveHostCoordinator = class {
46598
46808
  this.broadcastState();
46599
46809
  }
46600
46810
  stopForReadinessLoss() {
46811
+ ++this.actionGeneration;
46812
+ this.pendingStartMode = void 0;
46601
46813
  const call = this.call;
46602
46814
  if (!call) return;
46603
- this.pendingStartMode = void 0;
46604
46815
  this.beginCallStop(call);
46605
46816
  }
46606
46817
  disconnectHost(lease, code, reason) {
@@ -46694,8 +46905,7 @@ function registerLiveRoutes(app, deps) {
46694
46905
  });
46695
46906
  app.post("/live/start", deps.mutate(), async (_req, res) => {
46696
46907
  try {
46697
- await deps.ensureRuntimeReady?.();
46698
- res.status(200).json(deps.coordinator.start("resume").status);
46908
+ res.status(200).json(await deps.coordinator.requestStart("resume"));
46699
46909
  } catch (error2) {
46700
46910
  if (sendUnavailable(res, error2)) return;
46701
46911
  throw error2;
@@ -46703,8 +46913,7 @@ function registerLiveRoutes(app, deps) {
46703
46913
  });
46704
46914
  app.post("/live/new", deps.mutate(), async (_req, res) => {
46705
46915
  try {
46706
- await deps.ensureRuntimeReady?.();
46707
- res.status(200).json(deps.coordinator.start("new").status);
46916
+ res.status(200).json(await deps.coordinator.requestStart("new"));
46708
46917
  } catch (error2) {
46709
46918
  if (sendUnavailable(res, error2)) return;
46710
46919
  throw error2;
@@ -46781,7 +46990,7 @@ init_esbuild_shims();
46781
46990
 
46782
46991
  // packages/cli/src/serve/live/live-setup-controller.ts
46783
46992
  init_esbuild_shims();
46784
- import { randomUUID as randomUUID14 } from "node:crypto";
46993
+ import { randomUUID as randomUUID13 } from "node:crypto";
46785
46994
 
46786
46995
  // packages/cli/src/serve/live/provider-credentials.ts
46787
46996
  init_esbuild_shims();
@@ -46879,7 +47088,7 @@ __name(resolveLiveProviderCredential, "resolveLiveProviderCredential");
46879
47088
 
46880
47089
  // packages/cli/src/serve/live/qwen-realtime-session.ts
46881
47090
  init_esbuild_shims();
46882
- import { randomUUID as randomUUID13 } from "node:crypto";
47091
+ import { randomUUID as randomUUID12 } from "node:crypto";
46883
47092
  var QWEN_REALTIME_LIMITS = {
46884
47093
  maxInputAudioFrameBytes: 64 * 1024,
46885
47094
  maxOutputAudioFrameBytes: 256 * 1024,
@@ -47294,7 +47503,7 @@ function openQwenRealtimeSession(config, callbacks = {}, deps = {}) {
47294
47503
  const sendJson = /* @__PURE__ */ __name((body) => {
47295
47504
  if (terminal || closedByClient || ws.readyState !== ws.OPEN) return false;
47296
47505
  try {
47297
- ws.send(JSON.stringify({ event_id: randomUUID13(), ...body }));
47506
+ ws.send(JSON.stringify({ event_id: randomUUID12(), ...body }));
47298
47507
  return true;
47299
47508
  } catch (error2) {
47300
47509
  fail(
@@ -48657,7 +48866,7 @@ async function validateCredential(credential) {
48657
48866
  apiKey: credential.apiKey,
48658
48867
  model: credential.realtimeModel,
48659
48868
  voice: credential.voice,
48660
- callEpoch: `setup-${randomUUID14()}`
48869
+ callEpoch: `setup-${randomUUID13()}`
48661
48870
  });
48662
48871
  session.close({ discardPendingInput: true });
48663
48872
  }
@@ -48964,11 +49173,11 @@ __name(registerLiveSetupRoutes, "registerLiveSetupRoutes");
48964
49173
  // packages/cli/src/serve/live/live-host-installer.ts
48965
49174
  init_esbuild_shims();
48966
49175
  import { execFile as execFile2 } from "node:child_process";
48967
- import { createHash as createHash4, randomUUID as randomUUID15 } from "node:crypto";
48968
- import * as fs9 from "node:fs";
49176
+ import { createHash as createHash4, randomUUID as randomUUID14 } from "node:crypto";
49177
+ import * as fs8 from "node:fs";
48969
49178
  import * as fsp5 from "node:fs/promises";
48970
49179
  import * as os2 from "node:os";
48971
- import * as path17 from "node:path";
49180
+ import * as path16 from "node:path";
48972
49181
  import { Readable, Transform } from "node:stream";
48973
49182
  import { pipeline } from "node:stream/promises";
48974
49183
  import { promisify as promisify2 } from "node:util";
@@ -49048,7 +49257,7 @@ async function readBundleValue(appPath, key) {
49048
49257
  "raw",
49049
49258
  "-o",
49050
49259
  "-",
49051
- path17.join(appPath, "Contents", "Info.plist")
49260
+ path16.join(appPath, "Contents", "Info.plist")
49052
49261
  ]);
49053
49262
  }
49054
49263
  __name(readBundleValue, "readBundleValue");
@@ -49156,7 +49365,7 @@ async function downloadAsset(asset, url, destination, onProgress, fetchImpl) {
49156
49365
  await pipeline(
49157
49366
  Readable.fromWeb(response.body),
49158
49367
  guard,
49159
- fs9.createWriteStream(destination, { flags: "wx", mode: 384 })
49368
+ fs8.createWriteStream(destination, { flags: "wx", mode: 384 })
49160
49369
  );
49161
49370
  if (received !== asset.size || hash.digest("hex") !== asset.sha256) {
49162
49371
  throw new Error("Live Host checksum verification failed.");
@@ -49190,13 +49399,13 @@ async function downloadLiveHostRelease(currentArchitecture, destination, onProgr
49190
49399
  __name(downloadLiveHostRelease, "downloadLiveHostRelease");
49191
49400
  async function installLatestHost(currentArchitecture, onStatus) {
49192
49401
  const temporaryDirectory = await fsp5.mkdtemp(
49193
- path17.join(os2.tmpdir(), "qwen-live-host-")
49402
+ path16.join(os2.tmpdir(), "qwen-live-host-")
49194
49403
  );
49195
- const archivePath = path17.join(temporaryDirectory, "Qwen-Live-Host.zip");
49196
- const extractedPath = path17.join(temporaryDirectory, "extracted");
49197
- const candidatePath = path17.join(extractedPath, LIVE_HOST_APP_NAME);
49198
- const stagingPath = `/Applications/.Qwen Live Host.install-${randomUUID15()}.app`;
49199
- const backupPath = `/Applications/.Qwen Live Host.backup-${randomUUID15()}.app`;
49404
+ const archivePath = path16.join(temporaryDirectory, "Qwen-Live-Host.zip");
49405
+ const extractedPath = path16.join(temporaryDirectory, "extracted");
49406
+ const candidatePath = path16.join(extractedPath, LIVE_HOST_APP_NAME);
49407
+ const stagingPath = `/Applications/.Qwen Live Host.install-${randomUUID14()}.app`;
49408
+ const backupPath = `/Applications/.Qwen Live Host.backup-${randomUUID14()}.app`;
49200
49409
  let movedExisting = false;
49201
49410
  let installedCandidate = false;
49202
49411
  try {
@@ -49347,15 +49556,15 @@ var LiveHostInstaller = class {
49347
49556
 
49348
49557
  // packages/cli/src/serve/live/live-session-coordinator.ts
49349
49558
  init_esbuild_shims();
49350
- import { createHash as createHash5, randomUUID as randomUUID16 } from "node:crypto";
49559
+ import { createHash as createHash5, randomUUID as randomUUID15 } from "node:crypto";
49351
49560
  import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync2 } from "node:fs";
49352
- import { join as join15 } from "node:path";
49561
+ import { join as join14 } from "node:path";
49353
49562
 
49354
49563
  // packages/cli/src/serve/live/realtime-startup-context.ts
49355
49564
  init_esbuild_shims();
49356
49565
  import { readdirSync } from "node:fs";
49357
49566
  import { homedir } from "node:os";
49358
- import { basename as basename8, join as join14 } from "node:path";
49567
+ import { basename as basename8, join as join13 } from "node:path";
49359
49568
  var STARTUP_CONTEXT_HEADER = "Startup context from Qwen Code.\nThis is background context about recent work and machine/workspace layout. It may be incomplete or stale. Use it to inform responses, and do not repeat it back unless relevant.";
49360
49569
  var CURRENT_THREAD_SECTION_TOKEN_BUDGET = 1200;
49361
49570
  var RECENT_WORK_SECTION_TOKEN_BUDGET = 2200;
@@ -49597,7 +49806,7 @@ function collectTreeLines(directory, depth, lines) {
49597
49806
  const indent = " ".repeat(depth);
49598
49807
  lines.push(`${indent}- ${entry.name}${entry.isDirectory() ? "/" : ""}`);
49599
49808
  if (entry.isDirectory()) {
49600
- collectTreeLines(join14(directory, entry.name), depth + 1, lines);
49809
+ collectTreeLines(join13(directory, entry.name), depth + 1, lines);
49601
49810
  }
49602
49811
  }
49603
49812
  if (entries.length > DIR_ENTRY_LIMIT) {
@@ -49716,7 +49925,7 @@ function openLiveAudioCapture(source, identifier) {
49716
49925
  try {
49717
49926
  mkdirSync2(directory, { recursive: true, mode: 448 });
49718
49927
  const safeIdentifier = identifier.replace(/[^A-Za-z0-9_-]/g, "_");
49719
- const path19 = join15(
49928
+ const path19 = join14(
49720
49929
  directory,
49721
49930
  `${source}-${Date.now()}-${safeIdentifier}.pcm`
49722
49931
  );
@@ -50077,7 +50286,7 @@ var LiveSessionCoordinator = class {
50077
50286
  context.speechInProgress = true;
50078
50287
  context.inputCommitPending = true;
50079
50288
  context.inputAwaitingResponse = false;
50080
- const partialItemId = itemId ?? `partial:${randomUUID16()}`;
50289
+ const partialItemId = itemId ?? `partial:${randomUUID15()}`;
50081
50290
  context.activePartialInputItemId = partialItemId;
50082
50291
  if (!context.partialInputTranscripts.has(partialItemId)) {
50083
50292
  context.partialInputTranscripts.set(partialItemId, "");
@@ -50107,7 +50316,7 @@ var LiveSessionCoordinator = class {
50107
50316
  }, "onInputCommitted"),
50108
50317
  onInputTranscriptDelta: /* @__PURE__ */ __name(({ itemId, text }) => {
50109
50318
  if (this.isCurrentSocket(context, generation)) {
50110
- const partialItemId = itemId ?? context.activePartialInputItemId ?? `partial:${randomUUID16()}`;
50319
+ const partialItemId = itemId ?? context.activePartialInputItemId ?? `partial:${randomUUID15()}`;
50111
50320
  context.activePartialInputItemId = partialItemId;
50112
50321
  context.partialInputTranscripts.set(partialItemId, text);
50113
50322
  this.options.host.setTranscript?.(context.epoch, text);
@@ -50117,7 +50326,7 @@ var LiveSessionCoordinator = class {
50117
50326
  if (this.isCurrentSocket(context, generation)) {
50118
50327
  context.speechInProgress = false;
50119
50328
  context.inputCommitPending = false;
50120
- const completedItemId = itemId ?? context.activePartialInputItemId ?? `unattributed:${randomUUID16()}`;
50329
+ const completedItemId = itemId ?? context.activePartialInputItemId ?? `unattributed:${randomUUID15()}`;
50121
50330
  context.partialInputTranscripts.delete(completedItemId);
50122
50331
  if (context.activePartialInputItemId === completedItemId) {
50123
50332
  context.activePartialInputItemId = void 0;
@@ -50849,7 +51058,7 @@ var LiveSessionCoordinator = class {
50849
51058
  const runtime = context.runtime;
50850
51059
  if (!runtime) throw new Error("Conversation workspace is unavailable.");
50851
51060
  const bridge = runtime.bridge;
50852
- const promptId = randomUUID16();
51061
+ const promptId = randomUUID15();
50853
51062
  const lastEventId = bridge.getSessionLastEventId(locator.sessionId);
50854
51063
  const turnAbort = new AbortController();
50855
51064
  this.inFlightTurnAborts.add(turnAbort);
@@ -51012,9 +51221,12 @@ var LiveSessionCoordinator = class {
51012
51221
  if (update?.["sessionUpdate"] === "agent_message_chunk") {
51013
51222
  const source = updateSource(update);
51014
51223
  if (source === "background_notification") {
51015
- announcement = updateText(update);
51224
+ const text = updateText(update);
51225
+ announcement = announcement ? appendBounded(announcement, `
51226
+ ${text}`) : text;
51016
51227
  response = "";
51017
- backgroundTaskId = updateBackgroundTaskId(update);
51228
+ const taskId = updateBackgroundTaskId(update);
51229
+ if (taskId !== void 0) backgroundTaskId = taskId;
51018
51230
  } else if (source === "background_notification_response") {
51019
51231
  response = appendBounded(response, updateText(update));
51020
51232
  }
@@ -51166,7 +51378,7 @@ var LiveSessionCoordinator = class {
51166
51378
 
51167
51379
  // packages/cli/src/serve/live/live-task-service.ts
51168
51380
  init_esbuild_shims();
51169
- import { randomUUID as randomUUID17 } from "node:crypto";
51381
+ import { randomUUID as randomUUID16 } from "node:crypto";
51170
51382
  var DEFAULT_LIST_LIMIT = 20;
51171
51383
  var DEFAULT_READ_TURN_LIMIT = 3;
51172
51384
  var DEFAULT_WAIT_TIMEOUT_MS = 12e4;
@@ -51852,7 +52064,7 @@ var LiveTaskService = class {
51852
52064
  const record = target;
51853
52065
  if (record["type"] === "projectless") {
51854
52066
  const created = await this.getStandaloneSessionService().createWithInitialPrompt(
51855
- { sessionId: randomUUID17() },
52067
+ { sessionId: randomUUID16() },
51856
52068
  prompt
51857
52069
  );
51858
52070
  return {
@@ -51904,7 +52116,7 @@ var LiveTaskService = class {
51904
52116
  { sessionId, prompt: [{ type: "text", text: prompt }] },
51905
52117
  void 0,
51906
52118
  {
51907
- promptId: randomUUID17(),
52119
+ promptId: randomUUID16(),
51908
52120
  onPromptAdmitted: /* @__PURE__ */ __name(() => {
51909
52121
  admitted = true;
51910
52122
  onAdmitted?.();
@@ -52177,7 +52389,7 @@ var ConversationRuntimeManager = class {
52177
52389
  }
52178
52390
  async ensureOnce() {
52179
52391
  this.assertNotTerminal();
52180
- await this.options.ownership.acquire();
52392
+ if (!this.runtime) await this.options.checkLegacyOwner();
52181
52393
  this.assertNotTerminal();
52182
52394
  const root = await this.revalidateRoot();
52183
52395
  this.assertNotTerminal();
@@ -52268,6 +52480,226 @@ var ConversationRuntimeManager = class {
52268
52480
  }
52269
52481
  };
52270
52482
 
52483
+ // packages/cli/src/serve/conversations/conversation-runtime-ownership.ts
52484
+ init_esbuild_shims();
52485
+ import { constants as fsConstants3 } from "node:fs";
52486
+ import * as fs9 from "node:fs/promises";
52487
+ import * as path17 from "node:path";
52488
+ var OWNER_DIRECTORY = "conversations";
52489
+ var OWNER_FILE = "runtime-owner.json";
52490
+ var OWNER_LOCK = ".runtime-owner.lock";
52491
+ var MAX_OWNER_BYTES = 4 * 1024;
52492
+ var NONCE_PATTERN = /^[A-Za-z0-9_-]{16,256}$/;
52493
+ var DEFAULT_HANDOFF_GRACE_MS = 1e3;
52494
+ var UnsafeOwnershipStateError = class extends Error {
52495
+ static {
52496
+ __name(this, "UnsafeOwnershipStateError");
52497
+ }
52498
+ };
52499
+ function getConversationRuntimeOwnerPath(stableBaseDir) {
52500
+ return path17.join(stableBaseDir, OWNER_DIRECTORY, OWNER_FILE);
52501
+ }
52502
+ __name(getConversationRuntimeOwnerPath, "getConversationRuntimeOwnerPath");
52503
+ function processIsAlive(pid) {
52504
+ try {
52505
+ process.kill(pid, 0);
52506
+ return true;
52507
+ } catch (error2) {
52508
+ return error2.code !== "ESRCH";
52509
+ }
52510
+ }
52511
+ __name(processIsAlive, "processIsAlive");
52512
+ function delay2(milliseconds) {
52513
+ return new Promise((resolve7) => {
52514
+ setTimeout(resolve7, milliseconds);
52515
+ });
52516
+ }
52517
+ __name(delay2, "delay");
52518
+ function isMissing2(error2) {
52519
+ return error2.code === "ENOENT";
52520
+ }
52521
+ __name(isMissing2, "isMissing");
52522
+ function assertOwnerRecord(value) {
52523
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
52524
+ throw new UnsafeOwnershipStateError();
52525
+ }
52526
+ const keys = Object.keys(value).sort();
52527
+ if (keys.length !== 3 || keys[0] !== "instanceNonce" || keys[1] !== "pid" || keys[2] !== "version") {
52528
+ throw new UnsafeOwnershipStateError();
52529
+ }
52530
+ const record = value;
52531
+ if (record["version"] !== 1 || !Number.isSafeInteger(record["pid"]) || record["pid"] <= 0 || typeof record["instanceNonce"] !== "string" || !NONCE_PATTERN.test(record["instanceNonce"])) {
52532
+ throw new UnsafeOwnershipStateError();
52533
+ }
52534
+ return {
52535
+ version: 1,
52536
+ pid: record["pid"],
52537
+ instanceNonce: record["instanceNonce"]
52538
+ };
52539
+ }
52540
+ __name(assertOwnerRecord, "assertOwnerRecord");
52541
+ function sameRecord(left, right) {
52542
+ return left.version === right.version && left.pid === right.pid && left.instanceNonce === right.instanceNonce;
52543
+ }
52544
+ __name(sameRecord, "sameRecord");
52545
+ async function inspectDirectory(directory, requirePrivateMode) {
52546
+ const stat3 = await fs9.lstat(directory);
52547
+ if (!stat3.isDirectory() || stat3.isSymbolicLink()) {
52548
+ throw new UnsafeOwnershipStateError();
52549
+ }
52550
+ if (process.platform !== "win32" && (typeof process.getuid === "function" && stat3.uid !== process.getuid() || requirePrivateMode && (stat3.mode & 511) !== 448)) {
52551
+ throw new UnsafeOwnershipStateError();
52552
+ }
52553
+ return { dev: stat3.dev, ino: stat3.ino };
52554
+ }
52555
+ __name(inspectDirectory, "inspectDirectory");
52556
+ async function assertDirectoryIdentity(directory, expected, requirePrivateMode = true) {
52557
+ const current = await inspectDirectory(directory, requirePrivateMode);
52558
+ if (current.dev !== expected.dev || current.ino !== expected.ino) {
52559
+ throw new UnsafeOwnershipStateError();
52560
+ }
52561
+ }
52562
+ __name(assertDirectoryIdentity, "assertDirectoryIdentity");
52563
+ async function assertLockShapeIfPresent(lockPath) {
52564
+ let stat3;
52565
+ try {
52566
+ stat3 = await fs9.lstat(lockPath);
52567
+ } catch (error2) {
52568
+ if (isMissing2(error2)) return;
52569
+ throw error2;
52570
+ }
52571
+ if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && typeof process.getuid === "function" && stat3.uid !== process.getuid()) {
52572
+ throw new UnsafeOwnershipStateError();
52573
+ }
52574
+ }
52575
+ __name(assertLockShapeIfPresent, "assertLockShapeIfPresent");
52576
+ async function readOwnerRecord(ownerPath) {
52577
+ let pathStat;
52578
+ try {
52579
+ pathStat = await fs9.lstat(ownerPath);
52580
+ } catch (error2) {
52581
+ if (isMissing2(error2)) return void 0;
52582
+ throw error2;
52583
+ }
52584
+ if (!pathStat.isFile() || pathStat.isSymbolicLink() || pathStat.nlink !== 1 || pathStat.size <= 0 || pathStat.size > MAX_OWNER_BYTES || process.platform !== "win32" && ((pathStat.mode & 511) !== 384 || typeof process.getuid === "function" && pathStat.uid !== process.getuid())) {
52585
+ throw new UnsafeOwnershipStateError();
52586
+ }
52587
+ let handle;
52588
+ try {
52589
+ handle = await fs9.open(
52590
+ ownerPath,
52591
+ process.platform === "win32" ? fsConstants3.O_RDONLY : fsConstants3.O_RDONLY | fsConstants3.O_NOFOLLOW
52592
+ );
52593
+ } catch (error2) {
52594
+ if (error2.code === "ELOOP") {
52595
+ throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
52596
+ }
52597
+ throw error2;
52598
+ }
52599
+ try {
52600
+ const handleStat = await handle.stat();
52601
+ if (!handleStat.isFile() || handleStat.nlink !== 1 || handleStat.dev !== pathStat.dev || handleStat.ino !== pathStat.ino || handleStat.size !== pathStat.size || process.platform !== "win32" && ((handleStat.mode & 511) !== 384 || typeof process.getuid === "function" && handleStat.uid !== process.getuid())) {
52602
+ throw new UnsafeOwnershipStateError();
52603
+ }
52604
+ const serialized = await handle.readFile("utf8");
52605
+ let parsed;
52606
+ try {
52607
+ parsed = JSON.parse(serialized);
52608
+ } catch (error2) {
52609
+ throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
52610
+ }
52611
+ return assertOwnerRecord(parsed);
52612
+ } finally {
52613
+ await handle.close();
52614
+ }
52615
+ }
52616
+ __name(readOwnerRecord, "readOwnerRecord");
52617
+ async function syncDirectory(directory) {
52618
+ if (process.platform === "win32") return;
52619
+ const handle = await fs9.open(directory, fsConstants3.O_RDONLY);
52620
+ try {
52621
+ await handle.sync();
52622
+ } finally {
52623
+ await handle.close();
52624
+ }
52625
+ }
52626
+ __name(syncDirectory, "syncDirectory");
52627
+ async function checkLegacyConversationRuntimeOwner(options) {
52628
+ const ownerPath = getConversationRuntimeOwnerPath(options.stableBaseDir);
52629
+ const directory = path17.dirname(ownerPath);
52630
+ const lockPath = path17.join(directory, OWNER_LOCK);
52631
+ let reclaimed = false;
52632
+ try {
52633
+ let base;
52634
+ let identity;
52635
+ try {
52636
+ base = await inspectDirectory(options.stableBaseDir, false);
52637
+ identity = await inspectDirectory(directory, true);
52638
+ } catch (error2) {
52639
+ if (isMissing2(error2)) return;
52640
+ throw error2;
52641
+ }
52642
+ await assertLockShapeIfPresent(lockPath);
52643
+ const lockfile = (await import("./proper-lockfile-3LHWIM44.js")).default;
52644
+ let compromised = false;
52645
+ const release = await lockfile.lock(directory, {
52646
+ realpath: false,
52647
+ lockfilePath: lockPath,
52648
+ stale: 5e3,
52649
+ update: 1e3,
52650
+ retries: { retries: 40, minTimeout: 10, maxTimeout: 50 },
52651
+ ...options.lockOptions,
52652
+ onCompromised: /* @__PURE__ */ __name(() => {
52653
+ compromised = true;
52654
+ }, "onCompromised")
52655
+ });
52656
+ let operationError;
52657
+ try {
52658
+ await assertLockShapeIfPresent(lockPath);
52659
+ await assertDirectoryIdentity(options.stableBaseDir, base, false);
52660
+ await assertDirectoryIdentity(directory, identity);
52661
+ const existing = await readOwnerRecord(ownerPath);
52662
+ if (compromised) throw new UnsafeOwnershipStateError();
52663
+ if (existing) {
52664
+ if ((options.isProcessAlive ?? processIsAlive)(existing.pid)) {
52665
+ throw conversationRuntimeInUseError();
52666
+ }
52667
+ const confirmed = await readOwnerRecord(ownerPath);
52668
+ if (!confirmed || !sameRecord(existing, confirmed)) {
52669
+ throw new UnsafeOwnershipStateError();
52670
+ }
52671
+ await assertDirectoryIdentity(options.stableBaseDir, base, false);
52672
+ await assertDirectoryIdentity(directory, identity);
52673
+ if (compromised) throw new UnsafeOwnershipStateError();
52674
+ await fs9.unlink(ownerPath);
52675
+ await syncDirectory(directory);
52676
+ reclaimed = true;
52677
+ }
52678
+ } catch (error2) {
52679
+ operationError = error2;
52680
+ }
52681
+ try {
52682
+ await release();
52683
+ } catch (error2) {
52684
+ throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
52685
+ }
52686
+ if (compromised) throw new UnsafeOwnershipStateError();
52687
+ if (operationError) throw operationError;
52688
+ if (reclaimed) {
52689
+ await (options.wait ?? delay2)(
52690
+ options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS
52691
+ );
52692
+ }
52693
+ } catch (error2) {
52694
+ if (error2 instanceof ConversationRuntimeOwnershipError) throw error2;
52695
+ if (error2 instanceof UnsafeOwnershipStateError || error2.code === "ECOMPROMISED") {
52696
+ throw conversationRuntimeOwnershipCompromisedError(error2);
52697
+ }
52698
+ throw conversationRuntimeUnavailableError(error2);
52699
+ }
52700
+ }
52701
+ __name(checkLegacyConversationRuntimeOwner, "checkLegacyConversationRuntimeOwner");
52702
+
52271
52703
  // packages/cli/src/serve/server.ts
52272
52704
  var warnedDefaultTrust = false;
52273
52705
  function loadServeChannelWebhookConfigs(sources) {
@@ -52808,22 +53240,9 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
52808
53240
  }
52809
53241
  }, "getProviderReadiness")
52810
53242
  });
52811
- const conversationRuntimeOwnership = deps.liveConversationWorkspace ? deps.conversationRuntimeOwnershipFactory?.(
52812
- process.pid,
52813
- liveCoordinator.daemonInstanceNonce,
52814
- path18.resolve(
52815
- deps.liveDiscoveryStableBaseDir ?? getStableLiveDiscoveryBaseDir()
52816
- )
52817
- ) ?? createConversationRuntimeOwnership({
52818
- pid: process.pid,
52819
- instanceNonce: liveCoordinator.daemonInstanceNonce,
52820
- stableBaseDir: path18.resolve(
52821
- deps.liveDiscoveryStableBaseDir ?? getStableLiveDiscoveryBaseDir()
52822
- )
52823
- }) : void 0;
52824
- if (conversationRuntimeOwnership) {
52825
- serveAppLifecycle.setOwnership(conversationRuntimeOwnership);
52826
- }
53243
+ const stableLiveDiscoveryBaseDir = path18.resolve(
53244
+ deps.liveDiscoveryStableBaseDir ?? getStableLiveDiscoveryBaseDir()
53245
+ );
52827
53246
  liveCoordinator.setAppshotReadiness(
52828
53247
  liveVoiceEnabled && deps.liveConversationWorkspace ? {
52829
53248
  state: "checking",
@@ -52835,7 +53254,9 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
52835
53254
  );
52836
53255
  let standaloneSessionService;
52837
53256
  const conversationRuntimeManager = deps.liveConversationWorkspace ? new ConversationRuntimeManager({
52838
- ownership: conversationRuntimeOwnership,
53257
+ checkLegacyOwner: deps.checkLegacyConversationOwner ?? (() => checkLegacyConversationRuntimeOwner({
53258
+ stableBaseDir: stableLiveDiscoveryBaseDir
53259
+ })),
52839
53260
  workspace: deps.liveConversationWorkspace,
52840
53261
  registry: workspaceRegistry,
52841
53262
  publishRuntime: /* @__PURE__ */ __name(async (canonicalRoot, validate) => {
@@ -53119,6 +53540,14 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
53119
53540
  interruptTaskWaits: /* @__PURE__ */ __name((callerSessionId) => liveTaskService.interruptWait(callerSessionId), "interruptTaskWaits")
53120
53541
  });
53121
53542
  liveCoordinator.setHandlers({
53543
+ beforeStart: /* @__PURE__ */ __name(async () => {
53544
+ await ensureConversationRuntimeWithLifecycle();
53545
+ await publishLiveVoiceEnabled(true);
53546
+ await assertLiveDiscoveryPublisher(stableLiveDiscoveryBaseDir, {
53547
+ pid: process.pid,
53548
+ instanceNonce: liveCoordinator.daemonInstanceNonce
53549
+ });
53550
+ }, "beforeStart"),
53122
53551
  onHostReady: /* @__PURE__ */ __name(() => {
53123
53552
  if (!liveVoiceEnabled) return;
53124
53553
  void verifyLiveAppshotChannel();
@@ -53213,14 +53642,17 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
53213
53642
  );
53214
53643
  }
53215
53644
  const originAllowlist = new MutableOriginAllowlist(parsedAllowOrigins);
53216
- app.use(allowOriginCors(originAllowlist));
53217
- app.use(hostAllowlist(opts.hostname, getPort));
53218
53645
  const credentials = new CredentialStore(opts.token);
53219
53646
  const authenticate = bearerAuth(credentials);
53220
53647
  const rateLimiter = installRateLimiter(app, opts, daemonLog, {
53221
53648
  mount: false,
53222
53649
  workspaceQualifiedAcpEnabled
53223
53650
  });
53651
+ installAccessLogMiddleware(app, daemonLog);
53652
+ app.use(daemonInboundTraceIdCaptureMiddleware);
53653
+ app.use(hostAllowlist(opts.hostname, getPort));
53654
+ installRemoteSelfOriginMiddleware(app, opts.hostname, opts.token);
53655
+ app.use(allowOriginCors(originAllowlist));
53224
53656
  const healthRoutes = createHealthRoutes({
53225
53657
  opts,
53226
53658
  workspaceRegistry,
@@ -53237,8 +53669,6 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
53237
53669
  });
53238
53670
  healthRoutes.register(app);
53239
53671
  }
53240
- installAccessLogMiddleware(app, daemonLog);
53241
- app.use(daemonInboundTraceIdCaptureMiddleware);
53242
53672
  const webShellDir = opts.serveWebShell !== false ? deps.webShellDir : void 0;
53243
53673
  const webShellFrameAncestors = opts.allowOrigins && opts.allowOrigins.length > 0 ? [...parseAllowOriginPatterns(opts.allowOrigins).origins].filter(
53244
53674
  (o) => o.startsWith("chrome-extension://") || o.startsWith("moz-extension://")
@@ -53412,10 +53842,6 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
53412
53842
  if (liveVoiceSurfaceAvailable) {
53413
53843
  registerLiveRoutes(app, {
53414
53844
  coordinator: liveCoordinator,
53415
- ensureRuntimeReady: /* @__PURE__ */ __name(async () => {
53416
- await ensureConversationRuntimeWithLifecycle();
53417
- await publishLiveVoiceEnabled(true);
53418
- }, "ensureRuntimeReady"),
53419
53845
  mutate,
53420
53846
  ...deps.persistSetting ? {
53421
53847
  persistShortcut: /* @__PURE__ */ __name(async (shortcut) => {