@qwen-code/qwen-code 0.21.10 → 0.21.11-nightly.20260814.45c2e73080

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 (378) hide show
  1. package/bundled/coordinate/SKILL.md +52 -0
  2. package/bundled/qc-helper/docs/configuration/model-providers.md +10 -8
  3. package/bundled/qc-helper/docs/configuration/settings.md +10 -0
  4. package/bundled/qc-helper/docs/extension/_meta.ts +1 -0
  5. package/bundled/qc-helper/docs/extension/agent-plugins.md +50 -0
  6. package/bundled/qc-helper/docs/extension/extension-releasing.md +3 -3
  7. package/bundled/qc-helper/docs/extension/introduction.md +17 -3
  8. package/bundled/qc-helper/docs/features/_meta.ts +1 -0
  9. package/bundled/qc-helper/docs/features/arena.md +4 -3
  10. package/bundled/qc-helper/docs/features/code-review.md +1 -1
  11. package/bundled/qc-helper/docs/features/commands.md +7 -6
  12. package/bundled/qc-helper/docs/features/dual-output.md +5 -0
  13. package/bundled/qc-helper/docs/features/headless.md +8 -0
  14. package/bundled/qc-helper/docs/features/multi-agent-coordination.md +30 -0
  15. package/bundled/qc-helper/docs/qwen-serve.md +40 -40
  16. package/bundled/review/SKILL.md +45 -23
  17. package/chunks/{MaxSizedBox-FKXYULMW.js → MaxSizedBox-P4Z76535.js} +45 -44
  18. package/chunks/{StandaloneSessionPicker-OQS3M7AY.js → StandaloneSessionPicker-TRWDBCJG.js} +65 -64
  19. package/chunks/{acp-startup-profiler-VNTFWYAC.js → acp-startup-profiler-TVI2OVUN.js} +2 -2
  20. package/chunks/{acpAgent-AGS6HLQQ.js → acpAgent-MSZHQSZ7.js} +1645 -579
  21. package/chunks/{agent-4NCVO27U.js → agent-TMTEYQGK.js} +42 -41
  22. package/chunks/agent-headless-54WWND2M.js +87 -0
  23. package/chunks/{anthropicContentGenerator-D3Y4RFT4.js → anthropicContentGenerator-7ZK7U65G.js} +8 -8
  24. package/chunks/{artifact-tool-N652YE4L.js → artifact-tool-7HVSSXYZ.js} +2 -2
  25. package/chunks/{askUserQuestion-ONW74PKJ.js → askUserQuestion-IQCA2SOX.js} +2 -2
  26. package/chunks/{bridge-FHINXZMN.js → bridge-CI2NKV64.js} +49 -48
  27. package/chunks/{ca-ZLKAB4K3.js → ca-4CQ6MYNQ.js} +2 -1
  28. package/chunks/{channel-management-service-PHELKOW2.js → channel-management-service-LNEYNMDX.js} +6 -6
  29. package/chunks/channel-settings-store-QU4WFXHO.js +102 -0
  30. package/chunks/{channel-worker-group-WQP4RCDO.js → channel-worker-group-Q5WQVOMZ.js} +8 -7
  31. package/chunks/{channel-worker-manager-MRDFAKIM.js → channel-worker-manager-Z3JLH72P.js} +8 -7
  32. package/chunks/{channel-worker-supervisor-IVSDIMI4.js → channel-worker-supervisor-CG5HHT7K.js} +6 -5
  33. package/chunks/{chunk-A7XMDZRI.js → chunk-2AG524A4.js} +5 -5
  34. package/chunks/{chunk-GM463R2B.js → chunk-2ASWIM4A.js} +1 -1
  35. package/chunks/{chunk-DP3IHZGG.js → chunk-2AUM35J5.js} +59 -7
  36. package/chunks/{chunk-TZEZYNYD.js → chunk-2N6CV4PW.js} +1 -1
  37. package/chunks/{chunk-BSI645OU.js → chunk-3LHSUFPE.js} +3 -3
  38. package/chunks/{chunk-DCZEPFB4.js → chunk-3XLWKV4S.js} +3 -3
  39. package/chunks/{chunk-YWPSGJFI.js → chunk-4IBNVBGJ.js} +2 -2
  40. package/chunks/{chunk-ZRBMO3C7.js → chunk-4IWFPTAH.js} +1 -1
  41. package/chunks/{chunk-B2GJNDTV.js → chunk-4JS2QK7P.js} +1 -1
  42. package/chunks/{chunk-5MZCSWI4.js → chunk-4NV6L4GZ.js} +1184 -1450
  43. package/chunks/{chunk-Y3OVRWRY.js → chunk-4QC6SUVN.js} +1 -1
  44. package/chunks/{chunk-AOHJKPKL.js → chunk-5KZNWF2M.js} +1 -1
  45. package/chunks/{chunk-UMD7WQTR.js → chunk-5XNR53C7.js} +10 -8
  46. package/chunks/{chunk-IIJEYBNH.js → chunk-66PLFJQ7.js} +197 -60
  47. package/chunks/{chunk-SEZ556DZ.js → chunk-67F2BEYW.js} +1 -1
  48. package/chunks/{chunk-7GTMV7UE.js → chunk-6KXHEN6M.js} +8700 -2449
  49. package/chunks/{chunk-FVKHVJZQ.js → chunk-6OJDN5ZT.js} +1 -1
  50. package/chunks/{chunk-CKASRHZI.js → chunk-6SU6OW5Z.js} +1 -1
  51. package/chunks/{chunk-NEOXOWYH.js → chunk-6YUEAYJ5.js} +7 -7
  52. package/chunks/{chunk-QGNOFE5E.js → chunk-766PXUQ3.js} +1 -1
  53. package/chunks/{chunk-UVX4Y6IN.js → chunk-7JL5YBSA.js} +1 -1
  54. package/chunks/{chunk-2PLNY5TN.js → chunk-7MAHENBD.js} +4 -4
  55. package/chunks/{chunk-L2AFWWJE.js → chunk-7UNST76G.js} +105 -24
  56. package/chunks/{chunk-HUWENAHO.js → chunk-7WUMS2UA.js} +1 -1
  57. package/chunks/{chunk-MVUQRLOH.js → chunk-A4BAHMJF.js} +3 -3
  58. package/chunks/{chunk-7MH4J33A.js → chunk-A6GQUQ7I.js} +2 -2
  59. package/chunks/{chunk-GNPNYXJB.js → chunk-AAZWJAPQ.js} +2 -2
  60. package/chunks/{chunk-DX3RGJMS.js → chunk-ADJDLEVO.js} +72 -13
  61. package/chunks/{chunk-IWTMYQ32.js → chunk-AN3LCBS7.js} +9 -8
  62. package/chunks/{chunk-LHEC5V6G.js → chunk-AXEL55JW.js} +2 -2
  63. package/chunks/{chunk-QUI267ZP.js → chunk-B66LYK4B.js} +492 -63
  64. package/chunks/{chunk-VNNWAZSI.js → chunk-BCGJZGFI.js} +3 -3
  65. package/chunks/{chunk-F6WDTQ3M.js → chunk-BRYHERQ6.js} +5 -5
  66. package/chunks/{chunk-6ZRFAKXK.js → chunk-C2DR57L6.js} +1 -1
  67. package/chunks/{chunk-26CXSA6V.js → chunk-CAOT4DYN.js} +2 -2
  68. package/chunks/{chunk-H6XPXXMH.js → chunk-CQ35AJ4Z.js} +252 -254
  69. package/chunks/{chunk-F24A2JBM.js → chunk-CUXI3S6E.js} +914 -175
  70. package/chunks/{chunk-AEL7KN2O.js → chunk-DANYMI4U.js} +2 -2
  71. package/chunks/{chunk-AAE6SR4Q.js → chunk-DX7V233D.js} +1 -1
  72. package/chunks/{chunk-PJRW65JO.js → chunk-E74YSVIN.js} +1 -1
  73. package/chunks/{chunk-OWMAZHIX.js → chunk-EGB2PIYM.js} +1 -1
  74. package/chunks/{chunk-TRRF5BSP.js → chunk-F4BUGC4Y.js} +1 -1
  75. package/chunks/{chunk-4MKXUHXY.js → chunk-FGQY4VOZ.js} +5 -5
  76. package/chunks/{chunk-ZBVS26BY.js → chunk-FPGTNKCP.js} +7 -5
  77. package/chunks/{chunk-SR7RZ4MS.js → chunk-FTGU6G45.js} +2 -2
  78. package/chunks/{chunk-IBUGFUXC.js → chunk-G2ZEKO4T.js} +12 -12
  79. package/chunks/{chunk-NDU63YLI.js → chunk-GN2SCYBA.js} +4 -4
  80. package/chunks/{chunk-NV3F44FL.js → chunk-GNRFC5UM.js} +2 -2
  81. package/chunks/{chunk-KKBPOU75.js → chunk-H6BFLALJ.js} +1 -1
  82. package/chunks/chunk-HHJLM3WQ.js +41 -0
  83. package/chunks/{chunk-LLCWZQCU.js → chunk-HM7TLULV.js} +3 -3
  84. package/chunks/{chunk-ECWR5LQR.js → chunk-I76FLAP7.js} +3 -3
  85. package/chunks/{chunk-Q3AL4JQ3.js → chunk-IAE7LYSB.js} +2 -2
  86. package/chunks/{chunk-DREZZAZM.js → chunk-IDNVCWXZ.js} +13 -5
  87. package/chunks/{chunk-YF5MALI4.js → chunk-IPMHLZPY.js} +20 -16
  88. package/chunks/{chunk-UDXSXLER.js → chunk-IW6RQPQB.js} +14 -4
  89. package/chunks/{chunk-UBX6NL47.js → chunk-JLT5HCGQ.js} +47 -3
  90. package/chunks/{chunk-COBO5EBO.js → chunk-JRTJEGSP.js} +1 -1
  91. package/chunks/{chunk-PBRVUF5B.js → chunk-JW5UEE3V.js} +1 -1
  92. package/chunks/{chunk-W4RQUHY3.js → chunk-K5IDV3PC.js} +184 -22
  93. package/chunks/{chunk-O3EU6GMH.js → chunk-KACBT7N7.js} +27 -4
  94. package/chunks/{chunk-MFDYOYZZ.js → chunk-KCGEAL2C.js} +25 -2
  95. package/chunks/{chunk-EI3HZX6C.js → chunk-KK3FEHPJ.js} +1 -1
  96. package/chunks/{chunk-OJUQF2PL.js → chunk-KRRRRU3X.js} +5 -5
  97. package/chunks/{chunk-J6SZID63.js → chunk-KTWUFHS4.js} +2 -2
  98. package/chunks/{chunk-E2FPSSKP.js → chunk-KZKEVWJW.js} +57 -13
  99. package/chunks/{chunk-ZJ4W6SUY.js → chunk-L6PE52MF.js} +3 -3
  100. package/chunks/{chunk-YGT2AUJ7.js → chunk-LAKFZU36.js} +39 -19
  101. package/chunks/{chunk-47PEPJO7.js → chunk-LKN5SEHD.js} +3 -3
  102. package/chunks/{chunk-OQTXYMKW.js → chunk-LSMCI42W.js} +3 -3
  103. package/chunks/{chunk-ABVRJU3D.js → chunk-LY2SB7GC.js} +7 -7
  104. package/chunks/{chunk-D27I6YJT.js → chunk-M53FFYQJ.js} +27 -18
  105. package/chunks/{chunk-YTFDX4PR.js → chunk-M6NDLY2T.js} +1 -1
  106. package/chunks/{chunk-3P2LV43B.js → chunk-MMEDZKWK.js} +3 -3
  107. package/chunks/{chunk-VFMASYQA.js → chunk-MS7GNABG.js} +3 -0
  108. package/chunks/{chunk-6LP743KE.js → chunk-MUTFMB5B.js} +78 -112
  109. package/chunks/{chunk-URK542T4.js → chunk-NF5J2WFA.js} +15 -2
  110. package/chunks/{chunk-VSFKIRRW.js → chunk-NH6U7L42.js} +4 -4
  111. package/chunks/{chunk-DA4HRSBW.js → chunk-NHZF4VCD.js} +1 -1
  112. package/chunks/{chunk-QG3FFJYU.js → chunk-NJE5NH5B.js} +1 -1
  113. package/chunks/{chunk-2UUMVNYT.js → chunk-NM33GGOM.js} +3 -3
  114. package/chunks/{chunk-FOGU3LJX.js → chunk-NW7SPXVG.js} +1 -1
  115. package/chunks/{chunk-EUNWC2VS.js → chunk-O6SLWH4X.js} +2 -2
  116. package/chunks/{chunk-EBZ6BJTF.js → chunk-OEVVUUYW.js} +1 -1
  117. package/chunks/chunk-OMVHZ7E6.js +1280 -0
  118. package/chunks/{chunk-KZ22NXBY.js → chunk-OT72MGHE.js} +4 -4
  119. package/chunks/{chunk-DZUO626D.js → chunk-OUCCIS3E.js} +3 -3
  120. package/chunks/{chunk-OONWZLFK.js → chunk-OYLYERMH.js} +4 -4
  121. package/chunks/{chunk-P3BJLFSZ.js → chunk-OYQM5XZ4.js} +3 -3
  122. package/chunks/{chunk-NRLFZWCT.js → chunk-PNU3TILU.js} +3 -3
  123. package/chunks/{chunk-M6HMMKVG.js → chunk-PSTHNTHF.js} +1 -1
  124. package/chunks/{chunk-4PYCZH2V.js → chunk-QEWAHAW2.js} +3 -3
  125. package/chunks/{chunk-QJMOAMXT.js → chunk-RG2S3GYC.js} +8 -8
  126. package/chunks/{chunk-CTJLZLB5.js → chunk-RQS2BGPI.js} +1 -1
  127. package/chunks/{chunk-Y4R47ZUH.js → chunk-RTBUTKAX.js} +7 -7
  128. package/chunks/{chunk-NV65ZUVM.js → chunk-RZZV6GQN.js} +1 -1
  129. package/chunks/{chunk-UEOKWYGY.js → chunk-SESSAEWC.js} +11 -11
  130. package/chunks/{chunk-CPG6P4GG.js → chunk-SKRHR6N2.js} +1 -1
  131. package/chunks/{chunk-WAUGQKUU.js → chunk-SNHBRO4C.js} +9 -5
  132. package/chunks/{chunk-KID7K6H2.js → chunk-SNPOURNX.js} +6 -6
  133. package/chunks/{chunk-VWKER4ZH.js → chunk-SQCTJ435.js} +3 -3
  134. package/chunks/{chunk-Z4JX4NSH.js → chunk-SXJ7JYQA.js} +23 -23
  135. package/chunks/{chunk-XVHYA33G.js → chunk-TD7JVTIA.js} +4 -4
  136. package/chunks/{chunk-IRZ2ZH72.js → chunk-TEFHXP7C.js} +4 -4
  137. package/chunks/{chunk-2FRY5CRX.js → chunk-TNETSI2A.js} +3 -3
  138. package/chunks/{chunk-IA7TGCN2.js → chunk-TROB4PZY.js} +4 -4
  139. package/chunks/{chunk-4TRQPFDP.js → chunk-U3O2EO5Y.js} +26 -20
  140. package/chunks/{chunk-VKJ4KTPJ.js → chunk-U7ROFHSH.js} +1 -1
  141. package/chunks/{chunk-Q3JQ7OSU.js → chunk-UBC6PMV7.js} +1 -1
  142. package/chunks/{chunk-W5UC37EE.js → chunk-UFHPAMAV.js} +6 -0
  143. package/chunks/{chunk-EQL65XGA.js → chunk-UHF5VBKO.js} +47 -21
  144. package/chunks/{chunk-S6HYI3MF.js → chunk-UQPLUR4A.js} +2 -2
  145. package/chunks/{chunk-HGCQ5SE7.js → chunk-UXEO7E3V.js} +21 -0
  146. package/chunks/{chunk-WCG5O7IP.js → chunk-V3NMFQD2.js} +2 -2
  147. package/chunks/{chunk-EKPKKXY2.js → chunk-V4SJMQVJ.js} +1 -1
  148. package/chunks/{chunk-ONSZH6VM.js → chunk-VFJVRSRK.js} +2 -2
  149. package/chunks/{chunk-MZSJ43WV.js → chunk-W5ZFJYUG.js} +13 -0
  150. package/chunks/{chunk-XCGIMOLN.js → chunk-WCCLLK7X.js} +14 -1
  151. package/chunks/{chunk-4WL6SY4F.js → chunk-WDSTNDEW.js} +1 -1
  152. package/chunks/{chunk-KONVMRK7.js → chunk-WFTBYUOR.js} +1 -1
  153. package/chunks/{chunk-EI3NWELG.js → chunk-WH32GXQS.js} +6233 -4342
  154. package/chunks/{chunk-MIKXJYZB.js → chunk-WS5TWVT6.js} +305 -291
  155. package/chunks/{chunk-VJNBRRZG.js → chunk-WZMH7II3.js} +1 -1
  156. package/chunks/{chunk-67EWJE77.js → chunk-XY7DGTIC.js} +1 -1
  157. package/chunks/{chunk-HV76SFIA.js → chunk-YI5G32RU.js} +3 -3
  158. package/chunks/{chunk-OIVKILPI.js → chunk-YMB77M76.js} +18 -0
  159. package/chunks/{chunk-AQAJJMRR.js → chunk-YPITLFHS.js} +1 -1
  160. package/chunks/{chunk-WOJZWRAZ.js → chunk-YRLW2MSX.js} +1 -1
  161. package/chunks/{chunk-ZZCWJWTF.js → chunk-YY23TR4M.js} +31 -11
  162. package/chunks/{chunk-URKIBIFC.js → chunk-YYI3Z3AO.js} +3 -3
  163. package/chunks/chunk-Z7B6SRPM.js +32 -0
  164. package/chunks/{chunk-6Q5ABMTU.js → chunk-ZGONVQ3D.js} +23 -19
  165. package/chunks/{chunk-GWVUR3QZ.js → chunk-ZM6LZON7.js} +3 -3
  166. package/chunks/{chunk-XCWO3SMQ.js → chunk-ZPZANKVP.js} +3 -3
  167. package/chunks/{chunk-OCSFNUU4.js → chunk-ZRD3BUEX.js} +8 -8
  168. package/chunks/{chunk-PYQADEFD.js → chunk-ZRT36RSF.js} +1 -1
  169. package/chunks/{chunk-JT7XS4YW.js → chunk-ZZ7RUTJ4.js} +1 -1
  170. package/chunks/{computer-use-WQFK33Z3.js → computer-use-7BMFU557.js} +42 -41
  171. package/chunks/{config-utils-ULCSRMWD.js → config-utils-I732W437.js} +6 -6
  172. package/chunks/{contextCommand-7EOZND7C.js → contextCommand-VJ6UOMM4.js} +44 -43
  173. package/chunks/{core-runtime-FGMQRM6E.js → core-runtime-PMRKP77C.js} +42 -41
  174. package/chunks/{create-sub-session-QIDZUOPU.js → create-sub-session-23ULO5PO.js} +2 -2
  175. package/chunks/{create-sub-session-QM2K5HLZ.js → create-sub-session-5A3MSW22.js} +42 -41
  176. package/chunks/{cron-create-VONA5JYY.js → cron-create-5WUTNKNF.js} +4 -4
  177. package/chunks/{cron-delete-5JXSP2MI.js → cron-delete-JEQ27YPS.js} +4 -4
  178. package/chunks/{cron-list-KE4F2CIR.js → cron-list-IXGCA7UR.js} +4 -4
  179. package/chunks/{daemon-GWD7BT6E.js → daemon-PXIC4ZDK.js} +186 -7
  180. package/chunks/daemon-status-provider-33BLPRUA.js +103 -0
  181. package/chunks/daemon-trust-policy-ZUV26YGP.js +99 -0
  182. package/chunks/{daemon-trust-policy-monitor-6UKEABN5.js → daemon-trust-policy-monitor-35WRTIMA.js} +49 -48
  183. package/chunks/{de-LIW4XVLN.js → de-UBEBKG6V.js} +2 -1
  184. package/chunks/{deferred-core-runtime-67GJXHXS.js → deferred-core-runtime-ZSLQKM7J.js} +42 -41
  185. package/chunks/{display-image-NQRSIBXM.js → display-image-CAD7RAUM.js} +4 -4
  186. package/chunks/{dist-6BMOAE3Z.js → dist-362MN6CP.js} +4 -4
  187. package/chunks/{dist-3NTTUAHT.js → dist-5VDE7U3A.js} +3 -3
  188. package/chunks/{dist-Z3CS4OVP.js → dist-6RK4U6VU.js} +11 -5
  189. package/chunks/{dist-B2CGTW6T.js → dist-CCUH2Z4C.js} +3 -3
  190. package/chunks/{dist-J47AXBZC.js → dist-EZHCZSW6.js} +3 -3
  191. package/chunks/{dist-EZE3V3Q7.js → dist-JIORWIDV.js} +3 -3
  192. package/chunks/{dist-EWW3J4HQ.js → dist-M3XMEIP2.js} +3 -3
  193. package/chunks/{dist-OTUO3AS2.js → dist-NN5ARGTQ.js} +13 -5
  194. package/chunks/{earlyInputCapture-IWMYR6OB.js → earlyInputCapture-UNMCTGJR.js} +43 -42
  195. package/chunks/{edit-ZFGROCAF.js → edit-TXVTSXHY.js} +42 -41
  196. package/chunks/{en-SY5GTIGX.js → en-X6YV7GME.js} +2 -1
  197. package/chunks/{enter-worktree-TZZZCDM5.js → enter-worktree-7Q3X4PW7.js} +42 -41
  198. package/chunks/{enterPlanMode-U77BI3R6.js → enterPlanMode-AZBU3ZB6.js} +42 -41
  199. package/chunks/{environment-HC37DS2I.js → environment-TGFFQISF.js} +45 -44
  200. package/chunks/{errors-6AG54JPD.js → errors-GVPFT7BA.js} +44 -43
  201. package/chunks/{exit-worktree-UYYWFPNK.js → exit-worktree-7INKYMWE.js} +42 -41
  202. package/chunks/exitPlanMode-5CE7CLAE.js +85 -0
  203. package/chunks/{fast-path-F5FSZ3O7.js → fast-path-7B6F74IR.js} +5 -5
  204. package/chunks/{fast-path-settings-RPAVBD7P.js → fast-path-settings-LNOFM2YP.js} +2 -2
  205. package/chunks/{fr-RQFO7U4P.js → fr-VENTC2BS.js} +2 -1
  206. package/chunks/{gemini-NKQHYM36.js → gemini-4RUYPDKT.js} +92 -91
  207. package/chunks/{geminiContentGenerator-HCWZOUX3.js → geminiContentGenerator-NLL52POY.js} +6 -6
  208. package/chunks/{glob-3PDXKBAO.js → glob-DHU3INUK.js} +42 -41
  209. package/chunks/{goal-tools-SWNB6GP4.js → goal-tools-LQFO4BRY.js} +4 -4
  210. package/chunks/{grep-5HZKZYVD.js → grep-523W6G52.js} +42 -41
  211. package/chunks/handleAutoUpdate-PKUQ3OQQ.js +94 -0
  212. package/chunks/{i18n-Q27KKNDL.js → i18n-HYL2UBJW.js} +43 -42
  213. package/chunks/{image-gen-2Z2RJ6W7.js → image-gen-NLIDBAKE.js} +10 -10
  214. package/chunks/initializer-DGH7RAJ7.js +100 -0
  215. package/chunks/{installationInfo-XXB75T7O.js → installationInfo-FZ4XWV7O.js} +43 -42
  216. package/chunks/{ja-KOZKHJHZ.js → ja-QHT4EQTO.js} +2 -1
  217. package/chunks/{keychain-token-storage-TVAMTNP7.js → keychain-token-storage-GU75J2T2.js} +2 -2
  218. package/chunks/list-RH5HGWRJ.js +103 -0
  219. package/chunks/{list-agents-Z4WABFDZ.js → list-agents-5PNMK2AM.js} +2 -2
  220. package/chunks/loadedSettingsAdapter-XMX2JDOU.js +97 -0
  221. package/chunks/{loggingContentGenerator-6NTFBM7Q.js → loggingContentGenerator-T3J4HZ7U.js} +139 -98
  222. package/chunks/{loop-wakeup-UZ5RL5Y2.js → loop-wakeup-OV65FEGR.js} +5 -5
  223. package/chunks/{ls-TVHDGIES.js → ls-7CETV7WV.js} +4 -4
  224. package/chunks/{lsp-CVN6OQPI.js → lsp-IWTJWFLT.js} +2 -2
  225. package/chunks/{managed-npm-update-SPHYQUWZ.js → managed-npm-update-E5ZGIGWV.js} +45 -44
  226. package/chunks/mcp-6LC572CW.js +97 -0
  227. package/chunks/{monitor-ZBBPAA54.js → monitor-HQUS4RTV.js} +42 -41
  228. package/chunks/nonInteractiveCli-X7HKTS5Z.js +163 -0
  229. package/chunks/{notebook-edit-5W3FW7Z2.js → notebook-edit-QPI3LTFM.js} +42 -41
  230. package/chunks/{openaiContentGenerator-TQANPEVZ.js → openaiContentGenerator-GGS72DVB.js} +29 -29
  231. package/chunks/{pidfile-EQOBLH4E.js → pidfile-HD3EB6GL.js} +43 -42
  232. package/chunks/{processUtils-7XQG7EHS.js → processUtils-2WNEPSW4.js} +2 -2
  233. package/chunks/{pt-U6AOCTMF.js → pt-VL3I5RNY.js} +2 -1
  234. package/chunks/{qwenContentGenerator-BKCPHHXU.js → qwenContentGenerator-WJYPELF3.js} +48 -48
  235. package/chunks/{qwenOAuth2-BJ6PQKE6.js → qwenOAuth2-RSMEBZU4.js} +9 -9
  236. package/chunks/read-file-URU5ALY3.js +32 -0
  237. package/chunks/{read-mcp-resource-PZ4ZF6YL.js → read-mcp-resource-THCSZHXO.js} +2 -2
  238. package/chunks/{read-package-up-TCM6I7S2.js → read-package-up-K6RKTL5D.js} +1 -1
  239. package/chunks/{record-artifact-P4HFMS7X.js → record-artifact-76YYQA5F.js} +3 -3
  240. package/chunks/{resumeHistoryUtils-6N6XGJJW.js → resumeHistoryUtils-XMC3CR2U.js} +49 -48
  241. package/chunks/ripGrep-6NYCUBVW.js +85 -0
  242. package/chunks/{ru-CMX4UMYP.js → ru-4RCKL4PY.js} +2 -1
  243. package/chunks/{run-qwen-serve-BCKBCAMX.js → run-qwen-serve-H4IXCJDQ.js} +165 -65
  244. package/chunks/{runtime-E2437YKL.js → runtime-EJHNZR7H.js} +55 -54
  245. package/chunks/{scheduler-K3D5Z655.js → scheduler-VVORKEEZ.js} +44 -43
  246. package/chunks/{sdk-exporters-http-XVTZQRCE.js → sdk-exporters-http-JYKTSCMG.js} +11 -7
  247. package/chunks/{sdk-impl-7W7AKCS4.js → sdk-impl-ROR54N3H.js} +13 -10
  248. package/chunks/{send-message-CAMSLG2L.js → send-message-P5SLP57G.js} +6 -6
  249. package/chunks/serve-3ULKH2KQ.js +107 -0
  250. package/chunks/{server-UD6INW7J.js → server-J52IQLRJ.js} +949 -303
  251. package/chunks/{session-GR4ZEVW4.js → session-MNWSMCC2.js} +118 -98
  252. package/chunks/{settings-5O24D3OJ.js → settings-WFCKUQZO.js} +48 -47
  253. package/chunks/{shell-UTLWLG5G.js → shell-H5DZN76B.js} +42 -41
  254. package/chunks/{skill-QQAZL4VO.js → skill-STSDBOIL.js} +19 -19
  255. package/chunks/{skill-settings-P3YHJVBZ.js → skill-settings-LTJAR2LV.js} +48 -47
  256. package/chunks/spawnChannel-XL27KTLE.js +98 -0
  257. package/chunks/{standalone-update-QP742MGP.js → standalone-update-3FUDL2R6.js} +44 -43
  258. package/chunks/{startInteractiveUI-YCS6AEPN.js → startInteractiveUI-5BFJCCWU.js} +596 -335
  259. package/chunks/{syntheticOutput-PEBJQYJV.js → syntheticOutput-SEW4NA47.js} +3 -3
  260. package/chunks/{task-create-5NWCQSJF.js → task-create-247EAVF7.js} +10 -10
  261. package/chunks/{task-list-53265TRZ.js → task-list-ZJN4QHLK.js} +5 -5
  262. package/chunks/{task-stop-FPCOIRYX.js → task-stop-MAYQJ42I.js} +2 -2
  263. package/chunks/{task-update-5HN577LS.js → task-update-CG4FALQF.js} +10 -10
  264. package/chunks/{team-create-WFH7OCDQ.js → team-create-FC2EYGE7.js} +44 -43
  265. package/chunks/{team-delete-MMQB4OSC.js → team-delete-3XVRPQBP.js} +5 -5
  266. package/chunks/{team-plan-approval-EGTT53MV.js → team-plan-approval-X673CRIZ.js} +42 -41
  267. package/chunks/{terminal-image-renderer-BWRESAQ7.js → terminal-image-renderer-MRNJ77H7.js} +44 -43
  268. package/chunks/theme-manager-6UMSB7DJ.js +89 -0
  269. package/chunks/{todoWrite-JGV6VLOX.js → todoWrite-IE2YTCK7.js} +4 -4
  270. package/chunks/{tool-search-TI5PTIBF.js → tool-search-7Z3PPA5O.js} +19 -19
  271. package/chunks/total-session-admission-NU4KV76R.js +99 -0
  272. package/chunks/{trustedFolders-4KYHA4IG.js → trustedFolders-SCUSHKHS.js} +43 -42
  273. package/chunks/{update-relaunch-WB6LGIF2.js → update-relaunch-M6BNKY4W.js} +5 -5
  274. package/chunks/{updateCheck-LOS5GYFC.js → updateCheck-QMZZ53S6.js} +48 -47
  275. package/chunks/{useAutoAcceptIndicator-MHAPY52L.js → useAutoAcceptIndicator-GAFG5PFE.js} +52 -51
  276. package/chunks/{validateNonInterActiveAuth-QV22HNQU.js → validateNonInterActiveAuth-V44BOAD2.js} +87 -86
  277. package/chunks/{version-DALWZHKQ.js → version-A4J2RQXD.js} +2 -2
  278. package/chunks/{web-fetch-JMJVMYFE.js → web-fetch-43TWEBWB.js} +19 -19
  279. package/chunks/{web-search-DNDUIPU5.js → web-search-CS3Q6JBI.js} +11 -11
  280. package/chunks/{workflow-JGNN64PM.js → workflow-ETQXJUPR.js} +115 -49
  281. package/chunks/workspace-providers-status-Y4FPKLHN.js +100 -0
  282. package/chunks/{workspace-registration-store-LRJG7QA4.js → workspace-registration-store-JASCK5RS.js} +1 -1
  283. package/chunks/{workspace-registry-KVXIFM36.js → workspace-registry-MU3VIM2D.js} +49 -48
  284. package/chunks/{workspace-service-PO4AAKKT.js → workspace-service-MHVHRNDX.js} +54 -53
  285. package/chunks/workspace-skills-status-QVQMNHGO.js +100 -0
  286. package/chunks/{workspace-trust-reconciler-DOZPCVHG.js → workspace-trust-reconciler-ABXDCISO.js} +56 -55
  287. package/chunks/write-file-YL7EPQRJ.js +87 -0
  288. package/chunks/{zh-AGL2FVBI.js → zh-LMSTK4WD.js} +2 -1
  289. package/chunks/{zh-TW-KI66MHQY.js → zh-TW-SQ4HTSCW.js} +2 -1
  290. package/chunks/{zoom-image-CNC77ZMA.js → zoom-image-ZQV6O2KE.js} +15 -15
  291. package/cli.js +13 -13
  292. package/locales/ca.js +1 -0
  293. package/locales/de.js +1 -0
  294. package/locales/en.js +1 -0
  295. package/locales/fr.js +1 -0
  296. package/locales/ja.js +1 -0
  297. package/locales/pt.js +1 -0
  298. package/locales/ru.js +1 -0
  299. package/locales/zh-TW.js +1 -0
  300. package/locales/zh.js +1 -0
  301. package/package.json +4 -4
  302. package/web-shell/assets/{arc-CDk0d60K.js → arc-BDKBUdHd.js} +1 -1
  303. package/web-shell/assets/{architectureDiagram-3BPJPVTR-h-W3I2lP.js → architectureDiagram-3BPJPVTR-DgMi5iOf.js} +1 -1
  304. package/web-shell/assets/{blockDiagram-GPEHLZMM-D1pvSmZg.js → blockDiagram-GPEHLZMM-DOyxD2BK.js} +1 -1
  305. package/web-shell/assets/{c4Diagram-AAUBKEIU-ByAm5ZNf.js → c4Diagram-AAUBKEIU-CmXzCE_n.js} +1 -1
  306. package/web-shell/assets/channel-BCff03Ag.js +1 -0
  307. package/web-shell/assets/{chunk-2J33WTMH-VrGPPOGV.js → chunk-2J33WTMH-Dr13N7PT.js} +1 -1
  308. package/web-shell/assets/{chunk-4BX2VUAB-B7hTowgG.js → chunk-4BX2VUAB-CIFcKNCP.js} +1 -1
  309. package/web-shell/assets/{chunk-55IACEB6-j1Fq8DpE.js → chunk-55IACEB6-B8jmrVPK.js} +1 -1
  310. package/web-shell/assets/{chunk-727SXJPM-UjABYpF2.js → chunk-727SXJPM-CQc0wjze.js} +1 -1
  311. package/web-shell/assets/{chunk-AQP2D5EJ-D4uBItrs.js → chunk-AQP2D5EJ-CGdZxT9s.js} +1 -1
  312. package/web-shell/assets/{chunk-FMBD7UC4-DeFbKlb8.js → chunk-FMBD7UC4-4iCBhCLJ.js} +1 -1
  313. package/web-shell/assets/{chunk-ND2GUHAM-rQJ8TIgT.js → chunk-ND2GUHAM-B0mMzZcM.js} +1 -1
  314. package/web-shell/assets/{chunk-QZHKN3VN-DAGcRxvq.js → chunk-QZHKN3VN-6CURQrGl.js} +1 -1
  315. package/web-shell/assets/classDiagram-4FO5ZUOK-DnwxH0ri.js +1 -0
  316. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-DnwxH0ri.js +1 -0
  317. package/web-shell/assets/{cose-bilkent-S5V4N54A-MaE7MJSt.js → cose-bilkent-S5V4N54A-L6Fo1GN1.js} +1 -1
  318. package/web-shell/assets/{dagre-BM42HDAG-DzijYGSb.js → dagre-BM42HDAG-BTsGDeLA.js} +1 -1
  319. package/web-shell/assets/{diagram-2AECGRRQ-WdbG7WnX.js → diagram-2AECGRRQ-B4AXYZGR.js} +1 -1
  320. package/web-shell/assets/{diagram-5GNKFQAL-NYutsBnw.js → diagram-5GNKFQAL-C2yM5aNc.js} +1 -1
  321. package/web-shell/assets/{diagram-KO2AKTUF-Dqg0eBY0.js → diagram-KO2AKTUF-CrGLZmRK.js} +1 -1
  322. package/web-shell/assets/{diagram-LMA3HP47-C7vRP2Lb.js → diagram-LMA3HP47-rycHl4fv.js} +1 -1
  323. package/web-shell/assets/{diagram-OG6HWLK6-B2sEPpPt.js → diagram-OG6HWLK6-MQj80AQu.js} +1 -1
  324. package/web-shell/assets/{erDiagram-TEJ5UH35-a4zIbzm8.js → erDiagram-TEJ5UH35-DCgH-D0D.js} +1 -1
  325. package/web-shell/assets/{flowDiagram-I6XJVG4X-BK9y89ya.js → flowDiagram-I6XJVG4X-B0gnwCnt.js} +1 -1
  326. package/web-shell/assets/{ganttDiagram-6RSMTGT7-wUQTSNvV.js → ganttDiagram-6RSMTGT7-CB0OxXVE.js} +1 -1
  327. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Dnzt4SAi.js → gitGraphDiagram-PVQCEYII-xLxucse9.js} +1 -1
  328. package/web-shell/assets/{index-BA3wUcKL.js → index-BFFbq0E-.js} +1 -1
  329. package/web-shell/assets/index-D7XXR9S-.js +1789 -0
  330. package/web-shell/assets/index-Dk5RwPL9.css +5 -0
  331. package/web-shell/assets/{infoDiagram-5YYISTIA-DcaoToij.js → infoDiagram-5YYISTIA-7FCqN4qa.js} +1 -1
  332. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-DzduqhP2.js → ishikawaDiagram-YF4QCWOH-BGyKlnik.js} +1 -1
  333. package/web-shell/assets/{journeyDiagram-JHISSGLW-BvviZR_O.js → journeyDiagram-JHISSGLW-CmgSXMLF.js} +1 -1
  334. package/web-shell/assets/{kanban-definition-UN3LZRKU-Efm2JxY3.js → kanban-definition-UN3LZRKU-CjT2mF6A.js} +1 -1
  335. package/web-shell/assets/{linear-DtY3IbOs.js → linear-CiTDGfCW.js} +1 -1
  336. package/web-shell/assets/{mermaid.core-PzpFqoMe.js → mermaid.core-_QnqxPRF.js} +5 -5
  337. package/web-shell/assets/{mindmap-definition-RKZ34NQL-BLlTkHS0.js → mindmap-definition-RKZ34NQL-B1On14ZB.js} +1 -1
  338. package/web-shell/assets/{pieDiagram-4H26LBE5-D-mKF-jE.js → pieDiagram-4H26LBE5-x1Pf1OG2.js} +1 -1
  339. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-DYCzslGm.js → quadrantDiagram-W4KKPZXB-ZawmK1Q9.js} +1 -1
  340. package/web-shell/assets/{requirementDiagram-4Y6WPE33-Dfpxlk7R.js → requirementDiagram-4Y6WPE33-krIMX0c8.js} +1 -1
  341. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-D5cRaaxh.js → sankeyDiagram-5OEKKPKP-aMJyxtx_.js} +1 -1
  342. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-s04DReiS.js → sequenceDiagram-3UESZ5HK-C530-Kqz.js} +1 -1
  343. package/web-shell/assets/{stateDiagram-AJRCARHV-01UNFgnb.js → stateDiagram-AJRCARHV-DObd9dT_.js} +1 -1
  344. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Bttf9Ae9.js +1 -0
  345. package/web-shell/assets/{timeline-definition-PNZ67QCA-DX8_wZBC.js → timeline-definition-PNZ67QCA-D9LnwQ1O.js} +1 -1
  346. package/web-shell/assets/{vennDiagram-CIIHVFJN-BK0FlBme.js → vennDiagram-CIIHVFJN-B_MT_v6Y.js} +1 -1
  347. package/web-shell/assets/{wardley-L42UT6IY-DkPc9UlD.js → wardley-L42UT6IY-DHKPz5Hu.js} +1 -1
  348. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-DNKkpDAo.js → wardleyDiagram-YWT4CUSO-BoyKaItA.js} +1 -1
  349. package/web-shell/assets/{xychartDiagram-2RQKCTM6-CiPwg8QG.js → xychartDiagram-2RQKCTM6--xBJT7Kg.js} +1 -1
  350. package/web-shell/index.html +2 -2
  351. package/chunks/agent-headless-HYEHZFH6.js +0 -86
  352. package/chunks/channel-settings-store-OXYG5S5X.js +0 -101
  353. package/chunks/chunk-I5VM3SKY.js +0 -451
  354. package/chunks/chunk-PDPFQ2FO.js +0 -156
  355. package/chunks/daemon-status-provider-L3J6GKCT.js +0 -102
  356. package/chunks/daemon-trust-policy-4PHPY23S.js +0 -98
  357. package/chunks/exitPlanMode-RWJR2KGB.js +0 -84
  358. package/chunks/handleAutoUpdate-NHFSGYTF.js +0 -93
  359. package/chunks/initializer-Y5DJLT43.js +0 -99
  360. package/chunks/list-YHNQ32CS.js +0 -102
  361. package/chunks/loadedSettingsAdapter-GHUQK7H4.js +0 -96
  362. package/chunks/mcp-EA3KO6FS.js +0 -96
  363. package/chunks/nonInteractiveCli-NNOR56HU.js +0 -162
  364. package/chunks/read-file-KKTXGIZD.js +0 -32
  365. package/chunks/ripGrep-SJVAAYDV.js +0 -84
  366. package/chunks/serve-IH4XR5IL.js +0 -106
  367. package/chunks/spawnChannel-UAQMH6Y6.js +0 -94
  368. package/chunks/theme-manager-ZNDGAHJN.js +0 -88
  369. package/chunks/total-session-admission-66UDSOHO.js +0 -98
  370. package/chunks/workspace-providers-status-K22B3Z6B.js +0 -99
  371. package/chunks/workspace-skills-status-DDYCBVSH.js +0 -99
  372. package/chunks/write-file-TT6MWIKC.js +0 -86
  373. package/web-shell/assets/channel-DPFUV4oi.js +0 -1
  374. package/web-shell/assets/classDiagram-4FO5ZUOK-CLm0hVvw.js +0 -1
  375. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CLm0hVvw.js +0 -1
  376. package/web-shell/assets/index-BjC3yjjL.css +0 -5
  377. package/web-shell/assets/index-QzFq6w7o.js +0 -1775
  378. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DXb5olqv.js +0 -1
