@qwen-code/qwen-code 0.22.0-nightly.20260825.22bb5e8b9f → 0.22.1

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 (379) hide show
  1. package/bundled/coordinate/SKILL.md +3 -3
  2. package/bundled/qc-helper/docs/configuration/model-providers.md +2 -0
  3. package/bundled/qc-helper/docs/configuration/settings.md +6 -6
  4. package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
  5. package/bundled/qc-helper/docs/features/channels/dws.md +120 -0
  6. package/bundled/qc-helper/docs/features/channels/overview.md +3 -3
  7. package/bundled/qc-helper/docs/features/code-review.md +1 -1
  8. package/bundled/qc-helper/docs/qwen-serve.md +2 -0
  9. package/bundled/review/SKILL.md +47 -12
  10. package/bundled/review/references/persistence.md +6 -6
  11. package/bundled/review/references/posting.md +2 -2
  12. package/chunks/MaxSizedBox-UUTUE42J.js +112 -0
  13. package/chunks/{StandaloneSessionPicker-NEWUAPCT.js → StandaloneSessionPicker-XF2TVJFK.js} +78 -77
  14. package/chunks/{acp-startup-profiler-T4GEAPLX.js → acp-startup-profiler-GNYAL6LI.js} +2 -2
  15. package/chunks/{acpAgent-A5CIQGW6.js → acpAgent-GY53MJIW.js} +254 -158
  16. package/chunks/{agent-TQ6CYOIL.js → agent-7U6CC5KF.js} +41 -41
  17. package/chunks/agent-headless-32O4L2CT.js +87 -0
  18. package/chunks/{anthropicContentGenerator-FSBGS426.js → anthropicContentGenerator-U76GTVB6.js} +7 -7
  19. package/chunks/{artifact-tool-UQTNZDUF.js → artifact-tool-XDJCZZCF.js} +2 -2
  20. package/chunks/{askUserQuestion-BSZALR7M.js → askUserQuestion-ZXXERLEV.js} +2 -2
  21. package/chunks/{bridge-MBOVCHXN.js → bridge-DFX2FFH4.js} +57 -56
  22. package/chunks/{ca-DZBZOMLU.js → ca-7HPYOYSZ.js} +1 -0
  23. package/chunks/{channel-management-service-XGGL6PLF.js → channel-management-service-HXXS3HOZ.js} +4 -4
  24. package/chunks/channel-settings-store-ELLH2M4M.js +117 -0
  25. package/chunks/{channel-worker-group-GIXIF4VT.js → channel-worker-group-EVDC2P4K.js} +5 -5
  26. package/chunks/{channel-worker-manager-ZBSYXJEB.js → channel-worker-manager-IJJZHGEI.js} +5 -5
  27. package/chunks/{channel-worker-supervisor-NI6JEY4Q.js → channel-worker-supervisor-YSKB5GVB.js} +9 -5
  28. package/chunks/{chunk-CPZQJP6J.js → chunk-27ONXAFY.js} +1 -1
  29. package/chunks/{chunk-FXNLH7E6.js → chunk-2CRNTW2B.js} +18 -2
  30. package/chunks/{read-package-up-UXSW3YPB.js → chunk-2EAZ43JQ.js} +1 -0
  31. package/chunks/{chunk-YX4II73B.js → chunk-2FN2HNTI.js} +2 -2
  32. package/chunks/{chunk-7KGJGYGA.js → chunk-2MHGD7EE.js} +1 -1
  33. package/chunks/{chunk-H5K5MRU7.js → chunk-2NCVUT3C.js} +4 -4
  34. package/chunks/{chunk-VLEGGCEA.js → chunk-2NNTE2ED.js} +171 -1
  35. package/chunks/{chunk-LNKZTLTH.js → chunk-2SERYG4T.js} +1 -1
  36. package/chunks/{chunk-UEHH33VE.js → chunk-2YDYDDE2.js} +6 -6
  37. package/chunks/{chunk-U7GJPTEY.js → chunk-2YEZNBSD.js} +66 -60
  38. package/chunks/{chunk-L6PFEZUM.js → chunk-2ZV3CZKI.js} +82 -12
  39. package/chunks/{chunk-36XTQW3N.js → chunk-3B5DCAQU.js} +28 -11
  40. package/chunks/{chunk-DE24WTEJ.js → chunk-3BV7TZNQ.js} +3 -3
  41. package/chunks/{chunk-IKPQM6I5.js → chunk-3FSBMAYD.js} +1 -1
  42. package/chunks/{chunk-J54EA46E.js → chunk-3UZCLCXR.js} +3 -3
  43. package/chunks/{chunk-ZROP2DTX.js → chunk-43C2II2G.js} +5 -5
  44. package/chunks/{chunk-2ZH5XAOO.js → chunk-47SIHHPL.js} +8 -8
  45. package/chunks/{chunk-EEBIINBT.js → chunk-4DCP3362.js} +6 -14
  46. package/chunks/{chunk-DF6DJZIX.js → chunk-4TPAG3O7.js} +1 -1
  47. package/chunks/{chunk-6L5EXDDN.js → chunk-5CI4AXDD.js} +4 -4
  48. package/chunks/{chunk-7KOFLDEP.js → chunk-5JTIYALA.js} +1 -1
  49. package/chunks/{chunk-YPJVAQ7V.js → chunk-5MK32KJV.js} +3 -3
  50. package/chunks/{chunk-XXA72PGJ.js → chunk-5T4LWWNX.js} +2 -2
  51. package/chunks/{chunk-NA6AZRDQ.js → chunk-5Y2JCJAH.js} +2 -2
  52. package/chunks/{chunk-3ROKI6MD.js → chunk-5ZYZPDDF.js} +978 -886
  53. package/chunks/{chunk-U4SJGOBF.js → chunk-62PXFOK4.js} +4 -4
  54. package/chunks/{chunk-SKXXO64C.js → chunk-6E4WHQJV.js} +1 -1
  55. package/chunks/{chunk-6Y7XMJFF.js → chunk-6HTMIKXZ.js} +6 -6
  56. package/chunks/{chunk-MGEXTDBI.js → chunk-6KS24S3X.js} +2 -2
  57. package/chunks/{chunk-ZJWFRMCY.js → chunk-6US7BF3G.js} +2 -2
  58. package/chunks/{chunk-RSOG6JND.js → chunk-6YAR6ZU3.js} +2 -2
  59. package/chunks/{chunk-Z3GFRVAY.js → chunk-73WFGVIZ.js} +3 -3
  60. package/chunks/{chunk-IX3CWNG7.js → chunk-76WGY6LW.js} +3 -3
  61. package/chunks/{chunk-CGWPQ6IM.js → chunk-77TOMRBG.js} +3 -3
  62. package/chunks/{chunk-JVTU5JYO.js → chunk-7AS7QX72.js} +1 -1
  63. package/chunks/{chunk-RLIS2VLZ.js → chunk-7DPKPBOQ.js} +2 -2
  64. package/chunks/{chunk-XQNWTA4Y.js → chunk-7JPW6IYH.js} +1 -1
  65. package/chunks/{chunk-UEY5WCRB.js → chunk-7QGEJI7M.js} +1 -1
  66. package/chunks/{chunk-GWUZOBCQ.js → chunk-A7X32SCT.js} +5 -5
  67. package/chunks/{chunk-R7Q5V3A5.js → chunk-AYVIGUUK.js} +1 -1
  68. package/chunks/{chunk-AIT6BMBI.js → chunk-BDHLBR46.js} +17 -3
  69. package/chunks/{chunk-3G6MRLTM.js → chunk-BKDAF7ES.js} +2 -2
  70. package/chunks/{chunk-5AHCPETA.js → chunk-BQBUZDDH.js} +3 -3
  71. package/chunks/{chunk-3KV5KXKU.js → chunk-BVE5EMIG.js} +2 -2
  72. package/chunks/{chunk-NDVTSFWZ.js → chunk-BX2BZPFJ.js} +3 -3
  73. package/chunks/{chunk-7UVAWPYG.js → chunk-C4WBKZJT.js} +4 -4
  74. package/chunks/{chunk-HYBEI2LH.js → chunk-CITGRGCM.js} +2 -1
  75. package/chunks/{chunk-TEQKBONY.js → chunk-CPPYZHBN.js} +1 -1
  76. package/chunks/chunk-DCSAVGDJ.js +20 -0
  77. package/chunks/{chunk-RSWDOHXS.js → chunk-DEYPMJPD.js} +1 -1
  78. package/chunks/{chunk-OWE7TE3F.js → chunk-DP7LABIB.js} +1 -1
  79. package/chunks/{chunk-LQF4PWEU.js → chunk-E4I5MVBR.js} +1 -1
  80. package/chunks/{chunk-NFDTDV37.js → chunk-E55H6BZ7.js} +4 -0
  81. package/chunks/{chunk-K623ENWT.js → chunk-E6FGMDFQ.js} +4 -0
  82. package/chunks/{chunk-QWTNAHCM.js → chunk-EAV3TENS.js} +3 -3
  83. package/chunks/{chunk-27HAGBZG.js → chunk-EB4VDXNI.js} +1 -1
  84. package/chunks/{chunk-RDPKOVXL.js → chunk-EC5BONC3.js} +1 -1
  85. package/chunks/{chunk-JHZIPJWY.js → chunk-EEQYTWGU.js} +5 -5
  86. package/chunks/{chunk-MFSV57XN.js → chunk-EKP3M4RF.js} +1 -1
  87. package/chunks/{chunk-R544UY5E.js → chunk-ELY4QVIB.js} +1 -1
  88. package/chunks/{chunk-PFCVB5ZI.js → chunk-EMGAVCBZ.js} +2 -2
  89. package/chunks/{chunk-JGDTCEBH.js → chunk-FJWICLG7.js} +1 -1
  90. package/chunks/{chunk-OXMS5HCS.js → chunk-FK4H3V6S.js} +5 -5
  91. package/chunks/{chunk-WANR3VVK.js → chunk-FN5C6C7G.js} +125 -60
  92. package/chunks/{chunk-5PVLDRGJ.js → chunk-FPH6TXD3.js} +1 -1
  93. package/chunks/{chunk-OY3ZSNQC.js → chunk-FVDQ5E67.js} +3 -3
  94. package/chunks/{chunk-J752LLEJ.js → chunk-GNMJNDZE.js} +1 -1
  95. package/chunks/{chunk-MSCVPOZR.js → chunk-GNRVKN76.js} +4 -4
  96. package/chunks/{chunk-FNZ42WN7.js → chunk-GTUKW3I6.js} +1 -1
  97. package/chunks/{chunk-NSPS67BG.js → chunk-GZJUCMH4.js} +1 -1
  98. package/chunks/{chunk-SNWAXNJ4.js → chunk-HJOWQUE2.js} +14 -11
  99. package/chunks/{chunk-3K5ORUVO.js → chunk-I32QCIK7.js} +1 -1
  100. package/chunks/{chunk-BOQRZ443.js → chunk-I6VVOZDK.js} +2 -2
  101. package/chunks/{chunk-KUPVZ4EO.js → chunk-I6YW3T3W.js} +207 -26
  102. package/chunks/{chunk-O6CS7VRT.js → chunk-ICWGPK23.js} +7 -7
  103. package/chunks/{chunk-EFT2T2LA.js → chunk-IJVDHPKD.js} +2 -2
  104. package/chunks/{chunk-SEMN7BNM.js → chunk-IKN3IUJP.js} +9 -8
  105. package/chunks/{chunk-O5ONGZGZ.js → chunk-ILPXSKGQ.js} +2 -2
  106. package/chunks/{chunk-QQQSUCC4.js → chunk-IPQA4SR5.js} +1 -1
  107. package/chunks/{chunk-SXBRB7ZP.js → chunk-IRIX323G.js} +2 -2
  108. package/chunks/{chunk-EJ5XRNOK.js → chunk-J7MLXFC5.js} +2 -2
  109. package/chunks/{chunk-KDGY3ST4.js → chunk-JECO75XD.js} +2 -2
  110. package/chunks/chunk-JLGFGPZJ.js +346 -0
  111. package/chunks/{chunk-COT2IXPM.js → chunk-JUIJ3FXC.js} +5 -5
  112. package/chunks/{chunk-IFWUT4GY.js → chunk-JVPFTDBK.js} +1 -1
  113. package/chunks/{chunk-455ZIBFX.js → chunk-K63NK3KL.js} +13 -13
  114. package/chunks/{chunk-MBLNXX3G.js → chunk-KCOXDRQL.js} +5 -5
  115. package/chunks/{chunk-3LUGIYS3.js → chunk-KOJ6MHD5.js} +3 -1
  116. package/chunks/{chunk-W4JA6Z44.js → chunk-KWFP3WV6.js} +9 -7
  117. package/chunks/{chunk-QKSMM4HF.js → chunk-L436XFLJ.js} +1 -1
  118. package/chunks/{chunk-M4TV7AJX.js → chunk-LI2HEMKO.js} +4 -4
  119. package/chunks/{chunk-FLTGTSLG.js → chunk-LJP2BBMK.js} +4 -4
  120. package/chunks/{chunk-HTIG2U5C.js → chunk-LRKMQPMD.js} +1 -1
  121. package/chunks/{chunk-YS4H3OFV.js → chunk-MDZO5V2O.js} +6 -6
  122. package/chunks/{chunk-2HYQZYPT.js → chunk-MW5AHWOZ.js} +7 -7
  123. package/chunks/{chunk-SJDR2S55.js → chunk-MYLXL7F6.js} +11 -11
  124. package/chunks/{chunk-PIZZIIEA.js → chunk-MZS7GEC7.js} +1 -1
  125. package/chunks/{chunk-H3JIT2M6.js → chunk-NER3H7PI.js} +1 -1
  126. package/chunks/{chunk-XYUJPDPB.js → chunk-NVK4HJYQ.js} +1 -1
  127. package/chunks/{chunk-GQQHY6TL.js → chunk-NY3IJYAV.js} +7 -7
  128. package/chunks/{chunk-3E53DKST.js → chunk-O3BUXIPM.js} +3 -3
  129. package/chunks/{chunk-QOUFO7TV.js → chunk-O5YGAEQS.js} +6 -6
  130. package/chunks/{chunk-OINGLDAX.js → chunk-ODXCSIH5.js} +4 -4
  131. package/chunks/{chunk-FMDWTE5I.js → chunk-OI2DR6QB.js} +2 -2
  132. package/chunks/{chunk-ENZMDVCM.js → chunk-OQ6LTSX3.js} +1 -1
  133. package/chunks/{chunk-KUDADN3R.js → chunk-OT26ITEY.js} +3 -3
  134. package/chunks/{chunk-FZUVUBYH.js → chunk-OX44MOAN.js} +3 -3
  135. package/chunks/{chunk-LURJYO2T.js → chunk-OZ6KS6KW.js} +4 -0
  136. package/chunks/{chunk-D2IGZJA7.js → chunk-PAJGKZAA.js} +272 -3
  137. package/chunks/{chunk-MTKBZIXU.js → chunk-PVBT5QPD.js} +1 -1
  138. package/chunks/{chunk-HDH5IDJH.js → chunk-R2ZJH3FV.js} +3 -3
  139. package/chunks/{chunk-SJLW5XGQ.js → chunk-RRKNX553.js} +1 -1
  140. package/chunks/{chunk-JS55F2GJ.js → chunk-SDVF6A42.js} +3 -3
  141. package/chunks/{chunk-DZPWZPGJ.js → chunk-SKNVVYIJ.js} +3 -3
  142. package/chunks/{chunk-SIC4S3RX.js → chunk-SLEWBQWM.js} +2 -2
  143. package/chunks/{chunk-P7DVAZKV.js → chunk-SM7ZVKTF.js} +7 -7
  144. package/chunks/{chunk-3N7EFOOM.js → chunk-SQPOJ4ZI.js} +11 -1
  145. package/chunks/{chunk-YOM3CJOP.js → chunk-SRGENTPF.js} +19 -19
  146. package/chunks/{chunk-ZB7VDPZB.js → chunk-T2CRBIDJ.js} +1 -1
  147. package/chunks/{chunk-F37T2S4O.js → chunk-T2HMXHYA.js} +6 -6
  148. package/chunks/{chunk-5X33EPHJ.js → chunk-T6OODF2U.js} +1 -1
  149. package/chunks/{chunk-7GECZMES.js → chunk-TKO4TLT6.js} +3 -3
  150. package/chunks/{chunk-PQ4RTSTH.js → chunk-TOF4UZHH.js} +3 -3
  151. package/chunks/{chunk-LD76HNCC.js → chunk-UCSV2IZW.js} +3 -3
  152. package/chunks/{chunk-EUZE3GSL.js → chunk-UX3IFLJM.js} +93 -9
  153. package/chunks/{chunk-AHQBSQYT.js → chunk-V3GINY6K.js} +3 -3
  154. package/chunks/{chunk-DD5XZICM.js → chunk-VL4YX3FH.js} +1 -1
  155. package/chunks/{chunk-DLYJ3RN7.js → chunk-VMDURMFY.js} +58 -32
  156. package/chunks/{chunk-E6BJFSLJ.js → chunk-W2WRNJKX.js} +6 -6
  157. package/chunks/{chunk-YLFLHKDL.js → chunk-W3N5XAZ6.js} +1 -1
  158. package/chunks/{chunk-QKGJIP2H.js → chunk-WBT3STGU.js} +1 -1
  159. package/chunks/{chunk-X3PRXXUH.js → chunk-WEGXPP5E.js} +1 -1
  160. package/chunks/{chunk-V6R3IEHF.js → chunk-XJS54K4A.js} +2 -2
  161. package/chunks/{chunk-NDJ3436G.js → chunk-XNXWEGKB.js} +3 -3
  162. package/chunks/{chunk-UFWRXRQ5.js → chunk-XYX474JQ.js} +1312 -290
  163. package/chunks/{chunk-UY2JOZK7.js → chunk-ZEADBZLO.js} +3 -3
  164. package/chunks/{chunk-SNJOBGQV.js → chunk-ZJG323IA.js} +4 -3
  165. package/chunks/{chunk-CZIF7I53.js → chunk-ZKAZP2ZG.js} +2 -2
  166. package/chunks/{chunk-DV3KOUUU.js → chunk-ZLTEQYNC.js} +2 -2
  167. package/chunks/{chunk-RLR7K4JJ.js → chunk-ZWKGZB2K.js} +3 -3
  168. package/chunks/{chunk-EJ2GPZDU.js → chunk-ZXDM7DYV.js} +1049 -383
  169. package/chunks/config-utils-7M6PCTLT.js +113 -0
  170. package/chunks/contextCommand-G4QG3TW6.js +108 -0
  171. package/chunks/{core-runtime-SZFD2YQA.js → core-runtime-PKNQ63VL.js} +53 -52
  172. package/chunks/{create-sub-session-OXESCUS7.js → create-sub-session-PLGPY6TV.js} +53 -52
  173. package/chunks/{create-sub-session-5ZLCAS2P.js → create-sub-session-RVHSWVAP.js} +3 -3
  174. package/chunks/{cron-create-P4CPPO25.js → cron-create-IJGVR5R2.js} +4 -4
  175. package/chunks/{cron-delete-FPD75GL4.js → cron-delete-4N5BI6GL.js} +4 -4
  176. package/chunks/{cron-list-QPML4MWL.js → cron-list-2CATIPUX.js} +4 -4
  177. package/chunks/{daemon-HY4AVTUM.js → daemon-NAYK4XXU.js} +34 -12
  178. package/chunks/{daemon-git-worktree-guard-EAVTZ6CE.js → daemon-git-worktree-guard-LDBJXH2U.js} +331 -86
  179. package/chunks/daemon-status-provider-F5FEHVVG.js +118 -0
  180. package/chunks/daemon-trust-policy-C6YTU5CQ.js +114 -0
  181. package/chunks/{daemon-trust-policy-monitor-ITF54474.js → daemon-trust-policy-monitor-IGEJPHQ4.js} +59 -58
  182. package/chunks/{deferred-core-runtime-WQ4NQA3N.js → deferred-core-runtime-GHT3GDOR.js} +53 -52
  183. package/chunks/{display-image-HOBBUJS5.js → display-image-DR55LL6M.js} +5 -5
  184. package/chunks/dist-4Q7NTUNB.js +2512 -0
  185. package/chunks/{dist-RW4QZD3K.js → dist-6H6RZ5H6.js} +2 -2
  186. package/chunks/{dist-ZUWCGMJ4.js → dist-7CKN54NL.js} +1 -1
  187. package/chunks/{dist-ZQJEKFZH.js → dist-DJBNNPLN.js} +1 -1
  188. package/chunks/{dist-5BX3J3AL.js → dist-FVJZSIO4.js} +28 -7
  189. package/chunks/{dist-OB6D7E7T.js → dist-SATKXKUR.js} +1 -1
  190. package/chunks/{dist-MEANA2OS.js → dist-TJUDJTCB.js} +1 -1
  191. package/chunks/{dist-4LRFQF7R.js → dist-UQUFZDIY.js} +1 -1
  192. package/chunks/{dist-7HGG7XLA.js → dist-ZBVOXSKF.js} +1 -1
  193. package/chunks/earlyInputCapture-HOSJTLWP.js +109 -0
  194. package/chunks/{edit-4MZYBPF5.js → edit-KSPVUEAS.js} +42 -42
  195. package/chunks/{en-X66KZS7T.js → en-6MDBWMTG.js} +1 -0
  196. package/chunks/{enter-worktree-WNR4JUPU.js → enter-worktree-UOZ6ZTP7.js} +7 -7
  197. package/chunks/{enterPlanMode-2EL6YAM5.js → enterPlanMode-DZTABSKN.js} +41 -41
  198. package/chunks/{environment-4QYNT2L3.js → environment-JXOSW25V.js} +57 -54
  199. package/chunks/{errors-N66MMOYD.js → errors-IOXFDE4J.js} +55 -54
  200. package/chunks/{exit-worktree-BUHUM6YC.js → exit-worktree-G2QATUCV.js} +7 -7
  201. package/chunks/{exitPlanMode-F73VQJBO.js → exitPlanMode-PZG4FXRB.js} +41 -41
  202. package/chunks/{fast-path-3L4YK6SO.js → fast-path-EBS7NAVL.js} +2 -2
  203. package/chunks/{gemini-4PINQJWX.js → gemini-JELEKOVS.js} +107 -103
  204. package/chunks/{geminiContentGenerator-7T7IU2V5.js → geminiContentGenerator-I2CKP7XI.js} +8 -8
  205. package/chunks/{glob-TWUYSRRG.js → glob-TDVEVPQZ.js} +41 -41
  206. package/chunks/{goal-tools-FTDQHRRX.js → goal-tools-CNVXMSZD.js} +70 -27
  207. package/chunks/{grep-QUQ3J6SR.js → grep-3NLSS32D.js} +6 -6
  208. package/chunks/handleAutoUpdate-AWAGHKOX.js +111 -0
  209. package/chunks/{i18n-Q6K7AX7Y.js → i18n-CYA25C5F.js} +54 -53
  210. package/chunks/{image-gen-RYOBEDNB.js → image-gen-63NN2H5N.js} +9 -9
  211. package/chunks/initializer-JD2FLNLO.js +115 -0
  212. package/chunks/installationInfo-N3DCWVWR.js +109 -0
  213. package/chunks/{keychain-token-storage-LQTBIXSX.js → keychain-token-storage-3MGFRYGM.js} +2 -2
  214. package/chunks/list-XDQAUET5.js +118 -0
  215. package/chunks/{list-agents-522ILPAR.js → list-agents-EXRSHIDJ.js} +2 -2
  216. package/chunks/loadedSettingsAdapter-IK7H5JRK.js +112 -0
  217. package/chunks/{loggingContentGenerator-RTDUJF6Y.js → loggingContentGenerator-CZWUAHAI.js} +20 -20
  218. package/chunks/{loop-wakeup-VSA4TBIC.js → loop-wakeup-XBPB2BRO.js} +5 -5
  219. package/chunks/{ls-FUCLEBTL.js → ls-WFONAND2.js} +4 -4
  220. package/chunks/{lsp-FYP6TW4R.js → lsp-DUKPDUXN.js} +2 -2
  221. package/chunks/{managed-npm-update-NUDVKV7F.js → managed-npm-update-54W23SP5.js} +54 -53
  222. package/chunks/mcp-2E7ZLMEE.js +112 -0
  223. package/chunks/{monitor-AU2SG5OL.js → monitor-A4J5QRGJ.js} +41 -41
  224. package/chunks/nonInteractiveCli-ZNDXB62Y.js +185 -0
  225. package/chunks/{notebook-edit-TGU7XHIO.js → notebook-edit-4ANFZON5.js} +42 -42
  226. package/chunks/{openaiContentGenerator-QPFWSUPT.js → openaiContentGenerator-JCCJJQZC.js} +24 -24
  227. package/chunks/pidfile-DHV2Y7UD.js +113 -0
  228. package/chunks/{processUtils-ZSHN6VGJ.js → processUtils-JJAR56SO.js} +2 -2
  229. package/chunks/prompt-terminal-ledger-LDZ6QVYA.js +107 -0
  230. package/chunks/{qwenContentGenerator-MEXKZX5O.js → qwenContentGenerator-5JM44ZSA.js} +46 -46
  231. package/chunks/{qwenOAuth2-QHHUP4KQ.js → qwenOAuth2-JIYAWXTW.js} +8 -8
  232. package/chunks/{read-file-T7ESVJAQ.js → read-file-N3E5DY7N.js} +12 -12
  233. package/chunks/{read-mcp-resource-5QGBDZ43.js → read-mcp-resource-7A7NFSFL.js} +2 -2
  234. package/chunks/read-package-up-6T6ICKR7.js +13 -0
  235. package/chunks/{record-artifact-K6BYYWXY.js → record-artifact-CPJ4IJSD.js} +4 -4
  236. package/chunks/report-findings-VFM5DENC.js +33 -0
  237. package/chunks/{request-shutdown-EUXDG4IH.js → request-shutdown-AXVOFN5C.js} +7 -7
  238. package/chunks/{resumeHistoryUtils-JFEAZEWW.js → resumeHistoryUtils-YQRITQAG.js} +60 -59
  239. package/chunks/{ripGrep-KOP6AHIX.js → ripGrep-NEIHKBKB.js} +17 -17
  240. package/chunks/{run-qwen-serve-IAVPTDB7.js → run-qwen-serve-IWGPZADI.js} +577 -67
  241. package/chunks/{runtime-ZICTJKT5.js → runtime-I76HPFUE.js} +64 -63
  242. package/chunks/{scheduler-YNVAANNX.js → scheduler-M6YL4K4I.js} +55 -54
  243. package/chunks/{sdk-exporters-http-GCVM7E4X.js → sdk-exporters-http-XXSKBD2C.js} +2 -2
  244. package/chunks/{sdk-impl-E3KA6NMY.js → sdk-impl-VPNBLV7I.js} +4 -4
  245. package/chunks/{send-message-EJUCEIKN.js → send-message-A2GXDX3B.js} +7 -7
  246. package/chunks/{serve-NF25WYMU.js → serve-XY5S63GN.js} +59 -58
  247. package/chunks/{server-7LKYWHCE.js → server-TWXRRREO.js} +605 -334
  248. package/chunks/{session-5FBBDYPI.js → session-IT5ZXU7A.js} +104 -99
  249. package/chunks/{settings-F7IXLQQW.js → settings-IX5HOOCG.js} +58 -57
  250. package/chunks/{shell-IJYC4BVX.js → shell-LZ55AAJB.js} +41 -41
  251. package/chunks/{skill-RTZU743G.js → skill-WSZ53D2R.js} +107 -23
  252. package/chunks/{skill-settings-ZOHS4J2E.js → skill-settings-5U7FTJIK.js} +58 -57
  253. package/chunks/{spawnChannel-JLKWUMTV.js → spawnChannel-TMC6VXGN.js} +55 -54
  254. package/chunks/{standalone-update-W44DUURE.js → standalone-update-CUYGWTR4.js} +55 -54
  255. package/chunks/{startInteractiveUI-7HPDSR7W.js → startInteractiveUI-O6BI2OSA.js} +219 -170
  256. package/chunks/{syntheticOutput-3ITPRJOB.js → syntheticOutput-5AJ444QT.js} +3 -3
  257. package/chunks/{task-create-USIZE733.js → task-create-CDJSOEQD.js} +11 -11
  258. package/chunks/{task-list-AWAJUPIP.js → task-list-BELMPA75.js} +5 -5
  259. package/chunks/{task-stop-I2CQSMDX.js → task-stop-U3S3KZG2.js} +2 -2
  260. package/chunks/{task-update-TFF2KJGL.js → task-update-77VCFDDZ.js} +11 -11
  261. package/chunks/{team-create-IU2A6HD3.js → team-create-UF4TMQEH.js} +41 -41
  262. package/chunks/{team-delete-E4C4AMPF.js → team-delete-YWFXX77L.js} +5 -5
  263. package/chunks/{team-plan-approval-BWI43D37.js → team-plan-approval-U57NSR6C.js} +41 -41
  264. package/chunks/{terminal-image-renderer-GQAMHJF2.js → terminal-image-renderer-DRL3BROJ.js} +55 -54
  265. package/chunks/theme-manager-HHJPUDRN.js +104 -0
  266. package/chunks/{todoWrite-ZUS3HGEF.js → todoWrite-435EO2CS.js} +4 -4
  267. package/chunks/{tool-search-TQNHT22X.js → tool-search-SV35UV72.js} +17 -17
  268. package/chunks/{total-session-admission-JMM73HNK.js → total-session-admission-TQI7TCTL.js} +57 -56
  269. package/chunks/{trustedFolders-BKQ2UXIB.js → trustedFolders-YKK67IP3.js} +54 -53
  270. package/chunks/{update-relaunch-WI7IWWCM.js → update-relaunch-DX7LVA4P.js} +5 -5
  271. package/chunks/{updateCheck-K6WUHPPT.js → updateCheck-6JRTKTUF.js} +58 -57
  272. package/chunks/useAutoAcceptIndicator-MYXYSKSL.js +122 -0
  273. package/chunks/{validateNonInterActiveAuth-RXCZM7MM.js → validateNonInterActiveAuth-B26O4YJP.js} +100 -95
  274. package/chunks/{version-IRAYALVC.js → version-K5D7VJ4B.js} +2 -2
  275. package/chunks/{web-fetch-FUG5KGKQ.js → web-fetch-VFHZLLNZ.js} +16 -16
  276. package/chunks/{web-search-SO3LHSHP.js → web-search-AQE5A4J5.js} +9 -9
  277. package/chunks/{workflow-XJRA3GRI.js → workflow-XL6AEUZ7.js} +150 -52
  278. package/chunks/workspace-providers-status-H6TG34YV.js +116 -0
  279. package/chunks/{workspace-registration-store-LCB4GHNP.js → workspace-registration-store-I4U3V5LL.js} +1 -1
  280. package/chunks/{workspace-registry-QWPFWGEF.js → workspace-registry-2PWNIYNI.js} +57 -56
  281. package/chunks/{workspace-service-MPGLZJF6.js → workspace-service-4FGTUJLA.js} +65 -64
  282. package/chunks/workspace-skills-status-7VOLUDT6.js +115 -0
  283. package/chunks/{workspace-trust-reconciler-4QDDGBQZ.js → workspace-trust-reconciler-GJ466KCE.js} +65 -64
  284. package/chunks/write-file-PWOYCT2K.js +90 -0
  285. package/chunks/{zh-TW-FZ3ETVR2.js → zh-TW-MV4FWFB6.js} +1 -0
  286. package/chunks/{zh-K3OJZ5LI.js → zh-X3WGU6SI.js} +1 -0
  287. package/chunks/{zoom-image-TCBO2YL5.js → zoom-image-NYJPC3NI.js} +12 -12
  288. package/cli.js +13 -13
  289. package/locales/ca.js +1 -0
  290. package/locales/en.js +1 -0
  291. package/locales/zh-TW.js +1 -0
  292. package/locales/zh.js +1 -0
  293. package/package.json +3 -3
  294. package/web-shell/assets/{abnfDiagram-VCTEODGH-hQsSuKY7.js → abnfDiagram-VCTEODGH-yq7z7Anb.js} +1 -1
  295. package/web-shell/assets/{arc-CpKLq3XD.js → arc-CbJO0xnT.js} +1 -1
  296. package/web-shell/assets/{architectureDiagram-5GKGNRK7-Bplk1J-m.js → architectureDiagram-5GKGNRK7-CRh89421.js} +1 -1
  297. package/web-shell/assets/{blockDiagram-NRAW4CY4-B-cca4ej.js → blockDiagram-NRAW4CY4-C75KAhKv.js} +1 -1
  298. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BZ8cn00E.js → c4Diagram-UCG6FXSJ-BzlMveFB.js} +1 -1
  299. package/web-shell/assets/channel-B3sGR79J.js +1 -0
  300. package/web-shell/assets/{chunk-2Q5K7J3B-DEQ2uYU0.js → chunk-2Q5K7J3B-DA8QDX3a.js} +1 -1
  301. package/web-shell/assets/{chunk-5VM5RSS4-DqH8Lz-4.js → chunk-5VM5RSS4-Bgu7gQ7Y.js} +1 -1
  302. package/web-shell/assets/{chunk-F27PBJKO-Dru7qMTB.js → chunk-F27PBJKO-BOew7pIK.js} +1 -1
  303. package/web-shell/assets/{chunk-G27WJ6UU-DN8KcdzT.js → chunk-G27WJ6UU-DHx1I-hO.js} +1 -1
  304. package/web-shell/assets/{chunk-JWPE2WC7-DMS-EquZ.js → chunk-JWPE2WC7-SarFW0WU.js} +1 -1
  305. package/web-shell/assets/{chunk-LCL6LL3I-ubbLaEwq.js → chunk-LCL6LL3I-BLzP083Z.js} +1 -1
  306. package/web-shell/assets/{chunk-POPQ4Y6H-DdIZqnYy.js → chunk-POPQ4Y6H-Bmkv_iKm.js} +1 -1
  307. package/web-shell/assets/{chunk-SVP7TREG-DkgYFSnb.js → chunk-SVP7TREG-MPx9r1N2.js} +1 -1
  308. package/web-shell/assets/{chunk-XXDRQBXY-CaesHiYG.js → chunk-XXDRQBXY-Ck-09rKG.js} +1 -1
  309. package/web-shell/assets/classDiagram-DTDB5LWJ-sTGo0K3v.js +1 -0
  310. package/web-shell/assets/classDiagram-v2-JRS7N3AN-sTGo0K3v.js +1 -0
  311. package/web-shell/assets/{cose-bilkent-JH36ORCC-bqnC4Oq-.js → cose-bilkent-JH36ORCC-DWm6lfOG.js} +1 -1
  312. package/web-shell/assets/{cynefin-OW5HDTMX-mDRBhRzB.js → cynefin-OW5HDTMX-DcBUyr5R.js} +1 -1
  313. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-B4Tod_Ik.js → cynefinDiagram-5FMLGOSQ-Df8qmd_p.js} +1 -1
  314. package/web-shell/assets/{dagre-3AP2YEHR-DU9f-iCw.js → dagre-3AP2YEHR-DDmGspD7.js} +1 -1
  315. package/web-shell/assets/{diagram-S7CK7UJ4-BsYVeB7c.js → diagram-S7CK7UJ4-BK_qFvbi.js} +1 -1
  316. package/web-shell/assets/{diagram-UQ7AKVKN-frM5Sn9C.js → diagram-UQ7AKVKN-Uw3AP_bi.js} +1 -1
  317. package/web-shell/assets/{diagram-VSXAHHWV-C1Z7uZdv.js → diagram-VSXAHHWV-CJOQKxY7.js} +1 -1
  318. package/web-shell/assets/{diagram-VX7I27RA-CIY4x0M9.js → diagram-VX7I27RA-DhdvZna5.js} +1 -1
  319. package/web-shell/assets/{diagram-Z3DM3KII-hTl4GIbg.js → diagram-Z3DM3KII-edQU0nlP.js} +1 -1
  320. package/web-shell/assets/{ebnfDiagram-PWID7BFC-4loIGTHZ.js → ebnfDiagram-PWID7BFC-4kugBEsO.js} +1 -1
  321. package/web-shell/assets/{erDiagram-SSCWMZ5O-B9Up14ul.js → erDiagram-SSCWMZ5O-BMkFivWO.js} +1 -1
  322. package/web-shell/assets/{flowDiagram-A5DVABFB-CIPfQBl9.js → flowDiagram-A5DVABFB-BM1ea8g-.js} +1 -1
  323. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-DaZk3lrl.js → ganttDiagram-EL5Y4UJY-CXj_cKRf.js} +1 -1
  324. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-D-knAHoQ.js → gitGraphDiagram-WWUBYQGX-D0nEqwqu.js} +1 -1
  325. package/web-shell/assets/{index-Di8dYJlQ.js → index-B6JN54Pd.js} +1 -1
  326. package/web-shell/assets/{index-RNKRtdDf.css → index-C-XlQn24.css} +1 -1
  327. package/web-shell/assets/{index-pkWucfFU.js → index-DLjXM0dn.js} +367 -367
  328. package/web-shell/assets/{infoDiagram-RXCK75RN-7AJndIyq.js → infoDiagram-RXCK75RN-DF7aGGbQ.js} +1 -1
  329. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-DjIU3IKv.js → ishikawaDiagram-5VMMS53U-CZYNX1lL.js} +1 -1
  330. package/web-shell/assets/{journeyDiagram-EYS64GPL-D3cf3462.js → journeyDiagram-EYS64GPL-CvrqMUz1.js} +1 -1
  331. package/web-shell/assets/{kanban-definition-3QL26DDD-CmuPjlRe.js → kanban-definition-3QL26DDD-BZNJQZBj.js} +1 -1
  332. package/web-shell/assets/{layout-C2Ci1XAx.js → layout-Bf83x7D6.js} +1 -1
  333. package/web-shell/assets/{linear-CqOKGHue.js → linear-Bkc3ES2f.js} +1 -1
  334. package/web-shell/assets/{mermaid.core-Bnt57s5_.js → mermaid.core-C6xuovwz.js} +6 -6
  335. package/web-shell/assets/{mindmap-definition-FBJOCRG2-BSSJVfj3.js → mindmap-definition-FBJOCRG2-DzH6gVRg.js} +1 -1
  336. package/web-shell/assets/{pegDiagram-XKGWAZYB-DNLHwge4.js → pegDiagram-XKGWAZYB-DCvLh2fa.js} +1 -1
  337. package/web-shell/assets/{pieDiagram-E7YTZNPT-CYRSio_9.js → pieDiagram-E7YTZNPT-BtjVlx_6.js} +1 -1
  338. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-CzSwKETq.js → quadrantDiagram-AXDQQJYC-IbroqxFe.js} +1 -1
  339. package/web-shell/assets/{railroadDiagram-O6MQD6OU-Dzbg_Jis.js → railroadDiagram-O6MQD6OU-BvMykiWW.js} +1 -1
  340. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-CY3Apuzl.js → requirementDiagram-EFPCY7ZU-D-HHMyrh.js} +1 -1
  341. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-432Hiv50.js → sankeyDiagram-P5KCCOFB-C0XXhB6d.js} +1 -1
  342. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-CucAf-fk.js → sequenceDiagram-WJ2MYXX4-DseAXj5d.js} +1 -1
  343. package/web-shell/assets/{sizeCapture-X5ZJPWSS-RBc9fiXv.js → sizeCapture-X5ZJPWSS-Cek2EweK.js} +1 -1
  344. package/web-shell/assets/{stateDiagram-HBIQ2CUA-BwsgjK6k.js → stateDiagram-HBIQ2CUA-yLv8wafW.js} +1 -1
  345. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-DeThXnol.js +1 -0
  346. package/web-shell/assets/{swimlanes-XN3QIQJK-DMMYIqPz.js → swimlanes-XN3QIQJK-Cwz-opvE.js} +1 -1
  347. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-GW0R1ZSv.js +8 -0
  348. package/web-shell/assets/{timeline-definition-24CTP7MA-BbmmEMJb.js → timeline-definition-24CTP7MA-BJuFD7OG.js} +1 -1
  349. package/web-shell/assets/{vennDiagram-4TSXK5OY-DlfQjNzM.js → vennDiagram-4TSXK5OY-CNAavdoV.js} +1 -1
  350. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-86EXFbP6.js → wardleyDiagram-VM6X3IG4-DaIjAidq.js} +1 -1
  351. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-794nZBSV.js → xychartDiagram-S5SC5T6Z-DkcQXjTy.js} +1 -1
  352. package/web-shell/index.html +2 -2
  353. package/chunks/MaxSizedBox-RQWAKXYC.js +0 -111
  354. package/chunks/agent-headless-YBSOXERA.js +0 -87
  355. package/chunks/channel-settings-store-DD6W3EJQ.js +0 -116
  356. package/chunks/config-utils-WXWWMH2D.js +0 -112
  357. package/chunks/contextCommand-UKPGPBW5.js +0 -107
  358. package/chunks/daemon-status-provider-D2HNWRDK.js +0 -116
  359. package/chunks/daemon-trust-policy-F4JM5CKX.js +0 -113
  360. package/chunks/earlyInputCapture-54M7AWAF.js +0 -108
  361. package/chunks/handleAutoUpdate-T36AMYVP.js +0 -110
  362. package/chunks/initializer-6USYPDX7.js +0 -114
  363. package/chunks/installationInfo-46TRIE5M.js +0 -108
  364. package/chunks/list-BCX6JAYS.js +0 -117
  365. package/chunks/loadedSettingsAdapter-7OBB7B6J.js +0 -111
  366. package/chunks/mcp-FCS6V74Y.js +0 -111
  367. package/chunks/nonInteractiveCli-CQUUSJ3N.js +0 -180
  368. package/chunks/pidfile-SIEQM3X5.js +0 -112
  369. package/chunks/prompt-terminal-ledger-YIAGDBHG.js +0 -106
  370. package/chunks/theme-manager-73W4SEDX.js +0 -103
  371. package/chunks/useAutoAcceptIndicator-SMCU7IYQ.js +0 -121
  372. package/chunks/workspace-providers-status-ZYXLTCJ5.js +0 -115
  373. package/chunks/workspace-skills-status-ZVFYCT5C.js +0 -114
  374. package/chunks/write-file-2KVXXVWB.js +0 -90
  375. package/web-shell/assets/channel-DggMZLoL.js +0 -1
  376. package/web-shell/assets/classDiagram-DTDB5LWJ-DPMQMV0q.js +0 -1
  377. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DPMQMV0q.js +0 -1
  378. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-C_HLER48.js +0 -1
  379. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-KP0j5nd5.js +0 -8
