@qwen-code/qwen-code 0.19.12 → 0.20.0-nightly.20260721.cda0e0348

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 (280) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +1 -1
  2. package/bundled/qc-helper/docs/features/commands.md +54 -0
  3. package/bundled/qc-helper/docs/integration-github-action.md +1 -1
  4. package/bundled/qc-helper/docs/qwen-serve.md +44 -6
  5. package/bundled/review/DESIGN.md +2 -2
  6. package/bundled/review/SKILL.md +13 -9
  7. package/chunks/{MaxSizedBox-QOXLJGAF.js → MaxSizedBox-EE76OHAP.js} +30 -27
  8. package/chunks/{StandaloneSessionPicker-FLV6CGYJ.js → StandaloneSessionPicker-WZH4PC3K.js} +50 -45
  9. package/chunks/{acpAgent-OB2CTF3P.js → acpAgent-2ATF4LMP.js} +437 -156
  10. package/chunks/{agent-CKSI7BTR.js → agent-KTOOFWMV.js} +22 -22
  11. package/chunks/{agent-headless-U36LIYTU.js → agent-headless-WVJCQ27D.js} +22 -22
  12. package/chunks/{anthropicContentGenerator-ZZRGFEES.js → anthropicContentGenerator-W4JLNYWQ.js} +6 -5
  13. package/chunks/{artifact-tool-PHO5XEGZ.js → artifact-tool-WBCAMD3O.js} +2 -2
  14. package/chunks/{askUserQuestion-CEPBT47X.js → askUserQuestion-6DZC4UV5.js} +2 -2
  15. package/chunks/{bridge-AIKTINJG.js → bridge-T4TLAZSJ.js} +25 -25
  16. package/chunks/build-SSCNEHZZ.js +62 -0
  17. package/chunks/{ca-2SL2BXTK.js → ca-ISKASTR5.js} +606 -200
  18. package/chunks/{channel-worker-group-NEUVTPB2.js → channel-worker-group-QZV2SP5U.js} +4 -4
  19. package/chunks/{channel-worker-manager-7CQVOVWV.js → channel-worker-manager-3GMAU45H.js} +4 -4
  20. package/chunks/{channel-worker-supervisor-3BU2KNCZ.js → channel-worker-supervisor-QCXSXCRY.js} +3 -3
  21. package/chunks/{chunk-6ETOSWAO.js → chunk-246TW4IX.js} +3 -3
  22. package/chunks/{chunk-2CCDMJM7.js → chunk-25Y6JSH2.js} +3 -3
  23. package/chunks/{chunk-XSEWNUMZ.js → chunk-2CWOJ2FA.js} +8 -8
  24. package/chunks/{chunk-UZC5VPOJ.js → chunk-2GFRA3MN.js} +3 -3
  25. package/chunks/chunk-2GOPPEHK.js +442 -0
  26. package/chunks/{chunk-MRE77ST5.js → chunk-2ITGJJE2.js} +69 -2216
  27. package/chunks/{chunk-BABX5XRO.js → chunk-2LI23QA6.js} +1 -1
  28. package/chunks/{chunk-EFAXBOQO.js → chunk-32F7BZSK.js} +7 -7
  29. package/chunks/chunk-43T5WDQ7.js +127 -0
  30. package/chunks/{chunk-DJ4VHAFJ.js → chunk-4CWPMWCD.js} +7 -3
  31. package/chunks/{chunk-GMUPIMHF.js → chunk-4RA7PWIY.js} +3 -3
  32. package/chunks/{chunk-6IITZE7O.js → chunk-5JX5EWR5.js} +7 -7
  33. package/chunks/{chunk-OBSLEYCD.js → chunk-5PZ6R37W.js} +29 -2
  34. package/chunks/{chunk-HTHUX2T5.js → chunk-5QWWOFGG.js} +0 -1
  35. package/chunks/{chunk-3DJY4IFO.js → chunk-5SCI6E3E.js} +1 -1
  36. package/chunks/{chunk-GSPWDTYY.js → chunk-5WG2K5RH.js} +53 -16
  37. package/chunks/{chunk-NPMVLWYL.js → chunk-5YVZ2XLV.js} +6 -6
  38. package/chunks/{chunk-TKASNYDS.js → chunk-6DHWO5ZF.js} +3 -3
  39. package/chunks/{chunk-4CHDYDG3.js → chunk-6EFTQYW7.js} +1 -1
  40. package/chunks/{chunk-RKUMFUFM.js → chunk-6MC5ASQK.js} +4 -4
  41. package/chunks/{chunk-HZ4M2UQD.js → chunk-6RVJRVQR.js} +1 -1
  42. package/chunks/{chunk-W6CQPLWM.js → chunk-6ZBPS62S.js} +1 -1
  43. package/chunks/chunk-7KGXAXF7.js +114 -0
  44. package/chunks/{chunk-PK7COE5O.js → chunk-ABIL4ZQU.js} +1 -1
  45. package/chunks/{chunk-OEHCAWUA.js → chunk-ACW3VNUE.js} +2 -2
  46. package/chunks/{chunk-APOFULHK.js → chunk-AWVS63WA.js} +7 -6
  47. package/chunks/{chunk-KGWA7XYL.js → chunk-AY3CSB6F.js} +6 -226
  48. package/chunks/{chunk-XAAEDML2.js → chunk-AYCDXHZB.js} +1 -1
  49. package/chunks/{chunk-42VIHAYT.js → chunk-B452RETY.js} +1 -1
  50. package/chunks/{chunk-VAJS2E2D.js → chunk-BDBMYST4.js} +1 -1
  51. package/chunks/{chunk-5N7M4XYN.js → chunk-BUKOHGBE.js} +5 -5
  52. package/chunks/{chunk-F2RR4HO2.js → chunk-BVLROR2T.js} +1 -1
  53. package/chunks/{chunk-WIYV7CSF.js → chunk-BWK3FX3K.js} +3 -3
  54. package/chunks/{chunk-UE5TZ55T.js → chunk-C27BYUX6.js} +29 -2
  55. package/chunks/{chunk-KRMARA3A.js → chunk-CG2HPAVD.js} +29 -13
  56. package/chunks/{chunk-UOA2IHRI.js → chunk-CPCVCKKF.js} +1 -1
  57. package/chunks/{chunk-HD6EGS5K.js → chunk-CUJX3F4X.js} +31 -6
  58. package/chunks/{chunk-4RPARQ5D.js → chunk-D2VIDMVM.js} +2 -2
  59. package/chunks/{chunk-PUKUUASO.js → chunk-DMRO4GU2.js} +1 -1
  60. package/chunks/{chunk-64GC5EMF.js → chunk-DZZIOIVF.js} +1 -1
  61. package/chunks/{chunk-FUSMC3SZ.js → chunk-E5QFCC4X.js} +13 -8
  62. package/chunks/{chunk-LKR7QQ63.js → chunk-EAUYY7SS.js} +3 -3
  63. package/chunks/{chunk-NE6HHLL3.js → chunk-EDMGFJ3E.js} +2 -2
  64. package/chunks/{chunk-J2MKYJKZ.js → chunk-EIAK6Q2B.js} +2 -2
  65. package/chunks/{chunk-WEPXQKGP.js → chunk-EZVDJFZ7.js} +1 -1
  66. package/chunks/{chunk-NALRQ3SG.js → chunk-FCUUJKZF.js} +394 -128
  67. package/chunks/{chunk-4XCVGEEX.js → chunk-FSL5W5TI.js} +3 -3
  68. package/chunks/{chunk-CHPQFLW6.js → chunk-FYA3Y5JR.js} +5 -5
  69. package/chunks/{chunk-V4PCIS25.js → chunk-FZVSFBNW.js} +69 -7
  70. package/chunks/{chunk-4MPYGENG.js → chunk-G45NOBV7.js} +6 -6
  71. package/chunks/{chunk-OSSDHJDU.js → chunk-G45X5TRN.js} +1 -1
  72. package/chunks/{chunk-3B6PSWHE.js → chunk-GH7OEOYU.js} +4 -4
  73. package/chunks/{chunk-KANTXY7B.js → chunk-GKY2OJ7R.js} +2 -2
  74. package/chunks/chunk-GMGDLUC7.js +37 -0
  75. package/chunks/{chunk-2476XGOU.js → chunk-GPILFVPY.js} +1 -1
  76. package/chunks/{chunk-EISVEV45.js → chunk-H24SOJIQ.js} +2 -2
  77. package/chunks/{chunk-J6NT5YTN.js → chunk-H2XVO6NE.js} +1 -289
  78. package/chunks/{chunk-QIFTJDBY.js → chunk-IM2A6YO3.js} +1 -1
  79. package/chunks/{chunk-R3EDIMYZ.js → chunk-IYZENXFW.js} +1 -1
  80. package/chunks/{chunk-LPHGXXZX.js → chunk-JD3MKVKL.js} +1 -1
  81. package/chunks/{chunk-NUHSLBJZ.js → chunk-JNWZQ27S.js} +15 -9
  82. package/chunks/{chunk-ETN2G32U.js → chunk-JPRLCXAO.js} +4 -4
  83. package/chunks/{chunk-WHQNBBWW.js → chunk-JQMBPGOU.js} +2 -2
  84. package/chunks/{chunk-5QSVANRT.js → chunk-JR6UJ24K.js} +2 -2
  85. package/chunks/{chunk-VLHQMOZK.js → chunk-JRW46GQX.js} +3 -3
  86. package/chunks/{chunk-DUR7BZYK.js → chunk-KRI4VCHX.js} +53 -28
  87. package/chunks/{chunk-PR5XQ73G.js → chunk-KTNIZG2C.js} +2 -2
  88. package/chunks/{chunk-QSG4ZFG4.js → chunk-KTUQMDEP.js} +1 -1
  89. package/chunks/{chunk-HVGJWOR6.js → chunk-L4YSPHR4.js} +2 -2
  90. package/chunks/{chunk-BEZPRKD3.js → chunk-LC5CAVMS.js} +160 -2
  91. package/chunks/{chunk-67Q33DQY.js → chunk-LLDGOZMJ.js} +4 -4
  92. package/chunks/{chunk-UCTCDLDS.js → chunk-LWQ4IAOJ.js} +136 -4
  93. package/chunks/{chunk-GEHSF7MS.js → chunk-NEEB7UEN.js} +2545 -1974
  94. package/chunks/{chunk-GCY7QTCE.js → chunk-NO6XTCYT.js} +1822 -424
  95. package/chunks/{chunk-JCJPZMJV.js → chunk-OOCI5VVU.js} +1 -1
  96. package/chunks/{chunk-XSPFQQRE.js → chunk-OONJNQ42.js} +3 -3
  97. package/chunks/{chunk-ANRANWVE.js → chunk-OP4MOGXF.js} +1 -1
  98. package/chunks/{chunk-GW7BONBU.js → chunk-OV2KB55J.js} +5 -5
  99. package/chunks/{chunk-CPU6I5YV.js → chunk-P64HXIC5.js} +115 -32
  100. package/chunks/{chunk-SGPFJMRP.js → chunk-PBATSWUQ.js} +1 -1
  101. package/chunks/{chunk-GXFYV7MP.js → chunk-PFKNXN67.js} +1106 -592
  102. package/chunks/{chunk-KNGZ5EYL.js → chunk-PYNCSQSI.js} +198 -120
  103. package/chunks/{chunk-I7RRHHYG.js → chunk-QKTHJXCS.js} +1 -1
  104. package/chunks/chunk-QKYTTBYW.js +624 -0
  105. package/chunks/{chunk-76BFY7AF.js → chunk-QTERJVPZ.js} +1 -6
  106. package/chunks/{chunk-W4UN42YP.js → chunk-R3VZNHRX.js} +85 -21
  107. package/chunks/chunk-R5N7NF5D.js +1187 -0
  108. package/chunks/{chunk-ZSDFNE6Y.js → chunk-RF34V75B.js} +3 -3
  109. package/chunks/{chunk-HCCR43AY.js → chunk-RFIAR4YL.js} +1 -1
  110. package/chunks/chunk-RS7MT2QG.js +305 -0
  111. package/chunks/{chunk-BKNPMEN6.js → chunk-RVLZCXEE.js} +162 -17
  112. package/chunks/chunk-SV5PQVQE.js +71 -0
  113. package/chunks/{chunk-3ESL7JXA.js → chunk-U4VGYZN7.js} +3 -3
  114. package/chunks/{chunk-4CA4WUMS.js → chunk-UEY4AYUL.js} +2 -2
  115. package/chunks/{chunk-ZGT623SG.js → chunk-USTF7LPI.js} +12 -12
  116. package/chunks/chunk-V7RNNPGC.js +44 -0
  117. package/chunks/{chunk-VEFR4XJQ.js → chunk-W3BKN3LO.js} +1 -1
  118. package/chunks/{chunk-4SJJT466.js → chunk-WQQDJE2P.js} +94 -177
  119. package/chunks/{chunk-KMJOMWHE.js → chunk-WRRF6TEQ.js} +1 -1
  120. package/chunks/{chunk-GLH2NTPB.js → chunk-XCHUDLER.js} +1 -1
  121. package/chunks/{chunk-7SX6WZNO.js → chunk-XVVH63JG.js} +3 -3
  122. package/chunks/{chunk-N47VAEAJ.js → chunk-XZOBDSDG.js} +2379 -1291
  123. package/chunks/chunk-YGIUIIIF.js +125 -0
  124. package/chunks/{chunk-335ECZTA.js → chunk-ZEOZL37W.js} +1 -1
  125. package/chunks/{computer-use-4PUGCUQK.js → computer-use-M6MGRJF2.js} +22 -22
  126. package/chunks/{config-utils-6PJUXHLI.js → config-utils-MOGE4EVB.js} +3 -3
  127. package/chunks/{contextCommand-C57KTWFV.js → contextCommand-HTRJJYNE.js} +25 -26
  128. package/chunks/{create-sub-session-5Q42XR6I.js → create-sub-session-MB35IHCR.js} +22 -22
  129. package/chunks/{create-sub-session-DIJOV6HV.js → create-sub-session-P26FE5GG.js} +2 -2
  130. package/chunks/{cron-create-X462ERYA.js → cron-create-JWFHBDRQ.js} +4 -4
  131. package/chunks/{cron-delete-SL5UJUM3.js → cron-delete-GDX4E26G.js} +4 -4
  132. package/chunks/{cron-list-3MD6SVXI.js → cron-list-USMAIWPT.js} +4 -4
  133. package/chunks/{daemon-ZW6LHOXT.js → daemon-KLPTQIE4.js} +287 -143
  134. package/chunks/{daemon-status-provider-YPV3UXHT.js → daemon-status-provider-67EKK6S3.js} +29 -29
  135. package/chunks/{dist-NUXRQHC5.js → dist-OAV7LJGJ.js} +1 -1
  136. package/chunks/{dist-XLE6ODMB.js → dist-OMW6WDEO.js} +1 -1
  137. package/chunks/{dist-J2H4KTLB.js → dist-PJLG2XYX.js} +1 -1
  138. package/chunks/{dist-IEQSDXS7.js → dist-UIFWIFRO.js} +2 -2
  139. package/chunks/{dist-IGZMVS5R.js → dist-VGJTZL4E.js} +33 -22
  140. package/chunks/{dist-3DQNQJ6H.js → dist-XBJVSWS2.js} +1 -1
  141. package/chunks/{earlyInputCapture-5VDWSYAM.js → earlyInputCapture-7QJX25AC.js} +23 -23
  142. package/chunks/{edit-GORZTX2U.js → edit-BTPQWGAA.js} +23 -23
  143. package/chunks/{enter-worktree-LJB2AW4L.js → enter-worktree-N3SEYKOO.js} +22 -22
  144. package/chunks/{enterPlanMode-LIIPP37T.js → enterPlanMode-TN2JV5MY.js} +28 -23
  145. package/chunks/{environment-HQ2UHJ35.js → environment-HP6RK262.js} +24 -24
  146. package/chunks/{errors-6JD5VMVQ.js → errors-VHGRDDOQ.js} +24 -24
  147. package/chunks/{exit-worktree-IEP2WHOV.js → exit-worktree-FI3SQY3U.js} +22 -22
  148. package/chunks/{exitPlanMode-U5Z6XBLO.js → exitPlanMode-NZWRVIIY.js} +22 -22
  149. package/chunks/{fast-path-HFKNMP23.js → fast-path-EGP7AXNR.js} +3 -2
  150. package/chunks/{gemini-C2SCJH3N.js → gemini-AN5YMD5O.js} +70 -68
  151. package/chunks/{geminiContentGenerator-ADZTXEKV.js → geminiContentGenerator-ABTMU4FE.js} +4 -4
  152. package/chunks/{glob-GOAPGD6G.js → glob-5YABOPJB.js} +22 -22
  153. package/chunks/{grep-HZLSTX7D.js → grep-U67FKUJT.js} +22 -22
  154. package/chunks/{handleAutoUpdate-UF74WGFE.js → handleAutoUpdate-OOKBP5VD.js} +27 -28
  155. package/chunks/{i18n-FMXIYUOC.js → i18n-GMQV324P.js} +23 -23
  156. package/chunks/{initializer-ERDBM3DU.js → initializer-NWALZGQ5.js} +28 -28
  157. package/chunks/{installationInfo-LROMXYLX.js → installationInfo-Y3M433E7.js} +25 -23
  158. package/chunks/{keychain-token-storage-K23CFKGN.js → keychain-token-storage-DWRJMNH3.js} +2 -2
  159. package/chunks/{list-6JPJROU5.js → list-CQDDWHTS.js} +30 -30
  160. package/chunks/{loadedSettingsAdapter-QCWYUBBF.js → loadedSettingsAdapter-I5KG37EI.js} +27 -27
  161. package/chunks/{loop-wakeup-6H7OENTB.js → loop-wakeup-5GLTUBHA.js} +5 -5
  162. package/chunks/{ls-APTSOOS5.js → ls-FHBY3Y7I.js} +4 -4
  163. package/chunks/{lsp-HPACPJAN.js → lsp-B6VMEW6Y.js} +2 -2
  164. package/chunks/{mcp-3P3KWYWO.js → mcp-24HHCBSP.js} +27 -27
  165. package/chunks/{monitor-LMYKCF6R.js → monitor-Z7NZNNRC.js} +22 -22
  166. package/chunks/nonInteractiveCli-GVF2XDJT.js +126 -0
  167. package/chunks/{notebook-edit-IBEOVZ6A.js → notebook-edit-GFOYAQAZ.js} +23 -23
  168. package/chunks/{openaiContentGenerator-42PZKET5.js → openaiContentGenerator-XAAYV6WR.js} +11 -11
  169. package/chunks/{pidfile-VTBDIGOH.js → pidfile-ILI37KRQ.js} +23 -23
  170. package/chunks/{processUtils-L7ZKOGDG.js → processUtils-LIPJMLVZ.js} +2 -2
  171. package/chunks/{qwenContentGenerator-VR2CNFGI.js → qwenContentGenerator-DLJ3KKGZ.js} +24 -24
  172. package/chunks/{qwenOAuth2-6LS2T3Q6.js → qwenOAuth2-J47FU5PW.js} +11 -11
  173. package/chunks/react-SG7JAQSZ.js +8 -0
  174. package/chunks/{read-file-VSKOE22I.js → read-file-LCQ2KNNP.js} +8 -8
  175. package/chunks/{read-mcp-resource-C6NT52T6.js → read-mcp-resource-AKCL7I43.js} +2 -2
  176. package/chunks/{record-artifact-ENCU7QCL.js → record-artifact-PEUB7727.js} +2 -2
  177. package/chunks/resumeHistoryUtils-PSCSAKA6.js +78 -0
  178. package/chunks/{ripGrep-5V5FLW2A.js → ripGrep-Y2XW4EFC.js} +22 -22
  179. package/chunks/{run-qwen-serve-LSOPP4R2.js → run-qwen-serve-DQ5ZIR36.js} +1459 -148
  180. package/chunks/{runtime-LT7R4CS5.js → runtime-6MQFF2A6.js} +33 -31
  181. package/chunks/{scheduler-YOWQ7KZP.js → scheduler-K4S7NY3G.js} +22 -22
  182. package/chunks/{send-message-5GZ4FX2V.js → send-message-3RHE7HSM.js} +3 -3
  183. package/chunks/{serve-VWLBXKGK.js → serve-JFAAPC5J.js} +27 -27
  184. package/chunks/{server-3RW3FYOH.js → server-QB6CHRZN.js} +866 -271
  185. package/chunks/{session-ZONXFOBQ.js → session-FKPVXAAB.js} +79 -163
  186. package/chunks/{settings-JC3VC53L.js → settings-CADELKSU.js} +26 -26
  187. package/chunks/{shell-2NGEMAVM.js → shell-EON6WVVH.js} +22 -22
  188. package/chunks/{skill-3U2T6H3E.js → skill-FKSYXJ5U.js} +10 -10
  189. package/chunks/{spawnChannel-QEAUPARQ.js → spawnChannel-VM5IHLJO.js} +24 -24
  190. package/chunks/{src-75ZPXO7B.js → src-Q4XB6SVD.js} +66 -22
  191. package/chunks/{standalone-update-UUJWJWYY.js → standalone-update-KGZHPBMA.js} +24 -24
  192. package/chunks/{startInteractiveUI-V7XISPQ6.js → startInteractiveUI-EYDJIIIZ.js} +5484 -2045
  193. package/chunks/{syntheticOutput-ULOVVLY4.js → syntheticOutput-FG5PQKIR.js} +3 -3
  194. package/chunks/{task-create-DUE2PMNI.js → task-create-HX32YXO7.js} +7 -7
  195. package/chunks/{task-list-WVPNX7BZ.js → task-list-QWSY4ZIU.js} +5 -5
  196. package/chunks/{task-stop-CPEQWOT6.js → task-stop-GWC6UWAL.js} +2 -2
  197. package/chunks/{task-update-HY2LNFFB.js → task-update-NCTAB73Q.js} +7 -7
  198. package/chunks/{team-create-R6AXDYPG.js → team-create-CYP3YKYT.js} +22 -22
  199. package/chunks/{team-delete-JJV6IUOA.js → team-delete-KK37HTOG.js} +5 -5
  200. package/chunks/{team-plan-approval-O2ZPPT64.js → team-plan-approval-5LXIFKNV.js} +22 -22
  201. package/chunks/{theme-manager-YIX2IC2D.js → theme-manager-QOUMDWMP.js} +23 -23
  202. package/chunks/{todoWrite-JHHIDOIV.js → todoWrite-ERCAMLFS.js} +4 -4
  203. package/chunks/{tool-search-5IE2VO7X.js → tool-search-Q27QHQU3.js} +9 -9
  204. package/chunks/{total-session-admission-K6APQYEF.js → total-session-admission-HWVCZ2WR.js} +25 -25
  205. package/chunks/{trustedFolders-GPSSPVBF.js → trustedFolders-C6664IQC.js} +23 -23
  206. package/chunks/{update-relaunch-4BVAPX6Y.js → update-relaunch-QC3E4FZW.js} +9 -9
  207. package/chunks/{updateCheck-AHTHWLAM.js → updateCheck-MVUKJMBX.js} +33 -26
  208. package/chunks/useAutoAcceptIndicator-J234IFIS.js +80 -0
  209. package/chunks/{validateNonInterActiveAuth-UKAPCWDM.js → validateNonInterActiveAuth-YPPEKX4N.js} +61 -63
  210. package/chunks/{version-EXGWKKQE.js → version-5IXFQ4PT.js} +1 -1
  211. package/chunks/{web-fetch-ZDNE6FF2.js → web-fetch-L62NQVKN.js} +10 -10
  212. package/chunks/{workflow-G7U6OQWS.js → workflow-6MHBBFQU.js} +23 -23
  213. package/chunks/{workspace-providers-status-W6CEA6YM.js → workspace-providers-status-ZTW2B5QU.js} +30 -30
  214. package/chunks/{workspace-registration-store-OGBMWCLC.js → workspace-registration-store-P6QHCSMU.js} +7 -1
  215. package/chunks/{workspace-registry-ZUWQM44P.js → workspace-registry-R54M5O3W.js} +25 -25
  216. package/chunks/{workspace-service-UXX5P7GU.js → workspace-service-WYLRGM4A.js} +32 -32
  217. package/chunks/{workspace-skills-status-635B5R7N.js → workspace-skills-status-NN5QFU3A.js} +28 -28
  218. package/chunks/{write-file-DR3HN7IH.js → write-file-EAT3CHUK.js} +23 -23
  219. package/cli.js +11 -11
  220. package/locales/ca.js +763 -201
  221. package/package.json +3 -3
  222. package/web-shell/assets/{arc-_dVIKMdB.js → arc-B0iTWRo2.js} +1 -1
  223. package/web-shell/assets/{architectureDiagram-3BPJPVTR-MuN3nKpL.js → architectureDiagram-3BPJPVTR-DSQP4-9D.js} +1 -1
  224. package/web-shell/assets/{blockDiagram-GPEHLZMM-BtmvJjzx.js → blockDiagram-GPEHLZMM-BNPVXVT3.js} +1 -1
  225. package/web-shell/assets/{c4Diagram-AAUBKEIU-Dvi58_BU.js → c4Diagram-AAUBKEIU-DEHfJFiD.js} +1 -1
  226. package/web-shell/assets/channel-tVz-qNSq.js +1 -0
  227. package/web-shell/assets/{chunk-2J33WTMH-YqxOVhS1.js → chunk-2J33WTMH-VZ0uL1p9.js} +1 -1
  228. package/web-shell/assets/{chunk-4BX2VUAB-DoBgbC9z.js → chunk-4BX2VUAB-D5TKmvwG.js} +1 -1
  229. package/web-shell/assets/{chunk-55IACEB6-3NEQrBAr.js → chunk-55IACEB6-BDW1Lcq-.js} +1 -1
  230. package/web-shell/assets/{chunk-727SXJPM-DrCZQxp0.js → chunk-727SXJPM-Cj4h85iM.js} +1 -1
  231. package/web-shell/assets/{chunk-AQP2D5EJ-m_g3zjgv.js → chunk-AQP2D5EJ-5LeqiOhZ.js} +1 -1
  232. package/web-shell/assets/{chunk-FMBD7UC4-D1_crABJ.js → chunk-FMBD7UC4-BaTgsco7.js} +1 -1
  233. package/web-shell/assets/{chunk-ND2GUHAM-BdhgVtBx.js → chunk-ND2GUHAM-t3uGlIUk.js} +1 -1
  234. package/web-shell/assets/{chunk-QZHKN3VN-BlmThhm-.js → chunk-QZHKN3VN-rOnNXL2Q.js} +1 -1
  235. package/web-shell/assets/classDiagram-4FO5ZUOK-CWuaBxYV.js +1 -0
  236. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CWuaBxYV.js +1 -0
  237. package/web-shell/assets/{cose-bilkent-S5V4N54A-Cbjm_00Z.js → cose-bilkent-S5V4N54A-CcqXykgA.js} +1 -1
  238. package/web-shell/assets/{dagre-BM42HDAG-C39QNVgC.js → dagre-BM42HDAG-Dkjrchoy.js} +1 -1
  239. package/web-shell/assets/{diagram-2AECGRRQ-DNXSAixC.js → diagram-2AECGRRQ-B6lcra9M.js} +1 -1
  240. package/web-shell/assets/{diagram-5GNKFQAL-BCbGUPEA.js → diagram-5GNKFQAL-bAIzq3PT.js} +1 -1
  241. package/web-shell/assets/{diagram-KO2AKTUF-1eujKSDC.js → diagram-KO2AKTUF-G9MAZDNW.js} +1 -1
  242. package/web-shell/assets/{diagram-LMA3HP47-DUMKXgql.js → diagram-LMA3HP47-DVLF1uWZ.js} +1 -1
  243. package/web-shell/assets/{diagram-OG6HWLK6-BFktU3_u.js → diagram-OG6HWLK6-Cf7y20Tc.js} +1 -1
  244. package/web-shell/assets/{erDiagram-TEJ5UH35-BvJC7DLk.js → erDiagram-TEJ5UH35-C7ETZB3o.js} +1 -1
  245. package/web-shell/assets/{flowDiagram-I6XJVG4X-Cgu3PlOt.js → flowDiagram-I6XJVG4X-Cl2xgL6J.js} +1 -1
  246. package/web-shell/assets/{ganttDiagram-6RSMTGT7-DLNXN5Xh.js → ganttDiagram-6RSMTGT7-BgjbMs3q.js} +1 -1
  247. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-BQFRDv6R.js → gitGraphDiagram-PVQCEYII-JVX34Omm.js} +1 -1
  248. package/web-shell/assets/index-48bIcdqF.js +1197 -0
  249. package/web-shell/assets/{index-CdC3pjP3.js → index-BG7Zc4f_.js} +1 -1
  250. package/web-shell/assets/index-BI-JAO07.css +5 -0
  251. package/web-shell/assets/{infoDiagram-5YYISTIA-DT2mOSvp.js → infoDiagram-5YYISTIA-3NYyMeZU.js} +1 -1
  252. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-9fy_K4bd.js → ishikawaDiagram-YF4QCWOH-C03VCu-U.js} +1 -1
  253. package/web-shell/assets/{journeyDiagram-JHISSGLW-CoGSEuhE.js → journeyDiagram-JHISSGLW-C9PuBRZW.js} +1 -1
  254. package/web-shell/assets/{kanban-definition-UN3LZRKU-BP9hHYIj.js → kanban-definition-UN3LZRKU-C3LvioWR.js} +1 -1
  255. package/web-shell/assets/{linear-uIroDsmp.js → linear-Du6Yw8N_.js} +1 -1
  256. package/web-shell/assets/{mermaid.core-BUwoStsA.js → mermaid.core-BXY5D2-X.js} +5 -5
  257. package/web-shell/assets/{mindmap-definition-RKZ34NQL-DZB-FWim.js → mindmap-definition-RKZ34NQL-2UrHLaDp.js} +1 -1
  258. package/web-shell/assets/{pieDiagram-4H26LBE5-YPptloKl.js → pieDiagram-4H26LBE5-dC03ml45.js} +1 -1
  259. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-dgk3DSzm.js → quadrantDiagram-W4KKPZXB-CD6jARrp.js} +1 -1
  260. package/web-shell/assets/{requirementDiagram-4Y6WPE33-BH2En2i9.js → requirementDiagram-4Y6WPE33-BrK8aXfv.js} +1 -1
  261. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-BB98feeI.js → sankeyDiagram-5OEKKPKP-B5Vitki_.js} +1 -1
  262. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CunAIGh8.js → sequenceDiagram-3UESZ5HK-CBy2t6Bo.js} +1 -1
  263. package/web-shell/assets/{stateDiagram-AJRCARHV-DTJs_-I2.js → stateDiagram-AJRCARHV-Enrka6T2.js} +1 -1
  264. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DUtYfXpW.js +1 -0
  265. package/web-shell/assets/{timeline-definition-PNZ67QCA-Cd4AN7O0.js → timeline-definition-PNZ67QCA-CwFq78ss.js} +1 -1
  266. package/web-shell/assets/{vennDiagram-CIIHVFJN-xIG-rUU9.js → vennDiagram-CIIHVFJN-BkOidM0g.js} +1 -1
  267. package/web-shell/assets/{wardley-L42UT6IY-D1UyjIcG.js → wardley-L42UT6IY-D_j13hQW.js} +1 -1
  268. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BVM0Mb99.js → wardleyDiagram-YWT4CUSO-7EveB1w6.js} +1 -1
  269. package/web-shell/assets/{xychartDiagram-2RQKCTM6-BX31JDSz.js → xychartDiagram-2RQKCTM6-DRkBhMXr.js} +1 -1
  270. package/web-shell/index.html +2 -2
  271. package/chunks/chunk-EDFD7VOX.js +0 -368
  272. package/chunks/chunk-GFYFLDEG.js +0 -709
  273. package/chunks/chunk-LUJQUNKY.js +0 -3288
  274. package/chunks/nonInteractiveCli-YURFHZV5.js +0 -129
  275. package/web-shell/assets/channel-Bi5TehaT.js +0 -1
  276. package/web-shell/assets/classDiagram-4FO5ZUOK-BKhhRdd1.js +0 -1
  277. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BKhhRdd1.js +0 -1
  278. package/web-shell/assets/index-C_ouplMQ.js +0 -1187
  279. package/web-shell/assets/index-XGDFJE-X.css +0 -5
  280. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DrfFMYta.js +0 -1
