@qwen-code/qwen-code 0.21.8 → 0.21.9

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 (258) hide show
  1. package/README.md +2 -1
  2. package/bundled/qc-helper/docs/configuration/settings.md +32 -30
  3. package/bundled/qc-helper/docs/extension/introduction.md +15 -1
  4. package/bundled/qc-helper/docs/features/code-review.md +2 -0
  5. package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +1 -1
  6. package/bundled/qc-helper/docs/qwen-serve.md +42 -39
  7. package/bundled/review/SKILL.md +11 -7
  8. package/chunks/{MaxSizedBox-7PM6BGJ5.js → MaxSizedBox-6BZANW7X.js} +9 -9
  9. package/chunks/{StandaloneSessionPicker-3UQHM7GV.js → StandaloneSessionPicker-VDC5KE7T.js} +28 -25
  10. package/chunks/{acpAgent-5UWLFV6V.js → acpAgent-F2NSBCUF.js} +1433 -706
  11. package/chunks/{agent-624T2BLO.js → agent-VOHJOEBB.js} +8 -8
  12. package/chunks/{agent-headless-2EE5J2KX.js → agent-headless-J5NFOPHP.js} +8 -8
  13. package/chunks/{bridge-JENKGFFP.js → bridge-NQIZZLAS.js} +13 -13
  14. package/chunks/{channel-management-service-DDWUPHMU.js → channel-management-service-PHELKOW2.js} +4 -4
  15. package/chunks/{channel-settings-store-SA6JZSPH.js → channel-settings-store-VIY2OENO.js} +17 -15
  16. package/chunks/{channel-worker-group-E67EN3RV.js → channel-worker-group-MSHT6CWR.js} +6 -6
  17. package/chunks/{channel-worker-manager-SW4C45CF.js → channel-worker-manager-XXD3GDSK.js} +6 -6
  18. package/chunks/{channel-worker-supervisor-5SRD24FG.js → channel-worker-supervisor-IVSDIMI4.js} +4 -4
  19. package/chunks/{chunk-S3Y3GBFD.js → chunk-23VQTELM.js} +2 -2
  20. package/chunks/{chunk-XZKQT2B2.js → chunk-3WDYBTTI.js} +5 -5
  21. package/chunks/{chunk-YEF7XEO2.js → chunk-3XVDTHBJ.js} +3 -3
  22. package/chunks/{chunk-IBYULW65.js → chunk-46YJDYCU.js} +145 -10
  23. package/chunks/chunk-4JRM2BSM.js +48 -0
  24. package/chunks/{chunk-L4N6TIP7.js → chunk-4TRQPFDP.js} +4 -2
  25. package/chunks/{chunk-5ZGR6RKJ.js → chunk-4XQNB3KN.js} +3 -3
  26. package/chunks/chunk-5EJZE3FP.js +140 -0
  27. package/chunks/{chunk-XHD7CRP2.js → chunk-5RBDAGC6.js} +2 -2
  28. package/chunks/{chunk-KJZ26VBX.js → chunk-67EWJE77.js} +1 -1
  29. package/chunks/{chunk-TE3ZAJE7.js → chunk-6Q5ABMTU.js} +1 -1
  30. package/chunks/{chunk-U5SLIG7E.js → chunk-7AEPJGL4.js} +1 -1
  31. package/chunks/{chunk-OHKJVAKG.js → chunk-7GOYZQPR.js} +20 -1977
  32. package/chunks/{chunk-3SE7J4DR.js → chunk-7S4JBJLU.js} +3 -3
  33. package/chunks/{chunk-TKSZJ5BV.js → chunk-AKJQSWV4.js} +3 -3
  34. package/chunks/{chunk-E4ZBKMSF.js → chunk-ATMO54WE.js} +6 -6
  35. package/chunks/{chunk-KKDVZLGL.js → chunk-BAMN6XSD.js} +1 -1
  36. package/chunks/{chunk-IUQ52YJK.js → chunk-BIRWP6LU.js} +1 -1
  37. package/chunks/{chunk-AKA24BGO.js → chunk-BT6GQIEJ.js} +1 -1
  38. package/chunks/{chunk-ZCLLJARV.js → chunk-BZP4QPNK.js} +10 -10
  39. package/chunks/{chunk-2M5N3DHY.js → chunk-CMOBWHWW.js} +1 -1
  40. package/chunks/{chunk-WV5J6Q6N.js → chunk-D7BXVKSF.js} +1 -1
  41. package/chunks/{chunk-NLREQJFK.js → chunk-DA4HRSBW.js} +15 -0
  42. package/chunks/{chunk-GOEVOFQI.js → chunk-DH5YXSIF.js} +3 -3
  43. package/chunks/{chunk-DIWZNWZT.js → chunk-DX3RGJMS.js} +13 -2
  44. package/chunks/{chunk-PLFATELK.js → chunk-DZUO626D.js} +1 -1
  45. package/chunks/{chunk-NGYI5EF5.js → chunk-E2FPSSKP.js} +8 -8
  46. package/chunks/{chunk-ZPLALRXZ.js → chunk-FBMCDU63.js} +4 -137
  47. package/chunks/{chunk-2ILAOM2I.js → chunk-FCLHHEUK.js} +17 -16
  48. package/chunks/{chunk-SNRT2TJJ.js → chunk-G2TX5ZXC.js} +3 -3
  49. package/chunks/{chunk-C5VWPTGT.js → chunk-GAKGOXTC.js} +1 -1
  50. package/chunks/{chunk-QQWD7LZV.js → chunk-HADWBW5R.js} +4 -4
  51. package/chunks/{chunk-77QVBFCU.js → chunk-HZGBKOX3.js} +3 -3
  52. package/chunks/{chunk-RPWVIXDB.js → chunk-I5VM3SKY.js} +4 -4
  53. package/chunks/{chunk-7VUERJHS.js → chunk-II6G3EY6.js} +325 -104
  54. package/chunks/{chunk-FN6YXJOP.js → chunk-IOEZE2YT.js} +1 -1
  55. package/chunks/chunk-JUWS2Z5K.js +1995 -0
  56. package/chunks/{chunk-VXZ5HAOV.js → chunk-K4ADGWHU.js} +1 -1
  57. package/chunks/{chunk-YOM7DEGB.js → chunk-KSAFZ5TA.js} +2 -2
  58. package/chunks/{chunk-KAQCJO6Y.js → chunk-KTKYGS2P.js} +35 -9
  59. package/chunks/{chunk-GBDINRIL.js → chunk-KTQGGPGV.js} +3 -3
  60. package/chunks/{chunk-6M26GBKX.js → chunk-L2AFWWJE.js} +42 -3
  61. package/chunks/{chunk-QXVSWG66.js → chunk-LHEC5V6G.js} +2 -2
  62. package/chunks/{chunk-J26HHFI5.js → chunk-LP2QGNSP.js} +32 -2
  63. package/chunks/{chunk-HWX5HPUG.js → chunk-LZZLUCRS.js} +108 -11
  64. package/chunks/{chunk-KTJFU7RT.js → chunk-MFDYOYZZ.js} +2 -2
  65. package/chunks/{chunk-3WNQOYHQ.js → chunk-MHP476D3.js} +74 -31
  66. package/chunks/{chunk-Y4TETC74.js → chunk-MTCYGTWH.js} +4 -4
  67. package/chunks/{chunk-EN2TKTFH.js → chunk-NV3F44FL.js} +6 -2
  68. package/chunks/{chunk-BF52U4XJ.js → chunk-OGDIJKHK.js} +1 -1
  69. package/chunks/{chunk-7DVT4LVV.js → chunk-OGNFHGIG.js} +3 -3
  70. package/chunks/{chunk-IYES5WOT.js → chunk-P2FK2HBV.js} +2 -2
  71. package/chunks/{chunk-2M4K4KYS.js → chunk-P3RBMQ4P.js} +4 -4
  72. package/chunks/{chunk-FYAXKJK7.js → chunk-P4ZEZSJZ.js} +692 -106
  73. package/chunks/{chunk-UFALT4LK.js → chunk-PBRVUF5B.js} +1 -1
  74. package/chunks/{chunk-LKRMNRSN.js → chunk-PDPFQ2FO.js} +2 -0
  75. package/chunks/{chunk-6TR7CFXH.js → chunk-PNBBJOCP.js} +1 -1
  76. package/chunks/{chunk-M3STHEMM.js → chunk-PVOGHGSF.js} +5 -5
  77. package/chunks/{chunk-4WU6NY7F.js → chunk-QSNSL4R4.js} +2 -2
  78. package/chunks/{chunk-DQSDACD2.js → chunk-RBHQXGDK.js} +1 -1
  79. package/chunks/{chunk-ZHA242R4.js → chunk-RVSTTOJ4.js} +2 -2
  80. package/chunks/{chunk-EIVICVHM.js → chunk-SCAZZ3Q4.js} +4 -4
  81. package/chunks/{chunk-BF224XHL.js → chunk-T5RLUXWJ.js} +2 -2
  82. package/chunks/{chunk-B52AWKBB.js → chunk-T6HEQR2Q.js} +16 -5
  83. package/chunks/{chunk-FWBXMANW.js → chunk-THIKWITR.js} +3 -3
  84. package/chunks/{chunk-WG6542MA.js → chunk-TQCYNLNJ.js} +1 -1
  85. package/chunks/chunk-TQOF5KBL.js +71 -0
  86. package/chunks/{chunk-NPUXXRJI.js → chunk-TZ6KJ44L.js} +1 -1
  87. package/chunks/{chunk-YHJFF7KH.js → chunk-UJUM2SRN.js} +147 -47
  88. package/chunks/{chunk-4ALIARFY.js → chunk-UYAUA63Q.js} +1 -1
  89. package/chunks/chunk-VFMASYQA.js +389 -0
  90. package/chunks/chunk-VGHZT6JR.js +51 -0
  91. package/chunks/{chunk-ZWBUH5UP.js → chunk-VKJ4KTPJ.js} +1 -1
  92. package/chunks/{chunk-QGHSP65Z.js → chunk-VNNWAZSI.js} +2 -2
  93. package/chunks/{chunk-757GB46F.js → chunk-W3FSZSF2.js} +1 -1
  94. package/chunks/{chunk-GQCEQPYQ.js → chunk-WGK4TSB7.js} +3 -3
  95. package/chunks/{chunk-PG62DFWD.js → chunk-WP5VOXF7.js} +6 -127
  96. package/chunks/{chunk-NVRDQFCX.js → chunk-XTY5DN4Y.js} +1 -1
  97. package/chunks/{chunk-GXSNGY5M.js → chunk-XX7QFP34.js} +1677 -1307
  98. package/chunks/{chunk-3PY4LPJF.js → chunk-YGT2AUJ7.js} +84 -4
  99. package/chunks/{chunk-4DU3NCHG.js → chunk-YTFDX4PR.js} +8 -3
  100. package/chunks/{chunk-OA4JVLSA.js → chunk-Z7VOMGDC.js} +22 -1
  101. package/chunks/{chunk-DX5W5AON.js → chunk-ZBXGWQ4S.js} +3 -3
  102. package/chunks/chunk-ZLBIFIMV.js +1099 -0
  103. package/chunks/{chunk-HA3SAB64.js → chunk-ZOSTTOUJ.js} +1 -1
  104. package/chunks/{chunk-VWMUDKLC.js → chunk-ZTQSOV56.js} +4 -4
  105. package/chunks/{computer-use-ESQYJ3JY.js → computer-use-PMZ7ICGY.js} +8 -8
  106. package/chunks/{config-utils-XQHBJP7G.js → config-utils-ULCSRMWD.js} +4 -4
  107. package/chunks/{contextCommand-CX3YF4ZE.js → contextCommand-GEZU7YHE.js} +11 -10
  108. package/chunks/{core-runtime-DIAU7JMG.js → core-runtime-HRJI2MN6.js} +8 -8
  109. package/chunks/{create-sub-session-HDPD6HOA.js → create-sub-session-VBNVI4YU.js} +9 -9
  110. package/chunks/{daemon-VZBGJUNL.js → daemon-POSQPD3G.js} +115 -7
  111. package/chunks/{daemon-status-provider-H6O4UQ4F.js → daemon-status-provider-N4CRQKFI.js} +18 -18
  112. package/chunks/{daemon-trust-policy-BNUXG6MT.js → daemon-trust-policy-BHO3JUHM.js} +16 -14
  113. package/chunks/{daemon-trust-policy-monitor-E4EQ7GF4.js → daemon-trust-policy-monitor-YEKJ2726.js} +16 -14
  114. package/chunks/{deferred-core-runtime-CBMSHPAU.js → deferred-core-runtime-SH57E3J3.js} +8 -8
  115. package/chunks/{dist-KVISB2O2.js → dist-3NTTUAHT.js} +1 -1
  116. package/chunks/{dist-RCH3I7SS.js → dist-6BMOAE3Z.js} +2 -2
  117. package/chunks/{dist-IRL7WA5Z.js → dist-B2CGTW6T.js} +1 -1
  118. package/chunks/{dist-TUSWNE2I.js → dist-EWW3J4HQ.js} +1 -1
  119. package/chunks/{dist-HIACTZEK.js → dist-EZE3V3Q7.js} +1 -1
  120. package/chunks/{dist-EEEQGCZA.js → dist-J47AXBZC.js} +1 -1
  121. package/chunks/{dist-MKX5OSFF.js → dist-OTUO3AS2.js} +4 -1088
  122. package/chunks/{dist-MBF3I5MX.js → dist-Z3CS4OVP.js} +1 -1
  123. package/chunks/{earlyInputCapture-UIOP7OIN.js → earlyInputCapture-B2JJ2HME.js} +8 -8
  124. package/chunks/{edit-ITMZYFKA.js → edit-7FTXENAN.js} +10 -8
  125. package/chunks/{enter-worktree-S4PL5UV6.js → enter-worktree-JPHV2PBG.js} +8 -8
  126. package/chunks/{enterPlanMode-YV52NNJT.js → enterPlanMode-CGBJ3AHJ.js} +8 -8
  127. package/chunks/{environment-NGOWPRZV.js → environment-LXASZAHD.js} +11 -11
  128. package/chunks/{errors-BU26DTDX.js → errors-XIGVT2AD.js} +10 -10
  129. package/chunks/{exit-worktree-XRM6LH5F.js → exit-worktree-DKSGXW65.js} +8 -8
  130. package/chunks/{exitPlanMode-ZLI5F7KR.js → exitPlanMode-THFL2HYN.js} +8 -8
  131. package/chunks/{fast-path-UJWORIED.js → fast-path-4NXAT5UL.js} +4 -3
  132. package/chunks/{fast-path-settings-37WQD5B2.js → fast-path-settings-RPAVBD7P.js} +2 -2
  133. package/chunks/{gemini-ZSKNDUMU.js → gemini-B3N6FACU.js} +56 -60
  134. package/chunks/{geminiContentGenerator-YGEXOEKD.js → geminiContentGenerator-YYFE2HIE.js} +1 -1
  135. package/chunks/{glob-7KZG44BR.js → glob-BPHSCFJP.js} +8 -8
  136. package/chunks/{grep-6ZFC7RJ5.js → grep-ROZIRFLU.js} +8 -8
  137. package/chunks/{handleAutoUpdate-KSEL3TQS.js → handleAutoUpdate-WV6SPZQB.js} +13 -12
  138. package/chunks/{i18n-ZIUXBW5V.js → i18n-YWJWPQKD.js} +13 -11
  139. package/chunks/{image-gen-AUIZJJNK.js → image-gen-SISRZ6FS.js} +1 -1
  140. package/chunks/{initializer-7AHY3N6Q.js → initializer-66OAD6GO.js} +16 -14
  141. package/chunks/{installationInfo-VGBXMYLY.js → installationInfo-3YUGIP36.js} +9 -9
  142. package/chunks/{list-PSFKQHLB.js → list-VEYR66XB.js} +19 -17
  143. package/chunks/{loadedSettingsAdapter-FTMRCTOF.js → loadedSettingsAdapter-V2JCPCYD.js} +16 -14
  144. package/chunks/{loggingContentGenerator-MZAN52UV.js → loggingContentGenerator-RBLNDREC.js} +6 -6
  145. package/chunks/main-PXAUXNF2.js +8 -0
  146. package/chunks/{managed-npm-update-O4NHK45X.js → managed-npm-update-C5ID5R4R.js} +9 -9
  147. package/chunks/{mcp-6CFP2AYQ.js → mcp-OZ54NZJQ.js} +16 -14
  148. package/chunks/{monitor-DAKD6OU4.js → monitor-7Y4TVFTK.js} +18 -14
  149. package/chunks/{nonInteractiveCli-RC7VIUZL.js → nonInteractiveCli-QEK4LHAC.js} +51 -49
  150. package/chunks/{notebook-edit-474DPMRL.js → notebook-edit-OG35EBGY.js} +9 -8
  151. package/chunks/{openaiContentGenerator-2NFY2MWO.js → openaiContentGenerator-443BNRPJ.js} +5 -5
  152. package/chunks/{pidfile-KBFVDNQP.js → pidfile-ZK4OLRZA.js} +8 -8
  153. package/chunks/{processUtils-6GRYH4Y3.js → processUtils-4YGB4RUZ.js} +2 -2
  154. package/chunks/{qwenContentGenerator-KAHU6IZY.js → qwenContentGenerator-D5C2LCSZ.js} +9 -9
  155. package/chunks/{qwenOAuth2-RRQTCP4W.js → qwenOAuth2-Z4YQBMYN.js} +1 -1
  156. package/chunks/{read-file-3M6WXDXP.js → read-file-EXTJLWMU.js} +4 -4
  157. package/chunks/{resumeHistoryUtils-D6TAY3HX.js → resumeHistoryUtils-UPCGRJUL.js} +13 -12
  158. package/chunks/{ripGrep-PLPENT3E.js → ripGrep-QBVIRCU4.js} +8 -8
  159. package/chunks/{run-qwen-serve-ZAFIJKJC.js → run-qwen-serve-ZYGJNE3E.js} +169 -68
  160. package/chunks/{runtime-ZED7CYOZ.js → runtime-BZZ4LWCP.js} +21 -19
  161. package/chunks/{scheduler-MD3AL2W5.js → scheduler-YNQNOU2E.js} +135 -15
  162. package/chunks/{sdk-exporters-http-KHAB5JSD.js → sdk-exporters-http-XVTZQRCE.js} +2 -2
  163. package/chunks/{sdk-impl-KD7FSTC3.js → sdk-impl-7W7AKCS4.js} +7 -3
  164. package/chunks/{serve-E3VUDRZN.js → serve-LJHAXDCH.js} +18 -14
  165. package/chunks/{server-OWMEMAKR.js → server-ADMLELR6.js} +1229 -1098
  166. package/chunks/{session-HZ57QK7K.js → session-YKZXFFTM.js} +55 -53
  167. package/chunks/{settings-V7BR3RKP.js → settings-EQBUAQ7Y.js} +15 -13
  168. package/chunks/{shell-23OMNMW6.js → shell-3QZOJGTT.js} +8 -8
  169. package/chunks/{skill-6HBDYZRS.js → skill-UWSSMXE7.js} +5 -5
  170. package/chunks/{skill-settings-HWJLTU7M.js → skill-settings-T6MLB7NU.js} +15 -13
  171. package/chunks/{spawnChannel-N6KKUW5B.js → spawnChannel-VS7ZFUFP.js} +11 -11
  172. package/chunks/{standalone-update-QGIKHATD.js → standalone-update-2W26SRRO.js} +11 -10
  173. package/chunks/{startInteractiveUI-GX2CRL42.js → startInteractiveUI-CVS7K3D6.js} +86 -75
  174. package/chunks/{team-create-CFFKU7KL.js → team-create-4WFTNNUL.js} +8 -8
  175. package/chunks/{team-plan-approval-6EFOKR6A.js → team-plan-approval-DBYI33S3.js} +8 -8
  176. package/chunks/{terminal-image-renderer-TLDNACQY.js → terminal-image-renderer-S5WPPQKH.js} +8 -8
  177. package/chunks/{theme-manager-5LJ3H7VO.js → theme-manager-LI2RIOVR.js} +8 -8
  178. package/chunks/{tool-search-UJV3A24H.js → tool-search-4773EUQ4.js} +4 -4
  179. package/chunks/{total-session-admission-D63QYXGO.js → total-session-admission-PAY5CH2Z.js} +16 -15
  180. package/chunks/{trustedFolders-KZCOB53W.js → trustedFolders-FRSLE674.js} +9 -9
  181. package/chunks/{types-ML3TRJQ5.js → types-WYCFCEHR.js} +5 -3
  182. package/chunks/{update-relaunch-IFILM3SA.js → update-relaunch-ZSFQTU6M.js} +5 -5
  183. package/chunks/{updateCheck-YZ2CRCFC.js → updateCheck-AXWSO7KA.js} +12 -11
  184. package/chunks/{useAutoAcceptIndicator-AXEVNA3Q.js → useAutoAcceptIndicator-VHLXIA7U.js} +18 -16
  185. package/chunks/{validateNonInterActiveAuth-3WTOJFWA.js → validateNonInterActiveAuth-PDJECMFU.js} +48 -46
  186. package/chunks/{version-GXK7OHZY.js → version-RBN764QS.js} +1 -1
  187. package/chunks/{web-fetch-ILB4GAVR.js → web-fetch-7BJK42AF.js} +4 -4
  188. package/chunks/{web-search-HKRPGPZZ.js → web-search-L2CILQXV.js} +4 -3
  189. package/chunks/{workflow-FXIPRQQA.js → workflow-5VH2R74I.js} +170 -137
  190. package/chunks/{workspace-providers-status-NYHC7HSR.js → workspace-providers-status-OZTQ6JFH.js} +19 -17
  191. package/chunks/{workspace-registration-store-AKEB7OMW.js → workspace-registration-store-IX5RJQS5.js} +1 -1
  192. package/chunks/{workspace-registry-CDAS5TVZ.js → workspace-registry-73N4BGG4.js} +16 -15
  193. package/chunks/{workspace-service-PAMUKMAV.js → workspace-service-I5RUPSNV.js} +26 -22
  194. package/chunks/{workspace-skills-status-YQSHCCMS.js → workspace-skills-status-DMK6VYDO.js} +17 -15
  195. package/chunks/{workspace-trust-reconciler-RPTXOIY2.js → workspace-trust-reconciler-QX4RL3TC.js} +24 -21
  196. package/chunks/{write-file-CGS57TS4.js → write-file-UGDD5UTS.js} +8 -8
  197. package/chunks/{zoom-image-E7D72GYV.js → zoom-image-ZAHEO3YP.js} +4 -4
  198. package/cli.js +12 -12
  199. package/package.json +3 -3
  200. package/web-shell/assets/{arc-DybZaz32.js → arc-CHY4saMJ.js} +1 -1
  201. package/web-shell/assets/{architectureDiagram-3BPJPVTR-jN3qBd19.js → architectureDiagram-3BPJPVTR-Bu6CwvHj.js} +1 -1
  202. package/web-shell/assets/{blockDiagram-GPEHLZMM-Ct5DZPrj.js → blockDiagram-GPEHLZMM-XGt6iGf_.js} +1 -1
  203. package/web-shell/assets/{c4Diagram-AAUBKEIU-CUAFMlUG.js → c4Diagram-AAUBKEIU-CBbYl19W.js} +1 -1
  204. package/web-shell/assets/channel-B40srHOa.js +1 -0
  205. package/web-shell/assets/{chunk-2J33WTMH-CuV8n90B.js → chunk-2J33WTMH-BEhmVrdx.js} +1 -1
  206. package/web-shell/assets/{chunk-4BX2VUAB-BUzl_kls.js → chunk-4BX2VUAB-fQLyE0Bg.js} +1 -1
  207. package/web-shell/assets/{chunk-55IACEB6-BnDBLX6A.js → chunk-55IACEB6-yGdtyx4a.js} +1 -1
  208. package/web-shell/assets/{chunk-727SXJPM-B83uTOjm.js → chunk-727SXJPM-DYbX2GLo.js} +1 -1
  209. package/web-shell/assets/{chunk-AQP2D5EJ-DM3HLgpT.js → chunk-AQP2D5EJ-DyKTEsYn.js} +1 -1
  210. package/web-shell/assets/{chunk-FMBD7UC4-CSQ5hgyb.js → chunk-FMBD7UC4-D8Uy_GzX.js} +1 -1
  211. package/web-shell/assets/{chunk-ND2GUHAM-BWOF4SxX.js → chunk-ND2GUHAM-C8wNR2K7.js} +1 -1
  212. package/web-shell/assets/{chunk-QZHKN3VN-BsOH9LMi.js → chunk-QZHKN3VN-BnybNxnt.js} +1 -1
  213. package/web-shell/assets/classDiagram-4FO5ZUOK-qumcXQW_.js +1 -0
  214. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-qumcXQW_.js +1 -0
  215. package/web-shell/assets/{cose-bilkent-S5V4N54A-IENqH2iJ.js → cose-bilkent-S5V4N54A-jq4uiFRp.js} +1 -1
  216. package/web-shell/assets/{dagre-BM42HDAG--dyzDTGo.js → dagre-BM42HDAG-Bs7oye1U.js} +1 -1
  217. package/web-shell/assets/{diagram-2AECGRRQ-BE7Dcqof.js → diagram-2AECGRRQ-BHGGJNyM.js} +1 -1
  218. package/web-shell/assets/{diagram-5GNKFQAL-Cr8-5OTj.js → diagram-5GNKFQAL-BJezVLGT.js} +1 -1
  219. package/web-shell/assets/{diagram-KO2AKTUF-Bzey3uAY.js → diagram-KO2AKTUF-5JzQN_rL.js} +1 -1
  220. package/web-shell/assets/{diagram-LMA3HP47-sErl28Xb.js → diagram-LMA3HP47-BlPYOgY9.js} +1 -1
  221. package/web-shell/assets/{diagram-OG6HWLK6-Dq30ATIo.js → diagram-OG6HWLK6-CtMHEaFK.js} +1 -1
  222. package/web-shell/assets/{erDiagram-TEJ5UH35-BkCoEfVW.js → erDiagram-TEJ5UH35-CRNdq2AB.js} +1 -1
  223. package/web-shell/assets/{flowDiagram-I6XJVG4X-DHwO0rrI.js → flowDiagram-I6XJVG4X-De1WwLzu.js} +1 -1
  224. package/web-shell/assets/{ganttDiagram-6RSMTGT7-s7vAPxWq.js → ganttDiagram-6RSMTGT7-YbWfL5Zn.js} +1 -1
  225. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-CQxhwPOU.js → gitGraphDiagram-PVQCEYII-DzCN8bmd.js} +1 -1
  226. package/web-shell/assets/index-BDOGGGaN.css +5 -0
  227. package/web-shell/assets/{index-CF4wApWp.js → index-CocPvF9Q.js} +1 -1
  228. package/web-shell/assets/index-DSH2KrMc.js +1771 -0
  229. package/web-shell/assets/{infoDiagram-5YYISTIA-BnFrD0bq.js → infoDiagram-5YYISTIA-DLHoopnE.js} +1 -1
  230. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-Bf9zK5NK.js → ishikawaDiagram-YF4QCWOH-XnbU04SS.js} +1 -1
  231. package/web-shell/assets/{journeyDiagram-JHISSGLW-CyGAhsxi.js → journeyDiagram-JHISSGLW-CipPyEeJ.js} +1 -1
  232. package/web-shell/assets/{kanban-definition-UN3LZRKU-CbsK5akB.js → kanban-definition-UN3LZRKU-DrSeyE5d.js} +1 -1
  233. package/web-shell/assets/{linear-cQsF4P8D.js → linear-LrBKnAo_.js} +1 -1
  234. package/web-shell/assets/{mermaid.core-Z4HVqrKY.js → mermaid.core-C3U9UVmf.js} +5 -5
  235. package/web-shell/assets/{mindmap-definition-RKZ34NQL-CYnrBo_f.js → mindmap-definition-RKZ34NQL-DqRWgC9H.js} +1 -1
  236. package/web-shell/assets/{pieDiagram-4H26LBE5-CBzOfhrs.js → pieDiagram-4H26LBE5-BNXY5p6H.js} +1 -1
  237. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-D4LK1Ebn.js → quadrantDiagram-W4KKPZXB-Ccj9QzE4.js} +1 -1
  238. package/web-shell/assets/{requirementDiagram-4Y6WPE33-Bzti2Lcj.js → requirementDiagram-4Y6WPE33-CjPM2_gx.js} +1 -1
  239. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-yTBw5Z2s.js → sankeyDiagram-5OEKKPKP-C0RsvKbj.js} +1 -1
  240. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-D07UVRiZ.js → sequenceDiagram-3UESZ5HK-ClN1P5z7.js} +1 -1
  241. package/web-shell/assets/{stateDiagram-AJRCARHV-UE_lHsTn.js → stateDiagram-AJRCARHV-By0eiB2Y.js} +1 -1
  242. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Ds0WlK3F.js +1 -0
  243. package/web-shell/assets/{timeline-definition-PNZ67QCA-DRvYdiTs.js → timeline-definition-PNZ67QCA-g_iaSQgv.js} +1 -1
  244. package/web-shell/assets/{vennDiagram-CIIHVFJN-CQLIXs0u.js → vennDiagram-CIIHVFJN-y9ZqJ-TD.js} +1 -1
  245. package/web-shell/assets/{wardley-L42UT6IY-JZz_Xqse.js → wardley-L42UT6IY-BVVfaxpF.js} +1 -1
  246. package/web-shell/assets/{wardleyDiagram-YWT4CUSO--i7BiJwB.js → wardleyDiagram-YWT4CUSO-D3ooZKZT.js} +1 -1
  247. package/web-shell/assets/{xychartDiagram-2RQKCTM6-Bkc-bW0S.js → xychartDiagram-2RQKCTM6-6GXrY6M1.js} +1 -1
  248. package/web-shell/index.html +2 -2
  249. package/chunks/chunk-RXFQM6FQ.js +0 -42
  250. package/chunks/chunk-UA5H3DS2.js +0 -203
  251. package/web-shell/assets/channel-BMwLrwLW.js +0 -1
  252. package/web-shell/assets/classDiagram-4FO5ZUOK-BGDv98jY.js +0 -1
  253. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BGDv98jY.js +0 -1
  254. package/web-shell/assets/index-Bckpjr-I.css +0 -5
  255. package/web-shell/assets/index-DwEr9HEW.js +0 -1768
  256. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DC6xgXjX.js +0 -1
  257. /package/chunks/{chunk-VXZBKKQR.js → chunk-NTTBXH7U.js} +0 -0
  258. /package/chunks/{chunk-GRC5HGPI.js → chunk-OIBUG24X.js} +0 -0
@@ -1,8 +1,5 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
- import {
4
- recomputeMcpGating
5
- } from "./chunk-YEF7XEO2.js";
6
3
  import {
7
4
  classifyApiError,
8
5
  fireSessionDeleteHook
@@ -16,14 +13,17 @@ import {
16
13
  matchMcpServerByRef,
17
14
  parseExtensionRef,
18
15
  parseMcpServerRef
19
- } from "./chunk-FWBXMANW.js";
16
+ } from "./chunk-THIKWITR.js";
20
17
  import {
21
18
  getAvailableCommands,
22
19
  handleSlashCommand,
23
20
  insertAfterFunctionResponses,
24
21
  isSlashCommand,
25
22
  normalizePartList
26
- } from "./chunk-YHJFF7KH.js";
23
+ } from "./chunk-UJUM2SRN.js";
24
+ import {
25
+ recomputeMcpGating
26
+ } from "./chunk-3XVDTHBJ.js";
27
27
  import {
28
28
  SessionIdConflictError,
29
29
  appEvents,
@@ -31,27 +31,28 @@ import {
31
31
  cleanupReviewWorktreeLeases,
32
32
  loadCliConfig,
33
33
  normalizeDisabledToolList
34
- } from "./chunk-7VUERJHS.js";
34
+ } from "./chunk-II6G3EY6.js";
35
35
  import {
36
36
  getCommandSubcommandNames
37
- } from "./chunk-NVRDQFCX.js";
37
+ } from "./chunk-XTY5DN4Y.js";
38
38
  import {
39
39
  getEffectiveSupportedModes
40
- } from "./chunk-XHD7CRP2.js";
40
+ } from "./chunk-5RBDAGC6.js";
41
41
  import "./chunk-NYX53SV4.js";
42
- import "./chunk-EN2TKTFH.js";
42
+ import "./chunk-NV3F44FL.js";
43
43
  import {
44
44
  collectContextData,
45
45
  formatContextUsageText
46
- } from "./chunk-GOEVOFQI.js";
46
+ } from "./chunk-DH5YXSIF.js";
47
47
  import "./chunk-4WGODMVR.js";