@@ -40,7 +40,7 @@ import {
40
40
  CronScheduler,
41
41
  DEFAULT_RECURRING_MAX_AGE_DAYS,
42
42
  normalizeRecurringMaxAge
43
- } from "./chunk-J54EA46E.js";
43
+ } from "./chunk-3UZCLCXR.js";
44
44
  import {
45
45
  consumeUnread,
46
46
  forwardApproval,
@@ -49,13 +49,13 @@ import {
49
49
  sendStructuredMessage,
50
50
  wrapConfirmWithBadge,
51
51
  writeMessage
52
- } from "./chunk-PQ4RTSTH.js";
52
+ } from "./chunk-TOF4UZHH.js";
53
53
  import {
54
54
  claimTask,
55
55
  listTasks,
56
56
  onTasksUpdated,
57
57
  unassignTeammateTasks
58
- } from "./chunk-3E53DKST.js";
58
+ } from "./chunk-O3BUXIPM.js";
59
59
  import {
60
60
  assignTeammateColor,
61
61
  classifyShutdownResponse,
@@ -68,7 +68,7 @@ import {
68
68
  readProcStartToken,
69
69
  sanitizeName,
70
70
  writeTeamFile
71
- } from "./chunk-DV3KOUUU.js";
71
+ } from "./chunk-ZLTEQYNC.js";
72
72
  import {
73
73
  parsePositiveIntegerEnv
74
74
  } from "./chunk-6PVPNMXU.js";
@@ -78,7 +78,7 @@ import {
78
78
  buildRuntimeSnapshotId,
79
79
  resolveModelId,
80
80
  stripRuntimeSnapshotPrefix
81
- } from "./chunk-R7Q5V3A5.js";
81
+ } from "./chunk-AYVIGUUK.js";
82
82
  import {
83
83
  promptIdContext,
84
84
  todoWorkChainContext
@@ -93,7 +93,7 @@ import {
93
93
  worktreeBranchForSlug,
94
94
  writeRuntimeStatus,
95
95
  writeWorktreeSessionMarker
96
- } from "./chunk-FLTGTSLG.js";
96
+ } from "./chunk-LJP2BBMK.js";
97
97
  import {
98
98
  LEADER_NAME,
99
99
  MAX_TEAMMATES
@@ -117,7 +117,7 @@ import {
117
117
  require_dist as require_dist2,
118
118
  stringify,
119
119
  validateSkillName
120
- } from "./chunk-NA6AZRDQ.js";
120
+ } from "./chunk-5Y2JCJAH.js";
121
121
  import {
122
122
  DefaultHookOutput,
123
123
  HOOKS_CONFIG_FIELDS,
@@ -132,11 +132,11 @@ import {
132
132
  createHookOutput,
133
133
  getHookKey,
134
134
  isToolArtifactLike
135
- } from "./chunk-ZB7VDPZB.js";
135
+ } from "./chunk-T2CRBIDJ.js";
136
136
  import {
137
137
  canUseRipgrep,
138
138
  resolveBundleDir
139
- } from "./chunk-CGWPQ6IM.js";
139
+ } from "./chunk-77TOMRBG.js";
140
140
  import {
141
141
  findGitRoot,
142
142
  getCachedGitBranch,
@@ -146,7 +146,7 @@ import {
146
146
  globSync,
147
147
  isGitRepository,
148
148
  readFirstLineNoFollow
149
- } from "./chunk-RSWDOHXS.js";
149
+ } from "./chunk-DEYPMJPD.js";
150
150
  import {
151
151
  SHELL_SELF_KILL_REJECTION,
152
152
  buildShellExecWarnings,
@@ -165,15 +165,15 @@ import {
165
165
  shouldDefaultToNodePty,
166
166
  splitCommands,
167
167
  stripShellWrapper
168
- } from "./chunk-5X33EPHJ.js";
168
+ } from "./chunk-T6OODF2U.js";
169
169
  import {
170
170
  BaseTokenStorage,
171
171
  KeychainTokenStorage
172
- } from "./chunk-CPZQJP6J.js";
172
+ } from "./chunk-27ONXAFY.js";
173
173
  import {
174
174
  normalizeImageGenerationBaseUrl,
175
175
  resolveNetworkTarget
176
- } from "./chunk-UY2JOZK7.js";
176
+ } from "./chunk-ZEADBZLO.js";
177
177
  import {
178
178
  EvidenceSourceUnavailableError,
179
179
  GoalEvidenceCheckpointAccumulator,
@@ -198,7 +198,7 @@ import {
198
198
  validateTranscriptRecord,
199
199
  walkTranscriptUuidChain,
200
200
  wrapUserPromptSubmitContext
201
- } from "./chunk-WANR3VVK.js";
201
+ } from "./chunk-FN5C6C7G.js";
202
202
  import {
203
203
  APPROVAL_MODES,
204
204
  READ_ONLY_INSPECTION_TOOLS,
@@ -214,7 +214,7 @@ import {
214
214
  isPlanRequiredTeammatePreApprovalAllowedTool,
215
215
  isSubagentLikeExecutionContext,
216
216
  shouldUsePlanOnlyReminderInSubagentContext
217
- } from "./chunk-3KV5KXKU.js";
217
+ } from "./chunk-BVE5EMIG.js";
218
218
  import {
219
219
  require_proper_lockfile
220
220
  } from "./chunk-MLXTMF7H.js";