@@ -37,7 +37,7 @@ import {
37
37
  CronScheduler,
38
38
  DEFAULT_RECURRING_MAX_AGE_DAYS,
39
39
  normalizeRecurringMaxAge
40
- } from "./chunk-LKR7QQ63.js";
40
+ } from "./chunk-EAUYY7SS.js";
41
41
  import {
42
42
  consumeUnread,
43
43
  forwardApproval,
@@ -46,13 +46,13 @@ import {
46
46
  sendStructuredMessage,
47
47
  wrapConfirmWithBadge,
48
48
  writeMessage
49
- } from "./chunk-4XCVGEEX.js";
49
+ } from "./chunk-FSL5W5TI.js";
50
50
  import {
51
51
  claimTask,
52
52
  listTasks,
53
53
  onTasksUpdated,
54
54
  unassignTeammateTasks
55
- } from "./chunk-XSPFQQRE.js";
55
+ } from "./chunk-OONJNQ42.js";
56
56
  import {
57
57
  assignTeammateColor,
58
58
  classifyShutdownResponse,
@@ -60,7 +60,7 @@ import {
60
60
  formatAgentId,
61
61
  generateUniqueTeammateName,
62
62
  writeTeamFile
63
- } from "./chunk-4RPARQ5D.js";
63
+ } from "./chunk-D2VIDMVM.js";
64
64
  import {
65
65
  require_proper_lockfile
66
66
  } from "./chunk-E2UVIFI2.js";
@@ -103,7 +103,7 @@ import {
103
103
  runWithRuntimeContentGenerator,
104
104
  shouldUsePlanOnlyReminderInSubagentContext,
105
105
  spawnBlockReason
106
- } from "./chunk-UOA2IHRI.js";
106
+ } from "./chunk-CPCVCKKF.js";
107
107
  import {
108
108
  getTeammateContext,
109
109
  isTeammate,
@@ -114,7 +114,7 @@ import {
114
114
  escapeSystemReminderTags,
115
115
  escapeXml,
116
116
  renderAvailableSkillsBlock
117
- } from "./chunk-OSSDHJDU.js";
117
+ } from "./chunk-G45X5TRN.js";
118
118
  import {
119
119
  DefaultHookOutput,
120
120
  HOOKS_CONFIG_FIELDS,
@@ -129,7 +129,7 @@ import {
129
129
  createHookOutput,
130
130
  getHookKey,
131
131
  isToolArtifactLike
132
- } from "./chunk-SGPFJMRP.js";
132
+ } from "./chunk-PBATSWUQ.js";
133
133
  import {
134
134
  DEFAULT_FILE_FILTERING_OPTIONS,
135
135
  DEFAULT_QWEN_CUSTOM_IGNORE_FILE_NAMES,
@@ -139,17 +139,17 @@ import {
139
139
  getQwenIgnoreFileNames,
140
140
  isPathWithinRoot,
141
141
  require_ignore
142
- } from "./chunk-335ECZTA.js";
142
+ } from "./chunk-ZEOZL37W.js";
143
143
  import {
144
144
  BaseTokenStorage,
145
145
  KeychainTokenStorage
146
- } from "./chunk-JCJPZMJV.js";
146
+ } from "./chunk-OOCI5VVU.js";
147
147
  import {
148
148
  classifyRetryError,
149
149
  isFallbackEligible,
150
150
  isUnattendedMode,
151
151
  retryWithBackoff
152
- } from "./chunk-6ETOSWAO.js";
152
+ } from "./chunk-246TW4IX.js";
153
153
  import {
154
154
  openBrowserSecurely,
155
155
  shouldAttemptBrowserLaunch
@@ -300,7 +300,7 @@ import {
300
300
  updateMCPServerStatus,
301
301
  writeLine,
302
302
  writeLineSync
303
- } from "./chunk-CPU6I5YV.js";
303
+ } from "./chunk-P64HXIC5.js";
304
304
  import {
305
305
  E_TIMEOUT,
306
306
  Mutex,
@@ -324,16 +324,16 @@ import {
324
324
  isManagedMemoryPath,
325
325
  isTeamAutoMemPath,
326
326
  isUserAutoMemPath
327
- } from "./chunk-LPHGXXZX.js";
327
+ } from "./chunk-JD3MKVKL.js";
328
328
  import {
329
329
  atomicWriteFile,
330
330
  atomicWriteFileSync,
331
331
  atomicWriteJSON,
332
332
  renameWithRetry
333
- } from "./chunk-VAJS2E2D.js";
333
+ } from "./chunk-BDBMYST4.js";
334
334
  import {
335
335
  STRUCTURED_OUTPUT_REDACTED_ARGS
336
- } from "./chunk-WEPXQKGP.js";
336
+ } from "./chunk-EZVDJFZ7.js";
337
337
  import {
338
338
  AgentStatistics,
339
339
  BaseDeclarativeTool,
@@ -350,7 +350,7 @@ import {
350
350
  require_dist,
351
351
  require_fast_deep_equal,
352
352
  require_fast_uri
353
- } from "./chunk-ANRANWVE.js";
353
+ } from "./chunk-OP4MOGXF.js";
354
354
  import {
355
355
  DEFAULT_OPENAI_BASE_URL
356
356
  } from "./chunk-FEOZBUMT.js";
@@ -361,7 +361,7 @@ import {
361
361
  } from "./chunk-DJ2GSRLV.js";
362
362
  import {
363
363
  require_undici
364
- } from "./chunk-4CHDYDG3.js";
364
+ } from "./chunk-6EFTQYW7.js";
365
365
  import {
366
366
  DEFAULT_TOKEN_LIMIT,
367
367
  OUTPUT_TOKEN_CEILING,
@@ -369,10 +369,12 @@ import {
369
369
  defaultOutputCeiling,
370
370
  getToolCallPreparations,
371
371
  knownTokenLimit,
372
+ normalizeMcpToolName,
372
373
  parsePositiveIntegerEnvValue,
374
+ sanitizeToolNameForProvider,
373
375
  setToolCallPreparations,
374
376
  tokenLimit
375
- } from "./chunk-V4PCIS25.js";
377
+ } from "./chunk-FZVSFBNW.js";
376
378
  import {
377
379
  FinishReason,
378
380
  FunctionCallingConfigMode,
@@ -408,7 +410,7 @@ import {
408
410
  tildeifyPath,
409
411
  toFriendlyError,
410
412
  unescapePath
411
- } from "./chunk-UE5TZ55T.js";
413
+ } from "./chunk-C27BYUX6.js";
412
414
  import {
413
415
  require_src
414
416
  } from "./chunk-DMTGGOSA.js";