48
- import "./chunk-ZHA242R4.js";
49
- import "./chunk-YAF2MQZ6.js";
50
48
  import "./chunk-CTJLZLB5.js";
49
+ import "./chunk-SCAZZ3Q4.js";
50
+ import "./chunk-RVSTTOJ4.js";
51
+ import "./chunk-YAF2MQZ6.js";
51
52
  import {
52
53
  computeCpuPercent
53
54
  } from "./chunk-LBOVL47Y.js";
54
- import "./chunk-HWX5HPUG.js";
55
+ import "./chunk-LZZLUCRS.js";
55
56
  import "./chunk-6H67XLET.js";
56
57
  import {
57
58
  beginAcpBootstrapConfigProfiling,
@@ -59,8 +60,7 @@ import {
59
60
  endAcpBootstrapConfigProfiling,
60
61
  markAcpStartup
61
62
  } from "./chunk-CG3WBKJK.js";
62
- import "./chunk-EIVICVHM.js";
63
- import "./chunk-IYES5WOT.js";
63
+ import "./chunk-P2FK2HBV.js";
64
64
  import {
65
65
  GENERATION_MAX_PROMPT_BYTES,
66
66
  GENERATION_TIMEOUT_MS,
@@ -74,7 +74,6 @@ import {
74
74
  formatWorkspaceMemoryForgetSummary,
75
75
  isCompatibleLiveSessionSource,
76
76
  isValidServerName,
77
- loadSettingsCached,
78
77
  normalizeChannelDeliveryText,
79
78
  projectAcpToolResultUpdate,
80
79
  redactMcpServerSecrets,
@@ -83,7 +82,7 @@ import {
83
82
  shouldSuppressRememberErrorDetails,
84
83
  workspaceMemoryFailureCode,
85
84
  workspaceMemoryFailureDiagnostics
86
- } from "./chunk-ZPLALRXZ.js";
85
+ } from "./chunk-FBMCDU63.js";
87
86
  import {
88
87
  HistoryReplayer,
89
88
  MessageEmitter,
@@ -93,9 +92,9 @@ import {
93
92
  goalTerminalEventToHistoryItem,
94
93
  recordGoalStatusItem,
95
94
  restoreGoalFromHistory
96
- } from "./chunk-2M4K4KYS.js";
95
+ } from "./chunk-P3RBMQ4P.js";
97
96
  import "./chunk-OWMAZHIX.js";
98
- import "./chunk-4ALIARFY.js";
97
+ import "./chunk-UYAUA63Q.js";
99
98
  import "./chunk-4NFY2S7N.js";
100
99
  import "./chunk-2MIN6GRR.js";
101
100
  import "./chunk-QHTIBUWB.js";
@@ -103,58 +102,67 @@ import {
103
102
  isTerminalGoalStatusKind
104
103
  } from "./chunk-EKTCKZV5.js";
105
104
  import "./chunk-3Z43GZUQ.js";
106
- import "./chunk-RXFQM6FQ.js";
107
- import "./chunk-HGCQ5SE7.js";
108
105
  import {
109
- ACP_ROUTE_ID_PREFIX,
110
- buildAcpModelOptions,
111
- getCurrentAcpModelId,
112
- parseAcpBaseModelId,
113
- parseAcpModelOption,
114
- resolveAcpModelOption,
115
- sanitizeProviderBaseUrl
116
- } from "./chunk-GBDINRIL.js";
106
+ buildToolWriteOriginMeta
107
+ } from "./chunk-VGHZT6JR.js";
117
108
  import {
118
- mapSkillConfigToStatus
119
- } from "./chunk-BGXZBI5B.js";
109
+ normalizeSessionIdForLookup,
110
+ parseCallerSuppliedSessionId
111
+ } from "./chunk-TQOF5KBL.js";
112
+ import "./chunk-HGCQ5SE7.js";
120
113
  import {
121
114
  PERMISSION_RULE_TYPES,
122
115
  PermissionRulesValidationError,
123
116
  buildPermissionSettings,
124
117
  normalizePermissionRules,
125
118
  readPermissionRuleSet
126
- } from "./chunk-KKDVZLGL.js";
119
+ } from "./chunk-BAMN6XSD.js";
127
120
  import {
128
121
  MAX_AUDIO_BYTES,
129
122
  sanitizeVoiceErrorMessage,
130
123
  transcribeVoiceAudio
131
- } from "./chunk-DQSDACD2.js";
124
+ } from "./chunk-RBHQXGDK.js";
132
125
  import {
133
126
  readVoiceModel
134
- } from "./chunk-C5VWPTGT.js";
127
+ } from "./chunk-GAKGOXTC.js";
135
128
  import "./chunk-AOHJKPKL.js";
129
+ import "./chunk-NTTBXH7U.js";
130
+ import "./chunk-7S4JBJLU.js";
131
+ import "./chunk-3SH53ANB.js";
132
+ import {
133
+ ACP_ROUTE_ID_PREFIX,
134
+ buildAcpModelOptions,
135
+ getCurrentAcpModelId,
136
+ parseAcpBaseModelId,
137
+ parseAcpModelOption,
138
+ resolveAcpModelOption,
139
+ sanitizeProviderBaseUrl
140
+ } from "./chunk-KTQGGPGV.js";
141
+ import {
142
+ mapSkillConfigToStatus
143
+ } from "./chunk-BGXZBI5B.js";
136
144
  import {
137
145
  resolveSkillSettings
138
146
  } from "./chunk-Z4X5MTRT.js";
139
- import "./chunk-E4ZBKMSF.js";
140
- import "./chunk-QQWD7LZV.js";
147
+ import "./chunk-ATMO54WE.js";
148
+ import "./chunk-HADWBW5R.js";
141
149
  import "./chunk-57OAHC2Y.js";
150
+ import "./chunk-LHEC5V6G.js";
151
+ import "./chunk-67EWJE77.js";
152
+ import "./chunk-E2FPSSKP.js";
142
153
  import {
143
154
  createLoadedSettingsAdapter
144
- } from "./chunk-WV5J6Q6N.js";
145
- import "./chunk-VXZBKKQR.js";
146
- import "./chunk-3SE7J4DR.js";
147
- import "./chunk-3SH53ANB.js";
155
+ } from "./chunk-D7BXVKSF.js";
148
156
  import {
149
157
  SESSION_SOURCE_META_KEY,
150
158
  parseSessionSource
151
- } from "./chunk-FYAXKJK7.js";
159
+ } from "./chunk-P4ZEZSJZ.js";
152
160
  import "./chunk-MZSJ43WV.js";
153
161
  import "./chunk-XCGIMOLN.js";
154
162
  import "./chunk-OCPBI7J5.js";
155
163
  import {
156
164
  ndJsonStream
157
- } from "./chunk-RPWVIXDB.js";
165
+ } from "./chunk-I5VM3SKY.js";
158
166
  import {
159
167
  ACP_PREFLIGHT_KINDS,
160
168
  IDLE_HOOK_EVENTS,
@@ -162,10 +170,8 @@ import {
162
170
  SERVE_STATUS_EXT_METHODS,
163
171
  STATUS_SCHEMA_VERSION,
164
172
  mapDomainErrorToErrorKind
165
- } from "./chunk-NLREQJFK.js";
166
- import "./chunk-QXVSWG66.js";
167
- import "./chunk-KJZ26VBX.js";
168
- import "./chunk-NGYI5EF5.js";
173
+ } from "./chunk-DA4HRSBW.js";
174
+ import "./chunk-VKJ4KTPJ.js";
169
175
  import "./chunk-V6WHFGST.js";
170
176
  import {
171
177
  ACTIVE_WORK_CLOSE_IF_UNHELD_PARAM,
@@ -196,13 +202,14 @@ import {
196
202
  import {
197
203
  NOT_CURRENTLY_GENERATING_CANCEL_MESSAGE,
198
204
  isNotCurrentlyGeneratingCancelError
199
- } from "./chunk-J26HHFI5.js";
205
+ } from "./chunk-LP2QGNSP.js";
200
206
  import "./chunk-6PLDPT2C.js";
201
207
  import "./chunk-FYJ7W2PI.js";
202
208
  import "./chunk-YP5KH5Y7.js";
203
- import "./chunk-UFALT4LK.js";
209
+ import "./chunk-PBRVUF5B.js";
204
210
  import "./chunk-ALMR3E6Q.js";
205
211
  import "./chunk-HIBNSEJE.js";
212
+ import "./chunk-M5GB774H.js";
206
213
  import {
207
214
  EXTERNAL_TOOL_GUARD_READY_META_KEY,
208
215
  EXTERNAL_TOOL_GUARD_REQUIRED_VALUE,
@@ -210,12 +217,11 @@ import {
210
217
  PRIVATE_EXTERNAL_TOOL_GUARD_ENV,
211
218
  isValidExternalToolGuardDenialReason
212
219
  } from "./chunk-BKHCW2BI.js";
213
- import "./chunk-M5GB774H.js";
214
220
  import "./chunk-UVX4Y6IN.js";
215
- import "./chunk-ZWBUH5UP.js";
216
221
  import {
217
- ACP_EVENT_LOOP_STALL_RESTART_MS
218
- } from "./chunk-DIWZNWZT.js";
222
+ ACP_EVENT_LOOP_STALL_RESTART_MS,
223
+ CHANNEL_PROMPT_META_KEY
224
+ } from "./chunk-DX3RGJMS.js";
219
225
  import {
220
226
  AgentSideConnection,
221
227
  PROTOCOL_VERSION,
@@ -224,35 +230,46 @@ import {
224
230
  import {
225
231
  assembleMcpServers,
226
232
  loadMcpApprovals
227
- } from "./chunk-Y4TETC74.js";
233
+ } from "./chunk-MTCYGTWH.js";
228
234
  import {
229
235
  getOutputLanguageFilePath,
230
236
  getPersistScopeForModelSelection,
237
+ getUserSettingsPath,
231
238
  loadSettings,
232
239
  resolveOutputLanguageOrPreserveAuto,
233
240
  updateOutputLanguageFile,
234
241
  writeOutputLanguageAndRegisterPath
235
- } from "./chunk-OHKJVAKG.js";
242
+ } from "./chunk-JUWS2Z5K.js";
243
+ import "./chunk-7GOYZQPR.js";
236
244
  import "./chunk-RKUWKYED.js";
237
245
  import "./chunk-GOXKNSDZ.js";
238
- import "./chunk-IDS7MSUP.js";
239
246
  import {
240
- SUPPORTED_LANGUAGES,
247
+ getSystemDefaultsPath,
248
+ getSystemSettingsPath
249
+ } from "./chunk-IDS7MSUP.js";
250
+ import {
241
251
  getCurrentLanguage,
242
252
  setLanguageAsync
243
- } from "./chunk-PG62DFWD.js";
253
+ } from "./chunk-WP5VOXF7.js";
254
+ import {
255
+ SUPPORTED_LANGUAGES
256
+ } from "./chunk-5EJZE3FP.js";
244
257
  import {
258
+ findEnvFiles,
259
+ preResolveHomeEnvOverrides,
245
260
  reloadEnvironment
246
- } from "./chunk-B52AWKBB.js";
247
- import "./chunk-UA5H3DS2.js";
248
- import "./chunk-IUQ52YJK.js";
249
- import "./chunk-FN6YXJOP.js";
261
+ } from "./chunk-T6HEQR2Q.js";
262
+ import {
263
+ ENV_ACP_REPEATED_TOOL_FAILURE_GUARD
264
+ } from "./chunk-VFMASYQA.js";
265
+ import "./chunk-BIRWP6LU.js";
266
+ import "./chunk-IOEZE2YT.js";
250
267
  import "./chunk-VJNBRRZG.js";
251
268
  import {
252
269
  isFolderTrustEnabled,
253
270
  isWorkspaceTrusted,
254
271
  loadTrustedFolders
255
- } from "./chunk-HA3SAB64.js";
272
+ } from "./chunk-ZOSTTOUJ.js";
256
273
  import "./chunk-NPQ5ZKRP.js";
257
274
  import "./chunk-MR3PXB6E.js";
258
275
  import "./chunk-XFSFZCM5.js";
@@ -349,6 +366,7 @@ import {
349
366
  getScopedEnvContents,
350
367
  getStopHookContinuationReason,
351
368
  getToolCallRepeatKey,
369
+ ideContextStore,
352
370
  injectPermissionRulesIfMissing,
353
371
  isApproveOutcome,
354
372
  isDenialFallbackReason,
@@ -386,7 +404,7 @@ import {
386
404
  updateSetting,
387
405
  validatePlanModeShellApproval,
388
406
  validatePlanModeShellContext
389
- } from "./chunk-GXSNGY5M.js";
407
+ } from "./chunk-XX7QFP34.js";
390
408
  import "./chunk-GOFAQQZA.js";
391
409
  import "./chunk-5M6IDOMF.js";
392
410
  import "./chunk-TWPJO254.js";
@@ -400,7 +418,7 @@ import "./chunk-7MH4J33A.js";
400
418
  import {
401
419
  parsePositiveIntegerEnv
402
420
  } from "./chunk-6PVPNMXU.js";
403
- import "./chunk-VXZ5HAOV.js";
421
+ import "./chunk-K4ADGWHU.js";
404
422
  import "./chunk-IRH27ZC2.js";
405
423
  import "./chunk-QHWCP53L.js";
406
424
  import "./chunk-GNPNYXJB.js";