@@ -225,7 +225,7 @@ import {
225
225
  import {
226
226
  isUnattendedMode,
227
227
  retryWithBackoff
228
- } from "./chunk-AHQBSQYT.js";
228
+ } from "./chunk-V3GINY6K.js";
229
229
  import {
230
230
  isRetryableStreamTransportError
231
231
  } from "./chunk-QHMLYMMS.js";
@@ -237,17 +237,17 @@ import {
237
237
  addToolArgumentsAttributes,
238
238
  addToolCallResultAttributes,
239
239
  addUserPromptAttributes
240
- } from "./chunk-JS55F2GJ.js";
240
+ } from "./chunk-SDVF6A42.js";
241
241
  import {
242
242
  addDaemonRequestAttribute
243
- } from "./chunk-O5ONGZGZ.js";
243
+ } from "./chunk-ILPXSKGQ.js";
244
244
  import {
245
245
  supportsOpenAIPrefixCaching
246
246
  } from "./chunk-SAH4BD2J.js";
247
247
  import {
248
248
  DashScopeOpenAICompatibleProvider,
249
249
  selectDashScopeThinkingKnob
250
- } from "./chunk-CZIF7I53.js";
250
+ } from "./chunk-ZKAZP2ZG.js";
251
251
  import {
252
252
  childLaunchDepth,
253
253
  getCurrentAgentDepth,
@@ -258,7 +258,7 @@ import {
258
258
  runWithAgentContext,
259
259
  runWithRuntimeContentGenerator,
260
260
  spawnBlockReason
261
- } from "./chunk-OWE7TE3F.js";
261
+ } from "./chunk-DP7LABIB.js";
262
262
  import {
263
263
  getTeammateContext,
264
264
  isTeammate,
@@ -275,7 +275,7 @@ import {
275
275
  import {
276
276
  classifyRetryError,
277
277
  isFallbackEligible
278
- } from "./chunk-BOQRZ443.js";
278
+ } from "./chunk-I6VVOZDK.js";
279
279
  import {
280
280
  getThoughtSummary
281
281
  } from "./chunk-K2OJUPOE.js";
@@ -293,7 +293,7 @@ import {
293
293
  isQuotaExhaustedError,
294
294
  isRateLimitError,
295
295
  isStructuredError
296
- } from "./chunk-27HAGBZG.js";
296
+ } from "./chunk-EB4VDXNI.js";
297
297
  import {
298
298
  ApiRetryEvent,
299
299
  COMBINED_PASS_TOLERANCE_FACTOR,
@@ -383,7 +383,7 @@ import {
383
383
  updateMCPServerStatus,
384
384
  writeLine,
385
385
  writeLineSync
386
- } from "./chunk-EUZE3GSL.js";
386
+ } from "./chunk-UX3IFLJM.js";
387
387
  import {
388
388
  defaultModalities,
389
389
  isTieredEffortWireModel
@@ -403,7 +403,7 @@ import {
403
403
  readTextCursorWindowFromHandle,
404
404
  readTextRangeFromHandle,
405
405
  setGeminiMdFilename
406
- } from "./chunk-QKGJIP2H.js";
406
+ } from "./chunk-WBT3STGU.js";
407
407
  import {
408
408
  AUTO_MEMORY_INDEX_FILENAME,
409
409
  AUTO_MEMORY_PINNED_DIRNAME,
@@ -423,10 +423,10 @@ import {
423
423
  isManagedMemoryPath,
424
424
  isTeamAutoMemPath,
425
425
  isUserAutoMemPath
426
- } from "./chunk-MTKBZIXU.js";
426
+ } from "./chunk-PVBT5QPD.js";
427
427
  import {
428
428
  runSideQuery
429
- } from "./chunk-QQQSUCC4.js";
429
+ } from "./chunk-IPQA4SR5.js";
430
430
  import {
431
431
  normalizeMcpToolName,
432
432
  sanitizeToolNameForProvider
@@ -451,7 +451,7 @@ import {
451
451
  createContentGenerator,
452
452
  resetPreloadedContentGenerator,
453
453
  resolveContentGeneratorConfigWithSources
454
- } from "./chunk-O6CS7VRT.js";
454
+ } from "./chunk-ICWGPK23.js";
455
455
  import {
456
456
  DEFAULT_QWEN_MODEL
457
457
  } from "./chunk-XZA32HII.js";
@@ -460,7 +460,7 @@ import {
460
460
  atomicWriteFileSync,
461
461
  atomicWriteJSON,
462
462
  renameWithRetry
463
- } from "./chunk-UEY5WCRB.js";
463
+ } from "./chunk-7QGEJI7M.js";
464
464
  import {
465
465
  AuthType,
466
466
  getOrCreateMcpDispatcher,
@@ -468,7 +468,7 @@ import {
468
468
  preloadRuntimeFetchModule,
469
469
  redactProxyError,
470
470
  setResolvedProxyUrlForRuntimeFetch
471
- } from "./chunk-FNZ42WN7.js";
471
+ } from "./chunk-GTUKW3I6.js";
472
472
  import {
473
473
  safeJsonStringify
474
474
  } from "./chunk-HHJLM3WQ.js";
@@ -518,10 +518,10 @@ import {
518
518
  startToolSpan,
519
519
  stripAnsiAndControl,
520
520
  truncateSpanError
521
- } from "./chunk-ZJWFRMCY.js";
521
+ } from "./chunk-6US7BF3G.js";
522
522
  import {
523
523
  STRUCTURED_OUTPUT_REDACTED_ARGS
524
- } from "./chunk-DD5XZICM.js";
524
+ } from "./chunk-VL4YX3FH.js";
525
525
  import {
526
526
  BUBBLE_APPROVAL_MODE,
527
527
  FORK_AGENT,
@@ -554,11 +554,11 @@ import {
554
554
  selectForkHistory,
555
555
  stripSystemReminderBlocks,
556
556
  validateForkToolList
557
- } from "./chunk-COT2IXPM.js";
557
+ } from "./chunk-JUIJ3FXC.js";
558
558
  import {
559
559
  collectAvailableSkillEntries,
560
560
  renderAvailableSkillsBlock
561
- } from "./chunk-K623ENWT.js";
561
+ } from "./chunk-E6FGMDFQ.js";
562
562
  import {
563
563
  escapeSystemReminderTags,
564
564
  escapeXml
@@ -570,7 +570,7 @@ import {
570
570
  formatQwenIgnoreFileNames,
571
571
  isPathWithinRoot,
572
572
  require_ignore
573
- } from "./chunk-SJLW5XGQ.js";
573
+ } from "./chunk-RRKNX553.js";
574
574
  import {
575
575
  AgentStatistics,
576
576
  BaseDeclarativeTool,
@@ -587,7 +587,7 @@ import {
587
587
  require_dist,
588
588
  require_fast_deep_equal,
589
589
  require_fast_uri
590
- } from "./chunk-3LUGIYS3.js";
590
+ } from "./chunk-KOJ6MHD5.js";
591
591
  import {
592
592
  FatalConfigError,
593
593
  PATH_ARG_KEYS,
@@ -623,7 +623,7 @@ import {
623
623
  unescapePath,
624
624
  unregisterSessionModel,
625
625
  unregisterSessionProjectDir
626
- } from "./chunk-VLEGGCEA.js";
626
+ } from "./chunk-2NNTE2ED.js";
627
627
  import {
628
628
  require_src
629
629
  } from "./chunk-AMDSOFFV.js";
@@ -22158,6 +22158,58 @@ function compactTodoResultDisplay(display, purpose) {
22158
22158
  };
22159
22159
  }
22160
22160
  __name(compactTodoResultDisplay, "compactTodoResultDisplay");
22161
+ function isFindingsResultDisplay(resultDisplay) {
22162
+ return typeof resultDisplay === "object" && resultDisplay !== null && "type" in resultDisplay && resultDisplay.type === "findings_list";
22163
+ }
22164
+ __name(isFindingsResultDisplay, "isFindingsResultDisplay");
22165
+ function findingRetainedSize(finding) {
22166
+ return (finding.id?.length ?? 0) + finding.severity.length + (finding.confidence?.length ?? 0) + (finding.source?.length ?? 0) + finding.file.length + String(finding.line ?? "").length + finding.summary.length + finding.shortSummary.length + finding.failureScenario.length + (finding.category?.length ?? 0) + (finding.outcome?.length ?? 0) + (finding.outcomeNote?.length ?? 0) + 20;
22167
+ }
22168
+ __name(findingRetainedSize, "findingRetainedSize");
22169
+ function compactFindingsResultDisplay(display, purpose) {
22170
+ const compacted = {
22171
+ ...display,
22172
+ findings: display.findings.map((finding) => ({
22173
+ ...finding,
22174
+ summary: compactString(
22175
+ finding.summary,
22176
+ purpose,
22177
+ MAX_RETAINED_AGENT_FIELD_CHARS
22178
+ ),
22179
+ failureScenario: compactString(
22180
+ finding.failureScenario,
22181
+ purpose,
22182
+ MAX_RETAINED_AGENT_FIELD_CHARS
22183
+ ),
22184
+ ...finding.outcomeNote !== void 0 && {
22185
+ outcomeNote: compactString(
22186
+ finding.outcomeNote,
22187
+ purpose,
22188
+ MAX_RETAINED_AGENT_FIELD_CHARS
22189
+ )
22190
+ }
22191
+ }))
22192
+ };
22193
+ let total = 0;
22194
+ let kept = 0;
22195
+ for (const finding of compacted.findings) {
22196
+ const size = findingRetainedSize(finding);
22197
+ if (total + size > MAX_RETAINED_TOOL_RESULT_DISPLAY_CHARS) {
22198
+ break;
22199
+ }
22200
+ total += size;
22201
+ kept += 1;
22202
+ }
22203
+ if (kept === compacted.findings.length) {
22204
+ return compacted;
22205
+ }
22206
+ return {
22207
+ ...compacted,
22208
+ findings: compacted.findings.slice(0, kept),
22209
+ omittedFindings: compacted.findings.length - kept
22210
+ };
22211
+ }
22212
+ __name(compactFindingsResultDisplay, "compactFindingsResultDisplay");
22161
22213
  function isPlanResultDisplay(resultDisplay) {
22162
22214
  return typeof resultDisplay === "object" && resultDisplay !== null && "type" in resultDisplay && resultDisplay.type === "plan_summary";
22163
22215
  }
@@ -22271,6 +22323,9 @@ function compactToolResultDisplay(resultDisplay, purpose) {
22271
22323
  if (isTodoResultDisplay(resultDisplay)) {
22272
22324
  return compactTodoResultDisplay(resultDisplay, purpose);
22273
22325
  }
22326
+ if (isFindingsResultDisplay(resultDisplay)) {
22327
+ return compactFindingsResultDisplay(resultDisplay, purpose);
22328
+ }
22274
22329
  if (isPlanResultDisplay(resultDisplay)) {
22275
22330
  return compactPlanResultDisplay(resultDisplay, purpose);
22276
22331
  }
@@ -22475,17 +22530,17 @@ function summarizeTranscript(records) {
22475
22530
  };
22476
22531
  }
22477
22532
  __name(summarizeTranscript, "summarizeTranscript");