@@ -2,38 +2,31 @@
2
2
  "use strict";
3
3
  import {
4
4
  formatHistoryGapNotice
5
- } from "./chunk-ZRBMO3C7.js";
5
+ } from "./chunk-4IWFPTAH.js";
6
6
  import {
7
7
  sanitizeTerminalText
8
8
  } from "./chunk-4NFY2S7N.js";
9
- import {
10
- isGoalStatusKind,
11
- isTerminalGoalStatusKind
12
- } from "./chunk-EKTCKZV5.js";
13
9
  import {
14
10
  loadUndici
15
11
  } from "./chunk-3Z43GZUQ.js";
16
12
  import {
17
- getActiveGoal,
18
- registerGoalHook,
19
- setGoalTerminalObserver,
20
- setLastGoalTerminal,
21
- unregisterGoalHook
22
- } from "./chunk-EI3NWELG.js";
13
+ projectGoalStateToLegacy
14
+ } from "./chunk-WH32GXQS.js";
23
15
  import {
16
+ parseGoalSnapshotV2,
17
+ parseGoalStateCause,
24
18
  projectUserTranscriptForDisplay
25
- } from "./chunk-QUI267ZP.js";
19
+ } from "./chunk-B66LYK4B.js";
26
20
  import {
27
- apiActivityTracker,
28
21
  formatVisionBridgeNoticeDisplay,
29
22
  isVisionBridgeNoticeDisplay
30
- } from "./chunk-YGT2AUJ7.js";
23
+ } from "./chunk-LAKFZU36.js";
31
24
  import {
32
25
  ToolNames
33
- } from "./chunk-PYQADEFD.js";
26
+ } from "./chunk-ZRT36RSF.js";
34
27
  import {
35
28
  createDebugLogger
36
- } from "./chunk-OIVKILPI.js";
29
+ } from "./chunk-YMB77M76.js";
37
30
  import {
38
31
  writeStderrLine,
39
32
  writeStderrLineSafe
@@ -45,788 +38,147 @@ import {
45
38
  __name
46
39
  } from "./chunk-J2S4EL5Y.js";
47
40
 
48
- // packages/cli/src/ui/utils/restoreGoal.ts
41
+ // packages/cli/src/acp-integration/session/history-replayer.ts
49
42
  init_esbuild_shims();
50
- function findGoalToRestore(history) {
51
- for (let i = history.length - 1; i >= 0; i--) {
52
- const item = history[i];
53
- if (item?.type !== "goal_status" /* GOAL_STATUS */) continue;
54
- const goal = item;
55
- if (goal.kind !== "set" && goal.kind !== "checking") return null;
56
- const setAt = goal.setAt ?? findSetAtOfRun(history, i);
57
- return {
58
- condition: goal.condition,
59
- iterations: goal.iterations ?? 0,
60
- ...setAt !== void 0 ? { setAt } : {}
61
- };
62
- }
63
- return null;
43
+
44
+ // packages/acp-bridge/src/transcript-replay.ts
45
+ init_esbuild_shims();
46
+
47
+ // packages/core/dist/src/goals/goal-wire.js
48
+ init_esbuild_shims();
49
+
50
+ // packages/core/dist/src/goals/goal-protocol.js
51
+ init_esbuild_shims();
52
+ var GOAL_STATE_VERSION = 2;
53
+ var GOAL_CHECKPOINT_CLAIM_LIMIT = 32;
54
+ var GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS = 2e3;
55
+ var GOAL_CHECKPOINT_CLAIM_MAX_BYTES = 16e3;
56
+ var GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT = 32;
57
+ function isGoalEvidenceProofKind(value) {
58
+ return value === "user_input" || value === "delivered_output" || value === "external_fact";
64
59
  }
65
- __name(findGoalToRestore, "findGoalToRestore");
66
- function findSetAtOfRun(history, startIndex) {
67
- const start = history[startIndex];
68
- const condition = start?.condition;
69
- for (let i = startIndex - 1; i >= 0; i--) {
70
- const item = history[i];
71
- if (item?.type !== "goal_status" /* GOAL_STATUS */) continue;
72
- const goal = item;
73
- if (goal.kind !== "set" && goal.kind !== "checking") return void 0;
74
- if (goal.condition !== condition) return void 0;
75
- if (goal.setAt !== void 0) return goal.setAt;
60
+ __name(isGoalEvidenceProofKind, "isGoalEvidenceProofKind");
61
+
62
+ // packages/core/dist/src/goals/goal-reducer.js
63
+ init_esbuild_shims();
64
+ var MAX_BLOCKED_AUDIT_COUNT = 3;
65
+ function parseGoalStateRecordPayloadV2(value) {
66
+ if (!isRecord(value) || !hasOnlyKeys(value, [
67
+ "v",
68
+ "cause",
69
+ "snapshot",
70
+ "checkpointPending",
71
+ "blockedAudit"
72
+ ]) || value["v"] !== GOAL_STATE_VERSION || !isGoalStateCause(value["cause"]) || !isCheckpointPending(value["checkpointPending"]) || !isBlockedAudit(value["blockedAudit"])) {
73
+ return void 0;
76
74
  }
77
- return void 0;
75
+ const parsedSnapshot = parseGoalSnapshotV22(value["snapshot"]);
76
+ if (parsedSnapshot?.activity !== "idle")
77
+ return void 0;
78
+ const checkpointPending = value["checkpointPending"];
79
+ if (checkpointPending && (parsedSnapshot.goal?.status !== "active" || checkpointPending.permit.goalId !== parsedSnapshot.goal.goalId || checkpointPending.permit.revision !== parsedSnapshot.goal.revision || checkpointPending.recordUuid === parsedSnapshot.goal.evidenceCursor.recordId || value["cause"] !== "turn_finished" && value["cause"] !== "verifier_reject")) {
80
+ return void 0;
81
+ }
82
+ return {
83
+ v: GOAL_STATE_VERSION,
84
+ cause: value["cause"],
85
+ snapshot: parsedSnapshot,
86
+ ...checkpointPending ? { checkpointPending: structuredClone(checkpointPending) } : {},
87
+ ...value["blockedAudit"] ? { blockedAudit: structuredClone(value["blockedAudit"]) } : {}
88
+ };
78
89
  }
79
- __name(findSetAtOfRun, "findSetAtOfRun");
80
- function findLastTerminalGoal(history) {
81
- for (let i = history.length - 1; i >= 0; i--) {
82
- const item = history[i];
83
- if (item?.type !== "goal_status" /* GOAL_STATUS */) continue;
84
- const goal = item;
85
- if (!isTerminalGoalStatusKind(goal.kind)) continue;
90
+ __name(parseGoalStateRecordPayloadV2, "parseGoalStateRecordPayloadV2");
91
+ function parseGoalSnapshotV22(value) {
92
+ if (!isRecord(value) || !hasOnlyKeys(value, ["v", "goal", "activity"]) || value["v"] !== GOAL_STATE_VERSION || !isGoalActivity(value["activity"])) {
93
+ return void 0;
94
+ }
95
+ if (value["goal"] === null) {
86
96
  return {
87
- kind: goal.kind,
88
- condition: goal.condition,
89
- iterations: goal.iterations ?? 0,
90
- durationMs: goal.durationMs ?? 0,
91
- lastReason: goal.lastReason
97
+ v: GOAL_STATE_VERSION,
98
+ goal: null,
99
+ activity: value["activity"]
92
100
  };
93
101
  }
94
- return null;
102
+ const goal = parseGoalRecord(value["goal"]);
103
+ return goal ? { v: GOAL_STATE_VERSION, goal, activity: value["activity"] } : void 0;
95
104
  }
96
- __name(findLastTerminalGoal, "findLastTerminalGoal");
97
- function finiteNumber(value) {
98
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
105
+ __name(parseGoalSnapshotV22, "parseGoalSnapshotV2");
106
+ function parseGoalStateCause2(value) {
107
+ return isGoalStateCause(value) ? value : void 0;
99
108
  }
100
- __name(finiteNumber, "finiteNumber");
101
- function isTranscriptItemRecord(item) {
102
- return typeof item === "object" && item !== null && !Array.isArray(item);
103
- }
104
- __name(isTranscriptItemRecord, "isTranscriptItemRecord");
105
- function parseGoalStatusItem(item) {
106
- if (!isTranscriptItemRecord(item)) return null;
107
- if (item["type"] !== "goal_status" /* GOAL_STATUS */) return null;
108
- const kind = item["kind"];
109
- const condition = item["condition"];
110
- if (!isGoalStatusKind(kind) || typeof condition !== "string") return null;
111
- const iterations = finiteNumber(item["iterations"]);
112
- const setAt = finiteNumber(item["setAt"]);
113
- const durationMs = finiteNumber(item["durationMs"]);
114
- const lastReason = typeof item["lastReason"] === "string" ? item["lastReason"] : void 0;
115
- return {
116
- type: "goal_status" /* GOAL_STATUS */,
117
- kind,
118
- condition,
119
- ...iterations !== void 0 ? { iterations } : {},
120
- ...setAt !== void 0 ? { setAt } : {},
121
- ...durationMs !== void 0 ? { durationMs } : {},
122
- ...lastReason !== void 0 ? { lastReason } : {}
123
- };
109
+ __name(parseGoalStateCause2, "parseGoalStateCause");
110
+ function copyCursor(cursor) {
111
+ return { recordId: cursor.recordId };
124
112
  }
125
- __name(parseGoalStatusItem, "parseGoalStatusItem");
126
- function collectGoalStatusItemsFromRecords(records) {
127
- const items = [];
128
- for (const record of records) {
129
- if (record.type !== "system" || record.subtype !== "slash_command") {
130
- continue;
131
- }
132
- const payload = record.systemPayload;
133
- if (payload?.phase !== "result") continue;
134
- const raws = payload.outputHistoryItems;
135
- if (!Array.isArray(raws)) continue;
136
- for (const raw of raws) {
137
- const item = parseGoalStatusItem(raw);
138
- if (item) items.push(item);
139
- }
113
+ __name(copyCursor, "copyCursor");
114
+ function parseGoalRecord(value) {
115
+ if (!isRecord(value) || !hasOnlyKeys(value, [
116
+ "goalId",
117
+ "revision",
118
+ "objective",
119
+ "status",
120
+ "evidenceCursor",
121
+ "turnCount",
122
+ "activeTimeMs",
123
+ "createdAt",
124
+ "updatedAt",
125
+ "evidenceCheckpoint",
126
+ "lastReason"
127
+ ]) || typeof value["goalId"] !== "string" || !value["goalId"] || !isNonNegativeInteger(value["revision"]) || value["revision"] === 0 || typeof value["objective"] !== "string" || !value["objective"].trim() || !isGoalStatus(value["status"]) || !isTranscriptCursor(value["evidenceCursor"]) || !isNonNegativeInteger(value["turnCount"]) || !isNonNegativeNumber(value["activeTimeMs"]) || !isFiniteNumber(value["createdAt"]) || !isFiniteNumber(value["updatedAt"]) || !isGoalEvidenceCheckpoint(value["evidenceCheckpoint"]) || value["lastReason"] !== void 0 && typeof value["lastReason"] !== "string") {
128
+ return void 0;
129
+ }
130
+ if (value["evidenceCheckpoint"] && value["evidenceCursor"].recordId !== value["evidenceCheckpoint"].checkpointId) {
131
+ return void 0;
140
132
  }
141
- return items;
142
- }
143
- __name(collectGoalStatusItemsFromRecords, "collectGoalStatusItemsFromRecords");
144
- function goalTerminalEventToHistoryItem(event) {
145
133
  return {
146
- type: "goal_status" /* GOAL_STATUS */,
147
- kind: event.kind,
148
- condition: event.condition,
149
- iterations: event.iterations,
150
- durationMs: event.durationMs,
151
- lastReason: event.lastReason ?? event.systemMessage
134
+ goalId: value["goalId"],
135
+ revision: value["revision"],
136
+ objective: value["objective"],
137
+ status: value["status"],
138
+ evidenceCursor: copyCursor(value["evidenceCursor"]),
139
+ turnCount: value["turnCount"],
140
+ activeTimeMs: value["activeTimeMs"],
141
+ createdAt: value["createdAt"],
142
+ updatedAt: value["updatedAt"],
143
+ ...value["evidenceCheckpoint"] === void 0 ? {} : {
144
+ evidenceCheckpoint: structuredClone(value["evidenceCheckpoint"])
145
+ },
146
+ ...value["lastReason"] === void 0 ? {} : { lastReason: value["lastReason"] }
152
147
  };
153
148
  }
154
- __name(goalTerminalEventToHistoryItem, "goalTerminalEventToHistoryItem");
155
- function recordGoalStatusItem(config, item, rawCommand = "/goal") {
156
- try {
157
- const recording = config.getChatRecordingService?.();
158
- if (!recording) {
159
- writeStderrLineSafe(
160
- `qwen: no chat recording service; goal_status (kind=${item.kind}) will not survive a resume.`
161
- );
162
- return;
163
- }
164
- recording.recordSlashCommand({
165
- phase: "result",
166
- rawCommand,
167
- outputHistoryItems: [{ ...item }]
168
- });
169
- } catch (error) {
170
- writeStderrLineSafe(
171
- `qwen: failed to record goal_status (kind=${item.kind}): ${error}`
172
- );
173
- }
174
- }
175
- __name(recordGoalStatusItem, "recordGoalStatusItem");
176
- function installGoalTerminalObserver(args) {
177
- const { sessionId, config, addItem } = args;
178
- setGoalTerminalObserver(sessionId, (event) => {
179
- const item = goalTerminalEventToHistoryItem(event);
180
- addItem(item, Date.now());
181
- recordGoalStatusItem(config, item);
182
- });
183
- }
184
- __name(installGoalTerminalObserver, "installGoalTerminalObserver");
185
- function goalRestoreBlockedBy(config) {
186
- if (!config.isTrustedFolder()) return "untrusted-folder";
187
- if (config.getDisableAllHooks()) return "hooks-disabled";
188
- if (!config.getHookSystem()) return "no-hook-system";
189
- return null;
149
+ __name(parseGoalRecord, "parseGoalRecord");
150
+ function isTranscriptCursor(value) {
151
+ return isRecord(value) && hasOnlyKeys(value, ["recordId"]) && (typeof value["recordId"] === "string" || value["recordId"] === null);
190
152
  }
191
- __name(goalRestoreBlockedBy, "goalRestoreBlockedBy");
192
- function goalConditionBlockedBy(condition) {
193
- if (condition.length === 0) return "condition-invalid";
194
- return null;
153
+ __name(isTranscriptCursor, "isTranscriptCursor");
154
+ function isGoalStatus(value) {
155
+ return value === "active" || value === "paused" || value === "blocked" || value === "usage_limited" || value === "complete";
195
156
  }
196
- __name(goalConditionBlockedBy, "goalConditionBlockedBy");
197
- function restoreGoalFromHistory(history, config, addItem) {
198
- const sessionId = config.getSessionId();
199
- const lastTerminal = findLastTerminalGoal(history);
200
- setLastGoalTerminal(sessionId, lastTerminal ?? void 0);
201
- const restorable = findGoalToRestore(history);
202
- if (restorable === null) {
203
- unregisterGoalHook(config, sessionId);
204
- return { restored: false };
205
- }
206
- const blockedBy = goalRestoreBlockedBy(config);
207
- if (blockedBy) {
208
- unregisterGoalHook(config, sessionId);
209
- return { restored: false, blockedBy };
210
- }
211
- if (goalConditionBlockedBy(restorable.condition)) {
212
- writeStderrLineSafe(
213
- `qwen: refusing to restore a goal for session ${sessionId}: the condition is empty.`
214
- );
215
- unregisterGoalHook(config, sessionId);
216
- return { restored: false, blockedBy: "condition-invalid" };
217
- }
218
- registerGoalHook({
219
- config,
220
- sessionId,
221
- condition: restorable.condition,
222
- tokensAtStart: 0,
223
- // Resume the iteration count so MAX_GOAL_ITERATIONS is a cross-resume cap,
224
- // not a per-resume one.
225
- initialIterations: restorable.iterations,
226
- // Likewise the start time: without it every reload restarts the clock, and
227
- // `GET /goals` reports a long-running goal as freshly started.
228
- ...restorable.setAt !== void 0 ? { initialSetAt: restorable.setAt } : {}
229
- });
230
- if (addItem) {
231
- installGoalTerminalObserver({ sessionId, config, addItem });
232
- }
233
- return { restored: true, condition: restorable.condition };
157
+ __name(isGoalStatus, "isGoalStatus");
158
+ function isGoalActivity(value) {
159
+ return value === "idle" || value === "running" || value === "verifying";
234
160
  }
235
- __name(restoreGoalFromHistory, "restoreGoalFromHistory");
236
-
237
- // packages/cli/src/services/setup-github.ts
238
- init_esbuild_shims();
239
- import { promises as fsp } from "node:fs";
240
- import * as path from "node:path";
241
-
242
- // packages/cli/src/utils/gitUtils.ts
243
- init_esbuild_shims();
244
- import * as childProcess from "node:child_process";
245
- var debugLogger = createDebugLogger("GIT");
246
- async function runGit(args, opts = {}) {
247
- return await new Promise((resolve2, reject) => {
248
- childProcess.execFile(
249
- "git",
250
- args,
251
- {
252
- encoding: "utf-8",
253
- ...opts.cwd ? { cwd: opts.cwd } : {}
254
- },
255
- (err, stdout) => {
256
- if (err) {
257
- reject(err);
258
- return;
259
- }
260
- resolve2(String(stdout ?? "").trim());
261
- }
262
- );
263
- });
161
+ __name(isGoalActivity, "isGoalActivity");
162
+ function isGoalStateCause(value) {
163
+ return value === "create" || value === "replace" || value === "edit" || value === "pause" || value === "resume" || value === "turn_finished" || value === "checkpoint" || value === "verifier_accept" || value === "verifier_reject" || value === "complete" || value === "blocked" || value === "usage_limited" || value === "clear" || value === "migrated";
264
164
  }
265
- __name(runGit, "runGit");
266
- var isGitHubRepositoryAsync = /* @__PURE__ */ __name(async (opts = {}) => {
267
- try {
268
- const remotes = await runGit(["remote", "-v"], opts);
269
- return remotes.split("\n").some((line) => {
270
- const remoteUrl = line.trim().split(/\s+/)[1];
271
- return remoteUrl ? isGitHubRemoteUrl(remoteUrl) : false;
272
- });
273
- } catch (_error) {
274
- debugLogger.debug(`Failed to get git remote:`, _error);
275
- return false;
276
- }
277
- }, "isGitHubRepositoryAsync");
278
- function isGitHubRemoteUrl(remoteUrl) {
279
- if (remoteUrl.startsWith("git@github.com:")) {
165
+ __name(isGoalStateCause, "isGoalStateCause");
166
+ function isGoalEvidenceCheckpoint(value) {
167
+ if (value === void 0)
280
168
  return true;
281
- }
282
- if (remoteUrl.startsWith("git@")) {
283
- return false;
284
- }
285
- try {
286
- return new URL(remoteUrl).hostname === "github.com";
287
- } catch {
169
+ if (!isRecord(value) || !hasOnlyKeys(value, ["checkpointId", "createdAt", "claims"]) || typeof value["checkpointId"] !== "string" || value["checkpointId"].length === 0 || !isFiniteNumber(value["createdAt"]) || !Array.isArray(value["claims"]) || value["claims"].length === 0 || value["claims"].length > GOAL_CHECKPOINT_CLAIM_LIMIT) {
288
170
  return false;
289
171
  }
290
- }
291
- __name(isGitHubRemoteUrl, "isGitHubRemoteUrl");
292
- var getGitRepoRootAsync = /* @__PURE__ */ __name(async (opts = {}) => {
293
- const gitRepoRoot = await runGit(["rev-parse", "--show-toplevel"], opts);
294
- if (!gitRepoRoot) {
295
- throw new Error(`Git repo returned empty value`);
296
- }
297
- return gitRepoRoot;
298
- }, "getGitRepoRootAsync");
299
- var getLatestGitHubRelease = /* @__PURE__ */ __name(async (proxy) => {
300
- try {
301
- const controller = new AbortController();
302
- const endpoint = `https://api.github.com/repos/QwenLM/qwen-code-action/releases/latest`;
303
- const dispatcher = proxy ? new (await loadUndici()).ProxyAgent(proxy) : void 0;
304
- const response = await fetch(endpoint, {
305
- method: "GET",
306
- headers: {
307
- Accept: "application/vnd.github+json",
308
- "Content-Type": "application/json",
309
- "X-GitHub-Api-Version": "2022-11-28"
310
- },
311
- dispatcher,
312
- signal: AbortSignal.any([AbortSignal.timeout(3e4), controller.signal])
313
- });
314
- if (!response.ok) {
315
- throw new Error(
316
- `Invalid response code: ${response.status} - ${response.statusText}`
317
- );
318
- }
319
- const releaseTag = (await response.json()).tag_name;
320
- if (!releaseTag) {
321
- throw new Error(`Response did not include tag_name field`);
172
+ let checkpointBytes = 0;
173
+ for (const [index, claim] of value["claims"].entries()) {
174
+ if (!isRecord(claim) || !hasOnlyKeys(claim, ["id", "proofKind", "claim", "sourceRefs"]) || claim["id"] !== `${value["checkpointId"]}:${index + 1}` || !isGoalEvidenceProofKind(claim["proofKind"]) || typeof claim["claim"] !== "string" || claim["claim"].trim().length === 0 || [...claim["claim"]].length > GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS || !Array.isArray(claim["sourceRefs"]) || claim["sourceRefs"].length === 0 || claim["sourceRefs"].length > GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT || new Set(claim["sourceRefs"]).size !== claim["sourceRefs"].length || claim["sourceRefs"].some((reference) => typeof reference !== "string" || reference.length === 0)) {
175
+ return false;
322
176
  }
323
- return releaseTag;
324
- } catch (_error) {
325
- debugLogger.debug(
326
- `Failed to determine latest qwen-code-action release:`,
327
- _error
328
- );
329
- throw new Error(
330
- `Unable to determine the latest qwen-code-action release on GitHub.`
331
- );
177
+ checkpointBytes += new TextEncoder().encode(claim["claim"]).byteLength;
178
+ if (checkpointBytes > GOAL_CHECKPOINT_CLAIM_MAX_BYTES)
179
+ return false;
332
180
  }
333
- }, "getLatestGitHubRelease");
334
- async function getGitHubRepoInfoAsync(opts = {}) {
335
- return parseGitHubRepoInfo(
336
- await runGit(["remote", "get-url", "origin"], opts)
337
- );
338
- }
339
- __name(getGitHubRepoInfoAsync, "getGitHubRepoInfoAsync");
340
- function parseGitHubRepoInfo(remoteUrl) {
341
- let urlToParse = remoteUrl;
342
- if (remoteUrl.startsWith("git@github.com:")) {
343
- urlToParse = remoteUrl.replace("git@github.com:", "");
344
- } else if (remoteUrl.startsWith("git@")) {
345
- throw new Error(
346
- `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
347
- );
348
- }
349
- let parsedUrl;
350
- try {
351
- parsedUrl = new URL(urlToParse, "https://github.com");
352
- } catch {
353
- throw new Error(
354
- `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
355
- );
356
- }
357
- if (parsedUrl.hostname !== "github.com") {
358
- throw new Error(
359
- `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
360
- );
361
- }
362
- const parts = parsedUrl.pathname.split("/").filter((part) => part !== "");
363
- if (parts.length !== 2 || !parts[0] || !parts[1]) {
364
- throw new Error(
365
- `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
366
- );
367
- }
368
- return { owner: parts[0], repo: parts[1].replace(/\.git$/, "") };
369
- }
370
- __name(parseGitHubRepoInfo, "parseGitHubRepoInfo");
371
-
372
- // packages/cli/src/services/setup-github.ts
373
- var debugLogger2 = createDebugLogger("SETUP_GITHUB");
374
- var GITHUB_WORKFLOW_PATHS = [
375
- "qwen-dispatch/qwen-dispatch.yml",
376
- "qwen-assistant/qwen-invoke.yml",
377
- "issue-triage/qwen-triage.yml",
378
- "issue-triage/qwen-scheduled-triage.yml",
379
- "pr-review/qwen-review.yml"
380
- ];
381
- var GITIGNORE_ENTRIES = [".qwen/", "gha-creds-*.json"];
382
- var MAX_WORKFLOW_DOWNLOAD_BYTES = 5 * 1024 * 1024;
383
- var SetupGithubError = class extends Error {
384
- static {
385
- __name(this, "SetupGithubError");
386
- }
387
- code;
388
- status;
389
- partial;
390
- partialResult;
391
- constructor(code, message, status, partialResult) {
392
- super(message);
393
- this.name = "SetupGithubError";
394
- this.code = code;
395
- this.status = status;
396
- this.partial = partialResult !== void 0;
397
- this.partialResult = partialResult;
398
- }
399
- };
400
- function isWorkspaceGenerationClosed(error) {
401
- return Boolean(
402
- error && typeof error === "object" && "code" in error && error.code === "workspace_generation_closed"
403
- );
404
- }
405
- __name(isWorkspaceGenerationClosed, "isWorkspaceGenerationClosed");
406
- var nodeFileOps = {
407
- assertCanWrite() {
408
- },
409
- async ensureWorkflowDirectory(gitRepoRoot) {
410
- await fsp.mkdir(path.join(gitRepoRoot, ".github", "workflows"), {
411
- recursive: true
412
- });
413
- },
414
- async writeTextFile(gitRepoRoot, relativePath, content) {
415
- const target = path.join(gitRepoRoot, relativePath);
416
- await fsp.writeFile(target, content, { mode: 420 });
417
- return { sizeBytes: Buffer.byteLength(content, "utf8") };
418
- },
419
- async readTextFile(gitRepoRoot, relativePath) {
420
- try {
421
- return await fsp.readFile(path.join(gitRepoRoot, relativePath), "utf8");
422
- } catch (error) {
423
- if (error.code === "ENOENT") {
424
- return void 0;
425
- }
426
- throw error;
427
- }
428
- }
429
- };
430
- async function setupGithub(options = {}) {
431
- const cwd = options.cwd ?? process.cwd();
432
- const fileOps = options.fileOps ?? nodeFileOps;
433
- if (!await isGitHubRepositoryAsync({ cwd })) {
434
- throw new SetupGithubError(
435
- "github_repository_not_found",
436
- "Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
437
- 400
438
- );
439
- }
440
- let gitRepoRoot;
441
- try {
442
- gitRepoRoot = await getGitRepoRootAsync({ cwd });
443
- } catch (error) {
444
- debugLogger2.debug("Failed to get git repo root:", error);
445
- throw new SetupGithubError(
446
- "github_repository_not_found",
447
- "Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
448
- 400
449
- );
450
- }
451
- if (options.workspaceRoot) {
452
- const [gitRootReal, workspaceReal] = await Promise.all([
453
- realpathOrResolve(gitRepoRoot),
454
- realpathOrResolve(options.workspaceRoot)
455
- ]);
456
- if (gitRootReal !== workspaceReal) {
457
- throw new SetupGithubError(
458
- "github_git_root_mismatch",
459
- "The Git repository root must match the daemon workspace root.",
460
- 400
461
- );
462
- }
463
- }
464
- fileOps.assertCanWrite?.();
465
- let releaseTag;
466
- try {
467
- releaseTag = await getLatestGitHubRelease(options.proxy);
468
- } catch (error) {
469
- writeStderrLine(
470
- `qwen setup-github: failed to determine latest qwen-code-action release: ${error instanceof Error ? error.message : String(error)}`
471
- );
472
- debugLogger2.debug(
473
- "Failed to determine latest qwen-code-action release:",
474
- error
475
- );
476
- throw new SetupGithubError(
477
- "github_release_lookup_failed",
478
- "Unable to determine the latest qwen-code-action release on GitHub.",
479
- 502
480
- );
481
- }
482
- const readmeUrl = `https://github.com/QwenLM/qwen-code-action/blob/${releaseTag}/README.md#quick-start`;
483
- const secretsUrl = await resolveSecretsUrl(cwd);
484
- const downloads = await downloadWorkflows({
485
- releaseTag,
486
- proxy: options.proxy,
487
- abortSignal: options.abortSignal,
488
- fetchImpl: options.fetchImpl ?? fetch
489
- });
490
- const result = {
491
- kind: "github_setup",
492
- workspaceCwd: options.workspaceRoot ?? gitRepoRoot,
493
- gitRepoRoot,
494
- releaseTag,
495
- readmeUrl,
496
- ...secretsUrl ? { secretsUrl } : {},
497
- workflows: [],
498
- gitignore: { path: ".gitignore", status: "skipped" },
499
- warnings: []
500
- };
501
- result.gitignore = await updateGitignore(gitRepoRoot, fileOps);
502
- if (result.gitignore.status === "failed") {
503
- result.warnings.push("Failed to update .gitignore.");
504
- }
505
- try {
506
- await fileOps.ensureWorkflowDirectory(gitRepoRoot);
507
- for (const workflow of downloads) {
508
- const relativePath = path.posix.join(
509
- ".github",
510
- "workflows",
511
- path.posix.basename(workflow.sourcePath)
512
- );
513
- try {
514
- const write = await fileOps.writeTextFile(
515
- gitRepoRoot,
516
- relativePath,
517
- workflow.content
518
- );
519
- result.workflows.push({
520
- sourcePath: workflow.sourcePath,
521
- path: relativePath,
522
- status: "written",
523
- sizeBytes: write.sizeBytes
524
- });
525
- } catch (error) {
526
- if (isWorkspaceGenerationClosed(error)) throw error;
527
- result.partial = true;
528
- result.workflows.push({
529
- sourcePath: workflow.sourcePath,
530
- path: relativePath,
531
- status: "failed",
532
- error: error instanceof Error ? error.message : String(error)
533
- });
534
- throw new SetupGithubError(
535
- "github_workflow_write_failed",
536
- `Unable to write ${relativePath}.`,
537
- 500,
538
- result
539
- );
540
- }
541
- }
542
- } catch (error) {
543
- if (isWorkspaceGenerationClosed(error)) throw error;
544
- if (error instanceof SetupGithubError) throw error;
545
- throw new SetupGithubError(
546
- "github_workflow_write_failed",
547
- "Unable to create .github/workflows.",
548
- 500,
549
- result
550
- );
551
- }
552
- return result;
553
- }
554
- __name(setupGithub, "setupGithub");
555
- async function updateGitignore(gitRepoRoot, fileOps = nodeFileOps) {
556
- try {
557
- const existingContent = await fileOps.readTextFile(
558
- gitRepoRoot,
559
- ".gitignore"
560
- );
561
- if (existingContent === void 0) {
562
- const content = GITIGNORE_ENTRIES.join("\n") + "\n";
563
- await fileOps.writeTextFile(gitRepoRoot, ".gitignore", content);
564
- return {
565
- path: ".gitignore",
566
- status: "created",
567
- added: [...GITIGNORE_ENTRIES]
568
- };
569
- }
570
- const missingEntries = GITIGNORE_ENTRIES.filter(
571
- (entry) => !existingContent.split(/\r?\n/).some((line) => line.split("#")[0].trim() === entry)
572
- );
573
- if (missingEntries.length === 0) {
574
- return { path: ".gitignore", status: "unchanged" };
575
- }
576
- const nextContent = existingContent + "\n" + missingEntries.join("\n") + "\n";
577
- await fileOps.writeTextFile(gitRepoRoot, ".gitignore", nextContent);
578
- return {
579
- path: ".gitignore",
580
- status: "updated",
581
- added: missingEntries
582
- };
583
- } catch (error) {
584
- if (isWorkspaceGenerationClosed(error)) throw error;
585
- debugLogger2.debug("Failed to update .gitignore:", error);
586
- return {
587
- path: ".gitignore",
588
- status: "failed",
589
- error: error instanceof Error ? error.message : String(error)
590
- };
591
- }
592
- }
593
- __name(updateGitignore, "updateGitignore");
594
- async function downloadWorkflows(options) {
595
- const internalAbort = new AbortController();
596
- try {
597
- const dispatcher = options.proxy ? new (await loadUndici()).ProxyAgent(options.proxy) : void 0;
598
- return await Promise.all(
599
- GITHUB_WORKFLOW_PATHS.map(async (workflow) => {
600
- const endpoint = `https://raw.githubusercontent.com/QwenLM/qwen-code-action/refs/tags/${options.releaseTag}/examples/workflows/${workflow}`;
601
- const response = await options.fetchImpl(endpoint, {
602
- method: "GET",
603
- dispatcher,
604
- signal: AbortSignal.any([
605
- AbortSignal.timeout(3e4),
606
- internalAbort.signal,
607
- ...options.abortSignal ? [options.abortSignal] : []
608
- ])
609
- });
610
- if (!response.ok) {
611
- throw new Error(
612
- `Invalid response code downloading ${endpoint}: ${response.status} - ${response.statusText}`
613
- );
614
- }
615
- return {
616
- sourcePath: workflow,
617
- content: await readResponseTextWithLimit(response, workflow)
618
- };
619
- })
620
- );
621
- } catch (error) {
622
- internalAbort.abort();
623
- const message = error instanceof Error ? error.message : String(error);
624
- debugLogger2.debug("Failed to download qwen-code-action workflows:", error);
625
- throw new SetupGithubError(
626
- "github_workflow_download_failed",
627
- `Unable to download qwen-code-action workflows from GitHub. ${message}`,
628
- 502
629
- );
630
- }
631
- }
632
- __name(downloadWorkflows, "downloadWorkflows");
633
- async function readResponseTextWithLimit(response, sourcePath) {
634
- const contentLength = response.headers.get("content-length");
635
- if (contentLength !== null) {
636
- const parsedLength = Number(contentLength);
637
- if (Number.isFinite(parsedLength) && parsedLength > MAX_WORKFLOW_DOWNLOAD_BYTES) {
638
- throw new Error(
639
- `${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
640
- );
641
- }
642
- }
643
- if (!response.body) return "";
644
- const reader = response.body.getReader();
645
- const chunks = [];
646
- let totalBytes = 0;
647
- try {
648
- while (true) {
649
- const { done, value } = await reader.read();
650
- if (done) break;
651
- if (!value) continue;
652
- totalBytes += value.byteLength;
653
- if (totalBytes > MAX_WORKFLOW_DOWNLOAD_BYTES) {
654
- await reader.cancel().catch(() => {
655
- });
656
- throw new Error(
657
- `${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
658
- );
659
- }
660
- chunks.push(value);
661
- }
662
- } finally {
663
- reader.releaseLock();
664
- }
665
- const body = new Uint8Array(totalBytes);
666
- let offset = 0;
667
- for (const chunk of chunks) {
668
- body.set(chunk, offset);
669
- offset += chunk.byteLength;
670
- }
671
- return new TextDecoder().decode(body);
672
- }
673
- __name(readResponseTextWithLimit, "readResponseTextWithLimit");
674
- async function resolveSecretsUrl(cwd) {
675
- try {
676
- const repoInfo = await getGitHubRepoInfoAsync({ cwd });
677
- return `https://github.com/${repoInfo.owner}/${repoInfo.repo}/settings/secrets/actions`;
678
- } catch {
679
- return void 0;
680
- }
681
- }
682
- __name(resolveSecretsUrl, "resolveSecretsUrl");
683
- async function realpathOrResolve(input) {
684
- try {
685
- return await fsp.realpath(input);
686
- } catch {
687
- return path.resolve(input);
688
- }
689
- }
690
- __name(realpathOrResolve, "realpathOrResolve");
691
-
692
- // packages/acp-bridge/src/transcript-replay.ts
693
- init_esbuild_shims();
694
-
695
- // packages/core/dist/src/goals/goal-wire.js
696
- init_esbuild_shims();
697
-
698
- // packages/core/dist/src/goals/goal-protocol.js
699
- init_esbuild_shims();
700
- var GOAL_STATE_VERSION = 2;
701
- var GOAL_CHECKPOINT_CLAIM_LIMIT = 32;
702
- var GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS = 2e3;
703
- var GOAL_CHECKPOINT_CLAIM_MAX_BYTES = 16e3;
704
- var GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT = 32;
705
- function isGoalEvidenceProofKind(value) {
706
- return value === "user_input" || value === "delivered_output" || value === "external_fact";
707
- }
708
- __name(isGoalEvidenceProofKind, "isGoalEvidenceProofKind");
709
-
710
- // packages/core/dist/src/goals/goal-reducer.js
711
- init_esbuild_shims();
712
- var MAX_BLOCKED_AUDIT_COUNT = 3;
713
- function parseGoalStateRecordPayloadV2(value) {
714
- if (!isRecord(value) || !hasOnlyKeys(value, [
715
- "v",
716
- "cause",
717
- "snapshot",
718
- "checkpointPending",
719
- "blockedAudit"
720
- ]) || value["v"] !== GOAL_STATE_VERSION || !isGoalStateCause(value["cause"]) || !isCheckpointPending(value["checkpointPending"]) || !isBlockedAudit(value["blockedAudit"])) {
721
- return void 0;
722
- }
723
- const parsedSnapshot = parseGoalSnapshotV2(value["snapshot"]);
724
- if (parsedSnapshot?.activity !== "idle")
725
- return void 0;
726
- const checkpointPending = value["checkpointPending"];
727
- if (checkpointPending && (parsedSnapshot.goal?.status !== "active" || checkpointPending.permit.goalId !== parsedSnapshot.goal.goalId || checkpointPending.permit.revision !== parsedSnapshot.goal.revision || checkpointPending.recordUuid === parsedSnapshot.goal.evidenceCursor.recordId || value["cause"] !== "turn_finished" && value["cause"] !== "verifier_reject")) {
728
- return void 0;
729
- }
730
- return {
731
- v: GOAL_STATE_VERSION,
732
- cause: value["cause"],
733
- snapshot: parsedSnapshot,
734
- ...checkpointPending ? { checkpointPending: structuredClone(checkpointPending) } : {},
735
- ...value["blockedAudit"] ? { blockedAudit: structuredClone(value["blockedAudit"]) } : {}
736
- };
737
- }
738
- __name(parseGoalStateRecordPayloadV2, "parseGoalStateRecordPayloadV2");
739
- function parseGoalSnapshotV2(value) {
740
- if (!isRecord(value) || !hasOnlyKeys(value, ["v", "goal", "activity"]) || value["v"] !== GOAL_STATE_VERSION || !isGoalActivity(value["activity"])) {
741
- return void 0;
742
- }
743
- if (value["goal"] === null) {
744
- return {
745
- v: GOAL_STATE_VERSION,
746
- goal: null,
747
- activity: value["activity"]
748
- };
749
- }
750
- const goal = parseGoalRecord(value["goal"]);
751
- return goal ? { v: GOAL_STATE_VERSION, goal, activity: value["activity"] } : void 0;
752
- }
753
- __name(parseGoalSnapshotV2, "parseGoalSnapshotV2");
754
- function parseGoalStateCause(value) {
755
- return isGoalStateCause(value) ? value : void 0;
756
- }
757
- __name(parseGoalStateCause, "parseGoalStateCause");
758
- function copyCursor(cursor) {
759
- return { recordId: cursor.recordId };
760
- }
761
- __name(copyCursor, "copyCursor");
762
- function parseGoalRecord(value) {
763
- if (!isRecord(value) || !hasOnlyKeys(value, [
764
- "goalId",
765
- "revision",
766
- "objective",
767
- "status",
768
- "evidenceCursor",
769
- "turnCount",
770
- "activeTimeMs",
771
- "createdAt",
772
- "updatedAt",
773
- "evidenceCheckpoint",
774
- "lastReason"
775
- ]) || typeof value["goalId"] !== "string" || !value["goalId"] || !isNonNegativeInteger(value["revision"]) || value["revision"] === 0 || typeof value["objective"] !== "string" || !value["objective"].trim() || !isGoalStatus(value["status"]) || !isTranscriptCursor(value["evidenceCursor"]) || !isNonNegativeInteger(value["turnCount"]) || !isNonNegativeNumber(value["activeTimeMs"]) || !isFiniteNumber(value["createdAt"]) || !isFiniteNumber(value["updatedAt"]) || !isGoalEvidenceCheckpoint(value["evidenceCheckpoint"]) || value["lastReason"] !== void 0 && typeof value["lastReason"] !== "string") {
776
- return void 0;
777
- }
778
- if (value["evidenceCheckpoint"] && value["evidenceCursor"].recordId !== value["evidenceCheckpoint"].checkpointId) {
779
- return void 0;
780
- }
781
- return {
782
- goalId: value["goalId"],
783
- revision: value["revision"],
784
- objective: value["objective"],
785
- status: value["status"],
786
- evidenceCursor: copyCursor(value["evidenceCursor"]),
787
- turnCount: value["turnCount"],
788
- activeTimeMs: value["activeTimeMs"],
789
- createdAt: value["createdAt"],
790
- updatedAt: value["updatedAt"],
791
- ...value["evidenceCheckpoint"] === void 0 ? {} : {
792
- evidenceCheckpoint: structuredClone(value["evidenceCheckpoint"])
793
- },
794
- ...value["lastReason"] === void 0 ? {} : { lastReason: value["lastReason"] }
795
- };
796
- }
797
- __name(parseGoalRecord, "parseGoalRecord");
798
- function isTranscriptCursor(value) {
799
- return isRecord(value) && hasOnlyKeys(value, ["recordId"]) && (typeof value["recordId"] === "string" || value["recordId"] === null);
800
- }
801
- __name(isTranscriptCursor, "isTranscriptCursor");
802
- function isGoalStatus(value) {
803
- return value === "active" || value === "paused" || value === "blocked" || value === "usage_limited" || value === "complete";
804
- }
805
- __name(isGoalStatus, "isGoalStatus");
806
- function isGoalActivity(value) {
807
- return value === "idle" || value === "running" || value === "verifying";
808
- }
809
- __name(isGoalActivity, "isGoalActivity");
810
- function isGoalStateCause(value) {
811
- return value === "create" || value === "replace" || value === "edit" || value === "pause" || value === "resume" || value === "turn_finished" || value === "checkpoint" || value === "verifier_accept" || value === "verifier_reject" || value === "complete" || value === "blocked" || value === "usage_limited" || value === "clear" || value === "migrated";
812
- }
813
- __name(isGoalStateCause, "isGoalStateCause");
814
- function isGoalEvidenceCheckpoint(value) {
815
- if (value === void 0)
816
- return true;
817
- if (!isRecord(value) || !hasOnlyKeys(value, ["checkpointId", "createdAt", "claims"]) || typeof value["checkpointId"] !== "string" || value["checkpointId"].length === 0 || !isFiniteNumber(value["createdAt"]) || !Array.isArray(value["claims"]) || value["claims"].length === 0 || value["claims"].length > GOAL_CHECKPOINT_CLAIM_LIMIT) {
818
- return false;
819
- }
820
- let checkpointBytes = 0;
821
- for (const [index, claim] of value["claims"].entries()) {
822
- if (!isRecord(claim) || !hasOnlyKeys(claim, ["id", "proofKind", "claim", "sourceRefs"]) || claim["id"] !== `${value["checkpointId"]}:${index + 1}` || !isGoalEvidenceProofKind(claim["proofKind"]) || typeof claim["claim"] !== "string" || claim["claim"].trim().length === 0 || [...claim["claim"]].length > GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS || !Array.isArray(claim["sourceRefs"]) || claim["sourceRefs"].length === 0 || claim["sourceRefs"].length > GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT || new Set(claim["sourceRefs"]).size !== claim["sourceRefs"].length || claim["sourceRefs"].some((reference) => typeof reference !== "string" || reference.length === 0)) {
823
- return false;
824
- }
825
- checkpointBytes += new TextEncoder().encode(claim["claim"]).byteLength;
826
- if (checkpointBytes > GOAL_CHECKPOINT_CLAIM_MAX_BYTES)
827
- return false;
828
- }
829
- return true;
181
+ return true;
830
182
  }
831
183
  __name(isGoalEvidenceCheckpoint, "isGoalEvidenceCheckpoint");
832
184
  function isCheckpointPending(value) {
@@ -864,7 +216,7 @@ __name(isFiniteNumber, "isFiniteNumber");
864
216
 
865
217
  // packages/core/dist/src/goals/goal-legacy-projection.js
866
218
  init_esbuild_shims();
867
- function projectGoalStateToLegacy(payload, previousGoal = null) {
219
+ function projectGoalStateToLegacy2(payload, previousGoal = null) {
868
220
  const snapshotGoal = payload.snapshot.goal;
869
221
  const displayGoal = snapshotGoal ?? previousGoal;
870
222
  const kind = legacyStatusKind(payload);
@@ -895,7 +247,7 @@ function projectGoalStateToLegacy(payload, previousGoal = null) {
895
247
  } : null
896
248
  };
897
249
  }
898
- __name(projectGoalStateToLegacy, "projectGoalStateToLegacy");
250
+ __name(projectGoalStateToLegacy2, "projectGoalStateToLegacy");
899
251
  function isGoalCheckpointBookkeepingTransition(previous, next) {
900
252
  const previousGoal = previous?.goal;
901
253
  const nextGoal = next.goal;
@@ -920,12 +272,16 @@ function legacyStatusKind(payload) {
920
272
  case "replace":
921
273
  case "edit":
922
274
  case "resume":
923
- case "migrated":
924
275
  return "set";
925
276
  case "complete":
926
277
  return "achieved";
927
278
  case "clear":
928
279
  return "cleared";
280
+ // A migrated goal is always persisted `paused` (`createMigratedGoalState`),
281
+ // and nothing drives a paused goal. Projecting it as `set` would re-assert
282
+ // "active" to every client that derives the live goal from the newest card,
283
+ // leaving a phantom running goal behind a resumed pre-v2 transcript.
284
+ case "migrated":
929
285
  case "pause":
930
286
  return "paused";
931
287
  case "blocked":
@@ -954,6 +310,12 @@ var TRANSCRIPT_GOAL_STATUS_KINDS = /* @__PURE__ */ new Set([
954
310
  "cleared",
955
311
  "failed",
956
312
  "aborted",
313
+ // A paused goal is not running, and dropping the card here is not neutral:
314
+ // the replay stream is what feeds the goal renderer, so the older `set` card
315
+ // stays newest and every surface keeps claiming autonomous work is under way.
316
+ // Kept in step with `GOAL_STATUS_KINDS`, which the daemon-side reader
317
+ // (`parseGoalStatusItem`) validates the same on-disk cards against.
318
+ "paused",
957
319
  "checking"
958
320
  ]);
959
321
  function isObjectRecord(value) {
@@ -1023,12 +385,12 @@ function createTranscriptImageUpdate(options) {
1023
385
  __name(createTranscriptImageUpdate, "createTranscriptImageUpdate");
1024
386
  function createTranscriptUsageUpdate(usageMetadata, options = {}) {
1025
387
  const usage = {
1026
- inputTokens: finiteNumber2(usageMetadata.promptTokenCount) ?? 0,
1027
- outputTokens: finiteNumber2(usageMetadata.candidatesTokenCount) ?? 0,
1028
- totalTokens: finiteNumber2(usageMetadata.totalTokenCount) ?? 0,
1029
- ...finiteNumber2(usageMetadata.thoughtsTokenCount) !== void 0 ? { thoughtTokens: finiteNumber2(usageMetadata.thoughtsTokenCount) } : {},
1030
- ...finiteNumber2(usageMetadata.cachedContentTokenCount) !== void 0 ? {
1031
- cachedReadTokens: finiteNumber2(usageMetadata.cachedContentTokenCount)
388
+ inputTokens: finiteNumber(usageMetadata.promptTokenCount) ?? 0,
389
+ outputTokens: finiteNumber(usageMetadata.candidatesTokenCount) ?? 0,
390
+ totalTokens: finiteNumber(usageMetadata.totalTokenCount) ?? 0,
391
+ ...finiteNumber(usageMetadata.thoughtsTokenCount) !== void 0 ? { thoughtTokens: finiteNumber(usageMetadata.thoughtsTokenCount) } : {},
392
+ ...finiteNumber(usageMetadata.cachedContentTokenCount) !== void 0 ? {
393
+ cachedReadTokens: finiteNumber(usageMetadata.cachedContentTokenCount)
1032
394
  } : {}
1033
395
  };
1034
396
  const meta = buildUpdateMeta({
@@ -1480,7 +842,7 @@ var DefaultTranscriptReplayMachine = class {
1480
842
  previous: this.goalState,
1481
843
  next: payload2.snapshot
1482
844
  });
1483
- const projection = projectGoalStateToLegacy(
845
+ const projection = projectGoalStateToLegacy2(
1484
846
  payload2,
1485
847
  this.goalState?.goal ?? null
1486
848
  );
@@ -1541,9 +903,9 @@ var DefaultTranscriptReplayMachine = class {
1541
903
  }
1542
904
  }
1543
905
  addUsage(metadata) {
1544
- this.usage.promptTokens += finiteNumber2(metadata["promptTokenCount"]) ?? 0;
1545
- this.usage.candidateTokens += finiteNumber2(metadata["candidatesTokenCount"]) ?? 0;
1546
- this.usage.cachedTokens += finiteNumber2(metadata["cachedContentTokenCount"]) ?? 0;
906
+ this.usage.promptTokens += finiteNumber(metadata["promptTokenCount"]) ?? 0;
907
+ this.usage.candidateTokens += finiteNumber(metadata["candidatesTokenCount"]) ?? 0;
908
+ this.usage.cachedTokens += finiteNumber(metadata["cachedContentTokenCount"]) ?? 0;
1547
909
  }
1548
910
  correlateResultCallId(toolName, recordId) {
1549
911
  const candidates = [...this.pendingToolCalls.values()].filter(
@@ -1638,9 +1000,9 @@ function parseTranscriptGoalStatus(value) {
1638
1000
  if (typeof kind !== "string" || !TRANSCRIPT_GOAL_STATUS_KINDS.has(kind) || typeof condition !== "string") {
1639
1001
  return void 0;
1640
1002
  }
1641
- const iterations = finiteNumber2(value["iterations"]);
1642
- const setAt = finiteNumber2(value["setAt"]);
1643
- const durationMs = finiteNumber2(value["durationMs"]);
1003
+ const iterations = finiteNumber(value["iterations"]);
1004
+ const setAt = finiteNumber(value["setAt"]);
1005
+ const durationMs = finiteNumber(value["durationMs"]);
1644
1006
  const lastReason = typeof value["lastReason"] === "string" ? value["lastReason"] : void 0;
1645
1007
  return {
1646
1008
  kind,
@@ -1705,7 +1067,7 @@ function parseInitialState(value, onDiagnostic) {
1705
1067
  );
1706
1068
  const rawUsage = value.cumulativeUsage;
1707
1069
  const usage = isObjectRecord(rawUsage) ? rawUsage : {};
1708
- const validUsage = finiteNumber2(usage["promptTokens"]) !== void 0 && finiteNumber2(usage["cachedTokens"]) !== void 0 && finiteNumber2(usage["candidateTokens"]) !== void 0 && finiteNumber2(usage["apiTimeMs"]) !== void 0;
1070
+ const validUsage = finiteNumber(usage["promptTokens"]) !== void 0 && finiteNumber(usage["cachedTokens"]) !== void 0 && finiteNumber(usage["candidateTokens"]) !== void 0 && finiteNumber(usage["apiTimeMs"]) !== void 0;
1709
1071
  if (!validUsage) {
1710
1072
  onDiagnostic?.({
1711
1073
  code: "invalid_replay_state",
@@ -1715,7 +1077,7 @@ function parseInitialState(value, onDiagnostic) {
1715
1077
  });
1716
1078
  }
1717
1079
  const rawGoalState = value["goalState"];
1718
- const goalState = rawGoalState === void 0 ? void 0 : parseGoalSnapshotV2(rawGoalState);
1080
+ const goalState = rawGoalState === void 0 ? void 0 : parseGoalSnapshotV22(rawGoalState);
1719
1081
  if (rawGoalState !== void 0 && !goalState) {
1720
1082
  onDiagnostic?.({
1721
1083
  code: "invalid_replay_state",
@@ -1725,7 +1087,7 @@ function parseInitialState(value, onDiagnostic) {
1725
1087
  });
1726
1088
  }
1727
1089
  const rawGoalCause = value["goalCause"];
1728
- const goalCause = rawGoalCause === void 0 ? void 0 : parseGoalStateCause(rawGoalCause);
1090
+ const goalCause = rawGoalCause === void 0 ? void 0 : parseGoalStateCause2(rawGoalCause);
1729
1091
  if (rawGoalCause !== void 0 && !goalCause) {
1730
1092
  onDiagnostic?.({
1731
1093
  code: "invalid_replay_state",
@@ -1918,18 +1280,18 @@ function usageFromTaskExecution(display) {
1918
1280
  const summary = isObjectRecord(display["executionSummary"]) ? display["executionSummary"] : void 0;
1919
1281
  if (!summary) return {};
1920
1282
  return {
1921
- ...finiteNumber2(summary["inputTokens"]) !== void 0 ? { promptTokenCount: summary["inputTokens"] } : {},
1922
- ...finiteNumber2(summary["outputTokens"]) !== void 0 ? { candidatesTokenCount: summary["outputTokens"] } : {},
1923
- ...finiteNumber2(summary["thoughtTokens"]) !== void 0 ? { thoughtsTokenCount: summary["thoughtTokens"] } : {},
1924
- ...finiteNumber2(summary["cachedTokens"]) !== void 0 ? { cachedContentTokenCount: summary["cachedTokens"] } : {},
1925
- ...finiteNumber2(summary["totalTokens"]) !== void 0 ? { totalTokenCount: summary["totalTokens"] } : {}
1283
+ ...finiteNumber(summary["inputTokens"]) !== void 0 ? { promptTokenCount: summary["inputTokens"] } : {},
1284
+ ...finiteNumber(summary["outputTokens"]) !== void 0 ? { candidatesTokenCount: summary["outputTokens"] } : {},
1285
+ ...finiteNumber(summary["thoughtTokens"]) !== void 0 ? { thoughtsTokenCount: summary["thoughtTokens"] } : {},
1286
+ ...finiteNumber(summary["cachedTokens"]) !== void 0 ? { cachedContentTokenCount: summary["cachedTokens"] } : {},
1287
+ ...finiteNumber(summary["totalTokens"]) !== void 0 ? { totalTokenCount: summary["totalTokens"] } : {}
1926
1288
  };
1927
1289
  }
1928
1290
  __name(usageFromTaskExecution, "usageFromTaskExecution");
1929
- function finiteNumber2(value) {
1291
+ function finiteNumber(value) {
1930
1292
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1931
1293
  }
1932
- __name(finiteNumber2, "finiteNumber");
1294
+ __name(finiteNumber, "finiteNumber");
1933
1295
  function extractErrorMessage(value) {
1934
1296
  if (value instanceof Error) return value.message;
1935
1297
  if (!isObjectRecord(value)) return void 0;
@@ -1941,15 +1303,8 @@ function dedupeStrings(values) {
1941
1303
  }
1942
1304
  __name(dedupeStrings, "dedupeStrings");
1943
1305
 
1944
- // packages/cli/src/acp-integration/session/emitters/MessageEmitter.ts
1945
- init_esbuild_shims();
1946
-
1947
- // packages/cli/src/acp-integration/session/types.ts
1306
+ // packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
1948
1307
  init_esbuild_shims();
1949
- function hasFullSessionContext(context) {
1950
- return "config" in context;
1951
- }
1952
- __name(hasFullSessionContext, "hasFullSessionContext");
1953
1308
 
1954
1309
  // packages/cli/src/acp-integration/session/emitters/base-emitter.ts
1955
1310
  init_esbuild_shims();
@@ -1993,724 +1348,985 @@ var BaseEmitter = class {
1993
1348
  }
1994
1349
  };
1995
1350
 
1996
- // packages/cli/src/acp-integration/session/emitters/MessageEmitter.ts
1997
- var MessageEmitter = class extends BaseEmitter {
1351
+ // packages/cli/src/acp-integration/session/emitters/PlanEmitter.ts
1352
+ init_esbuild_shims();
1353
+ var PlanEmitter = class extends BaseEmitter {
1354
+ static {
1355
+ __name(this, "PlanEmitter");
1356
+ }
1357
+ /**
1358
+ * Emits a plan update with the given todo items.
1359
+ *
1360
+ * @param plan - Plan identity and todo items to send as plan entries
1361
+ */
1362
+ async emitPlan(plan, sourceCallId) {
1363
+ const cumulative = this.ctx.cumulativeUsage;
1364
+ await this.sendUpdate(
1365
+ createTranscriptPlanUpdate(plan.todos, cumulative, {
1366
+ planToolCallId: sourceCallId,
1367
+ todoPlanId: plan.planId
1368
+ })
1369
+ );
1370
+ }
1371
+ /**
1372
+ * Extracts todos from tool result display or args.
1373
+ * Tries multiple sources in priority order:
1374
+ * 1. Result display object with type 'todo_list'
1375
+ * 2. Result display as JSON string
1376
+ * 3. Args with 'todos' array when no result display is available
1377
+ *
1378
+ * @param resultDisplay - The tool result display (object, string, or undefined)
1379
+ * @param args - The tool call arguments (fallback source)
1380
+ * @returns Plan snapshot if found, null otherwise
1381
+ */
1382
+ extractPlan(resultDisplay, args) {
1383
+ const plan = extractTranscriptTodoPlan(resultDisplay, args);
1384
+ if (!plan) return null;
1385
+ return {
1386
+ ...plan.planId ? { planId: plan.planId } : {},
1387
+ todos: plan.todos.map((todo, index) => ({
1388
+ id: todo.id ?? String(index),
1389
+ content: todo.content,
1390
+ status: todo.status,
1391
+ ...todo.blockedBy ? { blockedBy: [...todo.blockedBy] } : {}
1392
+ }))
1393
+ };
1394
+ }
1395
+ };
1396
+
1397
+ // packages/cli/src/acp-integration/session/types.ts
1398
+ init_esbuild_shims();
1399
+ function hasFullSessionContext(context) {
1400
+ return "config" in context;
1401
+ }
1402
+ __name(hasFullSessionContext, "hasFullSessionContext");
1403
+
1404
+ // packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
1405
+ var KIND_MAP = {
1406
+ ["read" /* Read */]: "read",
1407
+ ["edit" /* Edit */]: "edit",
1408
+ ["delete" /* Delete */]: "delete",
1409
+ ["move" /* Move */]: "move",
1410
+ ["search" /* Search */]: "search",
1411
+ ["execute" /* Execute */]: "execute",
1412
+ ["think" /* Think */]: "think",
1413
+ ["fetch" /* Fetch */]: "fetch",
1414
+ // ACP defines no 'agent' ToolKind (verified through @agentclientprotocol/sdk
1415
+ // 0.25.1). The daemon's ClientSideConnection Zod-validates every session/update
1416
+ // and session/request_permission from the `qwen --acp` child before fanning out
1417
+ // to SSE clients, so emitting 'agent' is rejected at that hop and the frame is
1418
+ // dropped. Map the internal Kind.Agent to 'other' on the wire to stay
1419
+ // protocol-valid; dedicated agent UI is delivered out-of-band (via _meta.toolName)
1420
+ // in a follow-up rather than via a kind the protocol can't carry.
1421
+ ["agent" /* Agent */]: "other",
1422
+ ["other" /* Other */]: "other"
1423
+ };
1424
+ var ToolCallEmitter = class _ToolCallEmitter extends BaseEmitter {
1998
1425
  static {
1999
- __name(this, "MessageEmitter");
1426
+ __name(this, "ToolCallEmitter");
1427
+ }
1428
+ planEmitter;
1429
+ preparedCallIds = /* @__PURE__ */ new Set();
1430
+ constructor(ctx) {
1431
+ super(ctx);
1432
+ this.planEmitter = new PlanEmitter(ctx);
2000
1433
  }
2001
1434
  /**
2002
- * Emits a StopHookLoop event when Stop hooks create a loop.
2003
- * This informs the client that Stop hooks have been executed multiple times.
1435
+ * Emits a tool call start event.
2004
1436
  *
2005
- * @param iterationCount - The current iteration count
2006
- * @param reasons - Array of reasons from each Stop hook execution
2007
- * @param stopHookCount - Number of Stop hooks that were executed
1437
+ * @param params - Tool call start parameters
1438
+ * @returns true if event was emitted, false if skipped (e.g., TodoWriteTool)
2008
1439
  */
2009
- async emitStopHookLoop(iterationCount, reasons, stopHookCount) {
2010
- const activeGoal = getActiveGoal(this.sessionId);
2011
- await this.sendUpdate({
2012
- sessionUpdate: "agent_message_chunk",
2013
- content: { type: "text", text: "" },
2014
- _meta: {
2015
- stopHookLoop: {
2016
- iterationCount,
2017
- reasons,
2018
- stopHookCount,
2019
- ...activeGoal ? {
2020
- goal: {
2021
- condition: activeGoal.condition,
2022
- iterations: activeGoal.iterations,
2023
- setAt: activeGoal.setAt,
2024
- lastReason: activeGoal.lastReason
2025
- }
2026
- } : {}
1440
+ async emitStart(params) {
1441
+ if (this.isTodoWriteTool(params.toolName)) {
1442
+ return false;
1443
+ }
1444
+ if (params.phase === "preparing" && this.preparedCallIds.has(params.callId)) {
1445
+ return false;
1446
+ }
1447
+ const { title, locations, kind } = this.resolveToolMetadata(
1448
+ params.toolName,
1449
+ params.args
1450
+ );
1451
+ const provenance = _ToolCallEmitter.resolveToolProvenance(
1452
+ params.toolName,
1453
+ params.subagentMeta
1454
+ );
1455
+ const updatesPreparedCall = params.phase !== "preparing" && this.preparedCallIds.delete(params.callId);
1456
+ await this.sendUpdate(
1457
+ createTranscriptToolCallStartUpdate({
1458
+ toolName: params.toolName,
1459
+ callId: params.callId,
1460
+ status: params.status || "pending",
1461
+ args: params.args,
1462
+ metadata: { title, locations, kind },
1463
+ timestamp: params.timestamp,
1464
+ asUpdate: updatesPreparedCall,
1465
+ extra: {
1466
+ ...params.phase ? { phase: params.phase } : {},
1467
+ ...params.subagentMeta,
1468
+ provenance: provenance.provenance,
1469
+ ...provenance.serverId ? { serverId: provenance.serverId } : {}
2027
1470
  }
2028
- }
2029
- });
2030
- }
2031
- async emitGoalTerminal(event) {
2032
- await this.sendUpdate({
2033
- sessionUpdate: "agent_message_chunk",
2034
- content: { type: "text", text: "" },
2035
- _meta: {
2036
- goalTerminal: event
2037
- }
2038
- });
1471
+ })
1472
+ );
1473
+ if (params.phase === "preparing") {
1474
+ this.preparedCallIds.add(params.callId);
1475
+ }
1476
+ return true;
2039
1477
  }
2040
- async emitGoalStatus(status) {
1478
+ /**
1479
+ * Emits a terminal frame when a prepared tool call is discarded before
1480
+ * execution. TodoWrite remains represented exclusively by plan updates.
1481
+ *
1482
+ * @param callId - ID of the prepared tool call
1483
+ * @param toolName - Name of the prepared tool
1484
+ */
1485
+ async emitPreparationDiscarded(callId, toolName) {
1486
+ if (this.isTodoWriteTool(toolName)) return;
1487
+ this.preparedCallIds.delete(callId);
1488
+ const provenance = _ToolCallEmitter.resolveToolProvenance(toolName);
2041
1489
  await this.sendUpdate({
2042
- sessionUpdate: "agent_message_chunk",
2043
- content: { type: "text", text: "" },
1490
+ sessionUpdate: "tool_call_update",
1491
+ toolCallId: callId,
1492
+ status: "failed",
1493
+ content: [],
2044
1494
  _meta: {
2045
- goalStatus: status
1495
+ toolName,
1496
+ phase: "preparing",
1497
+ preparationDiscarded: true,
1498
+ provenance: provenance.provenance,
1499
+ ...provenance.serverId ? { serverId: provenance.serverId } : {}
2046
1500
  }
2047
1501
  });
2048
1502
  }
2049
1503
  /**
2050
- * Emits a user message chunk.
1504
+ * Emits a tool call result event.
1505
+ * Handles TodoWriteTool specially by routing to plan updates.
2051
1506
  *
2052
- * @param text - The user message text content
2053
- * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
1507
+ * @param params - Tool call result parameters
2054
1508
  */
2055
- async emitUserMessage(text, timestamp, options = {}) {
1509
+ async emitResult(params) {
1510
+ if (this.isTodoWriteTool(params.toolName)) {
1511
+ if (params.subagentMeta) return;
1512
+ if (!params.success) return;
1513
+ const plan = this.planEmitter.extractPlan(
1514
+ params.resultDisplay,
1515
+ params.args
1516
+ );
1517
+ if (plan && (plan.todos.length > 0 || params.args && Array.isArray(params.args["todos"]))) {
1518
+ await this.planEmitter.emitPlan(plan, params.callId);
1519
+ }
1520
+ return;
1521
+ }
1522
+ this.preparedCallIds.delete(params.callId);
1523
+ const provenance = _ToolCallEmitter.resolveToolProvenance(
1524
+ params.toolName,
1525
+ params.subagentMeta
1526
+ );
2056
1527
  await this.sendUpdate(
2057
- createTranscriptMessageUpdate({
2058
- role: "user",
2059
- text,
2060
- timestamp,
2061
- ...options.source ? { extra: { source: options.source } } : {}
1528
+ createTranscriptToolCallResultUpdate({
1529
+ toolName: params.toolName,
1530
+ callId: params.callId,
1531
+ success: params.success,
1532
+ message: params.message,
1533
+ resultDisplay: params.resultDisplay,
1534
+ errorMessage: params.error?.message,
1535
+ artifacts: params.artifacts,
1536
+ contentPrefix: buildToolResultContentPrefix(params.resultDisplay),
1537
+ timestamp: params.timestamp,
1538
+ extra: {
1539
+ ...params.subagentMeta,
1540
+ provenance: provenance.provenance,
1541
+ ...provenance.serverId ? { serverId: provenance.serverId } : {}
1542
+ }
2062
1543
  })
2063
1544
  );
2064
1545
  }
2065
1546
  /**
2066
- * Emits an agent thought chunk.
1547
+ * Emits a tool call error event.
1548
+ * Use this for explicit error handling when not using emitResult.
2067
1549
  *
2068
- * @param text - The thought text content
2069
- * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
1550
+ * @param callId - The tool call ID
1551
+ * @param toolName - The tool name
1552
+ * @param error - The error that occurred
1553
+ * @param subagentMeta - Optional subagent metadata
2070
1554
  */
2071
- async emitAgentThought(text, timestamp, subagentMeta) {
1555
+ async emitError(callId, toolName, error, subagentMeta) {
1556
+ this.preparedCallIds.delete(callId);
1557
+ const provenance = _ToolCallEmitter.resolveToolProvenance(
1558
+ toolName,
1559
+ subagentMeta
1560
+ );
2072
1561
  await this.sendUpdate(
2073
- createTranscriptMessageUpdate({
2074
- role: "assistant",
2075
- thought: true,
2076
- text,
2077
- timestamp,
2078
- ...subagentMeta ? { extra: { ...subagentMeta } } : {}
1562
+ createTranscriptToolCallResultUpdate({
1563
+ toolName,
1564
+ callId,
1565
+ success: false,
1566
+ errorMessage: error.message,
1567
+ extra: {
1568
+ ...subagentMeta,
1569
+ provenance: provenance.provenance,
1570
+ ...provenance.serverId ? { serverId: provenance.serverId } : {}
1571
+ }
2079
1572
  })
2080
1573
  );
2081
1574
  }
2082
1575
  /**
2083
- * Emits an agent message chunk.
1576
+ * Resolve a tool's provenance for UI dispatch on tool_call events.
1577
+ * The SDK reads `_meta.
1578
+ * provenance` + `_meta.serverId` to render builtin / MCP-server-badge /
1579
+ * subagent-block differently. Without this stamping, the SDK falls
1580
+ * back to string-matching the toolName which can't reliably
1581
+ * distinguish builtin from subagent.
1582
+ *
1583
+ * Resolution rules:
1584
+ * - `subagentMeta` present → `'subagent'` (a Task tool / Codex
1585
+ * subagent / etc. wrapping its own tool calls)
1586
+ * - toolName matches `mcp__<server>__<tool>` → `'mcp'` with
1587
+ * `serverId: <server>`. Naming convention from
1588
+ * `packages/core/src/tools/mcp-tool.ts` in the
1589
+ * `@qwen-code/qwen-code-core` package — mirrors the SDK's same
1590
+ * heuristic fallback so SDK consumers stay consistent with
1591
+ * daemon classification.
1592
+ * - everything else → `'builtin'`
1593
+ *
1594
+ * Static + pure so it can be unit-tested without an emitter
1595
+ * instance. Exported via `ToolCallEmitter.resolveToolProvenance`.
1596
+ */
1597
+ static resolveToolProvenance(toolName, subagentMeta) {
1598
+ if (subagentMeta !== void 0) {
1599
+ return { provenance: "subagent" };
1600
+ }
1601
+ if (toolName.startsWith("mcp__")) {
1602
+ const parts = toolName.split("__");
1603
+ if (parts.length >= 3 && parts[1] && parts[1].length > 0) {
1604
+ return { provenance: "mcp", serverId: parts[1] };
1605
+ }
1606
+ }
1607
+ return { provenance: "builtin" };
1608
+ }
1609
+ // ==================== Public Utilities ====================
1610
+ /**
1611
+ * Checks if a tool name is the TodoWriteTool.
1612
+ * Exposed for external use in components that need to check this.
1613
+ */
1614
+ isTodoWriteTool(toolName) {
1615
+ return toolName === ToolNames.TODO_WRITE;
1616
+ }
1617
+ /**
1618
+ * Checks if a tool name is the ExitPlanModeTool.
1619
+ */
1620
+ isExitPlanModeTool(toolName) {
1621
+ return toolName === ToolNames.EXIT_PLAN_MODE;
1622
+ }
1623
+ /**
1624
+ * Checks if a tool name is the EnterPlanModeTool.
1625
+ */
1626
+ isEnterPlanModeTool(toolName) {
1627
+ return toolName === ToolNames.ENTER_PLAN_MODE;
1628
+ }
1629
+ /**
1630
+ * Resolves tool metadata from the registry.
1631
+ * Falls back to defaults if tool not found or build fails.
2084
1632
  *
2085
- * @param text - The agent message text content
2086
- * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
1633
+ * @param toolName - Name of the tool
1634
+ * @param args - Tool call arguments (used to build invocation)
2087
1635
  */
2088
- async emitAgentMessage(text, timestamp, subagentMeta) {
2089
- await this.sendUpdate(
2090
- createTranscriptMessageUpdate({
2091
- role: "assistant",
2092
- text,
2093
- timestamp,
2094
- ...subagentMeta ? { extra: { ...subagentMeta } } : {}
2095
- })
2096
- );
1636
+ resolveToolMetadata(toolName, args) {
1637
+ if (!hasFullSessionContext(this.ctx)) {
1638
+ const description = typeof args?.["description"] === "string" ? args["description"].trim() : "";
1639
+ return {
1640
+ title: description ? `${toolName}: ${description}` : toolName,
1641
+ locations: [],
1642
+ kind: "other"
1643
+ };
1644
+ }
1645
+ const toolRegistry = this.ctx.config.getToolRegistry();
1646
+ const tool = toolRegistry.getTool(toolName);
1647
+ let title = tool?.displayName ?? toolName;
1648
+ let locations = [];
1649
+ let kind = "other";
1650
+ if (tool && args) {
1651
+ try {
1652
+ const invocation = tool.build(args);
1653
+ title = `${title}: ${invocation.getDescription()}`;
1654
+ locations = invocation.toolLocations().map((loc) => ({
1655
+ path: loc.path,
1656
+ line: loc.line ?? null
1657
+ }));
1658
+ kind = this.mapToolKind(tool.kind, toolName);
1659
+ } catch {
1660
+ if (typeof args["description"] === "string") {
1661
+ title = `${title}: ${args["description"]}`;
1662
+ }
1663
+ if (tool.kind) {
1664
+ kind = this.mapToolKind(tool.kind, toolName);
1665
+ }
1666
+ }
1667
+ }
1668
+ return { title, locations, kind };
1669
+ }
1670
+ /**
1671
+ * Maps core Tool Kind enum to ACP ToolKind string literals.
1672
+ *
1673
+ * @param kind - The core Kind enum value
1674
+ * @param toolName - Optional tool name to handle special cases like exit_plan_mode
1675
+ */
1676
+ mapToolKind(kind, toolName) {
1677
+ if (toolName && (this.isExitPlanModeTool(toolName) || this.isEnterPlanModeTool(toolName))) {
1678
+ return "switch_mode";
1679
+ }
1680
+ return KIND_MAP[kind] ?? "other";
1681
+ }
1682
+ };
1683
+ function buildToolResultContentPrefix(resultDisplay) {
1684
+ if (!isVisionBridgeNoticeDisplay(resultDisplay)) return [];
1685
+ return [
1686
+ {
1687
+ type: "content",
1688
+ content: {
1689
+ type: "text",
1690
+ text: sanitizeTerminalText(
1691
+ formatVisionBridgeNoticeDisplay(resultDisplay)
1692
+ )
1693
+ }
1694
+ }
1695
+ ];
1696
+ }
1697
+ __name(buildToolResultContentPrefix, "buildToolResultContentPrefix");
1698
+
1699
+ // packages/cli/src/acp-integration/session/history-replayer.ts
1700
+ var HistoryReplayer = class {
1701
+ constructor(ctx) {
1702
+ this.ctx = ctx;
1703
+ this.toolCallEmitter = new ToolCallEmitter(ctx);
1704
+ this.machine = this.createMachine();
2097
1705
  }
2098
- async emitSlashCommandOutput(text, timestamp) {
2099
- const epochMs = BaseEmitter.toEpochMs(timestamp);
2100
- await this.sendUpdate({
2101
- sessionUpdate: "agent_message_chunk",
2102
- content: { type: "text", text },
2103
- _meta: {
2104
- source: "slash_command",
2105
- ...epochMs != null ? { timestamp: epochMs } : {}
1706
+ static {
1707
+ __name(this, "HistoryReplayer");
1708
+ }
1709
+ toolCallEmitter;
1710
+ machine;
1711
+ async replay(records, gaps, options = {}) {
1712
+ try {
1713
+ if (options.goalBootstrap) {
1714
+ const update = {
1715
+ sessionUpdate: "agent_message_chunk",
1716
+ content: { type: "text", text: "" },
1717
+ _meta: {
1718
+ ...options.goalBootstrap.goalState ? { goalState: options.goalBootstrap.goalState } : {},
1719
+ goalStatus: options.goalBootstrap.goalStatus
1720
+ }
1721
+ };
1722
+ await this.sendUpdate(update);
2106
1723
  }
1724
+ await this.replayPage(records, {
1725
+ finalizeDangling: true,
1726
+ gaps,
1727
+ ...options.initialGoalState ? { goalState: options.initialGoalState } : {},
1728
+ ...options.initialGoalCause ? { goalCause: options.initialGoalCause } : {}
1729
+ });
1730
+ } finally {
1731
+ this.setActiveRecordId(null);
1732
+ }
1733
+ }
1734
+ static v2GoalBootstrap(rawGoalState, rawGoalCause) {
1735
+ const goalState = parseGoalSnapshotV2(rawGoalState);
1736
+ const goalCause = parseGoalStateCause(rawGoalCause);
1737
+ if (!goalState?.goal || goalState.goal.status !== "active" || !goalCause) {
1738
+ return void 0;
1739
+ }
1740
+ const projection = projectGoalStateToLegacy({
1741
+ v: 2,
1742
+ cause: goalCause,
1743
+ snapshot: goalState
2107
1744
  });
1745
+ const { type: _type, kind, ...goalStatus } = projection.goalStatus;
1746
+ if (kind !== "set" && kind !== "checking") {
1747
+ return void 0;
1748
+ }
1749
+ return { goalStatus: { ...goalStatus, kind }, goalState };
2108
1750
  }
2109
- /**
2110
- * Emits usage metadata.
2111
- */
2112
- async emitUsageMetadata(usageMetadata, text = "", durationMs, subagentMeta) {
2113
- const cumulative = this.ctx.cumulativeUsage;
2114
- if (cumulative) {
2115
- const addFinite = /* @__PURE__ */ __name((total, value) => typeof value === "number" && Number.isFinite(value) ? total + value : total, "addFinite");
2116
- cumulative.promptTokens = addFinite(
2117
- cumulative.promptTokens,
2118
- usageMetadata.promptTokenCount
2119
- );
2120
- cumulative.candidateTokens = addFinite(
2121
- cumulative.candidateTokens,
2122
- usageMetadata.candidatesTokenCount
2123
- );
2124
- cumulative.cachedTokens = addFinite(
2125
- cumulative.cachedTokens,
2126
- usageMetadata.cachedContentTokenCount
2127
- );
2128
- cumulative.apiTimeMs = addFinite(cumulative.apiTimeMs, durationMs);
2129
- }
2130
- let activityMeta = {};
2131
- if (typeof durationMs === "number") {
2132
- const activity = apiActivityTracker.drain();
2133
- activityMeta = {
2134
- ...activity.errors > 0 ? { apiErrors: activity.errors } : {},
2135
- ...activity.retries > 0 ? { apiRetries: activity.retries } : {}
2136
- };
1751
+ async replayPage(records, options = {}) {
1752
+ this.machine = this.createMachine(options);
1753
+ let replayError;
1754
+ try {
1755
+ for (const record of records) {
1756
+ for (const emission of this.machine.project(record)) {
1757
+ this.setActiveRecordId(
1758
+ emission.sourceRecordId,
1759
+ emission.sourceTimestamp
1760
+ );
1761
+ await this.sendUpdate(emission.update);
1762
+ }
1763
+ }
1764
+ } catch (error) {
1765
+ replayError = error;
2137
1766
  }
2138
- await this.sendUpdate(
2139
- createTranscriptUsageUpdate(usageMetadata, {
2140
- text,
2141
- extra: {
2142
- ...typeof durationMs === "number" ? { durationMs } : {},
2143
- ...activityMeta,
2144
- ...subagentMeta
1767
+ let danglingError;
1768
+ if (options.finalizeDangling === true) {
1769
+ for (const emission of this.machine.finalize()) {
1770
+ this.setActiveRecordId(
1771
+ emission.sourceRecordId,
1772
+ emission.sourceTimestamp
1773
+ );
1774
+ try {
1775
+ await this.sendUpdate(emission.update);
1776
+ } catch (error) {
1777
+ danglingError ??= error;
2145
1778
  }
2146
- })
2147
- );
2148
- if (!Number.isFinite(durationMs) || subagentMeta || !hasFullSessionContext(this.ctx)) {
2149
- return;
1779
+ }
2150
1780
  }
2151
- const used = usageMetadata.promptTokenCount ?? usageMetadata.totalTokenCount;
2152
- const size = this.ctx.config.getContentGeneratorConfig()?.contextWindowSize;
2153
- if (typeof used !== "number" || !Number.isSafeInteger(used) || used < 0 || typeof size !== "number" || !Number.isSafeInteger(size) || size <= 0) {
2154
- return;
1781
+ const replay = this.machine.snapshot();
1782
+ this.copyCumulativeUsage(replay);
1783
+ const state = {
1784
+ pendingToolCalls: options.finalizeDangling === true ? [] : replay.pendingToolCalls.map(toLegacyPendingToolCall),
1785
+ replay
1786
+ };
1787
+ this.setActiveRecordId(null);
1788
+ if (replayError && danglingError) {
1789
+ throw new AggregateError(
1790
+ [replayError, danglingError],
1791
+ "Replay and dangling-cleanup both failed"
1792
+ );
2155
1793
  }
2156
- await this.sendUpdate({
2157
- sessionUpdate: "usage_update",
2158
- used,
2159
- size
2160
- });
1794
+ if (replayError) throw replayError;
1795
+ if (danglingError) throw danglingError;
1796
+ return state;
2161
1797
  }
2162
- /**
2163
- * Emits a message chunk based on role and thought flag.
2164
- * This is the unified method that handles all message types.
2165
- *
2166
- * @param text - The message text content
2167
- * @param role - Whether this is a user or assistant message
2168
- * @param isThought - Whether this is an assistant thought (only applies to assistant role)
2169
- * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
2170
- */
2171
- async emitMessage(text, role, isThought = false, timestamp, subagentMeta) {
2172
- if (role === "user") {
2173
- return this.emitUserMessage(text, timestamp);
2174
- }
2175
- return isThought ? this.emitAgentThought(text, timestamp, subagentMeta) : this.emitAgentMessage(text, timestamp, subagentMeta);
1798
+ getPendingToolCalls() {
1799
+ return this.machine.snapshot().pendingToolCalls.map(toLegacyPendingToolCall);
2176
1800
  }
2177
- };
2178
-
2179
- // packages/cli/src/acp-integration/session/emitters/PlanEmitter.ts
2180
- init_esbuild_shims();
2181
- var PlanEmitter = class extends BaseEmitter {
2182
- static {
2183
- __name(this, "PlanEmitter");
1801
+ getReplayState() {
1802
+ return this.machine.snapshot();
2184
1803
  }
2185
- /**
2186
- * Emits a plan update with the given todo items.
2187
- *
2188
- * @param plan - Plan identity and todo items to send as plan entries
2189
- */
2190
- async emitPlan(plan, sourceCallId) {
1804
+ createMachine(options = {}) {
2191
1805
  const cumulative = this.ctx.cumulativeUsage;
2192
- await this.sendUpdate(
2193
- createTranscriptPlanUpdate(plan.todos, cumulative, {
2194
- planToolCallId: sourceCallId,
2195
- todoPlanId: plan.planId
2196
- })
2197
- );
1806
+ const initialState = {
1807
+ v: 1,
1808
+ pendingToolCalls: (options.pendingToolCalls ?? []).map(
1809
+ toPendingTranscriptToolCall
1810
+ ),
1811
+ cumulativeUsage: cumulative ? { ...cumulative } : {
1812
+ promptTokens: 0,
1813
+ cachedTokens: 0,
1814
+ candidateTokens: 0,
1815
+ apiTimeMs: 0
1816
+ },
1817
+ ...options.goalState ? { goalState: options.goalState } : {},
1818
+ ...options.goalCause ? { goalCause: options.goalCause } : {}
1819
+ };
1820
+ return createTranscriptReplayMachine({
1821
+ initialState,
1822
+ gaps: options.gaps,
1823
+ presentation: this.presentationAdapter(),
1824
+ onDiagnostic: /* @__PURE__ */ __name((diagnostic) => {
1825
+ if (diagnostic.code === "malformed_part" && diagnostic.path === "systemPayload.outputHistoryItems.goalStatus.condition") {
1826
+ writeStderrLineSafe(`qwen: ${diagnostic.message}`);
1827
+ }
1828
+ }, "onDiagnostic")
1829
+ });
2198
1830
  }
2199
- /**
2200
- * Extracts todos from tool result display or args.
2201
- * Tries multiple sources in priority order:
2202
- * 1. Result display object with type 'todo_list'
2203
- * 2. Result display as JSON string
2204
- * 3. Args with 'todos' array when no result display is available
2205
- *
2206
- * @param resultDisplay - The tool result display (object, string, or undefined)
2207
- * @param args - The tool call arguments (fallback source)
2208
- * @returns Plan snapshot if found, null otherwise
2209
- */
2210
- extractPlan(resultDisplay, args) {
2211
- const plan = extractTranscriptTodoPlan(resultDisplay, args);
2212
- if (!plan) return null;
1831
+ presentationAdapter() {
2213
1832
  return {
2214
- ...plan.planId ? { planId: plan.planId } : {},
2215
- todos: plan.todos.map((todo, index) => ({
2216
- id: todo.id ?? String(index),
2217
- content: todo.content,
2218
- status: todo.status,
2219
- ...todo.blockedBy ? { blockedBy: [...todo.blockedBy] } : {}
2220
- }))
1833
+ resolveToolMetadata: /* @__PURE__ */ __name((toolName, args) => this.toolCallEmitter.resolveToolMetadata(toolName, { ...args }), "resolveToolMetadata"),
1834
+ formatHistoryGap: /* @__PURE__ */ __name((gap) => formatHistoryGapNotice(gap), "formatHistoryGap"),
1835
+ buildToolResultContentPrefix
2221
1836
  };
2222
1837
  }
1838
+ async sendUpdate(update) {
1839
+ if (this.ctx.messageRewriter) {
1840
+ await this.ctx.messageRewriter.interceptUpdate(update);
1841
+ return;
1842
+ }
1843
+ await this.ctx.sendUpdate(update);
1844
+ }
1845
+ copyCumulativeUsage(state) {
1846
+ const cumulative = this.ctx.cumulativeUsage;
1847
+ if (!cumulative) return;
1848
+ cumulative.promptTokens = state.cumulativeUsage.promptTokens;
1849
+ cumulative.cachedTokens = state.cumulativeUsage.cachedTokens;
1850
+ cumulative.candidateTokens = state.cumulativeUsage.candidateTokens;
1851
+ cumulative.apiTimeMs = state.cumulativeUsage.apiTimeMs;
1852
+ }
1853
+ setActiveRecordId(recordId, timestamp) {
1854
+ this.ctx.setActiveRecordId?.(recordId, timestamp);
1855
+ }
2223
1856
  };
1857
+ function toPendingTranscriptToolCall(pending) {
1858
+ return {
1859
+ callId: pending.callId,
1860
+ toolName: pending.toolName,
1861
+ sourceRecordId: pending.recordId,
1862
+ ...pending.timestamp ? { sourceTimestamp: pending.timestamp } : {}
1863
+ };
1864
+ }
1865
+ __name(toPendingTranscriptToolCall, "toPendingTranscriptToolCall");
1866
+ function toLegacyPendingToolCall(pending) {
1867
+ return {
1868
+ callId: pending.callId,
1869
+ toolName: pending.toolName,
1870
+ recordId: pending.sourceRecordId,
1871
+ ...pending.sourceTimestamp ? { timestamp: pending.sourceTimestamp } : {}
1872
+ };
1873
+ }
1874
+ __name(toLegacyPendingToolCall, "toLegacyPendingToolCall");
2224
1875
 
2225
- // packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
1876
+ // packages/cli/src/services/setup-github.ts
2226
1877
  init_esbuild_shims();
2227
- var KIND_MAP = {
2228
- ["read" /* Read */]: "read",
2229
- ["edit" /* Edit */]: "edit",
2230
- ["delete" /* Delete */]: "delete",
2231
- ["move" /* Move */]: "move",
2232
- ["search" /* Search */]: "search",
2233
- ["execute" /* Execute */]: "execute",
2234
- ["think" /* Think */]: "think",
2235
- ["fetch" /* Fetch */]: "fetch",
2236
- // ACP defines no 'agent' ToolKind (verified through @agentclientprotocol/sdk
2237
- // 0.25.1). The daemon's ClientSideConnection Zod-validates every session/update
2238
- // and session/request_permission from the `qwen --acp` child before fanning out
2239
- // to SSE clients, so emitting 'agent' is rejected at that hop and the frame is
2240
- // dropped. Map the internal Kind.Agent to 'other' on the wire to stay
2241
- // protocol-valid; dedicated agent UI is delivered out-of-band (via _meta.toolName)
2242
- // in a follow-up rather than via a kind the protocol can't carry.
2243
- ["agent" /* Agent */]: "other",
2244
- ["other" /* Other */]: "other"
2245
- };
2246
- var ToolCallEmitter = class _ToolCallEmitter extends BaseEmitter {
2247
- static {
2248
- __name(this, "ToolCallEmitter");
2249
- }
2250
- planEmitter;
2251
- preparedCallIds = /* @__PURE__ */ new Set();
2252
- constructor(ctx) {
2253
- super(ctx);
2254
- this.planEmitter = new PlanEmitter(ctx);
2255
- }
2256
- /**
2257
- * Emits a tool call start event.
2258
- *
2259
- * @param params - Tool call start parameters
2260
- * @returns true if event was emitted, false if skipped (e.g., TodoWriteTool)
2261
- */
2262
- async emitStart(params) {
2263
- if (this.isTodoWriteTool(params.toolName)) {
2264
- return false;
2265
- }
2266
- if (params.phase === "preparing" && this.preparedCallIds.has(params.callId)) {
2267
- return false;
2268
- }
2269
- const { title, locations, kind } = this.resolveToolMetadata(
2270
- params.toolName,
2271
- params.args
2272
- );
2273
- const provenance = _ToolCallEmitter.resolveToolProvenance(
2274
- params.toolName,
2275
- params.subagentMeta
2276
- );
2277
- const updatesPreparedCall = params.phase !== "preparing" && this.preparedCallIds.delete(params.callId);
2278
- await this.sendUpdate(
2279
- createTranscriptToolCallStartUpdate({
2280
- toolName: params.toolName,
2281
- callId: params.callId,
2282
- status: params.status || "pending",
2283
- args: params.args,
2284
- metadata: { title, locations, kind },
2285
- timestamp: params.timestamp,
2286
- asUpdate: updatesPreparedCall,
2287
- extra: {
2288
- ...params.phase ? { phase: params.phase } : {},
2289
- ...params.subagentMeta,
2290
- provenance: provenance.provenance,
2291
- ...provenance.serverId ? { serverId: provenance.serverId } : {}
1878
+ import { promises as fsp } from "node:fs";
1879
+ import * as path from "node:path";
1880
+
1881
+ // packages/cli/src/utils/gitUtils.ts
1882
+ init_esbuild_shims();
1883
+ import * as childProcess from "node:child_process";
1884
+ var debugLogger = createDebugLogger("GIT");
1885
+ async function runGit(args, opts = {}) {
1886
+ return await new Promise((resolve2, reject) => {
1887
+ childProcess.execFile(
1888
+ "git",
1889
+ args,
1890
+ {
1891
+ encoding: "utf-8",
1892
+ ...opts.cwd ? { cwd: opts.cwd } : {}
1893
+ },
1894
+ (err, stdout) => {
1895
+ if (err) {
1896
+ reject(err);
1897
+ return;
2292
1898
  }
2293
- })
1899
+ resolve2(String(stdout ?? "").trim());
1900
+ }
2294
1901
  );
2295
- if (params.phase === "preparing") {
2296
- this.preparedCallIds.add(params.callId);
2297
- }
1902
+ });
1903
+ }
1904
+ __name(runGit, "runGit");
1905
+ var isGitHubRepositoryAsync = /* @__PURE__ */ __name(async (opts = {}) => {
1906
+ try {
1907
+ const remotes = await runGit(["remote", "-v"], opts);
1908
+ return remotes.split("\n").some((line) => {
1909
+ const remoteUrl = line.trim().split(/\s+/)[1];
1910
+ return remoteUrl ? isGitHubRemoteUrl(remoteUrl) : false;
1911
+ });
1912
+ } catch (_error) {
1913
+ debugLogger.debug(`Failed to get git remote:`, _error);
1914
+ return false;
1915
+ }
1916
+ }, "isGitHubRepositoryAsync");
1917
+ function isGitHubRemoteUrl(remoteUrl) {
1918
+ if (remoteUrl.startsWith("git@github.com:")) {
2298
1919
  return true;
2299
1920
  }
2300
- /**
2301
- * Emits a terminal frame when a prepared tool call is discarded before
2302
- * execution. TodoWrite remains represented exclusively by plan updates.
2303
- *
2304
- * @param callId - ID of the prepared tool call
2305
- * @param toolName - Name of the prepared tool
2306
- */
2307
- async emitPreparationDiscarded(callId, toolName) {
2308
- if (this.isTodoWriteTool(toolName)) return;
2309
- this.preparedCallIds.delete(callId);
2310
- const provenance = _ToolCallEmitter.resolveToolProvenance(toolName);
2311
- await this.sendUpdate({
2312
- sessionUpdate: "tool_call_update",
2313
- toolCallId: callId,
2314
- status: "failed",
2315
- content: [],
2316
- _meta: {
2317
- toolName,
2318
- phase: "preparing",
2319
- preparationDiscarded: true,
2320
- provenance: provenance.provenance,
2321
- ...provenance.serverId ? { serverId: provenance.serverId } : {}
2322
- }
2323
- });
1921
+ if (remoteUrl.startsWith("git@")) {
1922
+ return false;
2324
1923
  }
2325
- /**
2326
- * Emits a tool call result event.
2327
- * Handles TodoWriteTool specially by routing to plan updates.
2328
- *
2329
- * @param params - Tool call result parameters
2330
- */
2331
- async emitResult(params) {
2332
- if (this.isTodoWriteTool(params.toolName)) {
2333
- if (params.subagentMeta) return;
2334
- if (!params.success) return;
2335
- const plan = this.planEmitter.extractPlan(
2336
- params.resultDisplay,
2337
- params.args
1924
+ try {
1925
+ return new URL(remoteUrl).hostname === "github.com";
1926
+ } catch {
1927
+ return false;
1928
+ }
1929
+ }
1930
+ __name(isGitHubRemoteUrl, "isGitHubRemoteUrl");
1931
+ var getGitRepoRootAsync = /* @__PURE__ */ __name(async (opts = {}) => {
1932
+ const gitRepoRoot = await runGit(["rev-parse", "--show-toplevel"], opts);
1933
+ if (!gitRepoRoot) {
1934
+ throw new Error(`Git repo returned empty value`);
1935
+ }
1936
+ return gitRepoRoot;
1937
+ }, "getGitRepoRootAsync");
1938
+ var getLatestGitHubRelease = /* @__PURE__ */ __name(async (proxy) => {
1939
+ try {
1940
+ const controller = new AbortController();
1941
+ const endpoint = `https://api.github.com/repos/QwenLM/qwen-code-action/releases/latest`;
1942
+ const dispatcher = proxy ? new (await loadUndici()).ProxyAgent(proxy) : void 0;
1943
+ const response = await fetch(endpoint, {
1944
+ method: "GET",
1945
+ headers: {
1946
+ Accept: "application/vnd.github+json",
1947
+ "Content-Type": "application/json",
1948
+ "X-GitHub-Api-Version": "2022-11-28"
1949
+ },
1950
+ dispatcher,
1951
+ signal: AbortSignal.any([AbortSignal.timeout(3e4), controller.signal])
1952
+ });
1953
+ if (!response.ok) {
1954
+ throw new Error(
1955
+ `Invalid response code: ${response.status} - ${response.statusText}`
2338
1956
  );
2339
- if (plan && (plan.todos.length > 0 || params.args && Array.isArray(params.args["todos"]))) {
2340
- await this.planEmitter.emitPlan(plan, params.callId);
2341
- }
2342
- return;
2343
1957
  }
2344
- this.preparedCallIds.delete(params.callId);
2345
- const provenance = _ToolCallEmitter.resolveToolProvenance(
2346
- params.toolName,
2347
- params.subagentMeta
1958
+ const releaseTag = (await response.json()).tag_name;
1959
+ if (!releaseTag) {
1960
+ throw new Error(`Response did not include tag_name field`);
1961
+ }
1962
+ return releaseTag;
1963
+ } catch (_error) {
1964
+ debugLogger.debug(
1965
+ `Failed to determine latest qwen-code-action release:`,
1966
+ _error
2348
1967
  );
2349
- await this.sendUpdate(
2350
- createTranscriptToolCallResultUpdate({
2351
- toolName: params.toolName,
2352
- callId: params.callId,
2353
- success: params.success,
2354
- message: params.message,
2355
- resultDisplay: params.resultDisplay,
2356
- errorMessage: params.error?.message,
2357
- artifacts: params.artifacts,
2358
- contentPrefix: buildToolResultContentPrefix(params.resultDisplay),
2359
- timestamp: params.timestamp,
2360
- extra: {
2361
- ...params.subagentMeta,
2362
- provenance: provenance.provenance,
2363
- ...provenance.serverId ? { serverId: provenance.serverId } : {}
2364
- }
2365
- })
1968
+ throw new Error(
1969
+ `Unable to determine the latest qwen-code-action release on GitHub.`
2366
1970
  );
2367
1971
  }
2368
- /**
2369
- * Emits a tool call error event.
2370
- * Use this for explicit error handling when not using emitResult.
2371
- *
2372
- * @param callId - The tool call ID
2373
- * @param toolName - The tool name
2374
- * @param error - The error that occurred
2375
- * @param subagentMeta - Optional subagent metadata
2376
- */
2377
- async emitError(callId, toolName, error, subagentMeta) {
2378
- this.preparedCallIds.delete(callId);
2379
- const provenance = _ToolCallEmitter.resolveToolProvenance(
2380
- toolName,
2381
- subagentMeta
2382
- );
2383
- await this.sendUpdate(
2384
- createTranscriptToolCallResultUpdate({
2385
- toolName,
2386
- callId,
2387
- success: false,
2388
- errorMessage: error.message,
2389
- extra: {
2390
- ...subagentMeta,
2391
- provenance: provenance.provenance,
2392
- ...provenance.serverId ? { serverId: provenance.serverId } : {}
2393
- }
2394
- })
1972
+ }, "getLatestGitHubRelease");
1973
+ async function getGitHubRepoInfoAsync(opts = {}) {
1974
+ return parseGitHubRepoInfo(
1975
+ await runGit(["remote", "get-url", "origin"], opts)
1976
+ );
1977
+ }
1978
+ __name(getGitHubRepoInfoAsync, "getGitHubRepoInfoAsync");
1979
+ function parseGitHubRepoInfo(remoteUrl) {
1980
+ let urlToParse = remoteUrl;
1981
+ if (remoteUrl.startsWith("git@github.com:")) {
1982
+ urlToParse = remoteUrl.replace("git@github.com:", "");
1983
+ } else if (remoteUrl.startsWith("git@")) {
1984
+ throw new Error(
1985
+ `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
2395
1986
  );
2396
1987
  }
2397
- /**
2398
- * Resolve a tool's provenance for UI dispatch on tool_call events.
2399
- * The SDK reads `_meta.
2400
- * provenance` + `_meta.serverId` to render builtin / MCP-server-badge /
2401
- * subagent-block differently. Without this stamping, the SDK falls
2402
- * back to string-matching the toolName which can't reliably
2403
- * distinguish builtin from subagent.
2404
- *
2405
- * Resolution rules:
2406
- * - `subagentMeta` present → `'subagent'` (a Task tool / Codex
2407
- * subagent / etc. wrapping its own tool calls)
2408
- * - toolName matches `mcp__<server>__<tool>` → `'mcp'` with
2409
- * `serverId: <server>`. Naming convention from
2410
- * `packages/core/src/tools/mcp-tool.ts` in the
2411
- * `@qwen-code/qwen-code-core` package — mirrors the SDK's same
2412
- * heuristic fallback so SDK consumers stay consistent with
2413
- * daemon classification.
2414
- * - everything else → `'builtin'`
2415
- *
2416
- * Static + pure so it can be unit-tested without an emitter
2417
- * instance. Exported via `ToolCallEmitter.resolveToolProvenance`.
2418
- */
2419
- static resolveToolProvenance(toolName, subagentMeta) {
2420
- if (subagentMeta !== void 0) {
2421
- return { provenance: "subagent" };
2422
- }
2423
- if (toolName.startsWith("mcp__")) {
2424
- const parts = toolName.split("__");
2425
- if (parts.length >= 3 && parts[1] && parts[1].length > 0) {
2426
- return { provenance: "mcp", serverId: parts[1] };
2427
- }
2428
- }
2429
- return { provenance: "builtin" };
2430
- }
2431
- // ==================== Public Utilities ====================
2432
- /**
2433
- * Checks if a tool name is the TodoWriteTool.
2434
- * Exposed for external use in components that need to check this.
2435
- */
2436
- isTodoWriteTool(toolName) {
2437
- return toolName === ToolNames.TODO_WRITE;
1988
+ let parsedUrl;
1989
+ try {
1990
+ parsedUrl = new URL(urlToParse, "https://github.com");
1991
+ } catch {
1992
+ throw new Error(
1993
+ `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
1994
+ );
2438
1995
  }
2439
- /**
2440
- * Checks if a tool name is the ExitPlanModeTool.
2441
- */
2442
- isExitPlanModeTool(toolName) {
2443
- return toolName === ToolNames.EXIT_PLAN_MODE;
1996
+ if (parsedUrl.hostname !== "github.com") {
1997
+ throw new Error(
1998
+ `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
1999
+ );
2444
2000
  }
2445
- /**
2446
- * Checks if a tool name is the EnterPlanModeTool.
2447
- */
2448
- isEnterPlanModeTool(toolName) {
2449
- return toolName === ToolNames.ENTER_PLAN_MODE;
2001
+ const parts = parsedUrl.pathname.split("/").filter((part) => part !== "");
2002
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
2003
+ throw new Error(
2004
+ `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
2005
+ );
2450
2006
  }
2451
- /**
2452
- * Resolves tool metadata from the registry.
2453
- * Falls back to defaults if tool not found or build fails.
2454
- *
2455
- * @param toolName - Name of the tool
2456
- * @param args - Tool call arguments (used to build invocation)
2457
- */
2458
- resolveToolMetadata(toolName, args) {
2459
- if (!hasFullSessionContext(this.ctx)) {
2460
- const description = typeof args?.["description"] === "string" ? args["description"].trim() : "";
2461
- return {
2462
- title: description ? `${toolName}: ${description}` : toolName,
2463
- locations: [],
2464
- kind: "other"
2465
- };
2466
- }
2467
- const toolRegistry = this.ctx.config.getToolRegistry();
2468
- const tool = toolRegistry.getTool(toolName);
2469
- let title = tool?.displayName ?? toolName;
2470
- let locations = [];
2471
- let kind = "other";
2472
- if (tool && args) {
2473
- try {
2474
- const invocation = tool.build(args);
2475
- title = `${title}: ${invocation.getDescription()}`;
2476
- locations = invocation.toolLocations().map((loc) => ({
2477
- path: loc.path,
2478
- line: loc.line ?? null
2479
- }));
2480
- kind = this.mapToolKind(tool.kind, toolName);
2481
- } catch {
2482
- if (typeof args["description"] === "string") {
2483
- title = `${title}: ${args["description"]}`;
2484
- }
2485
- if (tool.kind) {
2486
- kind = this.mapToolKind(tool.kind, toolName);
2487
- }
2488
- }
2489
- }
2490
- return { title, locations, kind };
2007
+ return { owner: parts[0], repo: parts[1].replace(/\.git$/, "") };
2008
+ }
2009
+ __name(parseGitHubRepoInfo, "parseGitHubRepoInfo");
2010
+
2011
+ // packages/cli/src/services/setup-github.ts
2012
+ var debugLogger2 = createDebugLogger("SETUP_GITHUB");
2013
+ var GITHUB_WORKFLOW_PATHS = [
2014
+ "qwen-dispatch/qwen-dispatch.yml",
2015
+ "qwen-assistant/qwen-invoke.yml",
2016
+ "issue-triage/qwen-triage.yml",
2017
+ "issue-triage/qwen-scheduled-triage.yml",
2018
+ "pr-review/qwen-review.yml"
2019
+ ];
2020
+ var GITIGNORE_ENTRIES = [".qwen/", "gha-creds-*.json"];
2021
+ var MAX_WORKFLOW_DOWNLOAD_BYTES = 5 * 1024 * 1024;
2022
+ var SetupGithubError = class extends Error {
2023
+ static {
2024
+ __name(this, "SetupGithubError");
2491
2025
  }
2492
- /**
2493
- * Maps core Tool Kind enum to ACP ToolKind string literals.
2494
- *
2495
- * @param kind - The core Kind enum value
2496
- * @param toolName - Optional tool name to handle special cases like exit_plan_mode
2497
- */
2498
- mapToolKind(kind, toolName) {
2499
- if (toolName && (this.isExitPlanModeTool(toolName) || this.isEnterPlanModeTool(toolName))) {
2500
- return "switch_mode";
2501
- }
2502
- return KIND_MAP[kind] ?? "other";
2026
+ code;
2027
+ status;
2028
+ partial;
2029
+ partialResult;
2030
+ constructor(code, message, status, partialResult) {
2031
+ super(message);
2032
+ this.name = "SetupGithubError";
2033
+ this.code = code;
2034
+ this.status = status;
2035
+ this.partial = partialResult !== void 0;
2036
+ this.partialResult = partialResult;
2503
2037
  }
2504
2038
  };
2505
- function buildToolResultContentPrefix(resultDisplay) {
2506
- if (!isVisionBridgeNoticeDisplay(resultDisplay)) return [];
2507
- return [
2508
- {
2509
- type: "content",
2510
- content: {
2511
- type: "text",
2512
- text: sanitizeTerminalText(
2513
- formatVisionBridgeNoticeDisplay(resultDisplay)
2514
- )
2039
+ function isWorkspaceGenerationClosed(error) {
2040
+ return Boolean(
2041
+ error && typeof error === "object" && "code" in error && error.code === "workspace_generation_closed"
2042
+ );
2043
+ }
2044
+ __name(isWorkspaceGenerationClosed, "isWorkspaceGenerationClosed");
2045
+ var nodeFileOps = {
2046
+ assertCanWrite() {
2047
+ },
2048
+ async ensureWorkflowDirectory(gitRepoRoot) {
2049
+ await fsp.mkdir(path.join(gitRepoRoot, ".github", "workflows"), {
2050
+ recursive: true
2051
+ });
2052
+ },
2053
+ async writeTextFile(gitRepoRoot, relativePath, content) {
2054
+ const target = path.join(gitRepoRoot, relativePath);
2055
+ await fsp.writeFile(target, content, { mode: 420 });
2056
+ return { sizeBytes: Buffer.byteLength(content, "utf8") };
2057
+ },
2058
+ async readTextFile(gitRepoRoot, relativePath) {
2059
+ try {
2060
+ return await fsp.readFile(path.join(gitRepoRoot, relativePath), "utf8");
2061
+ } catch (error) {
2062
+ if (error.code === "ENOENT") {
2063
+ return void 0;
2515
2064
  }
2065
+ throw error;
2516
2066
  }
2517
- ];
2518
- }
2519
- __name(buildToolResultContentPrefix, "buildToolResultContentPrefix");
2520
-
2521
- // packages/cli/src/acp-integration/session/history-replayer.ts
2522
- init_esbuild_shims();
2523
- var GOAL_NOT_RESTORED_REASON = {
2524
- "untrusted-folder": "Goal not restored: this folder is not trusted, so its Stop hook cannot run.",
2525
- "hooks-disabled": "Goal not restored: hooks are disabled for this session.",
2526
- "no-hook-system": "Goal not restored: the hook system is unavailable."
2067
+ }
2527
2068
  };
2528
- var HistoryReplayer = class {
2529
- constructor(ctx, options = {}) {
2530
- this.ctx = ctx;
2531
- this.options = options;
2532
- this.messageEmitter = new MessageEmitter(ctx);
2533
- this.toolCallEmitter = new ToolCallEmitter(ctx);
2534
- this.machine = this.createMachine();
2069
+ async function setupGithub(options = {}) {
2070
+ const cwd = options.cwd ?? process.cwd();
2071
+ const fileOps = options.fileOps ?? nodeFileOps;
2072
+ if (!await isGitHubRepositoryAsync({ cwd })) {
2073
+ throw new SetupGithubError(
2074
+ "github_repository_not_found",
2075
+ "Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
2076
+ 400
2077
+ );
2535
2078
  }
2536
- static {
2537
- __name(this, "HistoryReplayer");
2079
+ let gitRepoRoot;
2080
+ try {
2081
+ gitRepoRoot = await getGitRepoRootAsync({ cwd });
2082
+ } catch (error) {
2083
+ debugLogger2.debug("Failed to get git repo root:", error);
2084
+ throw new SetupGithubError(
2085
+ "github_repository_not_found",
2086
+ "Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
2087
+ 400
2088
+ );
2538
2089
  }
2539
- messageEmitter;
2540
- toolCallEmitter;
2541
- options;
2542
- machine;
2543
- async replay(records, gaps) {
2544
- try {
2545
- await this.replayPage(records, {
2546
- finalizeDangling: true,
2547
- gaps
2548
- });
2549
- await this.supersedeUnrestorableGoal(records);
2550
- } finally {
2551
- this.setActiveRecordId(null);
2090
+ if (options.workspaceRoot) {
2091
+ const [gitRootReal, workspaceReal] = await Promise.all([
2092
+ realpathOrResolve(gitRepoRoot),
2093
+ realpathOrResolve(options.workspaceRoot)
2094
+ ]);
2095
+ if (gitRootReal !== workspaceReal) {
2096
+ throw new SetupGithubError(
2097
+ "github_git_root_mismatch",
2098
+ "The Git repository root must match the daemon workspace root.",
2099
+ 400
2100
+ );
2552
2101
  }
2553
2102
  }
2554
- async replayPage(records, options = {}) {
2555
- this.machine = this.createMachine(options);
2556
- let replayError;
2557
- try {
2558
- for (const record of records) {
2559
- for (const emission of this.machine.project(record)) {
2560
- this.setActiveRecordId(
2561
- emission.sourceRecordId,
2562
- emission.sourceTimestamp
2563
- );
2564
- await this.sendUpdate(emission.update);
2565
- }
2566
- }
2567
- } catch (error) {
2568
- replayError = error;
2569
- }
2570
- let danglingError;
2571
- if (options.finalizeDangling === true) {
2572
- for (const emission of this.machine.finalize()) {
2573
- this.setActiveRecordId(
2574
- emission.sourceRecordId,
2575
- emission.sourceTimestamp
2103
+ fileOps.assertCanWrite?.();
2104
+ let releaseTag;
2105
+ try {
2106
+ releaseTag = await getLatestGitHubRelease(options.proxy);
2107
+ } catch (error) {
2108
+ writeStderrLine(
2109
+ `qwen setup-github: failed to determine latest qwen-code-action release: ${error instanceof Error ? error.message : String(error)}`
2110
+ );
2111
+ debugLogger2.debug(
2112
+ "Failed to determine latest qwen-code-action release:",
2113
+ error
2114
+ );
2115
+ throw new SetupGithubError(
2116
+ "github_release_lookup_failed",
2117
+ "Unable to determine the latest qwen-code-action release on GitHub.",
2118
+ 502
2119
+ );
2120
+ }
2121
+ const readmeUrl = `https://github.com/QwenLM/qwen-code-action/blob/${releaseTag}/README.md#quick-start`;
2122
+ const secretsUrl = await resolveSecretsUrl(cwd);
2123
+ const downloads = await downloadWorkflows({
2124
+ releaseTag,
2125
+ proxy: options.proxy,
2126
+ abortSignal: options.abortSignal,
2127
+ fetchImpl: options.fetchImpl ?? fetch
2128
+ });
2129
+ const result = {
2130
+ kind: "github_setup",
2131
+ workspaceCwd: options.workspaceRoot ?? gitRepoRoot,
2132
+ gitRepoRoot,
2133
+ releaseTag,
2134
+ readmeUrl,
2135
+ ...secretsUrl ? { secretsUrl } : {},
2136
+ workflows: [],
2137
+ gitignore: { path: ".gitignore", status: "skipped" },
2138
+ warnings: []
2139
+ };
2140
+ result.gitignore = await updateGitignore(gitRepoRoot, fileOps);
2141
+ if (result.gitignore.status === "failed") {
2142
+ result.warnings.push("Failed to update .gitignore.");
2143
+ }
2144
+ try {
2145
+ await fileOps.ensureWorkflowDirectory(gitRepoRoot);
2146
+ for (const workflow of downloads) {
2147
+ const relativePath = path.posix.join(
2148
+ ".github",
2149
+ "workflows",
2150
+ path.posix.basename(workflow.sourcePath)
2151
+ );
2152
+ try {
2153
+ const write = await fileOps.writeTextFile(
2154
+ gitRepoRoot,
2155
+ relativePath,
2156
+ workflow.content
2157
+ );
2158
+ result.workflows.push({
2159
+ sourcePath: workflow.sourcePath,
2160
+ path: relativePath,
2161
+ status: "written",
2162
+ sizeBytes: write.sizeBytes
2163
+ });
2164
+ } catch (error) {
2165
+ if (isWorkspaceGenerationClosed(error)) throw error;
2166
+ result.partial = true;
2167
+ result.workflows.push({
2168
+ sourcePath: workflow.sourcePath,
2169
+ path: relativePath,
2170
+ status: "failed",
2171
+ error: error instanceof Error ? error.message : String(error)
2172
+ });
2173
+ throw new SetupGithubError(
2174
+ "github_workflow_write_failed",
2175
+ `Unable to write ${relativePath}.`,
2176
+ 500,
2177
+ result
2576
2178
  );
2577
- try {
2578
- await this.sendUpdate(emission.update);
2579
- } catch (error) {
2580
- danglingError ??= error;
2581
- }
2582
2179
  }
2583
2180
  }
2584
- const replay = this.machine.snapshot();
2585
- this.copyCumulativeUsage(replay);
2586
- const state = {
2587
- pendingToolCalls: options.finalizeDangling === true ? [] : replay.pendingToolCalls.map(toLegacyPendingToolCall),
2588
- replay
2589
- };
2590
- this.setActiveRecordId(null);
2591
- if (replayError && danglingError) {
2592
- throw new AggregateError(
2593
- [replayError, danglingError],
2594
- "Replay and dangling-cleanup both failed"
2595
- );
2596
- }
2597
- if (replayError) throw replayError;
2598
- if (danglingError) throw danglingError;
2599
- return state;
2600
- }
2601
- getPendingToolCalls() {
2602
- return this.machine.snapshot().pendingToolCalls.map(toLegacyPendingToolCall);
2603
- }
2604
- getReplayState() {
2605
- return this.machine.snapshot();
2181
+ } catch (error) {
2182
+ if (isWorkspaceGenerationClosed(error)) throw error;
2183
+ if (error instanceof SetupGithubError) throw error;
2184
+ throw new SetupGithubError(
2185
+ "github_workflow_write_failed",
2186
+ "Unable to create .github/workflows.",
2187
+ 500,
2188
+ result
2189
+ );
2606
2190
  }
2607
- createMachine(options = {}) {
2608
- const cumulative = this.ctx.cumulativeUsage;
2609
- const initialState = {
2610
- v: 1,
2611
- pendingToolCalls: (options.pendingToolCalls ?? []).map(
2612
- toPendingTranscriptToolCall
2613
- ),
2614
- cumulativeUsage: cumulative ? { ...cumulative } : {
2615
- promptTokens: 0,
2616
- cachedTokens: 0,
2617
- candidateTokens: 0,
2618
- apiTimeMs: 0
2619
- },
2620
- ...options.goalState ? { goalState: options.goalState } : {},
2621
- ...options.goalCause ? { goalCause: options.goalCause } : {}
2191
+ return result;
2192
+ }
2193
+ __name(setupGithub, "setupGithub");
2194
+ async function updateGitignore(gitRepoRoot, fileOps = nodeFileOps) {
2195
+ try {
2196
+ const existingContent = await fileOps.readTextFile(
2197
+ gitRepoRoot,
2198
+ ".gitignore"
2199
+ );
2200
+ if (existingContent === void 0) {
2201
+ const content = GITIGNORE_ENTRIES.join("\n") + "\n";
2202
+ await fileOps.writeTextFile(gitRepoRoot, ".gitignore", content);
2203
+ return {
2204
+ path: ".gitignore",
2205
+ status: "created",
2206
+ added: [...GITIGNORE_ENTRIES]
2207
+ };
2208
+ }
2209
+ const missingEntries = GITIGNORE_ENTRIES.filter(
2210
+ (entry) => !existingContent.split(/\r?\n/).some((line) => line.split("#")[0].trim() === entry)
2211
+ );
2212
+ if (missingEntries.length === 0) {
2213
+ return { path: ".gitignore", status: "unchanged" };
2214
+ }
2215
+ const nextContent = existingContent + "\n" + missingEntries.join("\n") + "\n";
2216
+ await fileOps.writeTextFile(gitRepoRoot, ".gitignore", nextContent);
2217
+ return {
2218
+ path: ".gitignore",
2219
+ status: "updated",
2220
+ added: missingEntries
2622
2221
  };
2623
- return createTranscriptReplayMachine({
2624
- initialState,
2625
- gaps: options.gaps,
2626
- presentation: this.presentationAdapter(),
2627
- onDiagnostic: /* @__PURE__ */ __name((diagnostic) => {
2628
- if (diagnostic.code === "malformed_part" && diagnostic.path === "systemPayload.outputHistoryItems.goalStatus.condition") {
2629
- writeStderrLineSafe(`qwen: ${diagnostic.message}`);
2630
- }
2631
- }, "onDiagnostic")
2632
- });
2633
- }
2634
- presentationAdapter() {
2222
+ } catch (error) {
2223
+ if (isWorkspaceGenerationClosed(error)) throw error;
2224
+ debugLogger2.debug("Failed to update .gitignore:", error);
2635
2225
  return {
2636
- resolveToolMetadata: /* @__PURE__ */ __name((toolName, args) => this.toolCallEmitter.resolveToolMetadata(toolName, { ...args }), "resolveToolMetadata"),
2637
- formatHistoryGap: /* @__PURE__ */ __name((gap) => formatHistoryGapNotice(gap), "formatHistoryGap"),
2638
- buildToolResultContentPrefix
2226
+ path: ".gitignore",
2227
+ status: "failed",
2228
+ error: error instanceof Error ? error.message : String(error)
2639
2229
  };
2640
2230
  }
2641
- async sendUpdate(update) {
2642
- if (this.ctx.messageRewriter) {
2643
- await this.ctx.messageRewriter.interceptUpdate(update);
2644
- return;
2231
+ }
2232
+ __name(updateGitignore, "updateGitignore");
2233
+ async function downloadWorkflows(options) {
2234
+ const internalAbort = new AbortController();
2235
+ try {
2236
+ const dispatcher = options.proxy ? new (await loadUndici()).ProxyAgent(options.proxy) : void 0;
2237
+ return await Promise.all(
2238
+ GITHUB_WORKFLOW_PATHS.map(async (workflow) => {
2239
+ const endpoint = `https://raw.githubusercontent.com/QwenLM/qwen-code-action/refs/tags/${options.releaseTag}/examples/workflows/${workflow}`;
2240
+ const response = await options.fetchImpl(endpoint, {
2241
+ method: "GET",
2242
+ dispatcher,
2243
+ signal: AbortSignal.any([
2244
+ AbortSignal.timeout(3e4),
2245
+ internalAbort.signal,
2246
+ ...options.abortSignal ? [options.abortSignal] : []
2247
+ ])
2248
+ });
2249
+ if (!response.ok) {
2250
+ throw new Error(
2251
+ `Invalid response code downloading ${endpoint}: ${response.status} - ${response.statusText}`
2252
+ );
2253
+ }
2254
+ return {
2255
+ sourcePath: workflow,
2256
+ content: await readResponseTextWithLimit(response, workflow)
2257
+ };
2258
+ })
2259
+ );
2260
+ } catch (error) {
2261
+ internalAbort.abort();
2262
+ const message = error instanceof Error ? error.message : String(error);
2263
+ debugLogger2.debug("Failed to download qwen-code-action workflows:", error);
2264
+ throw new SetupGithubError(
2265
+ "github_workflow_download_failed",
2266
+ `Unable to download qwen-code-action workflows from GitHub. ${message}`,
2267
+ 502
2268
+ );
2269
+ }
2270
+ }
2271
+ __name(downloadWorkflows, "downloadWorkflows");
2272
+ async function readResponseTextWithLimit(response, sourcePath) {
2273
+ const contentLength = response.headers.get("content-length");
2274
+ if (contentLength !== null) {
2275
+ const parsedLength = Number(contentLength);
2276
+ if (Number.isFinite(parsedLength) && parsedLength > MAX_WORKFLOW_DOWNLOAD_BYTES) {
2277
+ throw new Error(
2278
+ `${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
2279
+ );
2645
2280
  }
2646
- await this.ctx.sendUpdate(update);
2647
2281
  }
2648
- copyCumulativeUsage(state) {
2649
- const cumulative = this.ctx.cumulativeUsage;
2650
- if (!cumulative) return;
2651
- cumulative.promptTokens = state.cumulativeUsage.promptTokens;
2652
- cumulative.cachedTokens = state.cumulativeUsage.cachedTokens;
2653
- cumulative.candidateTokens = state.cumulativeUsage.candidateTokens;
2654
- cumulative.apiTimeMs = state.cumulativeUsage.apiTimeMs;
2282
+ if (!response.body) return "";
2283
+ const reader = response.body.getReader();
2284
+ const chunks = [];
2285
+ let totalBytes = 0;
2286
+ try {
2287
+ while (true) {
2288
+ const { done, value } = await reader.read();
2289
+ if (done) break;
2290
+ if (!value) continue;
2291
+ totalBytes += value.byteLength;
2292
+ if (totalBytes > MAX_WORKFLOW_DOWNLOAD_BYTES) {
2293
+ await reader.cancel().catch(() => {
2294
+ });
2295
+ throw new Error(
2296
+ `${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
2297
+ );
2298
+ }
2299
+ chunks.push(value);
2300
+ }
2301
+ } finally {
2302
+ reader.releaseLock();
2655
2303
  }
2656
- /**
2657
- * Emits a trailing `cleared` card when the transcript ends on an active goal
2658
- * that `restoreGoalFromHistory` is about to refuse.
2659
- *
2660
- * A client reads "there is an active goal" off the newest goal card it has
2661
- * seen, so replaying a `set` card that no Stop hook will drive leaves the UI
2662
- * claiming a goal is running when the loop is dead. The gates are pure
2663
- * functions of `config`, so the answer is known here, before restore runs.
2664
- *
2665
- * This card is emitted, not recorded: the transcript keeps its `set` card, so
2666
- * a later resume in a trusted folder (or with hooks re-enabled) restores the
2667
- * goal instead of finding it destroyed. Emitting from inside replay is also
2668
- * what puts the card *after* the `set` card — `loadSession` batches replay
2669
- * updates into its response, and a notification sent afterwards would reach
2670
- * the client first.
2671
- *
2672
- * Gated on `supersedeUnrestorableGoal`: only a resume registers a hook, and
2673
- * only a resume has a `config` that answers trust and hook-policy questions.
2674
- */
2675
- async supersedeUnrestorableGoal(records) {
2676
- if (!this.options.supersedeUnrestorableGoal) return;
2677
- const active = findGoalToRestore(
2678
- collectGoalStatusItemsFromRecords(records)
2679
- );
2680
- if (!active || goalConditionBlockedBy(active.condition)) return;
2681
- if (!hasFullSessionContext(this.ctx)) return;
2682
- const blockedBy = goalRestoreBlockedBy(this.ctx.config);
2683
- if (!blockedBy) return;
2684
- await this.messageEmitter.emitGoalStatus({
2685
- kind: "cleared",
2686
- condition: active.condition,
2687
- iterations: active.iterations,
2688
- ...active.setAt !== void 0 ? { setAt: active.setAt } : {},
2689
- lastReason: GOAL_NOT_RESTORED_REASON[blockedBy]
2690
- });
2304
+ const body = new Uint8Array(totalBytes);
2305
+ let offset = 0;
2306
+ for (const chunk of chunks) {
2307
+ body.set(chunk, offset);
2308
+ offset += chunk.byteLength;
2691
2309
  }
2692
- setActiveRecordId(recordId, timestamp) {
2693
- this.ctx.setActiveRecordId?.(recordId, timestamp);
2310
+ return new TextDecoder().decode(body);
2311
+ }
2312
+ __name(readResponseTextWithLimit, "readResponseTextWithLimit");
2313
+ async function resolveSecretsUrl(cwd) {
2314
+ try {
2315
+ const repoInfo = await getGitHubRepoInfoAsync({ cwd });
2316
+ return `https://github.com/${repoInfo.owner}/${repoInfo.repo}/settings/secrets/actions`;
2317
+ } catch {
2318
+ return void 0;
2694
2319
  }
2695
- };
2696
- function toPendingTranscriptToolCall(pending) {
2697
- return {
2698
- callId: pending.callId,
2699
- toolName: pending.toolName,
2700
- sourceRecordId: pending.recordId,
2701
- ...pending.timestamp ? { sourceTimestamp: pending.timestamp } : {}
2702
- };
2703
2320
  }
2704
- __name(toPendingTranscriptToolCall, "toPendingTranscriptToolCall");
2705
- function toLegacyPendingToolCall(pending) {
2706
- return {
2707
- callId: pending.callId,
2708
- toolName: pending.toolName,
2709
- recordId: pending.sourceRecordId,
2710
- ...pending.sourceTimestamp ? { timestamp: pending.sourceTimestamp } : {}
2711
- };
2321
+ __name(resolveSecretsUrl, "resolveSecretsUrl");
2322
+ async function realpathOrResolve(input) {
2323
+ try {
2324
+ return await fsp.realpath(input);
2325
+ } catch {
2326
+ return path.resolve(input);
2327
+ }
2712
2328
  }
2713
- __name(toLegacyPendingToolCall, "toLegacyPendingToolCall");
2329
+ __name(realpathOrResolve, "realpathOrResolve");
2714
2330
 
2715
2331
  // packages/cli/src/ui/utils/export/collect.ts
2716
2332
  init_esbuild_shims();
@@ -2931,7 +2547,7 @@ async function extractMetadata(conversation, config) {
2931
2547
  const gitBranch = firstRecord?.gitBranch;
2932
2548
  let gitRepo;
2933
2549
  if (cwd) {
2934
- const { getGitRepoName } = await import("./deferred-core-runtime-67GJXHXS.js");
2550
+ const { getGitRepoName } = await import("./deferred-core-runtime-ZSLQKM7J.js");
2935
2551
  gitRepo = getGitRepoName(cwd);
2936
2552
  }
2937
2553
  let model;
@@ -3782,19 +3398,132 @@ __name(generateExportFilename, "generateExportFilename");
3782
3398
  // packages/cli/src/ui/utils/export/index.ts
3783
3399
  init_esbuild_shims();
3784
3400
 
3401
+ // packages/cli/src/utils/json-string-byte-projection.ts
3402
+ init_esbuild_shims();
3403
+ import { Buffer as Buffer2 } from "node:buffer";
3404
+ var JSON_STRING_DELIMITER_BYTES = 2;
3405
+ function jsonPayloadBytesAt(value, index) {
3406
+ const code = value.charCodeAt(index);
3407
+ if (code === 34 || code === 92) return 2;
3408
+ if (code <= 31) {
3409
+ return code === 8 || code === 9 || code === 10 || code === 12 || code === 13 ? 2 : 6;
3410
+ }
3411
+ if (code <= 127) return 1;
3412
+ if (code <= 2047) return 2;
3413
+ if (code >= 55296 && code <= 56319) {
3414
+ const next = value.charCodeAt(index + 1);
3415
+ return next >= 56320 && next <= 57343 ? 4 : 6;
3416
+ }
3417
+ if (code >= 56320 && code <= 57343) return 6;
3418
+ return 3;
3419
+ }
3420
+ __name(jsonPayloadBytesAt, "jsonPayloadBytesAt");
3421
+ function jsonPayloadWidthAt(value, index) {
3422
+ const code = value.charCodeAt(index);
3423
+ if (code < 55296 || code > 56319) return 1;
3424
+ const next = value.charCodeAt(index + 1);
3425
+ return next >= 56320 && next <= 57343 ? 2 : 1;
3426
+ }
3427
+ __name(jsonPayloadWidthAt, "jsonPayloadWidthAt");
3428
+ function jsonStringPayloadByteLength(value, stopAfterBytes = Number.POSITIVE_INFINITY) {
3429
+ let bytes = 0;
3430
+ for (let index = 0; index < value.length; ) {
3431
+ bytes += jsonPayloadBytesAt(value, index);
3432
+ if (bytes > stopAfterBytes) return bytes;
3433
+ index += jsonPayloadWidthAt(value, index);
3434
+ }
3435
+ return bytes;
3436
+ }
3437
+ __name(jsonStringPayloadByteLength, "jsonStringPayloadByteLength");
3438
+ function jsonStringJsonByteLength(value) {
3439
+ return JSON_STRING_DELIMITER_BYTES + jsonStringPayloadByteLength(value);
3440
+ }
3441
+ __name(jsonStringJsonByteLength, "jsonStringJsonByteLength");
3442
+ function jsonPayloadWidthBefore(value, end) {
3443
+ const last = value.charCodeAt(end - 1);
3444
+ if (last >= 56320 && last <= 57343 && end >= 2) {
3445
+ const previous = value.charCodeAt(end - 2);
3446
+ if (previous >= 55296 && previous <= 56319) return 2;
3447
+ }
3448
+ return 1;
3449
+ }
3450
+ __name(jsonPayloadWidthBefore, "jsonPayloadWidthBefore");
3451
+ function selectPrefix(value, budget) {
3452
+ let end = 0;
3453
+ let bytes = 0;
3454
+ while (end < value.length) {
3455
+ const partBytes = jsonPayloadBytesAt(value, end);
3456
+ if (bytes + partBytes > budget) break;
3457
+ bytes += partBytes;
3458
+ end += jsonPayloadWidthAt(value, end);
3459
+ }
3460
+ return end;
3461
+ }
3462
+ __name(selectPrefix, "selectPrefix");
3463
+ function selectSuffix(value, budget) {
3464
+ let start = value.length;
3465
+ let bytes = 0;
3466
+ while (start > 0) {
3467
+ const partWidth = jsonPayloadWidthBefore(value, start);
3468
+ const partBytes = jsonPayloadBytesAt(value, start - partWidth);
3469
+ if (bytes + partBytes > budget) break;
3470
+ bytes += partBytes;
3471
+ start -= partWidth;
3472
+ }
3473
+ return start;
3474
+ }
3475
+ __name(selectSuffix, "selectSuffix");
3476
+ function copyString(value) {
3477
+ return value.split("").join("");
3478
+ }
3479
+ __name(copyString, "copyString");
3480
+ function truncateJsonStringPayload(value, originalPayloadBytes, payloadBudget, marker) {
3481
+ if (originalPayloadBytes <= payloadBudget) return value;
3482
+ const markerPayloadBytes = jsonStringPayloadByteLength(marker);
3483
+ if (payloadBudget < markerPayloadBytes) {
3484
+ return copyString(value.slice(0, selectPrefix(value, payloadBudget)));
3485
+ }
3486
+ const sourceBudget = payloadBudget - markerPayloadBytes;
3487
+ const headBudget = Math.floor(sourceBudget * 0.2);
3488
+ const tailBudget = sourceBudget - headBudget;
3489
+ const headEnd = selectPrefix(value, headBudget);
3490
+ const tailStart = selectSuffix(value, tailBudget);
3491
+ return copyString(value.slice(0, headEnd)) + marker + copyString(value.slice(tailStart));
3492
+ }
3493
+ __name(truncateJsonStringPayload, "truncateJsonStringPayload");
3494
+ function projectJsonStringToByteBudget(value, jsonByteBudget, marker) {
3495
+ const payloadBudget = Math.max(
3496
+ 0,
3497
+ jsonByteBudget - JSON_STRING_DELIMITER_BYTES
3498
+ );
3499
+ const payloadBytes = jsonStringPayloadByteLength(value, payloadBudget);
3500
+ if (payloadBytes <= payloadBudget) return value;
3501
+ const projected = truncateJsonStringPayload(
3502
+ value,
3503
+ payloadBytes,
3504
+ payloadBudget,
3505
+ marker
3506
+ );
3507
+ if (Buffer2.byteLength(JSON.stringify(projected), "utf8") <= jsonByteBudget) {
3508
+ return projected;
3509
+ }
3510
+ const fallback = copyString(
3511
+ marker.slice(0, selectPrefix(marker, payloadBudget))
3512
+ );
3513
+ return Buffer2.byteLength(JSON.stringify(fallback), "utf8") <= jsonByteBudget ? fallback : "";
3514
+ }
3515
+ __name(projectJsonStringToByteBudget, "projectJsonStringToByteBudget");
3516
+
3785
3517
  export {
3786
3518
  GITHUB_WORKFLOW_PATHS,
3787
3519
  SetupGithubError,
3788
3520
  setupGithub,
3789
3521
  createTranscriptMessageUpdate,
3790
- MessageEmitter,
3522
+ createTranscriptUsageUpdate,
3523
+ BaseEmitter,
3791
3524
  PlanEmitter,
3525
+ hasFullSessionContext,
3792
3526
  ToolCallEmitter,
3793
- collectGoalStatusItemsFromRecords,
3794
- goalTerminalEventToHistoryItem,
3795
- recordGoalStatusItem,
3796
- installGoalTerminalObserver,
3797
- restoreGoalFromHistory,
3798
3527
  HistoryReplayer,
3799
3528
  collectSessionData,
3800
3529
  normalizeSessionData,
@@ -3804,7 +3533,12 @@ export {
3804
3533
  toHtml,
3805
3534
  toJson,
3806
3535
  toJsonl,
3807
- generateExportFilename
3536
+ generateExportFilename,
3537
+ JSON_STRING_DELIMITER_BYTES,
3538
+ jsonStringPayloadByteLength,
3539
+ jsonStringJsonByteLength,
3540
+ truncateJsonStringPayload,
3541
+ projectJsonStringToByteBudget
3808
3542
  };
3809
3543
  /**
3810
3544
  * @license
@@ -3813,17 +3547,17 @@ export {
3813
3547
  */
3814
3548
  /**
3815
3549
  * @license
3816
- * Copyright 2025 Google LLC
3550
+ * Copyright 2025 Qwen Team
3817
3551
  * SPDX-License-Identifier: Apache-2.0
3818
3552
  */
3819
3553
  /**
3820
3554
  * @license
3821
- * Copyright 2025 Qwen Team
3555
+ * Copyright 2025 Qwen
3822
3556
  * SPDX-License-Identifier: Apache-2.0
3823
3557
  */
3824
3558
  /**
3825
3559
  * @license
3826
- * Copyright 2025 Qwen
3560
+ * Copyright 2025 Google LLC
3827
3561
  * SPDX-License-Identifier: Apache-2.0
3828
3562
  */
3829
3563
  /**