@@ -426,7 +444,7 @@ import {
426
444
  import {
427
445
  APPROVAL_MODES
428
446
  } from "./chunk-WAUGQKUU.js";
429
- import "./chunk-PLFATELK.js";
447
+ import "./chunk-DZUO626D.js";
430
448
  import {
431
449
  addToolArgumentsAttributes,
432
450
  addToolCallResultAttributes,
@@ -434,7 +452,7 @@ import {
434
452
  registerAcpEventLoopLagGauge,
435
453
  startEventLoopLagMonitor,
436
454
  withDaemonSpan
437
- } from "./chunk-L4N6TIP7.js";
455
+ } from "./chunk-4TRQPFDP.js";
438
456
  import "./chunk-SAH4BD2J.js";
439
457
  import {
440
458
  runWithRuntimeContentGenerator
@@ -475,6 +493,7 @@ import {
475
493
  PRIVATE_ACP_CAPABILITY_ENV,
476
494
  PRIVATE_PARENT_CAPABILITY_META_KEY,
477
495
  PromptSuggestionEvent,
496
+ RepeatedToolFailureGuardEvent,
478
497
  UserPromptEvent,
479
498
  formatFullTurnVisionNotice,
480
499
  formatVisionBridgeNotice,
@@ -487,6 +506,7 @@ import {
487
506
  logConversationFinishedEvent,
488
507
  logLoopDetected,
489
508
  logPromptSuggestion,
509
+ logRepeatedToolFailureGuard,
490
510
  logToolCall,
491
511
  logUserPrompt,
492
512
  normalizeParts,
@@ -496,7 +516,7 @@ import {
496
516
  shouldRunVisionBridge,
497
517
  splitImageParts,
498
518
  uiTelemetryService
499
- } from "./chunk-3PY4LPJF.js";
519
+ } from "./chunk-YGT2AUJ7.js";
500
520
  import "./chunk-WOJZWRAZ.js";
501
521
  import "./chunk-VGC4I5JJ.js";
502
522
  import {
@@ -518,7 +538,7 @@ import {
518
538
  import {
519
539
  AuthType,
520
540
  preloadContentGenerator
521
- } from "./chunk-M3STHEMM.js";
541
+ } from "./chunk-PVOGHGSF.js";
522
542
  import "./chunk-F6WFNA7U.js";
523
543
  import "./chunk-46UV252V.js";
524
544
  import {
@@ -536,9 +556,9 @@ import {
536
556
  startToolExecutionSpan,
537
557
  startToolSpan,
538
558
  withInteractionSpan
539
- } from "./chunk-6M26GBKX.js";
559
+ } from "./chunk-L2AFWWJE.js";
540
560
  import "./chunk-W4RQUHY3.js";
541
- import "./chunk-LKRMNRSN.js";
561
+ import "./chunk-PDPFQ2FO.js";
542
562
  import {
543
563
  Storage,
544
564
  createDebugLogger,
@@ -547,10 +567,10 @@ import {
547
567
  isSubpath
548
568
  } from "./chunk-OIVKILPI.js";
549
569
  import "./chunk-VOQXFAY5.js";
550
- import "./chunk-BF52U4XJ.js";
570
+ import "./chunk-OGDIJKHK.js";
551
571
  import {
552
572
  runExitCleanup
553
- } from "./chunk-6TR7CFXH.js";
573
+ } from "./chunk-PNBBJOCP.js";
554
574
  import {
555
575
  writeStderrLine,
556
576
  writeStderrLineSafe
@@ -759,11 +779,14 @@ var AcpFileSystemService = class {
759
779
  if (!this.capabilities.writeTextFile) {
760
780
  return this.fallback.writeTextFile(params);
761
781
  }
762
- const finalContent = params._meta?.["bom"] && params.content.charCodeAt(0) !== 65279 ? "\uFEFF" + params.content : params.content;
782
+ const { toolWriteOrigin, _meta: requestMeta, ...wireParams } = params;
783
+ const finalContent = requestMeta?.["bom"] && params.content.charCodeAt(0) !== 65279 ? "\uFEFF" + params.content : params.content;
784
+ const wireMeta = buildToolWriteOriginMeta(requestMeta, toolWriteOrigin);
763
785
  try {
764
786
  await this.connection.writeTextFile({
765
- ...params,
787
+ ...wireParams,
766
788
  content: finalContent,
789
+ ...wireMeta !== void 0 ? { _meta: wireMeta } : {},
767
790
  sessionId: this.sessionId
768
791
  });
769
792
  } catch (error) {
@@ -799,11 +822,126 @@ var AcpFileSystemService = class {
799
822
  // packages/cli/src/acp-integration/acpAgent.ts
800
823
  import { Readable, Writable } from "node:stream";
801
824
  import { pipeline } from "node:stream/promises";
802
- import * as fs from "node:fs/promises";
803
- import * as os2 from "node:os";
804
- import * as path3 from "node:path";
825
+ import * as fs2 from "node:fs/promises";
826
+ import * as os3 from "node:os";
827
+ import * as path4 from "node:path";
805
828
  import { createGunzip } from "node:zlib";
806
829
 
830
+ // packages/cli/src/config/settings-cache.ts
831
+ init_esbuild_shims();
832
+ import * as fs from "node:fs";
833
+ import * as os from "node:os";
834
+ import * as path2 from "node:path";
835
+ var MAX_CACHE_ENTRIES = 64;
836
+ var debugLogger2 = createDebugLogger("SETTINGS_CACHE");
837
+ var cache = /* @__PURE__ */ new Map();
838
+ function statSig(filePath) {
839
+ const st = fs.statSync(filePath, { throwIfNoEntry: false });
840
+ return st ? `${st.mtimeMs}:${st.size}:${st.ino}` : "missing";
841
+ }
842
+ __name(statSig, "statSig");
843
+ function realpathOr(p) {
844
+ try {
845
+ return fs.realpathSync(p);
846
+ } catch {
847
+ return path2.resolve(p);
848
+ }
849
+ }
850
+ __name(realpathOr, "realpathOr");
851
+ function settingsFileSigs(workspaceDir) {
852
+ const filePaths = [
853
+ getSystemSettingsPath(),
854
+ getSystemDefaultsPath(),
855
+ getUserSettingsPath(),
856
+ new Storage(workspaceDir).getWorkspaceSettingsPath()
857
+ ];
858
+ return filePaths.map((filePath) => ({ filePath, sig: statSig(filePath) }));
859
+ }
860
+ __name(settingsFileSigs, "settingsFileSigs");
861
+ function envFileSigs(settings, workspaceDir) {
862
+ return findEnvFiles(settings.merged, workspaceDir).map((filePath) => ({
863
+ filePath,
864
+ sig: statSig(filePath)
865
+ }));
866
+ }
867
+ __name(envFileSigs, "envFileSigs");
868
+ function sameFileSigs(a, b) {
869
+ if (a.length !== b.length) {
870
+ return false;
871
+ }
872
+ return a.every(
873
+ (sig, i) => sig.filePath === b[i].filePath && sig.sig === b[i].sig
874
+ );
875
+ }
876
+ __name(sameFileSigs, "sameFileSigs");
877
+ function isEntryFresh(key, entry) {
878
+ const fp = entry.fingerprint;
879
+ return ideContextStore.get()?.workspaceState?.isTrusted === fp.ideTrust && realpathOr(key) === fp.realCwd && // homeDir guards the corner where nothing else moves: QWEN_HOME set (so
880
+ // settings paths don't follow HOME), no .env files anywhere, and the new
881
+ // home equals the workspace dir — which flips workspaceSettingsActive.
882
+ realpathOr(os.homedir()) === fp.homeDir && sameFileSigs(settingsFileSigs(key), fp.settingsFiles) && sameFileSigs(envFileSigs(entry.settings, key), fp.envFiles);
883
+ }
884
+ __name(isEntryFresh, "isEntryFresh");
885
+ function loadSettingsCached(workspaceDir) {
886
+ preResolveHomeEnvOverrides();
887
+ const key = path2.resolve(workspaceDir);
888
+ const entry = cache.get(key);
889
+ if (entry) {
890
+ let isFresh = false;
891
+ try {
892
+ isFresh = isEntryFresh(key, entry);
893
+ } catch (error) {
894
+ debugLogger2.warn(
895
+ `fingerprint check failed for ${key}; reloading:`,
896
+ error
897
+ );
898
+ }
899
+ if (isFresh) {
900
+ cache.delete(key);
901
+ cache.set(key, entry);
902
+ debugLogger2.debug(`hit ${key}`);
903
+ return entry.settings;
904
+ }
905
+ cache.delete(key);
906
+ }
907
+ debugLogger2.debug(`miss ${key}`);
908
+ let preLoadSigs;
909
+ try {
910
+ preLoadSigs = settingsFileSigs(key);
911
+ } catch (error) {
912
+ debugLogger2.warn(`pre-load signing failed for ${key}; not caching:`, error);
913
+ }
914
+ const settings = loadSettings(key);
915
+ if (preLoadSigs) {
916
+ try {
917
+ cache.set(key, {
918
+ settings,
919
+ fingerprint: {
920
+ settingsFiles: preLoadSigs,
921
+ // .env discovery needs the merged settings (trust), so it can only
922
+ // be signed after the load — see difference (2) in the module doc.
923
+ envFiles: envFileSigs(settings, key),
924
+ ideTrust: ideContextStore.get()?.workspaceState?.isTrusted,
925
+ realCwd: realpathOr(key),
926
+ homeDir: realpathOr(os.homedir())
927
+ }
928
+ });
929
+ if (cache.size > MAX_CACHE_ENTRIES) {
930
+ const oldest = cache.keys().next().value;
931
+ if (oldest !== void 0) {
932
+ cache.delete(oldest);
933
+ debugLogger2.debug(`evicted LRU entry ${oldest}`);
934
+ }
935
+ }
936
+ } catch (error) {
937
+ cache.delete(key);
938
+ debugLogger2.warn(`caching failed for ${key}; serving uncached:`, error);
939
+ }
940
+ }
941
+ return settings;
942
+ }
943
+ __name(loadSettingsCached, "loadSettingsCached");
944
+
807
945
  // packages/cli/src/acp-integration/extension-skills.ts
808
946
  init_esbuild_shims();
809
947
  function extensionSkillRef(extensionName, skillName) {
@@ -833,16 +971,16 @@ __name(isInactiveExtensionSkill, "isInactiveExtensionSkill");
833
971
  init_esbuild_shims();
834
972
  import { Buffer as Buffer2 } from "node:buffer";
835
973
  import { randomUUID } from "node:crypto";
836
- import { realpathSync, statSync } from "node:fs";
837
- import * as os from "node:os";
838
- import * as path2 from "node:path";
974
+ import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
975
+ import * as os2 from "node:os";
976
+ import * as path3 from "node:path";
839
977
 
840
978
  // packages/cli/src/serve/live/capture-screen-context.ts
841
979
  init_esbuild_shims();
842
980
  import { constants } from "node:fs";
843
981
  import { open, unlink } from "node:fs/promises";
844
982
  import { tmpdir } from "node:os";
845
- import { dirname, join, resolve } from "node:path";
983
+ import { dirname, join, resolve as resolve2 } from "node:path";
846
984
  var MAX_SCREENSHOT_BYTES = 8 * 1024 * 1024;
847
985
  var PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
848
986
  var CAPTURE_SCREEN_CONTEXT_TOOL_NAME = "capture_screen_context";
@@ -854,9 +992,9 @@ function failure(message) {
854
992
  };
855
993
  }
856
994
  __name(failure, "failure");
857
- function resolvePrivatePngPath(path4, captureDirectory) {
858
- const resolvedPath = resolve(path4);
859
- if (dirname(resolvedPath) !== resolve(captureDirectory)) {
995
+ function resolvePrivatePngPath(path5, captureDirectory) {
996
+ const resolvedPath = resolve2(path5);
997
+ if (dirname(resolvedPath) !== resolve2(captureDirectory)) {
860
998
  throw new Error(
861
999
  "Host returned a screenshot outside its private directory."
862
1000
  );
@@ -864,8 +1002,8 @@ function resolvePrivatePngPath(path4, captureDirectory) {
864
1002
  return resolvedPath;
865
1003
  }
866
1004
  __name(resolvePrivatePngPath, "resolvePrivatePngPath");
867
- async function readPrivatePng(path4) {
868
- const handle = await open(path4, constants.O_RDONLY | constants.O_NOFOLLOW);
1005
+ async function readPrivatePng(path5) {
1006
+ const handle = await open(path5, constants.O_RDONLY | constants.O_NOFOLLOW);
869
1007
  try {
870
1008
  const stat2 = await handle.stat();
871
1009
  if (!stat2.isFile() || stat2.size <= 0 || stat2.size > MAX_SCREENSHOT_BYTES) {
@@ -1462,7 +1600,7 @@ function requestPermissionWithAbort(client, params, signal) {
1462
1600
  if (signal.aborted) {
1463
1601
  return Promise.reject(permissionAbortError(signal));
1464
1602
  }
1465
- return new Promise((resolve5, reject) => {
1603
+ return new Promise((resolve6, reject) => {
1466
1604
  let settled = false;
1467
1605
  const finish = /* @__PURE__ */ __name((callback) => {
1468
1606
  if (settled) return;
@@ -1480,7 +1618,7 @@ function requestPermissionWithAbort(client, params, signal) {
1480
1618
  return;
1481
1619
  }
1482
1620
  request.then(
1483
- (response) => finish(() => resolve5(response)),
1621
+ (response) => finish(() => resolve6(response)),
1484
1622
  (error) => finish(() => reject(error))
1485
1623
  );
1486
1624
  });
@@ -1620,7 +1758,7 @@ function toPermissionOptions(confirmation, forceHideAlwaysAllow = false) {
1620
1758
  __name(toPermissionOptions, "toPermissionOptions");
1621
1759
 
1622
1760
  // packages/cli/src/acp-integration/session/SubAgentTracker.ts
1623
- var debugLogger2 = createDebugLogger("ACP_SUBAGENT_TRACKER");
1761
+ var debugLogger3 = createDebugLogger("ACP_SUBAGENT_TRACKER");
1624
1762
  var SubAgentTracker = class {
1625
1763
  constructor(ctx, client, parentToolCallId, subagentType, onPermissionCancel, permissionRequester = (params, signal) => requestPermissionWithAbort(this.client, params, signal)) {
1626
1764
  this.ctx = ctx;
@@ -1681,7 +1819,7 @@ var SubAgentTracker = class {
1681
1819
  try {
1682
1820
  invocation = tool.build(event.args);
1683
1821
  } catch (e) {
1684
- debugLogger2.warn(`Failed to build subagent tool ${event.name}:`, e);
1822
+ debugLogger3.warn(`Failed to build subagent tool ${event.name}:`, e);
1685
1823
  }
1686
1824
  }
1687
1825
  this.toolStates.set(event.callId, {
@@ -1695,7 +1833,7 @@ var SubAgentTracker = class {
1695
1833
  args: event.args,
1696
1834
  subagentMeta: this.subagentMeta
1697
1835
  }).catch((error) => {
1698
- debugLogger2.debug(
1836
+ debugLogger3.debug(
1699
1837
  `Failed to emit subagent tool start for ${event.name}:`,
1700
1838
  error
1701
1839
  );
@@ -1719,7 +1857,7 @@ var SubAgentTracker = class {
1719
1857
  args: state?.args,
1720
1858
  subagentMeta: this.subagentMeta
1721
1859
  }).catch((error) => {
1722
- debugLogger2.debug(
1860
+ debugLogger3.debug(
1723
1861
  `Failed to emit subagent tool result for ${event.name}:`,
1724
1862
  error
1725
1863
  );
@@ -1780,7 +1918,7 @@ var SubAgentTracker = class {
1780
1918
  this.onPermissionCancel?.();
1781
1919
  }
1782
1920
  } catch (error) {
1783
- debugLogger2.error(
1921
+ debugLogger3.error(
1784
1922
  `Permission request failed for subagent tool ${event.name}:`,
1785
1923
  error
1786
1924
  );
@@ -1790,7 +1928,7 @@ var SubAgentTracker = class {
1790
1928
  try {
1791
1929
  await event.respond("cancel" /* Cancel */);
1792
1930
  } catch (respondError) {
1793
- debugLogger2.error(
1931
+ debugLogger3.error(
1794
1932
  `Failed to cancel subagent tool ${event.name} after permission request failure:`,
1795
1933
  respondError
1796
1934
  );
@@ -1806,7 +1944,7 @@ var SubAgentTracker = class {
1806
1944
  const event = args[0];
1807
1945
  if (abortSignal.aborted) return;
1808
1946
  void this.messageEmitter.emitUsageMetadata(event.usage, "", event.durationMs, this.subagentMeta).catch((error) => {
1809
- debugLogger2.debug("Failed to emit subagent usage metadata:", error);
1947
+ debugLogger3.debug("Failed to emit subagent usage metadata:", error);
1810
1948
  });
1811
1949
  };
1812
1950
  }
@@ -1825,7 +1963,7 @@ var SubAgentTracker = class {
1825
1963
  void 0,
1826
1964
  this.subagentMeta
1827
1965
  ).catch((error) => {
1828
- debugLogger2.debug("Failed to emit subagent stream text:", error);
1966
+ debugLogger3.debug("Failed to emit subagent stream text:", error);
1829
1967
  });
1830
1968
  };
1831
1969
  }
@@ -1887,8 +2025,8 @@ var TurnBuffer = class {
1887
2025
  // packages/cli/src/acp-integration/session/rewrite/LlmRewriter.ts
1888
2026
  init_esbuild_shims();
1889
2027
  import { readFileSync, existsSync } from "node:fs";
1890
- import { resolve as resolve2 } from "node:path";
1891
- var debugLogger3 = createDebugLogger("MESSAGE_REWRITER");
2028
+ import { resolve as resolve3 } from "node:path";
2029
+ var debugLogger4 = createDebugLogger("MESSAGE_REWRITER");
1892
2030
  var DEFAULT_REWRITE_PROMPT = `You are an assistant that rewrites raw coding-agent output into concise, user-friendly progress updates.
1893
2031
 
1894
2032
  The agent is a software engineering assistant that reads files, writes code, runs commands, and uses tools. Its raw output mixes internal reasoning with user-facing information. Your job: extract what the user cares about, drop what they don't.
@@ -1914,14 +2052,14 @@ var LlmRewriter = class {
1914
2052
  this.rewriteModel = rewriteConfig.model || void 0;
1915
2053
  this.contextTurns = rewriteConfig.contextTurns === "all" ? Infinity : rewriteConfig.contextTurns ?? 1;
1916
2054
  if (rewriteConfig.promptFile) {
1917
- const filePath = resolve2(rewriteConfig.promptFile);
2055
+ const filePath = resolve3(rewriteConfig.promptFile);
1918
2056
  if (existsSync(filePath)) {
1919
2057
  this.prompt = readFileSync(filePath, "utf-8").trim();
1920
- debugLogger3.info(
2058
+ debugLogger4.info(
1921
2059
  `Loaded rewrite prompt from file: ${filePath} (${this.prompt.length} chars)`
1922
2060
  );
1923
2061
  } else {
1924
- debugLogger3.warn(
2062
+ debugLogger4.warn(
1925
2063
  `Rewrite prompt file not found: ${filePath}, using default`
1926
2064
  );
1927
2065
  this.prompt = DEFAULT_REWRITE_PROMPT;
@@ -1958,7 +2096,7 @@ var LlmRewriter = class {
1958
2096
  const inputText = inputParts.join("\n\n");
1959
2097
  if (!inputText.trim()) return null;
1960
2098
  if (inputText.length < 10) return null;
1961
- debugLogger3.info(
2099
+ debugLogger4.info(
1962
2100
  `[REWRITE INPUT] system_prompt_len=${this.prompt.length} input_len=${inputText.length} context_turns=${this.outputHistory.length}
1963
2101
  --- INPUT TEXT ---
1964
2102
  ${inputText}
@@ -1987,10 +2125,10 @@ ${inputText}
1987
2125
  });
1988
2126
  const rewritten = result.text;
1989
2127
  if (!rewritten || rewritten.length < 5) {
1990
- debugLogger3.info(`[REWRITE OUTPUT] empty or too short, skipping`);
2128
+ debugLogger4.info(`[REWRITE OUTPUT] empty or too short, skipping`);
1991
2129
  return null;
1992
2130
  }
1993
- debugLogger3.info(
2131
+ debugLogger4.info(
1994
2132
  `[REWRITE OUTPUT] len=${rewritten.length}
1995
2133
  --- OUTPUT ---
1996
2134
  ${rewritten}
@@ -2004,7 +2142,7 @@ ${rewritten}
2004
2142
  }
2005
2143
  return rewritten;
2006
2144
  } catch (error) {
2007
- debugLogger3.warn(
2145
+ debugLogger4.warn(
2008
2146
  `LLM rewrite failed, skipping: ${error instanceof Error ? error.message : String(error)}`
2009
2147
  );
2010
2148
  return null;
@@ -2013,7 +2151,7 @@ ${rewritten}
2013
2151
  };
2014
2152
 
2015
2153
  // packages/cli/src/acp-integration/session/rewrite/MessageRewriteMiddleware.ts
2016
- var debugLogger4 = createDebugLogger("MESSAGE_REWRITE");
2154
+ var debugLogger5 = createDebugLogger("MESSAGE_REWRITE");
2017
2155
  var DEFAULT_REWRITE_TIMEOUT_MS = 3e4;
2018
2156
  var REWRITE_META_EXCLUDED_KEYS = /* @__PURE__ */ new Set([]);
2019
2157
  var MessageRewriteMiddleware = class {
@@ -2096,10 +2234,10 @@ var MessageRewriteMiddleware = class {
2096
2234
  try {
2097
2235
  const rewritten = await this.rewriter.rewrite(content, rewriteSignal);
2098
2236
  if (!rewritten) {
2099
- debugLogger4.info(`Turn ${turnIdx}: no rewrite output`);
2237
+ debugLogger5.info(`Turn ${turnIdx}: no rewrite output`);
2100
2238
  return;
2101
2239
  }
2102
- debugLogger4.info(
2240
+ debugLogger5.info(
2103
2241
  `Turn ${turnIdx}: rewritten ${rewritten.length} chars`
2104
2242
  );
2105
2243
  await this.sendUpdate({
@@ -2112,7 +2250,7 @@ var MessageRewriteMiddleware = class {
2112
2250
  }
2113
2251
  });
2114
2252
  } catch (error) {
2115
- debugLogger4.warn(
2253
+ debugLogger5.warn(
2116
2254
  `Turn ${turnIdx}: rewrite failed: ${error instanceof Error ? error.message : String(error)}`
2117
2255
  );
2118
2256
  }
@@ -2320,8 +2458,217 @@ var DaemonTodoStopGuard = class {
2320
2458
  }
2321
2459
  };
2322
2460
 
2461
+ // packages/cli/src/acp-integration/session/repeated-tool-failure-guard.ts
2462
+ init_esbuild_shims();
2463
+ var REPEATED_TOOL_FAILURE_THRESHOLD = 8;
2464
+ var REPEATED_TOOL_FAILURE_BATCH_THRESHOLD = 2;
2465
+ var REPEATED_TOOL_FAILURE_REMINDER = "System: the same tool execution has failed repeatedly for the same classified reason. Do not repeat the same approach. Inspect the returned result, change the approach or required preconditions, or explain the blocker.";
2466
+ var REPEATED_TOOL_FAILURE_STOP_MESSAGE = "Automatic continuation stopped because the same tool execution failure continued after a corrective reminder. New user input is required to continue.";
2467
+ var INELIGIBLE_RESET_REASON_PRECEDENCE = [
2468
+ "contract_violation",
2469
+ "cancelled",
2470
+ "unknown",
2471
+ "not_started",
2472
+ "post_execution_failure"
2473
+ ];
2474
+ function createRepeatedToolFailureGuardState() {
2475
+ return {
2476
+ phase: "idle",
2477
+ failureCount: 0,
2478
+ batchCount: 0,
2479
+ candidateOrdinal: 0,
2480
+ nextCandidateOrdinal: 1,
2481
+ enforcementDisabled: false
2482
+ };
2483
+ }
2484
+ __name(createRepeatedToolFailureGuardState, "createRepeatedToolFailureGuardState");
2485
+ function parseRepeatedToolFailureGuardMode(value) {
2486
+ const normalized = value?.trim().toLowerCase();
2487
+ switch (normalized) {
2488
+ case "off":
2489
+ case "shadow":
2490
+ case "warn":
2491
+ case "enforce":
2492
+ return normalized;
2493
+ default:
2494
+ return void 0;
2495
+ }
2496
+ }
2497
+ __name(parseRepeatedToolFailureGuardMode, "parseRepeatedToolFailureGuardMode");
2498
+ function resetState(state, enforcementDisabled = state.enforcementDisabled) {
2499
+ return {
2500
+ phase: "idle",
2501
+ failureCount: 0,
2502
+ batchCount: 0,
2503
+ candidateOrdinal: 0,
2504
+ nextCandidateOrdinal: state.nextCandidateOrdinal,
2505
+ enforcementDisabled
2506
+ };
2507
+ }
2508
+ __name(resetState, "resetState");
2509
+ function reset(state, reason, enforcementDisabled = state.enforcementDisabled) {
2510
+ const nextState = resetState(state, enforcementDisabled);
2511
+ if (state.phase === "idle" && state.enforcementDisabled === enforcementDisabled) {
2512
+ return { kind: "none", state: nextState };
2513
+ }
2514
+ return { kind: "reset", state: nextState, reason };
2515
+ }
2516
+ __name(reset, "reset");
2517
+ function keysEqual(left, right) {
2518
+ return left?.policyToolName === right.policyToolName && left.executionErrorType === right.executionErrorType;
2519
+ }
2520
+ __name(keysEqual, "keysEqual");
2521
+ function effectiveMode(mode, enforcementDisabled) {
2522
+ return mode === "enforce" && enforcementDisabled ? "warn" : mode;
2523
+ }
2524
+ __name(effectiveMode, "effectiveMode");
2525
+ function reduceRepeatedToolFailureGuard(state, input) {
2526
+ if (input.mode === "off" || state.phase === "latched") {
2527
+ return { kind: "none", state };
2528
+ }
2529
+ if (!input.inputReliable) {
2530
+ return reset(state, "unreliable_input", true);
2531
+ }
2532
+ if (input.hasExternalInput) {
2533
+ return reset(state, "external_input");
2534
+ }
2535
+ if (input.hasQueuedPrompt) {
2536
+ return reset(state, "queued_prompt");
2537
+ }
2538
+ if (!input.batch.complete) {
2539
+ return reset(state, "incomplete");
2540
+ }
2541
+ const observations = input.batch.observations.filter(
2542
+ (observation) => !observation.providerDuplicate
2543
+ );
2544
+ if (observations.length === 0) {
2545
+ return { kind: "none", state };
2546
+ }
2547
+ const eligible = [];
2548
+ const successfulPolicyToolNames = /* @__PURE__ */ new Set();
2549
+ const resetReasons = /* @__PURE__ */ new Set();
2550
+ let enforcementDisabled = state.enforcementDisabled;
2551
+ for (const observation of observations) {
2552
+ const { terminalStatus, executionStatus } = observation;
2553
+ if (terminalStatus === "cancelled") {
2554
+ resetReasons.add("cancelled");
2555
+ continue;
2556
+ }
2557
+ if (executionStatus === void 0 || executionStatus === "unknown") {
2558
+ resetReasons.add("unknown");
2559
+ enforcementDisabled = true;
2560
+ continue;
2561
+ }
2562
+ if (terminalStatus === "success") {
2563
+ if (executionStatus === "error" || executionStatus === "cancelled") {
2564
+ resetReasons.add("contract_violation");
2565
+ enforcementDisabled = true;
2566
+ } else if (executionStatus === "success" || executionStatus === "not_started") {
2567
+ if (observation.policyToolName) {
2568
+ successfulPolicyToolNames.add(observation.policyToolName);
2569
+ } else {
2570
+ resetReasons.add("unknown");
2571
+ enforcementDisabled = true;
2572
+ }
2573
+ } else {
2574
+ resetReasons.add("unknown");
2575
+ enforcementDisabled = true;
2576
+ }
2577
+ continue;
2578
+ }
2579
+ if (executionStatus === "cancelled") {
2580
+ resetReasons.add("cancelled");
2581
+ continue;
2582
+ }
2583
+ if (executionStatus === "not_started") {
2584
+ resetReasons.add("not_started");
2585
+ continue;
2586
+ }
2587
+ if (executionStatus === "success") {
2588
+ resetReasons.add("post_execution_failure");
2589
+ continue;
2590
+ }
2591
+ if (executionStatus !== "error") {
2592
+ resetReasons.add("unknown");
2593
+ enforcementDisabled = true;
2594
+ continue;
2595
+ }
2596
+ if (!observation.policyToolName || observation.executionErrorType === void 0 || observation.executionErrorType === "unknown" /* UNKNOWN */) {
2597
+ resetReasons.add("unknown");
2598
+ enforcementDisabled = true;
2599
+ continue;
2600
+ }
2601
+ eligible.push({
2602
+ policyToolName: observation.policyToolName,
2603
+ executionErrorType: observation.executionErrorType
2604
+ });
2605
+ }
2606
+ const resetReason = INELIGIBLE_RESET_REASON_PRECEDENCE.find(
2607
+ (reason) => resetReasons.has(reason)
2608
+ );
2609
+ if (resetReason !== void 0) {
2610
+ return reset(state, resetReason, enforcementDisabled);
2611
+ }
2612
+ const matchingFailures = eligible.filter(
2613
+ (failure2) => !successfulPolicyToolNames.has(failure2.policyToolName)
2614
+ );
2615
+ const key = matchingFailures[0];
2616
+ if (!key) {
2617
+ if (state.key && successfulPolicyToolNames.has(state.key.policyToolName)) {
2618
+ return reset(state, "success");
2619
+ }
2620
+ if (successfulPolicyToolNames.size > 0) {
2621
+ return { kind: "none", state };
2622
+ }
2623
+ return reset(state, "unknown", true);
2624
+ }
2625
+ if (matchingFailures.some((entry) => !keysEqual(entry, key))) {
2626
+ return reset(state, "mixed");
2627
+ }
2628
+ if (!keysEqual(state.key, key)) {
2629
+ const nextState2 = {
2630
+ phase: "tracking",
2631
+ key,
2632
+ failureCount: matchingFailures.length,
2633
+ batchCount: 1,
2634
+ candidateOrdinal: state.nextCandidateOrdinal,
2635
+ nextCandidateOrdinal: state.nextCandidateOrdinal + 1,
2636
+ enforcementDisabled: state.enforcementDisabled
2637
+ };
2638
+ return { kind: "tracked", state: nextState2 };
2639
+ }
2640
+ const failureCount = state.failureCount + matchingFailures.length;
2641
+ const batchCount = state.batchCount + 1;
2642
+ if (state.phase === "warned") {
2643
+ const nextState2 = {
2644
+ ...state,
2645
+ phase: "latched",
2646
+ failureCount,
2647
+ batchCount
2648
+ };
2649
+ return {
2650
+ kind: effectiveMode(input.mode, state.enforcementDisabled) === "enforce" ? "stop" : "would_stop",
2651
+ state: nextState2
2652
+ };
2653
+ }
2654
+ const nextState = {
2655
+ ...state,
2656
+ failureCount,
2657
+ batchCount
2658
+ };
2659
+ if (failureCount < REPEATED_TOOL_FAILURE_THRESHOLD || batchCount < REPEATED_TOOL_FAILURE_BATCH_THRESHOLD) {
2660
+ return { kind: "tracked", state: nextState };
2661
+ }
2662
+ nextState.phase = "warned";
2663
+ return {
2664
+ kind: effectiveMode(input.mode, state.enforcementDisabled) === "shadow" ? "would_warn" : "warn",
2665
+ state: nextState
2666
+ };
2667
+ }
2668
+ __name(reduceRepeatedToolFailureGuard, "reduceRepeatedToolFailureGuard");
2669
+
2323
2670
  // packages/cli/src/acp-integration/session/Session.ts
2324
- var debugLogger5 = createDebugLogger("SESSION");
2671
+ var debugLogger6 = createDebugLogger("SESSION");
2325
2672
  var permissionRequestTails = /* @__PURE__ */ new WeakMap();
2326
2673
  var USER_CANCEL_ABORT_REASON = "qwen:user-cancel";
2327
2674
  var SESSION_DISPOSE_ABORT_REASON = "qwen:session-dispose";
@@ -2354,7 +2701,7 @@ async function finalizeToolCallPreparations(tracker, includeResolved, streamName
2354
2701
  await tracker.discard(includeResolved);
2355
2702
  } catch (error) {
2356
2703
  const message = error instanceof Error ? error.message : String(error);
2357
- debugLogger5.warn(
2704
+ debugLogger6.warn(
2358
2705
  `Failed to discard tool preparations for ${streamName}; continuing stream: ${message}`
2359
2706
  );
2360
2707
  }
@@ -2377,24 +2724,81 @@ var LOOP_DETECTED_SKIP_MESSAGE = "Skipped because loop detection stopped the cur
2377
2724
  var LOOP_DETECTED_CONTEXT_MESSAGE = "System: this turn was terminated because the model exceeded tool-call safety limits. Try a different approach on the next turn.";
2378
2725
  var TOOL_EXECUTION_CANCELLED_MESSAGE = "Tool execution was cancelled.";
2379
2726
  var TOOL_POST_EXECUTION_CANCELLED_MESSAGE = "The tool had already completed; its output was discarded.";
2380
- function createDaemonToolLoopState() {
2727
+ function createDaemonToolLoopState(repeatedToolFailureMode) {
2381
2728
  return {
2382
2729
  totalToolCalls: 0,
2383
2730
  invalidToolParamErrors: /* @__PURE__ */ new Map(),
2384
2731
  toolCallKeyCounts: /* @__PURE__ */ new Map(),
2385
2732
  maxToolCallKeyRepeat: 0,
2386
- loopDetected: false
2733
+ loopDetected: false,
2734
+ repeatedToolFailureMode,
2735
+ repeatedToolFailureState: createRepeatedToolFailureGuardState()
2387
2736
  };
2388
2737
  }
2389
2738
  __name(createDaemonToolLoopState, "createDaemonToolLoopState");
2390
- function recordDaemonLoopDetected(config, promptId, loopType, message, loopState) {
2739
+ function repeatedToolFailureCountBucket(count) {
2740
+ if (count === 0) return "0";
2741
+ if (count <= 2) return "1-2";
2742
+ if (count <= 4) return "3-4";
2743
+ if (count <= 7) return "5-7";
2744
+ return "8+";
2745
+ }
2746
+ __name(repeatedToolFailureCountBucket, "repeatedToolFailureCountBucket");
2747
+ function repeatedToolFailureBatchBucket(count) {
2748
+ if (count === 0) return "0";
2749
+ if (count === 1) return "1";
2750
+ if (count === 2) return "2";
2751
+ return "3+";
2752
+ }
2753
+ __name(repeatedToolFailureBatchBucket, "repeatedToolFailureBatchBucket");
2754
+ function recordRepeatedToolFailureDecision(promptId, mode, previousState, decision, batch) {
2755
+ if (mode === "off" || decision.kind === "none") {
2756
+ return;
2757
+ }
2758
+ const countState = decision.kind === "reset" ? previousState : decision.state;
2759
+ const telemetryDecision = decision.kind === "warn" ? "warned" : decision.kind === "stop" ? "stopped" : decision.kind;
2760
+ const key = decision.kind === "reset" ? void 0 : decision.state.key;
2761
+ const matchingToolTypes = new Set(
2762
+ key ? batch.observations.filter(
2763
+ (observation) => !observation.providerDuplicate && observation.policyToolName === key.policyToolName && observation.executionErrorType === key.executionErrorType
2764
+ ).map((observation) => observation.toolType).filter((toolType2) => toolType2 !== void 0) : []
2765
+ );
2766
+ const toolType = matchingToolTypes.size === 1 ? [...matchingToolTypes][0] : void 0;
2767
+ logRepeatedToolFailureGuard(
2768
+ new RepeatedToolFailureGuardEvent({
2769
+ prompt_id: promptId,
2770
+ route: "acp_foreground",
2771
+ mode,
2772
+ phase_before: previousState.phase,
2773
+ phase_after: decision.state.phase,
2774
+ decision: telemetryDecision,
2775
+ failure_count_bucket: repeatedToolFailureCountBucket(
2776
+ countState.failureCount
2777
+ ),
2778
+ batch_count_bucket: repeatedToolFailureBatchBucket(countState.batchCount),
2779
+ candidate_ordinal: countState.candidateOrdinal,
2780
+ ...decision.kind === "reset" ? { reset_reason: decision.reason } : {
2781
+ terminal_status: "error",
2782
+ execution_status: "error",
2783
+ execution_error_type: key?.executionErrorType,
2784
+ tool_type: toolType
2785
+ }
2786
+ })
2787
+ );
2788
+ }
2789
+ __name(recordRepeatedToolFailureDecision, "recordRepeatedToolFailureDecision");
2790
+ function recordDaemonLoopDetected(config, promptId, loopType, message, loopState, options = {}) {
2391
2791
  if (!loopState.loopDetected) {
2392
2792
  loopState.loopDetected = true;
2393
- debugLogger5.warn(message);
2793
+ debugLogger6.warn(message);
2394
2794
  try {
2395
- logLoopDetected(config, new LoopDetectedEvent(loopType, promptId));
2795
+ logLoopDetected(
2796
+ config,
2797
+ new LoopDetectedEvent(loopType, promptId),
2798
+ options
2799
+ );
2396
2800
  } catch (error) {
2397
- debugLogger5.debug(
2801
+ debugLogger6.debug(
2398
2802
  "[Session] Failed to record loop detection telemetry",
2399
2803
  error
2400
2804
  );
@@ -2490,7 +2894,7 @@ function isContentBlock(value) {
2490
2894
  case "resource":
2491
2895
  return isEmbeddedResourceResource(value["resource"]);
2492
2896
  default:
2493
- debugLogger5.warn(`Unknown ContentBlock type: ${value["type"]}`);
2897
+ debugLogger6.warn(`Unknown ContentBlock type: ${value["type"]}`);
2494
2898
  return false;
2495
2899
  }
2496
2900
  }
@@ -2548,7 +2952,7 @@ function hasInlineMediaContentBlock(content) {
2548
2952
  __name(hasInlineMediaContentBlock, "hasInlineMediaContentBlock");
2549
2953
  function capMidTurnDrainItems(items, fieldName) {
2550
2954
  if (items.length <= MAX_MID_TURN_DRAIN_ITEMS) return items;
2551
- debugLogger5.warn(
2955
+ debugLogger6.warn(
2552
2956
  `Mid-turn drain response had ${items.length} ${fieldName}; processing first ${MAX_MID_TURN_DRAIN_ITEMS}`
2553
2957
  );
2554
2958
  return items.slice(0, MAX_MID_TURN_DRAIN_ITEMS);
@@ -2563,7 +2967,7 @@ function getMidTurnItemDisplayTextForLog(displayText) {
2563
2967
  __name(getMidTurnItemDisplayTextForLog, "getMidTurnItemDisplayTextForLog");
2564
2968
  function getValidMidTurnContentBlocks(content, displayText) {
2565
2969
  if (!Array.isArray(content)) {
2566
- debugLogger5.warn(
2970
+ debugLogger6.warn(
2567
2971
  `Dropped invalid mid-turn item: ${getMidTurnItemDisplayTextForLog(
2568
2972
  displayText
2569
2973
  )}`
@@ -2573,7 +2977,7 @@ function getValidMidTurnContentBlocks(content, displayText) {
2573
2977
  const validBlocks = content.filter(isContentBlock);
2574
2978
  const invalidBlockCount = content.length - validBlocks.length;
2575
2979
  if (invalidBlockCount > 0) {
2576
- debugLogger5.warn(
2980
+ debugLogger6.warn(
2577
2981
  `Dropped ${invalidBlockCount} invalid mid-turn content block(s): ${getMidTurnItemDisplayTextForLog(
2578
2982
  displayText
2579
2983
  )}`
@@ -2619,7 +3023,7 @@ function parseMidTurnDrainResponse(response) {
2619
3023
  );
2620
3024
  }
2621
3025
  if (!Array.isArray(response["messages"])) {
2622
- debugLogger5.warn(
3026
+ debugLogger6.warn(
2623
3027
  `Mid-turn drain response had no recognized 'items' or 'messages' field; keys: ${Object.keys(
2624
3028
  response
2625
3029
  ).join(", ")}`
@@ -2704,7 +3108,7 @@ function parsePromptChannelDelivery(params) {
2704
3108
  __name(parsePromptChannelDelivery, "parsePromptChannelDelivery");
2705
3109
  var MAX_NOTIFICATION_QUEUE = 20;
2706
3110
  var MAX_DEFERRED_UNRELATED_CRON_QUEUE = 20;
2707
- function resolveExistingFile(resolved, resolveRealPath2 = realpathSync, statFile = statSync) {
3111
+ function resolveExistingFile(resolved, resolveRealPath2 = realpathSync2, statFile = statSync2) {
2708
3112
  try {
2709
3113
  const canonicalPath = resolveRealPath2(resolved);
2710
3114
  const stats = statFile(canonicalPath);
@@ -2716,11 +3120,11 @@ function resolveExistingFile(resolved, resolveRealPath2 = realpathSync, statFile
2716
3120
  __name(resolveExistingFile, "resolveExistingFile");
2717
3121
  function resolveHomeLoopResolverRoots({
2718
3122
  homeQwenDir = Storage.getGlobalQwenDir(),
2719
- homeDir = os.homedir(),
3123
+ homeDir = os2.homedir(),
2720
3124
  qwenHome = process.env["QWEN_HOME"]
2721
3125
  } = {}) {
2722
3126
  return {
2723
- homeConfineRoot: (qwenHome ? homeQwenDir : homeDir) || path2.dirname(homeQwenDir),
3127
+ homeConfineRoot: (qwenHome ? homeQwenDir : homeDir) || path3.dirname(homeQwenDir),
2724
3128
  homeQwenDir
2725
3129
  };
2726
3130
  }
@@ -2759,7 +3163,7 @@ async function fireSessionPermissionDeniedForAutoMode(config, decision, outcome,
2759
3163
  callId
2760
3164
  );
2761
3165
  } catch (hookError) {
2762
- debugLogger5.warn(
3166
+ debugLogger6.warn(
2763
3167
  `PermissionDenied hook failed for tool ${callId}: ${hookError instanceof Error ? hookError.message : String(hookError)}`
2764
3168
  );
2765
3169
  }
@@ -2889,7 +3293,7 @@ async function buildAvailableCommandsSnapshot(config, abortSignal = AbortSignal.
2889
3293
  }
2890
3294
  }
2891
3295
  } catch (error) {
2892
- debugLogger5.error("Error loading available skills:", error);
3296
+ debugLogger6.error("Error loading available skills:", error);
2893
3297
  }
2894
3298
  for (const command of visibleSlashCommands) {
2895
3299
  if (command.kind !== "skill" /* SKILL */ || !command.skillDetail) {
@@ -2924,6 +3328,14 @@ var Session = class {
2924
3328
  this.runtimeBaseDir = config.storage.getRuntimeBaseDir();
2925
3329
  const todoStopGuardEnabled = this.settings.merged.experimental?.todoStopGuard === true && !this.config.getBareMode() && !this.config.isSafeMode();
2926
3330
  this.todoStopGuard = new DaemonTodoStopGuard(todoStopGuardEnabled);
3331
+ const configuredGuardMode = process.env[ENV_ACP_REPEATED_TOOL_FAILURE_GUARD];
3332
+ const parsedGuardMode = parseRepeatedToolFailureGuardMode(configuredGuardMode);
3333
+ this.repeatedToolFailureGuardMode = parsedGuardMode ?? "shadow";
3334
+ if (configuredGuardMode?.trim() && parsedGuardMode === void 0) {
3335
+ debugLogger6.warn(
3336
+ `${ENV_ACP_REPEATED_TOOL_FAILURE_GUARD} has an invalid value; defaulting to shadow. Expected off, shadow, warn, or enforce.`
3337
+ );
3338
+ }
2927
3339
  this.todoStopGuardBackgroundBaseline = this.#captureTodoStopGuardBackgroundBaseline();
2928
3340
  this.toolCallEmitter = new ToolCallEmitter(this);
2929
3341
  this.planEmitter = new PlanEmitter(this);
@@ -3000,6 +3412,7 @@ var Session = class {
3000
3412
  // `#drainMidTurnUserMessages`.
3001
3413
  midTurnRecoveredMessages = [];
3002
3414
  todoStopGuard;
3415
+ repeatedToolFailureGuardMode;
3003
3416
  todoStopGuardBackgroundBaseline;
3004
3417
  relatedAgentIds = /* @__PURE__ */ new Set();
3005
3418
  provisionalRelatedAgentCounts = /* @__PURE__ */ new Map();
@@ -3130,7 +3543,7 @@ var Session = class {
3130
3543
  resolved && outcome === "proceed_once" /* ProceedOnce */
3131
3544
  );
3132
3545
  } catch (error) {
3133
- debugLogger5.error("Workflow permission request failed:", error);
3546
+ debugLogger6.error("Workflow permission request failed:", error);
3134
3547
  await registry.resolvePendingApproval(
3135
3548
  runId,
3136
3549
  approval.approvalId,
@@ -3157,7 +3570,7 @@ var Session = class {
3157
3570
  }
3158
3571
  });
3159
3572
  } catch (error) {
3160
- debugLogger5.warn(
3573
+ debugLogger6.warn(
3161
3574
  "Failed to finalize workflow approval tool call:",
3162
3575
  error
3163
3576
  );
@@ -3326,7 +3739,7 @@ var Session = class {
3326
3739
  }
3327
3740
  return "unavailable";
3328
3741
  } catch (error) {
3329
- debugLogger5.warn(
3742
+ debugLogger6.warn(
3330
3743
  `Todo Stop Guard continuation claim unavailable [session ${this.sessionId}]: ${this.#formatError(error)}`
3331
3744
  );
3332
3745
  return "unavailable";
@@ -3616,7 +4029,7 @@ var Session = class {
3616
4029
  }
3617
4030
  });
3618
4031
  } catch (error) {
3619
- debugLogger5.warn(
4032
+ debugLogger6.warn(
3620
4033
  `Failed to emit persisted realtime transcript: ${this.#formatError(error)}`
3621
4034
  );
3622
4035
  }
@@ -3641,7 +4054,7 @@ var Session = class {
3641
4054
  */
3642
4055
  startCronScheduler() {
3643
4056
  this.#startCronSchedulerInRuntime().catch((error) => {
3644
- debugLogger5.warn(
4057
+ debugLogger6.warn(
3645
4058
  `Cron scheduler startup failed [session ${this.sessionId}]: ${error}`
3646
4059
  );
3647
4060
  });
@@ -3728,8 +4141,8 @@ var Session = class {
3728
4141
  }
3729
4142
  this.closing = true;
3730
4143
  let resolveGate;
3731
- const completion = new Promise((resolve5) => {
3732
- resolveGate = resolve5;
4144
+ const completion = new Promise((resolve6) => {
4145
+ resolveGate = resolve6;
3733
4146
  });
3734
4147
  this.closeGateCompletion = completion;
3735
4148
  this.resolveCloseGate = resolveGate;
@@ -3769,7 +4182,7 @@ var Session = class {
3769
4182
  if (pending.length > 0) {
3770
4183
  await Promise.allSettled(pending);
3771
4184
  }
3772
- await new Promise((resolve5) => setImmediate(resolve5));
4185
+ await new Promise((resolve6) => setImmediate(resolve6));
3773
4186
  }
3774
4187
  }
3775
4188
  #deferAutomaticQueueDrainUntilTurnsSettle() {
@@ -3843,7 +4256,7 @@ var Session = class {
3843
4256
  installRewriter() {
3844
4257
  const rewriteConfig = loadRewriteConfig(this.settings);
3845
4258
  if (rewriteConfig?.enabled) {
3846
- debugLogger5.info("Message rewrite middleware enabled");
4259
+ debugLogger6.info("Message rewrite middleware enabled");
3847
4260
  this.messageRewriter = new MessageRewriteMiddleware(
3848
4261
  this.config,
3849
4262
  rewriteConfig,
@@ -3862,7 +4275,7 @@ var Session = class {
3862
4275
  installGoalTerminalObserver() {
3863
4276
  setGoalTerminalObserver(this.sessionId, (event) => {
3864
4277
  void this.messageEmitter.emitGoalTerminal(event).catch((error) => {
3865
- debugLogger5.warn(
4278
+ debugLogger6.warn(
3866
4279
  `Failed to emit goal terminal update: ${this.#formatError(error)}`
3867
4280
  );
3868
4281
  });
@@ -3879,7 +4292,7 @@ var Session = class {
3879
4292
  */
3880
4293
  emitGoalStatus(status) {
3881
4294
  void this.messageEmitter.emitGoalStatus(status).catch((error) => {
3882
- debugLogger5.warn(
4295
+ debugLogger6.warn(
3883
4296
  `Failed to emit goal status update: ${this.#formatError(error)}`
3884
4297
  );
3885
4298
  });
@@ -4152,8 +4565,8 @@ var Session = class {
4152
4565
  const channelDelivery = parsePromptChannelDelivery(params);
4153
4566
  const channelDeliveryCapture = channelDelivery ? { finalText: "" } : void 0;
4154
4567
  let resolveCompletion;
4155
- this.pendingPromptCompletion = new Promise((resolve5) => {
4156
- resolveCompletion = resolve5;
4568
+ this.pendingPromptCompletion = new Promise((resolve6) => {
4569
+ resolveCompletion = resolve6;
4157
4570
  });
4158
4571
  try {
4159
4572
  const result = await this.#executePrompt(
@@ -4275,7 +4688,7 @@ var Session = class {
4275
4688
  const fullHistory = chat.getHistory(true);
4276
4689
  const lastEntry = fullHistory[fullHistory.length - 1];
4277
4690
  if (!lastEntry || lastEntry.role !== "model") {
4278
- debugLogger5.debug(
4691
+ debugLogger6.debug(
4279
4692
  "Skipping followup suggestion: last history entry is not model"
4280
4693
  );
4281
4694
  return;
@@ -4311,9 +4724,9 @@ var Session = class {
4311
4724
  }
4312
4725
  } catch (error) {
4313
4726
  if (ac.signal.aborted) {
4314
- debugLogger5.debug("Follow-up suggestion generation aborted");
4727
+ debugLogger6.debug("Follow-up suggestion generation aborted");
4315
4728
  } else {
4316
- debugLogger5.warn("Follow-up suggestion generation failed", error);
4729
+ debugLogger6.warn("Follow-up suggestion generation failed", error);
4317
4730
  }
4318
4731
  } finally {
4319
4732
  if (this.followupAbort === ac) {
@@ -4389,7 +4802,7 @@ var Session = class {
4389
4802
  apiHistory: this.#getCurrentChat().getHistory()
4390
4803
  });
4391
4804
  if (!recoveryPlan.continuation) {
4392
- debugLogger5.warn(
4805
+ debugLogger6.warn(
4393
4806
  `[Session] continue ${promptId}: no interrupted turn on re-detection, nothing to continue`
4394
4807
  );
4395
4808
  logConversationFinishedEvent(
@@ -4507,10 +4920,10 @@ var Session = class {
4507
4920
  this.config.getChatRecordingService()?.recordFileHistorySnapshot(latestSnapshot);
4508
4921
  }
4509
4922
  } catch (e) {
4510
- debugLogger5.error(`FileHistory: recordSnapshot failed: ${e}`);
4923
+ debugLogger6.error(`FileHistory: recordSnapshot failed: ${e}`);
4511
4924
  }
4512
4925
  } catch (e) {
4513
- debugLogger5.error(`FileHistory: makeSnapshot failed: ${e}`);
4926
+ debugLogger6.error(`FileHistory: makeSnapshot failed: ${e}`);
4514
4927
  }
4515
4928
  const systemReminders = await this.#buildInitialSystemReminders();
4516
4929
  if (systemReminders.length > 0) {
@@ -4554,7 +4967,9 @@ ${this.pendingRecoveredAgentsNotice}
4554
4967
  }
4555
4968
  let nextMessage = { role: "user", parts };
4556
4969
  let turnCount = 0;
4557
- const toolLoopState = createDaemonToolLoopState();
4970
+ const toolLoopState = createDaemonToolLoopState(
4971
+ promptMetadata?.[CHANNEL_PROMPT_META_KEY] === true ? "off" : this.repeatedToolFailureGuardMode
4972
+ );
4558
4973
  try {
4559
4974
  while (nextMessage !== null) {
4560
4975
  turnCount++;
@@ -4673,7 +5088,7 @@ ${this.pendingRecoveredAgentsNotice}
4673
5088
  const hooksEnabledForStopFailure = !this.config.getDisableAllHooks?.();
4674
5089
  if (hooksEnabledForStopFailure && hookSystem && this.config.hasHooksForEvent?.("StopFailure")) {
4675
5090
  hookSystem.fireStopFailureEvent(errorType, errorMessage).catch((err) => {
4676
- debugLogger5.warn(`StopFailure hook failed: ${err}`);
5091
+ debugLogger6.warn(`StopFailure hook failed: ${err}`);
4677
5092
  });
4678
5093
  }
4679
5094
  if (errorStatus === 429) {
@@ -4730,9 +5145,17 @@ ${this.pendingRecoveredAgentsNotice}
4730
5145
  toolRun,
4731
5146
  pendingSend.signal,
4732
5147
  promptId,
5148
+ toolLoopState,
4733
5149
  onFullTurnModel
4734
5150
  );
4735
5151
  nextMessage = nextAfterTools.message;
5152
+ if (nextAfterTools.stoppedByRepeatedToolFailure) {
5153
+ return {
5154
+ stopReason: getAbortAwareEndTurnStopReason(
5155
+ pendingSend.signal
5156
+ )
5157
+ };
5158
+ }
4736
5159
  if (toolRun.loopDetected) {
4737
5160
  this.todoStopGuard.suspend();
4738
5161
  await this.#preserveStoppedToolRun(
@@ -4810,7 +5233,7 @@ ${this.pendingRecoveredAgentsNotice}
4810
5233
  }
4811
5234
  if (this.todoStopGuard.needsStopInspection) {
4812
5235
  const drained = await this.#drainMidTurnInput(pendingSend.signal, {
4813
- watchQueuedPromptForTodoStopGuard: true,
5236
+ watchQueuedPrompt: true,
4814
5237
  onFullTurnModel
4815
5238
  });
4816
5239
  if (drained.parts.length > 0) {
@@ -4894,7 +5317,7 @@ ${this.pendingRecoveredAgentsNotice}
4894
5317
  }
4895
5318
  if (this.todoStopGuard.needsStopInspection) {
4896
5319
  const drained = await this.#drainMidTurnInput(pendingSend.signal, {
4897
- watchQueuedPromptForTodoStopGuard: true,
5320
+ watchQueuedPrompt: true,
4898
5321
  onFullTurnModel
4899
5322
  });
4900
5323
  if (drained.parts.length > 0) {
@@ -4981,7 +5404,7 @@ ${this.pendingRecoveredAgentsNotice}
4981
5404
  );
4982
5405
  this.todoStopGuard.suspend();
4983
5406
  await this.messageEmitter.emitAgentMessage(warning);
4984
- debugLogger5.warn(warning);
5407
+ debugLogger6.warn(warning);
4985
5408
  return { stopReason: "end_turn" };
4986
5409
  }
4987
5410
  if (!externalReason && !guardContinuation) {
@@ -5035,7 +5458,7 @@ ${this.pendingRecoveredAgentsNotice}
5035
5458
  async #runStopContinuation(pendingSend, streamPromptId, toolPromptId, parts, skipCompression, options = {}) {
5036
5459
  let nextMessage = { role: "user", parts };
5037
5460
  let nextGuardContinuation = options.guardContinuation;
5038
- const toolLoopState = createDaemonToolLoopState();
5461
+ const toolLoopState = createDaemonToolLoopState("off");
5039
5462
  let initialSend = true;
5040
5463
  let automaticContinuationValidated = false;
5041
5464
  let supersededAutomaticContinuation = false;
@@ -5101,7 +5524,7 @@ ${this.pendingRecoveredAgentsNotice}
5101
5524
  const drained = await this.#drainMidTurnInput(
5102
5525
  pendingSend.signal,
5103
5526
  {
5104
- watchQueuedPromptForTodoStopGuard: true,
5527
+ watchQueuedPrompt: true,
5105
5528
  onFullTurnModel: options.onFullTurnModel
5106
5529
  }
5107
5530
  );
@@ -5410,7 +5833,7 @@ ${this.pendingRecoveredAgentsNotice}
5410
5833
  const hookSystem = this.config.getHookSystem?.();
5411
5834
  if (!this.config.getDisableAllHooks?.() && hookSystem && this.config.hasHooksForEvent?.("StopFailure")) {
5412
5835
  hookSystem.fireStopFailureEvent(errorType, errorMessage).catch((err) => {
5413
- debugLogger5.warn(`StopFailure hook failed: ${err}`);
5836
+ debugLogger6.warn(`StopFailure hook failed: ${err}`);
5414
5837
  });
5415
5838
  }
5416
5839
  if (errorStatus === 429) {
@@ -5466,6 +5889,7 @@ ${this.pendingRecoveredAgentsNotice}
5466
5889
  toolRun,
5467
5890
  pendingSend.signal,
5468
5891
  toolPromptId,
5892
+ toolLoopState,
5469
5893
  options.onFullTurnModel
5470
5894
  );
5471
5895
  nextMessage = nextAfterTools.message;
@@ -5542,7 +5966,7 @@ ${this.pendingRecoveredAgentsNotice}
5542
5966
  }
5543
5967
  });
5544
5968
  } catch (error) {
5545
- debugLogger5.warn(
5969
+ debugLogger6.warn(
5546
5970
  `Failed to emit Todo Stop Guard status: ${this.#formatError(error)}`
5547
5971
  );
5548
5972
  }
@@ -5572,7 +5996,7 @@ ${this.pendingRecoveredAgentsNotice}
5572
5996
  const timer = setTimeout(() => {
5573
5997
  void this.client.extMethod(SERVE_CONTROL_EXT_METHODS.channelDelivery, params).catch((error) => {
5574
5998
  try {
5575
- debugLogger5.warn(
5999
+ debugLogger6.warn(
5576
6000
  `Channel delivery submission failed: ${error instanceof Error ? error.message : String(error)}`
5577
6001
  );
5578
6002
  } catch {
@@ -5610,7 +6034,7 @@ ${this.pendingRecoveredAgentsNotice}
5610
6034
  return new MessageDisplayDispatcher(
5611
6035
  messageBus,
5612
6036
  signal,
5613
- (message) => debugLogger5.warn(message)
6037
+ (message) => debugLogger6.warn(message)
5614
6038
  );
5615
6039
  }
5616
6040
  /**
@@ -5631,7 +6055,7 @@ ${this.pendingRecoveredAgentsNotice}
5631
6055
  message = decision.message;
5632
6056
  }
5633
6057
  if (abortSignal.aborted) {
5634
- debugLogger5.debug(
6058
+ debugLogger6.debug(
5635
6059
  `Send aborted after pre-compression preparation for prompt ${promptId}`
5636
6060
  );
5637
6061
  return { responseStream: null, stopReason: "cancelled" };
@@ -5660,20 +6084,20 @@ ${this.pendingRecoveredAgentsNotice}
5660
6084
  }
5661
6085
  } catch (compressionError) {
5662
6086
  if (abortSignal.aborted) {
5663
- debugLogger5.debug(`Auto-compression aborted for prompt ${promptId}`);
6087
+ debugLogger6.debug(`Auto-compression aborted for prompt ${promptId}`);
5664
6088
  return { responseStream: null, stopReason: "cancelled" };
5665
6089
  }
5666
6090
  if (this.#isAbortError(compressionError)) {
5667
6091
  throw compressionError;
5668
6092
  }
5669
- debugLogger5.warn(
6093
+ debugLogger6.warn(
5670
6094
  `Auto-compression failed for prompt ${promptId}; proceeding without compression: ` + this.#formatError(compressionError)
5671
6095
  );
5672
6096
  compressionFailed = true;
5673
6097
  }
5674
6098
  }
5675
6099
  if (abortSignal.aborted) {
5676
- debugLogger5.debug(`Auto-compression aborted for prompt ${promptId}`);
6100
+ debugLogger6.debug(`Auto-compression aborted for prompt ${promptId}`);
5677
6101
  return { responseStream: null, stopReason: "cancelled" };
5678
6102
  }
5679
6103
  if (!compressionInfo) {
@@ -5683,7 +6107,7 @@ ${this.pendingRecoveredAgentsNotice}
5683
6107
  if (sessionTokenLimit > 0) {
5684
6108
  const lastPromptTokenCount = this.#getPostCompressionTokenCount(compressionInfo);
5685
6109
  if (lastPromptTokenCount > sessionTokenLimit) {
5686
- debugLogger5.warn(
6110
+ debugLogger6.warn(
5687
6111
  `Session token limit exceeded for prompt ${promptId}: ${lastPromptTokenCount} > ${sessionTokenLimit}. Send dropped.`
5688
6112
  );
5689
6113
  await this.#emitAgentDiagnosticMessageSafely(
@@ -5700,7 +6124,7 @@ ${this.pendingRecoveredAgentsNotice}
5700
6124
  );
5701
6125
  }
5702
6126
  if (abortSignal.aborted) {
5703
- debugLogger5.debug(
6127
+ debugLogger6.debug(
5704
6128
  `Send aborted after compression diagnostic for prompt ${promptId}`
5705
6129
  );
5706
6130
  return { responseStream: null, stopReason: "cancelled" };
@@ -5713,7 +6137,7 @@ ${this.pendingRecoveredAgentsNotice}
5713
6137
  message = decision.message;
5714
6138
  }
5715
6139
  if (abortSignal.aborted) {
5716
- debugLogger5.debug(
6140
+ debugLogger6.debug(
5717
6141
  `Send aborted after pre-send validation for prompt ${promptId}`
5718
6142
  );
5719
6143
  return { responseStream: null, stopReason: "cancelled" };
@@ -5741,7 +6165,7 @@ ${this.pendingRecoveredAgentsNotice}
5741
6165
  ) ?? [];
5742
6166
  const droppedParts = (message.parts?.length ?? 0) - functionResponseParts.length;
5743
6167
  if (droppedParts > 0) {
5744
- debugLogger5.debug(
6168
+ debugLogger6.debug(
5745
6169
  `Dropping ${droppedParts} non-functionResponse part(s) from unsent ACP message after send was skipped.`
5746
6170
  );
5747
6171
  }
@@ -5771,19 +6195,20 @@ ${this.pendingRecoveredAgentsNotice}
5771
6195
  );
5772
6196
  await this.messageRewriter?.waitForPendingRewrites();
5773
6197
  }
5774
- async #buildNextMessageAfterToolRun(toolRun, abortSignal, promptId, onFullTurnModel) {
6198
+ async #buildNextMessageAfterToolRun(toolRun, abortSignal, promptId, toolLoopState, onFullTurnModel) {
5775
6199
  if (toolRun.loopDetected) {
5776
- debugLogger5.debug("Stopping ACP turn after daemon loop detection.");
6200
+ debugLogger6.debug("Stopping ACP turn after daemon loop detection.");
5777
6201
  return { message: null, hadMidTurnUserInput: false };
5778
6202
  }
5779
6203
  if (toolRun.repeatedDuplicateProviderToolCall) {
5780
6204
  this.todoStopGuard.suspend();
5781
- debugLogger5.debug(
6205
+ debugLogger6.debug(
5782
6206
  "Stopping ACP turn after dropping repeated duplicate provider tool-call response."
5783
6207
  );
5784
6208
  return { message: null, hadMidTurnUserInput: false };
5785
6209
  }
5786
6210
  const drained = await this.#drainMidTurnInput(abortSignal, {
6211
+ watchQueuedPrompt: toolLoopState.repeatedToolFailureMode !== "off",
5787
6212
  onFullTurnModel
5788
6213
  });
5789
6214
  const hadMidTurnUserInput = drained.parts.length > 0;
@@ -5791,11 +6216,90 @@ ${this.pendingRecoveredAgentsNotice}
5791
6216
  this.todoStopGuard.acceptMidTurnUserInput();
5792
6217
  }
5793
6218
  const activeTodoReminder = this.config.takeActiveTodoReminder(promptId);
6219
+ if (abortSignal.aborted) {
6220
+ return {
6221
+ message: {
6222
+ role: "user",
6223
+ parts: [
6224
+ ...toolRun.parts,
6225
+ ...activeTodoReminder ? [{ text: activeTodoReminder }] : [],
6226
+ ...drained.parts
6227
+ ]
6228
+ },
6229
+ hadMidTurnUserInput
6230
+ };
6231
+ }
6232
+ const previousRepeatedToolFailureState = toolLoopState.repeatedToolFailureState;
6233
+ const repeatedToolFailureBatch = toolRun.repeatedToolFailureBatch ?? {
6234
+ complete: false,
6235
+ observations: []
6236
+ };
6237
+ const repeatedToolFailureDecision = reduceRepeatedToolFailureGuard(
6238
+ previousRepeatedToolFailureState,
6239
+ {
6240
+ mode: toolLoopState.repeatedToolFailureMode,
6241
+ batch: repeatedToolFailureBatch,
6242
+ hasExternalInput: hadMidTurnUserInput,
6243
+ hasQueuedPrompt: drained.hasQueuedPrompt,
6244
+ inputReliable: drained.reliable
6245
+ }
6246
+ );
6247
+ recordRepeatedToolFailureDecision(
6248
+ promptId,
6249
+ toolLoopState.repeatedToolFailureMode,
6250
+ previousRepeatedToolFailureState,
6251
+ repeatedToolFailureDecision,
6252
+ repeatedToolFailureBatch
6253
+ );
6254
+ toolLoopState.repeatedToolFailureState = repeatedToolFailureDecision.state;
6255
+ if (repeatedToolFailureDecision.kind !== "none") {
6256
+ const { state } = repeatedToolFailureDecision;
6257
+ debugLogger6.debug(
6258
+ `[repeated-tool-failure-guard] mode=${toolLoopState.repeatedToolFailureMode} decision=${repeatedToolFailureDecision.kind} phase=${state.phase} candidate=${state.candidateOrdinal} failures=${state.failureCount} batches=${state.batchCount}`
6259
+ );
6260
+ }
5794
6261
  const parts = [
5795
6262
  ...toolRun.parts,
5796
6263
  ...activeTodoReminder ? [{ text: activeTodoReminder }] : [],
6264
+ ...repeatedToolFailureDecision.kind === "warn" ? [{ text: REPEATED_TOOL_FAILURE_REMINDER }] : [],
5797
6265
  ...drained.parts
5798
6266
  ];
6267
+ if (repeatedToolFailureDecision.kind === "stop") {
6268
+ this.todoStopGuard.suspend();
6269
+ this.#preserveUnsentMessageHistory(
6270
+ {
6271
+ role: "user",
6272
+ parts: [
6273
+ ...parts,
6274
+ { text: `System: ${REPEATED_TOOL_FAILURE_STOP_MESSAGE}` }
6275
+ ]
6276
+ },
6277
+ true
6278
+ );
6279
+ await this.messageRewriter?.waitForPendingRewrites();
6280
+ recordDaemonLoopDetected(
6281
+ this.config,
6282
+ promptId,
6283
+ "repeated_tool_execution_failure" /* REPEATED_TOOL_EXECUTION_FAILURE */,
6284
+ REPEATED_TOOL_FAILURE_STOP_MESSAGE,
6285
+ toolLoopState,
6286
+ { recordToQwenLogger: false }
6287
+ );
6288
+ try {
6289
+ await this.messageEmitter.emitAgentMessage(
6290
+ REPEATED_TOOL_FAILURE_STOP_MESSAGE
6291
+ );
6292
+ } catch (error) {
6293
+ debugLogger6.warn(
6294
+ `Failed to emit repeated tool failure stop message: ${this.#formatError(error)}`
6295
+ );
6296
+ }
6297
+ return {
6298
+ message: null,
6299
+ hadMidTurnUserInput,
6300
+ stoppedByRepeatedToolFailure: true
6301
+ };
6302
+ }
5799
6303
  return {
5800
6304
  message: { role: "user", parts },
5801
6305
  hadMidTurnUserInput
@@ -5868,7 +6372,7 @@ ${this.pendingRecoveredAgentsNotice}
5868
6372
  try {
5869
6373
  await this.#emitAgentDiagnosticMessage(text);
5870
6374
  } catch (notifyError) {
5871
- debugLogger5.warn(`${failureContext}: ${this.#formatError(notifyError)}`);
6375
+ debugLogger6.warn(`${failureContext}: ${this.#formatError(notifyError)}`);
5872
6376
  }
5873
6377
  }
5874
6378
  async #emitAgentDiagnosticMessage(text) {
@@ -5893,7 +6397,8 @@ ${this.pendingRecoveredAgentsNotice}
5893
6397
  try {
5894
6398
  drainPromise = this.client.extMethod(MID_TURN_QUEUE_DRAIN_METHOD, {
5895
6399
  sessionId: this.sessionId,
5896
- ...options.watchQueuedPromptForTodoStopGuard ? { todoStopGuardWatchQueuedPrompt: true } : {}
6400
+ // Keep the legacy wire name for ACP host compatibility.
6401
+ ...options.watchQueuedPrompt ? { todoStopGuardWatchQueuedPrompt: true } : {}
5897
6402
  });
5898
6403
  let timeoutHandle;
5899
6404
  const timeoutPromise = new Promise((_, reject) => {
@@ -5911,7 +6416,7 @@ ${this.pendingRecoveredAgentsNotice}
5911
6416
  this.midTurnDrainTimeoutStrikes = 0;
5912
6417
  const reliable = isValidMidTurnDrainResponse(
5913
6418
  response,
5914
- options.watchQueuedPromptForTodoStopGuard === true
6419
+ options.watchQueuedPrompt === true
5915
6420
  );
5916
6421
  return {
5917
6422
  parts: await this.#buildMidTurnParts(
@@ -5934,7 +6439,7 @@ ${this.pendingRecoveredAgentsNotice}
5934
6439
  if (isPermanentError) {
5935
6440
  this.midTurnDrainUnavailable = true;
5936
6441
  }
5937
- debugLogger5.warn(
6442
+ debugLogger6.warn(
5938
6443
  `Mid-turn queue drain ${isPermanentError ? "permanently " : ""}unavailable [session ${this.sessionId}]: ${errorMessage}`
5939
6444
  );
5940
6445
  return {
@@ -5964,9 +6469,9 @@ ${this.pendingRecoveredAgentsNotice}
5964
6469
  });
5965
6470
  const expired = Symbol("mid-turn-recovery-expired");
5966
6471
  let timer;
5967
- const deadline = new Promise((resolve5) => {
6472
+ const deadline = new Promise((resolve6) => {
5968
6473
  timer = setTimeout(
5969
- () => resolve5(expired),
6474
+ () => resolve6(expired),
5970
6475
  MID_TURN_QUEUE_RECOVERY_TIMEOUT_MS
5971
6476
  );
5972
6477
  timer.unref?.();
@@ -5980,14 +6485,14 @@ ${this.pendingRecoveredAgentsNotice}
5980
6485
  clearTimeout(timer);
5981
6486
  }
5982
6487
  if (late === expired) {
5983
- debugLogger5.warn(
6488
+ debugLogger6.warn(
5984
6489
  `[mid-turn] dropped a drain response that arrived after the ${MID_TURN_QUEUE_RECOVERY_TIMEOUT_MS}ms recovery deadline [session ${this.sessionId}]`
5985
6490
  );
5986
6491
  return;
5987
6492
  }
5988
6493
  const lateMessages = parseMidTurnDrainResponse(late);
5989
6494
  if (lateMessages.length > 0) {
5990
- debugLogger5.debug(
6495
+ debugLogger6.debug(
5991
6496
  `[mid-turn] recovered ${lateMessages.length} message(s) from a timed-out drain [session ${this.sessionId}]`
5992
6497
  );
5993
6498
  this.midTurnRecoveredMessages.push(...lateMessages);
@@ -6018,7 +6523,7 @@ ${this.pendingRecoveredAgentsNotice}
6018
6523
  }
6019
6524
  if (!abortSignal.aborted) {
6020
6525
  const errorMessage = this.#formatError(messageError);
6021
- debugLogger5.warn(
6526
+ debugLogger6.warn(
6022
6527
  `Failed to resolve mid-turn message: ${errorMessage}`
6023
6528
  );
6024
6529
  }
@@ -6046,7 +6551,7 @@ ${this.pendingRecoveredAgentsNotice}
6046
6551
  try {
6047
6552
  await scheduler.enableDurable(this.sessionId);
6048
6553
  } catch (err) {
6049
- debugLogger5.warn(
6554
+ debugLogger6.warn(
6050
6555
  `Durable cron init failed \u2014 persistent tasks will not fire in this session: ${err}`
6051
6556
  );
6052
6557
  }
@@ -6109,7 +6614,7 @@ ${this.pendingRecoveredAgentsNotice}
6109
6614
  unrelatedCount--;
6110
6615
  }
6111
6616
  if (evictedTaskIds.length > 0) {
6112
- debugLogger5.warn(
6617
+ debugLogger6.warn(
6113
6618
  `Cron queue overflow while automatic work is deferred: evicted ${evictedTaskIds.length} unrelated task(s): ${evictedTaskIds.join(", ")}`
6114
6619
  );
6115
6620
  }
@@ -6132,7 +6637,7 @@ ${this.pendingRecoveredAgentsNotice}
6132
6637
  try {
6133
6638
  await this.assertCanStartTurn();
6134
6639
  } catch (error) {
6135
- debugLogger5.warn(
6640
+ debugLogger6.warn(
6136
6641
  `Cron turn rejected [session ${this.sessionId}]: ${error instanceof Error ? error.message : String(error)}`
6137
6642
  );
6138
6643
  return;
@@ -6143,8 +6648,8 @@ ${this.pendingRecoveredAgentsNotice}
6143
6648
  if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
6144
6649
  this.cronProcessing = true;
6145
6650
  let resolveCompletion;
6146
- this.cronCompletion = new Promise((resolve5) => {
6147
- resolveCompletion = resolve5;
6651
+ this.cronCompletion = new Promise((resolve6) => {
6652
+ resolveCompletion = resolve6;
6148
6653
  });
6149
6654
  try {
6150
6655
  while (this.cronQueue.length > 0) {
@@ -6249,7 +6754,7 @@ ${this.pendingRecoveredAgentsNotice}
6249
6754
  loopTick = await resolver.resolve(loopMode, trustedAtResolve);
6250
6755
  } catch (resolveErr) {
6251
6756
  const code = resolveErr.code ?? "unknown";
6252
- debugLogger5.warn(
6757
+ debugLogger6.warn(
6253
6758
  `loop.md sentinel resolution failed (mode=${loopMode}, code=${code}) \u2014 check .qwen/loop.md permissions/IO`,
6254
6759
  resolveErr
6255
6760
  );
@@ -6272,7 +6777,7 @@ ${this.pendingRecoveredAgentsNotice}
6272
6777
  }
6273
6778
  const modelText = loopTick ? loopTick.modelText : prompt;
6274
6779
  if (loopTick) {
6275
- debugLogger5.debug(
6780
+ debugLogger6.debug(
6276
6781
  `loop tick: mode=${loopMode ?? autonomousMode} delivery=${loopTick.full ? "full" : loopTick.transientError ? "transient-error" : loopTick.autonomous ? "autonomous-tick" : loopTick.sourceLabel ? "reminder" : "absent"} source=${loopTick.sourceLabel ?? "none"} autonomous=${loopTick.autonomous ?? false} transient=${loopTick.transientError ?? false}`
6277
6782
  );
6278
6783
  }
@@ -6305,7 +6810,7 @@ ${this.pendingRecoveredAgentsNotice}
6305
6810
  { text: modelText }
6306
6811
  ]
6307
6812
  };
6308
- const toolLoopState = createDaemonToolLoopState();
6813
+ const toolLoopState = createDaemonToolLoopState("off");
6309
6814
  while (nextMessage !== null) {
6310
6815
  turnCount++;
6311
6816
  if (ac.signal.aborted) {
@@ -6436,7 +6941,8 @@ ${this.pendingRecoveredAgentsNotice}
6436
6941
  const nextAfterTools = await this.#buildNextMessageAfterToolRun(
6437
6942
  toolRun,
6438
6943
  ac.signal,
6439
- promptId
6944
+ promptId,
6945
+ toolLoopState
6440
6946
  );
6441
6947
  nextMessage = nextAfterTools.message;
6442
6948
  if (toolRun.loopDetected) {
@@ -6470,7 +6976,7 @@ ${this.pendingRecoveredAgentsNotice}
6470
6976
  }
6471
6977
  this.todoStopGuard.pauseForTrustedRetry();
6472
6978
  cronHadError = true;
6473
- debugLogger5.error("Error processing cron prompt:", error);
6979
+ debugLogger6.error("Error processing cron prompt:", error);
6474
6980
  const msg = error instanceof Error ? error.message : String(error);
6475
6981
  await this.messageEmitter.emitAgentMessage(
6476
6982
  `[${item.source} error] ${msg}`
@@ -6600,20 +7106,20 @@ ${this.pendingRecoveredAgentsNotice}
6600
7106
  (queued) => !this.#notificationContinuesTodoStopGuardWorkChain(queued)
6601
7107
  );
6602
7108
  if (evictedIndex < 0 && !incomingIsRelated) {
6603
- debugLogger5.warn(
7109
+ debugLogger6.warn(
6604
7110
  `Notification queue overflow: dropping unrelated task=${item.taskId} kind=${item.kind} while automatic work is deferred`
6605
7111
  );
6606
7112
  return;
6607
7113
  }
6608
7114
  if (evictedIndex < 0) {
6609
- debugLogger5.warn(
7115
+ debugLogger6.warn(
6610
7116
  `Notification queue overflow: dropping related task=${item.taskId} kind=${item.kind} because all queued items are related`
6611
7117
  );
6612
7118
  return;
6613
7119
  }
6614
7120
  }
6615
7121
  const [evicted] = this.notificationQueue.splice(evictedIndex, 1);
6616
- debugLogger5.warn(
7122
+ debugLogger6.warn(
6617
7123
  `Notification queue overflow: evicting task=${evicted?.taskId ?? "unknown"} kind=${evicted?.kind ?? "unknown"}`
6618
7124
  );
6619
7125
  }
@@ -6661,7 +7167,7 @@ ${this.pendingRecoveredAgentsNotice}
6661
7167
  }
6662
7168
  );
6663
7169
  } catch (error) {
6664
- debugLogger5.warn(
7170
+ debugLogger6.warn(
6665
7171
  `Daemon notification persistence rejected [session ${this.sessionId}, task ${item.taskId}]: ${error instanceof Error ? error.message : String(error)}`
6666
7172
  );
6667
7173
  return false;
@@ -6689,7 +7195,7 @@ ${this.pendingRecoveredAgentsNotice}
6689
7195
  try {
6690
7196
  await this.assertCanStartTurn();
6691
7197
  } catch (error) {
6692
- debugLogger5.warn(
7198
+ debugLogger6.warn(
6693
7199
  `Notification turn rejected [session ${this.sessionId}]: ${error instanceof Error ? error.message : String(error)}`
6694
7200
  );
6695
7201
  return;
@@ -6700,8 +7206,8 @@ ${this.pendingRecoveredAgentsNotice}
6700
7206
  if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
6701
7207
  this.notificationProcessing = true;
6702
7208
  let resolveCompletion;
6703
- this.notificationCompletion = new Promise((resolve5) => {
6704
- resolveCompletion = resolve5;
7209
+ this.notificationCompletion = new Promise((resolve6) => {
7210
+ resolveCompletion = resolve6;
6705
7211
  });
6706
7212
  try {
6707
7213
  while (this.notificationQueue.length > 0) {
@@ -6786,7 +7292,7 @@ ${this.pendingRecoveredAgentsNotice}
6786
7292
  ...notificationParts
6787
7293
  ]
6788
7294
  };
6789
- const toolLoopState = createDaemonToolLoopState();
7295
+ const toolLoopState = createDaemonToolLoopState("off");
6790
7296
  while (nextMessage !== null) {
6791
7297
  if (ac.signal.aborted) {
6792
7298
  this.todoStopGuard.suspend();
@@ -6915,7 +7421,8 @@ ${this.pendingRecoveredAgentsNotice}
6915
7421
  const nextAfterTools = await this.#buildNextMessageAfterToolRun(
6916
7422
  toolRun,
6917
7423
  ac.signal,
6918
- promptId
7424
+ promptId,
7425
+ toolLoopState
6919
7426
  );
6920
7427
  nextMessage = nextAfterTools.message;
6921
7428
  if (toolRun.loopDetected) {
@@ -6951,14 +7458,14 @@ ${this.pendingRecoveredAgentsNotice}
6951
7458
  return;
6952
7459
  }
6953
7460
  this.todoStopGuard.pauseForTrustedRetry();
6954
- debugLogger5.error("Error processing background notification:", error);
7461
+ debugLogger6.error("Error processing background notification:", error);
6955
7462
  const msg = error instanceof Error ? error.message : String(error);
6956
7463
  try {
6957
7464
  await this.messageEmitter.emitAgentMessage(
6958
7465
  `[notification error] ${msg}`
6959
7466
  );
6960
7467
  } catch (emitError) {
6961
- debugLogger5.error(
7468
+ debugLogger6.error(
6962
7469
  "Failed to emit background notification error:",
6963
7470
  emitError
6964
7471
  );
@@ -7019,7 +7526,7 @@ ${this.pendingRecoveredAgentsNotice}
7019
7526
  source: "background_notification"
7020
7527
  });
7021
7528
  } catch (error) {
7022
- debugLogger5.debug(
7529
+ debugLogger6.debug(
7023
7530
  `Background notification end-turn extNotification dropped: ${this.#formatError(error)}`
7024
7531
  );
7025
7532
  }
@@ -7028,7 +7535,7 @@ ${this.pendingRecoveredAgentsNotice}
7028
7535
  try {
7029
7536
  await this.sendAvailableCommandsUpdateOrThrow();
7030
7537
  } catch (error) {
7031
- debugLogger5.error("Error sending available commands update:", error);
7538
+ debugLogger6.error("Error sending available commands update:", error);
7032
7539
  }
7033
7540
  }
7034
7541
  async refreshSkillsFromSettings(options = {}) {
@@ -7050,7 +7557,7 @@ ${this.pendingRecoveredAgentsNotice}
7050
7557
  await skillManager.notifyConfigChanged();
7051
7558
  } catch (error) {
7052
7559
  if (!updateFailed) throw error;
7053
- debugLogger5.error(
7560
+ debugLogger6.error(
7054
7561
  "SkillManager refresh failed after command update failure:",
7055
7562
  error
7056
7563
  );
@@ -7097,9 +7604,9 @@ ${this.pendingRecoveredAgentsNotice}
7097
7604
  () => void 0,
7098
7605
  () => void 0
7099
7606
  ),
7100
- new Promise((resolve5) => {
7101
- if (signal.aborted) return resolve5();
7102
- abortListener = /* @__PURE__ */ __name(() => resolve5(), "abortListener");
7607
+ new Promise((resolve6) => {
7608
+ if (signal.aborted) return resolve6();
7609
+ abortListener = /* @__PURE__ */ __name(() => resolve6(), "abortListener");
7103
7610
  signal.addEventListener("abort", abortListener, { once: true });
7104
7611
  })
7105
7612
  ]).finally(() => {
@@ -7144,7 +7651,7 @@ ${this.pendingRecoveredAgentsNotice}
7144
7651
  sessionId: this.sessionId,
7145
7652
  currentModeId: params.modeId
7146
7653
  }).catch((error) => {
7147
- debugLogger5.debug("mode-update extNotification failed", error);
7654
+ debugLogger6.debug("mode-update extNotification failed", error);
7148
7655
  });
7149
7656
  }
7150
7657
  /**
@@ -7200,7 +7707,7 @@ ${this.pendingRecoveredAgentsNotice}
7200
7707
  sessionId: this.sessionId,
7201
7708
  currentModelId: currentAcpModelId
7202
7709
  }).catch((error) => {
7203
- debugLogger5.debug("model-update extNotification failed", error);
7710
+ debugLogger6.debug("model-update extNotification failed", error);
7204
7711
  });
7205
7712
  if (options.persistDefault ?? true) {
7206
7713
  const persistScope = getPersistScopeForModelSelection(this.settings);
@@ -7247,7 +7754,7 @@ ${this.pendingRecoveredAgentsNotice}
7247
7754
  await this.sendUpdate(update);
7248
7755
  legacyFrameSent = true;
7249
7756
  } catch (error) {
7250
- debugLogger5.debug("current_mode_update notification failed", error);
7757
+ debugLogger6.debug("current_mode_update notification failed", error);
7251
7758
  }
7252
7759
  try {
7253
7760
  await this.client.extNotification("qwen/notify/session/mode-update", {
@@ -7257,7 +7764,7 @@ ${this.pendingRecoveredAgentsNotice}
7257
7764
  legacyFrameSent
7258
7765
  });
7259
7766
  } catch (error) {
7260
- debugLogger5.debug("mode-update extNotification failed", error);
7767
+ debugLogger6.debug("mode-update extNotification failed", error);
7261
7768
  }
7262
7769
  }
7263
7770
  /**
@@ -7293,10 +7800,24 @@ ${this.pendingRecoveredAgentsNotice}
7293
7800
  });
7294
7801
  }, "queueToolResultRecord");
7295
7802
  const finalizeRunToolResult = /* @__PURE__ */ __name(async (result) => {
7296
- if (pendingToolResultRecords.length === 0) return result;
7297
7803
  const orderedRecords = [...pendingToolResultRecords].sort(
7298
7804
  (left, right) => left.ordinal - right.ordinal || left.sequence - right.sequence
7299
7805
  );
7806
+ const repeatedToolFailureBatch = {
7807
+ complete: orderedRecords.length === dedupedFunctionCalls.length && new Set(orderedRecords.map((record) => record.ordinal)).size === dedupedFunctionCalls.length,
7808
+ observations: orderedRecords.map((record) => ({
7809
+ callId: record.callId,
7810
+ policyToolName: record.policyToolName,
7811
+ toolType: record.toolType,
7812
+ terminalStatus: record.metadata.status,
7813
+ executionStatus: record.metadata.executionStatus,
7814
+ executionErrorType: record.executionErrorType,
7815
+ providerDuplicate: record.providerDuplicate
7816
+ }))
7817
+ };
7818
+ if (orderedRecords.length === 0) {
7819
+ return { ...result, repeatedToolFailureBatch };
7820
+ }
7300
7821
  const finalized = await finalizeToolResponses(
7301
7822
  this.config,
7302
7823
  orderedRecords.map((record) => ({
@@ -7311,7 +7832,8 @@ ${this.pendingRecoveredAgentsNotice}
7311
7832
  });
7312
7833
  return {
7313
7834
  ...result,
7314
- parts: finalized.flatMap((entry) => entry.responseParts)
7835
+ parts: finalized.flatMap((entry) => entry.responseParts),
7836
+ repeatedToolFailureBatch
7315
7837
  };
7316
7838
  }, "finalizeRunToolResult");
7317
7839
  let skippedToolCallCounter = 0;
@@ -7350,7 +7872,7 @@ ${this.pendingRecoveredAgentsNotice}
7350
7872
  }
7351
7873
  await this.toolCallEmitter.emitError(callId, toolName, error);
7352
7874
  } catch (recordError) {
7353
- debugLogger5.error("Failed to record skipped tool call:", recordError);
7875
+ debugLogger6.error("Failed to record skipped tool call:", recordError);
7354
7876
  }
7355
7877
  return part;
7356
7878
  }, "recordSkippedToolCall");
@@ -7366,7 +7888,7 @@ ${this.pendingRecoveredAgentsNotice}
7366
7888
  );
7367
7889
  if (repeatedDuplicateCall) {
7368
7890
  const providerCallId = getProviderToolCallId(repeatedDuplicateCall) ?? repeatedDuplicateCall.id;
7369
- debugLogger5.debug(
7891
+ debugLogger6.debug(
7370
7892
  `[Session.runToolCalls] Dropping batch after repeated duplicate provider tool-call id: ${providerCallId} (tool: ${repeatedDuplicateCall.name ?? "unknown_tool"})`
7371
7893
  );
7372
7894
  return await finalizeRunToolResult({
@@ -7382,7 +7904,7 @@ ${this.pendingRecoveredAgentsNotice}
7382
7904
  this.duplicateProviderToolCallResponseIds
7383
7905
  );
7384
7906
  const response = createDuplicateProviderToolCallResponse(request);
7385
- debugLogger5.debug(
7907
+ debugLogger6.debug(
7386
7908
  `[Session.runToolCalls] Suppressing duplicate provider tool-call id: ${providerCallId} (tool: ${request.name})`
7387
7909
  );
7388
7910
  batches.push({ kind: "duplicate", fc, request, response });
@@ -7426,7 +7948,7 @@ ${this.pendingRecoveredAgentsNotice}
7426
7948
  });
7427
7949
  }
7428
7950
  } catch (emitError) {
7429
- debugLogger5.debug(
7951
+ debugLogger6.debug(
7430
7952
  "[Session.runToolCalls] Failed to emit duplicate tool update",
7431
7953
  emitError
7432
7954
  );
@@ -7436,6 +7958,7 @@ ${this.pendingRecoveredAgentsNotice}
7436
7958
  toolName: request.name,
7437
7959
  responseParts: response.responseParts,
7438
7960
  persistedOutputFiles: response.persistedOutputFiles,
7961
+ providerDuplicate: true,
7439
7962
  metadata: {
7440
7963
  callId: response.callId,
7441
7964
  status: "error",
@@ -7524,13 +8047,13 @@ ${this.pendingRecoveredAgentsNotice}
7524
8047
  memoryWriteCandidates,
7525
8048
  this.config.getProjectRoot()
7526
8049
  );
7527
- debugLogger5.debug(
8050
+ debugLogger6.debug(
7528
8051
  `ACP session ${this.sessionId} checked marked context-file memory tool batch; matched=${matchedContextFileWrite}`
7529
8052
  );
7530
8053
  if (!matchedContextFileWrite) {
7531
8054
  return;
7532
8055
  }
7533
- debugLogger5.debug(
8056
+ debugLogger6.debug(
7534
8057
  `ACP session ${this.sessionId} refreshing memory after context-file memory write`
7535
8058
  );
7536
8059
  await refreshMemoryInstruction(this.config, {
@@ -7589,7 +8112,7 @@ ${this.pendingRecoveredAgentsNotice}
7589
8112
  results[idx] = r;
7590
8113
  if (r.loopDetected && executing.size > 1 && !warnedWaitingForInFlight) {
7591
8114
  warnedWaitingForInFlight = true;
7592
- debugLogger5.warn(
8115
+ debugLogger6.warn(
7593
8116
  `Loop detection stopped this ACP turn; waiting for ${executing.size - 1} in-flight tool call(s) to settle before returning.`
7594
8117
  );
7595
8118
  }
@@ -7792,6 +8315,7 @@ ${this.pendingRecoveredAgentsNotice}
7792
8315
  let terminalStatus;
7793
8316
  let toolType = "native";
7794
8317
  let mcpServerName = void 0;
8318
+ const guardContext = {};
7795
8319
  if (toolLoopState?.loopDetected) {
7796
8320
  return {
7797
8321
  parts: [
@@ -7847,7 +8371,7 @@ ${this.pendingRecoveredAgentsNotice}
7847
8371
  mcp_server_name: mcpServerName
7848
8372
  });
7849
8373
  } catch (telemetryError) {
7850
- debugLogger5.debug(
8374
+ debugLogger6.debug(
7851
8375
  "[Session.runTool] Failed to record terminal tool telemetry",
7852
8376
  telemetryError
7853
8377
  );
@@ -7871,7 +8395,7 @@ ${this.pendingRecoveredAgentsNotice}
7871
8395
  try {
7872
8396
  await this.toolCallEmitter.emitError(callId, toolName2, error);
7873
8397
  } catch (emitError) {
7874
- debugLogger5.debug(
8398
+ debugLogger6.debug(
7875
8399
  "[Session.runTool] Failed to emit terminal tool update",
7876
8400
  emitError
7877
8401
  );
@@ -7887,6 +8411,9 @@ ${this.pendingRecoveredAgentsNotice}
7887
8411
  callId,
7888
8412
  toolName: toolName2,
7889
8413
  responseParts: errorParts,
8414
+ policyToolName: guardContext.policyToolName,
8415
+ toolType,
8416
+ executionErrorType: executionStatus === "error" ? executionErrorType ?? opts.errorType : void 0,
7890
8417
  metadata: {
7891
8418
  callId,
7892
8419
  status: opts.status,
@@ -7952,6 +8479,7 @@ ${this.pendingRecoveredAgentsNotice}
7952
8479
  toolType = tool instanceof DiscoveredMCPTool ? "mcp" : "native";
7953
8480
  mcpServerName = tool instanceof DiscoveredMCPTool ? tool.serverName : void 0;
7954
8481
  const policyToolName = tool.name;
8482
+ guardContext.policyToolName = policyToolName;
7955
8483
  const originalPolicyRequestArgs = policyToolName === ToolNames.SHELL || policyToolName === ToolNames.MONITOR ? structuredClone(args) : args;
7956
8484
  const toolSpan = startToolSpan(
7957
8485
  policyToolName,
@@ -8149,7 +8677,7 @@ ${this.pendingRecoveredAgentsNotice}
8149
8677
  forceAutoReviewForAllow
8150
8678
  );
8151
8679
  if (finalPermission === "allow" && forceAutoReviewForAllow) {
8152
- debugLogger5.info(
8680
+ debugLogger6.info(
8153
8681
  `Auto mode: L4 allow overridden by protected-write guard for ${policyToolName}`
8154
8682
  );
8155
8683
  }
@@ -8199,7 +8727,7 @@ ${this.pendingRecoveredAgentsNotice}
8199
8727
  autoModeAllowed = true;
8200
8728
  break;
8201
8729
  case "blocked":
8202
- debugLogger5.warn(
8730
+ debugLogger6.warn(
8203
8731
  `Auto mode blocked (${outcome.reason}): tool=${policyToolName}, ` + formatDenialStateLog(denialState)
8204
8732
  );
8205
8733
  return earlyErrorResponse(
@@ -8215,7 +8743,7 @@ ${this.pendingRecoveredAgentsNotice}
8215
8743
  wasAutoModeManualFallback = isDenialFallbackReason(outcome.reason) || outcome.reason === "classifier_unavailable";
8216
8744
  autoModeFallbackMessage = outcome.message;
8217
8745
  if (wasAutoModeManualFallback) {
8218
- debugLogger5.warn(
8746
+ debugLogger6.warn(
8219
8747
  `Auto mode fallback to manual approval (${outcome.reason}): ` + formatDenialStateLog(denialState)
8220
8748
  );
8221
8749
  }
@@ -8233,12 +8761,12 @@ ${this.pendingRecoveredAgentsNotice}
8233
8761
  const before = this.config.getAutoModeDenialState();
8234
8762
  const after = recordFallbackApprove(before);
8235
8763
  if (after === before) {
8236
- debugLogger5.warn(
8764
+ debugLogger6.warn(
8237
8765
  `Auto mode denial counters already clear after fallback approval: ` + formatDenialStateLog(before)
8238
8766
  );
8239
8767
  return;
8240
8768
  }
8241
- debugLogger5.warn(
8769
+ debugLogger6.warn(
8242
8770
  `Auto mode denial counters reset after fallback approval: ${formatDenialStateLog(before)} -> ${formatDenialStateLog(after)}`
8243
8771
  );
8244
8772
  this.config.setAutoModeDenialState(after);
@@ -8514,7 +9042,7 @@ ${this.pendingRecoveredAgentsNotice}
8514
9042
  offeredPermissionOptions
8515
9043
  );
8516
9044
  } catch (error) {
8517
- debugLogger5.error(
9045
+ debugLogger6.error(
8518
9046
  `Permission request failed for tool ${toolName}:`,
8519
9047
  error
8520
9048
  );
@@ -8523,7 +9051,7 @@ ${this.pendingRecoveredAgentsNotice}
8523
9051
  "cancel" /* Cancel */
8524
9052
  );
8525
9053
  } catch (confirmError) {
8526
- debugLogger5.error(
9054
+ debugLogger6.error(
8527
9055
  `Failed to cancel tool ${toolName} after permission request failure:`,
8528
9056
  confirmError
8529
9057
  );
@@ -8588,7 +9116,7 @@ ${this.pendingRecoveredAgentsNotice}
8588
9116
  if (outcome !== "cancel" /* Cancel */) {
8589
9117
  throw error;
8590
9118
  }
8591
- debugLogger5.error(
9119
+ debugLogger6.error(
8592
9120
  `Failed to confirm cancellation for tool ${toolName}:`,
8593
9121
  error
8594
9122
  );
@@ -8655,7 +9183,7 @@ ${this.pendingRecoveredAgentsNotice}
8655
9183
  try {
8656
9184
  await this.toolCallEmitter.emitStart(startParams);
8657
9185
  } catch (emitError) {
8658
- debugLogger5.debug(
9186
+ debugLogger6.debug(
8659
9187
  "[Session.runTool] Failed to emit tool start update",
8660
9188
  emitError
8661
9189
  );
@@ -8685,7 +9213,7 @@ ${this.pendingRecoveredAgentsNotice}
8685
9213
  `\u2717 **PreToolUse blocked**: ${toolName} - ${blockReason}`
8686
9214
  );
8687
9215
  } catch (emitError) {
8688
- debugLogger5.debug(
9216
+ debugLogger6.debug(
8689
9217
  "[Session.runTool] Failed to emit PreToolUse block message",
8690
9218
  emitError
8691
9219
  );
@@ -8699,7 +9227,7 @@ ${this.pendingRecoveredAgentsNotice}
8699
9227
  });
8700
9228
  }
8701
9229
  if (preHookResult.additionalContext) {
8702
- debugLogger5.debug(
9230
+ debugLogger6.debug(
8703
9231
  `PreToolUse hook additional context for ${toolName}: ${preHookResult.additionalContext}`
8704
9232
  );
8705
9233
  }
@@ -8790,7 +9318,7 @@ ${this.pendingRecoveredAgentsNotice}
8790
9318
  status: "in_progress",
8791
9319
  _meta: { toolName, shellProgress: chunk }
8792
9320
  }).catch((err) => {
8793
- debugLogger5.debug(
9321
+ debugLogger6.debug(
8794
9322
  `[Session.runTool] heartbeat update failed for ${callId}: ${err}`
8795
9323
  );
8796
9324
  });
@@ -8815,7 +9343,7 @@ ${this.pendingRecoveredAgentsNotice}
8815
9343
  invocation.params
8816
9344
  );
8817
9345
  } catch {
8818
- debugLogger5.debug(
9346
+ debugLogger6.debug(
8819
9347
  "[Session.runTool] Failed to record tool arguments telemetry"
8820
9348
  );
8821
9349
  }
@@ -8923,7 +9451,7 @@ ${this.pendingRecoveredAgentsNotice}
8923
9451
  }
8924
9452
  if (postHookResult.shouldStop) {
8925
9453
  const stopMessage = postHookResult.stopReason || "Execution stopped by PostToolUse hook";
8926
- debugLogger5.info(
9454
+ debugLogger6.info(
8927
9455
  `PostToolUse hook requested stop for ${toolName}: ${stopMessage}`
8928
9456
  );
8929
9457
  this.todoStopGuard.suspend();
@@ -8958,7 +9486,7 @@ ${this.pendingRecoveredAgentsNotice}
8958
9486
  callId
8959
9487
  );
8960
9488
  if (failureHookResult.additionalContext) {
8961
- debugLogger5.debug(
9489
+ debugLogger6.debug(
8962
9490
  `PostToolUseFailure hook additional context for ${toolName}: ${failureHookResult.additionalContext}`
8963
9491
  );
8964
9492
  }
@@ -8969,7 +9497,7 @@ ${this.pendingRecoveredAgentsNotice}
8969
9497
  artifacts: failureHookResult.artifacts
8970
9498
  });
8971
9499
  } catch (hookError) {
8972
- debugLogger5.debug(
9500
+ debugLogger6.debug(
8973
9501
  "[Session.runTool] PostToolUseFailure hook failed",
8974
9502
  hookError
8975
9503
  );
@@ -8988,7 +9516,7 @@ ${this.pendingRecoveredAgentsNotice}
8988
9516
  try {
8989
9517
  await this.messageEmitter.emitAgentMessage(visionBridgeNotice);
8990
9518
  } catch (emitError) {
8991
- debugLogger5.debug(
9519
+ debugLogger6.debug(
8992
9520
  "[Session.runTool] Failed to emit vision bridge notice",
8993
9521
  emitError
8994
9522
  );
@@ -9018,7 +9546,7 @@ ${this.pendingRecoveredAgentsNotice}
9018
9546
  try {
9019
9547
  await this.planEmitter.emitPlan(plan, callId);
9020
9548
  } catch (emitError) {
9021
- debugLogger5.debug(
9549
+ debugLogger6.debug(
9022
9550
  "[Session.runTool] Failed to emit plan update",
9023
9551
  emitError
9024
9552
  );
@@ -9037,7 +9565,7 @@ ${this.pendingRecoveredAgentsNotice}
9037
9565
  artifacts: toolResult.artifacts
9038
9566
  });
9039
9567
  } catch (emitError) {
9040
- debugLogger5.debug(
9568
+ debugLogger6.debug(
9041
9569
  "[Session.runTool] Failed to emit terminal tool update",
9042
9570
  emitError
9043
9571
  );
@@ -9064,7 +9592,7 @@ ${this.pendingRecoveredAgentsNotice}
9064
9592
  mcp_server_name: mcpServerName
9065
9593
  });
9066
9594
  } catch (telemetryError) {
9067
- debugLogger5.debug(
9595
+ debugLogger6.debug(
9068
9596
  "[Session.runTool] Failed to record terminal tool telemetry",
9069
9597
  telemetryError
9070
9598
  );
@@ -9074,6 +9602,9 @@ ${this.pendingRecoveredAgentsNotice}
9074
9602
  toolName,
9075
9603
  responseParts,
9076
9604
  persistedOutputFiles: toolResult.persistedOutputFiles,
9605
+ policyToolName,
9606
+ toolType,
9607
+ executionErrorType: executionStatus === "error" ? executionErrorType : void 0,
9077
9608
  metadata: {
9078
9609
  callId,
9079
9610
  status,
@@ -9092,7 +9623,7 @@ ${this.pendingRecoveredAgentsNotice}
9092
9623
  try {
9093
9624
  addToolCallResultAttributes(this.config, toolSpan, result);
9094
9625
  } catch {
9095
- debugLogger5.debug(
9626
+ debugLogger6.debug(
9096
9627
  "[Session.runTool] Failed to record tool result telemetry"
9097
9628
  );
9098
9629
  }
@@ -9133,7 +9664,7 @@ ${this.pendingRecoveredAgentsNotice}
9133
9664
  callId
9134
9665
  );
9135
9666
  if (failureHookResult.additionalContext) {
9136
- debugLogger5.debug(
9667
+ debugLogger6.debug(
9137
9668
  `PostToolUseFailure hook additional context for ${toolName}: ${failureHookResult.additionalContext}`
9138
9669
  );
9139
9670
  }
@@ -9144,7 +9675,7 @@ ${this.pendingRecoveredAgentsNotice}
9144
9675
  artifacts: failureHookResult.artifacts
9145
9676
  });
9146
9677
  } catch (hookError) {
9147
- debugLogger5.debug(
9678
+ debugLogger6.debug(
9148
9679
  "[Session.runTool] PostToolUseFailure hook failed",
9149
9680
  hookError
9150
9681
  );
@@ -9305,8 +9836,8 @@ ${this.pendingRecoveredAgentsNotice}
9305
9836
  collectExtensionMentionRefs(part.text, extensionMentions);
9306
9837
  collectMcpServerMentionRefs(part.text, mcpServerMentions);
9307
9838
  for (const pathSpec of extractAtPathCommands(part.text)) {
9308
- if (!path2.isAbsolute(pathSpec)) continue;
9309
- const resolved = path2.resolve(
9839
+ if (!path3.isAbsolute(pathSpec)) continue;
9840
+ const resolved = path3.resolve(
9310
9841
  this.config.getProjectRoot(),
9311
9842
  pathSpec
9312
9843
  );
@@ -9375,7 +9906,7 @@ ${this.pendingRecoveredAgentsNotice}
9375
9906
  ...textPathSpecsToRead.entries(),
9376
9907
  ...atPathCommandParts.flatMap((part) => {
9377
9908
  const fileUri = part.fileData.fileUri;
9378
- const resolved = path2.resolve(this.config.getTargetDir(), fileUri);
9909
+ const resolved = path3.resolve(this.config.getTargetDir(), fileUri);
9379
9910
  const canonicalPath = resolveExistingFile(resolved);
9380
9911
  return canonicalPath ? [[canonicalPath, fileUri]] : [];
9381
9912
  })
@@ -9388,7 +9919,7 @@ ${this.pendingRecoveredAgentsNotice}
9388
9919
  if (resolveExistingFile(textPath) !== textPath || !this.config.getWorkspaceContext().isPathWithinWorkspace(textPath) || textPathSpecsToRead.has(textPath) && !getSpecificMimeType(textPath)?.startsWith("image/") || this.config.getFileService().shouldIgnoreFile(displayPath, filteringOptions) || this.config.getFileService().shouldIgnoreFile(textPath, filteringOptions)) {
9389
9920
  continue;
9390
9921
  }
9391
- const stats = statSync(textPath);
9922
+ const stats = statSync2(textPath);
9392
9923
  revalidatedTextPaths.push(textPath);
9393
9924
  displayPaths.set(textPath, displayPath);
9394
9925
  acceptedFileUris.add(displayPath);
@@ -9501,7 +10032,7 @@ ${contextPart.text}`
9501
10032
  formatFullTurnVisionNotice(fullTurnModel)
9502
10033
  );
9503
10034
  } catch (error) {
9504
- debugLogger5.debug(
10035
+ debugLogger6.debug(
9505
10036
  `full-turn vision: failed to emit notice; continuing error=${error instanceof Error ? error.message : String(error)}`
9506
10037
  );
9507
10038
  }
@@ -9510,19 +10041,19 @@ ${contextPart.text}`
9510
10041
  }
9511
10042
  let bridgeResult;
9512
10043
  try {
9513
- debugLogger5.debug("vision bridge: gate matched, running conversion");
10044
+ debugLogger6.debug("vision bridge: gate matched, running conversion");
9514
10045
  bridgeResult = await runVisionBridge({
9515
10046
  config: this.config,
9516
10047
  parts,
9517
10048
  signal: abortSignal
9518
10049
  });
9519
10050
  } catch (error) {
9520
- debugLogger5.debug(
10051
+ debugLogger6.debug(
9521
10052
  `vision bridge: failed before replacement; falling back to text-only parts error=${String(error instanceof Error ? error.message : error)}`
9522
10053
  );
9523
10054
  return splitImageParts(parts).nonImageParts;
9524
10055
  }
9525
- debugLogger5.debug(
10056
+ debugLogger6.debug(
9526
10057
  `vision bridge: status=${bridgeResult.status} applied=${bridgeResult.applied} model=${bridgeResult.modelId ?? "(none)"}${bridgeResult.error ? ` error=${bridgeResult.error}` : ""}`
9527
10058
  );
9528
10059
  if (bridgeResult.status !== "skipped" || bridgeResult.egressOccurred) {
@@ -9531,13 +10062,13 @@ ${contextPart.text}`
9531
10062
  formatVisionBridgeNotice(bridgeResult)
9532
10063
  );
9533
10064
  } catch (error) {
9534
- debugLogger5.debug(
10065
+ debugLogger6.debug(
9535
10066
  `vision bridge: failed to emit notice; continuing with bridge result error=${String(error instanceof Error ? error.message : error)}`
9536
10067
  );
9537
10068
  }
9538
10069
  }
9539
10070
  if (abortSignal.aborted) {
9540
- debugLogger5.debug("vision bridge: turn aborted after bridge returned");
10071
+ debugLogger6.debug("vision bridge: turn aborted after bridge returned");
9541
10072
  return splitImageParts(parts).nonImageParts;
9542
10073
  }
9543
10074
  if (bridgeResult.applied && bridgeResult.parts != null) {
@@ -9551,7 +10082,7 @@ ${contextPart.text}`
9551
10082
  }
9552
10083
  const voiceModel = readVoiceModel(this.settings);
9553
10084
  if (!voiceModel) {
9554
- debugLogger5.debug(
10085
+ debugLogger6.debug(
9555
10086
  "voice bridge: no voice model configured; replacing audio with note"
9556
10087
  );
9557
10088
  return parts.map(
@@ -9570,14 +10101,14 @@ ${contextPart.text}`
9570
10101
  }
9571
10102
  const inlineData = part.inlineData;
9572
10103
  if (approxBase64Bytes(inlineData.data) > MAX_AUDIO_BYTES) {
9573
- debugLogger5.debug(
10104
+ debugLogger6.debug(
9574
10105
  "voice bridge: audio too large; replacing audio with note"
9575
10106
  );
9576
10107
  converted.push({ text: buildVoiceUnavailableBlock("audio too large") });
9577
10108
  continue;
9578
10109
  }
9579
10110
  try {
9580
- debugLogger5.debug(`voice bridge: transcribing audio via ${voiceModel}`);
10111
+ debugLogger6.debug(`voice bridge: transcribing audio via ${voiceModel}`);
9581
10112
  const transcript = (await transcribeVoiceAudio(
9582
10113
  {
9583
10114
  data: new Uint8Array(Buffer2.from(inlineData.data, "base64")),
@@ -9594,7 +10125,7 @@ ${contextPart.text}`
9594
10125
  }
9595
10126
  )).trim();
9596
10127
  if (abortSignal.aborted) {
9597
- debugLogger5.debug("voice bridge: turn aborted after transcription");
10128
+ debugLogger6.debug("voice bridge: turn aborted after transcription");
9598
10129
  return converted;
9599
10130
  }
9600
10131
  if (transcript.length > 0) {
@@ -9607,10 +10138,10 @@ ${contextPart.text}`
9607
10138
  });
9608
10139
  } catch (error) {
9609
10140
  if (abortSignal.aborted) {
9610
- debugLogger5.debug("voice bridge: transcription cancelled");
10141
+ debugLogger6.debug("voice bridge: transcription cancelled");
9611
10142
  return converted;
9612
10143
  }
9613
- debugLogger5.debug(
10144
+ debugLogger6.debug(
9614
10145
  `voice bridge: transcription failed; replacing audio with note error=${sanitizeVoiceErrorMessage(String(error instanceof Error ? error.message : error))}`
9615
10146
  );
9616
10147
  converted.push({
@@ -9624,7 +10155,7 @@ ${contextPart.text}`
9624
10155
  transcribedCount > 0 ? this.#formatVoiceBridgeNotice(voiceModel, transcribedCount) : this.#formatVoiceBridgeEgressNotice(voiceModel, egressCount)
9625
10156
  );
9626
10157
  } catch (error) {
9627
- debugLogger5.debug(
10158
+ debugLogger6.debug(
9628
10159
  `voice bridge: failed to emit notice; continuing with bridge result error=${String(error instanceof Error ? error.message : error)}`
9629
10160
  );
9630
10161
  }
@@ -9685,7 +10216,7 @@ ${contextPart.text}`
9685
10216
  }
9686
10217
  debug(msg) {
9687
10218
  if (this.config.getDebugMode()) {
9688
- debugLogger5.warn(msg);
10219
+ debugLogger6.warn(msg);
9689
10220
  }
9690
10221
  }
9691
10222
  async emitHookArtifactsNotification(args) {
@@ -9725,7 +10256,7 @@ ${contextPart.text}`
9725
10256
  }
9726
10257
  );
9727
10258
  }).catch((err) => {
9728
- debugLogger5.debug(
10259
+ debugLogger6.debug(
9729
10260
  `ACP terminalSequence notification dropped (session=${this.sessionId}): ${err instanceof Error ? err.message : String(err)}`
9730
10261
  );
9731
10262
  });
@@ -9734,7 +10265,7 @@ ${contextPart.text}`
9734
10265
 
9735
10266
  // packages/cli/src/acp-integration/active-work-reporter.ts
9736
10267
  init_esbuild_shims();
9737
- var debugLogger6 = createDebugLogger("ACTIVE_WORK");
10268
+ var debugLogger7 = createDebugLogger("ACTIVE_WORK");
9738
10269
  var ActiveWorkReporter = class {
9739
10270
  constructor(send, listSources, intervalMs) {
9740
10271
  this.send = send;
@@ -9805,7 +10336,7 @@ var ActiveWorkReporter = class {
9805
10336
  });
9806
10337
  }
9807
10338
  } catch (error) {
9808
- debugLogger6.warn(
10339
+ debugLogger7.warn(
9809
10340
  `active-work snapshot collection failed; skipping this report: ${error instanceof Error ? error.message : String(error)}`
9810
10341
  );
9811
10342
  return;
@@ -9934,15 +10465,34 @@ function runWithAcpRuntimeOutputDir(settings, cwd, fn) {
9934
10465
  }
9935
10466
  __name(runWithAcpRuntimeOutputDir, "runWithAcpRuntimeOutputDir");
9936
10467
 
10468
+ // packages/cli/src/acp-integration/errorCodes.ts
10469
+ init_esbuild_shims();
10470
+ var ACP_ERROR_CODES = {
10471
+ // Parse error: invalid JSON received by server.
10472
+ PARSE_ERROR: -32700,
10473
+ // Invalid request: JSON is not a valid Request object.
10474
+ INVALID_REQUEST: -32600,
10475
+ // Method not found: method does not exist or is unavailable.
10476
+ METHOD_NOT_FOUND: -32601,
10477
+ // Invalid params: invalid method parameter(s).
10478
+ INVALID_PARAMS: -32602,
10479
+ // Internal error: implementation-defined server error.
10480
+ INTERNAL_ERROR: -32603,
10481
+ // Authentication required: must authenticate before operation.
10482
+ AUTH_REQUIRED: -32e3,
10483
+ // Resource not found: e.g. missing file.
10484
+ RESOURCE_NOT_FOUND: -32002
10485
+ };
10486
+
9937
10487
  // packages/cli/src/acp-integration/acpAgent.ts
9938
- var debugLogger7 = createDebugLogger("ACP_AGENT");
10488
+ var debugLogger8 = createDebugLogger("ACP_AGENT");
9939
10489
  var QWEN_ACP_LOCAL_READ_ROOTS_ENV = "QWEN_ACP_LOCAL_READ_ROOTS";
9940
10490
  var POSIX_TMP_LOCAL_READ_ROOT = "/tmp";
9941
10491
  var BTW_CHILD_TIMEOUT_MS = 55e3;
9942
10492
  var MCP_OAUTH_START_TIMEOUT_MS = 3e4;
9943
10493
  var SESSION_DRAIN_TIMEOUT_MS = 3e4;
9944
10494
  var WORKSPACE_MEMORY_REMEMBER_CHILD_TIMEOUT_MS = 295e3;
9945
- function createAcpSessionStartProfiler(span) {
10495
+ function createAcpSessionProfiler(span, attributePrefix) {
9946
10496
  let failedStage;
9947
10497
  const setAttribute = /* @__PURE__ */ __name((name, value) => {
9948
10498
  try {
@@ -9953,15 +10503,21 @@ function createAcpSessionStartProfiler(span) {
9953
10503
  const recordStage = /* @__PURE__ */ __name((stage, start) => {
9954
10504
  const durationMs = Math.round((performance.now() - start) * 100) / 100;
9955
10505
  if (Number.isFinite(durationMs) && durationMs >= 0) {
9956
- setAttribute(`qwen-code.daemon.session_start.${stage}_ms`, durationMs);
10506
+ setAttribute(
10507
+ `qwen-code.daemon.${attributePrefix}.${stage}_ms`,
10508
+ durationMs
10509
+ );
9957
10510
  }
9958
10511
  }, "recordStage");
9959
10512
  const recordFailure = /* @__PURE__ */ __name((stage) => {
9960
10513
  if (failedStage !== void 0) return;
9961
10514
  failedStage = stage;
9962
- setAttribute("qwen-code.daemon.session_start.failed_stage", stage);
10515
+ setAttribute(`qwen-code.daemon.${attributePrefix}.failed_stage`, stage);
9963
10516
  }, "recordFailure");
9964
10517
  return {
10518
+ fail(stage) {
10519
+ recordFailure(stage);
10520
+ },
9965
10521
  async time(stage, fn) {
9966
10522
  if (!span) return await fn();
9967
10523
  const start = performance.now();
@@ -9991,7 +10547,15 @@ function createAcpSessionStartProfiler(span) {
9991
10547
  }
9992
10548
  };
9993
10549
  }
10550
+ __name(createAcpSessionProfiler, "createAcpSessionProfiler");
10551
+ function createAcpSessionStartProfiler(span) {
10552
+ return createAcpSessionProfiler(span, "session_start");
10553
+ }
9994
10554
  __name(createAcpSessionStartProfiler, "createAcpSessionStartProfiler");
10555
+ function createAcpSessionRestoreProfiler(span) {
10556
+ return createAcpSessionProfiler(span, "session_restore");
10557
+ }
10558
+ __name(createAcpSessionRestoreProfiler, "createAcpSessionRestoreProfiler");
9995
10559
  function workspaceMemoryErrorData(code, diagnostics) {
9996
10560
  return {
9997
10561
  errorKind: code,
@@ -10070,10 +10634,10 @@ async function beginSessionCloseAfterCurrentGate(session, timeoutMs) {
10070
10634
  }
10071
10635
  }
10072
10636
  __name(beginSessionCloseAfterCurrentGate, "beginSessionCloseAfterCurrentGate");
10073
- var logWorkspaceMemoryExtractionError = createWorkspaceMemoryExtractionErrorLogger(debugLogger7);
10637
+ var logWorkspaceMemoryExtractionError = createWorkspaceMemoryExtractionErrorLogger(debugLogger8);
10074
10638
  function parseAcpLocalReadRootsEnv(raw = process.env[QWEN_ACP_LOCAL_READ_ROOTS_ENV]) {
10075
10639
  if (!raw) return [];
10076
- return raw.split(path3.delimiter).map((entry) => entry.trim()).filter((entry) => entry.length > 0 && path3.isAbsolute(entry));
10640
+ return raw.split(path4.delimiter).map((entry) => entry.trim()).filter((entry) => entry.length > 0 && path4.isAbsolute(entry));
10077
10641
  }
10078
10642
  __name(parseAcpLocalReadRootsEnv, "parseAcpLocalReadRootsEnv");
10079
10643
  function defaultAcpOnlyLocalReadRoots() {
@@ -10086,8 +10650,8 @@ function buildAcpLocalReadRoots(config) {
10086
10650
  // including auto-memory roots. The ACP-only additions below expand only
10087
10651
  // local read fallback, not read_file's default permission.
10088
10652
  config.storage.getProjectTempDir(),
10089
- path3.join(config.storage.getProjectDir(), "subagents"),
10090
- path3.join(config.getSessionRuntimeBaseDir(), "tmp"),
10653
+ path4.join(config.storage.getProjectDir(), "subagents"),
10654
+ path4.join(config.getSessionRuntimeBaseDir(), "tmp"),
10091
10655
  getAutoMemoryRoot(config.getTargetDir()),
10092
10656
  getUserAutoMemoryRoot(),
10093
10657
  ...config.storage.getUserSkillsDirs(),
@@ -10387,7 +10951,7 @@ function readRequiredString(value, fieldName) {
10387
10951
  }
10388
10952
  __name(readRequiredString, "readRequiredString");
10389
10953
  function validateSkillSlug(slug) {
10390
- if (!slug || slug === "." || slug === ".." || slug.includes("/") || slug.includes(path3.sep) || !/^[a-zA-Z0-9._-]+$/.test(slug)) {
10954
+ if (!slug || slug === "." || slug === ".." || slug.includes("/") || slug.includes(path4.sep) || !/^[a-zA-Z0-9._-]+$/.test(slug)) {
10391
10955
  throw RequestError.invalidParams(void 0, "Invalid skill.slug");
10392
10956
  }
10393
10957
  }
@@ -10856,7 +11420,7 @@ async function downloadGitHubSkillDirectoryFromApi(githubUrl, directoryPath, rel
10856
11420
  const name = readRequiredString(record["name"], "github.name");
10857
11421
  const itemPath = readRequiredString(record["path"], "github.path");
10858
11422
  const type = readRequiredString(record["type"], "github.type");
10859
- const relativePath = relativeRoot ? path3.posix.join(relativeRoot, name) : name;
11423
+ const relativePath = relativeRoot ? path4.posix.join(relativeRoot, name) : name;
10860
11424
  if (type === "dir") {
10861
11425
  files.push(
10862
11426
  ...await downloadGitHubSkillDirectoryFromApi(
@@ -10903,7 +11467,7 @@ async function downloadGitHubSkillDirectory(githubUrl, directoryPath) {
10903
11467
  githubUrl,
10904
11468
  directoryPath
10905
11469
  ).catch((error) => {
10906
- debugLogger7.warn(
11470
+ debugLogger8.warn(
10907
11471
  "GitHub API directory listing failed, falling back to archive download:",
10908
11472
  error
10909
11473
  );
@@ -10916,10 +11480,10 @@ __name(downloadGitHubSkillDirectory, "downloadGitHubSkillDirectory");
10916
11480
  async function downloadSkill(sourceUrl) {
10917
11481
  assertAllowedSkillSourceUrl(sourceUrl);
10918
11482
  const githubUrl = parseGitHubBlobSkillUrl(sourceUrl);
10919
- if (!githubUrl || path3.posix.basename(githubUrl.filePath) !== "SKILL.md") {
11483
+ if (!githubUrl || path4.posix.basename(githubUrl.filePath) !== "SKILL.md") {
10920
11484
  return downloadSingleSkillFile(sourceUrl);
10921
11485
  }
10922
- const skillDirectory = path3.posix.dirname(githubUrl.filePath);
11486
+ const skillDirectory = path4.posix.dirname(githubUrl.filePath);
10923
11487
  const files = await downloadGitHubSkillDirectory(githubUrl, skillDirectory);
10924
11488
  const skillFile = files.find((file) => file.relativePath === "SKILL.md");
10925
11489
  if (!skillFile) {
@@ -10935,9 +11499,9 @@ async function downloadSkill(sourceUrl) {
10935
11499
  }
10936
11500
  __name(downloadSkill, "downloadSkill");
10937
11501
  function resolveSkillInstallPath(skillDir, relativePath) {
10938
- const root = path3.resolve(skillDir);
10939
- const target = path3.resolve(skillDir, relativePath);
10940
- if (target !== root && !target.startsWith(root + path3.sep)) {
11502
+ const root = path4.resolve(skillDir);
11503
+ const target = path4.resolve(skillDir, relativePath);
11504
+ if (target !== root && !target.startsWith(root + path4.sep)) {
10941
11505
  throw RequestError.invalidParams(
10942
11506
  void 0,
10943
11507
  `Invalid skill file path: ${relativePath}`
@@ -10947,9 +11511,9 @@ function resolveSkillInstallPath(skillDir, relativePath) {
10947
11511
  }
10948
11512
  __name(resolveSkillInstallPath, "resolveSkillInstallPath");
10949
11513
  function resolveManagedSkillDir(skillsBaseDir, slug) {
10950
- const root = path3.resolve(skillsBaseDir);
10951
- const skillDir = path3.resolve(skillsBaseDir, slug);
10952
- if (!skillDir.startsWith(root + path3.sep)) {
11514
+ const root = path4.resolve(skillsBaseDir);
11515
+ const skillDir = path4.resolve(skillsBaseDir, slug);
11516
+ if (!skillDir.startsWith(root + path4.sep)) {
10953
11517
  throw RequestError.invalidParams(void 0, "Invalid skill.slug");
10954
11518
  }
10955
11519
  return skillDir;
@@ -11469,7 +12033,7 @@ function readMcpServers(source, scope) {
11469
12033
  const server = toMcpServerConfig(value);
11470
12034
  return server ? { name, scope, server: redactMcpServerSecrets(server) } : void 0;
11471
12035
  } catch (error) {
11472
- debugLogger7.warn(
12036
+ debugLogger8.warn(
11473
12037
  `Skipping malformed MCP server config [${scope}:${name}]:`,
11474
12038
  error
11475
12039
  );
@@ -11565,7 +12129,7 @@ function readHooks(source, scope, extensionName) {
11565
12129
  extensionName
11566
12130
  });
11567
12131
  } catch (error) {
11568
- debugLogger7.warn(
12132
+ debugLogger8.warn(
11569
12133
  `Skipping malformed hook entry [${scope}:${event}:${index}]:`,
11570
12134
  error
11571
12135
  );
@@ -11590,14 +12154,14 @@ function readScopeSettings(settings, scope) {
11590
12154
  __name(readScopeSettings, "readScopeSettings");
11591
12155
  async function resolvePreferredMemoryFile(dir, fallbackFilename) {
11592
12156
  for (const filename of getAllGeminiMdFilenames()) {
11593
- const filePath = path3.join(dir, filename);
12157
+ const filePath = path4.join(dir, filename);
11594
12158
  try {
11595
- await fs.access(filePath);
12159
+ await fs2.access(filePath);
11596
12160
  return filePath;
11597
12161
  } catch {
11598
12162
  }
11599
12163
  }
11600
- return path3.join(dir, fallbackFilename);
12164
+ return path4.join(dir, fallbackFilename);
11601
12165
  }
11602
12166
  __name(resolvePreferredMemoryFile, "resolvePreferredMemoryFile");
11603
12167
  async function resolveQwenMemoryPaths(params) {
@@ -11867,7 +12431,7 @@ async function runAcpAgent(config, settings, argv, options) {
11867
12431
  void preloadContentGenerator(
11868
12432
  session.getConfig().getContentGenerator()
11869
12433
  ).catch((error) => {
11870
- debugLogger7.debug(
12434
+ debugLogger8.debug(
11871
12435
  `[ACP] Session provider preload failed for ${sessionId}: ${error instanceof Error ? error.message : String(error)}`
11872
12436
  );
11873
12437
  });
@@ -11908,7 +12472,7 @@ async function runAcpAgent(config, settings, argv, options) {
11908
12472
  try {
11909
12473
  await agentInstance.shutdownMcpPool(8e3);
11910
12474
  } catch (err) {
11911
- debugLogger7.error(`[ACP] MCP pool drain (${label}) error:`, err);
12475
+ debugLogger8.error(`[ACP] MCP pool drain (${label}) error:`, err);
11912
12476
  if (strict) throw err;
11913
12477
  }
11914
12478
  }, "drainPoolBeforeExit");
@@ -11941,7 +12505,7 @@ async function runAcpAgent(config, settings, argv, options) {
11941
12505
  await hookSystem.fireSessionEndEvent(reason);
11942
12506
  } catch (err) {
11943
12507
  if (managedConfigs) failures.push(err);
11944
- debugLogger7.warn(
12508
+ debugLogger8.warn(
11945
12509
  `SessionEnd hook failed: ${err instanceof Error ? err.message : String(err)}`
11946
12510
  );
11947
12511
  }
@@ -11965,13 +12529,13 @@ async function runAcpAgent(config, settings, argv, options) {
11965
12529
  await terminal.writerShutdown;
11966
12530
  } catch (error) {
11967
12531
  failures.push(error);
11968
- debugLogger7.error("[ACP] Managed writer shutdown error:", error);
12532
+ debugLogger8.error("[ACP] Managed writer shutdown error:", error);
11969
12533
  const retainedLockPaths = terminal.configs.flatMap((config2) => {
11970
12534
  if (typeof config2.getSessionRuntimeBaseDir !== "function" || typeof config2.getSessionId !== "function") {
11971
12535
  return [];
11972
12536
  }
11973
12537
  return [
11974
- path3.join(
12538
+ path4.join(
11975
12539
  config2.getSessionRuntimeBaseDir(),
11976
12540
  "tmp",
11977
12541
  "session-writer-locks",
@@ -11992,7 +12556,7 @@ async function runAcpAgent(config, settings, argv, options) {
11992
12556
  await agent.finishManagedShutdown(terminal.configs);
11993
12557
  } catch (error) {
11994
12558
  failures.push(error);
11995
- debugLogger7.error("[ACP] Managed resource shutdown error:", error);
12559
+ debugLogger8.error("[ACP] Managed resource shutdown error:", error);
11996
12560
  }
11997
12561
  try {
11998
12562
  await drainPoolBeforeExit(label, true);
@@ -12003,7 +12567,7 @@ async function runAcpAgent(config, settings, argv, options) {
12003
12567
  await runExitCleanup();
12004
12568
  } catch (error) {
12005
12569
  failures.push(error);
12006
- debugLogger7.error("[ACP] Cleanup error:", error);
12570
+ debugLogger8.error("[ACP] Cleanup error:", error);
12007
12571
  }
12008
12572
  if (failures.length > 0) {
12009
12573
  throw new AggregateError(failures, "Managed ACP shutdown failed");
@@ -12014,14 +12578,14 @@ async function runAcpAgent(config, settings, argv, options) {
12014
12578
  const shutdownHandler = /* @__PURE__ */ __name(async () => {
12015
12579
  if (shuttingDown) return;
12016
12580
  shuttingDown = true;
12017
- debugLogger7.debug("[ACP] Shutdown signal received, closing streams");
12581
+ debugLogger8.debug("[ACP] Shutdown signal received, closing streams");
12018
12582
  if (agentInstance?.isTrustedManagedParent()) {
12019
12583
  let exitCode = 0;
12020
12584
  try {
12021
12585
  await shutdownManagedAgent("other" /* Other */, "signal");
12022
12586
  } catch (err) {
12023
12587
  exitCode = 1;
12024
- debugLogger7.error("[ACP] Managed shutdown error:", err);
12588
+ debugLogger8.error("[ACP] Managed shutdown error:", err);
12025
12589
  } finally {
12026
12590
  eventLoopMonitor.dispose();
12027
12591
  }
@@ -12046,12 +12610,12 @@ async function runAcpAgent(config, settings, argv, options) {
12046
12610
  }
12047
12611
  await drainPoolBeforeExit("signal");
12048
12612
  } catch (err) {
12049
- debugLogger7.error("[ACP] Shutdown error:", err);
12613
+ debugLogger8.error("[ACP] Shutdown error:", err);
12050
12614
  } finally {
12051
12615
  eventLoopMonitor.dispose();
12052
12616
  }
12053
12617
  runExitCleanup().catch((err) => {
12054
- debugLogger7.error("[ACP] Cleanup error:", err);
12618
+ debugLogger8.error("[ACP] Cleanup error:", err);
12055
12619
  }).finally(() => {
12056
12620
  process.exit(0);
12057
12621
  });
@@ -12238,6 +12802,7 @@ var QwenAgent = class {
12238
12802
  __name(this, "QwenAgent");
12239
12803
  }
12240
12804
  sessions = /* @__PURE__ */ new Map();
12805
+ startingSessionIds = /* @__PURE__ */ new Set();
12241
12806
  activePromptCalls = /* @__PURE__ */ new Map();
12242
12807
  workspaceMcpDiscoveryConfig;
12243
12808
  workspaceMcpDiscoveryPromise;
@@ -12260,7 +12825,7 @@ var QwenAgent = class {
12260
12825
  // cadence, so successive calls form a clean delta window independent of tool
12261
12826
  // activity. Init is guarded — `process.cpuUsage()` can throw in restricted
12262
12827
  // containers.
12263
- childCpuCoreCount = os2.availableParallelism?.() ?? os2.cpus().length ?? 1;
12828
+ childCpuCoreCount = os3.availableParallelism?.() ?? os3.cpus().length ?? 1;
12264
12829
  prevChildCpu = (() => {
12265
12830
  try {
12266
12831
  return process.cpuUsage();
@@ -12326,12 +12891,12 @@ var QwenAgent = class {
12326
12891
  try {
12327
12892
  session.beginCloseIfAvailable();
12328
12893
  } catch (error) {
12329
- debugLogger7.debug(
12894
+ debugLogger8.debug(
12330
12895
  `Session ${session.getId()} admission close during managed shutdown failed: ${error instanceof Error ? error.message : String(error)}`
12331
12896
  );
12332
12897
  }
12333
12898
  void session.cancelPendingPrompt().catch((error) => {
12334
- debugLogger7.debug(
12899
+ debugLogger8.debug(
12335
12900
  `Session ${session.getId()} cancel during managed shutdown failed: ${error instanceof Error ? error.message : String(error)}`
12336
12901
  );
12337
12902
  });
@@ -12479,7 +13044,7 @@ var QwenAgent = class {
12479
13044
  await run();
12480
13045
  }).catch((err) => {
12481
13046
  this.workspaceMcpDiscoveryError = err instanceof Error ? err.message : String(err);
12482
- debugLogger7.error(
13047
+ debugLogger8.error(
12483
13048
  `Workspace MCP ${label} failed: ${err instanceof Error ? err.message : String(err)}`
12484
13049
  );
12485
13050
  }).finally(() => {
@@ -12666,7 +13231,7 @@ var QwenAgent = class {
12666
13231
  try {
12667
13232
  const result = await this.mcpPool.drainAll({ force: true, timeoutMs });
12668
13233
  if (result.forced > 0 || result.errors.length > 0) {
12669
- debugLogger7.warn(
13234
+ debugLogger8.warn(
12670
13235
  `MCP pool drain: ${result.drained} clean, ${result.forced} timed out, ${result.errors.length} errors`
12671
13236
  );
12672
13237
  throw new Error(
@@ -12674,7 +13239,7 @@ var QwenAgent = class {
12674
13239
  );
12675
13240
  }
12676
13241
  } catch (err) {
12677
- debugLogger7.error(
13242
+ debugLogger8.error(
12678
13243
  `MCP pool drainAll failed: ${err instanceof Error ? err.message : String(err)}`
12679
13244
  );
12680
13245
  throw err;
@@ -12712,7 +13277,7 @@ var QwenAgent = class {
12712
13277
  this.sessions.delete(sessionId);
12713
13278
  this.activeWorkReporter?.notifyChanged();
12714
13279
  if (cleanupErrors.length > 0) {
12715
- debugLogger7.warn(
13280
+ debugLogger8.warn(
12716
13281
  `Session ${sessionId} closed after ${cleanupErrors.length} cleanup failure(s): ${cleanupErrors.map(
12717
13282
  (error) => error instanceof Error ? error.message : String(error)
12718
13283
  ).join("; ")}`
@@ -12766,21 +13331,21 @@ var QwenAgent = class {
12766
13331
  try {
12767
13332
  await cleanup();
12768
13333
  } catch (cleanupError) {
12769
- debugLogger7.warn(
13334
+ debugLogger8.warn(
12770
13335
  `Session cleanup failed while preserving the original request error: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`
12771
13336
  );
12772
13337
  }
12773
13338
  throw mapSessionWriterRequestError(error);
12774
13339
  }
12775
13340
  pendingConfigCleanupKey(runtimeBaseDir, sessionId) {
12776
- return `${path3.resolve(runtimeBaseDir)}\0${sessionId}`;
13341
+ return `${path4.resolve(runtimeBaseDir)}\0${sessionId}`;
12777
13342
  }
12778
13343
  async retryPendingConfigCleanup(runtimeBaseDir, requiredSessionId) {
12779
- const resolvedRuntimeBaseDir = path3.resolve(runtimeBaseDir);
13344
+ const resolvedRuntimeBaseDir = path4.resolve(runtimeBaseDir);
12780
13345
  const configs = /* @__PURE__ */ new Set();
12781
13346
  for (const pending of this.pendingConfigCleanup.values()) {
12782
13347
  for (const config of pending) {
12783
- if (path3.resolve(config.getSessionRuntimeBaseDir()) === resolvedRuntimeBaseDir) {
13348
+ if (path4.resolve(config.getSessionRuntimeBaseDir()) === resolvedRuntimeBaseDir) {
12784
13349
  configs.add(config);
12785
13350
  }
12786
13351
  }
@@ -12790,7 +13355,7 @@ var QwenAgent = class {
12790
13355
  await this.cleanupUnstoredConfig(config);
12791
13356
  } catch (error) {
12792
13357
  if (config.getSessionId() === requiredSessionId) throw error;
12793
- debugLogger7.warn(
13358
+ debugLogger8.warn(
12794
13359
  `Deferred Config cleanup retry failed for session ${config.getSessionId()}: ${error instanceof Error ? error.message : String(error)}`
12795
13360
  );
12796
13361
  }
@@ -12828,7 +13393,7 @@ var QwenAgent = class {
12828
13393
  try {
12829
13394
  await session.cancelPendingPrompt();
12830
13395
  } catch (err) {
12831
- debugLogger7.debug(
13396
+ debugLogger8.debug(
12832
13397
  `Session ${sessionId} cancel during close failed: ${err instanceof Error ? err.message : String(err)}`
12833
13398
  );
12834
13399
  }
@@ -12901,7 +13466,7 @@ var QwenAgent = class {
12901
13466
  return runWithAcpRuntimeOutputDir(settings, cwd, operation);
12902
13467
  }
12903
13468
  async assertLiveSessionScope(config, settings, cwd) {
12904
- if (path3.resolve(config.storage.getProjectRoot()) !== path3.resolve(cwd)) {
13469
+ if (path4.resolve(config.storage.getProjectRoot()) !== path4.resolve(cwd)) {
12905
13470
  throw RequestError.invalidParams(
12906
13471
  void 0,
12907
13472
  "The live session belongs to another workspace."
@@ -12912,7 +13477,7 @@ var QwenAgent = class {
12912
13477
  cwd,
12913
13478
  () => Storage.getRuntimeBaseDir()
12914
13479
  );
12915
- if (path3.resolve(config.getSessionRuntimeBaseDir()) !== path3.resolve(requestedRuntimeBaseDir)) {
13480
+ if (path4.resolve(config.getSessionRuntimeBaseDir()) !== path4.resolve(requestedRuntimeBaseDir)) {
12916
13481
  throw mapSessionWriterRequestError(new SessionWriterUnavailableError());
12917
13482
  }
12918
13483
  }
@@ -12935,7 +13500,7 @@ var QwenAgent = class {
12935
13500
  scope: "workspace",
12936
13501
  ...event
12937
13502
  }).catch((err) => {
12938
- debugLogger7.debug(
13503
+ debugLogger8.debug(
12939
13504
  `MCP workspace budget event delivery to session ${sid} failed (kind=${event.kind}): ${err instanceof Error ? err.message : String(err)}`
12940
13505
  );
12941
13506
  });
@@ -12970,7 +13535,7 @@ var QwenAgent = class {
12970
13535
  }
12971
13536
  this.clientCapabilities = args.clientCapabilities;
12972
13537
  const authMethods = buildAuthMethods();
12973
- const version = "0.21.8";
13538
+ const version = "0.21.9";
12974
13539
  const response = {
12975
13540
  protocolVersion: PROTOCOL_VERSION,
12976
13541
  agentInfo: {
@@ -13063,312 +13628,452 @@ var QwenAgent = class {
13063
13628
  }
13064
13629
  }
13065
13630
  }
13631
+ reserveStartingSessionId(sessionId) {
13632
+ if (this.sessions.has(sessionId) || this.startingSessionIds.has(sessionId)) {
13633
+ throw new RequestError(
13634
+ ACP_ERROR_CODES.INVALID_PARAMS,
13635
+ `Session ${sessionId} is already active or starting.`,
13636
+ { errorKind: "session_id_conflict", sessionId }
13637
+ );
13638
+ }
13639
+ this.startingSessionIds.add(sessionId);
13640
+ let released = false;
13641
+ return () => {
13642
+ if (released) return;
13643
+ released = true;
13644
+ this.startingSessionIds.delete(sessionId);
13645
+ };
13646
+ }
13066
13647
  async newSession(params) {
13067
13648
  const { cwd, mcpServers } = params;
13068
- const requestedSessionId = typeof params._meta?.[REQUESTED_SESSION_ID_META_KEY] === "string" ? params._meta[REQUESTED_SESSION_ID_META_KEY] : void 0;
13069
- const sessionSource = getSessionSource(params);
13070
- const parentContext = extractDaemonTraceContext(params);
13071
- return await withDaemonSpan(
13072
- "qwen-code.daemon.session_start",
13073
- { "qwen-code.daemon.operation": "acp_session_new" },
13074
- async (span) => {
13075
- const profiler = createAcpSessionStartProfiler(span);
13076
- const settings = profiler.timeSync(
13077
- "settings_load",
13078
- () => loadSettingsCached(cwd)
13079
- );
13080
- this.settings = settings;
13081
- const config = await profiler.time(
13082
- "config_setup",
13083
- () => this.newSessionConfig(
13084
- cwd,
13085
- mcpServers,
13086
- settings,
13087
- sessionSource,
13088
- requestedSessionId,
13089
- void 0,
13090
- shouldDeferMcpDiscovery(params) ? { skipMcpDiscovery: true } : void 0
13091
- )
13092
- );
13093
- let session;
13094
- try {
13095
- await profiler.time("auth", () => this.ensureAuthenticated(config));
13096
- profiler.timeSync(
13097
- "file_system_setup",
13098
- () => this.setupFileSystem(config)
13649
+ const parsedSessionId = parseCallerSuppliedSessionId(
13650
+ params._meta?.[REQUESTED_SESSION_ID_META_KEY]
13651
+ );
13652
+ if (parsedSessionId.kind === "invalid") {
13653
+ throw new RequestError(
13654
+ ACP_ERROR_CODES.INVALID_PARAMS,
13655
+ `\`_meta["${REQUESTED_SESSION_ID_META_KEY}"]\` must be an RFC UUID v1-v5`,
13656
+ { errorKind: "invalid_session_id", httpStatus: 400 }
13657
+ );
13658
+ }
13659
+ const requestedSessionId = parsedSessionId.kind === "valid" ? parsedSessionId.sessionId : void 0;
13660
+ const releaseStartingSessionId = requestedSessionId ? this.reserveStartingSessionId(requestedSessionId) : void 0;
13661
+ try {
13662
+ const sessionSource = getSessionSource(params);
13663
+ const parentContext = extractDaemonTraceContext(params);
13664
+ return await withDaemonSpan(
13665
+ "qwen-code.daemon.session_start",
13666
+ { "qwen-code.daemon.operation": "acp_session_new" },
13667
+ async (span) => {
13668
+ const profiler = createAcpSessionStartProfiler(span);
13669
+ const settings = profiler.timeSync(
13670
+ "settings_load",
13671
+ () => loadSettingsCached(cwd)
13099
13672
  );
13100
- session = await profiler.time(
13101
- "session_register",
13102
- () => this.createAndStoreSession(config, settings)
13673
+ this.settings = settings;
13674
+ const config = await profiler.time(
13675
+ "config_setup",
13676
+ () => this.newSessionConfig(
13677
+ cwd,
13678
+ mcpServers,
13679
+ settings,
13680
+ sessionSource,
13681
+ requestedSessionId,
13682
+ void 0,
13683
+ shouldDeferMcpDiscovery(params) ? { skipMcpDiscovery: true } : void 0
13684
+ )
13103
13685
  );
13104
- } catch (error) {
13105
- return this.cleanupAfterRequestFailure(error, async () => {
13106
- if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
13107
- await this.cleanupUnstoredConfig(config);
13108
- }
13109
- });
13110
- }
13111
- profiler.setSessionId(session.getId());
13112
- return profiler.timeSync("response_build", () => ({
13113
- sessionId: session.getId(),
13114
- models: this.buildAvailableModels(config),
13115
- modes: this.buildModesData(config),
13116
- configOptions: this.buildConfigOptions(config)
13117
- }));
13686
+ let session;
13687
+ try {
13688
+ await profiler.time("auth", () => this.ensureAuthenticated(config));
13689
+ profiler.timeSync(
13690
+ "file_system_setup",
13691
+ () => this.setupFileSystem(config)
13692
+ );
13693
+ session = await profiler.time(
13694
+ "session_register",
13695
+ () => this.createAndStoreSession(config, settings)
13696
+ );
13697
+ } catch (error) {
13698
+ return this.cleanupAfterRequestFailure(error, async () => {
13699
+ if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
13700
+ await this.cleanupUnstoredConfig(config);
13701
+ }
13702
+ });
13703
+ }
13704
+ profiler.setSessionId(session.getId());
13705
+ return profiler.timeSync("response_build", () => ({
13706
+ sessionId: session.getId(),
13707
+ models: this.buildAvailableModels(config),
13708
+ modes: this.buildModesData(config),
13709
+ configOptions: this.buildConfigOptions(config)
13710
+ }));
13711
+ },
13712
+ parentContext ? { parentContext } : {}
13713
+ );
13714
+ } finally {
13715
+ releaseStartingSessionId?.();
13716
+ }
13717
+ }
13718
+ async loadSession(params) {
13719
+ const sessionId = normalizeSessionIdForLookup(params.sessionId);
13720
+ const parentContext = extractDaemonTraceContext(params);
13721
+ return await withDaemonSpan(
13722
+ "qwen-code.daemon.session_restore",
13723
+ {
13724
+ "qwen-code.daemon.operation": "acp_session_load",
13725
+ "qwen-code.daemon.session_restore.action": "load",
13726
+ "session.id": sessionId
13118
13727
  },
13728
+ async (span) => this.loadSessionWithProfiler(
13729
+ params,
13730
+ sessionId,
13731
+ createAcpSessionRestoreProfiler(span)
13732
+ ),
13119
13733
  parentContext ? { parentContext } : {}
13120
13734
  );
13121
13735
  }
13122
- async loadSession(params) {
13736
+ async loadSessionWithProfiler(params, initialSessionId, profiler) {
13737
+ let sessionId = initialSessionId;
13123
13738
  const sessionSource = getSessionSource(params);
13124
- const settings = loadSettingsCached(params.cwd);
13125
- const liveSession = this.sessions.get(params.sessionId);
13739
+ const liveSession = this.sessions.get(sessionId);
13126
13740
  if (liveSession) {
13741
+ const settings = profiler.timeSync(
13742
+ "settings_load",
13743
+ () => loadSettingsCached(params.cwd)
13744
+ );
13127
13745
  const liveConfig = liveSession.getConfig();
13128
- await this.assertLiveSessionScope(liveConfig, settings, params.cwd);
13129
- return this.withLiveSessionRestore(
13130
- params.sessionId,
13131
- liveSession,
13132
- async (config2, sessionData2) => {
13133
- const response2 = {
13134
- modes: this.buildModesData(config2),
13135
- models: this.buildAvailableModels(config2),
13136
- configOptions: this.buildConfigOptions(config2),
13137
- ...sessionData2.artifactSnapshot ? { artifactSnapshot: sessionData2.artifactSnapshot } : {}
13138
- };
13139
- const records = sessionData2.conversation.messages;
13140
- const visibleRecords = selectVisibleHistoryRecords(
13141
- records,
13142
- shouldHideInheritedHistory(params)
13143
- );
13144
- if (visibleRecords.length === 0) return response2;
13145
- const bulkReplay2 = isBulkLoadReplayRequest(params);
13146
- const replayPage = bulkReplay2 ? selectRecentHistoryRecords(
13147
- visibleRecords,
13148
- getLoadReplayPageSize(params)
13149
- ) : { records: visibleRecords, hasMore: false };
13150
- const replay = await collectHistoryReplayUpdates({
13151
- sessionId: params.sessionId,
13152
- config: config2,
13153
- records: replayPage.records,
13154
- gaps: sessionData2.historyGaps,
13155
- cumulativeUsage: createReplayCumulativeUsage(),
13156
- logger: debugLogger7
13157
- });
13158
- if (!bulkReplay2) {
13159
- try {
13160
- for (const update of replay.updates) {
13161
- await liveSession.sendUpdate(update);
13746
+ return profiler.time("live_restore", async () => {
13747
+ await this.assertLiveSessionScope(liveConfig, settings, params.cwd);
13748
+ return this.withLiveSessionRestore(
13749
+ sessionId,
13750
+ liveSession,
13751
+ async (config, sessionData) => {
13752
+ const response = profiler.timeSync(
13753
+ "response_build",
13754
+ () => ({
13755
+ modes: this.buildModesData(config),
13756
+ models: this.buildAvailableModels(config),
13757
+ configOptions: this.buildConfigOptions(config),
13758
+ ...sessionData.artifactSnapshot ? { artifactSnapshot: sessionData.artifactSnapshot } : {}
13759
+ })
13760
+ );
13761
+ const records = sessionData.conversation.messages;
13762
+ const visibleRecords = selectVisibleHistoryRecords(
13763
+ records,
13764
+ shouldHideInheritedHistory(params)
13765
+ );
13766
+ if (visibleRecords.length === 0) return response;
13767
+ const bulkReplay = isBulkLoadReplayRequest(params);
13768
+ const replayPage = bulkReplay ? selectRecentHistoryRecords(
13769
+ visibleRecords,
13770
+ getLoadReplayPageSize(params)
13771
+ ) : { records: visibleRecords, hasMore: false };
13772
+ const replay = await collectHistoryReplayUpdates({
13773
+ sessionId,
13774
+ config,
13775
+ records: replayPage.records,
13776
+ gaps: sessionData.historyGaps,
13777
+ cumulativeUsage: createReplayCumulativeUsage(),
13778
+ logger: debugLogger8
13779
+ });
13780
+ if (!bulkReplay) {
13781
+ try {
13782
+ for (const update of replay.updates) {
13783
+ await liveSession.sendUpdate(update);
13784
+ }
13785
+ } finally {
13786
+ liveSession.clearActiveTodoPlanRevision();
13162
13787
  }
13163
- } finally {
13164
- liveSession.clearActiveTodoPlanRevision();
13165
- }
13166
- if (replay.replayError !== void 0) {
13167
- throw RequestError.internalError(void 0, replay.replayError);
13168
- }
13169
- return response2;
13170
- }
13171
- return {
13172
- ...response2,
13173
- _meta: {
13174
- [LOAD_REPLAY_META_KEY]: {
13175
- v: LOAD_REPLAY_VERSION,
13176
- updates: replay.updates,
13177
- ...replay.replayError !== void 0 ? { partial: true, replayError: replay.replayError } : {},
13178
- ...replayPage.hasMore ? { hasMore: true } : {}
13788
+ if (replay.replayError !== void 0) {
13789
+ throw RequestError.internalError(void 0, replay.replayError);
13179
13790
  }
13791
+ return response;
13180
13792
  }
13181
- };
13182
- }
13183
- );
13184
- }
13185
- const exists = await this.runWithPinnedRuntimeBaseDir(
13186
- settings,
13187
- params.cwd,
13188
- async () => {
13189
- const sessionService = new SessionService(params.cwd);
13190
- return sessionService.sessionExists(params.sessionId);
13191
- }
13192
- );
13193
- if (!exists) {
13194
- throw RequestError.resourceNotFound(`session:${params.sessionId}`);
13195
- }
13196
- this.settings = settings;
13197
- const config = await this.newSessionConfig(
13198
- params.cwd,
13199
- // `LoadSessionRequest.mcpServers` is required in today's ACP
13200
- // schema, but mirror `unstable_resumeSession` and tolerate a
13201
- // future loosening — `newSessionConfig` iterates the list, so
13202
- // a `null`/`undefined` would otherwise throw `TypeError`.
13203
- params.mcpServers ?? [],
13204
- settings,
13205
- sessionSource,
13206
- params.sessionId,
13207
- true
13208
- );
13209
- const sessionData = config.getResumedSessionData();
13210
- const bulkReplay = isBulkLoadReplayRequest(params);
13211
- const replayPageSize = bulkReplay ? getLoadReplayPageSize(params) : void 0;
13212
- let replayEnvelope;
13213
- try {
13214
- await this.ensureAuthenticated(config);
13215
- this.setupFileSystem(config);
13216
- await this.createAndStoreSession(config, settings, sessionData, {
13217
- enableLiveScreenContext: isCompatibleLiveSessionSource(
13218
- sessionSource ?? {}
13219
- ),
13220
- ...bulkReplay ? { replayHistory: false } : {},
13221
- beforeStartPostReplayServices: /* @__PURE__ */ __name(async (createdSession) => {
13222
- if (bulkReplay) {
13223
- const records = sessionData?.conversation.messages;
13224
- let replayUpdates = [];
13225
- if (records) {
13226
- createdSession.primeTurnFromHistory(records);
13227
- const visibleRecords = selectVisibleHistoryRecords(
13228
- records,
13229
- shouldHideInheritedHistory(params)
13230
- );
13231
- const replayPage = selectRecentHistoryRecords(
13232
- visibleRecords,
13233
- replayPageSize
13234
- );
13235
- const replayUsage = createReplayCumulativeUsage();
13236
- const replay = await collectHistoryReplayUpdates({
13237
- sessionId: params.sessionId,
13238
- config,
13239
- records: replayPage.records,
13240
- gaps: sessionData?.historyGaps,
13241
- cumulativeUsage: replayUsage,
13242
- supersedeUnrestorableGoal: true,
13243
- logger: debugLogger7
13244
- });
13245
- replayUpdates = replay.updates;
13246
- copyCumulativeUsage(createdSession.cumulativeUsage, replayUsage);
13247
- if (replay.replayError !== void 0) {
13248
- replayEnvelope = {
13793
+ return {
13794
+ ...response,
13795
+ _meta: {
13796
+ [LOAD_REPLAY_META_KEY]: {
13249
13797
  v: LOAD_REPLAY_VERSION,
13250
- updates: replayUpdates,
13251
- partial: true,
13252
- replayError: replay.replayError,
13798
+ updates: replay.updates,
13799
+ ...replay.replayError !== void 0 ? {
13800
+ partial: true,
13801
+ replayError: replay.replayError
13802
+ } : {},
13253
13803
  ...replayPage.hasMore ? { hasMore: true } : {}
13254
- };
13804
+ }
13255
13805
  }
13256
- replayEnvelope ??= {
13257
- v: LOAD_REPLAY_VERSION,
13258
- updates: replayUpdates,
13259
- ...replayPage.hasMore ? { hasMore: true } : {}
13260
- };
13261
- }
13262
- replayEnvelope ??= {
13263
- v: LOAD_REPLAY_VERSION,
13264
- updates: replayUpdates
13265
13806
  };
13266
13807
  }
13267
- await this.#restoreWorktreeOnResume(config, createdSession);
13268
- await this.#restoreBackgroundAgentsOnResume(config, createdSession);
13269
- this.#restoreGoalOnResume(config, createdSession);
13270
- }, "beforeStartPostReplayServices")
13271
- });
13272
- } catch (error) {
13273
- return this.cleanupAfterRequestFailure(error, async () => {
13274
- if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
13275
- await this.cleanupUnstoredConfig(config);
13276
- }
13808
+ );
13277
13809
  });
13278
13810
  }
13279
- const modesData = this.buildModesData(config);
13280
- const availableModels = this.buildAvailableModels(config);
13281
- const configOptions = this.buildConfigOptions(config);
13282
- const response = {
13283
- modes: modesData,
13284
- models: availableModels,
13285
- configOptions,
13286
- ...sessionData?.artifactSnapshot ? { artifactSnapshot: sessionData.artifactSnapshot } : {}
13287
- };
13288
- if (!replayEnvelope) {
13289
- return response;
13290
- }
13291
- return {
13292
- ...response,
13293
- _meta: {
13294
- [LOAD_REPLAY_META_KEY]: replayEnvelope
13811
+ const releaseStartingSessionId = this.reserveStartingSessionId(sessionId);
13812
+ try {
13813
+ const settings = profiler.timeSync(
13814
+ "settings_load",
13815
+ () => loadSettingsCached(params.cwd)
13816
+ );
13817
+ const persistedSessionId = await profiler.time(
13818
+ "existence_check",
13819
+ () => this.runWithPinnedRuntimeBaseDir(settings, params.cwd, async () => {
13820
+ const sessionService = new SessionService(params.cwd);
13821
+ if (await sessionService.sessionExists(sessionId)) {
13822
+ return sessionId;
13823
+ }
13824
+ return sessionService.findSessionIdIgnoringCase?.(sessionId);
13825
+ })
13826
+ );
13827
+ if (!persistedSessionId) {
13828
+ profiler.fail("existence_check");
13829
+ throw RequestError.resourceNotFound(`session:${sessionId}`);
13830
+ }
13831
+ sessionId = persistedSessionId;
13832
+ profiler.setSessionId(sessionId);
13833
+ this.settings = settings;
13834
+ const config = await profiler.time(
13835
+ "config_setup",
13836
+ () => this.newSessionConfig(
13837
+ params.cwd,
13838
+ // `LoadSessionRequest.mcpServers` is required in today's ACP
13839
+ // schema, but mirror `unstable_resumeSession` and tolerate a
13840
+ // future loosening — `newSessionConfig` iterates the list, so
13841
+ // a `null`/`undefined` would otherwise throw `TypeError`.
13842
+ params.mcpServers ?? [],
13843
+ settings,
13844
+ sessionSource,
13845
+ sessionId,
13846
+ true
13847
+ )
13848
+ );
13849
+ const sessionData = config.getResumedSessionData();
13850
+ const bulkReplay = isBulkLoadReplayRequest(params);
13851
+ const replayPageSize = bulkReplay ? getLoadReplayPageSize(params) : void 0;
13852
+ let replayEnvelope;
13853
+ try {
13854
+ await profiler.time("auth", () => this.ensureAuthenticated(config));
13855
+ profiler.timeSync(
13856
+ "file_system_setup",
13857
+ () => this.setupFileSystem(config)
13858
+ );
13859
+ await profiler.time(
13860
+ "session_register",
13861
+ () => this.createAndStoreSession(config, settings, sessionData, {
13862
+ enableLiveScreenContext: isCompatibleLiveSessionSource(
13863
+ sessionSource ?? {}
13864
+ ),
13865
+ ...bulkReplay ? { replayHistory: false } : {},
13866
+ beforeStartPostReplayServices: /* @__PURE__ */ __name(async (createdSession) => {
13867
+ if (bulkReplay) {
13868
+ const records = sessionData?.conversation.messages;
13869
+ let replayUpdates = [];
13870
+ if (records) {
13871
+ createdSession.primeTurnFromHistory(records);
13872
+ const visibleRecords = selectVisibleHistoryRecords(
13873
+ records,
13874
+ shouldHideInheritedHistory(params)
13875
+ );
13876
+ const replayPage = selectRecentHistoryRecords(
13877
+ visibleRecords,
13878
+ replayPageSize
13879
+ );
13880
+ const replayUsage = createReplayCumulativeUsage();
13881
+ const replay = await collectHistoryReplayUpdates({
13882
+ sessionId,
13883
+ config,
13884
+ records: replayPage.records,
13885
+ gaps: sessionData?.historyGaps,
13886
+ cumulativeUsage: replayUsage,
13887
+ supersedeUnrestorableGoal: true,
13888
+ logger: debugLogger8
13889
+ });
13890
+ replayUpdates = replay.updates;
13891
+ copyCumulativeUsage(
13892
+ createdSession.cumulativeUsage,
13893
+ replayUsage
13894
+ );
13895
+ if (replay.replayError !== void 0) {
13896
+ replayEnvelope = {
13897
+ v: LOAD_REPLAY_VERSION,
13898
+ updates: replayUpdates,
13899
+ partial: true,
13900
+ replayError: replay.replayError,
13901
+ ...replayPage.hasMore ? { hasMore: true } : {}
13902
+ };
13903
+ }
13904
+ replayEnvelope ??= {
13905
+ v: LOAD_REPLAY_VERSION,
13906
+ updates: replayUpdates,
13907
+ ...replayPage.hasMore ? { hasMore: true } : {}
13908
+ };
13909
+ }
13910
+ replayEnvelope ??= {
13911
+ v: LOAD_REPLAY_VERSION,
13912
+ updates: replayUpdates
13913
+ };
13914
+ }
13915
+ await this.#restoreWorktreeOnResume(config, createdSession);
13916
+ await this.#restoreBackgroundAgentsOnResume(
13917
+ config,
13918
+ createdSession
13919
+ );
13920
+ this.#restoreGoalOnResume(config, createdSession);
13921
+ }, "beforeStartPostReplayServices")
13922
+ })
13923
+ );
13924
+ } catch (error) {
13925
+ return this.cleanupAfterRequestFailure(error, async () => {
13926
+ if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
13927
+ await this.cleanupUnstoredConfig(config);
13928
+ }
13929
+ });
13295
13930
  }
13296
- };
13931
+ return profiler.timeSync("response_build", () => {
13932
+ const response = {
13933
+ modes: this.buildModesData(config),
13934
+ models: this.buildAvailableModels(config),
13935
+ configOptions: this.buildConfigOptions(config),
13936
+ ...sessionData?.artifactSnapshot ? { artifactSnapshot: sessionData.artifactSnapshot } : {}
13937
+ };
13938
+ if (!replayEnvelope) return response;
13939
+ return {
13940
+ ...response,
13941
+ _meta: {
13942
+ [LOAD_REPLAY_META_KEY]: replayEnvelope
13943
+ }
13944
+ };
13945
+ });
13946
+ } finally {
13947
+ releaseStartingSessionId();
13948
+ }
13297
13949
  }
13298
13950
  async unstable_resumeSession(params) {
13951
+ const sessionId = normalizeSessionIdForLookup(params.sessionId);
13952
+ const parentContext = extractDaemonTraceContext(params);
13953
+ return await withDaemonSpan(
13954
+ "qwen-code.daemon.session_restore",
13955
+ {
13956
+ "qwen-code.daemon.operation": "acp_session_resume",
13957
+ "qwen-code.daemon.session_restore.action": "resume",
13958
+ "session.id": sessionId
13959
+ },
13960
+ async (span) => this.resumeSessionWithProfiler(
13961
+ params,
13962
+ sessionId,
13963
+ createAcpSessionRestoreProfiler(span)
13964
+ ),
13965
+ parentContext ? { parentContext } : {}
13966
+ );
13967
+ }
13968
+ async resumeSessionWithProfiler(params, initialSessionId, profiler) {
13969
+ let sessionId = initialSessionId;
13299
13970
  const sessionSource = getSessionSource(params);
13300
- const settings = loadSettingsCached(params.cwd);
13301
- const liveSession = this.sessions.get(params.sessionId);
13971
+ const liveSession = this.sessions.get(sessionId);
13302
13972
  if (liveSession) {
13973
+ const settings = profiler.timeSync(
13974
+ "settings_load",
13975
+ () => loadSettingsCached(params.cwd)
13976
+ );
13303
13977
  const liveConfig = liveSession.getConfig();
13304
- await this.assertLiveSessionScope(liveConfig, settings, params.cwd);
13305
- return this.withLiveSessionRestore(
13306
- params.sessionId,
13307
- liveSession,
13308
- async (config2, sessionData2) => ({
13309
- modes: this.buildModesData(config2),
13310
- models: this.buildAvailableModels(config2),
13311
- configOptions: this.buildConfigOptions(config2),
13312
- ...sessionData2.artifactSnapshot ? { artifactSnapshot: sessionData2.artifactSnapshot } : {}
13978
+ return profiler.time("live_restore", async () => {
13979
+ await this.assertLiveSessionScope(liveConfig, settings, params.cwd);
13980
+ return this.withLiveSessionRestore(
13981
+ sessionId,
13982
+ liveSession,
13983
+ async (config, sessionData) => profiler.timeSync(
13984
+ "response_build",
13985
+ () => ({
13986
+ modes: this.buildModesData(config),
13987
+ models: this.buildAvailableModels(config),
13988
+ configOptions: this.buildConfigOptions(config),
13989
+ ...sessionData.artifactSnapshot ? { artifactSnapshot: sessionData.artifactSnapshot } : {}
13990
+ })
13991
+ )
13992
+ );
13993
+ });
13994
+ }
13995
+ const releaseStartingSessionId = this.reserveStartingSessionId(sessionId);
13996
+ try {
13997
+ const settings = profiler.timeSync(
13998
+ "settings_load",
13999
+ () => loadSettingsCached(params.cwd)
14000
+ );
14001
+ const persistedSessionId = await profiler.time(
14002
+ "existence_check",
14003
+ () => this.runWithPinnedRuntimeBaseDir(settings, params.cwd, async () => {
14004
+ const sessionService = new SessionService(params.cwd);
14005
+ if (await sessionService.sessionExists(sessionId)) {
14006
+ return sessionId;
14007
+ }
14008
+ return sessionService.findSessionIdIgnoringCase?.(sessionId);
13313
14009
  })
13314
14010
  );
13315
- }
13316
- const exists = await this.runWithPinnedRuntimeBaseDir(
13317
- settings,
13318
- params.cwd,
13319
- async () => {
13320
- const sessionService = new SessionService(params.cwd);
13321
- return sessionService.sessionExists(params.sessionId);
14011
+ if (!persistedSessionId) {
14012
+ profiler.fail("existence_check");
14013
+ throw RequestError.resourceNotFound(`session:${sessionId}`);
14014
+ }
14015
+ sessionId = persistedSessionId;
14016
+ profiler.setSessionId(sessionId);
14017
+ this.settings = settings;
14018
+ const config = await profiler.time(
14019
+ "config_setup",
14020
+ () => this.newSessionConfig(
14021
+ params.cwd,
14022
+ params.mcpServers ?? [],
14023
+ settings,
14024
+ sessionSource,
14025
+ sessionId,
14026
+ true
14027
+ )
14028
+ );
14029
+ try {
14030
+ await profiler.time("auth", () => this.ensureAuthenticated(config));
14031
+ profiler.timeSync(
14032
+ "file_system_setup",
14033
+ () => this.setupFileSystem(config)
14034
+ );
14035
+ await profiler.time(
14036
+ "session_register",
14037
+ () => this.createAndStoreSession(
14038
+ config,
14039
+ settings,
14040
+ config.getResumedSessionData(),
14041
+ {
14042
+ enableLiveScreenContext: isCompatibleLiveSessionSource(
14043
+ sessionSource ?? {}
14044
+ ),
14045
+ replayHistory: false,
14046
+ beforeStartPostReplayServices: /* @__PURE__ */ __name(async (createdSession) => {
14047
+ await this.#restoreWorktreeOnResume(config, createdSession);
14048
+ await this.#restoreBackgroundAgentsOnResume(
14049
+ config,
14050
+ createdSession
14051
+ );
14052
+ this.#restoreGoalOnResume(config, createdSession);
14053
+ }, "beforeStartPostReplayServices")
14054
+ }
14055
+ )
14056
+ );
14057
+ } catch (error) {
14058
+ return this.cleanupAfterRequestFailure(error, async () => {
14059
+ if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
14060
+ await this.cleanupUnstoredConfig(config);
14061
+ }
14062
+ });
13322
14063
  }
13323
- );
13324
- if (!exists) {
13325
- throw RequestError.resourceNotFound(`session:${params.sessionId}`);
13326
- }
13327
- this.settings = settings;
13328
- const config = await this.newSessionConfig(
13329
- params.cwd,
13330
- params.mcpServers ?? [],
13331
- settings,
13332
- sessionSource,
13333
- params.sessionId,
13334
- true
13335
- );
13336
- try {
13337
- await this.ensureAuthenticated(config);
13338
- this.setupFileSystem(config);
13339
- await this.createAndStoreSession(
13340
- config,
13341
- settings,
13342
- config.getResumedSessionData(),
13343
- {
13344
- enableLiveScreenContext: isCompatibleLiveSessionSource(
13345
- sessionSource ?? {}
13346
- ),
13347
- replayHistory: false,
13348
- beforeStartPostReplayServices: /* @__PURE__ */ __name(async (createdSession) => {
13349
- await this.#restoreWorktreeOnResume(config, createdSession);
13350
- await this.#restoreBackgroundAgentsOnResume(config, createdSession);
13351
- this.#restoreGoalOnResume(config, createdSession);
13352
- }, "beforeStartPostReplayServices")
13353
- }
14064
+ const sessionData = config.getResumedSessionData();
14065
+ return profiler.timeSync(
14066
+ "response_build",
14067
+ () => ({
14068
+ modes: this.buildModesData(config),
14069
+ models: this.buildAvailableModels(config),
14070
+ configOptions: this.buildConfigOptions(config),
14071
+ ...sessionData?.artifactSnapshot ? { artifactSnapshot: sessionData.artifactSnapshot } : {}
14072
+ })
13354
14073
  );
13355
- } catch (error) {
13356
- return this.cleanupAfterRequestFailure(error, async () => {
13357
- if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
13358
- await this.cleanupUnstoredConfig(config);
13359
- }
13360
- });
14074
+ } finally {
14075
+ releaseStartingSessionId();
13361
14076
  }
13362
- const modesData = this.buildModesData(config);
13363
- const availableModels = this.buildAvailableModels(config);
13364
- const configOptions = this.buildConfigOptions(config);
13365
- const sessionData = config.getResumedSessionData();
13366
- return {
13367
- modes: modesData,
13368
- models: availableModels,
13369
- configOptions,
13370
- ...sessionData?.artifactSnapshot ? { artifactSnapshot: sessionData.artifactSnapshot } : {}
13371
- };
13372
14077
  }
13373
14078
  /**
13374
14079
  * Shared worktree restore for both ACP entry points (`loadSession` and
@@ -13384,7 +14089,7 @@ var QwenAgent = class {
13384
14089
  session.pendingWorktreeNotice = restored.contextMessage;
13385
14090
  }
13386
14091
  } catch (error) {
13387
- debugLogger7.warn(`ACP worktree restore failed: ${error}`);
14092
+ debugLogger8.warn(`ACP worktree restore failed: ${error}`);
13388
14093
  }
13389
14094
  }
13390
14095
  async #restoreBackgroundAgentsOnResume(config, session) {
@@ -13417,7 +14122,7 @@ var QwenAgent = class {
13417
14122
  config
13418
14123
  );
13419
14124
  if (restored.restored) {
13420
- debugLogger7.info(
14125
+ debugLogger8.info(
13421
14126
  `ACP goal restored sessionId=${config.getSessionId()} condition=${restored.condition}`
13422
14127
  );
13423
14128
  } else if (restored.blockedBy && restored.blockedBy !== "condition-invalid") {
@@ -13463,27 +14168,30 @@ var QwenAgent = class {
13463
14168
  };
13464
14169
  }
13465
14170
  async setSessionMode(params) {
13466
- const session = this.sessions.get(params.sessionId);
14171
+ const sessionId = normalizeSessionIdForLookup(params.sessionId);
14172
+ const session = this.sessions.get(sessionId);
13467
14173
  if (!session) {
13468
14174
  throw RequestError.invalidParams(
13469
14175
  void 0,
13470
- `Session not found for id: ${params.sessionId}`
14176
+ `Session not found for id: ${sessionId}`
13471
14177
  );
13472
14178
  }
13473
- return session.setMode(params);
14179
+ return session.setMode({ ...params, sessionId });
13474
14180
  }
13475
14181
  async unstable_setSessionModel(params) {
13476
- const session = this.sessions.get(params.sessionId);
14182
+ const sessionId = normalizeSessionIdForLookup(params.sessionId);
14183
+ const session = this.sessions.get(sessionId);
13477
14184
  if (!session) {
13478
14185
  throw RequestError.invalidParams(
13479
14186
  void 0,
13480
- `Session not found for id: ${params.sessionId}`
14187
+ `Session not found for id: ${sessionId}`
13481
14188
  );
13482
14189
  }
13483
- return await session.setModel(params);
14190
+ return await session.setModel({ ...params, sessionId });
13484
14191
  }
13485
14192
  async setSessionConfigOption(params) {
13486
- const { sessionId, configId, value } = params;
14193
+ const sessionId = normalizeSessionIdForLookup(params.sessionId);
14194
+ const { configId, value } = params;
13487
14195
  const session = this.sessions.get(sessionId);
13488
14196
  if (!session) {
13489
14197
  throw RequestError.invalidParams(
@@ -13520,11 +14228,12 @@ var QwenAgent = class {
13520
14228
  };
13521
14229
  }
13522
14230
  async prompt(params) {
13523
- const session = this.sessions.get(params.sessionId);
14231
+ const sessionId = normalizeSessionIdForLookup(params.sessionId);
14232
+ const session = this.sessions.get(sessionId);
13524
14233
  if (!session) {
13525
- throw new Error(`Session not found: ${params.sessionId}`);
14234
+ throw new Error(`Session not found: ${sessionId}`);
13526
14235
  }
13527
- const sanitizedParams = { ...params };
14236
+ const sanitizedParams = { ...params, sessionId };
13528
14237
  const meta = params._meta && typeof params._meta === "object" ? { ...params._meta } : {};
13529
14238
  const suppliedContext = meta[INVOCATION_CONTEXT_META_KEY];
13530
14239
  const suppliedModelPrompt = meta[DAEMON_MODEL_PROMPT_META_KEY];
@@ -13554,14 +14263,14 @@ var QwenAgent = class {
13554
14263
  }, "settleCall");
13555
14264
  const call = {
13556
14265
  controller: new AbortController(),
13557
- settled: new Promise((resolve5) => {
13558
- settleCall = resolve5;
14266
+ settled: new Promise((resolve6) => {
14267
+ settleCall = resolve6;
13559
14268
  })
13560
14269
  };
13561
- let calls = this.activePromptCalls.get(params.sessionId);
14270
+ let calls = this.activePromptCalls.get(sessionId);
13562
14271
  if (!calls) {
13563
14272
  calls = /* @__PURE__ */ new Set();
13564
- this.activePromptCalls.set(params.sessionId, calls);
14273
+ this.activePromptCalls.set(sessionId, calls);
13565
14274
  }
13566
14275
  calls.add(call);
13567
14276
  try {
@@ -13574,16 +14283,17 @@ var QwenAgent = class {
13574
14283
  } finally {
13575
14284
  calls.delete(call);
13576
14285
  if (calls.size === 0) {
13577
- this.activePromptCalls.delete(params.sessionId);
14286
+ this.activePromptCalls.delete(sessionId);
13578
14287
  }
13579
14288
  settleCall();
13580
14289
  await this.activeWorkReporter?.flush();
13581
14290
  }
13582
14291
  }
13583
14292
  async cancel(params) {
13584
- const session = this.sessions.get(params.sessionId);
14293
+ const sessionId = normalizeSessionIdForLookup(params.sessionId);
14294
+ const session = this.sessions.get(sessionId);
13585
14295
  if (!session) {
13586
- throw new Error(`Session not found: ${params.sessionId}`);
14296
+ throw new Error(`Session not found: ${sessionId}`);
13587
14297
  }
13588
14298
  try {
13589
14299
  await session.cancelPendingPrompt();
@@ -13611,7 +14321,7 @@ var QwenAgent = class {
13611
14321
  await extensionManager.refreshCache();
13612
14322
  extensions = extensionManager.getLoadedExtensions();
13613
14323
  } catch (error) {
13614
- debugLogger7.warn(
14324
+ debugLogger8.warn(
13615
14325
  "Extension loading failed, continuing without extensions:",
13616
14326
  error
13617
14327
  );
@@ -13737,7 +14447,7 @@ var QwenAgent = class {
13737
14447
  pm.addPersistentRule(rule, ruleType);
13738
14448
  }
13739
14449
  } catch (error) {
13740
- debugLogger7.warn(
14450
+ debugLogger8.warn(
13741
14451
  `Failed to sync permission rules to a live session: ${error instanceof Error ? error.message : String(error)}`
13742
14452
  );
13743
14453
  }
@@ -14295,7 +15005,7 @@ var QwenAgent = class {
14295
15005
  if (!changed) return;
14296
15006
  await config.getSkillManager()?.refreshCache();
14297
15007
  } catch (error) {
14298
- debugLogger7.warn("Extension source revalidation failed:", error);
15008
+ debugLogger8.warn("Extension source revalidation failed:", error);
14299
15009
  }
14300
15010
  }
14301
15011
  async buildWorkspaceSkillsStatus(config) {
@@ -15192,9 +15902,9 @@ var QwenAgent = class {
15192
15902
  );
15193
15903
  }
15194
15904
  const download = await downloadSkill(request.sourceUrl);
15195
- const skillsBaseDir = path3.join(Storage.getGlobalQwenDir(), "skills");
15905
+ const skillsBaseDir = path4.join(Storage.getGlobalQwenDir(), "skills");
15196
15906
  const skillDir = resolveManagedSkillDir(skillsBaseDir, request.slug);
15197
- const skillFile = path3.join(skillDir, "SKILL.md");
15907
+ const skillFile = path4.join(skillDir, "SKILL.md");
15198
15908
  const parsed = skillManager.parseSkillContent(
15199
15909
  download.skillContent,
15200
15910
  skillFile,
@@ -15208,19 +15918,19 @@ var QwenAgent = class {
15208
15918
  }
15209
15919
  const stagingDir = `${skillDir}.installing-${process.pid}-${Date.now()}`;
15210
15920
  try {
15211
- await fs.rm(stagingDir, { recursive: true, force: true });
15921
+ await fs2.rm(stagingDir, { recursive: true, force: true });
15212
15922
  for (const file of download.files) {
15213
15923
  const targetPath = resolveSkillInstallPath(
15214
15924
  stagingDir,
15215
15925
  file.relativePath
15216
15926
  );
15217
- await fs.mkdir(path3.dirname(targetPath), { recursive: true });
15218
- await fs.writeFile(targetPath, file.content);
15927
+ await fs2.mkdir(path4.dirname(targetPath), { recursive: true });
15928
+ await fs2.writeFile(targetPath, file.content);
15219
15929
  }
15220
- await fs.rm(skillDir, { recursive: true, force: true });
15221
- await fs.rename(stagingDir, skillDir);
15930
+ await fs2.rm(skillDir, { recursive: true, force: true });
15931
+ await fs2.rename(stagingDir, skillDir);
15222
15932
  } catch (error) {
15223
- await fs.rm(stagingDir, { recursive: true, force: true }).catch(() => {
15933
+ await fs2.rm(stagingDir, { recursive: true, force: true }).catch(() => {
15224
15934
  });
15225
15935
  throw error;
15226
15936
  }
@@ -15253,17 +15963,17 @@ var QwenAgent = class {
15253
15963
  `Skill name "${parsed.name}" does not match requested slug "${request.slug}"`
15254
15964
  );
15255
15965
  }
15256
- const resolvedSkillDir = path3.resolve(skillDir);
15257
- const resolvedSkillFile = path3.resolve(skillFile);
15258
- const globalDir = path3.resolve(Storage.getGlobalQwenDir());
15259
- const isDedicatedSkillDir = resolvedSkillFile === path3.join(resolvedSkillDir, "SKILL.md");
15260
- if (!isDedicatedSkillDir || resolvedSkillDir === path3.parse(resolvedSkillDir).root || resolvedSkillDir === globalDir) {
15966
+ const resolvedSkillDir = path4.resolve(skillDir);
15967
+ const resolvedSkillFile = path4.resolve(skillFile);
15968
+ const globalDir = path4.resolve(Storage.getGlobalQwenDir());
15969
+ const isDedicatedSkillDir = resolvedSkillFile === path4.join(resolvedSkillDir, "SKILL.md");
15970
+ if (!isDedicatedSkillDir || resolvedSkillDir === path4.parse(resolvedSkillDir).root || resolvedSkillDir === globalDir) {
15261
15971
  throw RequestError.invalidParams(
15262
15972
  void 0,
15263
15973
  `Refusing to delete unexpected skill directory: ${skillDir}`
15264
15974
  );
15265
15975
  }
15266
- await fs.rm(skillDir, { recursive: true, force: true });
15976
+ await fs2.rm(skillDir, { recursive: true, force: true });
15267
15977
  await skillManager.refreshCache();
15268
15978
  return {
15269
15979
  slug: request.slug,
@@ -15273,11 +15983,11 @@ var QwenAgent = class {
15273
15983
  async readManagedSkillFile(slug, scope, skillManager, cwd) {
15274
15984
  if (scope === "global") {
15275
15985
  const qwenSkillDir = resolveManagedSkillDir(
15276
- path3.join(Storage.getGlobalQwenDir(), "skills"),
15986
+ path4.join(Storage.getGlobalQwenDir(), "skills"),
15277
15987
  slug
15278
15988
  );
15279
- const qwenSkillFile = path3.join(qwenSkillDir, "SKILL.md");
15280
- const qwenContent = await fs.readFile(qwenSkillFile, "utf8").catch(() => void 0);
15989
+ const qwenSkillFile = path4.join(qwenSkillDir, "SKILL.md");
15990
+ const qwenContent = await fs2.readFile(qwenSkillFile, "utf8").catch(() => void 0);
15281
15991
  if (qwenContent !== void 0) {
15282
15992
  return {
15283
15993
  skillDir: qwenSkillDir,
@@ -15305,34 +16015,34 @@ var QwenAgent = class {
15305
16015
  `${scope === "project" ? "Project" : "Global"} skill not found: ${slug}`
15306
16016
  );
15307
16017
  }
15308
- const content = await fs.readFile(skillFile, "utf8").catch(() => {
16018
+ const content = await fs2.readFile(skillFile, "utf8").catch(() => {
15309
16019
  throw RequestError.invalidParams(
15310
16020
  void 0,
15311
16021
  `${scope === "project" ? "Project" : "Global"} skill not found: ${slug}`
15312
16022
  );
15313
16023
  });
15314
16024
  return {
15315
- skillDir: path3.dirname(skillFile),
16025
+ skillDir: path4.dirname(skillFile),
15316
16026
  skillFile,
15317
16027
  content
15318
16028
  };
15319
16029
  }
15320
16030
  async findProjectSkillFileFromCwd(slug, cwd, skillManager) {
15321
- const projectRoot = path3.resolve(cwd);
16031
+ const projectRoot = path4.resolve(cwd);
15322
16032
  for (const configDir of PROJECT_SKILL_DIRS) {
15323
- const baseDir = path3.join(projectRoot, configDir, SKILLS_DIR);
16033
+ const baseDir = path4.join(projectRoot, configDir, SKILLS_DIR);
15324
16034
  const skills = await skillManager.loadSkillsFromDir(baseDir, "project");
15325
16035
  const skill = skills.find((candidate) => candidate.name === slug);
15326
16036
  const skillFile = skill?.filePath;
15327
16037
  if (!skillFile) continue;
15328
- const content = await fs.readFile(skillFile, "utf8").catch(() => {
16038
+ const content = await fs2.readFile(skillFile, "utf8").catch(() => {
15329
16039
  throw RequestError.invalidParams(
15330
16040
  void 0,
15331
16041
  `Project skill not found: ${slug}`
15332
16042
  );
15333
16043
  });
15334
16044
  return {
15335
- skillDir: path3.dirname(skillFile),
16045
+ skillDir: path4.dirname(skillFile),
15336
16046
  skillFile,
15337
16047
  content
15338
16048
  };
@@ -15363,13 +16073,13 @@ var QwenAgent = class {
15363
16073
  }
15364
16074
  const nextContent = setSkillFrontmatterEnabled(content, request.enabled);
15365
16075
  skillManager.parseSkillContent(nextContent, skillFile, level);
15366
- if (path3.basename(skillFile) !== "SKILL.md") {
16076
+ if (path4.basename(skillFile) !== "SKILL.md") {
15367
16077
  throw RequestError.invalidParams(
15368
16078
  void 0,
15369
16079
  `Refusing to write to unexpected skill file: ${skillFile}`
15370
16080
  );
15371
16081
  }
15372
- await fs.writeFile(skillFile, nextContent, "utf8");
16082
+ await fs2.writeFile(skillFile, nextContent, "utf8");
15373
16083
  await skillManager.refreshCache();
15374
16084
  return {
15375
16085
  slug: request.slug,
@@ -15379,13 +16089,18 @@ var QwenAgent = class {
15379
16089
  }
15380
16090
  async extMethod(method, params) {
15381
16091
  try {
16092
+ const rawSessionId = params["sessionId"];
16093
+ const normalizedParams = typeof rawSessionId === "string" ? {
16094
+ ...params,
16095
+ sessionId: normalizeSessionIdForLookup(rawSessionId)
16096
+ } : params;
15382
16097
  if (method === SERVE_CONTROL_EXT_METHODS.sessionBackgroundNotification && this.privateParentState !== "trusted") {
15383
16098
  throw RequestError.invalidParams(
15384
16099
  void 0,
15385
16100
  "Background notifications require a trusted private ACP parent"
15386
16101
  );
15387
16102
  }
15388
- return await this.extMethodInternal(method, params);
16103
+ return await this.extMethodInternal(method, normalizedParams);
15389
16104
  } catch (error) {
15390
16105
  const writerError = getSessionWriterError(error);
15391
16106
  if (writerError) {
@@ -15750,7 +16465,7 @@ var QwenAgent = class {
15750
16465
  config,
15751
16466
  finalizeDangling: !activePromptBeforeRead && !this.activePromptCalls.has(sessionId),
15752
16467
  encodeCursor: /* @__PURE__ */ __name((state) => encodeSessionTranscriptCursor(state, cwd), "encodeCursor"),
15753
- logger: debugLogger7
16468
+ logger: debugLogger8
15754
16469
  });
15755
16470
  return {
15756
16471
  v: 1,
@@ -15946,7 +16661,7 @@ var QwenAgent = class {
15946
16661
  );
15947
16662
  if (childSignal.aborted) {
15948
16663
  const timeoutCode = "remember_timeout";
15949
- debugLogger7.error("Workspace memory remember timed out:", {
16664
+ debugLogger8.error("Workspace memory remember timed out:", {
15950
16665
  projectRoot,
15951
16666
  code: timeoutCode,
15952
16667
  details: diagnostics.debugDetails,
@@ -15958,7 +16673,7 @@ var QwenAgent = class {
15958
16673
  workspaceMemoryErrorData(timeoutCode, diagnostics)
15959
16674
  );
15960
16675
  }
15961
- debugLogger7.error("Workspace memory remember failed:", {
16676
+ debugLogger8.error("Workspace memory remember failed:", {
15962
16677
  projectRoot,
15963
16678
  code,
15964
16679
  details: diagnostics.debugDetails,
@@ -16032,7 +16747,7 @@ var QwenAgent = class {
16032
16747
  );
16033
16748
  if (childSignal.aborted) {
16034
16749
  const timeoutCode = "forget_timeout";
16035
- debugLogger7.error("Workspace memory forget timed out:", {
16750
+ debugLogger8.error("Workspace memory forget timed out:", {
16036
16751
  projectRoot,
16037
16752
  code: timeoutCode,
16038
16753
  details: diagnostics.debugDetails,
@@ -16044,7 +16759,7 @@ var QwenAgent = class {
16044
16759
  workspaceMemoryErrorData(timeoutCode, diagnostics)
16045
16760
  );
16046
16761
  }
16047
- debugLogger7.error("Workspace memory forget failed:", {
16762
+ debugLogger8.error("Workspace memory forget failed:", {
16048
16763
  projectRoot,
16049
16764
  code,
16050
16765
  details: diagnostics.debugDetails,
@@ -16112,7 +16827,7 @@ var QwenAgent = class {
16112
16827
  );
16113
16828
  if (childSignal.aborted) {
16114
16829
  const timeoutCode = "dream_timeout";
16115
- debugLogger7.error("Workspace memory dream timed out:", {
16830
+ debugLogger8.error("Workspace memory dream timed out:", {
16116
16831
  projectRoot,
16117
16832
  code: timeoutCode,
16118
16833
  details: diagnostics.debugDetails,
@@ -16124,7 +16839,7 @@ var QwenAgent = class {
16124
16839
  workspaceMemoryErrorData(timeoutCode, diagnostics)
16125
16840
  );
16126
16841
  }
16127
- debugLogger7.error("Workspace memory dream failed:", {
16842
+ debugLogger8.error("Workspace memory dream failed:", {
16128
16843
  projectRoot,
16129
16844
  code,
16130
16845
  details: diagnostics.debugDetails,
@@ -16475,10 +17190,10 @@ var QwenAgent = class {
16475
17190
  let resolveStarted;
16476
17191
  let rejectStarted;
16477
17192
  let startedTimer;
16478
- const started = new Promise((resolve5, reject) => {
17193
+ const started = new Promise((resolve6, reject) => {
16479
17194
  resolveStarted = /* @__PURE__ */ __name((value) => {
16480
17195
  clearTimeout(startedTimer);
16481
- resolve5(value);
17196
+ resolve6(value);
16482
17197
  }, "resolveStarted");
16483
17198
  rejectStarted = /* @__PURE__ */ __name((reason) => {
16484
17199
  clearTimeout(startedTimer);
@@ -16534,7 +17249,7 @@ var QwenAgent = class {
16534
17249
  error: error instanceof Error ? error.message : String(error)
16535
17250
  });
16536
17251
  rejectStarted(error);
16537
- debugLogger7.warn(
17252
+ debugLogger8.warn(
16538
17253
  `MCP OAuth authentication failed for ${serverName}:`,
16539
17254
  error
16540
17255
  );
@@ -16546,7 +17261,7 @@ var QwenAgent = class {
16546
17261
  "discover"
16547
17262
  );
16548
17263
  } catch (error) {
16549
- debugLogger7.warn(
17264
+ debugLogger8.warn(
16550
17265
  `MCP OAuth authenticated for ${serverName}, but tool synchronization failed:`,
16551
17266
  error
16552
17267
  );
@@ -16970,7 +17685,7 @@ var QwenAgent = class {
16970
17685
  "Invalid or missing sessionId"
16971
17686
  );
16972
17687
  }
16973
- if (typeof targetPath !== "string" || targetPath.length === 0 || !path3.isAbsolute(targetPath) || targetPath.includes("\0")) {
17688
+ if (typeof targetPath !== "string" || targetPath.length === 0 || !path4.isAbsolute(targetPath) || targetPath.includes("\0")) {
16974
17689
  throw RequestError.invalidParams(
16975
17690
  void 0,
16976
17691
  "Invalid or missing path (must be an absolute path)"
@@ -16993,7 +17708,7 @@ var QwenAgent = class {
16993
17708
  }
16994
17709
  let stats;
16995
17710
  try {
16996
- stats = await fs.stat(targetPath);
17711
+ stats = await fs2.stat(targetPath);
16997
17712
  } catch {
16998
17713
  throw new RequestError(-32002, `Directory not found: ${targetPath}`, {
16999
17714
  errorKind: "directory_not_found",
@@ -17006,7 +17721,7 @@ var QwenAgent = class {
17006
17721
  path: targetPath
17007
17722
  });
17008
17723
  }
17009
- const canonicalPath = await fs.realpath(targetPath);
17724
+ const canonicalPath = await fs2.realpath(targetPath);
17010
17725
  let containmentRoots = allowedRoots;
17011
17726
  let managedTrustAllowed = false;
17012
17727
  if (managedRelocation === "live-conversation") {
@@ -17016,7 +17731,7 @@ var QwenAgent = class {
17016
17731
  "Live managed relocation requires a trusted private ACP parent"
17017
17732
  );
17018
17733
  }
17019
- if (!Array.isArray(allowedRoots) || allowedRoots.length !== 1 || typeof allowedRoots[0] !== "string" || !path3.isAbsolute(allowedRoots[0]) || allowedRoots[0].includes("\0")) {
17734
+ if (!Array.isArray(allowedRoots) || allowedRoots.length !== 1 || typeof allowedRoots[0] !== "string" || !path4.isAbsolute(allowedRoots[0]) || allowedRoots[0].includes("\0")) {
17020
17735
  throw RequestError.invalidParams(
17021
17736
  void 0,
17022
17737
  "Live managed relocation requires one absolute allowed root"
@@ -17027,9 +17742,9 @@ var QwenAgent = class {
17027
17742
  let canonicalRoot;
17028
17743
  let rootAfter;
17029
17744
  try {
17030
- rootBefore = await fs.lstat(rootPath);
17031
- canonicalRoot = await fs.realpath(rootPath);
17032
- rootAfter = await fs.lstat(canonicalRoot);
17745
+ rootBefore = await fs2.lstat(rootPath);
17746
+ canonicalRoot = await fs2.realpath(rootPath);
17747
+ rootAfter = await fs2.lstat(canonicalRoot);
17033
17748
  } catch {
17034
17749
  throw new RequestError(
17035
17750
  -32004,
@@ -17047,8 +17762,8 @@ var QwenAgent = class {
17047
17762
  let targetBefore;
17048
17763
  let targetAfter;
17049
17764
  try {
17050
- targetBefore = await fs.lstat(targetPath);
17051
- targetAfter = await fs.lstat(canonicalPath);
17765
+ targetBefore = await fs2.lstat(targetPath);
17766
+ targetAfter = await fs2.lstat(canonicalPath);
17052
17767
  } catch {
17053
17768
  throw new RequestError(
17054
17769
  -32004,
@@ -17056,8 +17771,8 @@ var QwenAgent = class {
17056
17771
  { errorKind: "containment_violation", path: canonicalPath }
17057
17772
  );
17058
17773
  }
17059
- const relativeTarget = path3.relative(canonicalRoot, canonicalPath);
17060
- if (!isOwnerOnlyDirectory(targetBefore) || !isOwnerOnlyDirectory(targetAfter) || targetBefore.dev !== targetAfter.dev || targetBefore.ino !== targetAfter.ino || relativeTarget.length === 0 || relativeTarget.startsWith("..") || path3.isAbsolute(relativeTarget) || relativeTarget.includes(path3.sep)) {
17774
+ const relativeTarget = path4.relative(canonicalRoot, canonicalPath);
17775
+ if (!isOwnerOnlyDirectory(targetBefore) || !isOwnerOnlyDirectory(targetAfter) || targetBefore.dev !== targetAfter.dev || targetBefore.ino !== targetAfter.ino || relativeTarget.length === 0 || relativeTarget.startsWith("..") || path4.isAbsolute(relativeTarget) || relativeTarget.includes(path4.sep)) {
17061
17776
  throw new RequestError(
17062
17777
  -32004,
17063
17778
  "Live managed relocation requires an owner-only direct child",
@@ -17066,7 +17781,7 @@ var QwenAgent = class {
17066
17781
  }
17067
17782
  let rootFinal;
17068
17783
  try {
17069
- rootFinal = await fs.lstat(canonicalRoot);
17784
+ rootFinal = await fs2.lstat(canonicalRoot);
17070
17785
  } catch {
17071
17786
  throw new RequestError(
17072
17787
  -32004,
@@ -17087,8 +17802,8 @@ var QwenAgent = class {
17087
17802
  if (Array.isArray(containmentRoots) && containmentRoots.length > 0) {
17088
17803
  const contained = containmentRoots.some((root) => {
17089
17804
  if (typeof root !== "string") return false;
17090
- const rel = path3.relative(root, canonicalPath);
17091
- return !rel.startsWith("..") && !path3.isAbsolute(rel);
17805
+ const rel = path4.relative(root, canonicalPath);
17806
+ return !rel.startsWith("..") && !path4.isAbsolute(rel);
17092
17807
  });
17093
17808
  if (!contained) {
17094
17809
  throw new RequestError(
@@ -17236,7 +17951,7 @@ var QwenAgent = class {
17236
17951
  try {
17237
17952
  await setLanguageAsync(language);
17238
17953
  } catch (err) {
17239
- debugLogger7.warn("setLanguageAsync failed:", err);
17954
+ debugLogger8.warn("setLanguageAsync failed:", err);
17240
17955
  throw new RequestError(
17241
17956
  -32603,
17242
17957
  `Failed to switch UI language: ${err instanceof Error ? err.message : String(err)}`
@@ -17250,7 +17965,7 @@ var QwenAgent = class {
17250
17965
  language
17251
17966
  );
17252
17967
  } catch (err) {
17253
- debugLogger7.warn("Failed to persist UI language setting:", err);
17968
+ debugLogger8.warn("Failed to persist UI language setting:", err);
17254
17969
  }
17255
17970
  let outputLanguage = null;
17256
17971
  let refreshed = false;
@@ -17264,7 +17979,7 @@ var QwenAgent = class {
17264
17979
  );
17265
17980
  fileWriteOk = true;
17266
17981
  } catch (err) {
17267
- debugLogger7.warn("Failed to write output-language.md:", err);
17982
+ debugLogger8.warn("Failed to write output-language.md:", err);
17268
17983
  }
17269
17984
  if (fileWriteOk) {
17270
17985
  try {
@@ -17274,7 +17989,7 @@ var QwenAgent = class {
17274
17989
  settingValue
17275
17990
  );
17276
17991
  } catch (err) {
17277
- debugLogger7.warn(
17992
+ debugLogger8.warn(
17278
17993
  "Failed to persist output language setting:",
17279
17994
  err
17280
17995
  );
@@ -17294,7 +18009,7 @@ var QwenAgent = class {
17294
18009
  writeOutputLanguageAndRegisterPath(settingValue, cfg);
17295
18010
  }
17296
18011
  } catch (err) {
17297
- debugLogger7.warn(
18012
+ debugLogger8.warn(
17298
18013
  `Failed to write output-language.md for session ${s.getId()} (path=${sessionPath ?? "global-default"}):`,
17299
18014
  err
17300
18015
  );
@@ -17307,7 +18022,7 @@ var QwenAgent = class {
17307
18022
  (r) => r.status === "rejected"
17308
18023
  ).length;
17309
18024
  if (failedCount > 0) {
17310
- debugLogger7.warn(
18025
+ debugLogger8.warn(
17311
18026
  `Language refresh failed for ${failedCount}/${results.length} session(s)`
17312
18027
  );
17313
18028
  }
@@ -17325,14 +18040,14 @@ var QwenAgent = class {
17325
18040
  "Invalid or missing sessionId"
17326
18041
  );
17327
18042
  }
17328
- debugLogger7.debug(`recap ext-method received for session=${sessionId}`);
18043
+ debugLogger8.debug(`recap ext-method received for session=${sessionId}`);
17329
18044
  const session = this.sessionOrThrow(sessionId);
17330
18045
  const config = session.getConfig();
17331
18046
  const recap = await generateSessionRecap(
17332
18047
  config,
17333
18048
  new AbortController().signal
17334
18049
  );
17335
- debugLogger7.debug(
18050
+ debugLogger8.debug(
17336
18051
  `recap ext-method completed for session=${sessionId} result=${recap ? `len=${recap.length}` : "null"}`
17337
18052
  );
17338
18053
  return { sessionId, recap };
@@ -17414,7 +18129,7 @@ var QwenAgent = class {
17414
18129
  const config = session.getConfig();
17415
18130
  const cacheSafeParams = buildBtwCacheSafeParams(config);
17416
18131
  if (!cacheSafeParams) {
17417
- debugLogger7.debug(`btw: no cacheSafeParams for session=${sessionId}`);
18132
+ debugLogger8.debug(`btw: no cacheSafeParams for session=${sessionId}`);
17418
18133
  return { sessionId, answer: null };
17419
18134
  }
17420
18135
  const childSignal = AbortSignal.timeout(BTW_CHILD_TIMEOUT_MS);
@@ -17468,7 +18183,7 @@ var QwenAgent = class {
17468
18183
  try {
17469
18184
  hasHistory = (config.getGeminiClient().getHistoryShallow() ?? []).length > 0;
17470
18185
  } catch (error) {
17471
- debugLogger7.debug("Failed to read history before /fork:", error);
18186
+ debugLogger8.debug("Failed to read history before /fork:", error);
17472
18187
  }
17473
18188
  if (!hasHistory) {
17474
18189
  throw RequestError.invalidParams(
@@ -17510,7 +18225,7 @@ var QwenAgent = class {
17510
18225
  ]
17511
18226
  });
17512
18227
  } catch (error) {
17513
- debugLogger7.debug("Failed to record fork event in history:", error);
18228
+ debugLogger8.debug("Failed to record fork event in history:", error);
17514
18229
  }
17515
18230
  return { sessionId, description, launched: true };
17516
18231
  }
@@ -17573,7 +18288,7 @@ ${outputText}
17573
18288
  'taskKind must be "agent", "shell", or "monitor"'
17574
18289
  );
17575
18290
  }
17576
- debugLogger7.info(
18291
+ debugLogger8.info(
17577
18292
  `sessionTaskCancel requested sessionId=${sessionId} taskId=${taskId} taskKind=${taskKind}`
17578
18293
  );
17579
18294
  const session = this.sessionOrThrow(sessionId);
@@ -17583,7 +18298,7 @@ ${outputText}
17583
18298
  const task = config.getBackgroundTaskRegistry().get(taskId);
17584
18299
  if (!task || task.status !== "running" && task.status !== "paused") {
17585
18300
  const reason = task ? "not_running" : "not_found";
17586
- debugLogger7.info(
18301
+ debugLogger8.info(
17587
18302
  `sessionTaskCancel skipped sessionId=${sessionId} taskId=${taskId} taskKind=${taskKind} reason=${reason} status=${task?.status ?? "missing"}`
17588
18303
  );
17589
18304
  return { cancelled: false, reason, status: task?.status };
@@ -17593,7 +18308,7 @@ ${outputText}
17593
18308
  } else {
17594
18309
  config.getBackgroundTaskRegistry().cancel(taskId);
17595
18310
  }
17596
- debugLogger7.info(
18311
+ debugLogger8.info(
17597
18312
  `sessionTaskCancel completed sessionId=${sessionId} taskId=${taskId} taskKind=${taskKind} status=${task.status}`
17598
18313
  );
17599
18314
  return { cancelled: true, status: task.status };
@@ -17602,13 +18317,13 @@ ${outputText}
17602
18317
  const task = config.getBackgroundShellRegistry().get(taskId);
17603
18318
  if (!task || task.status !== "running") {
17604
18319
  const reason = task ? "not_running" : "not_found";
17605
- debugLogger7.info(
18320
+ debugLogger8.info(
17606
18321
  `sessionTaskCancel skipped sessionId=${sessionId} taskId=${taskId} taskKind=${taskKind} reason=${reason} status=${task?.status ?? "missing"}`
17607
18322
  );
17608
18323
  return { cancelled: false, reason, status: task?.status };
17609
18324
  }
17610
18325
  config.getBackgroundShellRegistry().requestCancel(taskId);
17611
- debugLogger7.info(
18326
+ debugLogger8.info(
17612
18327
  `sessionTaskCancel completed sessionId=${sessionId} taskId=${taskId} taskKind=${taskKind} status=${task.status}`
17613
18328
  );
17614
18329
  return { cancelled: true, status: task.status };
@@ -17617,13 +18332,13 @@ ${outputText}
17617
18332
  const task = config.getMonitorRegistry().get(taskId);
17618
18333
  if (!task || task.status !== "running") {
17619
18334
  const reason = task ? "not_running" : "not_found";
17620
- debugLogger7.info(
18335
+ debugLogger8.info(
17621
18336
  `sessionTaskCancel skipped sessionId=${sessionId} taskId=${taskId} taskKind=${taskKind} reason=${reason} status=${task?.status ?? "missing"}`
17622
18337
  );
17623
18338
  return { cancelled: false, reason, status: task?.status };
17624
18339
  }
17625
18340
  config.getMonitorRegistry().cancel(taskId);
17626
- debugLogger7.info(
18341
+ debugLogger8.info(
17627
18342
  `sessionTaskCancel completed sessionId=${sessionId} taskId=${taskId} taskKind=${taskKind} status=${task.status}`
17628
18343
  );
17629
18344
  return { cancelled: true, status: task.status };
@@ -17653,7 +18368,7 @@ ${outputText}
17653
18368
  durationMs: Date.now() - cleared.setAt
17654
18369
  });
17655
18370
  }
17656
- debugLogger7.info(
18371
+ debugLogger8.info(
17657
18372
  `sessionGoalClear sessionId=${sessionId} cleared=${!!cleared} condition=${cleared?.condition ?? "(none)"}`
17658
18373
  );
17659
18374
  return {
@@ -17692,7 +18407,7 @@ ${outputText}
17692
18407
  }
17693
18408
  const session = this.sessionOrThrow(sessionId);
17694
18409
  const result = await session.continueLastTurn();
17695
- debugLogger7.info(
18410
+ debugLogger8.info(
17696
18411
  `sessionContinue sessionId=${sessionId} accepted=${result.accepted} interruption=${result.interruption}`
17697
18412
  );
17698
18413
  return result;
@@ -17714,7 +18429,7 @@ ${outputText}
17714
18429
  request.runtimeClientId
17715
18430
  );
17716
18431
  } catch (sessionErr) {
17717
- debugLogger7.warn(
18432
+ debugLogger8.warn(
17718
18433
  `workspaceMcpRuntimeAdd: failed to add runtime MCP server '${request.name}' to active session ${session.getConfig().getSessionId()}: ${sessionErr instanceof Error ? sessionErr.message : String(sessionErr)}`
17719
18434
  );
17720
18435
  }
@@ -17737,7 +18452,7 @@ ${outputText}
17737
18452
  request.runtimeClientId
17738
18453
  );
17739
18454
  } catch (sessionErr) {
17740
- debugLogger7.warn(
18455
+ debugLogger8.warn(
17741
18456
  `workspaceMcpRuntimeRemove: failed to remove runtime MCP server '${request.name}' from active session ${session.getConfig().getSessionId()}: ${sessionErr instanceof Error ? sessionErr.message : String(sessionErr)}`
17742
18457
  );
17743
18458
  }
@@ -17846,7 +18561,7 @@ ${outputText}
17846
18561
  }
17847
18562
  );
17848
18563
  if (success) {
17849
- fireSessionDeleteHook(this.config, sessionId, debugLogger7);
18564
+ fireSessionDeleteHook(this.config, sessionId, debugLogger8);
17850
18565
  }
17851
18566
  return { success };
17852
18567
  }
@@ -17972,7 +18687,7 @@ ${outputText}
17972
18687
  filesFailed = fileResult.filesFailed;
17973
18688
  } catch (err) {
17974
18689
  const reason = err instanceof Error ? err.message : String(err);
17975
- debugLogger7.error(
18690
+ debugLogger8.error(
17976
18691
  `[ACP] File-history rewind failed for session=${sessionId} promptId=${promptId}: ${reason}`
17977
18692
  );
17978
18693
  filesFailed = [`file-history-rewind: ${reason}`];
@@ -18004,7 +18719,7 @@ ${outputText}
18004
18719
  } catch (err) {
18005
18720
  const reason = err instanceof Error ? err.message : String(err);
18006
18721
  artifactSnapshotUnavailable = "artifact snapshot unavailable after rewind";
18007
- debugLogger7.warn(
18722
+ debugLogger8.warn(
18008
18723
  `[ACP] Failed to rebuild artifact snapshot after rewind for session=${sessionId}: ${reason}`
18009
18724
  );
18010
18725
  }
@@ -18060,7 +18775,7 @@ ${outputText}
18060
18775
  records: sessionData.conversation.messages,
18061
18776
  gaps: sessionData.historyGaps,
18062
18777
  cumulativeUsage: createReplayCumulativeUsage(),
18063
- logger: debugLogger7
18778
+ logger: debugLogger8
18064
18779
  });
18065
18780
  return {
18066
18781
  updates: replay.updates,
@@ -18416,7 +19131,7 @@ ${outputText}
18416
19131
  newMerged.providerProtocol ?? {}
18417
19132
  );
18418
19133
  } catch (err) {
18419
- debugLogger7.warn(
19134
+ debugLogger8.warn(
18420
19135
  `reload: reloadModelProvidersConfig failed for session ${id}: ${err}`
18421
19136
  );
18422
19137
  }
@@ -18426,7 +19141,7 @@ ${outputText}
18426
19141
  try {
18427
19142
  await config.switchModel(authType, newModelName);
18428
19143
  } catch (err) {
18429
- debugLogger7.warn(
19144
+ debugLogger8.warn(
18430
19145
  `reload: switchModel failed for session ${id}: ${err}`
18431
19146
  );
18432
19147
  }
@@ -18434,7 +19149,7 @@ ${outputText}
18434
19149
  try {
18435
19150
  await config.refreshAuth(authType);
18436
19151
  } catch (err) {
18437
- debugLogger7.warn(
19152
+ debugLogger8.warn(
18438
19153
  `reload: refreshAuth failed for session ${id}: ${err}`
18439
19154
  );
18440
19155
  }
@@ -18453,7 +19168,7 @@ ${outputText}
18453
19168
  session.clearTodoStopGuardTrust();
18454
19169
  }
18455
19170
  } catch (err) {
18456
- debugLogger7.warn(
19171
+ debugLogger8.warn(
18457
19172
  `reload: setApprovalMode failed for session ${id}: ${err}`
18458
19173
  );
18459
19174
  }
@@ -18462,14 +19177,14 @@ ${outputText}
18462
19177
  try {
18463
19178
  await config.refreshHierarchicalMemory();
18464
19179
  } catch (err) {
18465
- debugLogger7.warn(
19180
+ debugLogger8.warn(
18466
19181
  `reload: refreshHierarchicalMemory failed for session ${id}: ${err}`
18467
19182
  );
18468
19183
  }
18469
19184
  try {
18470
19185
  await config.getGeminiClient()?.refreshSystemInstruction();
18471
19186
  } catch (err) {
18472
- debugLogger7.warn(
19187
+ debugLogger8.warn(
18473
19188
  `reload: refreshSystemInstruction failed for session ${id}: ${err}`
18474
19189
  );
18475
19190
  }
@@ -18479,7 +19194,7 @@ ${outputText}
18479
19194
  for (let i = 0; i < results.length; i++) {
18480
19195
  if (results[i].status === "rejected") {
18481
19196
  const reason = results[i].reason;
18482
- debugLogger7.warn(
19197
+ debugLogger8.warn(
18483
19198
  `Session ${sessions[i][0]} reload failed: ${reason}`
18484
19199
  );
18485
19200
  skipped.push(sessions[i][0]);
@@ -18524,7 +19239,7 @@ ${outputText}
18524
19239
  );
18525
19240
  for (const result of configResults) {
18526
19241
  if (result.status === "rejected") {
18527
- debugLogger7.warn(`Skill config refresh failed: ${result.reason}`);
19242
+ debugLogger8.warn(`Skill config refresh failed: ${result.reason}`);
18528
19243
  }
18529
19244
  }
18530
19245
  }
@@ -18543,7 +19258,7 @@ ${outputText}
18543
19258
  for (let i = 0; i < results.length; i++) {
18544
19259
  if (results[i].status === "rejected") {
18545
19260
  const reason2 = results[i].reason;
18546
- debugLogger7.warn(
19261
+ debugLogger8.warn(
18547
19262
  `Session ${sessions[i].getId()} skill refresh failed: ${reason2}`
18548
19263
  );
18549
19264
  }
@@ -18587,12 +19302,12 @@ ${outputText}
18587
19302
  disposeTranscriptReplayConfig(config) {
18588
19303
  try {
18589
19304
  void Promise.resolve(config.getToolRegistry()?.stop()).catch((err) => {
18590
- debugLogger7.debug(
19305
+ debugLogger8.debug(
18591
19306
  `Transcript replay config tool registry stop failed: ${err instanceof Error ? err.message : String(err)}`
18592
19307
  );
18593
19308
  });
18594
19309
  } catch (err) {
18595
- debugLogger7.debug(
19310
+ debugLogger8.debug(
18596
19311
  `Transcript replay config tool registry stop failed: ${err instanceof Error ? err.message : String(err)}`
18597
19312
  );
18598
19313
  }
@@ -18606,7 +19321,7 @@ ${outputText}
18606
19321
  this.transcriptReplayConfigCache.clear();
18607
19322
  }
18608
19323
  async getTranscriptReplayConfig(cwd, settings) {
18609
- const key = path3.resolve(cwd);
19324
+ const key = path4.resolve(cwd);
18610
19325
  const cached = this.transcriptReplayConfigCache.get(key);
18611
19326
  if (cached?.settings === settings) {
18612
19327
  if (cached.config) {
@@ -18687,7 +19402,10 @@ ${outputText}
18687
19402
  });
18688
19403
  } catch (error) {
18689
19404
  if (error instanceof SessionIdConflictError) {
18690
- throw RequestError.invalidParams(void 0, error.message);
19405
+ throw new RequestError(ACP_ERROR_CODES.INVALID_PARAMS, error.message, {
19406
+ errorKind: "session_id_conflict",
19407
+ sessionId: error.sessionId
19408
+ });
18691
19409
  }
18692
19410
  const writerError = getSessionWriterError(error);
18693
19411
  if (writerError) {
@@ -18840,7 +19558,7 @@ ${outputText}
18840
19558
  sessionId: sid,
18841
19559
  ...event
18842
19560
  }).catch((err) => {
18843
- debugLogger7.debug(
19561
+ debugLogger8.debug(
18844
19562
  `MCP budget extNotification dropped (session=${sid}, kind=${event.kind}): ${err instanceof Error ? err.message : String(err)}`
18845
19563
  );
18846
19564
  });
@@ -18870,7 +19588,7 @@ ${outputText}
18870
19588
  try {
18871
19589
  await config.waitForMcpReady();
18872
19590
  } catch (err) {
18873
- debugLogger7.error(
19591
+ debugLogger8.error(
18874
19592
  `MCP discovery readiness failed: ${err instanceof Error ? err.message : String(err)}`
18875
19593
  );
18876
19594
  return;
@@ -18894,7 +19612,7 @@ ${outputText}
18894
19612
  try {
18895
19613
  await config.refreshAuth(selectedType, true);
18896
19614
  } catch (e) {
18897
- debugLogger7.error(`Authentication failed: ${e}`);
19615
+ debugLogger8.error(`Authentication failed: ${e}`);
18898
19616
  throw RequestError.authRequired(
18899
19617
  {
18900
19618
  authMethods: pickAuthMethodsForAuthRequired(selectedType)
@@ -18918,7 +19636,7 @@ ${outputText}
18918
19636
  }
18919
19637
  async createAndStoreSession(config, settings, sessionData, options = {}) {
18920
19638
  this.assertManagedSessionAdmission();
18921
- const sessionId = config.getSessionId();
19639
+ const sessionId = normalizeSessionIdForLookup(config.getSessionId());
18922
19640
  const geminiClient = config.getGeminiClient();
18923
19641
  const needsInitialize = !geminiClient.isInitialized();
18924
19642
  if (needsInitialize) {
@@ -18926,7 +19644,11 @@ ${outputText}
18926
19644
  }
18927
19645
  this.assertManagedSessionAdmission();
18928
19646
  if (this.sessions.has(sessionId)) {
18929
- throw new Error(`Session ${sessionId} is already active.`);
19647
+ throw new RequestError(
19648
+ ACP_ERROR_CODES.INVALID_PARAMS,
19649
+ `Session ${sessionId} is already active.`,
19650
+ { errorKind: "session_id_conflict", sessionId }
19651
+ );
18930
19652
  }
18931
19653
  const session = new Session(
18932
19654
  sessionId,
@@ -19113,3 +19835,8 @@ export {
19113
19835
  * Copyright 2025 Qwen
19114
19836
  * SPDX-License-Identifier: Apache-2.0
19115
19837
  */
19838
+ /**
19839
+ * @license
19840
+ * Copyright 2025 Google LLC
19841
+ * SPDX-License-Identifier: Apache-2.0
19842
+ */