22478
- async function persistUsageBeforeTranscriptDeletion(transcriptPath) {
22533
+ async function prepareUsageBeforeTranscriptDeletion(transcriptPath) {
22479
22534
  try {
22480
22535
  const records = await read(transcriptPath);
22481
22536
  const summarized = summarizeTranscript(records);
22482
- if (!summarized?.record) return false;
22537
+ if (!summarized?.record) return null;
22483
22538
  const usagePath = getUsageHistoryPath();
22484
22539
  try {
22485
22540
  if (fs5.existsSync(usagePath)) {
22486
22541
  const existing = await read(usagePath);
22487
22542
  if (existing.some((r) => r?.sessionId === summarized.sessionId)) {
22488
- return false;
22543
+ return null;
22489
22544
  }
22490
22545
  }
22491
22546
  } catch (e) {
@@ -22493,14 +22548,33 @@ async function persistUsageBeforeTranscriptDeletion(transcriptPath) {
22493
22548
  `persistUsageBeforeTranscriptDeletion: cannot read history: ${e}`
22494
22549
  );
22495
22550
  }
22496
- writeLineSync(usagePath, summarized.record);
22551
+ return { usagePath, record: summarized.record };
22552
+ } catch (e) {
22553
+ debugLogger11.debug(`prepareUsageBeforeTranscriptDeletion: ${e}`);
22554
+ return null;
22555
+ }
22556
+ }
22557
+ __name(prepareUsageBeforeTranscriptDeletion, "prepareUsageBeforeTranscriptDeletion");
22558
+ function commitUsageBeforeTranscriptDeletion(prepared) {
22559
+ try {
22560
+ if (fs5.existsSync(prepared.usagePath)) {
22561
+ const alreadyPersisted = fs5.readFileSync(prepared.usagePath, "utf8").split(/\r?\n/).some((line) => {
22562
+ const trimmed = line.trim();
22563
+ return trimmed.length > 0 && parseLineTolerant(
22564
+ trimmed,
22565
+ prepared.usagePath
22566
+ ).some((record4) => record4.sessionId === prepared.record.sessionId);
22567
+ });
22568
+ if (alreadyPersisted) return false;
22569
+ }
22570
+ writeLineSync(prepared.usagePath, prepared.record);
22497
22571
  return true;
22498
22572
  } catch (e) {
22499
- debugLogger11.debug(`persistUsageBeforeTranscriptDeletion: ${e}`);
22573
+ debugLogger11.debug(`commitUsageBeforeTranscriptDeletion: ${e}`);
22500
22574
  return false;
22501
22575
  }
22502
22576
  }
22503
- __name(persistUsageBeforeTranscriptDeletion, "persistUsageBeforeTranscriptDeletion");
22577
+ __name(commitUsageBeforeTranscriptDeletion, "commitUsageBeforeTranscriptDeletion");
22504
22578
  async function rebuildFromSessionJsonl(options2 = {}) {
22505
22579
  const {
22506
22580
  skipSessionInRebuild,
@@ -26844,17 +26918,17 @@ var SessionOrganizationService = class {
26844
26918
  return viewOrganization(store2.sessions[sessionId]);
26845
26919
  });
26846
26920
  }
26847
- async removeSession(sessionId) {
26921
+ async removeSession(sessionId, options2 = {}) {
26848
26922
  await this.withStoreLock(async () => {
26849
26923
  const store2 = await this.readStore();
26850
26924
  if (!Object.prototype.hasOwnProperty.call(store2.sessions, sessionId)) {
26851
26925
  return;
26852
26926
  }
26853
26927
  delete store2.sessions[sessionId];
26854
- await this.writeStore(store2);
26928
+ await this.writeStore(store2, options2);
26855
26929
  });
26856
26930
  }
26857
- async removeSessions(sessionIds) {
26931
+ async removeSessions(sessionIds, options2 = {}) {
26858
26932
  const uniqueSessionIds = [...new Set(sessionIds)];
26859
26933
  if (uniqueSessionIds.length === 0) return;
26860
26934
  await this.withStoreLock(async () => {
@@ -26867,7 +26941,7 @@ var SessionOrganizationService = class {
26867
26941
  }
26868
26942
  }
26869
26943
  if (changed) {
26870
- await this.writeStore(store2);
26944
+ await this.writeStore(store2, options2);
26871
26945
  }
26872
26946
  });
26873
26947
  }
@@ -26945,7 +27019,7 @@ var SessionOrganizationService = class {
26945
27019
  );
26946
27020
  return emptyStore();
26947
27021
  }
26948
- async writeStore(store2) {
27022
+ async writeStore(store2, options2 = {}) {
26949
27023
  await fs7.mkdir(path7.dirname(this.getStorePath()), { recursive: true });
26950
27024
  if (this.readFailed) {
26951
27025
  throw new SessionOrganizationError(
@@ -26953,11 +27027,15 @@ var SessionOrganizationService = class {
26953
27027
  "session_organization_store_unreadable"
26954
27028
  );
26955
27029
  }
26956
- await atomicWriteJSON(this.getStorePath(), {
26957
- schemaVersion: SCHEMA_VERSION,
26958
- groups: this.sortGroups(store2.groups),
26959
- sessions: store2.sessions
26960
- });
27030
+ await atomicWriteJSON(
27031
+ this.getStorePath(),
27032
+ {
27033
+ schemaVersion: SCHEMA_VERSION,
27034
+ groups: this.sortGroups(store2.groups),
27035
+ sessions: store2.sessions
27036
+ },
27037
+ { assertCanCommit: options2.assertCanCommit }
27038
+ );
26961
27039
  this.readFailed = false;
26962
27040
  }
26963
27041
  assertGroupNameAvailable(groups, name, exceptGroupId) {
@@ -27108,9 +27186,9 @@ async function readSessionPrs(filePath, options2 = {}) {
27108
27186
  return parsed.prs;
27109
27187
  }
27110
27188
  __name(readSessionPrs, "readSessionPrs");
27111
- async function writeSessionPrs(filePath, prs) {
27189
+ async function writeSessionPrs(filePath, prs, options2 = {}) {
27112
27190
  await fs8.mkdir(path8.dirname(filePath), { recursive: true });
27113
- await atomicWriteJSON(filePath, { prs });
27191
+ await atomicWriteJSON(filePath, { prs }, options2);
27114
27192
  }
27115
27193
  __name(writeSessionPrs, "writeSessionPrs");
27116
27194
  function mergeSessionPrLists(base, incoming) {
@@ -31534,6 +31612,20 @@ var BranchPointInvalidError = class extends Error {
31534
31612
  __name(this, "BranchPointInvalidError");
31535
31613
  }
31536
31614
  };
31615
+ var MAX_MAINTAINABLE_FIRST_RECORD_BYTES = 1024 * 1024;
31616
+ var SessionStorageEntryError = class extends Error {
31617
+ constructor(sessionId, reason) {
31618
+ super(
31619
+ reason === "non_regular" ? `Session storage entry for "${sessionId}" is not a regular file.` : reason === "foreign_project" ? `Session "${sessionId}" belongs to a different workspace.` : `Session "${sessionId}" does not have unambiguous workspace ownership.`
31620
+ );
31621
+ this.sessionId = sessionId;
31622
+ this.reason = reason;
31623
+ }
31624
+ static {
31625
+ __name(this, "SessionStorageEntryError");
31626
+ }
31627
+ name = "SessionStorageEntryError";
31628
+ };
31537
31629
  var SessionIdCaseConflictError = class extends Error {
31538
31630
  // `candidateSessionId` is set only when one exact spelling was found
31539
31631
  // persisted in both active and archived states, so callers can re-check
@@ -31725,6 +31817,17 @@ var SessionService = class {
31725
31817
  ...options2
31726
31818
  });
31727
31819
  }
31820
+ async acquireSessionMaintenanceLease(sessionId, options2) {
31821
+ if (!SESSION_FILE_PATTERN.test(`${sessionId}.jsonl`)) {
31822
+ throw new SessionWriterUnavailableError();
31823
+ }
31824
+ return SessionWriterLease.acquire({
31825
+ runtimeBaseDir: this.storage.getRuntimeBaseDir(),
31826
+ sessionId,
31827
+ transcriptPath: `${this.getSessionFilePath(sessionId, "active")}.maintenance`,
31828
+ ...options2
31829
+ });
31830
+ }
31728
31831
  warn(message) {
31729
31832
  debugLogger15.warn(message);
31730
31833
  this.onWarning?.(message);
@@ -31822,7 +31925,7 @@ var SessionService = class {
31822
31925
  return void 0;
31823
31926
  }
31824
31927
  const firstRecord = records[0];
31825
- if (!await this.sessionBelongsToCurrentProject(sessionId, firstRecord.cwd)) {
31928
+ if (typeof firstRecord.sessionId !== "string" || typeof firstRecord.cwd !== "string" || firstRecord.sessionId.toLowerCase() !== sessionId.toLowerCase() || !await this.sessionBelongsToCurrentProject(sessionId, firstRecord.cwd)) {
31826
31929
  return void 0;
31827
31930
  }
31828
31931
  return firstRecord;
@@ -31910,6 +32013,207 @@ var SessionService = class {
31910
32013
  if (archived) return "archived";
31911
32014
  return void 0;
31912
32015
  }
32016
+ /**
32017
+ * Classifies exact-spelling transcript files for lifecycle maintenance.
32018
+ * Unlike {@link getSessionLocation}, empty or damaged regular files still
32019
+ * occupy their state. A readable head that explicitly belongs to another
32020
+ * workspace remains unavailable to this service.
32021
+ */
32022
+ async getMaintainableSessionLocation(sessionId) {
32023
+ try {
32024
+ return (await this.resolveMaintainableSessionSnapshot(sessionId, false)).location;
32025
+ } catch (error3) {
32026
+ if (error3 instanceof SessionStorageEntryError && error3.reason === "foreign_project") {
32027
+ return void 0;
32028
+ }
32029
+ throw error3;
32030
+ }
32031
+ }
32032
+ async resolveMaintainableSessionSnapshot(sessionId, captureIdentity = true) {
32033
+ if (!SESSION_FILE_PATTERN.test(`${sessionId}.jsonl`)) {
32034
+ return { location: void 0, identities: [] };
32035
+ }
32036
+ const identities = [];
32037
+ let hasForeignState = false;
32038
+ for (const state of ["active", "archived"]) {
32039
+ try {
32040
+ const identity = await this.readMaintainableSessionIdentity(
32041
+ sessionId,
32042
+ state,
32043
+ captureIdentity
32044
+ );
32045
+ if (identity) identities.push(identity);
32046
+ } catch (error3) {
32047
+ if (error3 instanceof SessionStorageEntryError && error3.reason === "foreign_project") {
32048
+ hasForeignState = true;
32049
+ continue;
32050
+ }
32051
+ throw error3;
32052
+ }
32053
+ }
32054
+ if (hasForeignState) {
32055
+ if (identities.length === 0) {
32056
+ throw new SessionStorageEntryError(sessionId, "foreign_project");
32057
+ }
32058
+ throw new SessionStorageEntryError(sessionId, "ambiguous_project");
32059
+ }
32060
+ const active = identities.some((identity) => identity.state === "active");
32061
+ const archived = identities.some(
32062
+ (identity) => identity.state === "archived"
32063
+ );
32064
+ return {
32065
+ location: active && archived ? "conflict" : active ? "active" : archived ? "archived" : void 0,
32066
+ identities
32067
+ };
32068
+ }
32069
+ async readMaintainableSessionIdentity(sessionId, state, captureIdentity) {
32070
+ const filePath = this.getSessionFilePath(sessionId, state);
32071
+ let fileHandle;
32072
+ try {
32073
+ fileHandle = await fs11.promises.open(
32074
+ filePath,
32075
+ fs11.constants.O_RDONLY | (process.platform === "win32" ? 0 : (fs11.constants.O_NOFOLLOW ?? 0) | (fs11.constants.O_NONBLOCK ?? 0))
32076
+ );
32077
+ } catch (error3) {
32078
+ const code = error3.code;
32079
+ if (code === "ENOENT") return void 0;
32080
+ if (code === "ELOOP") {
32081
+ throw new SessionStorageEntryError(sessionId, "non_regular");
32082
+ }
32083
+ throw error3;
32084
+ }
32085
+ try {
32086
+ const opened = this.maintainableSessionIdentity(
32087
+ sessionId,
32088
+ state,
32089
+ filePath,
32090
+ await fileHandle.stat()
32091
+ );
32092
+ const firstRecord = await this.readFirstMaintainableRecord(
32093
+ fileHandle,
32094
+ filePath
32095
+ );
32096
+ if (firstRecord) {
32097
+ if (typeof firstRecord.sessionId !== "string" || typeof firstRecord.cwd !== "string") {
32098
+ throw new SessionStorageEntryError(sessionId, "unknown_project");
32099
+ }
32100
+ if (firstRecord.sessionId.toLowerCase() !== sessionId.toLowerCase()) {
32101
+ throw new SessionStorageEntryError(sessionId, "foreign_project");
32102
+ }
32103
+ if (!await this.sessionBelongsToCurrentProject(
32104
+ firstRecord.sessionId,
32105
+ firstRecord.cwd
32106
+ )) {
32107
+ throw new SessionStorageEntryError(sessionId, "foreign_project");
32108
+ }
32109
+ }
32110
+ const current = this.maintainableSessionIdentity(
32111
+ sessionId,
32112
+ state,
32113
+ filePath,
32114
+ await fs11.promises.lstat(filePath)
32115
+ );
32116
+ const stillOpened = this.maintainableSessionIdentity(
32117
+ sessionId,
32118
+ state,
32119
+ filePath,
32120
+ await fileHandle.stat()
32121
+ );
32122
+ if (!this.sameMaintainableSessionIdentity(opened, current) || !this.sameMaintainableSessionIdentity(opened, stillOpened)) {
32123
+ throw new SessionTranscriptChangedError();
32124
+ }
32125
+ return captureIdentity ? current : opened;
32126
+ } finally {
32127
+ await fileHandle.close();
32128
+ }
32129
+ }
32130
+ async readFirstMaintainableRecord(fileHandle, filePath) {
32131
+ const buffer = Buffer.allocUnsafe(64 * 1024);
32132
+ const decoder = new TextDecoder();
32133
+ let pending = "";
32134
+ while (true) {
32135
+ const { bytesRead } = await fileHandle.read(buffer);
32136
+ pending += decoder.decode(buffer.subarray(0, bytesRead), {
32137
+ stream: bytesRead > 0
32138
+ });
32139
+ let newline2 = pending.indexOf("\n");
32140
+ const firstLineLength = newline2 >= 0 ? newline2 : pending.length;
32141
+ if (firstLineLength > MAX_MAINTAINABLE_FIRST_RECORD_BYTES && newline2 < 0) {
32142
+ const prefix = pending.trimStart();
32143
+ if (!prefix || prefix.startsWith("{")) {
32144
+ throw new SessionTranscriptIdentityUnavailableError();
32145
+ }
32146
+ return void 0;
32147
+ }
32148
+ while (newline2 >= 0) {
32149
+ const line = pending.slice(0, newline2).trim();
32150
+ pending = pending.slice(newline2 + 1);
32151
+ if (line) {
32152
+ const record4 = parseLineTolerant(
32153
+ line,
32154
+ filePath
32155
+ )[0];
32156
+ if (record4) return record4;
32157
+ }
32158
+ newline2 = pending.indexOf("\n");
32159
+ }
32160
+ if (bytesRead === 0) {
32161
+ if (!pending.trim()) return void 0;
32162
+ return parseLineTolerant(
32163
+ pending.trim(),
32164
+ filePath
32165
+ )[0];
32166
+ }
32167
+ }
32168
+ }
32169
+ maintainableSessionIdentity(sessionId, state, filePath, stats) {
32170
+ if (!stats.isFile()) {
32171
+ throw new SessionStorageEntryError(sessionId, "non_regular");
32172
+ }
32173
+ if (!hasVerifiableInode(stats.ino)) {
32174
+ throw new SessionTranscriptIdentityUnavailableError();
32175
+ }
32176
+ return {
32177
+ state,
32178
+ filePath,
32179
+ dev: stats.dev,
32180
+ ino: stats.ino,
32181
+ size: stats.size,
32182
+ mtimeMs: stats.mtimeMs,
32183
+ ctimeMs: stats.ctimeMs
32184
+ };
32185
+ }
32186
+ sameMaintainableSessionIdentity(expected, actual) {
32187
+ return expected.state === actual.state && expected.filePath === actual.filePath && expected.dev === actual.dev && expected.ino === actual.ino && expected.size === actual.size && expected.mtimeMs === actual.mtimeMs && expected.ctimeMs === actual.ctimeMs;
32188
+ }
32189
+ assertMaintainableSessionUnchanged(sessionId, snapshot) {
32190
+ for (const state of ["active", "archived"]) {
32191
+ const expected = snapshot.identities.find(
32192
+ (identity) => identity.state === state
32193
+ );
32194
+ const filePath = this.getSessionFilePath(sessionId, state);
32195
+ let stats;
32196
+ try {
32197
+ stats = fs11.lstatSync(filePath);
32198
+ } catch (error3) {
32199
+ if (error3.code === "ENOENT") {
32200
+ if (!expected) continue;
32201
+ throw new SessionTranscriptChangedError();
32202
+ }
32203
+ throw error3;
32204
+ }
32205
+ if (!expected) throw new SessionTranscriptChangedError();
32206
+ const actual = this.maintainableSessionIdentity(
32207
+ sessionId,
32208
+ state,
32209
+ filePath,
32210
+ stats
32211
+ );
32212
+ if (!this.sameMaintainableSessionIdentity(expected, actual)) {
32213
+ throw new SessionTranscriptChangedError();
32214
+ }
32215
+ }
32216
+ }
31913
32217
  /**
31914
32218
  * Finds a persisted session whose UUID filename differs only by case.
31915
32219
  * Legacy CLI sessions may have been written with `uuidgen`'s uppercase
@@ -32042,12 +32346,23 @@ var SessionService = class {
32042
32346
  { recursive: true, force: true }
32043
32347
  );
32044
32348
  }
32045
- async removeSessionOrganization(sessionId) {
32349
+ async removeSessionOrganization(sessionId, assertCanMutate) {
32046
32350
  try {
32047
- await new SessionOrganizationService(this.projectRoot, (message) => {
32048
- this.warn(message);
32049
- }).removeSession(sessionId);
32351
+ const service = new SessionOrganizationService(
32352
+ this.projectRoot,
32353
+ (message) => {
32354
+ this.warn(message);
32355
+ }
32356
+ );
32357
+ if (assertCanMutate) {
32358
+ await service.removeSession(sessionId, {
32359
+ assertCanCommit: assertCanMutate
32360
+ });
32361
+ } else {
32362
+ await service.removeSession(sessionId);
32363
+ }
32050
32364
  } catch (error3) {
32365
+ assertCanMutate?.();
32051
32366
  this.warn(
32052
32367
  `removeSession: failed to clear session organization for ${sessionId}: ${error3}`
32053
32368
  );
@@ -32113,12 +32428,13 @@ ${payload}`, "utf8");
32113
32428
  * no transition would ever reunite them otherwise. Throws propagate to
32114
32429
  * the caller, which owns the warn-only policy.
32115
32430
  */
32116
- async movePrSidecar(sourcePath, destinationPath) {
32431
+ async movePrSidecar(sourcePath, destinationPath, assertCanMutate) {
32117
32432
  if (!fs11.existsSync(sourcePath)) {
32118
32433
  return;
32119
32434
  }
32120
32435
  fs11.mkdirSync(path11.dirname(destinationPath), { recursive: true });
32121
32436
  if (!fs11.existsSync(destinationPath)) {
32437
+ assertCanMutate?.();
32122
32438
  fs11.renameSync(sourcePath, destinationPath);
32123
32439
  return;
32124
32440
  }
@@ -32127,8 +32443,15 @@ ${payload}`, "utf8");
32127
32443
  await readSessionPrs(sourcePath) ?? []
32128
32444
  );
32129
32445
  if (merged.length > 0) {
32130
- await writeSessionPrs(destinationPath, merged);
32446
+ if (assertCanMutate) {
32447
+ await writeSessionPrs(destinationPath, merged, {
32448
+ assertCanCommit: assertCanMutate
32449
+ });
32450
+ } else {
32451
+ await writeSessionPrs(destinationPath, merged);
32452
+ }
32131
32453
  }
32454
+ assertCanMutate?.();
32132
32455
  fs11.unlinkSync(sourcePath);
32133
32456
  }
32134
32457
  sessionFileMoveError(action, error3) {
@@ -32714,65 +33037,77 @@ ${payload}`, "utf8");
32714
33037
  * @param sessionId The session ID to remove
32715
33038
  * @returns true if removed, false if not found
32716
33039
  */
32717
- async removeSession(sessionId) {
32718
- const removed = await this.removeSessionFiles(sessionId);
33040
+ async removeSession(sessionId, options2 = {}) {
33041
+ const removed = await this.removeSessionFiles(sessionId, options2);
32719
33042
  if (removed) {
32720
- await this.removeSessionOrganization(sessionId);
33043
+ await this.removeSessionOrganization(sessionId, options2.assertCanMutate);
32721
33044
  }
32722
33045
  return removed;
32723
33046
  }
32724
33047
  /**
32725
33048
  * Usage salvage wrapper enforcing the "never blocks deletion" contract at
32726
- * the call site: persistUsageBeforeTranscriptDeletion catches its own
32727
- * errors, but this second layer keeps the guarantee structural rather
32728
- * than an implementation detail of another module.
33049
+ * the call site. Preparation is read-only so rejected lifecycle mutations
33050
+ * cannot pin an incomplete usage summary; commit happens only after every
33051
+ * mutation fence passes.
32729
33052
  */
32730
- async salvageUsageBestEffort(transcriptPath) {
33053
+ async prepareUsageSalvageBestEffort(transcriptPath) {
32731
33054
  try {
32732
- await persistUsageBeforeTranscriptDeletion(transcriptPath);
33055
+ return await prepareUsageBeforeTranscriptDeletion(transcriptPath);
32733
33056
  } catch (error3) {
32734
33057
  this.warn(
32735
33058
  `usage salvage failed for ${transcriptPath}: ${error3}; deleting anyway`
32736
33059
  );
33060
+ return null;
32737
33061
  }
32738
33062
  }
32739
- async removeSessionFiles(sessionId) {
33063
+ commitUsageSalvageBestEffort(prepared) {
33064
+ if (!prepared) return;
33065
+ try {
33066
+ commitUsageBeforeTranscriptDeletion(prepared);
33067
+ } catch (error3) {
33068
+ this.warn(`usage salvage commit failed: ${error3}; deleting anyway`);
33069
+ }
33070
+ }
33071
+ async removeSessionFiles(sessionId, options2 = {}) {
32740
33072
  if (!SESSION_FILE_PATTERN.test(`${sessionId}.jsonl`)) {
32741
33073
  return false;
32742
33074
  }
32743
33075
  try {
32744
- const activePath = this.getSessionFilePath(sessionId, "active");
32745
- const active = await this.readProjectSessionHead(sessionId, activePath);
32746
- if (active) {
32747
- await this.salvageUsageBestEffort(activePath);
32748
- this.removeFileIfExists(activePath);
32749
- const archivedPath2 = this.getSessionFilePath(sessionId, "archived");
32750
- if (fs11.existsSync(archivedPath2)) {
32751
- await this.salvageUsageBestEffort(archivedPath2);
32752
- this.removeFileIfExists(archivedPath2);
32753
- }
32754
- this.removeWorktreeSidecars(sessionId);
32755
- this.removePrSidecars(sessionId);
32756
- this.removePromptLedgers(sessionId);
32757
- this.removeFileHistoryBackups(sessionId);
32758
- return true;
33076
+ const physicalSnapshot = await this.resolveMaintainableSessionSnapshot(sessionId);
33077
+ if (physicalSnapshot.location === void 0) return false;
33078
+ const preparedUsage = /* @__PURE__ */ new Map();
33079
+ const preparedSessionIds = /* @__PURE__ */ new Set();
33080
+ for (const identity of physicalSnapshot.identities) {
33081
+ const prepared = await this.prepareUsageSalvageBestEffort(
33082
+ identity.filePath
33083
+ );
33084
+ if (prepared && !preparedSessionIds.has(prepared.record.sessionId)) {
33085
+ preparedUsage.set(identity.filePath, prepared);
33086
+ preparedSessionIds.add(prepared.record.sessionId);
33087
+ }
32759
33088
  }
32760
- const archivedPath = this.getSessionFilePath(sessionId, "archived");
32761
- const archived = await this.readProjectSessionHead(
32762
- sessionId,
32763
- archivedPath
32764
- );
32765
- if (!archived) {
32766
- return false;
33089
+ await options2.assertStorageUnchanged?.();
33090
+ options2.assertCanMutate?.();
33091
+ this.assertMaintainableSessionUnchanged(sessionId, physicalSnapshot);
33092
+ for (const identity of physicalSnapshot.identities) {
33093
+ this.removeFileIfExists(identity.filePath);
33094
+ this.commitUsageSalvageBestEffort(
33095
+ preparedUsage.get(identity.filePath) ?? null
33096
+ );
32767
33097
  }
32768
- await this.salvageUsageBestEffort(archivedPath);
32769
- this.removeFileIfExists(archivedPath);
33098
+ options2.assertCanMutate?.();
32770
33099
  this.removeWorktreeSidecars(sessionId);
33100
+ options2.assertCanMutate?.();
32771
33101
  this.removePrSidecars(sessionId);
33102
+ options2.assertCanMutate?.();
32772
33103
  this.removePromptLedgers(sessionId);
33104
+ options2.assertCanMutate?.();
32773
33105
  this.removeFileHistoryBackups(sessionId);
32774
33106
  return true;
32775
33107
  } catch (error3) {
33108
+ if (error3 instanceof SessionStorageEntryError && error3.reason === "foreign_project") {
33109
+ return false;
33110
+ }
32776
33111
  if (error3.code === "ENOENT") {
32777
33112
  return false;
32778
33113
  }
@@ -32782,6 +33117,7 @@ ${payload}`, "utf8");
32782
33117
  async archiveSessions(sessionIds, options2 = {}) {
32783
33118
  const archived = [];
32784
33119
  const alreadyArchived = [];
33120
+ const resolvedConflicts = [];
32785
33121
  const notFound = [];
32786
33122
  const errors = [];
32787
33123
  for (const sessionId of [...new Set(sessionIds)]) {
@@ -32790,25 +33126,54 @@ ${payload}`, "utf8");
32790
33126
  notFound.push(sessionId);
32791
33127
  continue;
32792
33128
  }
32793
- if (options2.knownLocation !== "active") {
32794
- const location = await this.getSessionLocation(sessionId);
32795
- if (location === void 0) {
32796
- notFound.push(sessionId);
32797
- continue;
32798
- }
32799
- if (location === "archived") {
32800
- alreadyArchived.push(sessionId);
32801
- continue;
32802
- }
32803
- if (location === "conflict") {
33129
+ const snapshot = await this.resolveMaintainableSessionSnapshot(sessionId);
33130
+ const location = snapshot.location;
33131
+ if (location === void 0) {
33132
+ notFound.push(sessionId);
33133
+ continue;
33134
+ }
33135
+ if (location === "archived") {
33136
+ alreadyArchived.push(sessionId);
33137
+ continue;
33138
+ }
33139
+ if (location === "conflict") {
33140
+ if (!options2.resolveConflicts) {
32804
33141
  throw new Error(`Session archive conflict: ${sessionId}`);
32805
33142
  }
33143
+ const active = snapshot.identities.find(
33144
+ (identity) => identity.state === "active"
33145
+ );
33146
+ await options2.assertStorageUnchanged?.();
33147
+ options2.assertCanMutate?.();
33148
+ this.assertMaintainableSessionUnchanged(sessionId, snapshot);
33149
+ this.removeFileIfExists(active.filePath);
33150
+ try {
33151
+ options2.assertCanMutate?.();
33152
+ await this.movePrSidecar(
33153
+ this.getPrSessionPathForState(sessionId, "active"),
33154
+ this.getPrSessionPathForState(sessionId, "archived"),
33155
+ options2.assertCanMutate
33156
+ );
33157
+ } catch (sidecarError) {
33158
+ options2.assertCanMutate?.();
33159
+ this.warn(
33160
+ `archiveSessions: failed to merge active pr sidecar for ${sessionId}: ${sidecarError}`
33161
+ );
33162
+ }
33163
+ options2.assertCanMutate?.();
33164
+ this.removeFileIfExists(
33165
+ this.getWorktreeSessionPathForState(sessionId, "active")
33166
+ );
33167
+ options2.assertCanMutate?.();
33168
+ this.removeFileIfExists(
33169
+ this.getPromptLedgerPathForState(sessionId, "active")
33170
+ );
33171
+ archived.push(sessionId);
33172
+ resolvedConflicts.push(sessionId);
33173
+ continue;
32806
33174
  }
32807
33175
  const sourcePath = this.getSessionFilePath(sessionId, "active");
32808
33176
  const targetPath = this.getSessionFilePath(sessionId, "archived");
32809
- if (fs11.existsSync(targetPath)) {
32810
- throw new Error(`Session archive conflict: ${sessionId}`);
32811
- }
32812
33177
  fs11.mkdirSync(this.getArchiveChatsDir(), { recursive: true });
32813
33178
  const activeSidecar = this.getWorktreeSessionPathForState(
32814
33179
  sessionId,
@@ -32826,11 +33191,15 @@ ${payload}`, "utf8");
32826
33191
  sessionId,
32827
33192
  "archived"
32828
33193
  );
33194
+ await options2.assertStorageUnchanged?.();
33195
+ options2.assertCanMutate?.();
33196
+ this.assertMaintainableSessionUnchanged(sessionId, snapshot);
32829
33197
  try {
32830
33198
  fs11.renameSync(sourcePath, targetPath);
32831
33199
  } catch (error3) {
32832
33200
  throw this.sessionFileMoveError("archive", error3);
32833
33201
  }
33202
+ options2.assertCanMutate?.();
32834
33203
  try {
32835
33204
  this.moveOptionalFile(activeSidecar, archivedSidecar);
32836
33205
  } catch (sidecarError) {
@@ -32841,56 +33210,100 @@ ${payload}`, "utf8");
32841
33210
  try {
32842
33211
  await this.movePrSidecar(
32843
33212
  this.getPrSessionPathForState(sessionId, "active"),
32844
- this.getPrSessionPathForState(sessionId, "archived")
33213
+ this.getPrSessionPathForState(sessionId, "archived"),
33214
+ options2.assertCanMutate
32845
33215
  );
32846
33216
  } catch (sidecarError) {
33217
+ options2.assertCanMutate?.();
32847
33218
  this.warn(
32848
33219
  `archiveSessions: failed to move pr sidecar for ${sessionId}: ${sidecarError}`
32849
33220
  );
32850
33221
  }
32851
33222
  try {
33223
+ options2.assertCanMutate?.();
32852
33224
  this.moveLedgerSidecar(activeLedger, archivedLedger);
32853
33225
  } catch (ledgerError) {
33226
+ options2.assertCanMutate?.();
32854
33227
  this.warn(
32855
33228
  `archiveSessions: failed to move prompt ledger for ${sessionId} from ${activeLedger} to ${archivedLedger}: ${ledgerError}`
32856
33229
  );
32857
33230
  }
32858
33231
  archived.push(sessionId);
32859
33232
  } catch (error3) {
33233
+ if (error3 instanceof SessionStorageEntryError && error3.reason === "foreign_project") {
33234
+ notFound.push(sessionId);
33235
+ continue;
33236
+ }
32860
33237
  errors.push({
32861
33238
  sessionId,
32862
33239
  error: error3 instanceof Error ? error3 : new Error(String(error3))
32863
33240
  });
32864
33241
  }
32865
33242
  }
32866
- return { archived, alreadyArchived, notFound, errors };
33243
+ return {
33244
+ archived,
33245
+ alreadyArchived,
33246
+ resolvedConflicts,
33247
+ notFound,
33248
+ errors
33249
+ };
32867
33250
  }
32868
33251
  async unarchiveSessions(sessionIds, options2 = {}) {
32869
33252
  const unarchived = [];
32870
33253
  const alreadyActive = [];
33254
+ const resolvedConflicts = [];
32871
33255
  const notFound = [];
32872
33256
  const errors = [];
32873
33257
  for (const sessionId of [...new Set(sessionIds)]) {
32874
33258
  try {
32875
- if (options2.knownLocation !== "archived") {
32876
- const location = await this.getSessionLocation(sessionId);
32877
- if (location === void 0) {
32878
- notFound.push(sessionId);
32879
- continue;
32880
- }
32881
- if (location === "active") {
32882
- alreadyActive.push(sessionId);
32883
- continue;
32884
- }
32885
- if (location === "conflict") {
33259
+ const snapshot = await this.resolveMaintainableSessionSnapshot(sessionId);
33260
+ const location = snapshot.location;
33261
+ if (location === void 0) {
33262
+ notFound.push(sessionId);
33263
+ continue;
33264
+ }
33265
+ if (location === "active") {
33266
+ alreadyActive.push(sessionId);
33267
+ continue;
33268
+ }
33269
+ if (location === "conflict") {
33270
+ if (!options2.resolveConflicts) {
32886
33271
  throw new Error(`Session archive conflict: ${sessionId}`);
32887
33272
  }
33273
+ const archived = snapshot.identities.find(
33274
+ (identity) => identity.state === "archived"
33275
+ );
33276
+ await options2.assertStorageUnchanged?.();
33277
+ options2.assertCanMutate?.();
33278
+ this.assertMaintainableSessionUnchanged(sessionId, snapshot);
33279
+ this.removeFileIfExists(archived.filePath);
33280
+ try {
33281
+ options2.assertCanMutate?.();
33282
+ await this.movePrSidecar(
33283
+ this.getPrSessionPathForState(sessionId, "archived"),
33284
+ this.getPrSessionPathForState(sessionId, "active"),
33285
+ options2.assertCanMutate
33286
+ );
33287
+ } catch (sidecarError) {
33288
+ options2.assertCanMutate?.();
33289
+ this.warn(
33290
+ `unarchiveSessions: failed to merge archived pr sidecar for ${sessionId}: ${sidecarError}`
33291
+ );
33292
+ }
33293
+ options2.assertCanMutate?.();
33294
+ this.removeFileIfExists(
33295
+ this.getWorktreeSessionPathForState(sessionId, "archived")
33296
+ );
33297
+ options2.assertCanMutate?.();
33298
+ this.removeFileIfExists(
33299
+ this.getPromptLedgerPathForState(sessionId, "archived")
33300
+ );
33301
+ unarchived.push(sessionId);
33302
+ resolvedConflicts.push(sessionId);
33303
+ continue;
32888
33304
  }
32889
33305
  const sourcePath = this.getSessionFilePath(sessionId, "archived");
32890
33306
  const targetPath = this.getSessionFilePath(sessionId, "active");
32891
- if (fs11.existsSync(targetPath)) {
32892
- throw new Error(`Session archive conflict: ${sessionId}`);
32893
- }
32894
33307
  const archivedSidecar = this.getWorktreeSessionPathForState(
32895
33308
  sessionId,
32896
33309
  "archived"
@@ -32900,11 +33313,15 @@ ${payload}`, "utf8");
32900
33313
  "active"
32901
33314
  );
32902
33315
  fs11.mkdirSync(path11.dirname(targetPath), { recursive: true });
33316
+ await options2.assertStorageUnchanged?.();
33317
+ options2.assertCanMutate?.();
33318
+ this.assertMaintainableSessionUnchanged(sessionId, snapshot);
32903
33319
  try {
32904
33320
  fs11.renameSync(sourcePath, targetPath);
32905
33321
  } catch (error3) {
32906
33322
  throw this.sessionFileMoveError("unarchive", error3);
32907
33323
  }
33324
+ options2.assertCanMutate?.();
32908
33325
  try {
32909
33326
  this.moveOptionalFile(archivedSidecar, activeSidecar);
32910
33327
  } catch (sidecarError) {
@@ -32915,9 +33332,11 @@ ${payload}`, "utf8");
32915
33332
  try {
32916
33333
  await this.movePrSidecar(
32917
33334
  this.getPrSessionPathForState(sessionId, "archived"),
32918
- this.getPrSessionPathForState(sessionId, "active")
33335
+ this.getPrSessionPathForState(sessionId, "active"),
33336
+ options2.assertCanMutate
32919
33337
  );
32920
33338
  } catch (sidecarError) {
33339
+ options2.assertCanMutate?.();
32921
33340
  this.warn(
32922
33341
  `unarchiveSessions: failed to move pr sidecar for ${sessionId}: ${sidecarError}`
32923
33342
  );
@@ -32931,21 +33350,33 @@ ${payload}`, "utf8");
32931
33350
  "active"
32932
33351
  );
32933
33352
  try {
33353
+ options2.assertCanMutate?.();
32934
33354
  this.moveLedgerSidecar(archivedLedger, activeLedger);
32935
33355
  } catch (ledgerError) {
33356
+ options2.assertCanMutate?.();
32936
33357
  this.warn(
32937
33358
  `unarchiveSessions: failed to move prompt ledger for ${sessionId} from ${archivedLedger} to ${activeLedger}: ${ledgerError}`
32938
33359
  );
32939
33360
  }
32940
33361
  unarchived.push(sessionId);
32941
33362
  } catch (error3) {
33363
+ if (error3 instanceof SessionStorageEntryError && error3.reason === "foreign_project") {
33364
+ notFound.push(sessionId);
33365
+ continue;
33366
+ }
32942
33367
  errors.push({
32943
33368
  sessionId,
32944
33369
  error: error3 instanceof Error ? error3 : new Error(String(error3))
32945
33370
  });
32946
33371
  }
32947
33372
  }
32948
- return { unarchived, alreadyActive, notFound, errors };
33373
+ return {
33374
+ unarchived,
33375
+ alreadyActive,
33376
+ resolvedConflicts,
33377
+ notFound,
33378
+ errors
33379
+ };
32949
33380
  }
32950
33381
  /**
32951
33382
  * Removes multiple sessions in one call.
@@ -33337,6 +33768,29 @@ ${payload}`, "utf8");
33337
33768
  const filePath = path11.join(chatsDir, `${sessionId}.jsonl`);
33338
33769
  return this.readSessionTitleFromFile(filePath);
33339
33770
  }
33771
+ async readSessionDisplayNameFromFile(filePath, titleInfo = this.readSessionTitleInfoFromFile(filePath)) {
33772
+ const records = await readLines(
33773
+ filePath,
33774
+ titleInfo.title ? 1 : MAX_PROMPT_SCAN_LINES
33775
+ );
33776
+ if (records.length === 0) return void 0;
33777
+ if (!await this.sessionBelongsToCurrentProject(
33778
+ records[0].sessionId,
33779
+ records[0].cwd
33780
+ )) {
33781
+ return void 0;
33782
+ }
33783
+ return titleInfo.title || this.extractFirstPromptFromRecords(records) || void 0;
33784
+ }
33785
+ async getSessionDisplayName(sessionId) {
33786
+ if (!SESSION_FILE_PATTERN.test(`${sessionId}.jsonl`)) return void 0;
33787
+ const filePath = path11.join(this.getChatsDir(), `${sessionId}.jsonl`);
33788
+ try {
33789
+ return await this.readSessionDisplayNameFromFile(filePath);
33790
+ } catch {
33791
+ return void 0;
33792
+ }
33793
+ }
33340
33794
  /**
33341
33795
  * Finds sessions by custom title.
33342
33796
  * Returns all matching sessions ordered by most recent first.
@@ -33409,15 +33863,14 @@ ${payload}`, "utf8");
33409
33863
  return matches;
33410
33864
  }
33411
33865
  /**
33412
- * Returns the customTitles in this project that start with `prefix`
33866
+ * Returns the picker display names in this project that start with `prefix`
33413
33867
  * (case-insensitive). Single project-wide scan — meant to replace
33414
33868
  * repeated `findSessionsByTitle()` probes when the caller needs to
33415
- * pick the first free `(Branch N)` slot in memory.
33869
+ * pick the first free numeric suffix in memory.
33416
33870
  *
33417
- * Skips the heavy hydration steps (message count, prompt extraction)
33418
- * that `findSessionsByTitle` does — collision lookup only needs the
33419
- * title and a project filter, so we read the first record only when
33420
- * the title actually matches the prefix.
33871
+ * Matches the session picker by preferring `customTitle` and falling back
33872
+ * to the first prompt. Each untitled candidate performs one head read
33873
+ * bounded by `MAX_PROMPT_SCAN_LINES`; other metadata stays unhydrated.
33421
33874
  *
33422
33875
  * @param prefix Case-insensitive title prefix to match.
33423
33876
  */
@@ -33441,23 +33894,22 @@ ${payload}`, "utf8");
33441
33894
  filesProcessed++;
33442
33895
  const filePath = path11.join(chatsDir, name);
33443
33896
  const titleInfo = this.readSessionTitleInfoFromFile(filePath);
33444
- if (!titleInfo.title) continue;
33445
- if (!titleInfo.title.toLowerCase().trim().startsWith(normalizedPrefix)) {
33897
+ if (titleInfo.title && !titleInfo.title.toLowerCase().trim().startsWith(normalizedPrefix)) {
33446
33898
  continue;
33447
33899
  }
33448
33900
  try {
33449
- const records = await readLines(filePath, 1);
33450
- if (records.length === 0) continue;
33451
- if (!await this.sessionBelongsToCurrentProject(
33452
- records[0].sessionId,
33453
- records[0].cwd
33454
- )) {
33901
+ const displayName = await this.readSessionDisplayNameFromFile(
33902
+ filePath,
33903
+ titleInfo
33904
+ );
33905
+ if (!displayName) continue;
33906
+ if (!displayName.toLowerCase().trim().startsWith(normalizedPrefix)) {
33455
33907
  continue;
33456
33908
  }
33909
+ titles.push(displayName);
33457
33910
  } catch {
33458
33911
  continue;
33459
33912
  }
33460
- titles.push(titleInfo.title);
33461
33913
  }
33462
33914
  return titles;
33463
33915
  }
@@ -33650,24 +34102,25 @@ function replayUiTelemetryFromConversation(conversation, sessionId) {
33650
34102
  return resumeTokenCounts;
33651
34103
  }
33652
34104
  __name(replayUiTelemetryFromConversation, "replayUiTelemetryFromConversation");
33653
- var MAX_BRANCH_COLLISION_SCAN = 99;
33654
34105
  async function computeUniqueBranchTitle(baseName, sessionService) {
33655
- const maxSuffixLen = " (Branch 1234567890123)".length;
34106
+ const maxSuffixLen = "(1234567890123)".length;
33656
34107
  const trimmed = baseName.trim().slice(0, SESSION_TITLE_MAX_LENGTH - maxSuffixLen);
33657
34108
  const taken = new Set(
33658
- (await sessionService.findSessionTitlesByPrefix(`${trimmed} (Branch`)).map(
34109
+ (await sessionService.findSessionTitlesByPrefix(`${trimmed}(`)).map(
33659
34110
  (t) => t.toLowerCase().trim()
33660
34111
  )
33661
34112
  );
33662
- const first = `${trimmed} (Branch)`;
33663
- if (!taken.has(first.toLowerCase())) return first;
33664
- for (let n = 2; n <= MAX_BRANCH_COLLISION_SCAN; n++) {
33665
- const candidate = `${trimmed} (Branch ${n})`;
34113
+ for (let n = 1; ; n++) {
34114
+ const candidate = `${trimmed}(${n})`;
33666
34115
  if (!taken.has(candidate.toLowerCase())) return candidate;
33667
34116
  }
33668
- return `${trimmed} (Branch ${Date.now()})`;
33669
34117
  }
33670
34118
  __name(computeUniqueBranchTitle, "computeUniqueBranchTitle");
34119
+ function normalizeDerivedBranchTitle(baseName) {
34120
+ const normalized = baseName.trim().replace(/\s*\(Branch(?:\s+\d+)?\)$/, "").replace(/(\S)\(\d+\)$/, "$1").trim();
34121
+ return normalized || void 0;
34122
+ }
34123
+ __name(normalizeDerivedBranchTitle, "normalizeDerivedBranchTitle");
33671
34124
 
33672
34125
  // packages/core/src/services/sessionTitle.ts
33673
34126
  var debugLogger16 = createDebugLogger("SESSION_TITLE");
@@ -38951,11 +39404,12 @@ var GeminiChat = class {
38951
39404
  */
38952
39405
  async tryCompress(promptId, force = false, signal, options2) {
38953
39406
  this.adoptTokenCountsForRoute(options2?.requestRouteKey);
38954
- const originalTokenCountIsEstimated = options2?.originalTokenCountOverride === void 0 && this.promptCountIsEstimateDerived();
38955
- const originalTokenCount = originalTokenCountIsEstimated ? options2?.precomputedEffectiveTokens ?? estimateContentTokens(
39407
+ const originalTokenCountOverride = options2?.originalTokenCountOverride;
39408
+ const originalTokenCountIsEstimated = originalTokenCountOverride !== void 0 ? originalTokenCountOverride.isEstimated : options2?.precomputedEffectiveTokens !== void 0 || this.promptCountIsEstimateDerived();
39409
+ const originalTokenCount = originalTokenCountOverride !== void 0 ? originalTokenCountOverride.count : originalTokenCountIsEstimated ? options2?.precomputedEffectiveTokens ?? estimateContentTokens(
38956
39410
  options2?.pendingUserMessage ? [...this.getHistoryShallow(true), options2.pendingUserMessage] : this.getHistoryShallow(true),
38957
39411
  resolveSlimmingConfig(this.config.getChatCompression()).imageTokenEstimate
38958
- ) : options2?.originalTokenCountOverride ?? this.lastPromptTokenCount;
39412
+ ) : this.lastPromptTokenCount;
38959
39413
  debugLogger21.debug(
38960
39414
  `[compaction] token-count provenance: prompt_id=${promptId}, originalTokenCount=${originalTokenCount}, estimated=${originalTokenCountIsEstimated}`
38961
39415
  );
@@ -38973,6 +39427,7 @@ var GeminiChat = class {
38973
39427
  customInstructions: options2?.customInstructions,
38974
39428
  signal
38975
39429
  });
39430
+ info.originalTokenCountIsEstimated = originalTokenCountIsEstimated;
38976
39431
  this.adoptTokenCountsForRoute(options2?.requestRouteKey);
38977
39432
  if (info.compressionStatus === 1 /* COMPRESSED */ && newHistory) {
38978
39433
  info.newTokenCountIsEstimated ??= true;
@@ -39039,6 +39494,7 @@ var GeminiChat = class {
39039
39494
  info: {
39040
39495
  originalTokenCount: apiBaseline2,
39041
39496
  newTokenCount: apiBaseline2,
39497
+ originalTokenCountIsEstimated: this.promptCountIsEstimateDerived(),
39042
39498
  compressionStatus: 5 /* NOOP */
39043
39499
  }
39044
39500
  };
@@ -39053,6 +39509,7 @@ var GeminiChat = class {
39053
39509
  const info = {
39054
39510
  originalTokenCount: apiBaseline,
39055
39511
  newTokenCount: adjustedTokenCount,
39512
+ originalTokenCountIsEstimated: baselineIsEstimated,
39056
39513
  newTokenCountIsEstimated: true,
39057
39514
  compressionStatus: 1 /* COMPRESSED */,
39058
39515
  triggerReason: "manual"
@@ -39642,6 +40099,7 @@ var GeminiChat = class {
39642
40099
  if (contextOverflow.isExceeded) {
39643
40100
  if (!exactRoute && !reactiveCompressionAttempted) {
39644
40101
  reactiveCompressionAttempted = true;
40102
+ const reactiveOriginalTokenCountIsEstimated = contextOverflow.actualTokens === void 0;
39645
40103
  const reactiveOriginalTokenCount = contextOverflow.actualTokens ?? contextOverflow.limitTokens ?? cgConfig?.contextWindowSize ?? DEFAULT_TOKEN_LIMIT;
39646
40104
  debugLogger21.warn(
39647
40105
  "Context length exceeded; attempting reactive compression."
@@ -39652,7 +40110,10 @@ var GeminiChat = class {
39652
40110
  true,
39653
40111
  params.config?.abortSignal,
39654
40112
  {
39655
- originalTokenCountOverride: reactiveOriginalTokenCount,
40113
+ originalTokenCountOverride: {
40114
+ count: reactiveOriginalTokenCount,
40115
+ isEstimated: reactiveOriginalTokenCountIsEstimated
40116
+ },
39656
40117
  precomputedEffectiveTokens: reactiveOriginalTokenCount,
39657
40118
  requestGenerationConfig: params.config,
39658
40119
  requestRouteKey,
@@ -43127,6 +43588,91 @@ var TOOL_NAME_ALIASES = {
43127
43588
  monitor: "monitor",
43128
43589
  Monitor: "monitor",
43129
43590
  MonitorTool: "monitor",
43591
+ // Send Message tool (teams)
43592
+ send_message: "send_message",
43593
+ SendMessage: "send_message",
43594
+ SendMessageTool: "send_message",
43595
+ // Goal tools — the display name of get_goal is "Goal" (see ToolDisplayNames)
43596
+ get_goal: "get_goal",
43597
+ Goal: "get_goal",
43598
+ GetGoal: "get_goal",
43599
+ update_goal: "update_goal",
43600
+ UpdateGoal: "update_goal",
43601
+ UpdateGoalTool: "update_goal",
43602
+ // Save Memory tool
43603
+ save_memory: "save_memory",
43604
+ SaveMemory: "save_memory",
43605
+ SaveMemoryTool: "save_memory",
43606
+ // Ask User Question tool
43607
+ ask_user_question: "ask_user_question",
43608
+ AskUserQuestion: "ask_user_question",
43609
+ AskUserQuestionTool: "ask_user_question",
43610
+ // Cron tools
43611
+ cron_create: "cron_create",
43612
+ CronCreate: "cron_create",
43613
+ cron_list: "cron_list",
43614
+ CronList: "cron_list",
43615
+ cron_delete: "cron_delete",
43616
+ CronDelete: "cron_delete",
43617
+ // Loop wakeup tool
43618
+ loop_wakeup: "loop_wakeup",
43619
+ LoopWakeup: "loop_wakeup",
43620
+ LoopWakeupTool: "loop_wakeup",
43621
+ // Create Sub Session tool
43622
+ create_sub_session: "create_sub_session",
43623
+ CreateSubSession: "create_sub_session",
43624
+ CreateSubSessionTool: "create_sub_session",
43625
+ // List Agents tool
43626
+ list_agents: "list_agents",
43627
+ ListAgents: "list_agents",
43628
+ ListAgentsTool: "list_agents",
43629
+ // Task lifecycle tools (teams)
43630
+ task_stop: "task_stop",
43631
+ TaskStop: "task_stop",
43632
+ task_create: "task_create",
43633
+ TaskCreate: "task_create",
43634
+ task_update: "task_update",
43635
+ TaskUpdate: "task_update",
43636
+ task_list: "task_list",
43637
+ TaskList: "task_list",
43638
+ // Team tools
43639
+ team_create: "team_create",
43640
+ TeamCreate: "team_create",
43641
+ team_delete: "team_delete",
43642
+ TeamDelete: "team_delete",
43643
+ team_plan_approval: "team_plan_approval",
43644
+ TeamPlanApproval: "team_plan_approval",
43645
+ // Image generation tool
43646
+ image_gen: "image_gen",
43647
+ ImageGen: "image_gen",
43648
+ ImageGenTool: "image_gen",
43649
+ // Tool search tool
43650
+ tool_search: "tool_search",
43651
+ ToolSearch: "tool_search",
43652
+ ToolSearchTool: "tool_search",
43653
+ // Structured output (synthetic --json-schema contract)
43654
+ structured_output: "structured_output",
43655
+ StructuredOutput: "structured_output",
43656
+ // Worktree tools
43657
+ enter_worktree: "enter_worktree",
43658
+ EnterWorktree: "enter_worktree",
43659
+ exit_worktree: "exit_worktree",
43660
+ ExitWorktree: "exit_worktree",
43661
+ // Workflow / artifact tools
43662
+ workflow: "workflow",
43663
+ Workflow: "workflow",
43664
+ artifact: "artifact",
43665
+ Artifact: "artifact",
43666
+ record_artifact: "record_artifact",
43667
+ RecordArtifact: "record_artifact",
43668
+ // Report Findings tool
43669
+ report_findings: "report_findings",
43670
+ ReportFindings: "report_findings",
43671
+ request_shutdown: "request_shutdown",
43672
+ RequestShutdown: "request_shutdown",
43673
+ // Display image tool
43674
+ display_image: "display_image",
43675
+ DisplayImage: "display_image",
43130
43676
  // Legacy edit tool name
43131
43677
  replace: "edit"
43132
43678
  };
@@ -63192,8 +63738,26 @@ var CoreToolScheduler = class {
63192
63738
  const matchingRule = pm.findMatchingDenyRule({
63193
63739
  toolName: canonicalName
63194
63740
  });
63195
- const ruleInfo = matchingRule ? ` Matching deny rule: "${matchingRule}".` : "";
63196
- const permissionErrorMessage = `Qwen Code requires permission to use "${reqInfo.name}", but that permission was declined.${ruleInfo}`;
63741
+ let permissionErrorMessage;
63742
+ if (matchingRule) {
63743
+ permissionErrorMessage = `Qwen Code requires permission to use "${reqInfo.name}", but that permission was declined. Matching deny rule: "${matchingRule}".`;
63744
+ } else if (pm.isPermissionsAllowListActive() && // Only attribute the miss to `permissions.allow` when the tool
63745
+ // is genuinely uncovered. While the allowlist is active a
63746
+ // COVERED tool can still be rejected by a different gate —
63747
+ // e.g. the legacy `coreTools` (`--core-tools` / `tools.core`)
63748
+ // allowlist — and there the "add a permissions.allow rule"
63749
+ // advice is factually wrong and a no-op (#9827). The optional
63750
+ // call keeps scoped PermissionManager shims (installed via
63751
+ // `as unknown as PermissionManager`, e.g.
63752
+ // memory-scoped-agent-config.ts) from throwing until they grow
63753
+ // the delegation; when coverage is unknown the fallback stays
63754
+ // on the pre-#9827 message rather than risk the wrong
63755
+ // attribution (#9827).
63756
+ (typeof pm.isCoveredByAllowOrAskRule === "function" ? !pm.isCoveredByAllowOrAskRule(canonicalName) : false)) {
63757
+ permissionErrorMessage = `"${reqInfo.name}" is not covered by any permissions.allow rule in the active registry allowlist, so the tool is not available. Add a rule covering it to settings permissions.allow (or permissions.ask) and restart to re-enable it.`;
63758
+ } else {
63759
+ permissionErrorMessage = `Qwen Code requires permission to use "${reqInfo.name}", but that permission was declined.`;
63760
+ }
63197
63761
  newToolCalls.push({
63198
63762
  status: "error",
63199
63763
  request: reqInfo,
@@ -79831,6 +80395,14 @@ function createMemoryScopedAgentConfig(config3, projectRoot, options2 = {}) {
79831
80395
  return basePm.isToolEnabled(toolName);
79832
80396
  }
79833
80397
  return true;
80398
+ },
80399
+ // The scheduler's permission-denied message branch calls this on
80400
+ // whatever `getPermissionManager()` returns (#9827). Without the
80401
+ // delegation a shim-rejected call under an active allowlist threw
80402
+ // `TypeError: ... is not a function` instead of reaching the
80403
+ // designed permission error.
80404
+ isPermissionsAllowListActive() {
80405
+ return basePm?.isPermissionsAllowListActive() ?? false;
79834
80406
  }
79835
80407
  };
79836
80408
  const scopedConfig = Object.create(config3);
@@ -81977,6 +82549,14 @@ function createSkillScopedAgentConfig(config3, projectRoot) {
81977
82549
  if (isScopedTool2(toolName)) return true;
81978
82550
  if (basePm) return basePm.isToolEnabled(toolName);
81979
82551
  return true;
82552
+ },
82553
+ // The scheduler's permission-denied message branch calls this on
82554
+ // whatever `getPermissionManager()` returns (#9827). Without the
82555
+ // delegation a shim-rejected call under an active allowlist threw
82556
+ // `TypeError: ... is not a function` instead of reaching the
82557
+ // designed permission error.
82558
+ isPermissionsAllowListActive() {
82559
+ return basePm?.isPermissionsAllowListActive() ?? false;
81980
82560
  }
81981
82561
  };
81982
82562
  const scopedConfig = Object.create(config3);
@@ -83476,6 +84056,13 @@ var GeminiClient = class _GeminiClient {
83476
84056
  }
83477
84057
  chat;
83478
84058
  initializedSessionId;
84059
+ /**
84060
+ * Open session-swap telemetry transaction, if any. See
84061
+ * {@link beginTelemetrySwap} for the lifetime contract. Holds the undo for
84062
+ * the replay the current swap's `initialize()` performed, armed by
84063
+ * {@link armTelemetrySwapUndo} inside the replay branches.
84064
+ */
84065
+ telemetrySwap;
83479
84066
  sessionTurnCount = 0;
83480
84067
  toolCallCount = 0;
83481
84068
  skillsModifiedInSession = false;
@@ -83572,6 +84159,7 @@ var GeminiClient = class _GeminiClient {
83572
84159
  const resumedSessionData = this.config.getResumedSessionData();
83573
84160
  const restoreRuntime = this.config.getSessionRestoreRuntime?.();
83574
84161
  if (restoreRuntime) {
84162
+ this.armTelemetrySwapUndo(sessionId);
83575
84163
  uiTelemetryService.resetSession(sessionId);
83576
84164
  for (const event of restoreRuntime.uiTelemetryEvents) {
83577
84165
  uiTelemetryService.addEvent(event, sessionId);
@@ -83596,6 +84184,7 @@ var GeminiClient = class _GeminiClient {
83596
84184
  );
83597
84185
  }
83598
84186
  } else if (resumedSessionData) {
84187
+ this.armTelemetrySwapUndo(sessionId);
83599
84188
  const resumeTokenCounts = replayUiTelemetryFromConversation(
83600
84189
  resumedSessionData.conversation,
83601
84190
  this.config.getSessionId()
@@ -83664,6 +84253,140 @@ var GeminiClient = class _GeminiClient {
83664
84253
  isInitialized() {
83665
84254
  return this.chat !== void 0;
83666
84255
  }
84256
+ /**
84257
+ * Opens a session-swap telemetry transaction for the `/resume` / `/branch`
84258
+ * hooks (#9833).
84259
+ *
84260
+ * Lifetime contract: one call per swap attempt, closed by exactly one
84261
+ * {@link commitTelemetrySwap} (the UI swap committed — the replayed history
84262
+ * now belongs to the session the user is on) or
84263
+ * {@link abortTelemetrySwap} (the swap failed and core rolled back — put
84264
+ * the usage aggregate back). The undo is armed lazily by
84265
+ * {@link armTelemetrySwapUndo} inside `initialize()`'s replay branches, so
84266
+ * it is scoped to the ONE replay this swap performs:
84267
+ *
84268
+ * - A replay outside any transaction (process-startup `Config.initialize()`,
84269
+ * ACP) arms nothing — there is no owning swap to settle it, and a
84270
+ * process-lived undo would let a much later failed swap restore a
84271
+ * process-start snapshot and wipe everything accrued since.
84272
+ * - `initialize()` only replays when its private `initializedSessionId`
84273
+ * differs from the config session id. The hooks cannot see that fact, so
84274
+ * the snapshot is taken here, inside the replay decision, never keyed on
84275
+ * a caller's guess.
84276
+ *
84277
+ * Serialization: returns false WITHOUT opening when a transaction is
84278
+ * already open. Callers MUST abort the swap attempt on a false return
84279
+ * (the hooks surface "a session switch is already in progress"). Two
84280
+ * concurrent swaps cannot share this single slot: the second open would
84281
+ * no-op while both replays mutate the same aggregate, so the first swap's
84282
+ * stale settlement would either no-op or restore its snapshot over the
84283
+ * second swap's committed state — the double-count / split-brain this
84284
+ * transaction exists to close. Nothing else serializes the swaps: the
84285
+ * session picker fires them fire-and-forget and no input gate covers
84286
+ * them, so this slot is the latch.
84287
+ */
84288
+ beginTelemetrySwap() {
84289
+ if (this.telemetrySwap) {
84290
+ if (debugLogger59.isEnabled()) {
84291
+ debugLogger59.debug(
84292
+ "[TELEMETRY_SWAP_BEGIN] rejected: a swap is already in progress"
84293
+ );
84294
+ }
84295
+ return false;
84296
+ }
84297
+ this.telemetrySwap = { outgoingHint: this.config.getSessionId() };
84298
+ return true;
84299
+ }
84300
+ /**
84301
+ * The swap committed: drop the armed undo without restoring. The replayed
84302
+ * history legitimately belongs to the session the user is now on, and a
84303
+ * later failed swap must restore ITS OWN pre-swap snapshot, never this one.
84304
+ * Safe to call with no transaction open (no-op).
84305
+ */
84306
+ commitTelemetrySwap() {
84307
+ const undo = this.telemetrySwap?.undo;
84308
+ this.telemetrySwap = void 0;
84309
+ if (debugLogger59.isEnabled()) {
84310
+ debugLogger59.debug(
84311
+ `[TELEMETRY_SWAP_COMMIT] undo=${undo ? "dropped" : "none"} incoming=${undo?.sessionId ?? "n/a"}`
84312
+ );
84313
+ }
84314
+ }
84315
+ /**
84316
+ * The swap failed and core rolled back: restore the usage aggregate (and
84317
+ * the two affected session buckets) to the state captured before this
84318
+ * swap's replay. Overwrites rather than subtracts, so it stays correct
84319
+ * when the rollback's own re-`initialize()` (the `/branch` and `/resume`
84320
+ * paths) has already replayed something else on top.
84321
+ *
84322
+ * Also forgets `initializedSessionId` when it still names the abandoned
84323
+ * INCOMING session: undoing the replay without forgetting it would make a
84324
+ * retry early-return and never replay, permanently under-counting the
84325
+ * session. The clear is an identity check, not the assumption that the
84326
+ * undo always names the incoming session — when the swap's forward
84327
+ * `initialize()` never ran (e.g. `/branch` fails between
84328
+ * `startNewSession(fork)` and `initialize()`), the rollback's own
84329
+ * re-initialize arms the undo with the PARENT's id and sets
84330
+ * `initializedSessionId` to it. That session is live and correctly
84331
+ * initialized; clearing it would make the next `initialize()` of the
84332
+ * session the user is already on skip the early return and re-replay its
84333
+ * stored telemetry on top of the live aggregate — a permanent
84334
+ * double-count. The undo belongs to the outgoing session's own
84335
+ * re-initialize exactly when `undo.sessionId` matches the begin-time
84336
+ * `outgoingHint` (#9844 review).
84337
+ *
84338
+ * Safe to call with no transaction open or nothing armed (no-op). Returns
84339
+ * whether an undo was applied.
84340
+ */
84341
+ abortTelemetrySwap() {
84342
+ const swap = this.telemetrySwap;
84343
+ this.telemetrySwap = void 0;
84344
+ if (debugLogger59.isEnabled()) {
84345
+ debugLogger59.debug(
84346
+ `[TELEMETRY_SWAP_ABORT] undo=${swap?.undo ? "applied" : "none"} incoming=${swap?.undo?.sessionId ?? "n/a"} outgoing=${swap?.undo?.snapshot.outgoingSessionId ?? "n/a"}`
84347
+ );
84348
+ }
84349
+ if (!swap?.undo) return false;
84350
+ uiTelemetryService.restoreFromReplaySnapshot(swap.undo.snapshot);
84351
+ if (swap.undo.sessionId !== swap.outgoingHint && this.initializedSessionId === swap.undo.sessionId) {
84352
+ this.initializedSessionId = void 0;
84353
+ }
84354
+ return true;
84355
+ }
84356
+ /**
84357
+ * Arms the undo for the replay the current `initialize()` call is about to
84358
+ * perform. Called only by the replay branches; a fresh-start `initialize()`
84359
+ * replays nothing, and an undo armed there would outlive the transaction.
84360
+ *
84361
+ * `??=` on the undo: within one swap only the FIRST replay's pre-state is
84362
+ * the correct restore point — on the `/branch` rollback the re-initialize
84363
+ * of the parent runs while the failed swap's undo is still outstanding.
84364
+ * No-ops when no transaction is open (replay outside a swap).
84365
+ *
84366
+ * The snapshot also covers the session the process is currently on — the
84367
+ * one a failed swap rolls back to. That is the transaction's
84368
+ * `outgoingHint`, captured at open time, NOT `initializedSessionId`: an
84369
+ * earlier failed swap's abort clears `initializedSessionId`, so keying on
84370
+ * it would snapshot no outgoing bucket and the rollback's re-initialize
84371
+ * would wipe the live session's never-persisted state. The `/branch`
84372
+ * rollback re-initializes that session, and the re-initialize's
84373
+ * `resetSession` wipes its live bucket — only what the transcript persists
84374
+ * comes back (skill invocations never do), so the undo must put the
84375
+ * captured bucket back.
84376
+ */
84377
+ armTelemetrySwapUndo(sessionId) {
84378
+ if (!this.telemetrySwap || this.telemetrySwap.undo) return;
84379
+ const outgoing = this.telemetrySwap.outgoingHint ?? this.initializedSessionId;
84380
+ this.telemetrySwap.undo = {
84381
+ sessionId,
84382
+ snapshot: uiTelemetryService.snapshotForReplay(sessionId, outgoing)
84383
+ };
84384
+ if (debugLogger59.isEnabled()) {
84385
+ debugLogger59.debug(
84386
+ `[TELEMETRY_SWAP_ARM] incoming=${sessionId} outgoing=${outgoing ?? "n/a"}`
84387
+ );
84388
+ }
84389
+ }
83667
84390
  getHistory(curated = false) {
83668
84391
  return this.getChat().getHistory(curated);
83669
84392
  }
@@ -117737,7 +118460,7 @@ var HybridTokenStorage = class extends BaseTokenStorage {
117737
118460
  const forceFileStorage = process.env[FORCE_FILE_STORAGE_ENV_VAR] === "true";
117738
118461
  if (!forceFileStorage) {
117739
118462
  try {
117740
- const { KeychainTokenStorage: KeychainTokenStorage2 } = await import("./keychain-token-storage-LQTBIXSX.js");
118463
+ const { KeychainTokenStorage: KeychainTokenStorage2 } = await import("./keychain-token-storage-3MGFRYGM.js");
117741
118464
  const keychainStorage = new KeychainTokenStorage2(this.serviceName);
117742
118465
  const isAvailable = await keychainStorage.isAvailable();
117743
118466
  if (isAvailable) {
@@ -122963,11 +123686,21 @@ var ToolRegistry = class _ToolRegistry {
122963
123686
  }
122964
123687
  }
122965
123688
  }
123689
+ const permissionManager = this.config.getPermissionManager?.();
122966
123690
  for (const func of functions) {
122967
123691
  if (!func.name) {
122968
123692
  debugLogger75.warn("Discovered a tool with no name. Skipping.");
122969
123693
  continue;
122970
123694
  }
123695
+ if (permissionManager) {
123696
+ const toolEnabled = await permissionManager.isToolEnabled(func.name);
123697
+ if (!toolEnabled) {
123698
+ debugLogger75.info(
123699
+ `Discovered tool "${func.name}" skipped: not enabled by the permission manager (permissions.allow registry allowlist or whole-tool deny rule, #9827).`
123700
+ );
123701
+ continue;
123702
+ }
123703
+ }
122971
123704
  const parameters = func.parametersJsonSchema && typeof func.parametersJsonSchema === "object" && !Array.isArray(func.parametersJsonSchema) ? func.parametersJsonSchema : {};
122972
123705
  this.registerTool(
122973
123706
  new DiscoveredTool(
@@ -126548,6 +127281,59 @@ var PermissionManager = class _PermissionManager {
126548
127281
  * Populated during `initialize()` from `config.getCoreTools()`.
126549
127282
  */
126550
127283
  coreToolsAllowList = null;
127284
+ /**
127285
+ * Whether the `permissions.allow` registry allowlist is active.
127286
+ *
127287
+ * Snapshotted once in `initialize()`: the allowlist activates only when
127288
+ * `settings.permissions.allow` (exposed via `getRegistryAllowList()`)
127289
+ * contains at least one VALID rule. Pure auto-approval sources —
127290
+ * `--allowed-tools`, the SDK `allowedTools` param, the legacy
127291
+ * `tools.allowed` key — deliberately do NOT activate it; they keep their
127292
+ * documented "bypass the confirmation dialog" semantics (#9827).
127293
+ *
127294
+ * Activation is not re-evaluated later: rules granted mid-session
127295
+ * ("Always allow", skill `allowedTools`, `/permissions` writes) extend
127296
+ * allowlist MEMBERSHIP but must never activate the allowlist under a
127297
+ * running session, or approving one tool would suddenly
127298
+ * permission-error every tool not on the list. Registry composition is
127299
+ * a startup decision, consistent with the "Requires restart" semantics
127300
+ * of the other tool-availability settings.
127301
+ */
127302
+ permissionsAllowListActive = false;
127303
+ /**
127304
+ * Frozen snapshot of the allow rules in force at startup, captured at
127305
+ * the end of `initialize()`.
127306
+ *
127307
+ * Registry membership must be monotonic within a session: activation and
127308
+ * registration are snapshotted at startup ("Requires restart"), so
127309
+ * REMOVING an allow rule mid-session — `/permissions` →
127310
+ * `removePersistentRule`, or a `qwen serve` settings edit →
127311
+ * `syncLivePermissionManagers` — must not hard-block a tool that was
127312
+ * legitimately registered (it is still listed in `/tools` and its schema
127313
+ * is still sent to the model; blocking every call with EXECUTION_DENIED
127314
+ * until restart contradicts the restart-scoped contract). Removals take
127315
+ * effect at restart; membership is the union of this frozen startup set
127316
+ * and the live rule set, so mid-session GRANTS still extend coverage
127317
+ * (#9827).
127318
+ */
127319
+ startupAllowRules = [];
127320
+ /**
127321
+ * Frozen snapshot of the ask rules in force at startup.
127322
+ *
127323
+ * Ask rules count toward registry-allowlist membership: a tool the user
127324
+ * configured to always be prompted for must stay usable, so "always ask"
127325
+ * must not silently become "unregistered" whenever an allowlist is
127326
+ * active (#9827). Membership is monotonic within the session for the
127327
+ * same reason as `startupAllowRules`: removing an ask rule mid-session
127328
+ * must not deregister a tool that was legitimately registered.
127329
+ */
127330
+ startupAskRules = [];
127331
+ /**
127332
+ * Set once the restart caveat for session allow-rule grants under an
127333
+ * active registry allowlist has been logged, so repeated skill
127334
+ * `allowedTools` grants do not pile identical warnings into the log.
127335
+ */
127336
+ sessionGrantAllowlistCaveatLogged = false;
126551
127337
  /**
126552
127338
  * Initialise from the config's permission parameters.
126553
127339
  * Must be called once before any rule lookups.
@@ -126570,6 +127356,11 @@ var PermissionManager = class _PermissionManager {
126570
127356
  if (this.config.getApprovalMode?.() === "auto") {
126571
127357
  this.stripDangerousRulesForAutoMode();
126572
127358
  }
127359
+ this.permissionsAllowListActive = parseRules(
127360
+ this.config.getRegistryAllowList?.() ?? []
127361
+ ).some((rule) => !rule.invalid);
127362
+ this.startupAllowRules = this.getEffectiveAllowRules();
127363
+ this.startupAskRules = this.getEffectiveAskRules();
126573
127364
  }
126574
127365
  // ---------------------------------------------------------------------------
126575
127366
  // Core evaluation
@@ -126848,6 +127639,21 @@ var PermissionManager = class _PermissionManager {
126848
127639
  "create_sub_session",
126849
127640
  "monitor"
126850
127641
  ]);
127642
+ /**
127643
+ * Synthetic plan-mode lifecycle tools that must stay registered even under
127644
+ * an active `permissions.allow` registry allowlist. The plan-mode system
127645
+ * reminder instructs the model to present its plan by calling
127646
+ * `exit_plan_mode`, and `enter_plan_mode` / `ask_user_question` are the
127647
+ * sanctioned plan-flow entry and clarification tools; dropping their
127648
+ * schemas makes the plan flow impossible to complete (#9827). They belong
127649
+ * to the same exemption class as `structured_output` and the "synthetic
127650
+ * system tools" the CORE_TOOLS docstring names — deny rules still apply.
127651
+ */
127652
+ static PLAN_LIFECYCLE_TOOLS = /* @__PURE__ */ new Set([
127653
+ ToolNames.EXIT_PLAN_MODE,
127654
+ ToolNames.ENTER_PLAN_MODE,
127655
+ ToolNames.ASK_USER_QUESTION
127656
+ ]);
126851
127657
  /**
126852
127658
  * Check if a tool is a core tool subject to the coreTools allowlist check.
126853
127659
  */
@@ -126857,17 +127663,35 @@ var PermissionManager = class _PermissionManager {
126857
127663
  /**
126858
127664
  * Determine whether a tool should be present in the tool registry.
126859
127665
  *
126860
- * A tool is disabled (returns false) when a `deny` rule without a specifier
126861
- * (i.e. a whole-tool deny) matches. Specifier-based deny rules such as
126862
- * `"Bash(rm -rf *)"` do NOT remove the tool from the registry – they only
126863
- * deny specific invocations at runtime.
127666
+ * A tool is disabled (returns false) when:
127667
+ * - the `permissions.allow` registry allowlist is active and the tool is
127668
+ * not covered by any allow or ask rule (see
127669
+ * `isPermissionsAllowListActive`; ask rules keep their tool registered
127670
+ * so "always require confirmation" never silently becomes "tool
127671
+ * unavailable"), or
127672
+ * - a `deny` rule without a specifier (i.e. a whole-tool deny) matches.
127673
+ *
127674
+ * Specifier-based deny rules such as `"Bash(rm -rf *)"` do NOT remove the
127675
+ * tool from the registry – they only deny specific invocations at runtime.
127676
+ * Likewise, specifier-based allow rules such as `"Bash(npm test)"` DO keep
127677
+ * the tool in the registry — the allowlist is tool-level, not
127678
+ * invocation-level.
126864
127679
  *
126865
127680
  * Non-core tools (MCP, Skill, Agent, etc.) skip the coreTools allowlist
126866
127681
  * check because they are dynamically discovered or essential for system
126867
- * operation.
127682
+ * operation, but they ARE subject to the `permissions.allow` registry
127683
+ * allowlist (except MCP tools, `structured_output`, and the
127684
+ * `computer_use__*` family, see below) — that is the documented migration
127685
+ * semantic of the legacy `tools.core` whitelist ("unlisted tools are
127686
+ * disabled at registry level") and the only way to keep e.g.
127687
+ * `send_message` / `update_goal` schemas out of the model request
127688
+ * (#9827).
126868
127689
  */
126869
127690
  async isToolEnabled(toolName) {
126870
127691
  const canonicalName = resolveToolName(toolName);
127692
+ if (this.permissionsAllowListActive && canonicalName !== ToolNames.STRUCTURED_OUTPUT && !_PermissionManager.PLAN_LIFECYCLE_TOOLS.has(canonicalName) && canonicalName !== ToolNames.TASK_STOP && canonicalName !== ToolNames.TOOL_SEARCH && !canonicalName.startsWith("mcp__") && !canonicalName.startsWith("computer_use__") && !this.isCoveredByAllowOrAskRule(canonicalName)) {
127693
+ return false;
127694
+ }
126871
127695
  if (!this.isCoreTool(canonicalName)) {
126872
127696
  const decision2 = await this.evaluate({ toolName: canonicalName });
126873
127697
  return decision2 !== "deny";
@@ -126880,6 +127704,74 @@ var PermissionManager = class _PermissionManager {
126880
127704
  const decision = await this.evaluate({ toolName: canonicalName });
126881
127705
  return decision !== "deny";
126882
127706
  }
127707
+ /**
127708
+ * Whether the `permissions.allow` registry allowlist is active for this
127709
+ * session. See the `permissionsAllowListActive` field for the activation
127710
+ * contract (snapshot at `initialize()`, restart-scoped).
127711
+ */
127712
+ isPermissionsAllowListActive() {
127713
+ return this.permissionsAllowListActive;
127714
+ }
127715
+ /**
127716
+ * All allow rules currently in force: persistent + session + any rules
127717
+ * the AUTO-mode strip moved to the stash (they are configured rules,
127718
+ * merely suspended for runtime auto-approval purposes).
127719
+ */
127720
+ getEffectiveAllowRules() {
127721
+ return [
127722
+ ...this.sessionRules.allow,
127723
+ ...this.persistentRules.allow,
127724
+ ...this.strippedAllowRules?.session ?? [],
127725
+ ...this.strippedAllowRules?.persistent ?? []
127726
+ ];
127727
+ }
127728
+ /**
127729
+ * All ask rules currently in force: persistent + session. AUTO mode
127730
+ * strips only allow rules (the stash in `strippedAllowRules`), so ask
127731
+ * rules are never suspended and no stash applies here.
127732
+ */
127733
+ getEffectiveAskRules() {
127734
+ return [...this.sessionRules.ask, ...this.persistentRules.ask];
127735
+ }
127736
+ /**
127737
+ * Registry-membership check for the `permissions.allow` allowlist: true
127738
+ * when any in-force allow OR ask rule mentions the tool. Ask rules count
127739
+ * because they express "this tool must stay usable, with confirmation" —
127740
+ * a tool covered only by an ask rule must not be silently deregistered
127741
+ * whenever an allowlist is active, or the documented "always require
127742
+ * user confirmation" would become "tool unavailable" and the ask rule
127743
+ * could never fire (#9827). Tool-name matching is specifier-agnostic
127744
+ * (`Bash(npm test)` keeps `run_shell_command` registered) and honours
127745
+ * meta-categories (`Read` covers grep/glob/..., `Bash` covers monitor)
127746
+ * via `toolMatchesRuleToolName`.
127747
+ *
127748
+ * Membership is monotonic within the session: the union of the frozen
127749
+ * startup rule sets (`startupAllowRules` / `startupAskRules`) and the
127750
+ * live rule sets. Removing a STARTUP rule mid-session therefore never
127751
+ * deregisters an already-registered tool (removals take effect at
127752
+ * restart, matching the documented "Requires restart" contract), while
127753
+ * rules granted mid-session — skill `allowedTools`, "Always allow",
127754
+ * `/permissions` writes — extend membership live even though they can
127755
+ * never ACTIVATE the allowlist (#9827).
127756
+ *
127757
+ * Caveat: extending membership flips this runtime predicate only. A
127758
+ * mid-session grant can never RESTORE a tool that the startup allowlist
127759
+ * skipped at REGISTRATION — the registry is built once in
127760
+ * `Config.initialize` and `ensureTool` returns undefined for factories
127761
+ * that were never stored, so such a call still fails TOOL_NOT_REGISTERED
127762
+ * until the rule is added to settings `permissions.allow` and the
127763
+ * session restarts (#9827).
127764
+ *
127765
+ * Public so the scheduler can tell an allowlist miss (tool genuinely
127766
+ * uncovered) apart from a rejection by a different gate — e.g. the
127767
+ * legacy `coreTools` allowlist — for a tool that IS covered, where
127768
+ * "add a permissions.allow rule" advice would be a no-op (#9827).
127769
+ */
127770
+ isCoveredByAllowOrAskRule(toolName) {
127771
+ const canonicalName = resolveToolName(toolName);
127772
+ const covered = /* @__PURE__ */ __name((rule) => !rule.invalid && toolMatchesRuleToolName(rule.toolName, canonicalName), "covered");
127773
+ return this.startupAllowRules.some(covered) || this.getEffectiveAllowRules().some(covered) || this.startupAskRules.some(covered) || this.getEffectiveAskRules().some(covered);
127774
+ }
126883
127775
  /**
126884
127776
  * Find the first deny rule that matches the given context.
126885
127777
  * Returns the raw rule string if found, or undefined if no deny rule matches.
@@ -127128,6 +128020,12 @@ var PermissionManager = class _PermissionManager {
127128
128020
  * Add a session-level allow rule (in-memory, cleared when the session ends).
127129
128021
  * Used when the user clicks "Always allow for this session".
127130
128022
  *
128023
+ * Under an active `permissions.allow` registry allowlist the grant
128024
+ * auto-approves matching calls and extends allowlist MEMBERSHIP, but it
128025
+ * cannot REGISTER a tool the startup allowlist skipped — registry
128026
+ * composition is restart-scoped. The first such grant logs a caveat
128027
+ * pointing at the restart path (#9827).
128028
+ *
127131
128029
  * @param raw - The raw rule string, e.g. "Bash(git status)".
127132
128030
  */
127133
128031
  addSessionAllowRule(raw) {
@@ -127139,6 +128037,12 @@ var PermissionManager = class _PermissionManager {
127139
128037
  );
127140
128038
  return;
127141
128039
  }
128040
+ if (this.permissionsAllowListActive && !this.sessionGrantAllowlistCaveatLogged) {
128041
+ this.sessionGrantAllowlistCaveatLogged = true;
128042
+ debugLogger81.warn(
128043
+ "Session allow rule granted while the permissions.allow registry allowlist is active: the grant auto-approves matching calls, but it cannot register a tool the startup allowlist skipped at registration \u2014 an unavailable tool stays unavailable until the rule is added to settings permissions.allow and the session restarts (#9827)."
128044
+ );
128045
+ }
127142
128046
  if (this.strippedAllowRules && isDangerousAllowRule(rule)) {
127143
128047
  const exists2 = this.strippedAllowRules.session.some(
127144
128048
  (r) => r.raw === rule.raw
@@ -130383,7 +131287,7 @@ var FileReadCache = class _FileReadCache {
130383
131287
  init_esbuild_shims();
130384
131288
  import * as fs70 from "node:fs";
130385
131289
  import * as path68 from "node:path";
130386
- import * as os19 from "node:os";
131290
+ import * as os20 from "node:os";
130387
131291
 
130388
131292
  // packages/core/src/extension/variables.ts
130389
131293
  init_esbuild_shims();
@@ -130626,7 +131530,7 @@ __name(resolveEnvVarsInObjectInternal, "resolveEnvVarsInObjectInternal");
130626
131530
  // packages/core/src/extension/github.ts
130627
131531
  init_esbuild_shims();
130628
131532
  import * as crypto6 from "node:crypto";
130629
- import * as os18 from "node:os";
131533
+ import * as os19 from "node:os";
130630
131534
  import * as https2 from "node:https";
130631
131535
  import * as fs62 from "node:fs";
130632
131536
  import * as path61 from "node:path";
@@ -135939,6 +136843,110 @@ async function prepareStoredGitCredentialDeletion(extensionDir) {
135939
136843
  }
135940
136844
  __name(prepareStoredGitCredentialDeletion, "prepareStoredGitCredentialDeletion");
135941
136845
 
136846
+ // packages/core/src/extension/extension-git-client.ts
136847
+ init_esbuild_shims();
136848
+ import * as os18 from "node:os";
136849
+ function assertCredentialedHttpsSource(source) {
136850
+ try {
136851
+ const parsed = new URL(source);
136852
+ if (parsed.protocol === "https:" && !parsed.username && !parsed.password && parsed.href === source) {
136853
+ return;
136854
+ }
136855
+ } catch {
136856
+ }
136857
+ throw new Error(
136858
+ "Credentialed Git operations require a valid HTTPS repository URL."
136859
+ );
136860
+ }
136861
+ __name(assertCredentialedHttpsSource, "assertCredentialedHttpsSource");
136862
+ var generatedConfigKeyAllowances = [
136863
+ [/alias/, "allowUnsafeAlias"],
136864
+ [/core.askpass/, "allowUnsafeAskPass"],
136865
+ [/core.editor/, "allowUnsafeEditor"],
136866
+ [/core.fsmonitor/, "allowUnsafeFsMonitor"],
136867
+ [/core.gitproxy/, "allowUnsafeGitProxy"],
136868
+ [/core.hookspath/, "allowUnsafeHooksPath"],
136869
+ [/core.pager/, "allowUnsafePager"],
136870
+ [/core.sshcommand/, "allowUnsafeSshCommand"],
136871
+ [/credential(..+)?.helper/, "allowUnsafeCredentialHelper"],
136872
+ [/diff(..+)?.command/, "allowUnsafeDiffExternal"],
136873
+ [/diff.external/, "allowUnsafeDiffExternal"],
136874
+ [/diff(..+)?.textconv/, "allowUnsafeDiffTextConv"],
136875
+ [/filter(..+)?.clean/, "allowUnsafeFilter"],
136876
+ [/filter(..+)?.smudge/, "allowUnsafeFilter"],
136877
+ [/gpg(..+)?.program/, "allowUnsafeGpgProgram"],
136878
+ [/init.templatedir/, "allowUnsafeTemplateDir"],
136879
+ [/merge(..+)?.driver/, "allowUnsafeMergeDriver"],
136880
+ [/mergetool(..+)?.path/, "allowUnsafeMergeDriver"],
136881
+ [/mergetool(..+)?.cmd/, "allowUnsafeMergeDriver"],
136882
+ [/protocol(..+)?.allow/, "allowUnsafeProtocolOverride"],
136883
+ [/remote(..+)?.receivepack/, "allowUnsafePack"],
136884
+ [/remote(..+)?.uploadpack/, "allowUnsafePack"],
136885
+ [/sequence.editor/, "allowUnsafeEditor"]
136886
+ ];
136887
+ function allowGeneratedConfigKeyFalsePositives(unsafe, key) {
136888
+ const normalizedKey = key.toLowerCase().trim();
136889
+ for (const [pattern, category] of generatedConfigKeyAllowances) {
136890
+ if (pattern.test(normalizedKey)) {
136891
+ unsafe[category] = true;
136892
+ }
136893
+ }
136894
+ }
136895
+ __name(allowGeneratedConfigKeyFalsePositives, "allowGeneratedConfigKeyFalsePositives");
136896
+ function createExtensionGitClient(simpleGit, {
136897
+ baseDir,
136898
+ signal,
136899
+ networkPolicy,
136900
+ networkConfig = [],
136901
+ authentication
136902
+ }) {
136903
+ if (authentication) assertCredentialedHttpsSource(authentication.source);
136904
+ const restrictEnvironment = networkPolicy === "public" || authentication !== void 0;
136905
+ const hasNetworkConfig = networkConfig.length > 0;
136906
+ const unsafe = {};
136907
+ if (restrictEnvironment) unsafe.allowUnsafeConfigPaths = true;
136908
+ if (hasNetworkConfig) unsafe.allowUnsafeProtocolOverride = true;
136909
+ const credentialConfigKey = authentication ? `http.${authentication.source}.extraHeader` : void 0;
136910
+ if (credentialConfigKey) {
136911
+ unsafe.allowUnsafeConfigEnvCount = true;
136912
+ allowGeneratedConfigKeyFalsePositives(unsafe, credentialConfigKey);
136913
+ }
136914
+ const git = simpleGit(baseDir, {
136915
+ ...signal ? { abort: signal } : {},
136916
+ ...hasNetworkConfig ? { config: networkConfig } : {},
136917
+ ...restrictEnvironment || hasNetworkConfig ? { unsafe } : {}
136918
+ });
136919
+ if (!restrictEnvironment) return git;
136920
+ const environment = {
136921
+ GIT_CONFIG_NOSYSTEM: "1",
136922
+ GIT_CONFIG_GLOBAL: os18.devNull
136923
+ };
136924
+ for (const key of [
136925
+ "PATH",
136926
+ "Path",
136927
+ "SystemRoot",
136928
+ "SYSTEMROOT",
136929
+ "WINDIR",
136930
+ "TEMP",
136931
+ "TMP",
136932
+ "TMPDIR"
136933
+ ]) {
136934
+ const value = process.env[key];
136935
+ if (value !== void 0) environment[key] = value;
136936
+ }
136937
+ if (authentication && credentialConfigKey) {
136938
+ const value = Buffer.from(
136939
+ `${authentication.credential.username}:${authentication.credential.password}`,
136940
+ "utf8"
136941
+ ).toString("base64");
136942
+ environment["GIT_CONFIG_COUNT"] = "1";
136943
+ environment["GIT_CONFIG_KEY_0"] = credentialConfigKey;
136944
+ environment["GIT_CONFIG_VALUE_0"] = `Authorization: Basic ${value}`;
136945
+ }
136946
+ return git.env(environment);
136947
+ }
136948
+ __name(createExtensionGitClient, "createExtensionGitClient");
136949
+
135942
136950
  // packages/core/src/extension/github.ts
135943
136951
  var debugLogger90 = createDebugLogger("EXT_GITHUB");
135944
136952
  var SUPPORTED_ARCHIVE_EXTENSIONS = [".tar.gz", ".zip"];
@@ -136045,40 +137053,18 @@ function createPinnedGitConfig(curlResolve) {
136045
137053
  ];
136046
137054
  }
136047
137055
  __name(createPinnedGitConfig, "createPinnedGitConfig");
136048
- function restrictGitEnvironment(git, networkPolicy, authentication) {
136049
- if (networkPolicy !== "public" && !authentication) return git;
136050
- const environment = {
136051
- GIT_CONFIG_NOSYSTEM: "1",
136052
- GIT_CONFIG_GLOBAL: os18.devNull
136053
- };
136054
- for (const key of [
136055
- "PATH",
136056
- "Path",
136057
- "SystemRoot",
136058
- "SYSTEMROOT",
136059
- "WINDIR",
136060
- "TEMP",
136061
- "TMP",
136062
- "TMPDIR"
136063
- ]) {
136064
- const value = process.env[key];
136065
- if (value !== void 0) environment[key] = value;
136066
- }
136067
- if (authentication) {
136068
- const value = Buffer.from(
136069
- `${authentication.credential.username}:${authentication.credential.password}`,
136070
- "utf8"
136071
- ).toString("base64");
136072
- environment["GIT_CONFIG_COUNT"] = "1";
136073
- environment["GIT_CONFIG_KEY_0"] = `http.${authentication.source}.extraHeader`;
136074
- environment["GIT_CONFIG_VALUE_0"] = `Authorization: Basic ${value}`;
137056
+ function resolveGitRef(ref) {
137057
+ const resolvedRef = ref || "HEAD";
137058
+ if (resolvedRef.startsWith("-")) {
137059
+ throw new Error('Git refs must not start with "-".');
136075
137060
  }
136076
- return git.env(environment);
137061
+ return resolvedRef;
136077
137062
  }
136078
- __name(restrictGitEnvironment, "restrictGitEnvironment");
137063
+ __name(resolveGitRef, "resolveGitRef");
136079
137064
  async function cloneFromGit(installMetadata, destination, signal, credential, hideSource = false) {
136080
137065
  const redactedSource = hideSource ? "credentialed HTTPS Git source" : redactUrlCredentials(installMetadata.source);
136081
137066
  try {
137067
+ const refToFetch = resolveGitRef(installMetadata.ref);
136082
137068
  const { simpleGit } = await loadSimpleGit();
136083
137069
  let networkConfig = [];
136084
137070
  if (installMetadata.networkPolicy === "public") {
@@ -136094,22 +137080,15 @@ async function cloneFromGit(installMetadata, destination, signal, credential, hi
136094
137080
  networkConfig = networkTarget.curlResolve ? createPinnedGitConfig(networkTarget.curlResolve) : [];
136095
137081
  }
136096
137082
  const effectiveCredential = credential ?? getGitHubCredential(installMetadata.source);
136097
- const git = restrictGitEnvironment(
136098
- simpleGit(destination, {
136099
- ...signal ? { abort: signal } : {},
136100
- ...networkConfig.length > 0 ? {
136101
- config: networkConfig,
136102
- unsafe: {
136103
- allowUnsafeConfigPaths: true,
136104
- allowUnsafeProtocolOverride: true
136105
- }
136106
- } : {}
136107
- }),
136108
- installMetadata.networkPolicy,
136109
- effectiveCredential ? { source: installMetadata.source, credential: effectiveCredential } : void 0
136110
- );
137083
+ const git = createExtensionGitClient(simpleGit, {
137084
+ baseDir: destination,
137085
+ signal,
137086
+ networkPolicy: installMetadata.networkPolicy,
137087
+ networkConfig,
137088
+ authentication: effectiveCredential ? { source: installMetadata.source, credential: effectiveCredential } : void 0
137089
+ });
136111
137090
  signal?.throwIfAborted();
136112
- const symlinkValue = os18.platform() === "win32" ? "false" : "true";
137091
+ const symlinkValue = os19.platform() === "win32" ? "false" : "true";
136113
137092
  await git.clone(installMetadata.source, "./", [
136114
137093
  "-c",
136115
137094
  `core.symlinks=${symlinkValue}`,
@@ -136121,7 +137100,6 @@ async function cloneFromGit(installMetadata, destination, signal, credential, hi
136121
137100
  if (remotes.length === 0) {
136122
137101
  throw new Error(`Unable to find any remotes for repo ${redactedSource}`);
136123
137102
  }
136124
- const refToFetch = installMetadata.ref || "HEAD";
136125
137103
  const remoteUrl = remotes[0].refs.fetch;
136126
137104
  if (!remoteUrl) {
136127
137105
  throw new Error(`Unable to find a fetch URL for repo ${redactedSource}`);
@@ -136319,7 +137297,7 @@ async function checkForExtensionUpdate(extension, extensionManager, signal) {
136319
137297
  let extensionDir = installMetadata.source;
136320
137298
  if (isSupportedArchivePath(installMetadata.source)) {
136321
137299
  tempDir = await fs62.promises.mkdtemp(
136322
- path61.join(os18.tmpdir(), "extension-archive-update-")
137300
+ path61.join(os19.tmpdir(), "extension-archive-update-")
136323
137301
  );
136324
137302
  signal?.throwIfAborted();
136325
137303
  await extractArchiveFile(installMetadata.source, tempDir, signal);
@@ -136376,7 +137354,7 @@ async function checkForExtensionUpdate(extension, extensionManager, signal) {
136376
137354
  let convertedDir;
136377
137355
  try {
136378
137356
  tempDir = await fs62.promises.mkdtemp(
136379
- path61.join(os18.tmpdir(), "extension-archive-update-")
137357
+ path61.join(os19.tmpdir(), "extension-archive-update-")
136380
137358
  );
136381
137359
  await downloadFromArchiveUrl(installMetadata, tempDir, signal);
136382
137360
  const converted = await convertCompatibleExtension(
@@ -136425,6 +137403,7 @@ async function checkForExtensionUpdate(extension, extensionManager, signal) {
136425
137403
  }
136426
137404
  try {
136427
137405
  if (installMetadata.type === "git") {
137406
+ const refToCheck = resolveGitRef(installMetadata.ref);
136428
137407
  const storedCredential = installMetadata.credentialPersistence === "stored" ? (await resolveStoredGitCredential(extension.path)).credential : void 0;
136429
137408
  if (await shouldUsePublicGitHubArchiveFallback(installMetadata)) {
136430
137409
  if (!installMetadata.gitCommit) {
@@ -136436,7 +137415,7 @@ async function checkForExtensionUpdate(extension, extensionManager, signal) {
136436
137415
  const remoteSha = await resolvePublicGitHubCommitSha(
136437
137416
  owner,
136438
137417
  repo,
136439
- installMetadata.ref || "HEAD",
137418
+ refToCheck,
136440
137419
  signal
136441
137420
  );
136442
137421
  return remoteSha === installMetadata.gitCommit ? "up to date" /* UP_TO_DATE */ : "update available" /* UPDATE_AVAILABLE */;
@@ -136488,21 +137467,13 @@ async function checkForExtensionUpdate(extension, extensionManager, signal) {
136488
137467
  }
136489
137468
  signal?.throwIfAborted();
136490
137469
  const effectiveCredential = storedCredential ?? getGitHubCredential(remoteUrl);
136491
- const git = restrictGitEnvironment(
136492
- simpleGit(extension.path, {
136493
- ...signal ? { abort: signal } : {},
136494
- ...networkConfig.length > 0 ? {
136495
- config: networkConfig,
136496
- unsafe: {
136497
- allowUnsafeConfigPaths: true,
136498
- allowUnsafeProtocolOverride: true
136499
- }
136500
- } : {}
136501
- }),
136502
- installMetadata.networkPolicy,
136503
- effectiveCredential ? { source: remoteUrl, credential: effectiveCredential } : void 0
136504
- );
136505
- const refToCheck = installMetadata.ref || "HEAD";
137470
+ const git = createExtensionGitClient(simpleGit, {
137471
+ baseDir: extension.path,
137472
+ signal,
137473
+ networkPolicy: installMetadata.networkPolicy,
137474
+ networkConfig,
137475
+ authentication: effectiveCredential ? { source: remoteUrl, credential: effectiveCredential } : void 0
137476
+ });
136506
137477
  const refPatterns = installMetadata.ref ? [refToCheck, `${refToCheck}^{}`] : [refToCheck];
136507
137478
  const lsRemoteOutput = await git.listRemote([remoteUrl, ...refPatterns]);
136508
137479
  signal?.throwIfAborted();
@@ -136678,8 +137649,8 @@ async function extractArchiveFile(archivePath, destination, signal, options2 = {
136678
137649
  }
136679
137650
  __name(extractArchiveFile, "extractArchiveFile");
136680
137651
  function findReleaseAsset(assets) {
136681
- const platform2 = os18.platform();
136682
- const arch2 = os18.arch();
137652
+ const platform2 = os19.platform();
137653
+ const arch2 = os19.arch();
136683
137654
  const platformArchPrefix = `${platform2}.${arch2}.`;
136684
137655
  const platformPrefix = `${platform2}.`;
136685
137656
  const platformArchAsset = assets.find(
@@ -140070,7 +141041,7 @@ var ExtensionManager = class _ExtensionManager {
140070
141041
  "enabled"
140071
141042
  );
140072
141043
  } else {
140073
- const scopePath = os19.homedir();
141044
+ const scopePath = os20.homedir();
140074
141045
  snapshot = await this.extensionStore.setLegacyPathActivation(
140075
141046
  { id: extension.id, name: extension.name },
140076
141047
  scopePath,
@@ -140112,7 +141083,7 @@ var ExtensionManager = class _ExtensionManager {
140112
141083
  "disabled"
140113
141084
  );
140114
141085
  } else {
140115
- const scopePath = os19.homedir();
141086
+ const scopePath = os20.homedir();
140116
141087
  snapshot = await this.extensionStore.setLegacyPathActivation(
140117
141088
  { id: extension.id, name: extension.name },
140118
141089
  scopePath,
@@ -152257,6 +153228,7 @@ var Config = class _Config {
152257
153228
  permissionsAllow;
152258
153229
  permissionsAsk;
152259
153230
  permissionsDeny;
153231
+ permissionsRegistryAllowList;
152260
153232
  permissionsAutoMode;
152261
153233
  toolDiscoveryCommand;
152262
153234
  toolCallCommand;
@@ -152564,6 +153536,7 @@ var Config = class _Config {
152564
153536
  this.permissionsAllow = params.permissions?.allow || [];
152565
153537
  this.permissionsAsk = params.permissions?.ask || [];
152566
153538
  this.permissionsDeny = params.permissions?.deny || [];
153539
+ this.permissionsRegistryAllowList = params.permissions?.registryAllowList || [];
152567
153540
  this.permissionsAutoMode = params.permissions?.autoMode ?? {};
152568
153541
  this.toolInvocationGuard = params.toolInvocationGuard;
152569
153542
  this.toolDiscoveryCommand = params.toolDiscoveryCommand;
@@ -154969,6 +155942,16 @@ var Config = class _Config {
154969
155942
  getPermissionsAsk() {
154970
155943
  return this.permissionsAsk;
154971
155944
  }
155945
+ /**
155946
+ * Returns the allow rules that come from `settings.permissions.allow`
155947
+ * only — never `--allowed-tools` / the SDK `allowedTools` param (merged
155948
+ * into `getPermissionsAllow()` above) nor the legacy `tools.allowed`
155949
+ * key. Consumed by `PermissionManager` to decide whether the
155950
+ * registry-level allowlist is active (#9827).
155951
+ */
155952
+ getRegistryAllowList() {
155953
+ return this.permissionsRegistryAllowList;
155954
+ }
154972
155955
  /**
154973
155956
  * Returns the merged deny-rules for PermissionManager.
154974
155957
  *
@@ -156107,17 +157090,42 @@ var Config = class _Config {
156107
157090
  }
156108
157091
  /**
156109
157092
  * Whether the built-in `list_directory` tool is enabled. Opt-in: the tool
156110
- * is disabled by default and turns on either through the
156111
- * `tools.listDirectory.enabled` setting or by being explicitly listed in
156112
- * the `coreTools` allowlist. Entries are normalised with `parseRule` — the
156113
- * same parser `PermissionManager` uses to build its allowlist — so alias
156114
- * forms (`ListFiles`) and specifier forms (`list_directory(/src)`) match.
157093
+ * is disabled by default and turns on through the
157094
+ * `tools.listDirectory.enabled` setting, by being explicitly listed in the
157095
+ * `coreTools` allowlist, or by being covered by an allow OR ask rule while
157096
+ * the `permissions.allow` registry allowlist is active (#9827). Coverage
157097
+ * scans the merged allow set (`getPermissionsAllow()` — settings +
157098
+ * `--allowed-tools` + SDK `allowedTools` + legacy `tools.allowed`) so it
157099
+ * counts exactly what `PermissionManager.isToolEnabled()` counts, while
157100
+ * activation still comes only from `settings.permissions.allow` rules
157101
+ * (`getRegistryAllowList()`), ignoring empty/whitespace-only entries the
157102
+ * same way `PermissionManager.initialize`'s `parseRules` does (and
157103
+ * skipping non-string entries, which settings load never type-validates).
157104
+ * Entries are
157105
+ * normalised with `parseRule` — the same parser `PermissionManager` uses —
157106
+ * so alias forms (`ListFiles`) and specifier forms (`list_directory(/src)`)
157107
+ * match; the check honours meta-categories (`Read`) via
157108
+ * `toolMatchesRuleToolName`, matching the coverage semantics of the
157109
+ * registry gate itself (`isCoveredByAllowOrAskRule`, which counts ask
157110
+ * rules too).
156115
157111
  */
156116
157112
  isLsToolEnabled() {
156117
157113
  if (this.lsToolEnabled) return true;
156118
- return this.getCoreTools()?.some(
157114
+ if (this.getCoreTools()?.some(
156119
157115
  (name) => parseRule(name).toolName === ToolNames.LS
156120
- ) ?? false;
157116
+ ) ?? false) {
157117
+ return true;
157118
+ }
157119
+ const coveredByPermissionRule = /* @__PURE__ */ __name((raw) => {
157120
+ if (typeof raw !== "string" || raw.trim() === "") return false;
157121
+ const rule = parseRule(raw);
157122
+ return !rule.invalid && toolMatchesRuleToolName(rule.toolName, ToolNames.LS);
157123
+ }, "coveredByPermissionRule");
157124
+ const allowListActive = this.getRegistryAllowList().some(
157125
+ (raw) => typeof raw === "string" && raw.trim() !== "" && !parseRule(raw).invalid
157126
+ );
157127
+ if (!allowListActive) return false;
157128
+ return this.getPermissionsAllow().some(coveredByPermissionRule) || this.getPermissionsAsk().some(coveredByPermissionRule);
156121
157129
  }
156122
157130
  isAgentTeamEnabled() {
156123
157131
  if (process10.env["QWEN_CODE_ENABLE_AGENT_TEAM"] === "1") return true;
@@ -157212,6 +158220,11 @@ var Config = class _Config {
157212
158220
  * skills, user/project file commands, MCP prompts). Called by the CLI's
157213
158221
  * CommandService after initialisation so that the startup snapshot and
157214
158222
  * per-turn drain can include these in the `<available_skills>` listing.
158223
+ *
158224
+ * Unlike `disabledSkillNamesProvider`, late attachment (after
158225
+ * `Config.initialize()` has warmed the tool registry) is supported:
158226
+ * `SkillTool.validateToolParams` consults this provider live rather than
158227
+ * relying on its construction-time snapshot (issue #9821).
157215
158228
  */
157216
158229
  setModelInvocableCommandsProvider(provider) {
157217
158230
  this.modelInvocableCommandsProvider = provider;
@@ -157290,7 +158303,7 @@ var Config = class _Config {
157290
158303
  }
157291
158304
  if (!enabled) return;
157292
158305
  registry3.registerFactory(ToolNames.IMAGE_GEN, async () => {
157293
- const { ImageGenTool } = await import("./image-gen-RYOBEDNB.js");
158306
+ const { ImageGenTool } = await import("./image-gen-63NN2H5N.js");
157294
158307
  return new ImageGenTool(this);
157295
158308
  });
157296
158309
  }
@@ -157320,36 +158333,36 @@ var Config = class _Config {
157320
158333
  if (options2?.forSubAgent) return;
157321
158334
  const schema = this.jsonSchema;
157322
158335
  await registerLazy(ToolNames.STRUCTURED_OUTPUT, async () => {
157323
- const { SyntheticOutputTool } = await import("./syntheticOutput-3ITPRJOB.js");
158336
+ const { SyntheticOutputTool } = await import("./syntheticOutput-5AJ444QT.js");
157324
158337
  return new SyntheticOutputTool(schema);
157325
158338
  });
157326
158339
  }, "registerStructuredOutputIfRequested");
157327
158340
  const registerGoalWorkerTools = /* @__PURE__ */ __name(async () => {
157328
158341
  if (options2?.forSubAgent) return;
157329
158342
  await registerLazy(ToolNames.GET_GOAL, async () => {
157330
- const { GetGoalTool } = await import("./goal-tools-FTDQHRRX.js");
158343
+ const { GetGoalTool } = await import("./goal-tools-CNVXMSZD.js");
157331
158344
  return new GetGoalTool(this);
157332
158345
  });
157333
158346
  await registerLazy(ToolNames.UPDATE_GOAL, async () => {
157334
- const { UpdateGoalTool } = await import("./goal-tools-FTDQHRRX.js");
158347
+ const { UpdateGoalTool } = await import("./goal-tools-CNVXMSZD.js");
157335
158348
  return new UpdateGoalTool(this);
157336
158349
  });
157337
158350
  }, "registerGoalWorkerTools");
157338
158351
  if (this.getBareMode()) {
157339
158352
  await registerLazy(ToolNames.READ_FILE, async () => {
157340
- const { ReadFileTool } = await import("./read-file-T7ESVJAQ.js");
158353
+ const { ReadFileTool } = await import("./read-file-N3E5DY7N.js");
157341
158354
  return new ReadFileTool(this);
157342
158355
  });
157343
158356
  await registerLazy(ToolNames.EDIT, async () => {
157344
- const { EditTool } = await import("./edit-4MZYBPF5.js");
158357
+ const { EditTool } = await import("./edit-KSPVUEAS.js");
157345
158358
  return new EditTool(this);
157346
158359
  });
157347
158360
  await registerLazy(ToolNames.NOTEBOOK_EDIT, async () => {
157348
- const { NotebookEditTool } = await import("./notebook-edit-TGU7XHIO.js");
158361
+ const { NotebookEditTool } = await import("./notebook-edit-4ANFZON5.js");
157349
158362
  return new NotebookEditTool(this);
157350
158363
  });
157351
158364
  await registerLazy(ToolNames.SHELL, async () => {
157352
- const { ShellTool: ShellTool2 } = await import("./shell-IJYC4BVX.js");
158365
+ const { ShellTool: ShellTool2 } = await import("./shell-LZ55AAJB.js");
157353
158366
  return new ShellTool2(this);
157354
158367
  });
157355
158368
  await registerGoalWorkerTools();
@@ -157361,45 +158374,45 @@ var Config = class _Config {
157361
158374
  }
157362
158375
  await registerGoalWorkerTools();
157363
158376
  await registerLazy(ToolNames.TOOL_SEARCH, async () => {
157364
- const { ToolSearchTool } = await import("./tool-search-TQNHT22X.js");
158377
+ const { ToolSearchTool } = await import("./tool-search-SV35UV72.js");
157365
158378
  return new ToolSearchTool(this);
157366
158379
  });
157367
158380
  await registerLazy(ToolNames.READ_MCP_RESOURCE, async () => {
157368
- const { ReadMcpResourceTool } = await import("./read-mcp-resource-5QGBDZ43.js");
158381
+ const { ReadMcpResourceTool } = await import("./read-mcp-resource-7A7NFSFL.js");
157369
158382
  return new ReadMcpResourceTool(this);
157370
158383
  });
157371
158384
  await registerLazy(ToolNames.AGENT, async () => {
157372
- const { AgentTool: AgentTool2 } = await import("./agent-TQ6CYOIL.js");
158385
+ const { AgentTool: AgentTool2 } = await import("./agent-7U6CC5KF.js");
157373
158386
  return new AgentTool2(this);
157374
158387
  });
157375
158388
  await registerLazy(ToolNames.LIST_AGENTS, async () => {
157376
- const { ListAgentsTool } = await import("./list-agents-522ILPAR.js");
158389
+ const { ListAgentsTool } = await import("./list-agents-EXRSHIDJ.js");
157377
158390
  return new ListAgentsTool(this);
157378
158391
  });
157379
158392
  await registerLazy(ToolNames.TASK_STOP, async () => {
157380
- const { TaskStopTool } = await import("./task-stop-I2CQSMDX.js");
158393
+ const { TaskStopTool } = await import("./task-stop-U3S3KZG2.js");
157381
158394
  return new TaskStopTool(this);
157382
158395
  });
157383
158396
  await registerLazy(ToolNames.SEND_MESSAGE, async () => {
157384
- const { SendMessageTool } = await import("./send-message-EJUCEIKN.js");
158397
+ const { SendMessageTool } = await import("./send-message-A2GXDX3B.js");
157385
158398
  return new SendMessageTool(this);
157386
158399
  });
157387
158400
  await registerLazy(ToolNames.SKILL, async () => {
157388
- const { SkillTool } = await import("./skill-RTZU743G.js");
158401
+ const { SkillTool } = await import("./skill-WSZ53D2R.js");
157389
158402
  return new SkillTool(this);
157390
158403
  });
157391
158404
  if (this.isLsToolEnabled()) {
157392
158405
  await registerLazy(ToolNames.LS, async () => {
157393
- const { LSTool } = await import("./ls-FUCLEBTL.js");
158406
+ const { LSTool } = await import("./ls-WFONAND2.js");
157394
158407
  return new LSTool(this);
157395
158408
  });
157396
158409
  }
157397
158410
  await registerLazy(ToolNames.READ_FILE, async () => {
157398
- const { ReadFileTool } = await import("./read-file-T7ESVJAQ.js");
158411
+ const { ReadFileTool } = await import("./read-file-N3E5DY7N.js");
157399
158412
  return new ReadFileTool(this);
157400
158413
  });
157401
158414
  await registerLazy(ToolNames.ZOOM_IMAGE, async () => {
157402
- const { ZoomImageTool } = await import("./zoom-image-TCBO2YL5.js");
158415
+ const { ZoomImageTool } = await import("./zoom-image-NYJPC3NI.js");
157403
158416
  return new ZoomImageTool(this);
157404
158417
  });
157405
158418
  if (this.getUseRipgrep()) {
@@ -157414,7 +158427,7 @@ var Config = class _Config {
157414
158427
  recordStartupEvent("config_initialize_ripgrep_probe_end");
157415
158428
  if (useRipgrep) {
157416
158429
  await registerLazy(ToolNames.GREP, async () => {
157417
- const { RipGrepTool } = await import("./ripGrep-KOP6AHIX.js");
158430
+ const { RipGrepTool } = await import("./ripGrep-NEIHKBKB.js");
157418
158431
  return new RipGrepTool(this);
157419
158432
  });
157420
158433
  } else {
@@ -157427,7 +158440,7 @@ var Config = class _Config {
157427
158440
  )
157428
158441
  );
157429
158442
  await registerLazy(ToolNames.GREP, async () => {
157430
- const { GrepTool } = await import("./grep-QUQ3J6SR.js");
158443
+ const { GrepTool } = await import("./grep-3NLSS32D.js");
157431
158444
  return new GrepTool(this);
157432
158445
  });
157433
158446
  }
@@ -157435,77 +158448,81 @@ var Config = class _Config {
157435
158448
  recordStartupEvent("config_initialize_ripgrep_probe_start");
157436
158449
  recordStartupEvent("config_initialize_ripgrep_probe_end");
157437
158450
  await registerLazy(ToolNames.GREP, async () => {
157438
- const { GrepTool } = await import("./grep-QUQ3J6SR.js");
158451
+ const { GrepTool } = await import("./grep-3NLSS32D.js");
157439
158452
  return new GrepTool(this);
157440
158453
  });
157441
158454
  }
157442
158455
  await registerLazy(ToolNames.GLOB, async () => {
157443
- const { GlobTool } = await import("./glob-TWUYSRRG.js");
158456
+ const { GlobTool } = await import("./glob-TDVEVPQZ.js");
157444
158457
  return new GlobTool(this);
157445
158458
  });
157446
158459
  await registerLazy(ToolNames.EDIT, async () => {
157447
- const { EditTool } = await import("./edit-4MZYBPF5.js");
158460
+ const { EditTool } = await import("./edit-KSPVUEAS.js");
157448
158461
  return new EditTool(this);
157449
158462
  });
157450
158463
  await registerLazy(ToolNames.NOTEBOOK_EDIT, async () => {
157451
- const { NotebookEditTool } = await import("./notebook-edit-TGU7XHIO.js");
158464
+ const { NotebookEditTool } = await import("./notebook-edit-4ANFZON5.js");
157452
158465
  return new NotebookEditTool(this);
157453
158466
  });
157454
158467
  await registerLazy(ToolNames.WRITE_FILE, async () => {
157455
- const { WriteFileTool } = await import("./write-file-2KVXXVWB.js");
158468
+ const { WriteFileTool } = await import("./write-file-PWOYCT2K.js");
157456
158469
  return new WriteFileTool(this);
157457
158470
  });
157458
158471
  await registerLazy(ToolNames.SHELL, async () => {
157459
- const { ShellTool: ShellTool2 } = await import("./shell-IJYC4BVX.js");
158472
+ const { ShellTool: ShellTool2 } = await import("./shell-LZ55AAJB.js");
157460
158473
  return new ShellTool2(this);
157461
158474
  });
157462
158475
  await registerLazy(ToolNames.TODO_WRITE, async () => {
157463
- const { TodoWriteTool } = await import("./todoWrite-ZUS3HGEF.js");
158476
+ const { TodoWriteTool } = await import("./todoWrite-435EO2CS.js");
157464
158477
  return new TodoWriteTool(this);
157465
158478
  });
158479
+ await registerLazy(ToolNames.REPORT_FINDINGS, async () => {
158480
+ const { ReportFindingsTool } = await import("./report-findings-VFM5DENC.js");
158481
+ return new ReportFindingsTool();
158482
+ });
157466
158483
  const supportsUserInteraction = resolveInteractionMode(this) !== "headless";
157467
158484
  if (supportsUserInteraction) {
157468
158485
  await registerLazy(ToolNames.ASK_USER_QUESTION, async () => {
157469
- const { AskUserQuestionTool } = await import("./askUserQuestion-BSZALR7M.js");
158486
+ const { AskUserQuestionTool } = await import("./askUserQuestion-ZXXERLEV.js");
157470
158487
  return new AskUserQuestionTool(this);
157471
158488
  });
157472
158489
  }
157473
158490
  if (!this.sdkMode && (supportsUserInteraction || options2?.forSubAgent)) {
157474
158491
  await registerLazy(ToolNames.EXIT_PLAN_MODE, async () => {
157475
- const { ExitPlanModeTool: ExitPlanModeTool2 } = await import("./exitPlanMode-F73VQJBO.js");
158492
+ const { ExitPlanModeTool: ExitPlanModeTool2 } = await import("./exitPlanMode-PZG4FXRB.js");
157476
158493
  return new ExitPlanModeTool2(this);
157477
158494
  });
157478
158495
  }
157479
158496
  if (!this.sdkMode && supportsUserInteraction) {
157480
158497
  await registerLazy(ToolNames.ENTER_PLAN_MODE, async () => {
157481
- const { EnterPlanModeTool } = await import("./enterPlanMode-2EL6YAM5.js");
158498
+ const { EnterPlanModeTool } = await import("./enterPlanMode-DZTABSKN.js");
157482
158499
  return new EnterPlanModeTool(this);
157483
158500
  });
157484
158501
  }
157485
158502
  await registerLazy(ToolNames.ENTER_WORKTREE, async () => {
157486
- const { EnterWorktreeTool } = await import("./enter-worktree-WNR4JUPU.js");
158503
+ const { EnterWorktreeTool } = await import("./enter-worktree-UOZ6ZTP7.js");
157487
158504
  return new EnterWorktreeTool(this);
157488
158505
  });
157489
158506
  await registerLazy(ToolNames.EXIT_WORKTREE, async () => {
157490
- const { ExitWorktreeTool } = await import("./exit-worktree-BUHUM6YC.js");
158507
+ const { ExitWorktreeTool } = await import("./exit-worktree-G2QATUCV.js");
157491
158508
  return new ExitWorktreeTool(this);
157492
158509
  });
157493
158510
  await registerLazy(ToolNames.WEB_FETCH, async () => {
157494
- const { WebFetchTool } = await import("./web-fetch-FUG5KGKQ.js");
158511
+ const { WebFetchTool } = await import("./web-fetch-VFHZLLNZ.js");
157495
158512
  return new WebFetchTool(this);
157496
158513
  });
157497
158514
  if (resolveInteractionMode(this) === "interactive" && !this.sdkMode && !this.getScreenReader() && !options2?.forSubAgent) {
157498
158515
  await registerLazy(ToolNames.DISPLAY_IMAGE, async () => {
157499
- const { DisplayImageTool } = await import("./display-image-HOBBUJS5.js");
158516
+ const { DisplayImageTool } = await import("./display-image-DR55LL6M.js");
157500
158517
  return new DisplayImageTool(this);
157501
158518
  });
157502
158519
  }
157503
158520
  if (this.webSearchSettings?.enabled) {
157504
- const { evaluateWebSearchGate } = await import("./web-search-SO3LHSHP.js");
158521
+ const { evaluateWebSearchGate } = await import("./web-search-AQE5A4J5.js");
157505
158522
  const gate = evaluateWebSearchGate(this);
157506
158523
  if (gate.ok) {
157507
158524
  await registerLazy(ToolNames.WEB_SEARCH, async () => {
157508
- const { WebSearchTool } = await import("./web-search-SO3LHSHP.js");
158525
+ const { WebSearchTool } = await import("./web-search-AQE5A4J5.js");
157509
158526
  return new WebSearchTool(this);
157510
158527
  });
157511
158528
  } else if (!this.webSearchNoticeEmitted && !options2?.forSubAgent) {
@@ -157516,87 +158533,87 @@ var Config = class _Config {
157516
158533
  await this.registerImageGenerationTool(registry3);
157517
158534
  if (this.isArtifactEnabled()) {
157518
158535
  await registerLazy(ToolNames.ARTIFACT, async () => {
157519
- const { ArtifactTool } = await import("./artifact-tool-UQTNZDUF.js");
158536
+ const { ArtifactTool } = await import("./artifact-tool-XDJCZZCF.js");
157520
158537
  return new ArtifactTool(this);
157521
158538
  });
157522
158539
  }
157523
158540
  if (this.isRecordArtifactEnabled()) {
157524
158541
  await registerLazy(ToolNames.RECORD_ARTIFACT, async () => {
157525
- const { RecordArtifactTool } = await import("./record-artifact-K6BYYWXY.js");
158542
+ const { RecordArtifactTool } = await import("./record-artifact-CPJ4IJSD.js");
157526
158543
  return new RecordArtifactTool(this);
157527
158544
  });
157528
158545
  }
157529
158546
  if (this.isLspEnabled() && this.getLspClient()) {
157530
158547
  await registerLazy(ToolNames.LSP, async () => {
157531
- const { LspTool } = await import("./lsp-FYP6TW4R.js");
158548
+ const { LspTool } = await import("./lsp-DUKPDUXN.js");
157532
158549
  return new LspTool(this);
157533
158550
  });
157534
158551
  }
157535
158552
  await registerStructuredOutputIfRequested();
157536
158553
  if (this.isCronEnabled()) {
157537
158554
  await registerLazy(ToolNames.CRON_CREATE, async () => {
157538
- const { CronCreateTool } = await import("./cron-create-P4CPPO25.js");
158555
+ const { CronCreateTool } = await import("./cron-create-IJGVR5R2.js");
157539
158556
  return new CronCreateTool(this);
157540
158557
  });
157541
158558
  await registerLazy(ToolNames.CRON_LIST, async () => {
157542
- const { CronListTool } = await import("./cron-list-QPML4MWL.js");
158559
+ const { CronListTool } = await import("./cron-list-2CATIPUX.js");
157543
158560
  return new CronListTool(this);
157544
158561
  });
157545
158562
  await registerLazy(ToolNames.CRON_DELETE, async () => {
157546
- const { CronDeleteTool } = await import("./cron-delete-FPD75GL4.js");
158563
+ const { CronDeleteTool } = await import("./cron-delete-4N5BI6GL.js");
157547
158564
  return new CronDeleteTool(this);
157548
158565
  });
157549
158566
  await registerLazy(ToolNames.LOOP_WAKEUP, async () => {
157550
- const { LoopWakeupTool } = await import("./loop-wakeup-VSA4TBIC.js");
158567
+ const { LoopWakeupTool } = await import("./loop-wakeup-XBPB2BRO.js");
157551
158568
  return new LoopWakeupTool(this);
157552
158569
  });
157553
158570
  }
157554
158571
  if (this.getSubSessionSpawner()) {
157555
158572
  await registerLazy(ToolNames.CREATE_SUB_SESSION, async () => {
157556
- const { CreateSubSessionTool } = await import("./create-sub-session-5ZLCAS2P.js");
158573
+ const { CreateSubSessionTool } = await import("./create-sub-session-RVHSWVAP.js");
157557
158574
  return new CreateSubSessionTool(this);
157558
158575
  });
157559
158576
  }
157560
158577
  if (this.isAgentTeamEnabled()) {
157561
158578
  await registerLazy(ToolNames.TEAM_CREATE, async () => {
157562
- const { TeamCreateTool } = await import("./team-create-IU2A6HD3.js");
158579
+ const { TeamCreateTool } = await import("./team-create-UF4TMQEH.js");
157563
158580
  return new TeamCreateTool(this);
157564
158581
  });
157565
158582
  await registerLazy(ToolNames.TEAM_DELETE, async () => {
157566
- const { TeamDeleteTool } = await import("./team-delete-E4C4AMPF.js");
158583
+ const { TeamDeleteTool } = await import("./team-delete-YWFXX77L.js");
157567
158584
  return new TeamDeleteTool(this);
157568
158585
  });
157569
158586
  await registerLazy(ToolNames.TEAM_PLAN_APPROVAL, async () => {
157570
- const { TeamPlanApprovalTool } = await import("./team-plan-approval-BWI43D37.js");
158587
+ const { TeamPlanApprovalTool } = await import("./team-plan-approval-U57NSR6C.js");
157571
158588
  return new TeamPlanApprovalTool(this);
157572
158589
  });
157573
158590
  if (!options2?.forSubAgent) {
157574
158591
  await registerLazy(ToolNames.REQUEST_SHUTDOWN, async () => {
157575
- const { RequestShutdownTool } = await import("./request-shutdown-EUXDG4IH.js");
158592
+ const { RequestShutdownTool } = await import("./request-shutdown-AXVOFN5C.js");
157576
158593
  return new RequestShutdownTool(this);
157577
158594
  });
157578
158595
  }
157579
158596
  await registerLazy(ToolNames.TASK_CREATE, async () => {
157580
- const { TaskCreateTool } = await import("./task-create-USIZE733.js");
158597
+ const { TaskCreateTool } = await import("./task-create-CDJSOEQD.js");
157581
158598
  return new TaskCreateTool(this);
157582
158599
  });
157583
158600
  await registerLazy(ToolNames.TASK_UPDATE, async () => {
157584
- const { TaskUpdateTool } = await import("./task-update-TFF2KJGL.js");
158601
+ const { TaskUpdateTool } = await import("./task-update-77VCFDDZ.js");
157585
158602
  return new TaskUpdateTool(this);
157586
158603
  });
157587
158604
  await registerLazy(ToolNames.TASK_LIST, async () => {
157588
- const { TaskListTool } = await import("./task-list-AWAJUPIP.js");
158605
+ const { TaskListTool } = await import("./task-list-BELMPA75.js");
157589
158606
  return new TaskListTool(this);
157590
158607
  });
157591
158608
  }
157592
158609
  if (this.isWorkflowsEnabled()) {
157593
158610
  await registerLazy(ToolNames.WORKFLOW, async () => {
157594
- const { WorkflowTool } = await import("./workflow-XJRA3GRI.js");
158611
+ const { WorkflowTool } = await import("./workflow-XL6AEUZ7.js");
157595
158612
  return new WorkflowTool(this);
157596
158613
  });
157597
158614
  }
157598
158615
  await registerLazy(ToolNames.MONITOR, async () => {
157599
- const { MonitorTool } = await import("./monitor-AU2SG5OL.js");
158616
+ const { MonitorTool } = await import("./monitor-A4J5QRGJ.js");
157600
158617
  return new MonitorTool(this);
157601
158618
  });
157602
158619
  if (this.pendingMcpBudgetCallback) {
@@ -158055,6 +159072,7 @@ export {
158055
159072
  fetchGitLog,
158056
159073
  fetchGitCommitDetail,
158057
159074
  FILE_HISTORY_DIR,
159075
+ hasVerifiableInode,
158058
159076
  SESSION_ARTIFACT_PERSISTENCE_VERSION,
158059
159077
  WORKSPACE_CONTENT_SHA256_METADATA_KEY,
158060
159078
  WORKSPACE_CONTENT_MTIME_MS_METADATA_KEY,
@@ -158087,12 +159105,16 @@ export {
158087
159105
  SessionTranscriptReader,
158088
159106
  SessionWriterError,
158089
159107
  SESSION_WRITER_RPC_CODES,
159108
+ SessionTranscriptChangedError,
158090
159109
  SessionWriterUnavailableError,
159110
+ SessionTranscriptIdentityUnavailableError,
158091
159111
  BranchPointInvalidError,
159112
+ SessionStorageEntryError,
158092
159113
  SessionIdCaseConflictError,
158093
159114
  SESSION_TITLE_MAX_LENGTH,
158094
159115
  SessionService,
158095
159116
  computeUniqueBranchTitle,
159117
+ normalizeDerivedBranchTitle,
158096
159118
  tryGenerateSessionTitle,
158097
159119
  TURN_RESULT_TEXT_MAX_CHARS,
158098
159120
  TURN_RESULT_CODE_TEXT_TRUNCATED,