@@ -8664,16 +8666,16 @@ var require_windows = __commonJS({
8664
8666
  return false;
8665
8667
  }
8666
8668
  __name(checkPathExt, "checkPathExt");
8667
- function checkStat(stat19, path99, options2) {
8668
- if (!stat19.isSymbolicLink() && !stat19.isFile()) {
8669
+ function checkStat(stat20, path99, options2) {
8670
+ if (!stat20.isSymbolicLink() && !stat20.isFile()) {
8669
8671
  return false;
8670
8672
  }
8671
8673
  return checkPathExt(path99, options2);
8672
8674
  }
8673
8675
  __name(checkStat, "checkStat");
8674
8676
  function isexe(path99, options2, cb) {
8675
- fs93.stat(path99, function(er2, stat19) {
8676
- cb(er2, er2 ? false : checkStat(stat19, path99, options2));
8677
+ fs93.stat(path99, function(er2, stat20) {
8678
+ cb(er2, er2 ? false : checkStat(stat20, path99, options2));
8677
8679
  });
8678
8680
  }
8679
8681
  __name(isexe, "isexe");
@@ -8692,8 +8694,8 @@ var require_mode = __commonJS({
8692
8694
  isexe.sync = sync2;
8693
8695
  var fs93 = __require("fs");
8694
8696
  function isexe(path99, options2, cb) {
8695
- fs93.stat(path99, function(er2, stat19) {
8696
- cb(er2, er2 ? false : checkStat(stat19, options2));
8697
+ fs93.stat(path99, function(er2, stat20) {
8698
+ cb(er2, er2 ? false : checkStat(stat20, options2));
8697
8699
  });
8698
8700
  }
8699
8701
  __name(isexe, "isexe");
@@ -8701,14 +8703,14 @@ var require_mode = __commonJS({
8701
8703
  return checkStat(fs93.statSync(path99), options2);
8702
8704
  }
8703
8705
  __name(sync2, "sync");
8704
- function checkStat(stat19, options2) {
8705
- return stat19.isFile() && checkMode(stat19, options2);
8706
+ function checkStat(stat20, options2) {
8707
+ return stat20.isFile() && checkMode(stat20, options2);
8706
8708
  }
8707
8709
  __name(checkStat, "checkStat");
8708
- function checkMode(stat19, options2) {
8709
- var mod = stat19.mode;
8710
- var uid = stat19.uid;
8711
- var gid = stat19.gid;
8710
+ function checkMode(stat20, options2) {
8711
+ var mod = stat20.mode;
8712
+ var uid = stat20.uid;
8713
+ var gid = stat20.gid;
8712
8714
  var myUid = options2.uid !== void 0 ? options2.uid : process.getuid && process.getuid();
8713
8715
  var myGid = options2.gid !== void 0 ? options2.gid : process.getgid && process.getgid();
8714
8716
  var u2 = parseInt("100", 8);
@@ -9413,12 +9415,12 @@ var require_src3 = __commonJS({
9413
9415
  function check(path99, isFile, isDirectory) {
9414
9416
  log(`checking %s`, path99);
9415
9417
  try {
9416
- const stat19 = fs_1.statSync(path99);
9417
- if (stat19.isFile() && isFile) {
9418
+ const stat20 = fs_1.statSync(path99);
9419
+ if (stat20.isFile() && isFile) {
9418
9420
  log(`[OK] path represents a file`);
9419
9421
  return true;
9420
9422
  }
9421
- if (stat19.isDirectory() && isDirectory) {
9423
+ if (stat20.isDirectory() && isDirectory) {
9422
9424
  log(`[OK] path represents a directory`);
9423
9425
  return true;
9424
9426
  }
@@ -29231,12 +29233,12 @@ var require_resolve_symlink = __commonJS({
29231
29233
  fs_1.default.realpath(path99, (error, resolvedPath) => {
29232
29234
  if (error)
29233
29235
  return queue.dequeue(suppressErrors ? null : error, state);
29234
- fs_1.default.stat(resolvedPath, (error2, stat19) => {
29236
+ fs_1.default.stat(resolvedPath, (error2, stat20) => {
29235
29237
  if (error2)
29236
29238
  return queue.dequeue(suppressErrors ? null : error2, state);
29237
- if (stat19.isDirectory() && isRecursive(path99, resolvedPath, state))
29239
+ if (stat20.isDirectory() && isRecursive(path99, resolvedPath, state))
29238
29240
  return queue.dequeue(null, state);
29239
- callback(stat19, resolvedPath);
29241
+ callback(stat20, resolvedPath);
29240
29242
  queue.dequeue(null, state);
29241
29243
  });
29242
29244
  });
@@ -29246,10 +29248,10 @@ var require_resolve_symlink = __commonJS({
29246
29248
  queue.enqueue();
29247
29249
  try {
29248
29250
  const resolvedPath = fs_1.default.realpathSync(path99);
29249
- const stat19 = fs_1.default.statSync(resolvedPath);
29250
- if (stat19.isDirectory() && isRecursive(path99, resolvedPath, state))
29251
+ const stat20 = fs_1.default.statSync(resolvedPath);
29252
+ if (stat20.isDirectory() && isRecursive(path99, resolvedPath, state))
29251
29253
  return;
29252
- callback(stat19, resolvedPath);
29254
+ callback(stat20, resolvedPath);
29253
29255
  } catch (e) {
29254
29256
  if (!suppressErrors)
29255
29257
  throw e;
@@ -29568,8 +29570,8 @@ var require_walker = __commonJS({
29568
29570
  this.walkDirectory(this.state, path99, path99, depth - 1, this.walk);
29569
29571
  } else if (this.resolveSymlink && entry.isSymbolicLink()) {
29570
29572
  let path99 = joinPath.joinPathWithBasePath(entry.name, directoryPath);
29571
- this.resolveSymlink(path99, this.state, (stat19, resolvedPath) => {
29572
- if (stat19.isDirectory()) {
29573
+ this.resolveSymlink(path99, this.state, (stat20, resolvedPath) => {
29574
+ if (stat20.isDirectory()) {
29573
29575
  resolvedPath = (0, utils_1.normalizePath)(resolvedPath, this.state.options);
29574
29576
  if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path99 + pathSeparator))
29575
29577
  return;
@@ -31459,12 +31461,12 @@ async function cleanupLegacyOutputFiles(dir, now, maxAgeMs, result) {
31459
31461
  __name(cleanupLegacyOutputFiles, "cleanupLegacyOutputFiles");
31460
31462
  async function tryDeleteIfOld(filePath, now, maxAgeMs, result) {
31461
31463
  try {
31462
- const stat19 = await fs2.lstat(filePath);
31463
- if (!stat19.isFile()) return;
31464
- if (now - stat19.mtimeMs < maxAgeMs) return;
31464
+ const stat20 = await fs2.lstat(filePath);
31465
+ if (!stat20.isFile()) return;
31466
+ if (now - stat20.mtimeMs < maxAgeMs) return;
31465
31467
  await fs2.unlink(filePath);
31466
31468
  result.filesDeleted++;
31467
- result.bytesFreed += stat19.size;
31469
+ result.bytesFreed += stat20.size;
31468
31470
  } catch (error) {
31469
31471
  if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
31470
31472
  return;
@@ -32360,6 +32362,7 @@ var MAX_GOAL_ITERATIONS = 50;
32360
32362
  var GOAL_JUDGE_TIMEOUT_MS = 25e3;
32361
32363
  var GOAL_HOOK_TIMEOUT_SECONDS = 30;
32362
32364
  var GOAL_HOOK_TIMEOUT_MS = GOAL_HOOK_TIMEOUT_SECONDS * 1e3;
32365
+ var GOAL_HOOK_ID_OUTPUT_KEY = "qwenGoalHookId";
32363
32366
  var GOAL_ABORTED_REASON = "Goal max iterations reached; cleared. Re-set with `/goal <condition>` if you still need it.";
32364
32367
  var GOAL_JUDGE_TIMEOUT_MESSAGE = "Goal judge timed out; the automatic /goal loop paused. The goal remains active.";
32365
32368
  function continuationReasonForGoal(condition) {
@@ -32367,6 +32370,14 @@ function continuationReasonForGoal(condition) {
32367
32370
  Goal condition: ${condition}`;
32368
32371
  }
32369
32372
  __name(continuationReasonForGoal, "continuationReasonForGoal");
32373
+ function getStopHookContinuationReason(output) {
32374
+ const hasGoalOutput = typeof output.hookSpecificOutput?.[GOAL_HOOK_ID_OUTPUT_KEY] === "string";
32375
+ if (!hasGoalOutput) {
32376
+ return output.stopReason || output.reason || "No reason provided";
32377
+ }
32378
+ return [output.stopReason, output.reason].filter(Boolean).join("\n") || "No reason provided";
32379
+ }
32380
+ __name(getStopHookContinuationReason, "getStopHookContinuationReason");
32370
32381
  async function judgeGoalWithTimeout(config, args) {
32371
32382
  let timeoutId;
32372
32383
  const judgeController = new AbortController();
@@ -32510,7 +32521,10 @@ function createGoalStopHookCallback(args) {
32510
32521
  }
32511
32522
  return {
32512
32523
  decision: "block",
32513
- reason: continuationReasonForGoal(condition)
32524
+ reason: continuationReasonForGoal(condition),
32525
+ hookSpecificOutput: {
32526
+ [GOAL_HOOK_ID_OUTPUT_KEY]: evaluated.hookId
32527
+ }
32514
32528
  };
32515
32529
  };
32516
32530
  }
@@ -32848,7 +32862,8 @@ function parseAndFormatApiError(error, authType) {
32848
32862
  if (isAlreadyFormatted(error.message)) {
32849
32863
  return error.message;
32850
32864
  }
32851
- let text = `[API Error: ${error.message}]`;
32865
+ const message = error instanceof Error ? getErrorMessage(error) : error.message;
32866
+ let text = `[API Error: ${message}]`;
32852
32867
  if (error.status === 429) {
32853
32868
  text += getRateLimitMessage(authType);
32854
32869
  }
@@ -34080,42 +34095,353 @@ import fs10 from "node:fs";
34080
34095
  import { randomUUID as randomUUID2 } from "node:crypto";
34081
34096
  import readline from "node:readline";
34082
34097
 
34083
- // packages/core/src/utils/conversation-chain.ts
34098
+ // packages/core/src/utils/transcript-records.ts
34084
34099
  init_esbuild_shims();
34085
- function buildOrderedUuidChain(records, opts) {
34086
- if (records.length === 0) return { uuids: [], gaps: [] };
34087
- const detectGaps = opts?.detectGaps ?? false;
34088
- const firstByUuid = /* @__PURE__ */ new Map();
34089
- for (const r2 of records) {
34090
- if (!firstByUuid.has(r2.uuid)) firstByUuid.set(r2.uuid, r2);
34100
+ var TranscriptRecordPreparationError = class extends TypeError {
34101
+ constructor(code, message) {
34102
+ super(message);
34103
+ this.code = code;
34104
+ this.name = "TranscriptRecordPreparationError";
34105
+ }
34106
+ static {
34107
+ __name(this, "TranscriptRecordPreparationError");
34091
34108
  }
34109
+ };
34110
+ var RECORD_TYPES = /* @__PURE__ */ new Set([
34111
+ "user",
34112
+ "assistant",
34113
+ "tool_result",
34114
+ "system"
34115
+ ]);
34116
+ var ARTIFACT_RECORD_SUBTYPES = /* @__PURE__ */ new Set([
34117
+ "session_artifact_event",
34118
+ "session_artifact_snapshot"
34119
+ ]);
34120
+ var KNOWN_RECORD_SUBTYPES = /* @__PURE__ */ new Set([
34121
+ "chat_compression",
34122
+ "slash_command",
34123
+ "ui_telemetry",
34124
+ "at_command",
34125
+ "attribution_snapshot",
34126
+ "notification",
34127
+ "cron",
34128
+ "mid_turn_user_message",
34129
+ "custom_title",
34130
+ "parent_session",
34131
+ "rewind",
34132
+ "agent_bootstrap",
34133
+ "agent_launch_prompt",
34134
+ "file_history_snapshot",
34135
+ "session_source",
34136
+ ...ARTIFACT_RECORD_SUBTYPES
34137
+ ]);
34138
+ function isObjectRecord(value) {
34139
+ return typeof value === "object" && value !== null && !Array.isArray(value);
34140
+ }
34141
+ __name(isObjectRecord, "isObjectRecord");
34142
+ function diagnostic(code, message, affectsCompleteness, fields = {}, severity = affectsCompleteness ? "warning" : "info") {
34143
+ return {
34144
+ code,
34145
+ severity,
34146
+ message,
34147
+ affectsCompleteness,
34148
+ ...fields
34149
+ };
34150
+ }
34151
+ __name(diagnostic, "diagnostic");
34152
+ function isTranscriptConversationRecord(record2) {
34153
+ return !isTranscriptArtifactRecord(record2);
34154
+ }
34155
+ __name(isTranscriptConversationRecord, "isTranscriptConversationRecord");
34156
+ function isTranscriptArtifactRecord(record2) {
34157
+ return record2.type === "system" && typeof record2.subtype === "string" && ARTIFACT_RECORD_SUBTYPES.has(record2.subtype);
34158
+ }
34159
+ __name(isTranscriptArtifactRecord, "isTranscriptArtifactRecord");
34160
+ function validateTranscriptRecord(value, recordIndex) {
34161
+ const diagnostics = [];
34162
+ if (!isObjectRecord(value)) {
34163
+ diagnostics.push(
34164
+ diagnostic(
34165
+ "invalid_record",
34166
+ "Skipped a transcript record that is not an object.",
34167
+ true,
34168
+ { recordIndex }
34169
+ )
34170
+ );
34171
+ return { diagnostics };
34172
+ }
34173
+ const uuid = value["uuid"];
34174
+ const parentUuid = value["parentUuid"];
34175
+ const sessionId = value["sessionId"];
34176
+ const type = value["type"];
34177
+ const recordId = typeof uuid === "string" ? uuid : void 0;
34178
+ if (typeof uuid !== "string" || uuid.length === 0 || typeof parentUuid !== "string" && parentUuid !== null || typeof sessionId !== "string" || sessionId.length === 0) {
34179
+ diagnostics.push(
34180
+ diagnostic(
34181
+ "invalid_record",
34182
+ "Skipped a transcript record with invalid identity fields.",
34183
+ true,
34184
+ { recordIndex, recordId }
34185
+ )
34186
+ );
34187
+ return { diagnostics };
34188
+ }
34189
+ if (typeof type !== "string" || !RECORD_TYPES.has(type)) {
34190
+ diagnostics.push(
34191
+ diagnostic(
34192
+ "unknown_record_or_part",
34193
+ "Skipped a transcript record with an unknown record type.",
34194
+ true,
34195
+ { recordIndex, recordId }
34196
+ )
34197
+ );
34198
+ return { diagnostics };
34199
+ }
34200
+ const timestamp = value["timestamp"];
34201
+ if (timestamp !== void 0 && (typeof timestamp !== "string" || !Number.isFinite(new Date(timestamp).getTime()))) {
34202
+ diagnostics.push(
34203
+ diagnostic(
34204
+ "invalid_timestamp",
34205
+ "Ignored an invalid transcript record timestamp.",
34206
+ false,
34207
+ { recordIndex, recordId, path: "timestamp" }
34208
+ )
34209
+ );
34210
+ }
34211
+ const subtype = value["subtype"];
34212
+ if (subtype !== void 0 && (typeof subtype !== "string" || !KNOWN_RECORD_SUBTYPES.has(subtype))) {
34213
+ diagnostics.push(
34214
+ diagnostic(
34215
+ "unknown_record_or_part",
34216
+ "The transcript record has an unknown subtype.",
34217
+ true,
34218
+ { recordIndex, recordId, path: "subtype" }
34219
+ )
34220
+ );
34221
+ }
34222
+ let message;
34223
+ if (value["message"] !== void 0) {
34224
+ if (!isObjectRecord(value["message"])) {
34225
+ diagnostics.push(
34226
+ diagnostic(
34227
+ "malformed_part",
34228
+ "Ignored a malformed transcript message payload.",
34229
+ true,
34230
+ { recordIndex, recordId, path: "message" }
34231
+ )
34232
+ );
34233
+ } else {
34234
+ const parts = value["message"]["parts"];
34235
+ if (parts !== void 0 && !Array.isArray(parts)) {
34236
+ diagnostics.push(
34237
+ diagnostic(
34238
+ "malformed_part",
34239
+ "Ignored malformed transcript message parts.",
34240
+ true,
34241
+ { recordIndex, recordId, path: "message.parts" }
34242
+ )
34243
+ );
34244
+ }
34245
+ message = {
34246
+ ...typeof value["message"]["role"] === "string" ? { role: value["message"]["role"] } : {},
34247
+ ...Array.isArray(parts) ? { parts } : {}
34248
+ };
34249
+ }
34250
+ }
34251
+ return {
34252
+ record: {
34253
+ ...value,
34254
+ uuid,
34255
+ parentUuid,
34256
+ sessionId,
34257
+ type,
34258
+ ...typeof subtype === "string" ? { subtype } : { subtype: void 0 },
34259
+ ...typeof timestamp === "string" && Number.isFinite(new Date(timestamp).getTime()) ? { timestamp } : { timestamp: void 0 },
34260
+ ...message ? { message } : { message: void 0 }
34261
+ },
34262
+ diagnostics
34263
+ };
34264
+ }
34265
+ __name(validateTranscriptRecord, "validateTranscriptRecord");
34266
+ function selectTranscriptLeaf(records, leafUuid) {
34267
+ if (leafUuid !== void 0) {
34268
+ return records.some(
34269
+ (record2) => record2.uuid === leafUuid && isTranscriptConversationRecord(record2)
34270
+ ) ? leafUuid : void 0;
34271
+ }
34272
+ for (let index = records.length - 1; index >= 0; index -= 1) {
34273
+ const record2 = records[index];
34274
+ if (record2 && isTranscriptConversationRecord(record2)) return record2.uuid;
34275
+ }
34276
+ return void 0;
34277
+ }
34278
+ __name(selectTranscriptLeaf, "selectTranscriptLeaf");
34279
+ function walkTranscriptUuidChain(leafUuid, lookup2) {
34092
34280
  const uuids = [];
34093
34281
  const gaps = [];
34094
34282
  const visited = /* @__PURE__ */ new Set();
34095
- const startUuid = opts?.leafUuid ?? records[records.length - 1].uuid;
34096
- if (!firstByUuid.has(startUuid)) return { uuids: [], gaps: [] };
34097
- let currentUuid = startUuid;
34283
+ let currentUuid = leafUuid;
34284
+ let cycleUuid;
34098
34285
  while (currentUuid) {
34099
- if (visited.has(currentUuid)) break;
34286
+ if (visited.has(currentUuid)) {
34287
+ cycleUuid = currentUuid;
34288
+ break;
34289
+ }
34100
34290
  visited.add(currentUuid);
34291
+ const record2 = lookup2(currentUuid);
34292
+ if (!record2) break;
34101
34293
  uuids.push(currentUuid);
34102
- const rec = firstByUuid.get(currentUuid);
34103
- if (!rec) break;
34104
- const parent = rec.parentUuid;
34105
- if (!parent) break;
34106
- if (firstByUuid.has(parent)) {
34107
- currentUuid = parent;
34108
- continue;
34109
- }
34110
- if (detectGaps) {
34111
- gaps.push({ childUuid: currentUuid, missingParentUuid: parent });
34294
+ if (!record2.parentUuid) break;
34295
+ if (!lookup2(record2.parentUuid)) {
34296
+ gaps.push({
34297
+ childUuid: currentUuid,
34298
+ missingParentUuid: record2.parentUuid
34299
+ });
34300
+ break;
34112
34301
  }
34113
- break;
34302
+ currentUuid = record2.parentUuid;
34114
34303
  }
34115
34304
  uuids.reverse();
34116
- return { uuids, gaps };
34305
+ return { uuids, gaps, ...cycleUuid ? { cycleUuid } : {} };
34117
34306
  }
34118
- __name(buildOrderedUuidChain, "buildOrderedUuidChain");
34307
+ __name(walkTranscriptUuidChain, "walkTranscriptUuidChain");
34308
+ function aggregateTranscriptRecordFragments(records) {
34309
+ const first2 = records[0];
34310
+ if (!first2) {
34311
+ throw new Error("Cannot aggregate empty transcript record array");
34312
+ }
34313
+ const base = { ...first2 };
34314
+ let message = first2.message ? { ...first2.message, parts: [...first2.message.parts ?? []] } : void 0;
34315
+ for (let index = 1; index < records.length; index += 1) {
34316
+ const record2 = records[index];
34317
+ if (record2.message !== void 0) {
34318
+ message = message ? {
34319
+ role: message.role,
34320
+ parts: [...message.parts ?? [], ...record2.message.parts ?? []]
34321
+ } : { ...record2.message, parts: [...record2.message.parts ?? []] };
34322
+ }
34323
+ if (record2.usageMetadata) base["usageMetadata"] = record2.usageMetadata;
34324
+ if (record2.toolCallResult && !base["toolCallResult"]) {
34325
+ base["toolCallResult"] = record2.toolCallResult;
34326
+ }
34327
+ if (record2.model && !base["model"]) base["model"] = record2.model;
34328
+ if (record2.timestamp && (!base["timestamp"] || record2.timestamp > String(base["timestamp"]))) {
34329
+ base["timestamp"] = record2.timestamp;
34330
+ }
34331
+ }
34332
+ base["message"] = message;
34333
+ return base;
34334
+ }
34335
+ __name(aggregateTranscriptRecordFragments, "aggregateTranscriptRecordFragments");
34336
+ function prepareTranscriptRecords(values, options2 = {}) {
34337
+ if (!Array.isArray(values)) {
34338
+ throw new TranscriptRecordPreparationError(
34339
+ "invalid_records",
34340
+ "Transcript records must be an array."
34341
+ );
34342
+ }
34343
+ const diagnostics = [];
34344
+ const records = [];
34345
+ const sourceIndexByRecord = /* @__PURE__ */ new Map();
34346
+ for (let index = 0; index < values.length; index += 1) {
34347
+ const validated = validateTranscriptRecord(values[index], index);
34348
+ diagnostics.push(...validated.diagnostics);
34349
+ if (validated.record) {
34350
+ records.push(validated.record);
34351
+ sourceIndexByRecord.set(validated.record, index);
34352
+ }
34353
+ }
34354
+ const sessionIds = new Set(records.map((record2) => record2.sessionId));
34355
+ if (sessionIds.size > 1) {
34356
+ throw new TranscriptRecordPreparationError(
34357
+ "mixed_session_ids",
34358
+ "Transcript records contain multiple session ids."
34359
+ );
34360
+ }
34361
+ const leafUuid = selectTranscriptLeaf(records, options2.leafUuid);
34362
+ if (options2.leafUuid !== void 0 && leafUuid === void 0) {
34363
+ throw new TranscriptRecordPreparationError(
34364
+ "leaf_not_found",
34365
+ "The requested transcript leaf was not found."
34366
+ );
34367
+ }
34368
+ if (!leafUuid) {
34369
+ if (records.length > 0) {
34370
+ diagnostics.push(
34371
+ diagnostic(
34372
+ "artifact_only",
34373
+ "The input contains no conversation records.",
34374
+ false
34375
+ )
34376
+ );
34377
+ }
34378
+ return {
34379
+ ...sessionIds.size === 1 ? { sessionId: records[0].sessionId } : {},
34380
+ records: [],
34381
+ gaps: [],
34382
+ diagnostics
34383
+ };
34384
+ }
34385
+ const fragmentsByUuid = /* @__PURE__ */ new Map();
34386
+ const firstByUuid = /* @__PURE__ */ new Map();
34387
+ for (const record2 of records) {
34388
+ if (!isTranscriptConversationRecord(record2)) continue;
34389
+ const fragments = fragmentsByUuid.get(record2.uuid);
34390
+ if (fragments) {
34391
+ if (fragments[0].parentUuid !== record2.parentUuid) {
34392
+ diagnostics.push(
34393
+ diagnostic(
34394
+ "conflicting_parent_uuid",
34395
+ "Duplicate transcript record fragments disagree on parentUuid.",
34396
+ true,
34397
+ {
34398
+ recordIndex: sourceIndexByRecord.get(record2),
34399
+ recordId: record2.uuid,
34400
+ path: "parentUuid"
34401
+ }
34402
+ )
34403
+ );
34404
+ }
34405
+ fragments.push(record2);
34406
+ } else {
34407
+ fragmentsByUuid.set(record2.uuid, [record2]);
34408
+ firstByUuid.set(record2.uuid, record2);
34409
+ }
34410
+ }
34411
+ const chain = walkTranscriptUuidChain(
34412
+ leafUuid,
34413
+ (uuid) => firstByUuid.get(uuid)
34414
+ );
34415
+ for (const gap of chain.gaps) {
34416
+ diagnostics.push(
34417
+ diagnostic(
34418
+ "history_gap",
34419
+ "The active transcript chain is missing a parent record.",
34420
+ true,
34421
+ { recordId: gap.childUuid }
34422
+ )
34423
+ );
34424
+ }
34425
+ if (chain.cycleUuid) {
34426
+ diagnostics.push(
34427
+ diagnostic(
34428
+ "parent_cycle",
34429
+ "The active transcript chain contains a parent cycle.",
34430
+ true,
34431
+ { recordId: chain.cycleUuid }
34432
+ )
34433
+ );
34434
+ }
34435
+ return {
34436
+ ...sessionIds.size === 1 ? { sessionId: records[0].sessionId } : {},
34437
+ records: chain.uuids.map(
34438
+ (uuid) => aggregateTranscriptRecordFragments(fragmentsByUuid.get(uuid) ?? [])
34439
+ ),
34440
+ gaps: chain.gaps,
34441
+ diagnostics
34442
+ };
34443
+ }
34444
+ __name(prepareTranscriptRecords, "prepareTranscriptRecords");
34119
34445
 
34120
34446
  // packages/core/src/services/fileHistoryService.ts
34121
34447
  init_esbuild_shims();
@@ -35225,13 +35551,9 @@ async function synthesizeUntrackedHunk(gitRoot, filePath) {
35225
35551
  }
35226
35552
  }
35227
35553
  __name(synthesizeUntrackedHunk, "synthesizeUntrackedHunk");
35228
- function parseGitNumstat(stdout) {
35554
+ function forEachNumstatEntry(stdout, visit) {
35229
35555
  const tokens = stdout.split("\0");
35230
35556
  if (tokens.length > 0 && tokens[tokens.length - 1] === "") tokens.pop();
35231
- let added = 0;
35232
- let removed = 0;
35233
- let validFileCount = 0;
35234
- const perFileStats = /* @__PURE__ */ new Map();
35235
35557
  let pending = null;
35236
35558
  let renameOld = null;
35237
35559
  for (const token of tokens) {
@@ -35240,13 +35562,7 @@ function parseGitNumstat(stdout) {
35240
35562
  renameOld = token;
35241
35563
  continue;
35242
35564
  }
35243
- commitEntry(
35244
- token,
35245
- pending.added,
35246
- pending.removed,
35247
- pending.isBinary,
35248
- renameOld
35249
- );
35565
+ visit({ ...pending, path: token, oldPath: renameOld });
35250
35566
  pending = null;
35251
35567
  renameOld = null;
35252
35568
  continue;
@@ -35257,16 +35573,32 @@ function parseGitNumstat(stdout) {
35257
35573
  if (secondTab < 0) continue;
35258
35574
  const addStr = token.slice(0, firstTab);
35259
35575
  const remStr = token.slice(firstTab + 1, secondTab);
35260
- const filePath = token.slice(secondTab + 1);
35576
+ const path99 = token.slice(secondTab + 1);
35261
35577
  const isBinary2 = addStr === "-" || remStr === "-";
35262
- const fileAdded = isBinary2 ? 0 : parseInt(addStr, 10) || 0;
35263
- const fileRemoved = isBinary2 ? 0 : parseInt(remStr, 10) || 0;
35264
- if (filePath === "") {
35265
- pending = { added: fileAdded, removed: fileRemoved, isBinary: isBinary2 };
35578
+ const added = isBinary2 ? 0 : parseInt(addStr, 10) || 0;
35579
+ const removed = isBinary2 ? 0 : parseInt(remStr, 10) || 0;
35580
+ if (path99 === "") {
35581
+ pending = { added, removed, isBinary: isBinary2 };
35266
35582
  continue;
35267
35583
  }
35268
- commitEntry(filePath, fileAdded, fileRemoved, isBinary2);
35584
+ visit({ path: path99, added, removed, isBinary: isBinary2 });
35269
35585
  }
35586
+ }
35587
+ __name(forEachNumstatEntry, "forEachNumstatEntry");
35588
+ function parseGitNumstat(stdout) {
35589
+ let added = 0;
35590
+ let removed = 0;
35591
+ let validFileCount = 0;
35592
+ const perFileStats = /* @__PURE__ */ new Map();
35593
+ forEachNumstatEntry(stdout, (entry) => {
35594
+ commitEntry(
35595
+ entry.path,
35596
+ entry.added,
35597
+ entry.removed,
35598
+ entry.isBinary,
35599
+ entry.oldPath
35600
+ );
35601
+ });
35270
35602
  function commitEntry(filePath, fileAdded, fileRemoved, isBinary2, oldPath) {
35271
35603
  validFileCount++;
35272
35604
  added += fileAdded;
@@ -35767,6 +36099,150 @@ async function countStashEntries(gitRoot) {
35767
36099
  }
35768
36100
  }
35769
36101
  __name(countStashEntries, "countStashEntries");
36102
+ var MAX_LOG_LIMIT = 200;
36103
+ var DEFAULT_LOG_LIMIT = 50;
36104
+ var LOG_FORMAT = "%H%x00%h%x00%an%x00%ae%x00%at%x00%s%x00%D%x00%P";
36105
+ var LOG_DETAIL_FORMAT = "%H%x00%h%x00%an%x00%ae%x00%at%x00%s%x00%D%x00%P%x00%b";
36106
+ function parseLogFields(parts) {
36107
+ if (parts.length !== 8) return null;
36108
+ return {
36109
+ sha: parts[0],
36110
+ shortSha: parts[1],
36111
+ authorName: parts[2],
36112
+ authorEmail: parts[3],
36113
+ authorDate: parseInt(parts[4], 10) || 0,
36114
+ subject: parts[5],
36115
+ refs: parts[6],
36116
+ parents: parts[7] ? parts[7].split(" ").filter(Boolean) : []
36117
+ };
36118
+ }
36119
+ __name(parseLogFields, "parseLogFields");
36120
+ async function fetchGitLog(cwd, options2) {
36121
+ const gitRoot = findGitRoot(cwd);
36122
+ if (!gitRoot) return null;
36123
+ const limit = Math.min(
36124
+ Math.max(options2?.limit ?? DEFAULT_LOG_LIMIT, 1),
36125
+ MAX_LOG_LIMIT
36126
+ );
36127
+ const skip = Math.max(options2?.skip ?? 0, 0);
36128
+ const stdout = await runGit(
36129
+ [
36130
+ "--no-optional-locks",
36131
+ "log",
36132
+ "-z",
36133
+ `--format=${LOG_FORMAT}`,
36134
+ "-n",
36135
+ String(limit + 1),
36136
+ ...skip > 0 ? ["--skip", String(skip)] : []
36137
+ ],
36138
+ gitRoot
36139
+ );
36140
+ if (stdout === null) {
36141
+ const head = await runGit(["rev-parse", "--verify", "HEAD"], gitRoot);
36142
+ return head === null ? { entries: [], hasMore: false } : null;
36143
+ }
36144
+ const fields = stdout.split("\0");
36145
+ if (fields.at(-1) === "") fields.pop();
36146
+ const recordCount = Math.floor(fields.length / 8);
36147
+ const hasMore = recordCount > limit;
36148
+ const pageCount = hasMore ? limit : recordCount;
36149
+ const entries = [];
36150
+ for (let i2 = 0; i2 < pageCount; i2++) {
36151
+ const entry = parseLogFields(fields.slice(i2 * 8, i2 * 8 + 8));
36152
+ if (entry) entries.push(entry);
36153
+ }
36154
+ return { entries, hasMore };
36155
+ }
36156
+ __name(fetchGitLog, "fetchGitLog");
36157
+ async function fetchGitCommitDetail(cwd, sha) {
36158
+ if (!/^[0-9a-f]{7,40}$/i.test(sha)) return null;
36159
+ const gitRoot = findGitRoot(cwd);
36160
+ if (!gitRoot) return null;
36161
+ const metaRaw = await runGit(
36162
+ [
36163
+ "--no-optional-locks",
36164
+ "log",
36165
+ "-1",
36166
+ "-z",
36167
+ `--format=${LOG_DETAIL_FORMAT}`,
36168
+ sha
36169
+ ],
36170
+ gitRoot
36171
+ );
36172
+ if (metaRaw === null) return null;
36173
+ const parts = metaRaw.split("\0");
36174
+ if (parts.at(-1) === "") parts.pop();
36175
+ if (parts.length !== 9) return null;
36176
+ const parents = parts[7] ? parts[7].split(" ").filter(Boolean) : [];
36177
+ const diffTreeArgs = parents.length > 1 ? [
36178
+ "--no-optional-locks",
36179
+ "diff-tree",
36180
+ "--no-commit-id",
36181
+ "--numstat",
36182
+ // Detect renames so `git mv` counts as one file (by its new path),
36183
+ // matching the main `git diff` path — diff-tree is plumbing and does
36184
+ // NOT honour diff.renames, so without -M a rename splits into a
36185
+ // delete + add pair. The three-token `-z` rename sequence it then
36186
+ // emits is handled by the pending-rename state machine below.
36187
+ "-M",
36188
+ "-r",
36189
+ "-z",
36190
+ `${sha}^1`,
36191
+ sha
36192
+ ] : [
36193
+ "--no-optional-locks",
36194
+ "diff-tree",
36195
+ "--no-commit-id",
36196
+ "--numstat",
36197
+ // Detect renames so `git mv` counts as one file (by its new path),
36198
+ // matching the main `git diff` path — diff-tree is plumbing and does
36199
+ // NOT honour diff.renames, so without -M a rename splits into a
36200
+ // delete + add pair. The three-token `-z` rename sequence it then
36201
+ // emits is handled by the pending-rename state machine below.
36202
+ "-M",
36203
+ "-r",
36204
+ "-z",
36205
+ "--root",
36206
+ sha
36207
+ ];
36208
+ const numstatRaw = await runGit(diffTreeArgs, gitRoot);
36209
+ const files = [];
36210
+ let filesCount = 0;
36211
+ let linesAdded = 0;
36212
+ let linesRemoved = 0;
36213
+ if (numstatRaw) {
36214
+ forEachNumstatEntry(numstatRaw, (entry) => {
36215
+ filesCount++;
36216
+ linesAdded += entry.added;
36217
+ linesRemoved += entry.removed;
36218
+ if (files.length < MAX_FILES) {
36219
+ files.push({
36220
+ path: entry.path,
36221
+ added: entry.added,
36222
+ removed: entry.removed,
36223
+ isBinary: entry.isBinary
36224
+ });
36225
+ }
36226
+ });
36227
+ }
36228
+ return {
36229
+ sha: parts[0],
36230
+ shortSha: parts[1],
36231
+ authorName: parts[2],
36232
+ authorEmail: parts[3],
36233
+ authorDate: parseInt(parts[4], 10) || 0,
36234
+ subject: parts[5],
36235
+ refs: parts[6],
36236
+ parents,
36237
+ body: parts[8].replace(/\n$/, ""),
36238
+ files,
36239
+ filesCount,
36240
+ linesAdded,
36241
+ linesRemoved,
36242
+ hiddenCount: Math.max(filesCount - files.length, 0)
36243
+ };
36244
+ }
36245
+ __name(fetchGitCommitDetail, "fetchGitCommitDetail");
35770
36246
 
35771
36247
  // packages/core/src/services/fileHistoryService.ts
35772
36248
  var debugLogger12 = createDebugLogger("FILE_HISTORY");
@@ -37021,12 +37497,8 @@ var MAX_PERSISTED_MIME_CHARS = 120;
37021
37497
  var MAX_PERSISTED_FIELD_CHARS = 200;
37022
37498
  var MAX_PERSISTED_TIMESTAMP_CHARS = 64;
37023
37499
  var SECRET_TOKEN_VALUE_PATTERN = /(?:^|\s)(?:bearer\s+\S{8,}|sk-[A-Za-z0-9_-]{12,}|(?:gh[pousr]|github_pat)_[A-Za-z0-9_/-]{12,}|[a-f0-9]{40,}|[A-Za-z0-9+/]{48,}={0,2})(?:$|\s)/i;
37024
- var ARTIFACT_RECORD_SUBTYPES = /* @__PURE__ */ new Set([
37025
- "session_artifact_event",
37026
- "session_artifact_snapshot"
37027
- ]);
37028
37500
  function isSessionArtifactRecord(record2) {
37029
- return record2.type === "system" && typeof record2.subtype === "string" && ARTIFACT_RECORD_SUBTYPES.has(record2.subtype);
37501
+ return isTranscriptArtifactRecord(record2);
37030
37502
  }
37031
37503
  __name(isSessionArtifactRecord, "isSessionArtifactRecord");
37032
37504
  function stableSessionArtifactId(sessionId, identityKey) {
@@ -38310,10 +38782,10 @@ function makeSessionTranscriptNotFoundError(sessionId) {
38310
38782
  return error;
38311
38783
  }
38312
38784
  __name(makeSessionTranscriptNotFoundError, "makeSessionTranscriptNotFoundError");
38313
- function isObjectRecord(value) {
38785
+ function isObjectRecord2(value) {
38314
38786
  return typeof value === "object" && value !== null && !Array.isArray(value);
38315
38787
  }
38316
- __name(isObjectRecord, "isObjectRecord");
38788
+ __name(isObjectRecord2, "isObjectRecord");
38317
38789
  function isFiniteNonNegativeInteger(value) {
38318
38790
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
38319
38791
  }
@@ -38423,11 +38895,11 @@ function decodeCursorState(cursor, key) {
38423
38895
  try {
38424
38896
  const decoded = Buffer.from(cursor, "base64url").toString("utf8");
38425
38897
  const parsed = JSON.parse(decoded);
38426
- if (!isObjectRecord(parsed)) {
38898
+ if (!isObjectRecord2(parsed)) {
38427
38899
  throw new InvalidSessionTranscriptCursorError();
38428
38900
  }
38429
38901
  const fileIdentity = parsed["fileIdentity"];
38430
- if (parsed["v"] !== SESSION_TRANSCRIPT_CURSOR_VERSION || typeof parsed["sessionId"] !== "string" || !isObjectRecord(fileIdentity) || !isFiniteNonNegativeInteger(fileIdentity["dev"]) || !isFiniteNonNegativeInteger(fileIdentity["ino"]) || !isFiniteNonNegativeInteger(parsed["snapshotSize"]) || !isFiniteNonNegativeInteger(parsed["position"]) || parsed["direction"] !== void 0 && parsed["direction"] !== "backward" || typeof parsed["leafUuid"] !== "string" || typeof parsed["startTime"] !== "string" || typeof parsed["lastUpdated"] !== "string" || typeof parsed["mac"] !== "string") {
38902
+ if (parsed["v"] !== SESSION_TRANSCRIPT_CURSOR_VERSION || typeof parsed["sessionId"] !== "string" || !isObjectRecord2(fileIdentity) || !isFiniteNonNegativeInteger(fileIdentity["dev"]) || !isFiniteNonNegativeInteger(fileIdentity["ino"]) || !isFiniteNonNegativeInteger(parsed["snapshotSize"]) || !isFiniteNonNegativeInteger(parsed["position"]) || parsed["direction"] !== void 0 && parsed["direction"] !== "backward" || typeof parsed["leafUuid"] !== "string" || typeof parsed["startTime"] !== "string" || typeof parsed["lastUpdated"] !== "string" || typeof parsed["mac"] !== "string") {
38431
38903
  debugLogger13.debug("cursor decode failed: invalid payload shape");
38432
38904
  throw new InvalidSessionTranscriptCursorError();
38433
38905
  }
@@ -38662,12 +39134,6 @@ function pruneCache(now = Date.now()) {
38662
39134
  }
38663
39135
  }
38664
39136
  __name(pruneCache, "pruneCache");
38665
- function isChatRecord(value) {
38666
- if (!isObjectRecord(value)) return false;
38667
- const type = value["type"];
38668
- return typeof value["uuid"] === "string" && (typeof value["parentUuid"] === "string" || value["parentUuid"] === null) && typeof value["sessionId"] === "string" && typeof value["timestamp"] === "string" && (type === "user" || type === "assistant" || type === "tool_result" || type === "system");
38669
- }
38670
- __name(isChatRecord, "isChatRecord");
38671
39137
  async function forEachLineInSnapshot(filePath, snapshotSize, onLine) {
38672
39138
  if (snapshotSize === 0) return;
38673
39139
  let pending = [];
@@ -38721,7 +39187,10 @@ async function readSegmentRecords(handle, filePath, segment, uuid) {
38721
39187
  await handle.read(buffer, 0, segment.length, segment.offset);
38722
39188
  const line = buffer.toString("utf8").trim();
38723
39189
  if (line.length === 0) return [];
38724
- const records = parseLineTolerant(line, filePath).filter((record3) => isChatRecord(record3));
39190
+ const records = parseLineTolerant(line, filePath).flatMap((value) => {
39191
+ const record3 = validateTranscriptRecord(value).record;
39192
+ return record3 && isTranscriptConversationRecord(record3) ? [record3] : [];
39193
+ });
38725
39194
  const anomalySessionId = path9.basename(filePath, ".jsonl");
38726
39195
  const record2 = records[segment.fragmentIndex];
38727
39196
  if (!record2) {
@@ -38739,42 +39208,6 @@ async function readSegmentRecords(handle, filePath, segment, uuid) {
38739
39208
  return [record2];
38740
39209
  }
38741
39210
  __name(readSegmentRecords, "readSegmentRecords");
38742
- function aggregateRecords(records) {
38743
- if (records.length === 0) {
38744
- throw new Error("Cannot aggregate empty transcript record array");
38745
- }
38746
- const base = { ...records[0] };
38747
- for (let i2 = 1; i2 < records.length; i2++) {
38748
- const record2 = records[i2];
38749
- if (record2.message !== void 0) {
38750
- if (base.message === void 0) {
38751
- base.message = record2.message;
38752
- } else {
38753
- base.message = {
38754
- role: base.message.role,
38755
- parts: [
38756
- ...base.message.parts ?? [],
38757
- ...record2.message.parts ?? []
38758
- ]
38759
- };
38760
- }
38761
- }
38762
- if (record2.usageMetadata) {
38763
- base.usageMetadata = record2.usageMetadata;
38764
- }
38765
- if (record2.toolCallResult && !base.toolCallResult) {
38766
- base.toolCallResult = record2.toolCallResult;
38767
- }
38768
- if (record2.model && !base.model) {
38769
- base.model = record2.model;
38770
- }
38771
- if (record2.timestamp > base.timestamp) {
38772
- base.timestamp = record2.timestamp;
38773
- }
38774
- }
38775
- return base;
38776
- }
38777
- __name(aggregateRecords, "aggregateRecords");
38778
39211
  async function readAggregatedRecords(index, uuids) {
38779
39212
  const handle = await fsp.open(index.filePath, "r");
38780
39213
  try {
@@ -38789,7 +39222,7 @@ async function readAggregatedRecords(index, uuids) {
38789
39222
  );
38790
39223
  }
38791
39224
  if (physicalRecords.length > 0) {
38792
- records.push(aggregateRecords(physicalRecords));
39225
+ records.push(aggregateTranscriptRecordFragments(physicalRecords));
38793
39226
  }
38794
39227
  }
38795
39228
  return records;
@@ -38825,12 +39258,12 @@ async function buildIndex(params) {
38825
39258
  const text = line.toString("utf8").trim();
38826
39259
  if (text.length === 0) return;
38827
39260
  let fragmentIndex = 0;
38828
- for (const record2 of parseLineTolerant(
38829
- text,
38830
- filePath
38831
- )) {
38832
- if (!isChatRecord(record2)) continue;
38833
- startTime ??= record2.timestamp;
39261
+ for (const value of parseLineTolerant(text, filePath)) {
39262
+ const record2 = validateTranscriptRecord(value).record;
39263
+ if (!record2 || !isTranscriptConversationRecord(record2)) {
39264
+ continue;
39265
+ }
39266
+ if (record2.timestamp) startTime ??= record2.timestamp;
38834
39267
  leafUuid = record2.uuid;
38835
39268
  const existing = byUuid.get(record2.uuid);
38836
39269
  const segment = {
@@ -38853,43 +39286,30 @@ async function buildIndex(params) {
38853
39286
  }
38854
39287
  }
38855
39288
  );
38856
- if (!leafUuid || !startTime) {
39289
+ if (!leafUuid) {
38857
39290
  debugLogger13.warn(
38858
39291
  `index build failed: no transcript records session=${sessionId}`
38859
39292
  );
38860
39293
  throw new SessionTranscriptSnapshotUnavailableError(sessionId);
38861
39294
  }
38862
- const activeUuids = [];
38863
- const gaps = [];
38864
- const visited = /* @__PURE__ */ new Set();
38865
- let currentUuid = leafUuid;
38866
- while (currentUuid && !visited.has(currentUuid)) {
38867
- visited.add(currentUuid);
38868
- const entry = byUuid.get(currentUuid);
38869
- if (!entry) {
38870
- debugLogger13.debug(
38871
- `active chain terminated: missing uuid session=${sessionId} uuid=${currentUuid}`
38872
- );
38873
- break;
38874
- }
38875
- activeUuids.push(currentUuid);
38876
- const parentUuid = entry.parentUuid;
38877
- if (!parentUuid) break;
38878
- if (!byUuid.has(parentUuid)) {
38879
- gaps.push({ childUuid: currentUuid, missingParentUuid: parentUuid });
38880
- debugLogger13.debug(
38881
- `active chain gap session=${sessionId} child=${currentUuid} missingParent=${parentUuid}`
38882
- );
38883
- break;
38884
- }
38885
- currentUuid = parentUuid;
38886
- }
38887
- if (currentUuid && visited.has(currentUuid)) {
39295
+ startTime ??= lastUpdated;
39296
+ const chain = walkTranscriptUuidChain(leafUuid, (uuid) => {
39297
+ const entry = byUuid.get(uuid);
39298
+ return entry ? {
39299
+ uuid,
39300
+ parentUuid: entry.parentUuid,
39301
+ sessionId,
39302
+ timestamp: startTime,
39303
+ type: "system"
39304
+ } : void 0;
39305
+ });
39306
+ const activeUuids = [...chain.uuids];
39307
+ const gaps = [...chain.gaps];
39308
+ if (chain.cycleUuid) {
38888
39309
  debugLogger13.debug(
38889
- `active chain terminated: cycle session=${sessionId} uuid=${currentUuid}`
39310
+ `active chain terminated: cycle session=${sessionId} uuid=${chain.cycleUuid}`
38890
39311
  );
38891
39312
  }
38892
- activeUuids.reverse();
38893
39313
  debugLogger13.debug(
38894
39314
  `index build complete session=${sessionId} records=${byUuid.size} active=${activeUuids.length} gaps=${gaps.length}`
38895
39315
  );
@@ -39168,6 +39588,14 @@ var SessionService = class {
39168
39588
  if (getProjectHash(recordCwd) === this.projectHash) {
39169
39589
  return true;
39170
39590
  }
39591
+ const worktreesMarker = `${path10.sep}.qwen${path10.sep}worktrees${path10.sep}`;
39592
+ const markerIdx = recordCwd.lastIndexOf(worktreesMarker);
39593
+ if (markerIdx > 0) {
39594
+ const repoRoot = recordCwd.substring(0, markerIdx);
39595
+ if (getProjectHash(repoRoot) === this.projectHash) {
39596
+ return true;
39597
+ }
39598
+ }
39171
39599
  const status = await readRuntimeStatus(
39172
39600
  this.storage.getRuntimeStatusPath(sessionId)
39173
39601
  );
@@ -39181,6 +39609,9 @@ var SessionService = class {
39181
39609
  getWorktreeSessionPath(sessionId) {
39182
39610
  return this.getWorktreeSessionPathForState(sessionId, "active");
39183
39611
  }
39612
+ getWorktreeSessionPathForArchiveState(sessionId, state) {
39613
+ return this.getWorktreeSessionPathForState(sessionId, state);
39614
+ }
39184
39615
  async readProjectSessionHead(sessionId, filePath) {
39185
39616
  try {
39186
39617
  const records = await readLines(filePath, 1);
@@ -39731,49 +40162,11 @@ var SessionService = class {
39731
40162
  return [];
39732
40163
  }
39733
40164
  }
39734
- /**
39735
- * Aggregates multiple records with the same uuid into a single ChatRecord.
39736
- * Merges content fields (message, tokens, model, toolCallResult).
39737
- */
39738
- aggregateRecords(records) {
39739
- if (records.length === 0) {
39740
- throw new Error("Cannot aggregate empty records array");
39741
- }
39742
- const base = { ...records[0] };
39743
- for (let i2 = 1; i2 < records.length; i2++) {
39744
- const record2 = records[i2];
39745
- if (record2.message !== void 0) {
39746
- if (base.message === void 0) {
39747
- base.message = record2.message;
39748
- } else {
39749
- base.message = {
39750
- role: base.message.role,
39751
- parts: [
39752
- ...base.message.parts || [],
39753
- ...record2.message.parts || []
39754
- ]
39755
- };
39756
- }
39757
- }
39758
- if (record2.usageMetadata) {
39759
- base.usageMetadata = record2.usageMetadata;
39760
- }
39761
- if (record2.toolCallResult && !base.toolCallResult) {
39762
- base.toolCallResult = record2.toolCallResult;
39763
- }
39764
- if (record2.model && !base.model) {
39765
- base.model = record2.model;
39766
- }
39767
- if (record2.timestamp > base.timestamp) {
39768
- base.timestamp = record2.timestamp;
39769
- }
39770
- }
39771
- return base;
39772
- }
39773
40165
  /**
39774
40166
  * Reconstructs a linear conversation from tree-structured records.
39775
40167
  *
39776
- * Delegates the parentUuid walk to {@link buildOrderedUuidChain}. With
40168
+ * Delegates validation, parentUuid walking, and fragment aggregation to the
40169
+ * shared transcript record preparation module. With
39777
40170
  * `detectGaps`, a walk that stops on a physically-missing parent records the
39778
40171
  * break in the returned `gaps` (see {@link HistoryGap}) so the surface can
39779
40172
  * mark it — the earlier records are NOT reconstructed (reconnecting them
@@ -39782,30 +40175,13 @@ var SessionService = class {
39782
40175
  */
39783
40176
  reconstructHistory(records, opts) {
39784
40177
  if (records.length === 0) return { messages: [], gaps: [] };
39785
- const recordsByUuid = /* @__PURE__ */ new Map();
39786
- for (const record2 of records) {
39787
- const existing = recordsByUuid.get(record2.uuid) || [];
39788
- existing.push(record2);
39789
- recordsByUuid.set(record2.uuid, existing);
39790
- }
39791
- const { uuids, gaps } = buildOrderedUuidChain(records, opts);
39792
- const messages = [];
39793
- for (const uuid of uuids) {
39794
- const recordsForUuid = recordsByUuid.get(uuid);
39795
- if (recordsForUuid && recordsForUuid.length > 0) {
39796
- messages.push(this.aggregateRecords(recordsForUuid));
39797
- }
39798
- }
39799
- return { messages, gaps };
39800
- }
39801
- lastConversationRecordUuid(records) {
39802
- for (let index = records.length - 1; index >= 0; index--) {
39803
- const record2 = records[index];
39804
- if (record2 && !isSessionArtifactRecord(record2)) {
39805
- return record2.uuid;
39806
- }
39807
- }
39808
- return null;
40178
+ const prepared = prepareTranscriptRecords(records, {
40179
+ ...opts?.leafUuid !== void 0 ? { leafUuid: opts.leafUuid } : {}
40180
+ });
40181
+ return {
40182
+ messages: prepared.records.map((record2) => record2),
40183
+ gaps: opts?.detectGaps ? [...prepared.gaps] : []
40184
+ };
39809
40185
  }
39810
40186
  /**
39811
40187
  * Loads a session by its session ID.
@@ -39862,12 +40238,7 @@ var SessionService = class {
39862
40238
  )) {
39863
40239
  return;
39864
40240
  }
39865
- const leafUuid = this.lastConversationRecordUuid(records);
39866
- if (!leafUuid) {
39867
- return;
39868
- }
39869
40241
  const { messages, gaps } = this.reconstructHistory(records, {
39870
- leafUuid,
39871
40242
  detectGaps: true
39872
40243
  });
39873
40244
  if (messages.length === 0) {
@@ -40226,13 +40597,7 @@ var SessionService = class {
40226
40597
  `Source session does not belong to current project: ${sourceSessionId}`
40227
40598
  );
40228
40599
  }
40229
- const leafUuid = this.lastConversationRecordUuid(records);
40230
- if (!leafUuid) {
40231
- throw new Error(`Source session not found or empty: ${sourceSessionId}`);
40232
- }
40233
- const { messages: activeMessages } = this.reconstructHistory(records, {
40234
- leafUuid
40235
- });
40600
+ const { messages: activeMessages } = this.reconstructHistory(records);
40236
40601
  const sourceRecords = includeActiveSideArtifactRecords(
40237
40602
  records,
40238
40603
  activeMessages
@@ -43149,6 +43514,81 @@ I found the following 'app.config' files:
43149
43514
  To help you check their settings, I can read their contents. Which one would you like to start with, or should I read all of them?
43150
43515
  </example>
43151
43516
  `.trim();
43517
+ var gemma4ToolCallExamples = `
43518
+ # Examples (Illustrating Tone and Workflow)
43519
+ <example>
43520
+ user: 1 + 2
43521
+ model: 3
43522
+ </example>
43523
+
43524
+ <example>
43525
+ user: is 13 a prime number?
43526
+ model: true
43527
+ </example>
43528
+
43529
+ <example>
43530
+ user: start the server implemented in server.js
43531
+ model: <|tool_call>call:${ToolNames.SHELL}{command:<|"|>node server.js<|"|>,is_background:true}<tool_call|>
43532
+ </example>
43533
+
43534
+ <example>
43535
+ user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib.
43536
+ model: Okay, I can refactor 'src/auth.py'.
43537
+ First, I'll analyze the code and check for a test safety net before planning any changes.
43538
+ <|tool_call>call:${ToolNames.GLOB}{pattern:<|"|>tests/test_auth.py<|"|>}<tool_call|>
43539
+ <|tool_call>call:${ToolNames.READ_FILE}{file_path:<|"|>/path/to/tests/test_auth.py<|"|>,offset:0,limit:10}<tool_call|>
43540
+ (After analysis)
43541
+ Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring.
43542
+ I'll also confirm 'requests' is a dependency.
43543
+ <|tool_call>call:${ToolNames.READ_FILE}{file_path:<|"|>/path/to/requirements.txt<|"|>}<tool_call|>
43544
+ (After analysis)
43545
+ Looks good, 'requests' is available.
43546
+
43547
+ Here's the plan:
43548
+ 1. Replace the 'urllib' calls with 'requests'.
43549
+ 2. Add proper 'try...except' error handling for the new network calls.
43550
+ 3. Remove the old 'urllib' import.
43551
+ 4. Run the project's linter and tests to verify the changes.
43552
+
43553
+ <|tool_call>call:${ToolNames.EDIT}{file_path:<|"|>/path/to/src/auth.py<|"|>,old_string:<|"|>(old code content)<|"|>,new_string:<|"|>(new code content)<|"|>}<tool_call|>
43554
+ Refactoring complete. Running verification...
43555
+ <|tool_call>call:${ToolNames.SHELL}{command:<|"|>ruff check src/auth.py && pytest<|"|>}<tool_call|>
43556
+ (After verification passes)
43557
+ All checks passed. This is a stable checkpoint.
43558
+ Would you like me to write a commit message and commit these changes?
43559
+ </example>
43560
+
43561
+ <example>
43562
+ user: Delete the temp directory.
43563
+ model: I can run \`rm -rf /path/to/project/temp\`. This will permanently delete the directory and all its contents.
43564
+ </example>
43565
+
43566
+ <example>
43567
+ user: Write tests for someFile.ts
43568
+ model:
43569
+ Okay, I can write those tests. First, I'll read someFile.ts to understand its functionality.
43570
+ <|tool_call>call:${ToolNames.READ_FILE}{file_path:<|"|>/path/to/someFile.ts<|"|>}<tool_call|>
43571
+ Now I'll look for existing or related test files to understand current testing conventions and dependencies.
43572
+ <|tool_call>call:${ToolNames.READ_FILE}{file_path:<|"|>/path/to/existingTest.test.ts<|"|>}<tool_call|>
43573
+ (After reviewing existing tests and the file content)
43574
+ <|tool_call>call:${ToolNames.WRITE_FILE}{file_path:<|"|>/path/to/someFile.test.ts<|"|>,content:<|"|>(test code content)<|"|>}<tool_call|>
43575
+ I've written the tests. Now I'll run the project's test command to verify them.
43576
+ <|tool_call>call:${ToolNames.SHELL}{command:<|"|>npm run test<|"|>}<tool_call|>
43577
+ (After verification passes)
43578
+ All checks passed. This is a stable checkpoint.
43579
+ </example>
43580
+
43581
+ <example>
43582
+ user: Where are all the 'app.config' files in this project? I need to check their settings.
43583
+ model:
43584
+ <|tool_call>call:${ToolNames.GLOB}{pattern:<|"|>./**/app.config<|"|>}<tool_call|>
43585
+ (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config'])
43586
+ I found the following 'app.config' files:
43587
+ - /path/to/moduleA/app.config
43588
+ - /path/to/moduleB/app.config
43589
+ To help you check their settings, I can read their contents. Which one would you like to start with, or should I read all of them?
43590
+ </example>
43591
+ `.trim();
43152
43592
  function getToolCallExamples(model) {
43153
43593
  const toolCallStyle = process2.env["QWEN_CODE_TOOL_CALL_STYLE"];
43154
43594
  if (toolCallStyle) {
@@ -43157,6 +43597,8 @@ function getToolCallExamples(model) {
43157
43597
  return qwenCoderToolCallExamples;
43158
43598
  case "qwen-vl":
43159
43599
  return qwenVlToolCallExamples;
43600
+ case "gemma4":
43601
+ return gemma4ToolCallExamples;
43160
43602
  case "general":
43161
43603
  return generalToolCallExamples;
43162
43604
  default:
@@ -43176,13 +43618,16 @@ function getToolCallExamples(model) {
43176
43618
  if (/coder-model/i.test(model)) {
43177
43619
  return qwenCoderToolCallExamples;
43178
43620
  }
43621
+ if (/gemma[-_]?4/i.test(model)) {
43622
+ return gemma4ToolCallExamples;
43623
+ }
43179
43624
  }
43180
43625
  return generalToolCallExamples;
43181
43626
  }
43182
43627
  __name(getToolCallExamples, "getToolCallExamples");
43183
43628
  function getPlanModeSystemReminder(planOnly = false) {
43184
43629
  return `<system-reminder>
43185
- Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits, run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supersedes any other instructions you have received (for example, to make edits).
43630
+ Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits, run tools classified as state-modifying (including changing configs or making commits), or otherwise make changes to the system. A shell command whose safety cannot be determined may run only after the user explicitly approves that exact invocation once, and only when it is necessary for the investigation. This supersedes any other instructions you have received (for example, to make edits).
43186
43631
 
43187
43632
  ## Iterative Planning Workflow
43188
43633
 
@@ -43218,10 +43663,13 @@ Start by quickly scanning a few key files to form an initial understanding of th
43218
43663
 
43219
43664
  If a non-read-only tool is blocked:
43220
43665
  - Do NOT retry the blocked tool or repeatedly attempt similar non-read-only tools
43666
+ - Do NOT use wrappers, quoting tricks, aliases, or obfuscation to make a blocked write look unknown
43221
43667
  - Do NOT immediately call exit_plan_mode just to unblock it \u2014 continue gathering context with read-only tools first
43222
43668
  - Pivot to read-only tools (read_file, grep_search, glob, list_directory, agents) to gather the information the blocked tool would have provided
43223
43669
  - Once you have enough context to form a complete plan, call exit_plan_mode
43224
43670
 
43671
+ An exact one-off approval for an unknown shell command approves only that invocation. It does not approve the plan, authorize related commands, or exit Plan mode.
43672
+
43225
43673
  ### When to Converge
43226
43674
 
43227
43675
  Your plan is ready when you have addressed all ambiguities and it covers: what to change, which files to modify, what existing code to reuse (with file paths), and how to verify the changes. Present your plan ${planOnly ? "directly" : `by calling the ${ToolNames.EXIT_PLAN_MODE} tool, which will prompt the user to confirm the plan`}. Do NOT make any file changes or run any tools that modify the system state in any way until the user has confirmed the plan.
@@ -49577,25 +50025,32 @@ function matchesMcpPattern(pattern, toolName) {
49577
50025
  if (pattern === toolName) {
49578
50026
  return true;
49579
50027
  }
50028
+ if (!pattern.endsWith("*") && pattern.split("__").length >= 3 && normalizeMcpToolName(pattern) === normalizeMcpToolName(toolName)) {
50029
+ return true;
50030
+ }
49580
50031
  if (pattern.endsWith("*")) {
49581
- const prefix = pattern.slice(0, -1);
49582
- return toolName.startsWith(prefix);
50032
+ const prefix = sanitizeToolNameForProvider(pattern.slice(0, -1));
50033
+ return sanitizeToolNameForProvider(toolName).startsWith(prefix);
49583
50034
  }
49584
50035
  const patternParts = pattern.split("__");
49585
50036
  const toolParts = toolName.split("__");
49586
- if (patternParts.length === 2 && toolParts.length >= 3 && patternParts[0] === toolParts[0] && patternParts[1] === toolParts[1]) {
50037
+ if (patternParts.length === 2 && toolParts.length >= 3 && patternParts[0] === toolParts[0] && sanitizeToolNameForProvider(patternParts[1]) === sanitizeToolNameForProvider(toolParts[1])) {
49587
50038
  return true;
49588
50039
  }
49589
50040
  return false;
49590
50041
  }
49591
50042
  __name(matchesMcpPattern, "matchesMcpPattern");
49592
- function matchesRule(rule, toolName, command, filePath, domain, pathContext, specifier, toolParams, pathMatchMode = "lexical") {
50043
+ function matchesRule(rule, toolName, command, filePath, domain, pathContext, specifier, toolParams, toolAliases2, pathMatchMode = "lexical") {
49593
50044
  const canonicalCtxToolName = resolveToolName(toolName);
49594
50045
  if (rule.invalid) {
49595
50046
  return false;
49596
50047
  }
49597
50048
  if (rule.toolName.startsWith("mcp__") || canonicalCtxToolName.startsWith("mcp__")) {
49598
- if (!matchesMcpPattern(rule.toolName, canonicalCtxToolName)) {
50049
+ const matchesLegacyExactName = !rule.toolName.endsWith("*") && rule.toolName.split("__").length >= 3 && (toolAliases2 ?? []).some(
50050
+ (alias) => rule.toolName === resolveToolName(alias)
50051
+ );
50052
+ const matchesMcpName = matchesMcpPattern(rule.toolName, canonicalCtxToolName) || matchesLegacyExactName;
50053
+ if (!matchesMcpName) {
49599
50054
  return false;
49600
50055
  }
49601
50056
  if (rule.specifier) {
@@ -54629,6 +55084,11 @@ async function classifyInternal(command) {
54629
55084
  }
54630
55085
  }
54631
55086
  __name(classifyInternal, "classifyInternal");
55087
+ async function classifyShellCommandSafety(command) {
55088
+ if (typeof command !== "string" || !command.trim()) return "unknown";
55089
+ return classifyInternal(command).catch(() => "unknown");
55090
+ }
55091
+ __name(classifyShellCommandSafety, "classifyShellCommandSafety");
54632
55092
  async function isShellCommandReadOnlyAST(command) {
54633
55093
  if (typeof command !== "string" || !command.trim()) return false;
54634
55094
  if (parserInitFailed) {
@@ -54981,7 +55441,16 @@ var PermissionManager = class _PermissionManager {
54981
55441
  * to match equivalent shell commands (e.g. `cat` → Read, `curl` → WebFetch).
54982
55442
  */
54983
55443
  evaluateSingle(ctx) {
54984
- const { toolName, command, cwd, filePath, domain, specifier, toolParams } = ctx;
55444
+ const {
55445
+ toolName,
55446
+ toolAliases: toolAliases2,
55447
+ command,
55448
+ cwd,
55449
+ filePath,
55450
+ domain,
55451
+ specifier,
55452
+ toolParams
55453
+ } = ctx;
54985
55454
  const pathCtx = this.config.getProjectRoot && this.config.getCwd ? {
54986
55455
  projectRoot: this.config.getProjectRoot(),
54987
55456
  cwd: cwd ?? this.config.getCwd()
@@ -54993,7 +55462,8 @@ var PermissionManager = class _PermissionManager {
54993
55462
  domain,
54994
55463
  pathCtx,
54995
55464
  specifier,
54996
- toolParams
55465
+ toolParams,
55466
+ toolAliases2
54997
55467
  ];
54998
55468
  const baseDecision = (() => {
54999
55469
  for (const rule of [
@@ -55224,7 +55694,16 @@ var PermissionManager = class _PermissionManager {
55224
55694
  */
55225
55695
  findMatchingDenyRule(ctx) {
55226
55696
  ctx = this.normalizePermissionContext(ctx);
55227
- const { toolName, command, cwd, filePath, domain, specifier, toolParams } = ctx;
55697
+ const {
55698
+ toolName,
55699
+ toolAliases: toolAliases2,
55700
+ command,
55701
+ cwd,
55702
+ filePath,
55703
+ domain,
55704
+ specifier,
55705
+ toolParams
55706
+ } = ctx;
55228
55707
  const pathCtx = this.config.getProjectRoot && this.config.getCwd ? {
55229
55708
  projectRoot: this.config.getProjectRoot(),
55230
55709
  cwd: cwd ?? this.config.getCwd()
@@ -55236,7 +55715,8 @@ var PermissionManager = class _PermissionManager {
55236
55715
  domain,
55237
55716
  pathCtx,
55238
55717
  specifier,
55239
- toolParams
55718
+ toolParams,
55719
+ toolAliases2
55240
55720
  ];
55241
55721
  for (const rule of [
55242
55722
  ...this.sessionRules.deny,
@@ -55290,7 +55770,16 @@ var PermissionManager = class _PermissionManager {
55290
55770
  */
55291
55771
  hasRelevantRules(ctx) {
55292
55772
  ctx = this.normalizePermissionContext(ctx);
55293
- const { toolName, command, cwd, filePath, domain, specifier, toolParams } = ctx;
55773
+ const {
55774
+ toolName,
55775
+ toolAliases: toolAliases2,
55776
+ command,
55777
+ cwd,
55778
+ filePath,
55779
+ domain,
55780
+ specifier,
55781
+ toolParams
55782
+ } = ctx;
55294
55783
  const pathCtx = this.config.getProjectRoot && this.config.getCwd ? {
55295
55784
  projectRoot: this.config.getProjectRoot(),
55296
55785
  cwd: cwd ?? this.config.getCwd()
@@ -55321,7 +55810,13 @@ var PermissionManager = class _PermissionManager {
55321
55810
  void 0
55322
55811
  ];
55323
55812
  return restrictiveRules.some(
55324
- (rule) => matchesRule(rule, ...opMatchArgs, void 0, "canonical")
55813
+ (rule) => matchesRule(
55814
+ rule,
55815
+ ...opMatchArgs,
55816
+ void 0,
55817
+ void 0,
55818
+ "canonical"
55819
+ )
55325
55820
  ) || allowRules.some(
55326
55821
  (rule) => matchesRule(rule, ...opMatchArgs, void 0)
55327
55822
  );
@@ -55344,7 +55839,8 @@ var PermissionManager = class _PermissionManager {
55344
55839
  domain,
55345
55840
  pathCtx,
55346
55841
  specifier,
55347
- toolParams
55842
+ toolParams,
55843
+ toolAliases2
55348
55844
  ];
55349
55845
  return restrictiveRules.some(
55350
55846
  (rule) => matchesRule(rule, ...matchArgs, "canonical")
@@ -55361,7 +55857,16 @@ var PermissionManager = class _PermissionManager {
55361
55857
  */
55362
55858
  hasMatchingAskRule(ctx) {
55363
55859
  ctx = this.normalizePermissionContext(ctx);
55364
- const { toolName, command, cwd, filePath, domain, specifier, toolParams } = ctx;
55860
+ const {
55861
+ toolName,
55862
+ toolAliases: toolAliases2,
55863
+ command,
55864
+ cwd,
55865
+ filePath,
55866
+ domain,
55867
+ specifier,
55868
+ toolParams
55869
+ } = ctx;
55365
55870
  const pathCtx = this.config.getProjectRoot && this.config.getCwd ? {
55366
55871
  projectRoot: this.config.getProjectRoot(),
55367
55872
  cwd: cwd ?? this.config.getCwd()
@@ -55383,7 +55888,13 @@ var PermissionManager = class _PermissionManager {
55383
55888
  void 0
55384
55889
  ];
55385
55890
  return askRules.some(
55386
- (rule) => matchesRule(rule, ...opMatchArgs, void 0, "canonical")
55891
+ (rule) => matchesRule(
55892
+ rule,
55893
+ ...opMatchArgs,
55894
+ void 0,
55895
+ void 0,
55896
+ "canonical"
55897
+ )
55387
55898
  );
55388
55899
  })) {
55389
55900
  return true;
@@ -55404,7 +55915,8 @@ var PermissionManager = class _PermissionManager {
55404
55915
  domain,
55405
55916
  pathCtx,
55406
55917
  specifier,
55407
- toolParams
55918
+ toolParams,
55919
+ toolAliases2
55408
55920
  ];
55409
55921
  return askRules.some(
55410
55922
  (rule) => matchesRule(rule, ...matchArgs, "canonical")
@@ -58253,7 +58765,7 @@ init_esbuild_shims();
58253
58765
  // packages/core/src/core/permission-helpers.ts
58254
58766
  init_esbuild_shims();
58255
58767
  import * as path18 from "node:path";
58256
- function buildPermissionCheckContext(toolName, toolParams, targetDir) {
58768
+ function buildPermissionCheckContext(toolName, toolParams, targetDir, toolAliases2) {
58257
58769
  const rawCommand = "command" in toolParams ? String(toolParams["command"]) : void 0;
58258
58770
  const command = rawCommand;
58259
58771
  const cwd = typeof toolParams["directory"] === "string" ? path18.isAbsolute(toolParams["directory"]) ? toolParams["directory"] : path18.resolve(targetDir, toolParams["directory"]) : void 0;
@@ -58272,7 +58784,16 @@ function buildPermissionCheckContext(toolName, toolParams, targetDir) {
58272
58784
  }
58273
58785
  }
58274
58786
  const specifier = typeof toolParams["skill"] === "string" ? toolParams["skill"] : typeof toolParams["subagent_type"] === "string" ? toolParams["subagent_type"] : typeof toolParams["server_name"] === "string" ? toolParams["server_name"] : void 0;
58275
- return { toolName, command, cwd, filePath, domain, specifier, toolParams };
58787
+ return {
58788
+ toolName,
58789
+ toolAliases: toolAliases2,
58790
+ command,
58791
+ cwd,
58792
+ filePath,
58793
+ domain,
58794
+ specifier,
58795
+ toolParams
58796
+ };
58276
58797
  }
58277
58798
  __name(buildPermissionCheckContext, "buildPermissionCheckContext");
58278
58799
  async function evaluatePermissionRules(pm, defaultPermission, pmCtx) {
@@ -58324,7 +58845,8 @@ async function evaluatePermissionFlow(config, invocation, toolName, toolParams)
58324
58845
  const pmCtx = buildPermissionCheckContext(
58325
58846
  toolName,
58326
58847
  toolParams,
58327
- config.getTargetDir?.() ?? ""
58848
+ config.getTargetDir?.() ?? "",
58849
+ invocation.permissionAliases
58328
58850
  );
58329
58851
  const { finalPermission, pmForcedAsk } = await evaluatePermissionRules(
58330
58852
  pm,
@@ -58382,6 +58904,200 @@ function isAutoEditApproved(approvalMode, confirmationDetails) {
58382
58904
  }
58383
58905
  __name(isAutoEditApproved, "isAutoEditApproved");
58384
58906
 
58907
+ // packages/core/src/core/plan-mode-shell-policy.ts
58908
+ init_esbuild_shims();
58909
+ import { isDeepStrictEqual } from "node:util";
58910
+ var UNKNOWN_WARNING = "Plan mode could not determine whether this shell command is read-only. Approval applies only to this exact invocation once; it may modify system state, and Plan mode will remain active.";
58911
+ var WRITE_BLOCK_MESSAGE = "Plan mode blocked this shell command because it was classified as state-modifying. Do not retry it through wrappers or obfuscation; continue read-only investigation and include the action in the plan.";
58912
+ var NO_APPROVAL_MESSAGE = "Plan mode could not determine whether this shell command is read-only, and no approval surface is available. The command was not run; Plan mode remains active.";
58913
+ var STALE_APPROVAL_MESSAGE = "Plan-mode shell approval is no longer valid because the mode, permission policy, or exact invocation changed. Submit a new tool call.";
58914
+ function isApplicable(decision) {
58915
+ return decision.classification !== "not-applicable";
58916
+ }
58917
+ __name(isApplicable, "isApplicable");
58918
+ function clone(value) {
58919
+ return structuredClone(value);
58920
+ }
58921
+ __name(clone, "clone");
58922
+ function abortError(signal) {
58923
+ return signal.reason instanceof Error ? signal.reason : new Error("Plan-mode shell policy evaluation was aborted.");
58924
+ }
58925
+ __name(abortError, "abortError");
58926
+ function raceWithAbort(operation, signal) {
58927
+ if (signal.aborted) {
58928
+ return Promise.reject(abortError(signal));
58929
+ }
58930
+ return new Promise((resolve38, reject) => {
58931
+ let settled = false;
58932
+ const finish = /* @__PURE__ */ __name((callback) => {
58933
+ if (settled) return;
58934
+ settled = true;
58935
+ signal.removeEventListener("abort", onAbort);
58936
+ callback();
58937
+ }, "finish");
58938
+ const onAbort = /* @__PURE__ */ __name(() => finish(() => reject(abortError(signal))), "onAbort");
58939
+ signal.addEventListener("abort", onAbort, { once: true });
58940
+ let pending;
58941
+ try {
58942
+ pending = operation();
58943
+ } catch (error) {
58944
+ finish(() => reject(error));
58945
+ return;
58946
+ }
58947
+ pending.then(
58948
+ (value) => finish(() => resolve38(value)),
58949
+ (error) => finish(() => reject(error))
58950
+ );
58951
+ });
58952
+ }
58953
+ __name(raceWithAbort, "raceWithAbort");
58954
+ function appendUnique(values, value) {
58955
+ return values?.includes(value) ? values : [...values ?? [], value];
58956
+ }
58957
+ __name(appendUnique, "appendUnique");
58958
+ function effectiveWorkingDirectory(config, invocationParams) {
58959
+ const directory = invocationParams["directory"];
58960
+ return typeof directory === "string" && directory.length > 0 ? directory : config.getTargetDir();
58961
+ }
58962
+ __name(effectiveWorkingDirectory, "effectiveWorkingDirectory");
58963
+ async function evaluatePlanModeShellPolicy(input) {
58964
+ if (input.toolName !== ToolNames.SHELL && input.toolName !== ToolNames.MONITOR) {
58965
+ return { classification: "not-applicable" };
58966
+ }
58967
+ if (input.config.getApprovalMode() !== "plan" /* PLAN */) {
58968
+ return { classification: "not-applicable" };
58969
+ }
58970
+ const rawCommand = typeof input.invocationParams["command"] === "string" ? input.invocationParams["command"] : "";
58971
+ const safetyCommand = input.toolName === ToolNames.MONITOR ? normalizeMonitorCommand(rawCommand).safetyCommand : rawCommand;
58972
+ const permissionContext = clone(input.permissionContext);
58973
+ permissionContext.cwd = effectiveWorkingDirectory(
58974
+ input.config,
58975
+ input.invocationParams
58976
+ );
58977
+ permissionContext.toolParams = clone(input.invocationParams);
58978
+ const invocationDirectory = input.invocationParams["directory"];
58979
+ const ambientWorkingDirectory = input.ambientWorkingDirectory ?? (typeof invocationDirectory !== "string" || invocationDirectory.length === 0 ? input.config.getTargetDir() : void 0);
58980
+ const snapshot = {
58981
+ requestArgs: clone(input.requestArgs),
58982
+ invocationParams: clone(input.invocationParams),
58983
+ approvalModeRevision: input.config.getApprovalModeRevision(),
58984
+ permissionContext,
58985
+ ambientWorkingDirectory
58986
+ };
58987
+ let classification;
58988
+ try {
58989
+ classification = await raceWithAbort(
58990
+ () => classifyShellCommandSafety(safetyCommand),
58991
+ input.signal
58992
+ );
58993
+ } catch (error) {
58994
+ if (input.signal.aborted) throw error;
58995
+ classification = "unknown";
58996
+ }
58997
+ return {
58998
+ classification,
58999
+ rawCommand,
59000
+ snapshot,
59001
+ writeBlockMessage: WRITE_BLOCK_MESSAGE,
59002
+ noApprovalMessage: NO_APPROVAL_MESSAGE
59003
+ };
59004
+ }
59005
+ __name(evaluatePlanModeShellPolicy, "evaluatePlanModeShellPolicy");
59006
+ async function validatePlanModeShellContext(input) {
59007
+ if (!isApplicable(input.decision)) return void 0;
59008
+ const decision = input.decision;
59009
+ if (input.signal.aborted) throw abortError(input.signal);
59010
+ const matchesSnapshot = /* @__PURE__ */ __name(() => !input.signal.aborted && input.config.getApprovalMode() === "plan" /* PLAN */ && input.config.getApprovalModeRevision() === decision.snapshot.approvalModeRevision && (decision.snapshot.ambientWorkingDirectory === void 0 || input.config.getTargetDir() === decision.snapshot.ambientWorkingDirectory) && effectiveWorkingDirectory(input.config, input.invocationParams) === decision.snapshot.permissionContext.cwd && isDeepStrictEqual(input.requestArgs, decision.snapshot.requestArgs) && isDeepStrictEqual(
59011
+ input.invocationParams,
59012
+ decision.snapshot.invocationParams
59013
+ ), "matchesSnapshot");
59014
+ if (!matchesSnapshot()) return STALE_APPROVAL_MESSAGE;
59015
+ const permissionManager = input.config.getPermissionManager?.();
59016
+ if (permissionManager) {
59017
+ try {
59018
+ const currentPermission = await raceWithAbort(
59019
+ () => permissionManager.evaluate(
59020
+ clone(decision.snapshot.permissionContext)
59021
+ ),
59022
+ input.signal
59023
+ );
59024
+ if (currentPermission === "deny") return STALE_APPROVAL_MESSAGE;
59025
+ } catch {
59026
+ if (input.signal.aborted) throw abortError(input.signal);
59027
+ return STALE_APPROVAL_MESSAGE;
59028
+ }
59029
+ }
59030
+ if (input.signal.aborted) throw abortError(input.signal);
59031
+ return matchesSnapshot() ? void 0 : STALE_APPROVAL_MESSAGE;
59032
+ }
59033
+ __name(validatePlanModeShellContext, "validatePlanModeShellContext");
59034
+ function decoratePlanModeShellConfirmation(decision, confirmation) {
59035
+ if (!isApplicable(decision)) return confirmation;
59036
+ if (confirmation.type === "ask_user_question") {
59037
+ throw new Error(decision.noApprovalMessage);
59038
+ }
59039
+ if (decision.classification !== "unknown") {
59040
+ return { ...confirmation, hideAlwaysAllow: true };
59041
+ }
59042
+ if (confirmation.type === "exec") {
59043
+ return {
59044
+ ...confirmation,
59045
+ hideAlwaysAllow: true,
59046
+ warnings: appendUnique(confirmation.warnings, UNKNOWN_WARNING)
59047
+ };
59048
+ }
59049
+ if (confirmation.type === "edit") {
59050
+ const warnings = appendUnique(confirmation.warnings, UNKNOWN_WARNING);
59051
+ return {
59052
+ ...confirmation,
59053
+ hideAlwaysAllow: true,
59054
+ hideModify: true,
59055
+ skipIdeDiff: true,
59056
+ warnings: appendUnique(
59057
+ warnings,
59058
+ `Exact shell command: \`${decision.rawCommand}\``
59059
+ )
59060
+ };
59061
+ }
59062
+ throw new Error(decision.noApprovalMessage);
59063
+ }
59064
+ __name(decoratePlanModeShellConfirmation, "decoratePlanModeShellConfirmation");
59065
+ async function validatePlanModeShellApproval(input) {
59066
+ if (!isApplicable(input.decision)) {
59067
+ return { outcome: input.outcome, payload: input.payload };
59068
+ }
59069
+ if (input.outcome === "cancel" /* Cancel */) {
59070
+ return {
59071
+ outcome: "cancel" /* Cancel */,
59072
+ ...input.payload?.cancelMessage ? { payload: { cancelMessage: input.payload.cancelMessage } } : {}
59073
+ };
59074
+ }
59075
+ const invalidContext = await validatePlanModeShellContext(input);
59076
+ const invalidOutcome = input.outcome !== "proceed_once" /* ProceedOnce */;
59077
+ const invalidPayload = input.payload?.newContent !== void 0 || input.payload?.updatedInput !== void 0 && !isDeepStrictEqual(
59078
+ input.payload.updatedInput,
59079
+ input.decision.snapshot.requestArgs
59080
+ );
59081
+ if (invalidContext || invalidOutcome || invalidPayload) {
59082
+ return {
59083
+ outcome: "cancel" /* Cancel */,
59084
+ payload: { cancelMessage: STALE_APPROVAL_MESSAGE }
59085
+ };
59086
+ }
59087
+ return { outcome: "proceed_once" /* ProceedOnce */ };
59088
+ }
59089
+ __name(validatePlanModeShellApproval, "validatePlanModeShellApproval");
59090
+
59091
+ // packages/core/src/core/plan-mode-entry-policy.ts
59092
+ init_esbuild_shims();
59093
+ var PLAN_MODE_ENTRY_SIBLING_SKIP_MESSAGE = "Tool call skipped because enter_plan_mode is an execution boundary. Retry it in the next model turn after observing the resulting approval mode.";
59094
+ function findPlanModeEntryBatchBoundaryIndex(toolNames) {
59095
+ if (toolNames.length <= 1) return void 0;
59096
+ const index = toolNames.indexOf(ToolNames.ENTER_PLAN_MODE);
59097
+ return index === -1 ? void 0 : index;
59098
+ }
59099
+ __name(findPlanModeEntryBatchBoundaryIndex, "findPlanModeEntryBatchBoundaryIndex");
59100
+
58385
59101
  // packages/core/src/core/geminiRequest.ts
58386
59102
  init_esbuild_shims();
58387
59103
  function partListUnionToString(value) {
@@ -65642,7 +66358,7 @@ var HybridTokenStorage = class extends BaseTokenStorage {
65642
66358
  const forceFileStorage = process.env[FORCE_FILE_STORAGE_ENV_VAR] === "true";
65643
66359
  if (!forceFileStorage) {
65644
66360
  try {
65645
- const { KeychainTokenStorage: KeychainTokenStorage2 } = await import("./keychain-token-storage-K23CFKGN.js");
66361
+ const { KeychainTokenStorage: KeychainTokenStorage2 } = await import("./keychain-token-storage-DWRJMNH3.js");
65646
66362
  const keychainStorage = new KeychainTokenStorage2(this.serviceName);
65647
66363
  const isAvailable = await keychainStorage.isAvailable();
65648
66364
  if (isAvailable) {
@@ -70842,15 +71558,28 @@ var ToolRegistry = class _ToolRegistry {
70842
71558
  * built-ins and MCP-discovered tools flow through `registerTool`, so
70843
71559
  * gating here covers every registration path.
70844
71560
  */
70845
- isToolDisabled(name) {
70846
- return this.config.getDisabledTools().has(name);
71561
+ isToolDisabled(name, aliases = []) {
71562
+ const disabledTools = this.config.getDisabledTools();
71563
+ const hasExactMatch = disabledTools.has(name) || aliases.some((alias) => disabledTools.has(alias));
71564
+ if (hasExactMatch || !name.startsWith("mcp__")) {
71565
+ return hasExactMatch;
71566
+ }
71567
+ for (const disabledName of disabledTools) {
71568
+ if (normalizeMcpToolName(disabledName) === name) {
71569
+ return true;
71570
+ }
71571
+ }
71572
+ return false;
70847
71573
  }
70848
71574
  /**
70849
71575
  * Registers a tool definition.
70850
71576
  * @param tool - The tool object containing schema and execution logic.
70851
71577
  */
70852
71578
  registerTool(tool) {
70853
- if (this.isToolDisabled(tool.name)) {
71579
+ if (this.isToolDisabled(
71580
+ tool.name,
71581
+ tool instanceof DiscoveredMCPTool ? tool.permissionAliases : []
71582
+ )) {
70854
71583
  debugLogger39.info(
70855
71584
  `Tool "${tool.name}" skipped: present in disabledTools set.`
70856
71585
  );
@@ -70867,7 +71596,10 @@ var ToolRegistry = class _ToolRegistry {
70867
71596
  );
70868
71597
  }
70869
71598
  }
70870
- if (this.isToolDisabled(tool.name)) {
71599
+ if (this.isToolDisabled(
71600
+ tool.name,
71601
+ tool instanceof DiscoveredMCPTool ? tool.permissionAliases : []
71602
+ )) {
70871
71603
  debugLogger39.info(
70872
71604
  `Tool "${tool.name}" skipped (post-rename): present in disabledTools set.`
70873
71605
  );
@@ -75064,6 +75796,12 @@ var TOKEN_PLAN_MODELS = [
75064
75796
  modalities: { image: true, video: true }
75065
75797
  },
75066
75798
  { id: "qwen3.7-max", contextWindowSize: 1e6, enableThinking: true },
75799
+ {
75800
+ id: "qwen3.8-max-preview",
75801
+ contextWindowSize: 1e6,
75802
+ enableThinking: true,
75803
+ modalities: { image: true, video: true }
75804
+ },
75067
75805
  {
75068
75806
  id: "qwen3.6-flash",
75069
75807
  contextWindowSize: 1e6,
@@ -89156,8 +89894,8 @@ var GitWorktreeService = class _GitWorktreeService {
89156
89894
  async getRegisteredWorktreeBranch(worktreePath) {
89157
89895
  let resolvedWorktreePath;
89158
89896
  try {
89159
- const stat19 = await fs25.stat(worktreePath);
89160
- if (!stat19.isDirectory()) return null;
89897
+ const stat20 = await fs25.stat(worktreePath);
89898
+ if (!stat20.isDirectory()) return null;
89161
89899
  resolvedWorktreePath = await fs25.realpath(worktreePath);
89162
89900
  } catch {
89163
89901
  return null;
@@ -89996,6 +90734,387 @@ function takeRecentDialog2(history, windowSize) {
89996
90734
  }
89997
90735
  __name(takeRecentDialog2, "takeRecentDialog");
89998
90736
 
90737
+ // packages/core/src/utils/conversation-chain.ts
90738
+ init_esbuild_shims();
90739
+ function buildOrderedUuidChain(records, opts) {
90740
+ if (records.length === 0) return { uuids: [], gaps: [] };
90741
+ const detectGaps = opts?.detectGaps ?? false;
90742
+ const transcriptRecords = records;
90743
+ const firstByUuid = /* @__PURE__ */ new Map();
90744
+ for (const r2 of records) {
90745
+ if (isTranscriptConversationRecord(r2) && !firstByUuid.has(r2.uuid)) {
90746
+ firstByUuid.set(r2.uuid, r2);
90747
+ }
90748
+ }
90749
+ const startUuid = selectTranscriptLeaf(transcriptRecords, opts?.leafUuid);
90750
+ if (!startUuid) return { uuids: [], gaps: [] };
90751
+ const chain = walkTranscriptUuidChain(
90752
+ startUuid,
90753
+ (uuid) => firstByUuid.get(uuid)
90754
+ );
90755
+ return {
90756
+ uuids: [...chain.uuids],
90757
+ gaps: detectGaps ? [...chain.gaps] : []
90758
+ };
90759
+ }
90760
+ __name(buildOrderedUuidChain, "buildOrderedUuidChain");
90761
+
90762
+ // packages/core/src/utils/conversation-branches.ts
90763
+ init_esbuild_shims();
90764
+ var SUMMARY_TEXT_LIMIT = 200;
90765
+ var SYNTHETIC_USER_SUBTYPES = /* @__PURE__ */ new Set([
90766
+ "notification",
90767
+ "cron",
90768
+ "mid_turn_user_message"
90769
+ ]);
90770
+ var NEUTRAL_TAIL_SUBTYPES = /* @__PURE__ */ new Set([
90771
+ "custom_title",
90772
+ "session_artifact_event",
90773
+ "session_artifact_snapshot"
90774
+ ]);
90775
+ function inspectConversationBranches(records) {
90776
+ if (records.length === 0) return { branches: [], diagnostics: [] };
90777
+ const index = buildConversationIndex(records);
90778
+ const semanticLeaves = findSemanticLeaves(index);
90779
+ const leafCountByAncestor = countLeafDescendants(
90780
+ semanticLeaves.map(({ leafUuid }) => leafUuid),
90781
+ index.firstByUuid
90782
+ );
90783
+ const rewindUuids = [...index.firstByUuid.values()].filter(isRewindRecord).map((record2) => record2.uuid);
90784
+ const forestPositions = indexForest(index);
90785
+ const branches = semanticLeaves.map(
90786
+ ({ leafUuid, physicalLeafUuid }) => summarizeBranch(
90787
+ leafUuid,
90788
+ physicalLeafUuid,
90789
+ leafCountByAncestor,
90790
+ rewindUuids,
90791
+ forestPositions,
90792
+ index
90793
+ )
90794
+ );
90795
+ return { branches, diagnostics: index.diagnostics };
90796
+ }
90797
+ __name(inspectConversationBranches, "inspectConversationBranches");
90798
+ function indexForest(index) {
90799
+ const positions = /* @__PURE__ */ new Map();
90800
+ let clock = 0;
90801
+ for (const [uuid, record2] of index.firstByUuid) {
90802
+ if (record2.parentUuid !== null && index.firstByUuid.has(record2.parentUuid)) {
90803
+ continue;
90804
+ }
90805
+ const stack = [
90806
+ { uuid, exiting: false }
90807
+ ];
90808
+ while (stack.length > 0) {
90809
+ const frame = stack.pop();
90810
+ if (frame.exiting) {
90811
+ const position = positions.get(frame.uuid);
90812
+ if (position) position.exitedAt = clock++;
90813
+ continue;
90814
+ }
90815
+ if (positions.has(frame.uuid)) continue;
90816
+ positions.set(frame.uuid, {
90817
+ rootUuid: uuid,
90818
+ enteredAt: clock++,
90819
+ exitedAt: -1
90820
+ });
90821
+ stack.push({ uuid: frame.uuid, exiting: true });
90822
+ const children = index.childrenByUuid.get(frame.uuid) ?? [];
90823
+ for (let childIndex = children.length - 1; childIndex >= 0; childIndex--) {
90824
+ stack.push({ uuid: children[childIndex], exiting: false });
90825
+ }
90826
+ }
90827
+ }
90828
+ return positions;
90829
+ }
90830
+ __name(indexForest, "indexForest");
90831
+ function buildConversationIndex(records) {
90832
+ const firstByUuid = /* @__PURE__ */ new Map();
90833
+ const recordsByUuid = /* @__PURE__ */ new Map();
90834
+ const physicalIndexByUuid = /* @__PURE__ */ new Map();
90835
+ for (const [physicalIndex, record2] of records.entries()) {
90836
+ const grouped = recordsByUuid.get(record2.uuid);
90837
+ if (grouped) {
90838
+ grouped.push(record2);
90839
+ } else {
90840
+ firstByUuid.set(record2.uuid, record2);
90841
+ recordsByUuid.set(record2.uuid, [record2]);
90842
+ physicalIndexByUuid.set(record2.uuid, physicalIndex);
90843
+ }
90844
+ }
90845
+ const diagnostics = [];
90846
+ const childrenByUuid = /* @__PURE__ */ new Map();
90847
+ for (const [uuid, grouped] of recordsByUuid) {
90848
+ const parentUuids = [
90849
+ ...new Set(grouped.map((record2) => record2.parentUuid))
90850
+ ];
90851
+ if (parentUuids.length > 1) {
90852
+ diagnostics.push({ kind: "conflicting-parent", uuid, parentUuids });
90853
+ }
90854
+ const parentUuid = firstByUuid.get(uuid)?.parentUuid;
90855
+ if (parentUuid === void 0 || parentUuid === null) continue;
90856
+ if (!firstByUuid.has(parentUuid)) {
90857
+ diagnostics.push({
90858
+ kind: "missing-parent",
90859
+ childUuid: uuid,
90860
+ missingParentUuid: parentUuid
90861
+ });
90862
+ continue;
90863
+ }
90864
+ const children = childrenByUuid.get(parentUuid);
90865
+ if (children) {
90866
+ children.push(uuid);
90867
+ } else {
90868
+ childrenByUuid.set(parentUuid, [uuid]);
90869
+ }
90870
+ }
90871
+ diagnostics.push(...findParentCycles(firstByUuid));
90872
+ return {
90873
+ firstByUuid,
90874
+ recordsByUuid,
90875
+ childrenByUuid,
90876
+ physicalIndexByUuid,
90877
+ diagnostics
90878
+ };
90879
+ }
90880
+ __name(buildConversationIndex, "buildConversationIndex");
90881
+ function findParentCycles(firstByUuid) {
90882
+ const complete = /* @__PURE__ */ new Set();
90883
+ const diagnostics = [];
90884
+ for (const startUuid of firstByUuid.keys()) {
90885
+ if (complete.has(startUuid)) continue;
90886
+ const path99 = [];
90887
+ const positionByUuid = /* @__PURE__ */ new Map();
90888
+ let currentUuid = startUuid;
90889
+ while (currentUuid !== null && firstByUuid.has(currentUuid)) {
90890
+ if (complete.has(currentUuid)) break;
90891
+ const existingPosition = positionByUuid.get(currentUuid);
90892
+ if (existingPosition !== void 0) {
90893
+ diagnostics.push({
90894
+ kind: "parent-cycle",
90895
+ uuids: path99.slice(existingPosition)
90896
+ });
90897
+ break;
90898
+ }
90899
+ positionByUuid.set(currentUuid, path99.length);
90900
+ path99.push(currentUuid);
90901
+ currentUuid = firstByUuid.get(currentUuid)?.parentUuid ?? null;
90902
+ }
90903
+ for (const uuid of path99) complete.add(uuid);
90904
+ }
90905
+ return diagnostics;
90906
+ }
90907
+ __name(findParentCycles, "findParentCycles");
90908
+ function findSemanticLeaves(index) {
90909
+ const candidates = /* @__PURE__ */ new Set();
90910
+ const physicalLeafBySemanticLeaf = /* @__PURE__ */ new Map();
90911
+ for (const uuid of index.firstByUuid.keys()) {
90912
+ if ((index.childrenByUuid.get(uuid)?.length ?? 0) > 0) continue;
90913
+ const leafUuid = collapseNeutralTail(uuid, index.firstByUuid);
90914
+ if (leafUuid === null) continue;
90915
+ candidates.add(leafUuid);
90916
+ physicalLeafBySemanticLeaf.set(leafUuid, uuid);
90917
+ }
90918
+ const superseded = /* @__PURE__ */ new Set();
90919
+ for (const candidate of candidates) {
90920
+ const visited = /* @__PURE__ */ new Set();
90921
+ let currentUuid = index.firstByUuid.get(candidate)?.parentUuid ?? null;
90922
+ while (currentUuid !== null && index.firstByUuid.has(currentUuid) && !visited.has(currentUuid)) {
90923
+ if (candidates.has(currentUuid)) superseded.add(currentUuid);
90924
+ visited.add(currentUuid);
90925
+ currentUuid = index.firstByUuid.get(currentUuid)?.parentUuid ?? null;
90926
+ }
90927
+ }
90928
+ const leaves = [...candidates].filter(
90929
+ (candidate) => !superseded.has(candidate)
90930
+ );
90931
+ return leaves.sort((left, right) => {
90932
+ const leftPhysicalLeaf = physicalLeafBySemanticLeaf.get(left);
90933
+ const rightPhysicalLeaf = physicalLeafBySemanticLeaf.get(right);
90934
+ return index.physicalIndexByUuid.get(leftPhysicalLeaf) - index.physicalIndexByUuid.get(rightPhysicalLeaf);
90935
+ }).map((leafUuid) => ({
90936
+ leafUuid,
90937
+ physicalLeafUuid: physicalLeafBySemanticLeaf.get(leafUuid)
90938
+ }));
90939
+ }
90940
+ __name(findSemanticLeaves, "findSemanticLeaves");
90941
+ function countLeafDescendants(semanticLeaves, firstByUuid) {
90942
+ const counts = /* @__PURE__ */ new Map();
90943
+ for (const leafUuid of semanticLeaves) {
90944
+ for (const uuid of buildChain(leafUuid, firstByUuid)) {
90945
+ counts.set(uuid, (counts.get(uuid) ?? 0) + 1);
90946
+ }
90947
+ }
90948
+ return counts;
90949
+ }
90950
+ __name(countLeafDescendants, "countLeafDescendants");
90951
+ function collapseNeutralTail(leafUuid, firstByUuid) {
90952
+ const visited = /* @__PURE__ */ new Set();
90953
+ let currentUuid = leafUuid;
90954
+ while (!visited.has(currentUuid)) {
90955
+ visited.add(currentUuid);
90956
+ const record2 = firstByUuid.get(currentUuid);
90957
+ if (!record2) return null;
90958
+ if (!isNeutralTailRecord(record2)) return currentUuid;
90959
+ const parentUuid = record2.parentUuid;
90960
+ if (parentUuid === null || !firstByUuid.has(parentUuid)) return null;
90961
+ currentUuid = parentUuid;
90962
+ }
90963
+ return null;
90964
+ }
90965
+ __name(collapseNeutralTail, "collapseNeutralTail");
90966
+ function summarizeBranch(leafUuid, physicalLeafUuid, leafCountByAncestor, rewindUuids, forestPositions, index) {
90967
+ const chain = buildChain(leafUuid, index.firstByUuid);
90968
+ const chainSet = new Set(chain);
90969
+ const branchPointUuid = findBranchPoint(chain, leafCountByAncestor);
90970
+ const containsRewindUuids = chain.filter(
90971
+ (uuid) => isRewindRecord(index.firstByUuid.get(uuid))
90972
+ );
90973
+ const siblingRewindUuids = rewindUuids.filter(
90974
+ (rewindUuid) => !chainSet.has(rewindUuid) && isSiblingPath(
90975
+ leafUuid,
90976
+ chain,
90977
+ rewindUuid,
90978
+ forestPositions,
90979
+ index.firstByUuid
90980
+ )
90981
+ );
90982
+ const firstRecord = index.firstByUuid.get(chain[0]);
90983
+ const physicalLeafRecord = index.firstByUuid.get(physicalLeafUuid);
90984
+ const recordCounts = { user: 0, assistant: 0, toolResult: 0, system: 0 };
90985
+ for (const uuid of chain) {
90986
+ const record2 = index.firstByUuid.get(uuid);
90987
+ if (record2.type === "tool_result") {
90988
+ recordCounts.toolResult++;
90989
+ } else {
90990
+ recordCounts[record2.type]++;
90991
+ }
90992
+ }
90993
+ const firstDistinctIndex = branchPointUuid ? chain.indexOf(branchPointUuid) + 1 : 0;
90994
+ const firstUserTextAfterBranchPoint = findUserText(
90995
+ chain.slice(firstDistinctIndex),
90996
+ index
90997
+ );
90998
+ const lastUserText = findUserText([...chain].reverse(), index);
90999
+ const lastAssistantText = findAssistantText([...chain].reverse(), index);
91000
+ return {
91001
+ leafUuid,
91002
+ branchPointUuid,
91003
+ classification: classifyBranch(
91004
+ containsRewindUuids.length > 0,
91005
+ siblingRewindUuids.length > 0
91006
+ ),
91007
+ containsRewindUuids,
91008
+ siblingRewindUuids,
91009
+ ...firstUserTextAfterBranchPoint ? { firstUserTextAfterBranchPoint } : {},
91010
+ ...lastUserText ? { lastUserText } : {},
91011
+ ...lastAssistantText ? { lastAssistantText } : {},
91012
+ recordCounts,
91013
+ startedAt: firstRecord.timestamp,
91014
+ updatedAt: physicalLeafRecord.timestamp
91015
+ };
91016
+ }
91017
+ __name(summarizeBranch, "summarizeBranch");
91018
+ function findBranchPoint(chain, leafCountByAncestor) {
91019
+ for (let index = chain.length - 2; index >= 0; index--) {
91020
+ const candidate = chain[index];
91021
+ if (candidate && (leafCountByAncestor.get(candidate) ?? 0) > 1) {
91022
+ return candidate;
91023
+ }
91024
+ }
91025
+ return null;
91026
+ }
91027
+ __name(findBranchPoint, "findBranchPoint");
91028
+ function findUserText(uuids, index) {
91029
+ for (const uuid of uuids) {
91030
+ const record2 = index.firstByUuid.get(uuid);
91031
+ if (!record2 || record2.type !== "user" || isSyntheticUserRecord(record2)) {
91032
+ continue;
91033
+ }
91034
+ const text = extractText2(index.recordsByUuid.get(uuid) ?? [], "user");
91035
+ if (text) return text;
91036
+ }
91037
+ return void 0;
91038
+ }
91039
+ __name(findUserText, "findUserText");
91040
+ function findAssistantText(uuids, index) {
91041
+ for (const uuid of uuids) {
91042
+ if (index.firstByUuid.get(uuid)?.type !== "assistant") continue;
91043
+ const text = extractText2(index.recordsByUuid.get(uuid) ?? [], "assistant");
91044
+ if (text) return text;
91045
+ }
91046
+ return void 0;
91047
+ }
91048
+ __name(findAssistantText, "findAssistantText");
91049
+ function extractText2(records, type) {
91050
+ const text = records.filter(
91051
+ (record2) => record2.type === type && (type !== "user" || !isSyntheticUserRecord(record2))
91052
+ ).flatMap((record2) => record2.message?.parts ?? []).map((part) => {
91053
+ const textPart = part;
91054
+ return typeof textPart.text === "string" && textPart.thought !== true ? textPart.text : "";
91055
+ }).join(" ").replace(/\s+/g, " ").trim();
91056
+ if (!text) return void 0;
91057
+ return text.length > SUMMARY_TEXT_LIMIT ? `${text.slice(0, SUMMARY_TEXT_LIMIT)}...` : text;
91058
+ }
91059
+ __name(extractText2, "extractText");
91060
+ function buildChain(leafUuid, firstByUuid) {
91061
+ const chain = [];
91062
+ const visited = /* @__PURE__ */ new Set();
91063
+ let currentUuid = leafUuid;
91064
+ while (currentUuid !== null && firstByUuid.has(currentUuid) && !visited.has(currentUuid)) {
91065
+ visited.add(currentUuid);
91066
+ chain.push(currentUuid);
91067
+ currentUuid = firstByUuid.get(currentUuid)?.parentUuid ?? null;
91068
+ }
91069
+ chain.reverse();
91070
+ return chain;
91071
+ }
91072
+ __name(buildChain, "buildChain");
91073
+ function isSiblingPath(leafUuid, leafChain, rewindUuid, forestPositions, firstByUuid) {
91074
+ const leafPosition = forestPositions.get(leafUuid);
91075
+ const rewindPosition = forestPositions.get(rewindUuid);
91076
+ if (leafPosition && rewindPosition) {
91077
+ return leafPosition.rootUuid === rewindPosition.rootUuid && !isAncestorPosition(leafPosition, rewindPosition);
91078
+ }
91079
+ return pathsDiverge(leafChain, buildChain(rewindUuid, firstByUuid));
91080
+ }
91081
+ __name(isSiblingPath, "isSiblingPath");
91082
+ function isAncestorPosition(ancestor, descendant) {
91083
+ return ancestor.enteredAt <= descendant.enteredAt && ancestor.exitedAt >= descendant.exitedAt;
91084
+ }
91085
+ __name(isAncestorPosition, "isAncestorPosition");
91086
+ function pathsDiverge(left, right) {
91087
+ const rightPositions = new Map(right.map((uuid, index) => [uuid, index]));
91088
+ for (let leftIndex = left.length - 1; leftIndex >= 0; leftIndex--) {
91089
+ const uuid = left[leftIndex];
91090
+ if (!uuid) continue;
91091
+ const rightIndex = rightPositions.get(uuid);
91092
+ if (rightIndex === void 0) continue;
91093
+ return leftIndex < left.length - 1 && rightIndex < right.length - 1;
91094
+ }
91095
+ return false;
91096
+ }
91097
+ __name(pathsDiverge, "pathsDiverge");
91098
+ function isNeutralTailRecord(record2) {
91099
+ return record2.type === "system" && record2.subtype !== void 0 && NEUTRAL_TAIL_SUBTYPES.has(record2.subtype);
91100
+ }
91101
+ __name(isNeutralTailRecord, "isNeutralTailRecord");
91102
+ function isSyntheticUserRecord(record2) {
91103
+ return record2.externalInputKind === "notification" || record2.subtype !== void 0 && SYNTHETIC_USER_SUBTYPES.has(record2.subtype);
91104
+ }
91105
+ __name(isSyntheticUserRecord, "isSyntheticUserRecord");
91106
+ function isRewindRecord(record2) {
91107
+ return record2?.type === "system" && record2.subtype === "rewind";
91108
+ }
91109
+ __name(isRewindRecord, "isRewindRecord");
91110
+ function classifyBranch(containsRewind, hasSiblingRewind) {
91111
+ if (containsRewind && hasSiblingRewind) return "mixed-rewind";
91112
+ if (containsRewind) return "rewind-descendant";
91113
+ if (hasSiblingRewind) return "rewind-sibling";
91114
+ return "ordinary";
91115
+ }
91116
+ __name(classifyBranch, "classifyBranch");
91117
+
89999
91118
  // packages/core/src/services/worktreeSessionService.ts
90000
91119
  init_esbuild_shims();
90001
91120
  import * as fs26 from "node:fs/promises";
@@ -90259,8 +91378,8 @@ async function restoreWorktreeContext(sidecarPath, onWarn) {
90259
91378
  }
90260
91379
  let worktreeAlive = false;
90261
91380
  try {
90262
- const stat19 = await fs26.stat(session.worktreePath);
90263
- worktreeAlive = stat19.isDirectory();
91381
+ const stat20 = await fs26.stat(session.worktreePath);
91382
+ worktreeAlive = stat20.isDirectory();
90264
91383
  } catch {
90265
91384
  worktreeAlive = false;
90266
91385
  }
@@ -93051,10 +94170,10 @@ function readOutputTail(outputFile) {
93051
94170
  let fd;
93052
94171
  try {
93053
94172
  fd = fs28.openSync(outputFile, getReadOutputOpenFlags());
93054
- const stat19 = fs28.fstatSync(fd);
93055
- if (!stat19.isFile() || stat19.size <= 0) return void 0;
93056
- const length = Math.min(stat19.size, MAX_NOTIFICATION_OUTPUT_TAIL_BYTES);
93057
- const start = stat19.size - length;
94173
+ const stat20 = fs28.fstatSync(fd);
94174
+ if (!stat20.isFile() || stat20.size <= 0) return void 0;
94175
+ const length = Math.min(stat20.size, MAX_NOTIFICATION_OUTPUT_TAIL_BYTES);
94176
+ const start = stat20.size - length;
93058
94177
  const buffer = Buffer.allocUnsafe(length);
93059
94178
  const bytesRead = fs28.readSync(fd, buffer, 0, length, start);
93060
94179
  let sliceOffset = 0;
@@ -95318,6 +96437,32 @@ async function listChannelMemoryEntries(target) {
95318
96437
  return document.entries;
95319
96438
  }
95320
96439
  __name(listChannelMemoryEntries, "listChannelMemoryEntries");
96440
+ async function getFileRevision(filePath) {
96441
+ try {
96442
+ const stats = await fs32.stat(filePath, { bigint: true });
96443
+ return [
96444
+ stats.dev,
96445
+ stats.ino,
96446
+ stats.size,
96447
+ stats.mtimeNs,
96448
+ stats.ctimeNs
96449
+ ].join(":");
96450
+ } catch (error) {
96451
+ if (isMissingFile(error)) {
96452
+ return "missing";
96453
+ }
96454
+ throw error;
96455
+ }
96456
+ }
96457
+ __name(getFileRevision, "getFileRevision");
96458
+ async function getChannelMemoryRevision(target) {
96459
+ const [canonical, legacy] = await Promise.all([
96460
+ getFileRevision(getChannelMemoryFilePath(target)),
96461
+ getFileRevision(getLegacyChannelMemoryFilePath(target))
96462
+ ]);
96463
+ return createHash11("sha256").update(canonical).update("\0").update(legacy).digest("hex");
96464
+ }
96465
+ __name(getChannelMemoryRevision, "getChannelMemoryRevision");
95321
96466
  async function addChannelMemoryEntries(target, texts, createdBy) {
95322
96467
  const textSnapshot = Array.from(texts);
95323
96468
  if (textSnapshot.length > MAX_CHANNEL_MEMORY_ENTRIES_PER_REQUEST) {
@@ -97327,11 +98472,11 @@ var WorkspaceMemoryFileTooLargeError = class extends Error {
97327
98472
  async function composeAppendedContent(filePath, newContent) {
97328
98473
  let existing = "";
97329
98474
  try {
97330
- const stat19 = await fs39.stat(filePath);
97331
- if (stat19.size > MAX_EXISTING_FILE_BYTES) {
98475
+ const stat20 = await fs39.stat(filePath);
98476
+ if (stat20.size > MAX_EXISTING_FILE_BYTES) {
97332
98477
  throw new WorkspaceMemoryFileTooLargeError(
97333
98478
  filePath,
97334
- stat19.size,
98479
+ stat20.size,
97335
98480
  MAX_EXISTING_FILE_BYTES
97336
98481
  );
97337
98482
  }
@@ -98380,13 +99525,13 @@ var IdeClient = class _IdeClient {
98380
99525
  lockFiles.map(async (file) => {
98381
99526
  const fullPath = path47.join(ideDir, file);
98382
99527
  try {
98383
- const stat19 = await fs40.promises.stat(fullPath);
99528
+ const stat20 = await fs40.promises.stat(fullPath);
98384
99529
  const content = await fs40.promises.readFile(fullPath, "utf8");
98385
99530
  try {
98386
99531
  return {
98387
99532
  file,
98388
99533
  fullPath,
98389
- mtimeMs: stat19.mtimeMs,
99534
+ mtimeMs: stat20.mtimeMs,
98390
99535
  parsed: JSON.parse(content)
98391
99536
  };
98392
99537
  } catch (error) {
@@ -99922,7 +101067,7 @@ var LspResponseNormalizer = class {
99922
101067
  /**
99923
101068
  * Convert diagnostic back to LSP format for requests
99924
101069
  */
99925
- denormalizeDiagnostic(diagnostic) {
101070
+ denormalizeDiagnostic(diagnostic2) {
99926
101071
  const severityMap = {
99927
101072
  error: 1,
99928
101073
  warning: 2,
@@ -99930,11 +101075,11 @@ var LspResponseNormalizer = class {
99930
101075
  hint: 4
99931
101076
  };
99932
101077
  return {
99933
- range: diagnostic.range,
99934
- message: diagnostic.message,
99935
- severity: diagnostic.severity ? severityMap[diagnostic.severity] : void 0,
99936
- code: diagnostic.code,
99937
- source: diagnostic.source
101078
+ range: diagnostic2.range,
101079
+ message: diagnostic2.message,
101080
+ severity: diagnostic2.severity ? severityMap[diagnostic2.severity] : void 0,
101081
+ code: diagnostic2.code,
101082
+ source: diagnostic2.source
99938
101083
  };
99939
101084
  }
99940
101085
  /**
@@ -107832,8 +108977,8 @@ async function collectResources(resourcePaths, pluginRoot, destDir) {
107832
108977
  debugLogger75.warn(`Resource path not found: ${resolvedPath}`);
107833
108978
  continue;
107834
108979
  }
107835
- const stat19 = fs51.statSync(resolvedPath);
107836
- if (stat19.isDirectory()) {
108980
+ const stat20 = fs51.statSync(resolvedPath);
108981
+ if (stat20.isDirectory()) {
107837
108982
  const dirName = path56.basename(resolvedPath);
107838
108983
  const finalDestDir = dirName === destFolderName ? destDir : path56.join(destDir, dirName);
107839
108984
  const files = await glob("**/*", {
@@ -109425,7 +110570,7 @@ import * as path62 from "node:path";
109425
110570
  init_esbuild_shims();
109426
110571
  import * as fs57 from "node:fs";
109427
110572
  import * as path61 from "node:path";
109428
- import { stat as stat9 } from "node:fs/promises";
110573
+ import { stat as stat10 } from "node:fs/promises";
109429
110574
  var debugLogger79 = createDebugLogger("EXT_MARKETPLACE");
109430
110575
  function parseSourceAndPluginName(source) {
109431
110576
  const urlSchemes = ["http://", "https://", "git@", "sso://"];
@@ -109612,7 +110757,7 @@ async function loadMarketplaceConfigFromSource(source, networkPolicy) {
109612
110757
  const trimmed2 = source.trim();
109613
110758
  const lowerTrimmed = trimmed2.toLowerCase();
109614
110759
  try {
109615
- const stats = await stat9(trimmed2);
110760
+ const stats = await stat10(trimmed2);
109616
110761
  if (stats.isDirectory()) {
109617
110762
  return await readLocalMarketplaceConfig(trimmed2);
109618
110763
  }
@@ -109685,7 +110830,7 @@ async function parseInstallSource(source, options2 = {}) {
109685
110830
  let marketplaceConfig = null;
109686
110831
  let isLocalPath = false;
109687
110832
  try {
109688
- await stat9(repo);
110833
+ await stat10(repo);
109689
110834
  isLocalPath = true;
109690
110835
  } catch {
109691
110836
  }
@@ -115584,13 +116729,13 @@ import * as os20 from "os";
115584
116729
  // node_modules/chokidar/esm/index.js
115585
116730
  init_esbuild_shims();
115586
116731
  import { stat as statcb } from "fs";
115587
- import { stat as stat13, readdir as readdir11 } from "fs/promises";
116732
+ import { stat as stat14, readdir as readdir11 } from "fs/promises";
115588
116733
  import { EventEmitter as EventEmitter5 } from "events";
115589
116734
  import * as sysPath2 from "path";
115590
116735
 
115591
116736
  // node_modules/readdirp/esm/index.js
115592
116737
  init_esbuild_shims();
115593
- import { stat as stat11, lstat as lstat6, readdir as readdir10, realpath as realpath7 } from "node:fs/promises";
116738
+ import { stat as stat12, lstat as lstat6, readdir as readdir10, realpath as realpath7 } from "node:fs/promises";
115594
116739
  import { Readable } from "node:stream";
115595
116740
  import { resolve as presolve, relative as prelative, join as pjoin, sep as psep } from "node:path";
115596
116741
  var EntryTypes = {
@@ -115660,7 +116805,7 @@ var ReaddirpStream = class extends Readable {
115660
116805
  const { root, type } = opts;
115661
116806
  this._fileFilter = normalizeFilter(opts.fileFilter);
115662
116807
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
115663
- const statMethod = opts.lstat ? lstat6 : stat11;
116808
+ const statMethod = opts.lstat ? lstat6 : stat12;
115664
116809
  if (wantBigintFsStats) {
115665
116810
  this._stat = (path99) => statMethod(path99, { bigint: true });
115666
116811
  } else {
@@ -115815,7 +116960,7 @@ __name(readdirp, "readdirp");
115815
116960
  // node_modules/chokidar/esm/handler.js
115816
116961
  init_esbuild_shims();
115817
116962
  import { watchFile, unwatchFile, watch as fs_watch } from "fs";
115818
- import { open as open6, stat as stat12, lstat as lstat7, realpath as fsrealpath } from "fs/promises";
116963
+ import { open as open6, stat as stat13, lstat as lstat7, realpath as fsrealpath } from "fs/promises";
115819
116964
  import * as sysPath from "path";
115820
116965
  import { type as osType } from "os";
115821
116966
  var STR_DATA = "data";
@@ -115842,7 +116987,7 @@ var EVENTS = {
115842
116987
  };
115843
116988
  var EV = EVENTS;
115844
116989
  var THROTTLE_MODE_WATCH = "watch";
115845
- var statMethods = { lstat: lstat7, stat: stat12 };
116990
+ var statMethods = { lstat: lstat7, stat: stat13 };
115846
116991
  var KEY_LISTENERS = "listeners";
115847
116992
  var KEY_ERR = "errHandlers";
115848
116993
  var KEY_RAW = "rawEmitters";
@@ -116332,7 +117477,7 @@ var NodeFsHandler = class {
116332
117477
  return;
116333
117478
  if (!newStats || newStats.mtimeMs === 0) {
116334
117479
  try {
116335
- const newStats2 = await stat12(file);
117480
+ const newStats2 = await stat13(file);
116336
117481
  if (this.fsw.closed)
116337
117482
  return;
116338
117483
  const at2 = newStats2.atimeMs;
@@ -117045,7 +118190,7 @@ var FSWatcher = class extends EventEmitter5 {
117045
118190
  const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path99) : path99;
117046
118191
  let stats2;
117047
118192
  try {
117048
- stats2 = await stat13(fullPath);
118193
+ stats2 = await stat14(fullPath);
117049
118194
  } catch (err) {
117050
118195
  }
117051
118196
  if (!stats2 || this.closed)
@@ -117173,8 +118318,8 @@ var FSWatcher = class extends EventEmitter5 {
117173
118318
  }
117174
118319
  return this._userIgnored(path99, stats);
117175
118320
  }
117176
- _isntIgnored(path99, stat19) {
117177
- return !this._isIgnored(path99, stat19);
118321
+ _isntIgnored(path99, stat20) {
118322
+ return !this._isIgnored(path99, stat20);
117178
118323
  }
117179
118324
  /**
117180
118325
  * Provides a set of common helpers and properties relating to symlink handling.
@@ -118345,12 +119490,12 @@ __name(isWithin, "isWithin");
118345
119490
  async function readBoundedTaskFile(filePath) {
118346
119491
  const handle = await fs66.open(filePath, "r");
118347
119492
  try {
118348
- const stat19 = await handle.stat();
118349
- if (!stat19.isFile()) {
119493
+ const stat20 = await handle.stat();
119494
+ if (!stat20.isFile()) {
118350
119495
  return null;
118351
119496
  }
118352
119497
  const cap = LOOP_TASK_FILE_MAX_BYTES + 1;
118353
- const allocSize = Math.min(cap, stat19.size + 1);
119498
+ const allocSize = Math.min(cap, stat20.size + 1);
118354
119499
  const buffer = Buffer.alloc(allocSize);
118355
119500
  let total = 0;
118356
119501
  while (total < allocSize) {
@@ -123613,6 +124758,7 @@ ${_TeamManager.escapeEnvelopeTags(m2.text)}
123613
124758
  // fileDiff}`), which doesn't match what permission policies
123614
124759
  // expect to see (e.g. `{file_path, content}`).
123615
124760
  toolInput: event.args ?? {},
124761
+ confirmationDetails: event.confirmationDetails,
123616
124762
  respond: event.respond,
123617
124763
  timestamp: Date.now()
123618
124764
  };
@@ -123814,9 +124960,12 @@ var MAX_DESCRIPTION_LENGTH2 = 40;
123814
124960
  var MAX_RECENT_ACTIVITIES = 10;
123815
124961
  var DEFAULT_MAX_CONCURRENT_BACKGROUND_AGENTS = 10;
123816
124962
  var BACKGROUND_AGENT_CONCURRENCY_ENV = "QWEN_CODE_MAX_BACKGROUND_AGENTS";
123817
- function normalizeBackgroundApprovalOutcome(outcome) {
124963
+ function normalizeBackgroundApprovalOutcome(outcome, confirmationDetails) {
123818
124964
  if (outcome === "proceed_always" /* ProceedAlways */ || outcome === "proceed_always_project" /* ProceedAlwaysProject */ || outcome === "proceed_always_user" /* ProceedAlwaysUser */ || outcome === "proceed_always_server" /* ProceedAlwaysServer */ || outcome === "proceed_always_tool" /* ProceedAlwaysTool */) {
123819
- return "proceed_once" /* ProceedOnce */;
124965
+ if (confirmationDetails.type === "plan" && outcome === "proceed_always" /* ProceedAlways */) {
124966
+ return outcome;
124967
+ }
124968
+ return "cancel" /* Cancel */;
123820
124969
  }
123821
124970
  return outcome;
123822
124971
  }
@@ -124228,9 +125377,13 @@ var BackgroundTaskRegistry = class {
124228
125377
  );
124229
125378
  this.emitApprovalChange(entry);
124230
125379
  try {
125380
+ const normalizedOutcome = normalizeBackgroundApprovalOutcome(
125381
+ outcome,
125382
+ approval.confirmationDetails
125383
+ );
124231
125384
  await approval.respond(
124232
- normalizeBackgroundApprovalOutcome(outcome),
124233
- payload
125385
+ normalizedOutcome,
125386
+ normalizedOutcome === outcome ? payload : void 0
124234
125387
  );
124235
125388
  } catch (error) {
124236
125389
  debugLogger99.error(
@@ -124928,11 +126081,11 @@ function reconstructHistory(records, leafUuid) {
124928
126081
  return uuids.map((uuid) => firstByUuid.get(uuid)).filter((record2) => !!record2);
124929
126082
  }
124930
126083
  __name(reconstructHistory, "reconstructHistory");
124931
- function extractText2(parts) {
126084
+ function extractText3(parts) {
124932
126085
  if (!parts?.length) return "";
124933
126086
  return parts.map((part) => "text" in part && part.text ? part.text : "").join("\n").trim();
124934
126087
  }
124935
- __name(extractText2, "extractText");
126088
+ __name(extractText3, "extractText");
124936
126089
  function coalesceAdjacentUserHistory(messages) {
124937
126090
  const result = [];
124938
126091
  for (const message of messages) {
@@ -124960,7 +126113,7 @@ function recoverTranscript(records) {
124960
126113
  const launchPromptRecord = filtered.find(
124961
126114
  (record2) => record2.type === "system" && record2.subtype === "agent_launch_prompt" && record2.systemPayload
124962
126115
  );
124963
- const initialPrompt = filtered.find((record2) => record2.type === "user") ? extractText2(
126116
+ const initialPrompt = filtered.find((record2) => record2.type === "user") ? extractText3(
124964
126117
  filtered.find((record2) => record2.type === "user")?.message?.parts
124965
126118
  ) : void 0;
124966
126119
  const stableForBranch = [...filtered];
@@ -126272,7 +127425,7 @@ async function evaluateToolCall(toolName, args, overlayFs, approvalMode) {
126272
127425
  }
126273
127426
  if (toolName === ToolNames.SHELL) {
126274
127427
  const command = typeof args["command"] === "string" ? args["command"] : "";
126275
- if (command && await isShellCommandReadOnlyAST(command)) {
127428
+ if (command && await classifyShellCommandSafety(command) === "read-only") {
126276
127429
  return { action: "allow" };
126277
127430
  }
126278
127431
  return {
@@ -127148,12 +128301,12 @@ function resolveGitDir2(crawlDirectory) {
127148
128301
  while (current) {
127149
128302
  const gitPath = path77.join(current, ".git");
127150
128303
  try {
127151
- const stat19 = fs71.statSync(gitPath);
127152
- if (stat19.isDirectory()) {
128304
+ const stat20 = fs71.statSync(gitPath);
128305
+ if (stat20.isDirectory()) {
127153
128306
  pathCacheSet(resolveGitDirCache, cacheKey, gitPath);
127154
128307
  return gitPath;
127155
128308
  }
127156
- if (stat19.isFile()) {
128309
+ if (stat20.isFile()) {
127157
128310
  const contents = fs71.readFileSync(gitPath, "utf8").trim();
127158
128311
  const match2 = contents.match(/^gitdir:\s*(.+)$/i);
127159
128312
  if (!match2) {
@@ -127748,13 +128901,13 @@ async function crawlWithGitLsFiles(stateKey, crawlDirectory, cwd, options2, work
127748
128901
  if (deletedSet.has(normalizedFile)) {
127749
128902
  return true;
127750
128903
  }
127751
- let stat19;
128904
+ let stat20;
127752
128905
  try {
127753
- stat19 = fs71.lstatSync(path77.join(gitRoot, ...normalizedFile.split("/")));
128906
+ stat20 = fs71.lstatSync(path77.join(gitRoot, ...normalizedFile.split("/")));
127754
128907
  } catch {
127755
128908
  return true;
127756
128909
  }
127757
- if (stat19.isDirectory()) {
128910
+ if (stat20.isDirectory()) {
127758
128911
  return true;
127759
128912
  }
127760
128913
  if (relativeToGitRoot && relativeToGitRoot !== "." && normalizedFile === relativeToGitRoot) {
@@ -133084,8 +134237,8 @@ function getWelcomeBackStatePath() {
133084
134237
  return path86.join(process.cwd(), ".qwen", WELCOME_BACK_STATE_FILENAME);
133085
134238
  }
133086
134239
  __name(getWelcomeBackStatePath, "getWelcomeBackStatePath");
133087
- function buildSummaryFingerprint(stat19) {
133088
- return `${stat19.mtimeMs}:${stat19.size}`;
134240
+ function buildSummaryFingerprint(stat20) {
134241
+ return `${stat20.mtimeMs}:${stat20.size}`;
133089
134242
  }
133090
134243
  __name(buildSummaryFingerprint, "buildSummaryFingerprint");
133091
134244
  async function getWelcomeBackState() {
@@ -138161,7 +139314,8 @@ __name(dedupeRequestsByCallId, "dedupeRequestsByCallId");
138161
139314
  var GATE_HEADROOM = 3e3;
138162
139315
  var GATE_EXEMPT_TOOLS = /* @__PURE__ */ new Set([
138163
139316
  ToolNames.READ_FILE,
138164
- ToolNames.READ_MCP_RESOURCE
139317
+ ToolNames.READ_MCP_RESOURCE,
139318
+ ToolNames.ENTER_PLAN_MODE
138165
139319
  ]);
138166
139320
  function extractTextFromPartListUnion(c3) {
138167
139321
  if (typeof c3 === "string") return c3;
@@ -139212,7 +140366,7 @@ var CoreToolScheduler = class {
139212
140366
  if (!unknownToolName.startsWith("mcp__")) {
139213
140367
  return null;
139214
140368
  }
139215
- const prefixOf = /* @__PURE__ */ __name((server) => `mcp__${server}__`.replace(/[^a-zA-Z0-9_.-]/g, "_"), "prefixOf");
140369
+ const prefixOf = /* @__PURE__ */ __name((server) => sanitizeToolNameForProvider(`mcp__${server}__`), "prefixOf");
139216
140370
  const byPrefixLengthDesc = /* @__PURE__ */ __name((a, b3) => prefixOf(b3).length - prefixOf(a).length, "byPrefixLengthDesc");
139217
140371
  const candidates = Array.from(
139218
140372
  /* @__PURE__ */ new Set([
@@ -139347,6 +140501,9 @@ var CoreToolScheduler = class {
139347
140501
  const requestsToProcess = dedupeRequestsByCallId(
139348
140502
  Array.isArray(request) ? request : [request]
139349
140503
  );
140504
+ const planModeEntryBoundaryIndex = findPlanModeEntryBatchBoundaryIndex(
140505
+ requestsToProcess.map((item) => canonicalToolName2(item.name))
140506
+ );
139350
140507
  if (this.validationRetryCounts.size > 0) {
139351
140508
  const currentToolNames = new Set(requestsToProcess.map((r2) => r2.name));
139352
140509
  for (const key of [...this.validationRetryCounts.keys()]) {
@@ -139358,7 +140515,20 @@ var CoreToolScheduler = class {
139358
140515
  }
139359
140516
  }
139360
140517
  const newToolCalls = [];
139361
- for (const reqInfo of requestsToProcess) {
140518
+ for (const [requestIndex, reqInfo] of requestsToProcess.entries()) {
140519
+ if (planModeEntryBoundaryIndex !== void 0 && requestIndex !== planModeEntryBoundaryIndex) {
140520
+ newToolCalls.push({
140521
+ status: "error",
140522
+ request: reqInfo,
140523
+ response: createErrorResponse(
140524
+ reqInfo,
140525
+ new Error(PLAN_MODE_ENTRY_SIBLING_SKIP_MESSAGE),
140526
+ "execution_denied" /* EXECUTION_DENIED */
140527
+ ),
140528
+ durationMs: 0
140529
+ });
140530
+ continue;
140531
+ }
139362
140532
  const canonicalName = canonicalToolName2(reqInfo.name);
139363
140533
  const pm = this.config.getPermissionManager?.();
139364
140534
  if (pm && !await pm.isToolEnabled(canonicalName)) {
@@ -139511,7 +140681,7 @@ var CoreToolScheduler = class {
139511
140681
  this.finalizeToolSpan(reqInfo.callId);
139512
140682
  continue;
139513
140683
  }
139514
- const toolParams = invocation.params;
140684
+ let toolParams = invocation.params;
139515
140685
  const flowResult = await evaluatePermissionFlow(
139516
140686
  this.config,
139517
140687
  invocation,
@@ -139528,6 +140698,7 @@ var CoreToolScheduler = class {
139528
140698
  } = flowResult;
139529
140699
  const approvalMode = this.config.getApprovalMode();
139530
140700
  const isPlanMode = approvalMode === "plan" /* PLAN */;
140701
+ const isPlanShellCall = isPlanMode && (canonicalName === ToolNames.SHELL || canonicalName === ToolNames.MONITOR);
139531
140702
  const isExitPlanModeTool = canonicalName === ToolNames.EXIT_PLAN_MODE;
139532
140703
  const isEnterPlanModeTool = canonicalName === ToolNames.ENTER_PLAN_MODE;
139533
140704
  const forceAutoReviewForAllow = approvalMode === "auto" /* AUTO */ && (shouldForceAutoModeReviewForAllow(pmCtx, this.config.getCwd()) || shouldClassifyAllShellForAutoMode(canonicalName, this.config));
@@ -139572,19 +140743,6 @@ var CoreToolScheduler = class {
139572
140743
  this.finalizeToolSpan(reqInfo.callId);
139573
140744
  continue;
139574
140745
  }
139575
- if (finalPermission === "allow" && !forceAutoReviewForAllow) {
139576
- if (approvalMode === "auto" /* AUTO */) {
139577
- this.config.setAutoModeDenialState(
139578
- recordAllow(this.config.getAutoModeDenialState())
139579
- );
139580
- }
139581
- this.setToolCallOutcome(
139582
- reqInfo.callId,
139583
- "proceed_always" /* ProceedAlways */
139584
- );
139585
- this.setStatusInternal(reqInfo.callId, "scheduled");
139586
- continue;
139587
- }
139588
140746
  if (finalPermission === "deny") {
139589
140747
  this.setStatusInternal(
139590
140748
  reqInfo.callId,
@@ -139603,6 +140761,72 @@ var CoreToolScheduler = class {
139603
140761
  this.finalizeToolSpan(reqInfo.callId);
139604
140762
  continue;
139605
140763
  }
140764
+ let planShellAmbientWorkingDirectory;
140765
+ if (isPlanShellCall) {
140766
+ const directory = toolParams["directory"];
140767
+ planShellAmbientWorkingDirectory = typeof directory === "string" && directory.length > 0 ? void 0 : this.config.getTargetDir();
140768
+ invocation.params = {
140769
+ ...structuredClone(invocation.params),
140770
+ directory: typeof directory === "string" && directory.length > 0 ? directory : planShellAmbientWorkingDirectory
140771
+ };
140772
+ toolParams = invocation.params;
140773
+ }
140774
+ const planShellDecision = isPlanShellCall ? await evaluatePlanModeShellPolicy({
140775
+ config: this.config,
140776
+ toolName: canonicalName,
140777
+ requestArgs: reqInfo.args,
140778
+ invocationParams: toolParams,
140779
+ permissionContext: pmCtx,
140780
+ ambientWorkingDirectory: planShellAmbientWorkingDirectory,
140781
+ signal
140782
+ }) : { classification: "not-applicable" };
140783
+ const rejectPlanShell = /* @__PURE__ */ __name((message) => {
140784
+ this.setStatusInternal(reqInfo.callId, "error", {
140785
+ ...createErrorResponse(
140786
+ reqInfo,
140787
+ new Error(message),
140788
+ "execution_denied" /* EXECUTION_DENIED */
140789
+ ),
140790
+ resultDisplay: message
140791
+ });
140792
+ setToolSpanFailure(
140793
+ toolSpan,
140794
+ TOOL_FAILURE_KIND_PLAN_MODE_BLOCKED,
140795
+ TOOL_SPAN_STATUS_PLAN_MODE_BLOCKED
140796
+ );
140797
+ this.finalizeToolSpan(reqInfo.callId);
140798
+ }, "rejectPlanShell");
140799
+ if (planShellDecision.classification !== "not-applicable") {
140800
+ const initialPlanShellError = await validatePlanModeShellContext({
140801
+ config: this.config,
140802
+ decision: planShellDecision,
140803
+ requestArgs: reqInfo.args,
140804
+ invocationParams: invocation.params,
140805
+ signal
140806
+ });
140807
+ if (initialPlanShellError) {
140808
+ rejectPlanShell(initialPlanShellError);
140809
+ continue;
140810
+ }
140811
+ }
140812
+ if (planShellDecision.classification === "write") {
140813
+ rejectPlanShell(planShellDecision.writeBlockMessage);
140814
+ continue;
140815
+ }
140816
+ const planShellRequiresConfirmation = planShellDecision.classification === "unknown";
140817
+ if (finalPermission === "allow" && !forceAutoReviewForAllow && !planShellRequiresConfirmation) {
140818
+ if (approvalMode === "auto" /* AUTO */) {
140819
+ this.config.setAutoModeDenialState(
140820
+ recordAllow(this.config.getAutoModeDenialState())
140821
+ );
140822
+ }
140823
+ this.setToolCallOutcome(
140824
+ reqInfo.callId,
140825
+ "proceed_always" /* ProceedAlways */
140826
+ );
140827
+ this.setStatusInternal(reqInfo.callId, "scheduled");
140828
+ continue;
140829
+ }
139606
140830
  if (!requiresUserInteraction && shouldRunAutoModeForCall(approvalMode, canonicalName)) {
139607
140831
  const denialState = this.config.getAutoModeDenialState();
139608
140832
  const fallback = shouldFallback(denialState);
@@ -139676,7 +140900,7 @@ var CoreToolScheduler = class {
139676
140900
  const isAskUserQuestionTool = canonicalName === ToolNames.ASK_USER_QUESTION;
139677
140901
  let confirmationDetails;
139678
140902
  if (!needsConfirmation(
139679
- confirmationPermission,
140903
+ planShellRequiresConfirmation ? "ask" : confirmationPermission,
139680
140904
  approvalMode,
139681
140905
  canonicalName,
139682
140906
  requiresUserInteraction
@@ -139688,8 +140912,33 @@ var CoreToolScheduler = class {
139688
140912
  this.setStatusInternal(reqInfo.callId, "scheduled");
139689
140913
  } else {
139690
140914
  confirmationDetails = await invocation.getConfirmationDetails(signal);
140915
+ if (planShellDecision.classification !== "not-applicable") {
140916
+ const preDisplayPlanShellError = await validatePlanModeShellContext({
140917
+ config: this.config,
140918
+ decision: planShellDecision,
140919
+ requestArgs: reqInfo.args,
140920
+ invocationParams: invocation.params,
140921
+ signal
140922
+ });
140923
+ if (preDisplayPlanShellError) {
140924
+ rejectPlanShell(preDisplayPlanShellError);
140925
+ continue;
140926
+ }
140927
+ }
140928
+ try {
140929
+ confirmationDetails = decoratePlanModeShellConfirmation(
140930
+ planShellDecision,
140931
+ confirmationDetails
140932
+ );
140933
+ } catch {
140934
+ if (planShellDecision.classification === "unknown") {
140935
+ rejectPlanShell(planShellDecision.noApprovalMessage);
140936
+ continue;
140937
+ }
140938
+ throw new Error("Unable to prepare shell confirmation.");
140939
+ }
139691
140940
  injectPermissionRulesIfMissing(confirmationDetails, pmCtx);
139692
- if (isPlanModeBlocked(
140941
+ if (planShellDecision.classification === "not-applicable" && isPlanModeBlocked(
139693
140942
  isPlanMode,
139694
140943
  isExitPlanModeTool,
139695
140944
  isAskUserQuestionTool,
@@ -139726,7 +140975,11 @@ var CoreToolScheduler = class {
139726
140975
  }
139727
140976
  const isNonInteractiveDeny = !this.config.isInteractive() && !this.config.getExperimentalZedIntegration() && this.config.getInputFormat() !== "stream-json" /* STREAM_JSON */;
139728
140977
  if (isNonInteractiveDeny) {
139729
- const errorMessage = `Qwen Code requires permission to use "${reqInfo.name}", but that permission was declined (non-interactive mode cannot prompt for confirmation).`;
140978
+ const errorMessage = planShellDecision.classification === "unknown" ? planShellDecision.noApprovalMessage : `Qwen Code requires permission to use "${reqInfo.name}", but that permission was declined (non-interactive mode cannot prompt for confirmation).`;
140979
+ if (planShellDecision.classification === "unknown") {
140980
+ rejectPlanShell(errorMessage);
140981
+ continue;
140982
+ }
139730
140983
  this.setStatusInternal(
139731
140984
  reqInfo.callId,
139732
140985
  "error",
@@ -139752,10 +141005,44 @@ var CoreToolScheduler = class {
139752
141005
  messageBus,
139753
141006
  canonicalName,
139754
141007
  reqInfo.args || {},
139755
- permissionMode
141008
+ permissionMode,
141009
+ void 0,
141010
+ signal
139756
141011
  );
139757
141012
  if (hookResult.hasDecision && (!hookResult.shouldAllow || !requiresUserInteraction)) {
139758
141013
  if (hookResult.shouldAllow) {
141014
+ if (planShellDecision.classification !== "not-applicable") {
141015
+ const approval = await validatePlanModeShellApproval({
141016
+ config: this.config,
141017
+ decision: planShellDecision,
141018
+ requestArgs: reqInfo.args,
141019
+ invocationParams: invocation.params,
141020
+ signal,
141021
+ outcome: "proceed_once" /* ProceedOnce */,
141022
+ payload: hookResult.updatedInput ? { updatedInput: hookResult.updatedInput } : void 0
141023
+ });
141024
+ if (approval.outcome === "cancel" /* Cancel */) {
141025
+ await confirmationDetails.onConfirm(
141026
+ approval.outcome,
141027
+ approval.payload
141028
+ );
141029
+ rejectPlanShell(
141030
+ approval.payload?.cancelMessage ?? planShellDecision.noApprovalMessage
141031
+ );
141032
+ continue;
141033
+ }
141034
+ await confirmationDetails.onConfirm(
141035
+ approval.outcome,
141036
+ approval.payload
141037
+ );
141038
+ this.recordAutoModeFallbackResolution(
141039
+ reqInfo.callId,
141040
+ approval.outcome
141041
+ );
141042
+ this.setToolCallOutcome(reqInfo.callId, approval.outcome);
141043
+ this.setStatusInternal(reqInfo.callId, "scheduled");
141044
+ continue;
141045
+ }
139759
141046
  if (hookResult.updatedInput && typeof reqInfo.args === "object") {
139760
141047
  this.setArgsInternal(
139761
141048
  reqInfo.callId,
@@ -139810,7 +141097,11 @@ var CoreToolScheduler = class {
139810
141097
  }
139811
141098
  }
139812
141099
  if (this.config.getShouldAvoidPermissionPrompts?.()) {
139813
- const errorMessage = `Tool "${reqInfo.name}" requires permission, but background agents cannot prompt for confirmation. The tool call was denied.`;
141100
+ const errorMessage = planShellDecision.classification === "unknown" ? planShellDecision.noApprovalMessage : `Tool "${reqInfo.name}" requires permission, but background agents cannot prompt for confirmation. The tool call was denied.`;
141101
+ if (planShellDecision.classification === "unknown") {
141102
+ rejectPlanShell(errorMessage);
141103
+ continue;
141104
+ }
139814
141105
  this.setStatusInternal(
139815
141106
  reqInfo.callId,
139816
141107
  "error",
@@ -139838,25 +141129,68 @@ var CoreToolScheduler = class {
139838
141129
  this.finalizeToolSpan(reqInfo.callId);
139839
141130
  continue;
139840
141131
  }
139841
- this.openIdeDiffIfEnabled(
139842
- confirmationDetails,
139843
- reqInfo.callId,
139844
- signal
139845
- );
141132
+ if (planShellDecision.classification !== "not-applicable") {
141133
+ const finalPreDisplayPlanShellError = await validatePlanModeShellContext({
141134
+ config: this.config,
141135
+ decision: planShellDecision,
141136
+ requestArgs: reqInfo.args,
141137
+ invocationParams: invocation.params,
141138
+ signal
141139
+ });
141140
+ if (finalPreDisplayPlanShellError) {
141141
+ rejectPlanShell(finalPreDisplayPlanShellError);
141142
+ continue;
141143
+ }
141144
+ }
141145
+ if (confirmationDetails.type !== "edit" || !confirmationDetails.skipIdeDiff) {
141146
+ this.openIdeDiffIfEnabled(
141147
+ confirmationDetails,
141148
+ reqInfo.callId,
141149
+ signal
141150
+ );
141151
+ }
139846
141152
  const originalOnConfirm = confirmationDetails.onConfirm;
141153
+ let planShellResponseClaimed = false;
139847
141154
  const wrappedConfirmationDetails = {
139848
141155
  ...confirmationDetails,
139849
141156
  // When PM has an explicit 'ask' rule, 'always allow' would be
139850
141157
  // ineffective because ask takes priority over allow.
139851
141158
  // Hide the option so users aren't misled.
139852
141159
  ...pmForcedAsk || requiresUserInteraction ? { hideAlwaysAllow: true } : {},
139853
- onConfirm: /* @__PURE__ */ __name((outcome, payload) => this.handleConfirmationResponse(
139854
- reqInfo.callId,
139855
- originalOnConfirm,
139856
- outcome,
139857
- signal,
139858
- payload
139859
- ), "onConfirm")
141160
+ onConfirm: /* @__PURE__ */ __name(async (outcome, payload) => {
141161
+ if (planShellDecision.classification !== "not-applicable") {
141162
+ if (planShellResponseClaimed) return;
141163
+ planShellResponseClaimed = true;
141164
+ const currentCall = this.toolCalls.find(
141165
+ (call) => call.request.callId === reqInfo.callId && call.status === "awaiting_approval"
141166
+ );
141167
+ if (!currentCall) return;
141168
+ const approval = await validatePlanModeShellApproval({
141169
+ config: this.config,
141170
+ decision: planShellDecision,
141171
+ requestArgs: currentCall.request.args,
141172
+ invocationParams: currentCall.invocation.params,
141173
+ signal,
141174
+ outcome,
141175
+ payload
141176
+ });
141177
+ await this.handleConfirmationResponse(
141178
+ reqInfo.callId,
141179
+ originalOnConfirm,
141180
+ approval.outcome,
141181
+ signal,
141182
+ approval.payload
141183
+ );
141184
+ return;
141185
+ }
141186
+ await this.handleConfirmationResponse(
141187
+ reqInfo.callId,
141188
+ originalOnConfirm,
141189
+ outcome,
141190
+ signal,
141191
+ payload
141192
+ );
141193
+ }, "onConfirm")
139860
141194
  };
139861
141195
  this.setStatusInternal(
139862
141196
  reqInfo.callId,
@@ -141151,7 +142485,7 @@ ${failureHookResult.additionalContext}`;
141151
142485
  }
141152
142486
  }
141153
142487
  async maybePersistLargeToolResult(callId, toolName, content) {
141154
- if (GATE_EXEMPT_TOOLS.has(toolName)) return content;
142488
+ if (GATE_EXEMPT_TOOLS.has(canonicalToolName2(toolName))) return content;
141155
142489
  const text = extractTextFromPartListUnion(content);
141156
142490
  if (!text || isAlreadyTruncated(text)) return content;
141157
142491
  const gateThreshold = this.config.getTruncateToolOutputThreshold() + GATE_HEADROOM;
@@ -141238,6 +142572,9 @@ ${failureHookResult.additionalContext}`;
141238
142572
  * media-bearing, non-text, or already-persisted results.
141239
142573
  */
141240
142574
  async offloadCallOutput(call) {
142575
+ if (canonicalToolName2(call.request.name) === ToolNames.ENTER_PLAN_MODE) {
142576
+ return null;
142577
+ }
141241
142578
  const parts = call.response.responseParts;
141242
142579
  if (parts.length !== 1) return null;
141243
142580
  const fr2 = parts[0]?.functionResponse;
@@ -141297,7 +142634,7 @@ ${failureHookResult.additionalContext}`;
141297
142634
  }
141298
142635
  async autoApproveCompatiblePendingTools(signal, triggeringCallId) {
141299
142636
  const pendingTools = this.toolCalls.filter(
141300
- (call) => call.status === "awaiting_approval" && call.request.callId !== triggeringCallId && // A tool bounced by a PreToolUse 'ask' must NOT be auto-approved as a
142637
+ (call) => call.status === "awaiting_approval" && call.request.callId !== triggeringCallId && (!("hideAlwaysAllow" in call.confirmationDetails) || call.confirmationDetails.hideAlwaysAllow !== true) && // A tool bounced by a PreToolUse 'ask' must NOT be auto-approved as a
141301
142638
  // side effect of approving a sibling: the hook explicitly requested
141302
142639
  // confirmation, and re-execution skips the hook — auto-approving here
141303
142640
  // would silently defeat the hook's gate. It requires its own explicit
@@ -149580,7 +150917,7 @@ The current date is: ${today}. Note: This is the authoritative current date \u20
149580
150917
  if (isTopLevelInteraction) endInteractionSpan("cancelled");
149581
150918
  return turn;
149582
150919
  }
149583
- const continueReason = stopOutput.getEffectiveReason();
150920
+ const continueReason = getStopHookContinuationReason(stopOutput);
149584
150921
  const currentIterationCount = (options2?.stopHookState?.iterationCount ?? 0) + 1;
149585
150922
  const currentReasons = [
149586
150923
  ...options2?.stopHookState?.reasons ?? [],
@@ -149630,9 +150967,30 @@ The current date is: ${today}. Note: This is the authoritative current date \u20
149630
150967
  const activeGoal = getActiveGoal(this.config.getSessionId());
149631
150968
  const hookTurnBudget = activeGoal ? boundedTurns : boundedTurns - 1;
149632
150969
  const pendingSteer = await takeSteerInput(hookTurnBudget);
149633
- const continueRequest = [{ text: continueReason }];
150970
+ const activeGoalAfterSteer = getActiveGoal(
150971
+ this.config.getSessionId()
150972
+ );
150973
+ const activeGoalChanged = activeGoal !== void 0 && activeGoalAfterSteer?.hookId !== activeGoal.hookId;
150974
+ const goalContinuationChanged = activeGoalChanged && stopOutput.hookSpecificOutput?.[GOAL_HOOK_ID_OUTPUT_KEY] === activeGoal.hookId;
150975
+ if (activeGoalChanged) {
150976
+ const activeGoalEvent3 = maybeEmitActiveGoalChange(activeGoalAfterSteer);
150977
+ if (activeGoalEvent3) {
150978
+ yield activeGoalEvent3;
150979
+ }
150980
+ }
150981
+ const discardGoalContinuation = goalContinuationChanged && response.hasNonGoalBlockingStopHook === false;
150982
+ const continuationReasonAfterSteer = discardGoalContinuation ? void 0 : goalContinuationChanged && response.hasNonGoalBlockingStopHook === true ? response.nonGoalBlockingStopReason || "No reason provided" : continueReason;
150983
+ if (!continuationReasonAfterSteer && !pendingSteer) {
150984
+ if (isTopLevelInteraction) endInteractionSpan("ok");
150985
+ normalCompletion = true;
150986
+ return turn;
150987
+ }
150988
+ const continueRequest = continuationReasonAfterSteer ? [{ text: continuationReasonAfterSteer }] : [];
149634
150989
  if (pendingSteer) {
149635
- continueRequest.push({ text: "\n\n" }, ...pendingSteer.parts);
150990
+ if (continueRequest.length > 0) {
150991
+ continueRequest.push({ text: "\n\n" });
150992
+ }
150993
+ continueRequest.push(...pendingSteer.parts);
149636
150994
  }
149637
150995
  const pushCountBefore = currentPushCount();
149638
150996
  let hookTurn;
@@ -149645,9 +151003,12 @@ The current date is: ${today}. Note: This is the authoritative current date \u20
149645
151003
  type: "hook" /* Hook */,
149646
151004
  modelOverride: options2?.modelOverride,
149647
151005
  getSteerInput: options2?.getSteerInput,
149648
- stopHookState: {
151006
+ stopHookState: discardGoalContinuation ? void 0 : {
149649
151007
  iterationCount: currentIterationCount,
149650
- reasons: currentReasons
151008
+ reasons: continuationReasonAfterSteer && continuationReasonAfterSteer !== continueReason ? [
151009
+ ...currentReasons.slice(0, -1),
151010
+ continuationReasonAfterSteer
151011
+ ] : currentReasons
149651
151012
  }
149652
151013
  },
149653
151014
  hookTurnBudget
@@ -152051,6 +153412,8 @@ var Config = class {
152051
153412
  }
152052
153413
  let result;
152053
153414
  let stopHookCount;
153415
+ let hasNonGoalBlockingStopHook;
153416
+ let nonGoalBlockingStopReason;
152054
153417
  const input = request.input || {};
152055
153418
  const signal = request.signal;
152056
153419
  switch (request.eventName) {
@@ -152081,6 +153444,18 @@ var Config = class {
152081
153444
  );
152082
153445
  result = stopResult.finalOutput ? createHookOutput("Stop", stopResult.finalOutput) : void 0;
152083
153446
  stopHookCount = stopResult.allOutputs.length;
153447
+ const goalHookId = stopResult.finalOutput?.hookSpecificOutput?.[GOAL_HOOK_ID_OUTPUT_KEY];
153448
+ if (typeof goalHookId === "string") {
153449
+ const nonGoalBlockingOutputs = stopResult.allOutputs.filter(
153450
+ (output) => output.hookSpecificOutput?.[GOAL_HOOK_ID_OUTPUT_KEY] !== goalHookId && (output.decision === "block" || output.decision === "deny" || output.continue === false)
153451
+ );
153452
+ hasNonGoalBlockingStopHook = nonGoalBlockingOutputs.length > 0;
153453
+ if (hasNonGoalBlockingStopHook) {
153454
+ nonGoalBlockingStopReason = nonGoalBlockingOutputs.map(
153455
+ (output) => output.stopReason || output.reason || "No reason provided"
153456
+ ).join("\n");
153457
+ }
153458
+ }
152084
153459
  break;
152085
153460
  }
152086
153461
  case "MessageDisplay": {
@@ -152195,7 +153570,9 @@ var Config = class {
152195
153570
  success: true,
152196
153571
  output: result,
152197
153572
  // Include stop hook count for Stop events
152198
- stopHookCount
153573
+ stopHookCount,
153574
+ hasNonGoalBlockingStopHook,
153575
+ nonGoalBlockingStopReason
152199
153576
  });
152200
153577
  } catch (error) {
152201
153578
  this.debugLogger.warn(`Hook execution failed: ${error}`);
@@ -155211,25 +156588,25 @@ var Config = class {
155211
156588
  if (options2?.forSubAgent) return;
155212
156589
  const schema = this.jsonSchema;
155213
156590
  await registerLazy(ToolNames.STRUCTURED_OUTPUT, async () => {
155214
- const { SyntheticOutputTool } = await import("./syntheticOutput-ULOVVLY4.js");
156591
+ const { SyntheticOutputTool } = await import("./syntheticOutput-FG5PQKIR.js");
155215
156592
  return new SyntheticOutputTool(schema);
155216
156593
  });
155217
156594
  }, "registerStructuredOutputIfRequested");
155218
156595
  if (this.getBareMode()) {
155219
156596
  await registerLazy(ToolNames.READ_FILE, async () => {
155220
- const { ReadFileTool } = await import("./read-file-VSKOE22I.js");
156597
+ const { ReadFileTool } = await import("./read-file-LCQ2KNNP.js");
155221
156598
  return new ReadFileTool(this);
155222
156599
  });
155223
156600
  await registerLazy(ToolNames.EDIT, async () => {
155224
- const { EditTool } = await import("./edit-GORZTX2U.js");
156601
+ const { EditTool } = await import("./edit-BTPQWGAA.js");
155225
156602
  return new EditTool(this);
155226
156603
  });
155227
156604
  await registerLazy(ToolNames.NOTEBOOK_EDIT, async () => {
155228
- const { NotebookEditTool } = await import("./notebook-edit-IBEOVZ6A.js");
156605
+ const { NotebookEditTool } = await import("./notebook-edit-GFOYAQAZ.js");
155229
156606
  return new NotebookEditTool(this);
155230
156607
  });
155231
156608
  await registerLazy(ToolNames.SHELL, async () => {
155232
- const { ShellTool: ShellTool2 } = await import("./shell-2NGEMAVM.js");
156609
+ const { ShellTool: ShellTool2 } = await import("./shell-EON6WVVH.js");
155233
156610
  return new ShellTool2(this);
155234
156611
  });
155235
156612
  await registerStructuredOutputIfRequested();
@@ -155239,35 +156616,35 @@ var Config = class {
155239
156616
  return registry;
155240
156617
  }
155241
156618
  await registerLazy(ToolNames.TOOL_SEARCH, async () => {
155242
- const { ToolSearchTool } = await import("./tool-search-5IE2VO7X.js");
156619
+ const { ToolSearchTool } = await import("./tool-search-Q27QHQU3.js");
155243
156620
  return new ToolSearchTool(this);
155244
156621
  });
155245
156622
  await registerLazy(ToolNames.READ_MCP_RESOURCE, async () => {
155246
- const { ReadMcpResourceTool } = await import("./read-mcp-resource-C6NT52T6.js");
156623
+ const { ReadMcpResourceTool } = await import("./read-mcp-resource-AKCL7I43.js");
155247
156624
  return new ReadMcpResourceTool(this);
155248
156625
  });
155249
156626
  await registerLazy(ToolNames.AGENT, async () => {
155250
- const { AgentTool: AgentTool2 } = await import("./agent-CKSI7BTR.js");
156627
+ const { AgentTool: AgentTool2 } = await import("./agent-KTOOFWMV.js");
155251
156628
  return new AgentTool2(this);
155252
156629
  });
155253
156630
  await registerLazy(ToolNames.TASK_STOP, async () => {
155254
- const { TaskStopTool } = await import("./task-stop-CPEQWOT6.js");
156631
+ const { TaskStopTool } = await import("./task-stop-GWC6UWAL.js");
155255
156632
  return new TaskStopTool(this);
155256
156633
  });
155257
156634
  await registerLazy(ToolNames.SEND_MESSAGE, async () => {
155258
- const { SendMessageTool } = await import("./send-message-5GZ4FX2V.js");
156635
+ const { SendMessageTool } = await import("./send-message-3RHE7HSM.js");
155259
156636
  return new SendMessageTool(this);
155260
156637
  });
155261
156638
  await registerLazy(ToolNames.SKILL, async () => {
155262
- const { SkillTool } = await import("./skill-3U2T6H3E.js");
156639
+ const { SkillTool } = await import("./skill-FKSYXJ5U.js");
155263
156640
  return new SkillTool(this);
155264
156641
  });
155265
156642
  await registerLazy(ToolNames.LS, async () => {
155266
- const { LSTool } = await import("./ls-APTSOOS5.js");
156643
+ const { LSTool } = await import("./ls-FHBY3Y7I.js");
155267
156644
  return new LSTool(this);
155268
156645
  });
155269
156646
  await registerLazy(ToolNames.READ_FILE, async () => {
155270
- const { ReadFileTool } = await import("./read-file-VSKOE22I.js");
156647
+ const { ReadFileTool } = await import("./read-file-LCQ2KNNP.js");
155271
156648
  return new ReadFileTool(this);
155272
156649
  });
155273
156650
  if (this.getUseRipgrep()) {
@@ -155282,7 +156659,7 @@ var Config = class {
155282
156659
  recordStartupEvent("config_initialize_ripgrep_probe_end");
155283
156660
  if (useRipgrep) {
155284
156661
  await registerLazy(ToolNames.GREP, async () => {
155285
- const { RipGrepTool: RipGrepTool2 } = await import("./ripGrep-5V5FLW2A.js");
156662
+ const { RipGrepTool: RipGrepTool2 } = await import("./ripGrep-Y2XW4EFC.js");
155286
156663
  return new RipGrepTool2(this);
155287
156664
  });
155288
156665
  } else {
@@ -155295,7 +156672,7 @@ var Config = class {
155295
156672
  )
155296
156673
  );
155297
156674
  await registerLazy(ToolNames.GREP, async () => {
155298
- const { GrepTool } = await import("./grep-HZLSTX7D.js");
156675
+ const { GrepTool } = await import("./grep-U67FKUJT.js");
155299
156676
  return new GrepTool(this);
155300
156677
  });
155301
156678
  }
@@ -155303,139 +156680,139 @@ var Config = class {
155303
156680
  recordStartupEvent("config_initialize_ripgrep_probe_start");
155304
156681
  recordStartupEvent("config_initialize_ripgrep_probe_end");
155305
156682
  await registerLazy(ToolNames.GREP, async () => {
155306
- const { GrepTool } = await import("./grep-HZLSTX7D.js");
156683
+ const { GrepTool } = await import("./grep-U67FKUJT.js");
155307
156684
  return new GrepTool(this);
155308
156685
  });
155309
156686
  }
155310
156687
  await registerLazy(ToolNames.GLOB, async () => {
155311
- const { GlobTool } = await import("./glob-GOAPGD6G.js");
156688
+ const { GlobTool } = await import("./glob-5YABOPJB.js");
155312
156689
  return new GlobTool(this);
155313
156690
  });
155314
156691
  await registerLazy(ToolNames.EDIT, async () => {
155315
- const { EditTool } = await import("./edit-GORZTX2U.js");
156692
+ const { EditTool } = await import("./edit-BTPQWGAA.js");
155316
156693
  return new EditTool(this);
155317
156694
  });
155318
156695
  await registerLazy(ToolNames.NOTEBOOK_EDIT, async () => {
155319
- const { NotebookEditTool } = await import("./notebook-edit-IBEOVZ6A.js");
156696
+ const { NotebookEditTool } = await import("./notebook-edit-GFOYAQAZ.js");
155320
156697
  return new NotebookEditTool(this);
155321
156698
  });
155322
156699
  await registerLazy(ToolNames.WRITE_FILE, async () => {
155323
- const { WriteFileTool } = await import("./write-file-DR3HN7IH.js");
156700
+ const { WriteFileTool } = await import("./write-file-EAT3CHUK.js");
155324
156701
  return new WriteFileTool(this);
155325
156702
  });
155326
156703
  await registerLazy(ToolNames.SHELL, async () => {
155327
- const { ShellTool: ShellTool2 } = await import("./shell-2NGEMAVM.js");
156704
+ const { ShellTool: ShellTool2 } = await import("./shell-EON6WVVH.js");
155328
156705
  return new ShellTool2(this);
155329
156706
  });
155330
156707
  await registerLazy(ToolNames.TODO_WRITE, async () => {
155331
- const { TodoWriteTool } = await import("./todoWrite-JHHIDOIV.js");
156708
+ const { TodoWriteTool } = await import("./todoWrite-ERCAMLFS.js");
155332
156709
  return new TodoWriteTool(this);
155333
156710
  });
155334
156711
  await registerLazy(ToolNames.ASK_USER_QUESTION, async () => {
155335
- const { AskUserQuestionTool } = await import("./askUserQuestion-CEPBT47X.js");
156712
+ const { AskUserQuestionTool } = await import("./askUserQuestion-6DZC4UV5.js");
155336
156713
  return new AskUserQuestionTool(this);
155337
156714
  });
155338
156715
  if (!this.sdkMode) {
155339
156716
  await registerLazy(ToolNames.EXIT_PLAN_MODE, async () => {
155340
- const { ExitPlanModeTool } = await import("./exitPlanMode-U5Z6XBLO.js");
156717
+ const { ExitPlanModeTool } = await import("./exitPlanMode-NZWRVIIY.js");
155341
156718
  return new ExitPlanModeTool(this);
155342
156719
  });
155343
156720
  await registerLazy(ToolNames.ENTER_PLAN_MODE, async () => {
155344
- const { EnterPlanModeTool } = await import("./enterPlanMode-LIIPP37T.js");
156721
+ const { EnterPlanModeTool } = await import("./enterPlanMode-TN2JV5MY.js");
155345
156722
  return new EnterPlanModeTool(this);
155346
156723
  });
155347
156724
  }
155348
156725
  await registerLazy(ToolNames.ENTER_WORKTREE, async () => {
155349
- const { EnterWorktreeTool } = await import("./enter-worktree-LJB2AW4L.js");
156726
+ const { EnterWorktreeTool } = await import("./enter-worktree-N3SEYKOO.js");
155350
156727
  return new EnterWorktreeTool(this);
155351
156728
  });
155352
156729
  await registerLazy(ToolNames.EXIT_WORKTREE, async () => {
155353
- const { ExitWorktreeTool } = await import("./exit-worktree-IEP2WHOV.js");
156730
+ const { ExitWorktreeTool } = await import("./exit-worktree-FI3SQY3U.js");
155354
156731
  return new ExitWorktreeTool(this);
155355
156732
  });
155356
156733
  await registerLazy(ToolNames.WEB_FETCH, async () => {
155357
- const { WebFetchTool } = await import("./web-fetch-ZDNE6FF2.js");
156734
+ const { WebFetchTool } = await import("./web-fetch-L62NQVKN.js");
155358
156735
  return new WebFetchTool(this);
155359
156736
  });
155360
156737
  if (this.isArtifactEnabled()) {
155361
156738
  await registerLazy(ToolNames.ARTIFACT, async () => {
155362
- const { ArtifactTool } = await import("./artifact-tool-PHO5XEGZ.js");
156739
+ const { ArtifactTool } = await import("./artifact-tool-WBCAMD3O.js");
155363
156740
  return new ArtifactTool(this);
155364
156741
  });
155365
156742
  }
155366
156743
  if (this.isRecordArtifactEnabled()) {
155367
156744
  await registerLazy(ToolNames.RECORD_ARTIFACT, async () => {
155368
- const { RecordArtifactTool } = await import("./record-artifact-ENCU7QCL.js");
156745
+ const { RecordArtifactTool } = await import("./record-artifact-PEUB7727.js");
155369
156746
  return new RecordArtifactTool();
155370
156747
  });
155371
156748
  }
155372
156749
  if (this.isLspEnabled() && this.getLspClient()) {
155373
156750
  await registerLazy(ToolNames.LSP, async () => {
155374
- const { LspTool } = await import("./lsp-HPACPJAN.js");
156751
+ const { LspTool } = await import("./lsp-B6VMEW6Y.js");
155375
156752
  return new LspTool(this);
155376
156753
  });
155377
156754
  }
155378
156755
  await registerStructuredOutputIfRequested();
155379
156756
  if (this.isCronEnabled()) {
155380
156757
  await registerLazy(ToolNames.CRON_CREATE, async () => {
155381
- const { CronCreateTool } = await import("./cron-create-X462ERYA.js");
156758
+ const { CronCreateTool } = await import("./cron-create-JWFHBDRQ.js");
155382
156759
  return new CronCreateTool(this);
155383
156760
  });
155384
156761
  await registerLazy(ToolNames.CRON_LIST, async () => {
155385
- const { CronListTool } = await import("./cron-list-3MD6SVXI.js");
156762
+ const { CronListTool } = await import("./cron-list-USMAIWPT.js");
155386
156763
  return new CronListTool(this);
155387
156764
  });
155388
156765
  await registerLazy(ToolNames.CRON_DELETE, async () => {
155389
- const { CronDeleteTool } = await import("./cron-delete-SL5UJUM3.js");
156766
+ const { CronDeleteTool } = await import("./cron-delete-GDX4E26G.js");
155390
156767
  return new CronDeleteTool(this);
155391
156768
  });
155392
156769
  await registerLazy(ToolNames.LOOP_WAKEUP, async () => {
155393
- const { LoopWakeupTool } = await import("./loop-wakeup-6H7OENTB.js");
156770
+ const { LoopWakeupTool } = await import("./loop-wakeup-5GLTUBHA.js");
155394
156771
  return new LoopWakeupTool(this);
155395
156772
  });
155396
156773
  }
155397
156774
  await registerLazy(ToolNames.CREATE_SUB_SESSION, async () => {
155398
- const { CreateSubSessionTool } = await import("./create-sub-session-DIJOV6HV.js");
156775
+ const { CreateSubSessionTool } = await import("./create-sub-session-P26FE5GG.js");
155399
156776
  return new CreateSubSessionTool(this);
155400
156777
  });
155401
156778
  if (this.isAgentTeamEnabled()) {
155402
156779
  await registerLazy(ToolNames.TEAM_CREATE, async () => {
155403
- const { TeamCreateTool } = await import("./team-create-R6AXDYPG.js");
156780
+ const { TeamCreateTool } = await import("./team-create-CYP3YKYT.js");
155404
156781
  return new TeamCreateTool(this);
155405
156782
  });
155406
156783
  await registerLazy(ToolNames.TEAM_DELETE, async () => {
155407
- const { TeamDeleteTool } = await import("./team-delete-JJV6IUOA.js");
156784
+ const { TeamDeleteTool } = await import("./team-delete-KK37HTOG.js");
155408
156785
  return new TeamDeleteTool(this);
155409
156786
  });
155410
156787
  await registerLazy(ToolNames.TEAM_PLAN_APPROVAL, async () => {
155411
- const { TeamPlanApprovalTool } = await import("./team-plan-approval-O2ZPPT64.js");
156788
+ const { TeamPlanApprovalTool } = await import("./team-plan-approval-5LXIFKNV.js");
155412
156789
  return new TeamPlanApprovalTool(this);
155413
156790
  });
155414
156791
  await registerLazy(ToolNames.TASK_CREATE, async () => {
155415
- const { TaskCreateTool } = await import("./task-create-DUE2PMNI.js");
156792
+ const { TaskCreateTool } = await import("./task-create-HX32YXO7.js");
155416
156793
  return new TaskCreateTool(this);
155417
156794
  });
155418
156795
  await registerLazy(ToolNames.TASK_UPDATE, async () => {
155419
- const { TaskUpdateTool } = await import("./task-update-HY2LNFFB.js");
156796
+ const { TaskUpdateTool } = await import("./task-update-NCTAB73Q.js");
155420
156797
  return new TaskUpdateTool(this);
155421
156798
  });
155422
156799
  await registerLazy(ToolNames.TASK_LIST, async () => {
155423
- const { TaskListTool } = await import("./task-list-WVPNX7BZ.js");
156800
+ const { TaskListTool } = await import("./task-list-QWSY4ZIU.js");
155424
156801
  return new TaskListTool(this);
155425
156802
  });
155426
156803
  }
155427
156804
  if (this.isWorkflowsEnabled()) {
155428
156805
  await registerLazy(ToolNames.WORKFLOW, async () => {
155429
- const { WorkflowTool } = await import("./workflow-G7U6OQWS.js");
156806
+ const { WorkflowTool } = await import("./workflow-6MHBBFQU.js");
155430
156807
  return new WorkflowTool(this);
155431
156808
  });
155432
156809
  }
155433
156810
  if (this.isComputerUseEnabled()) {
155434
- const { registerComputerUseTools } = await import("./computer-use-4PUGCUQK.js");
156811
+ const { registerComputerUseTools } = await import("./computer-use-M6MGRJF2.js");
155435
156812
  await registerComputerUseTools(registerLazy, this);
155436
156813
  }
155437
156814
  await registerLazy(ToolNames.MONITOR, async () => {
155438
- const { MonitorTool } = await import("./monitor-LMYKCF6R.js");
156815
+ const { MonitorTool } = await import("./monitor-Z7NZNNRC.js");
155439
156816
  return new MonitorTool(this);
155440
156817
  });
155441
156818
  if (this.pendingMcpBudgetCallback) {
@@ -159075,6 +160452,7 @@ export {
159075
160452
  MAX_GOAL_ITERATIONS,
159076
160453
  GOAL_HOOK_TIMEOUT_SECONDS,
159077
160454
  GOAL_HOOK_TIMEOUT_MS,
160455
+ getStopHookContinuationReason,
159078
160456
  abortGoalForStopHookCap,
159079
160457
  createGoalStopHookCallback,
159080
160458
  unregisterGoalHook,
@@ -159125,7 +160503,14 @@ export {
159125
160503
  TERMINAL_CSI_REGEX,
159126
160504
  TERMINAL_SHIFT_DCS_REGEX,
159127
160505
  stripTerminalControlSequences,
159128
- buildOrderedUuidChain,
160506
+ TranscriptRecordPreparationError,
160507
+ isTranscriptConversationRecord,
160508
+ isTranscriptArtifactRecord,
160509
+ validateTranscriptRecord,
160510
+ selectTranscriptLeaf,
160511
+ walkTranscriptUuidChain,
160512
+ aggregateTranscriptRecordFragments,
160513
+ prepareTranscriptRecords,
159129
160514
  MAX_FILES,
159130
160515
  MAX_DIFF_SIZE_BYTES,
159131
160516
  MAX_LINES_PER_FILE,
@@ -159142,6 +160527,10 @@ export {
159142
160527
  getGitWorkingTreeStatus,
159143
160528
  parseStatusBranchLine,
159144
160529
  parseStatusEntries,
160530
+ MAX_LOG_LIMIT,
160531
+ DEFAULT_LOG_LIMIT,
160532
+ fetchGitLog,
160533
+ fetchGitCommitDetail,
159145
160534
  MAX_SNAPSHOTS,
159146
160535
  FILE_HISTORY_DIR,
159147
160536
  serializeSnapshot,
@@ -159311,6 +160700,14 @@ export {
159311
160700
  getEffectivePermissionForConfirmation,
159312
160701
  isPlanModeBlocked,
159313
160702
  isAutoEditApproved,
160703
+ isShellCommandReadOnlyAST,
160704
+ extractCommandRules,
160705
+ evaluatePlanModeShellPolicy,
160706
+ validatePlanModeShellContext,
160707
+ decoratePlanModeShellConfirmation,
160708
+ validatePlanModeShellApproval,
160709
+ PLAN_MODE_ENTRY_SIBLING_SKIP_MESSAGE,
160710
+ findPlanModeEntryBatchBoundaryIndex,
159314
160711
  MAX_TRANSCRIPT_MESSAGES,
159315
160712
  extractShellOperations,
159316
160713
  AUTO_MODE_DENIAL_LIMITS,
@@ -159374,8 +160771,6 @@ export {
159374
160771
  ShellExecutionService,
159375
160772
  StructuredToolError,
159376
160773
  checkPriorRead,
159377
- isShellCommandReadOnlyAST,
159378
- extractCommandRules,
159379
160774
  escape,
159380
160775
  globStream,
159381
160776
  glob,
@@ -159480,6 +160875,7 @@ export {
159480
160875
  MAX_RETAINED_TERMINAL_AGENTS,
159481
160876
  buildBackgroundEntryLabel,
159482
160877
  BackgroundTaskRegistry,
160878
+ buildOrderedUuidChain,
159483
160879
  DEFAULT_BACKGROUND_AGENT_CONTINUATION_MESSAGE,
159484
160880
  BackgroundAgentResumeService,
159485
160881
  saveCacheSafeParams,
@@ -159775,6 +161171,7 @@ export {
159775
161171
  applyProviderInstallPlan,
159776
161172
  IMAGE_CAPABILITY,
159777
161173
  generateSessionRecap,
161174
+ inspectConversationBranches,
159778
161175
  createToolUseSummaryMessage,
159779
161176
  TOOL_USE_SUMMARY_SYSTEM_PROMPT,
159780
161177
  generateToolUseSummary,
@@ -159805,6 +161202,7 @@ export {
159805
161202
  getChannelMemoryFilePath,
159806
161203
  getLegacyChannelMemoryFilePath,
159807
161204
  listChannelMemoryEntries,
161205
+ getChannelMemoryRevision,
159808
161206
  addChannelMemoryEntries,
159809
161207
  updateChannelMemoryEntry,
159810
161208
  removeChannelMemoryEntries,
@@ -160110,16 +161508,16 @@ export {
160110
161508
  */
160111
161509
  /**
160112
161510
  * @license
160113
- * Copyright 2026 Qwen Team
161511
+ * Copyright 2026 Qwen
160114
161512
  * SPDX-License-Identifier: Apache-2.0
160115
- *
160116
- * Provider registry — imports all provider definitions and assembles the
160117
- * lookup tables used by the UI and CLI commands.
160118
161513
  */
160119
161514
  /**
160120
161515
  * @license
160121
- * Copyright 2026 Qwen
161516
+ * Copyright 2026 Qwen Team
160122
161517
  * SPDX-License-Identifier: Apache-2.0
161518
+ *
161519
+ * Provider registry — imports all provider definitions and assembles the
161520
+ * lookup tables used by the UI and CLI commands.
160123
161521
  */
160124
161522
  /**
160125
161523
  * @license