@iowarp/clio-coder 0.4.4 → 0.4.5

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 (555) hide show
  1. package/CHANGELOG.md +92 -2
  2. package/CONTRIBUTING.md +25 -15
  3. package/README.md +340 -27
  4. package/dist/{acp-WNAYYF4F.js → acp-H3CU2HBQ.js} +25 -24
  5. package/dist/{agents-3OKXHLOI.js → agents-IXQQZ7BD.js} +77 -77
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-VKNNMGPU.js → auth-R7KYF7N3.js} +38 -38
  8. package/dist/builtins-CRFDQUVP.js +22 -0
  9. package/dist/{chunk-TQAHXW6Y.js → chunk-22PQ4TX4.js} +4 -4
  10. package/dist/{chunk-NEDJ26B5.js → chunk-2GPGAE5W.js} +6 -51
  11. package/dist/{chunk-IKCO5N3L.js → chunk-2QPI3TR3.js} +3 -3
  12. package/dist/{chunk-HRQMFLJP.js → chunk-32KJPXAM.js} +6 -6
  13. package/dist/{chunk-65DEGPJ6.js → chunk-3A3CUMKA.js} +6 -4
  14. package/dist/{chunk-JCI2ROMZ.js → chunk-3T4DXWP6.js} +7 -7
  15. package/dist/{chunk-DR52UMZW.js → chunk-3UW3KU4A.js} +2 -2
  16. package/dist/{chunk-6Q3CYFD3.js → chunk-4SVIVOMC.js} +184 -33
  17. package/dist/{chunk-W54I7H25.js → chunk-5A6XR3RJ.js} +44 -19
  18. package/dist/{chunk-YPC6ZR5L.js → chunk-5CMARGPF.js} +119 -5
  19. package/dist/{chunk-KXDSS5WJ.js → chunk-5CY4Q6QI.js} +4 -4
  20. package/dist/{chunk-I2DWJ4GM.js → chunk-5DDOTTG4.js} +54 -42
  21. package/dist/{chunk-D4CJV46V.js → chunk-5GZICIYO.js} +3 -3
  22. package/dist/{chunk-4IUZQIJ3.js → chunk-5PHVPU4G.js} +2 -2
  23. package/dist/{chunk-3ODX73FK.js → chunk-5VTJP36Q.js} +4 -4
  24. package/dist/{chunk-54X7T7DK.js → chunk-5ZMXGW7P.js} +79 -7
  25. package/dist/chunk-5ZSZEYJK.js +119 -0
  26. package/dist/{chunk-IXIY2H4R.js → chunk-633EXGZA.js} +5 -5
  27. package/dist/{chunk-CUSRQKPU.js → chunk-6CDNRHWH.js} +299 -89
  28. package/dist/{chunk-EBY63B7G.js → chunk-6EXUUOSN.js} +2 -2
  29. package/dist/{chunk-SVNXH4L2.js → chunk-6ICZKDUC.js} +2 -2
  30. package/dist/{chunk-JEIYHLOR.js → chunk-6SYEGZI3.js} +12 -12
  31. package/dist/{chunk-DQOVN6KV.js → chunk-6YA46L5A.js} +4 -4
  32. package/dist/{chunk-NZMNUPZZ.js → chunk-77CZRFTE.js} +3 -3
  33. package/dist/{chunk-6PAZTBPA.js → chunk-7HBHHVCK.js} +15 -6
  34. package/dist/{chunk-25QBEXRS.js → chunk-7TKWWPD7.js} +5 -4
  35. package/dist/{chunk-2VTFPG5O.js → chunk-7WLRF2U5.js} +2 -2
  36. package/dist/chunk-7WUZEB2M.js +165 -0
  37. package/dist/{chunk-3UUXNFEX.js → chunk-7YJWEF2L.js} +61 -34
  38. package/dist/{chunk-3EBYEESD.js → chunk-A46ILRS2.js} +5 -5
  39. package/dist/{chunk-UOIZ7DA4.js → chunk-AP7HDJOP.js} +2 -2
  40. package/dist/{chunk-APJ265NV.js → chunk-B5GGDIHT.js} +146 -146
  41. package/dist/{chunk-PMZVFWSR.js → chunk-B5ZTR6KZ.js} +2 -2
  42. package/dist/{chunk-I5FWO7L5.js → chunk-B6UM3OZC.js} +2 -2
  43. package/dist/{chunk-2CU2H6KE.js → chunk-BBV5TKE6.js} +5 -5
  44. package/dist/{chunk-4O6MANBS.js → chunk-BS4GAMUB.js} +14 -10
  45. package/dist/{chunk-S66XZJOF.js → chunk-C27U2TYG.js} +2 -2
  46. package/dist/{chunk-QZWQA4DE.js → chunk-CBSKDFWL.js} +3 -3
  47. package/dist/{chunk-2LEAKD4C.js → chunk-CKK25WN3.js} +3 -3
  48. package/dist/{chunk-BYP5D4HI.js → chunk-CTTI7G3T.js} +2 -2
  49. package/dist/{chunk-XAKHZX5N.js → chunk-CVDAFGPW.js} +4 -4
  50. package/dist/{chunk-RKKLTLYB.js → chunk-CXQ37WJH.js} +3 -3
  51. package/dist/{chunk-GTUD2WMY.js → chunk-DBREN25X.js} +44 -9
  52. package/dist/{chunk-YNFKXPEC.js → chunk-DIMRLNIC.js} +35 -66
  53. package/dist/{chunk-NDDGJUXD.js → chunk-DNCE23JJ.js} +2 -2
  54. package/dist/{chunk-HVDIIIQW.js → chunk-DNHVRBH4.js} +3 -3
  55. package/dist/{chunk-XULDXHTN.js → chunk-DRD2A54W.js} +102 -50
  56. package/dist/{chunk-D7E7WCDF.js → chunk-DVNAPPXU.js} +2 -2
  57. package/dist/{chunk-YXLYO42X.js → chunk-DXVMLM3Z.js} +3 -2
  58. package/dist/{chunk-5MEZN6CB.js → chunk-DZK63TZJ.js} +6 -6
  59. package/dist/{chunk-IGLP3ODT.js → chunk-E3BQTQUP.js} +15 -15
  60. package/dist/{chunk-IWHMRKLL.js → chunk-E3LEPLQ2.js} +2 -2
  61. package/dist/{chunk-3R73A4XB.js → chunk-ECBHH7LU.js} +3 -3
  62. package/dist/chunk-ECOMVOHP.js +139 -0
  63. package/dist/chunk-EFSEIZE6.js +56 -0
  64. package/dist/{chunk-FEAXX7B6.js → chunk-EHCPSZJF.js} +4 -4
  65. package/dist/{chunk-4NSRCOYP.js → chunk-EHOSNVVM.js} +3 -2
  66. package/dist/{chunk-7UGL4MB5.js → chunk-EQEJJ53P.js} +10 -10
  67. package/dist/{chunk-GWZNEVM2.js → chunk-EWD5P3GK.js} +9 -9
  68. package/dist/{chunk-6UINWWS6.js → chunk-F34AR6O3.js} +14 -14
  69. package/dist/{chunk-GHS5EBTQ.js → chunk-FKIOX6DS.js} +29 -20
  70. package/dist/{chunk-HAXOFFRH.js → chunk-FQOOGXBH.js} +7 -7
  71. package/dist/{chunk-Y55JBDO5.js → chunk-FSTIBAGM.js} +38 -23
  72. package/dist/{chunk-ZTJUVLTU.js → chunk-FXFVDPWY.js} +2 -2
  73. package/dist/{chunk-XPLRXC72.js → chunk-GD55RTIW.js} +3 -3
  74. package/dist/{chunk-5B2AEOW5.js → chunk-GH5ZR6JP.js} +472 -472
  75. package/dist/{chunk-TOIVGRUX.js → chunk-GJ24ODAX.js} +5 -5
  76. package/dist/{chunk-QUFRYSWI.js → chunk-GNQRWTMY.js} +129 -48
  77. package/dist/{chunk-5ICU3EUH.js → chunk-GVYWZNRK.js} +5 -5
  78. package/dist/{chunk-GX5WYQO4.js → chunk-GXCCHKN6.js} +6 -6
  79. package/dist/{chunk-K6T2ZAMZ.js → chunk-HGSLRG33.js} +6 -6
  80. package/dist/{chunk-26QSH3EJ.js → chunk-HHVJNVUJ.js} +5 -5
  81. package/dist/{chunk-F4EKGO4N.js → chunk-HL26ADLH.js} +4 -2
  82. package/dist/{chunk-JT2RFCC5.js → chunk-HR3HPQ76.js} +5 -5
  83. package/dist/{chunk-ID64D7PE.js → chunk-HXHFDHB6.js} +24 -24
  84. package/dist/{chunk-ELWDPP3Y.js → chunk-I7VLWRK2.js} +8 -8
  85. package/dist/{chunk-6OSVSQL5.js → chunk-ICO4TQ2F.js} +7 -5
  86. package/dist/{chunk-SZAA6XDG.js → chunk-IFDRAD6F.js} +2 -2
  87. package/dist/{chunk-72YIHOZQ.js → chunk-ILJ7DWGE.js} +9 -9
  88. package/dist/{chunk-2JH2WHGE.js → chunk-J2FYEQ5L.js} +4 -4
  89. package/dist/{chunk-BMS5RKQY.js → chunk-JABWPKFY.js} +3 -3
  90. package/dist/{chunk-QDC3K2U3.js → chunk-K2BLQC5E.js} +3 -3
  91. package/dist/{chunk-AUPNRN7C.js → chunk-K2HL3GBL.js} +4 -4
  92. package/dist/{chunk-2ASED4PZ.js → chunk-K6RDB7IA.js} +26 -26
  93. package/dist/{chunk-FFUPXJC4.js → chunk-KDWLXVMN.js} +23 -24
  94. package/dist/{chunk-OZNBF4L3.js → chunk-KECNXMDE.js} +2 -2
  95. package/dist/{chunk-6QOTUPRG.js → chunk-KF6GFW6O.js} +66 -18
  96. package/dist/{chunk-BTK3SSSK.js → chunk-KMF54VH3.js} +2 -2
  97. package/dist/chunk-KPRLAMP4.js +32 -0
  98. package/dist/{chunk-ECH6PKUQ.js → chunk-KQ6IDQIB.js} +2 -2
  99. package/dist/{chunk-3UNOLWNZ.js → chunk-KTFSFCVN.js} +20 -9
  100. package/dist/{chunk-57XXR6DR.js → chunk-KYKNBD4Y.js} +24 -23
  101. package/dist/{chunk-IRXAATOX.js → chunk-L4N3DWNW.js} +3 -3
  102. package/dist/{chunk-LCGCVYZ4.js → chunk-LQTKDAUO.js} +2 -2
  103. package/dist/{chunk-U6TMQNSI.js → chunk-LTR5QCLS.js} +4 -4
  104. package/dist/chunk-LUL5Z66S.js +221 -0
  105. package/dist/{chunk-ELZVTCGV.js → chunk-LVFANMOH.js} +151 -327
  106. package/dist/{chunk-H7IXIC72.js → chunk-LY4N4TTL.js} +17 -3
  107. package/dist/{chunk-VKPAQYEB.js → chunk-LZBMXNLP.js} +5 -5
  108. package/dist/{chunk-UL3WSD3F.js → chunk-M4KFUXS7.js} +2 -2
  109. package/dist/{chunk-NXYCB2VD.js → chunk-M6TAYK66.js} +6 -6
  110. package/dist/{chunk-NEKRRTYW.js → chunk-MC3JSVR6.js} +2 -2
  111. package/dist/{chunk-CFGTUFWB.js → chunk-MCJKEGHO.js} +2 -2
  112. package/dist/{chunk-DXKJURES.js → chunk-MDU3C27C.js} +10 -7
  113. package/dist/{chunk-6XLNIQDB.js → chunk-MYI32N4R.js} +2 -2
  114. package/dist/{chunk-3GY4F45V.js → chunk-NC4KV7EL.js} +6 -6
  115. package/dist/{chunk-LLXSDWXS.js → chunk-NF3BK5WR.js} +5 -5
  116. package/dist/chunk-NTK3WTHM.js +141 -0
  117. package/dist/{chunk-GYV6VZOC.js → chunk-NTTS3O53.js} +2 -2
  118. package/dist/{chunk-RZDWV63N.js → chunk-NY6IWDVU.js} +6 -6
  119. package/dist/{chunk-XXYSBZIQ.js → chunk-O2RQ7LCK.js} +4 -4
  120. package/dist/{chunk-4BJ5BYCE.js → chunk-O3VV6IVK.js} +2 -2
  121. package/dist/{chunk-W6GROXXM.js → chunk-O5F25NIE.js} +2 -2
  122. package/dist/{chunk-NXIMQY5W.js → chunk-ODUTYZIU.js} +5 -5
  123. package/dist/{chunk-LTIKRKFL.js → chunk-ONRTXOZY.js} +4 -4
  124. package/dist/{chunk-KFV5L5SK.js → chunk-OQM5IVJY.js} +118 -232
  125. package/dist/{chunk-XRZT5WY5.js → chunk-P5SC4DLJ.js} +4 -4
  126. package/dist/{chunk-R6Q67RJH.js → chunk-PECBKCDK.js} +34 -6
  127. package/dist/{chunk-33YXPOE3.js → chunk-PPEZJWUG.js} +2 -2
  128. package/dist/{chunk-RXTN6AKH.js → chunk-PWWSIB2A.js} +5 -5
  129. package/dist/{chunk-2STGEDFV.js → chunk-QEQISF75.js} +2 -2
  130. package/dist/{chunk-3DPEIQKN.js → chunk-QH3ZTUOA.js} +2 -2
  131. package/dist/{chunk-YAKGTXEV.js → chunk-QRFXEO6Y.js} +2 -2
  132. package/dist/{chunk-35MSIRKH.js → chunk-QUIJZSDW.js} +2 -2
  133. package/dist/{chunk-HHV2GANA.js → chunk-R2P2U3ZS.js} +2 -2
  134. package/dist/{chunk-2DSOYNFC.js → chunk-R6MAYTMS.js} +7 -7
  135. package/dist/{chunk-JQLNNIKT.js → chunk-R6MICQYU.js} +6 -6
  136. package/dist/{chunk-NAI6ZFCY.js → chunk-RLTT5GVY.js} +122 -11
  137. package/dist/{chunk-DT3LWJOB.js → chunk-RXIOCVBZ.js} +24 -6
  138. package/dist/{chunk-N56KALIC.js → chunk-S32UQ5GL.js} +61 -34
  139. package/dist/{chunk-UEPWCCTY.js → chunk-SBZX6ARC.js} +12 -12
  140. package/dist/chunk-SD7SHNDW.js +15 -0
  141. package/dist/{chunk-NRO2BJRH.js → chunk-SDWNDICN.js} +10235 -4015
  142. package/dist/{chunk-UXCU4E3T.js → chunk-SE4ZKILO.js} +6 -6
  143. package/dist/chunk-SL2RDHKO.js +19 -0
  144. package/dist/{chunk-NUGM5KR6.js → chunk-SRCEQKQS.js} +2 -2
  145. package/dist/{chunk-OMQNJVKW.js → chunk-SRZOW5L2.js} +43 -13
  146. package/dist/{chunk-3M6DQK6S.js → chunk-T334FW2H.js} +7 -7
  147. package/dist/{chunk-V76WTFTW.js → chunk-T52TPHYC.js} +6 -6
  148. package/dist/{chunk-I7XBWTYH.js → chunk-T53XI6I7.js} +5 -5
  149. package/dist/{chunk-2ZSONWVL.js → chunk-T7FDXNRU.js} +13 -13
  150. package/dist/{chunk-JSD46VO2.js → chunk-TEG3RYVZ.js} +43 -36
  151. package/dist/{chunk-3I7MS7N2.js → chunk-TK2BMCBZ.js} +2 -2
  152. package/dist/{chunk-5OIVVPHF.js → chunk-TN5FW4XY.js} +13 -6
  153. package/dist/{chunk-75W7L2E2.js → chunk-TZ7MFRG4.js} +1041 -162
  154. package/dist/{chunk-36CT5VVL.js → chunk-U2JOLB7O.js} +126 -77
  155. package/dist/{chunk-LL4KHSZI.js → chunk-U2MSJ57E.js} +2 -2
  156. package/dist/{chunk-FTMGRKEF.js → chunk-U44YYLVV.js} +4 -4
  157. package/dist/{chunk-YECAMM3D.js → chunk-U7H5WRG5.js} +5 -5
  158. package/dist/{chunk-RQCKCSRL.js → chunk-U7VQ4NI4.js} +22 -22
  159. package/dist/{chunk-5TUB6SLS.js → chunk-UFYNOQK4.js} +7 -7
  160. package/dist/{chunk-R346GLFC.js → chunk-UHW5V7HC.js} +2 -2
  161. package/dist/{chunk-USR47QNF.js → chunk-UL36QJX6.js} +14 -14
  162. package/dist/{chunk-VIA6RFQZ.js → chunk-UQIVHSE4.js} +4 -4
  163. package/dist/{chunk-RAY4OVGZ.js → chunk-URBGEOH3.js} +5 -5
  164. package/dist/chunk-USZA7GWL.js +341 -0
  165. package/dist/{chunk-YD5GIKET.js → chunk-UTUNT5QL.js} +48 -579
  166. package/dist/{chunk-ZA4VCIGV.js → chunk-UUQ5G6EZ.js} +60 -41
  167. package/dist/{chunk-23L32XTI.js → chunk-UXAC2FX4.js} +68 -39
  168. package/dist/{chunk-VG7TBQIY.js → chunk-V552WL53.js} +68 -4
  169. package/dist/{chunk-BWH6N36D.js → chunk-VHKTOLEW.js} +272 -42
  170. package/dist/{chunk-EXLD33WO.js → chunk-VLPTKCKT.js} +24 -9
  171. package/dist/{chunk-336NSSKI.js → chunk-VNBICSS2.js} +2 -2
  172. package/dist/{chunk-VAVR4IJY.js → chunk-VQD7NH7Z.js} +3 -3
  173. package/dist/{chunk-LBMZMYH2.js → chunk-W2RJEH6Q.js} +3 -3
  174. package/dist/{chunk-7CR24IG7.js → chunk-WDV62RKY.js} +2 -2
  175. package/dist/{chunk-S6PYF2XF.js → chunk-WFKDPU7U.js} +4 -4
  176. package/dist/{chunk-BJVFZO5U.js → chunk-WJIMKGD6.js} +7 -7
  177. package/dist/{chunk-5636DCO5.js → chunk-WLMSOT73.js} +59 -12
  178. package/dist/{chunk-MXHC5QYU.js → chunk-WTQGRBHV.js} +5 -144
  179. package/dist/chunk-WXA2CFJO.js +23 -0
  180. package/dist/{chunk-QSNYB6ZV.js → chunk-XCUDZQLX.js} +3 -3
  181. package/dist/{chunk-4M6Z5QVF.js → chunk-XXBQKW32.js} +11 -11
  182. package/dist/{chunk-OEJSLEPW.js → chunk-YEJIG7LN.js} +332 -332
  183. package/dist/chunk-YGDMBK7O.js +567 -0
  184. package/dist/{chunk-4WR7VSYB.js → chunk-YYB3MC65.js} +23 -9
  185. package/dist/{chunk-2IR2NMPA.js → chunk-ZIDFQJRB.js} +2 -2
  186. package/dist/{chunk-Q4WO54TA.js → chunk-ZMZQEBKI.js} +14 -14
  187. package/dist/{chunk-6EJMN2Y3.js → chunk-ZTNFYMIO.js} +2 -2
  188. package/dist/{chunk-WEPFGWHJ.js → chunk-ZZFWWYLX.js} +2 -2
  189. package/dist/cli/index.js +44 -44
  190. package/dist/clio-5I2IBFYL.js +26 -0
  191. package/dist/{code-nav-IJR2DBPR.js → code-nav-YXIAEZVS.js} +48 -32
  192. package/dist/codewiki/build-worker.js +76 -29
  193. package/dist/{compile-cache-OQAVB7Y5.js → compile-cache-WJEPUZEJ.js} +4 -4
  194. package/dist/{components-2TGAI2RC.js → components-TNIKXCBH.js} +13 -13
  195. package/dist/{config-IUA6OYNS.js → config-Y2JDJ3JJ.js} +210 -124
  196. package/dist/configure-SML6UBZ5.js +55 -0
  197. package/dist/{context-4MPR7WKB.js → context-P5YSEO55.js} +125 -121
  198. package/dist/{context-2DKHWH2T.js → context-QQ53HSGJ.js} +91 -62
  199. package/dist/{context-BOYF5EJM.js → context-S2EEC3EJ.js} +62 -31
  200. package/dist/context-clear-TMEQCOTH.js +183 -0
  201. package/dist/{context-index-HNG3MOME.js → context-index-HP2JFUWA.js} +13 -11
  202. package/dist/{context-map-COB37XXN.js → context-map-INTXD54D.js} +71 -21
  203. package/dist/{context-working-set-3I3FYX6Y.js → context-working-set-CNLSQN5K.js} +31 -31
  204. package/dist/detail-5572VLBO.js +114 -0
  205. package/dist/{dispatch-runner-RJ5I2F2O.js → dispatch-runner-FRHD6P2O.js} +191 -116
  206. package/dist/{docs-SPOV3BAN.js → docs-BL7ROUFN.js} +4 -4
  207. package/dist/{doctor-DKICC2SN.js → doctor-N3LCM2LG.js} +58 -58
  208. package/dist/{eval-OQOQUDHK.js → eval-BUU3ZOUZ.js} +473 -168
  209. package/dist/{eval-inventory-Y6QRFOH5.js → eval-inventory-QOYZERXJ.js} +7 -7
  210. package/dist/evidence-DTGEN456.js +224 -0
  211. package/dist/{evidence-4DQ25GUQ.js → evidence-SQ5DNFEN.js} +110 -94
  212. package/dist/{evolve-GSS52E5J.js → evolve-IJNUFZDS.js} +107 -91
  213. package/dist/{extensions-G7MFLYHT.js → extensions-YVRHX6ZI.js} +16 -16
  214. package/dist/{fleet-Q37YHHAQ.js → fleet-ZNNVSYFO.js} +147 -147
  215. package/dist/{fleet-commands-G7E4N7SM.js → fleet-commands-5YE7NPJL.js} +27 -26
  216. package/dist/{fleet-decisions-O7M6QBA2.js → fleet-decisions-3SBSCTCW.js} +16 -15
  217. package/dist/{fleet-graph-TOUBW6OW.js → fleet-graph-6HHPWF5T.js} +39 -38
  218. package/dist/{fleet-inspect-SW33JJNI.js → fleet-inspect-JEYMGCGC.js} +107 -91
  219. package/dist/{fleet-new-RDVJLHHH.js → fleet-new-RCKGSRDV.js} +3 -3
  220. package/dist/{fleet-preflight-CV2655TW.js → fleet-preflight-QRSHIIDE.js} +10 -9
  221. package/dist/{fleet-validate-KESZX2YH.js → fleet-validate-4PM4GDDL.js} +46 -42
  222. package/dist/{fleet-verify-UQPMTVE3.js → fleet-verify-NJDTHTO3.js} +105 -89
  223. package/dist/fleet-view-UP2BWQQY.js +117 -0
  224. package/dist/{init-PXEXQSBF.js → init-S3GZQ5ZF.js} +123 -123
  225. package/dist/{install-NKNG7KD4.js → install-3RZDDP23.js} +5 -5
  226. package/dist/{interop-ZG5T62U3.js → interop-YOTGXFJM.js} +25 -25
  227. package/dist/inventory-K2OZ36YJ.js +117 -0
  228. package/dist/{library-B2W4N74O.js → library-GJI6W6OK.js} +45 -44
  229. package/dist/{memory-YCANYS5A.js → memory-OQOXQGYD.js} +107 -93
  230. package/dist/{models-GERTU3YI.js → models-3IK2Y5WE.js} +63 -62
  231. package/dist/{monitor-CPNIUULB.js → monitor-FTJLTKCQ.js} +136 -107
  232. package/dist/{orchestrator-J4BSH4WQ.js → orchestrator-N47O7SFD.js} +1159 -697
  233. package/dist/{panes-BOHAEGYC.js → panes-7BTYH3XQ.js} +8 -8
  234. package/dist/{panes-NXSLDQZ2.js → panes-WPOMEMRH.js} +22 -22
  235. package/dist/{paths-VSUWNC22.js → paths-J3KN7UAO.js} +12 -12
  236. package/dist/preload-65U34NG6.js +115 -0
  237. package/dist/{registry-LG64LTF4.js → registry-DESGAXWK.js} +3 -3
  238. package/dist/{reset-TNWTB5LU.js → reset-MUVQDLNL.js} +20 -20
  239. package/dist/{resources-4PXNMD5G.js → resources-LM76COAO.js} +41 -40
  240. package/dist/{run-D6XJ34CN.js → run-3VFZQ33N.js} +162 -156
  241. package/dist/{share-2NWMJJEE.js → share-4JUB4BL7.js} +43 -42
  242. package/dist/{skills-KR7WON5G.js → skills-S36AAJHU.js} +47 -46
  243. package/dist/{skills-eval-O2ZNOLDS.js → skills-eval-G6T57L7M.js} +127 -107
  244. package/dist/{skills-inventory-ZZOUBK7O.js → skills-inventory-WLM46PJH.js} +41 -40
  245. package/dist/slash-commands-GBARG3Y7.js +91 -0
  246. package/dist/{steer-XA25PSCS.js → steer-S7D7IKPU.js} +7 -7
  247. package/dist/{support-7EMVWYG2.js → support-5VAEC32W.js} +14 -14
  248. package/dist/{targets-OMH2XCSN.js → targets-N5REUETU.js} +145 -94
  249. package/dist/tasks-6BVY5YZF.js +36 -0
  250. package/dist/{terminal-lease-C2J3JYRE.js → terminal-lease-57UEOJKS.js} +12 -11
  251. package/dist/tools-6OCQ6SVB.js +28 -0
  252. package/dist/{trace-FXMXUZUF.js → trace-JHLXWUMN.js} +18 -17
  253. package/dist/{tree-sitter-HGKH6LG4.js → tree-sitter-AQUUOSYM.js} +6 -6
  254. package/dist/{tui-primitives-K5PASC3O.js → tui-primitives-RCY2HN7G.js} +3 -3
  255. package/dist/{uninstall-HALS6BLF.js → uninstall-FXYMFFRT.js} +17 -17
  256. package/dist/{upgrade-MS72RJEP.js → upgrade-4HD5HAIV.js} +40 -39
  257. package/dist/{usage-NHG6MCJM.js → usage-4GWM2WWP.js} +136 -105
  258. package/dist/{verifiers-7AUNVXDY.js → verifiers-GSKWKWVG.js} +28 -27
  259. package/dist/verify-3AS3ULCY.js +30 -0
  260. package/dist/{version-KGEG7EPO.js → version-RFPKO6T7.js} +4 -4
  261. package/dist/{web-fetch-V4FKSDAV.js → web-fetch-MQN4FH3X.js} +169 -18
  262. package/dist/wiki-generate-7BV7XWIY.js +614 -0
  263. package/dist/{with-panes-BDQEWBRT.js → with-panes-OFTNAR4Y.js} +34 -20
  264. package/dist/worker/entry.js +99 -88
  265. package/dist/{workspace-ZJ6BFM3Q.js → workspace-DZ7JADBG.js} +6 -6
  266. package/docs/README.md +7 -6
  267. package/docs/architecture/acp.md +10 -0
  268. package/docs/architecture/architecture.md +5 -5
  269. package/docs/architecture/context-engine.md +44 -59
  270. package/docs/architecture/context-working-set.md +7 -9
  271. package/docs/architecture/dispatch-architecture-rationale.md +1 -1
  272. package/docs/architecture/evidence-and-memory.md +10 -0
  273. package/docs/architecture/pi-boundary.md +37 -7
  274. package/docs/architecture/prompt-envelope-and-tools.md +7 -7
  275. package/docs/architecture/session-lifecycle.md +4 -4
  276. package/docs/architecture/worker-dispatch-mechanics.md +4 -0
  277. package/docs/guide/commands-and-modes.md +49 -36
  278. package/docs/guide/configuration-and-targets.md +7 -2
  279. package/docs/guide/configuration-reference.md +13 -3
  280. package/docs/guide/environment-variables.md +6 -2
  281. package/docs/guide/fleet-dispatch.md +12 -0
  282. package/docs/guide/installation-and-lifecycle.md +35 -9
  283. package/docs/guide/proactive-memory.md +1 -1
  284. package/docs/guide/skills-marketplace.md +11 -3
  285. package/docs/guide/tool-usage.md +9 -2
  286. package/docs/process/development-pipeline.md +10 -10
  287. package/docs/process/documentation-guide.md +2 -2
  288. package/docs/process/eval-runner.md +15 -0
  289. package/docs/process/evals-internal.md +1 -1
  290. package/docs/process/release-cut-checklist.md +6 -6
  291. package/evals/README.md +4 -0
  292. package/evals/behavioral-corpus-grader.mjs +147 -14
  293. package/evals/behavioral-model-negative-control.yaml +1 -0
  294. package/evals/behavioral-model.yaml +266 -1
  295. package/evals/fixtures/docs-retrieval.json +102 -0
  296. package/evals/fixtures/scalar-decision.json +17 -0
  297. package/evals/fixtures/scout-citation-pipeline.json +55 -0
  298. package/evals/fixtures/source-explanation.json +74 -0
  299. package/evals/fixtures/tool-arguments.json +18 -0
  300. package/evals/fixtures/tool-surface/read.txt +4 -0
  301. package/evals/fixtures/tool-surface/subdir/keep.txt +1 -0
  302. package/evals/no-edit-memory-grader.mjs +149 -0
  303. package/evals/scalar-decision-grader.py +41 -0
  304. package/evals/scalar-decision-machinery.ts +145 -0
  305. package/evals/source-explanation-grader.mjs +118 -0
  306. package/evals/tool-surface-grader.mjs +53 -0
  307. package/evals/tool-surface-model.yaml +274 -0
  308. package/package.json +14 -14
  309. package/skills/README.md +6 -6
  310. package/skills/registry.yaml +1 -1
  311. package/skills/skill-marketplace.json +1 -1
  312. package/src/cli/bootstrap-generate.ts +6 -0
  313. package/src/cli/config-inspect.ts +24 -7
  314. package/src/cli/config-trust.ts +62 -0
  315. package/src/cli/config.ts +8 -0
  316. package/src/cli/context-map.ts +75 -14
  317. package/src/cli/context.ts +46 -17
  318. package/src/cli/eval.ts +17 -3
  319. package/src/cli/modes/print.ts +32 -4
  320. package/src/cli/run.ts +16 -14
  321. package/src/cli/skills-eval.ts +10 -8
  322. package/src/cli/steer-channel.ts +31 -18
  323. package/src/cli/targets.ts +83 -31
  324. package/src/cli/tasks.ts +10 -1
  325. package/src/cli/upgrade.ts +9 -6
  326. package/src/cli/usage.ts +24 -0
  327. package/src/cli/wiki-generate.ts +239 -96
  328. package/src/core/bash-exec.ts +43 -15
  329. package/src/core/bus-events.ts +15 -0
  330. package/src/core/config.ts +33 -14
  331. package/src/core/defaults.ts +5 -4
  332. package/src/core/file-references.ts +11 -1
  333. package/src/core/incomplete-installation.ts +3 -1
  334. package/src/core/settings-layers.ts +21 -5
  335. package/src/core/termination.ts +26 -9
  336. package/src/core/untrusted-content.ts +16 -0
  337. package/src/core/workspace-trust.ts +179 -0
  338. package/src/domains/agents/builtins/coder.md +4 -2
  339. package/src/domains/agents/builtins/context-bootstrap.md +3 -1
  340. package/src/domains/agents/builtins/documenter.md +7 -4
  341. package/src/domains/agents/builtins/researcher.md +1 -0
  342. package/src/domains/agents/builtins/scout.md +7 -1
  343. package/src/domains/agents/result-contract.ts +199 -26
  344. package/src/domains/context/bootstrap-prompt.ts +11 -9
  345. package/src/domains/context/bootstrap.ts +74 -39
  346. package/src/domains/context/clio-md.ts +88 -26
  347. package/src/domains/context/codewiki/build-operation.ts +121 -0
  348. package/src/domains/context/codewiki/build-worker-protocol.ts +37 -3
  349. package/src/domains/context/codewiki/build-worker.ts +3 -35
  350. package/src/domains/context/codewiki/coordinator.ts +36 -6
  351. package/src/domains/context/codewiki/indexer.ts +59 -19
  352. package/src/domains/context/contract.ts +6 -2
  353. package/src/domains/context/extension.ts +72 -10
  354. package/src/domains/context/fingerprint.ts +39 -34
  355. package/src/domains/context/index.ts +7 -1
  356. package/src/domains/context/prompt-context.ts +55 -14
  357. package/src/domains/context/refresh.ts +9 -57
  358. package/src/domains/context/wiki/assemble.ts +14 -10
  359. package/src/domains/context/wiki/evidence.ts +209 -0
  360. package/src/domains/context/wiki/generate.ts +201 -67
  361. package/src/domains/context/wiki/meta.ts +10 -2
  362. package/src/domains/context/wiki/plan-store.ts +70 -14
  363. package/src/domains/context/wiki/plan.ts +71 -14
  364. package/src/domains/context/wiki/prompts.ts +42 -1
  365. package/src/domains/context/wiki/source-content.ts +106 -0
  366. package/src/domains/context/wiki/staleness.ts +33 -22
  367. package/src/domains/context/working-set/contract.ts +8 -2
  368. package/src/domains/context/working-set/engine.ts +17 -4
  369. package/src/domains/context/working-set/fold.ts +15 -2
  370. package/src/domains/context/working-set/marker.ts +2 -1
  371. package/src/domains/context/working-set/project.ts +18 -7
  372. package/src/domains/context/working-set/recall.ts +82 -56
  373. package/src/domains/dispatch/active-route-planner.ts +6 -3
  374. package/src/domains/dispatch/admission-queue.ts +19 -7
  375. package/src/domains/dispatch/admission.ts +3 -3
  376. package/src/domains/dispatch/budget-envelope.ts +47 -82
  377. package/src/domains/dispatch/capacity-lease.ts +57 -19
  378. package/src/domains/dispatch/contract.ts +10 -2
  379. package/src/domains/dispatch/event-pump.ts +28 -7
  380. package/src/domains/dispatch/execution-role.ts +49 -2
  381. package/src/domains/dispatch/execution-scheduler.ts +2 -0
  382. package/src/domains/dispatch/extension.ts +190 -105
  383. package/src/domains/dispatch/fleet-run.ts +20 -0
  384. package/src/domains/dispatch/gate-role-prompts.ts +4 -2
  385. package/src/domains/dispatch/parallel-writers.ts +34 -0
  386. package/src/domains/dispatch/reservation-store.ts +8 -34
  387. package/src/domains/dispatch/route-approval.ts +3 -3
  388. package/src/domains/dispatch/route-observer.ts +4 -2
  389. package/src/domains/dispatch/route-quality.ts +6 -1
  390. package/src/domains/dispatch/types.ts +4 -3
  391. package/src/domains/dispatch/worker-spawn.ts +58 -21
  392. package/src/domains/dispatch/workspace-checkpoint.ts +57 -0
  393. package/src/domains/eval/compare/behavioral.ts +81 -14
  394. package/src/domains/eval/compare/compare.ts +15 -5
  395. package/src/domains/eval/compare/envelope.ts +12 -5
  396. package/src/domains/eval/metrics/context.ts +24 -1
  397. package/src/domains/eval/metrics/tracked.ts +4 -28
  398. package/src/domains/eval/reports/comparison.ts +9 -9
  399. package/src/domains/eval/runners/clio-run.ts +5 -1
  400. package/src/domains/eval/schema/suite.ts +2 -0
  401. package/src/domains/eval/schema/validate.ts +1 -0
  402. package/src/domains/eval/suites/run.ts +189 -13
  403. package/src/domains/eval/verifiers/integrity.ts +39 -0
  404. package/src/domains/eval/verifiers/patch.ts +58 -2
  405. package/src/domains/eval/workspaces/temp-copy.ts +3 -0
  406. package/src/domains/evidence/build.ts +4 -2
  407. package/src/domains/interop/registry.ts +2 -2
  408. package/src/domains/middleware/hooks-io.ts +45 -26
  409. package/src/domains/middleware/hooks.ts +6 -0
  410. package/src/domains/middleware/injection-screen.ts +23 -0
  411. package/src/domains/middleware/rules.ts +5 -1
  412. package/src/domains/middleware/stalled-turn.ts +18 -3
  413. package/src/domains/middleware/task-board-reminder.ts +4 -2
  414. package/src/domains/middleware/task-nudge.ts +4 -1
  415. package/src/domains/mux/contract.ts +34 -1
  416. package/src/domains/mux/dock-controller.ts +8 -1
  417. package/src/domains/mux/index.ts +1 -0
  418. package/src/domains/mux/socket-client.ts +13 -3
  419. package/src/domains/observability/contract.ts +2 -2
  420. package/src/domains/observability/projection.ts +30 -9
  421. package/src/domains/prompts/compiler.ts +10 -2
  422. package/src/domains/prompts/contract.ts +7 -4
  423. package/src/domains/prompts/extension.ts +28 -64
  424. package/src/domains/prompts/fragments/identity/clio.md +23 -0
  425. package/src/domains/prompts/fragments/operating/contract.md +10 -0
  426. package/src/domains/prompts/fragments/operating/delegation.md +5 -0
  427. package/src/domains/prompts/fragments/wiki/page.md +28 -15
  428. package/src/domains/prompts/fragments/wiki/plan.md +4 -4
  429. package/src/domains/prompts/preload-prefix.ts +31 -0
  430. package/src/domains/prompts/preload.ts +135 -61
  431. package/src/domains/providers/auth/backend-file.ts +15 -11
  432. package/src/domains/providers/auth/storage.ts +3 -5
  433. package/src/domains/providers/catalog.ts +18 -3
  434. package/src/domains/providers/runtime-resolution.ts +11 -9
  435. package/src/domains/providers/runtimes/cloud/openrouter.ts +2 -0
  436. package/src/domains/resources/skills/promotion.ts +8 -1
  437. package/src/domains/safety/action-classifier.ts +9 -0
  438. package/src/domains/safety/autonomy.ts +10 -1
  439. package/src/domains/safety/contract.ts +5 -1
  440. package/src/domains/safety/default-path-policy.ts +11 -0
  441. package/src/domains/safety/extension.ts +11 -2
  442. package/src/domains/safety/policy-engine.ts +189 -32
  443. package/src/domains/safety/project-policy.ts +7 -2
  444. package/src/domains/safety/workspace-trust.ts +43 -0
  445. package/src/domains/session/compaction/compact.ts +384 -21
  446. package/src/domains/session/compaction/cut-point.ts +42 -5
  447. package/src/domains/session/compaction/tokens.ts +9 -1
  448. package/src/domains/session/decision-board.ts +43 -33
  449. package/src/domains/session/entries.ts +169 -4
  450. package/src/domains/session/prompt-manifest.ts +47 -8
  451. package/src/domains/session/task-board.ts +21 -3
  452. package/src/domains/user-tasks/handoff.ts +16 -0
  453. package/src/engine/acp/adapter.ts +44 -12
  454. package/src/engine/acp/server.ts +1 -0
  455. package/src/engine/acp/transport.ts +2 -1
  456. package/src/engine/acp/types.ts +6 -1
  457. package/src/engine/antigravity/subprocess-runtime.ts +20 -4
  458. package/src/engine/api-registry.ts +19 -2
  459. package/src/engine/apis/openai-completions.ts +13 -6
  460. package/src/engine/apis/output-budget.ts +26 -10
  461. package/src/engine/claude/sdk-runtime.ts +4 -3
  462. package/src/engine/env-api-keys.ts +2 -1
  463. package/src/engine/external-subprocess.ts +14 -3
  464. package/src/engine/loop-guard.ts +19 -2
  465. package/src/engine/provider-diagnostics.ts +129 -0
  466. package/src/engine/provider-payload.ts +3 -1
  467. package/src/engine/worker-runtime.ts +13 -2
  468. package/src/engine/worker-tools.ts +5 -1
  469. package/src/entry/extension-reload.ts +1 -0
  470. package/src/entry/orchestrator.ts +53 -15
  471. package/src/interactive/chat-loop-messages.ts +12 -4
  472. package/src/interactive/chat-loop.ts +115 -45
  473. package/src/interactive/chat-renderer.ts +60 -0
  474. package/src/interactive/context-recall-command.ts +2 -1
  475. package/src/interactive/dispatch-board.ts +17 -2
  476. package/src/interactive/editor-submit.ts +13 -0
  477. package/src/interactive/interactive-application.ts +8 -2
  478. package/src/interactive/interactive-event-projection.ts +7 -1
  479. package/src/interactive/interactive-presentation.ts +15 -7
  480. package/src/interactive/interactive-slash-runtime.ts +2 -0
  481. package/src/interactive/layout.ts +2 -1
  482. package/src/interactive/model-session-replay.ts +2 -2
  483. package/src/interactive/overlay-frame.ts +1 -0
  484. package/src/interactive/overlay-general-openers.ts +3 -1
  485. package/src/interactive/overlay-session-lifecycle.ts +6 -0
  486. package/src/interactive/overlays/ask-user.ts +1 -0
  487. package/src/interactive/overlays/message-picker.ts +1 -1
  488. package/src/interactive/renderers/tool-execution.ts +17 -1
  489. package/src/interactive/renderers/worker-entry.ts +25 -10
  490. package/src/interactive/slash-commands.ts +9 -7
  491. package/src/interactive/turn-context.ts +221 -53
  492. package/src/interactive/turn-middleware.ts +3 -1
  493. package/src/interactive/turn-persistence.ts +3 -0
  494. package/src/interactive/turn-runtime.ts +11 -2
  495. package/src/interactive/turn-state.ts +10 -9
  496. package/src/interactive/watch-pane.ts +18 -4
  497. package/src/interactive/worker-stream.ts +7 -7
  498. package/src/tools/agent-tools.ts +6 -3
  499. package/src/tools/bash.ts +1 -1
  500. package/src/tools/builtin-tool-catalog.ts +9 -2
  501. package/src/tools/codewiki/code-nav.ts +4 -10
  502. package/src/tools/compete-judge-task.ts +71 -0
  503. package/src/tools/compete-worktrees.ts +34 -0
  504. package/src/tools/context/index.ts +32 -7
  505. package/src/tools/context/surface.ts +15 -4
  506. package/src/tools/decide.ts +1 -1
  507. package/src/tools/dispatch-admission.ts +12 -1
  508. package/src/tools/dispatch-arguments.ts +38 -1
  509. package/src/tools/dispatch-plan.ts +7 -7
  510. package/src/tools/dispatch-runner.ts +48 -32
  511. package/src/tools/dispatch-schema.ts +30 -23
  512. package/src/tools/dispatch-scout-admission.ts +10 -44
  513. package/src/tools/dispatch-scout.ts +2 -3
  514. package/src/tools/find.ts +13 -4
  515. package/src/tools/grep.ts +13 -1
  516. package/src/tools/ls.ts +7 -1
  517. package/src/tools/monitor.ts +26 -11
  518. package/src/tools/network-policy.ts +11 -24
  519. package/src/tools/observation.ts +39 -2
  520. package/src/tools/read.ts +112 -15
  521. package/src/tools/registry.ts +54 -17
  522. package/src/tools/result-shaping.ts +110 -2
  523. package/src/tools/tasks.ts +33 -7
  524. package/src/tools/verify/frontend.ts +67 -30
  525. package/src/tools/verify/numeric.ts +6 -1
  526. package/src/tools/web-fetch-network.ts +179 -0
  527. package/src/tools/web-fetch-surface.ts +2 -1
  528. package/src/tools/web-fetch.ts +15 -13
  529. package/src/tools/worker-evidence.ts +27 -0
  530. package/src/worker/spec-contract.ts +12 -8
  531. package/dist/builtins-WGALA46I.js +0 -22
  532. package/dist/chunk-2WZ546HR.js +0 -792
  533. package/dist/chunk-5PSMVOLM.js +0 -56
  534. package/dist/chunk-EL24TAU4.js +0 -1560
  535. package/dist/chunk-IZXGRF7P.js +0 -4048
  536. package/dist/chunk-JVCV3ICN.js +0 -47
  537. package/dist/chunk-MNJGS2IN.js +0 -33
  538. package/dist/chunk-O5CVSAG5.js +0 -122
  539. package/dist/chunk-ODGTEFFI.js +0 -50
  540. package/dist/chunk-OQE5J4C6.js +0 -73
  541. package/dist/chunk-UUVG37B4.js +0 -244
  542. package/dist/chunk-V6HJFQZE.js +0 -228
  543. package/dist/clio-QLICPCF5.js +0 -25
  544. package/dist/configure-VEPX4NMX.js +0 -55
  545. package/dist/context-clear-S4ZJCQUX.js +0 -182
  546. package/dist/detail-A7JAVSIG.js +0 -98
  547. package/dist/evidence-4F5USFKH.js +0 -208
  548. package/dist/fleet-view-MN2VG4MR.js +0 -101
  549. package/dist/inventory-C26CFDRR.js +0 -101
  550. package/dist/preload-P6DGH2PZ.js +0 -13
  551. package/dist/slash-commands-ZXPJD64J.js +0 -92
  552. package/dist/tasks-IPAGMEIX.js +0 -36
  553. package/dist/tools-EFFEAIDP.js +0 -28
  554. package/dist/verify-FWYGPKMR.js +0 -29
  555. package/dist/wiki-generate-743CIGJW.js +0 -476
@@ -6,6 +6,7 @@
6
6
  * all flow through it.
7
7
  */
8
8
 
9
+ import { createHash } from "node:crypto";
9
10
  import {
10
11
  BusChannels,
11
12
  type ContextActivityStatus,
@@ -23,6 +24,7 @@ import {
23
24
  import type { ClioSettings } from "../core/config.js";
24
25
  import type { SafeEventBus } from "../core/event-bus.js";
25
26
  import { residencyTargetKey } from "../core/residency-target-key.js";
27
+ import type { PendingSkillToolPolicy } from "../core/skill-activation.js";
26
28
  import type { ToolName } from "../core/tool-names.js";
27
29
  import { buildEvictionFields, planEviction } from "../domains/context/working-set/engine.js";
28
30
  import { foldWorkingSet } from "../domains/context/working-set/fold.js";
@@ -45,7 +47,8 @@ import {
45
47
  DEFAULT_COMPACTION_THRESHOLD,
46
48
  shouldCompact,
47
49
  } from "../domains/session/compaction/auto.js";
48
- import type { CompactResult } from "../domains/session/compaction/compact.js";
50
+ import type { CompactInput, CompactResult } from "../domains/session/compaction/compact.js";
51
+ import { DEFAULT_KEEP_RECENT_TOKENS } from "../domains/session/compaction/defaults.js";
49
52
  import { maskStaleObservations } from "../domains/session/compaction/mask-observations.js";
50
53
  import { estimateTokens } from "../domains/session/compaction/tokens.js";
51
54
  import {
@@ -73,13 +76,15 @@ import {
73
76
  type PromptCacheStats,
74
77
  } from "../domains/session/context-ledger.js";
75
78
  import type { SessionContract } from "../domains/session/contract.js";
76
- import type { CompactionTrigger, SessionEntry } from "../domains/session/entries.js";
79
+ import { type CompactionTrigger, mainSkillContextState, type SessionEntry } from "../domains/session/entries.js";
77
80
  import {
78
81
  appendPromptCompileRecord,
79
82
  PROMPT_MANIFEST_VERSION,
80
83
  readPromptCompileRecords,
81
84
  type SessionPromptCompileRecord,
82
85
  } from "../domains/session/prompt-manifest.js";
86
+ import { filterEntriesToActivePath } from "../domains/session/tree/active-path.js";
87
+ import { resolveReservedOutputTokens } from "../engine/apis/output-budget.js";
83
88
  import type { AgentMessage, Usage } from "../engine/types.js";
84
89
  import { resolveToolPromptHint, type ToolRegistry } from "../tools/registry.js";
85
90
  import {
@@ -105,7 +110,13 @@ export interface TurnContextDeps {
105
110
  observability?: ObservabilityContract | undefined;
106
111
  bus?: SafeEventBus | undefined;
107
112
  readSessionEntries?: (() => ReadonlyArray<SessionEntry>) | undefined;
108
- autoCompact?: ((instructions?: string, trigger?: CompactionTrigger) => Promise<CompactResult | null>) | undefined;
113
+ autoCompact?:
114
+ | ((
115
+ instructions?: string,
116
+ trigger?: CompactionTrigger,
117
+ budget?: Pick<CompactInput, "keepRecentTokens" | "preserveUserTurnId" | "skillContextState" | "signal">,
118
+ ) => Promise<CompactResult | null>)
119
+ | undefined;
109
120
  /** Test seam for the eviction planner; production uses `planEviction` from the working-set engine. */
110
121
  planEviction?: typeof planEviction;
111
122
  getMemorySection?: (() => string) | undefined;
@@ -121,7 +132,7 @@ export interface LiveContextEstimate {
121
132
  * did not see.
122
133
  */
123
134
  tokens: number;
124
- /** Pure chars/4 projection, with the pre-existing provider-usage anchor. */
135
+ /** Structural projection; includes the legacy usage floor when no live anchor is trusted. */
125
136
  estimatedTokens: number;
126
137
  /**
127
138
  * Provider-attested prompt tokens for the messages up to the last reconciled
@@ -187,7 +198,10 @@ export interface TurnContext {
187
198
  instructions?: string,
188
199
  triggerOverride?: CompactionTrigger,
189
200
  pendingUserText?: string,
201
+ pendingSkillPolicy?: PendingSkillToolPolicy,
202
+ signal?: AbortSignal,
190
203
  ): Promise<boolean>;
204
+ cancelCompaction(): void;
191
205
  postToolContinuationGuard(
192
206
  agentRuntime: AgentRuntime,
193
207
  signal?: AbortSignal,
@@ -244,6 +258,7 @@ function evictionSkipMessage(
244
258
  export function createTurnContext(deps: TurnContextDeps): TurnContext {
245
259
  const { state, middleware } = deps;
246
260
  const compactionTrigger = new AutoCompactionTrigger<CompactResult | null>();
261
+ let compactionController: AbortController | null = null;
247
262
 
248
263
  let currentContextSnapshot: ContextSnapshot | null = null;
249
264
  /**
@@ -252,14 +267,25 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
252
267
  *
253
268
  * `tokens` is the provider's own prompt count for that call plus the output
254
269
  * it produced, which together are what the next call's prompt carries for
255
- * the same messages. `anchoredMessageCount` is the length of the live
256
- * message list at that moment, so anything appended since is priced by
257
- * estimate and added on top. Unlike the per-message usage anchor inside
270
+ * the same messages. The anchored message prefix identifies that history,
271
+ * so anything appended since is priced by estimate and added on top.
272
+ * Unlike the per-message usage anchor inside
258
273
  * `estimateAgentContextTokens`, this survives `contextUsageInvalidated`:
259
274
  * a working-set projection subtracts the tokens it removed rather than
260
275
  * throwing the attestation away.
261
276
  */
262
- let reconciledAnchor: { tokens: number; anchoredMessageCount: number } | null = null;
277
+ let reconciledAnchor: {
278
+ tokens: number;
279
+ anchoredMessages: ReadonlyArray<AgentMessage>;
280
+ runtime: AgentRuntime;
281
+ model: AgentRuntime["agent"]["state"]["model"];
282
+ modelKey: string;
283
+ targetId: string;
284
+ runtimeId: string;
285
+ wireModelId: string;
286
+ systemPromptTokens: number;
287
+ toolSchemaTokens: number;
288
+ } | null = null;
263
289
  let lastCompactionEvent: { stage: string; tokensBefore: number; tokensAfter: number; trigger: string } | null = null;
264
290
  // Last settled run's provider cache usage plus whether the compiled system
265
291
  // prompt was reused. Shown together in /context so "prompt reused" can
@@ -292,11 +318,10 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
292
318
  let resumedPromptHash: string | null = null;
293
319
  const sessionWorkingContextPaths = new Set<string>();
294
320
  let pendingPromptLogEntry: SessionPromptCompileRecord | null = null;
295
- // A post-tool guard can run after every tool result in one model turn. Once
296
- // both automatic stages report that they have nothing to do, remember that
297
- // stable user-turn id so the remaining results do not repeat the same plan
298
- // and summary probes. A new submitted user turn gets a new id naturally.
299
- let emptyAutoCompactTurnId: string | null = null;
321
+ // Reuse an empty automatic attempt only for identical ledger and provider
322
+ // context. Same-turn tool growth or same-length content replacement must
323
+ // get a fresh cut; ordinary below-threshold checks never fingerprint it.
324
+ let emptyAutoCompactContextKey: string | null = null;
300
325
 
301
326
  // Cache-disturbance honesty (T3.3). Accumulate every known local-runtime
302
327
  // disturbance and prefix-byte change since the last settled run. The next
@@ -549,27 +574,36 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
549
574
  return { contextWindow: 0, contextWindowSource: null, contextWindowSlots: null };
550
575
  };
551
576
 
552
- /**
553
- * Carry the reconciled anchor onto the current message list: the attested
554
- * prompt for the messages it covered, plus a chars/4 estimate of everything
555
- * appended since, plus text that has not been submitted yet. The tool
556
- * schemas and the system prompt are inside the attested figure already, so
557
- * they are not added again. Null when there is no attestation, or when the
558
- * list is shorter than the anchor covered, which means the history it
559
- * described was rewritten beneath it.
560
- */
561
- const reconciledAnchoredTokens = (agentRuntime: AgentRuntime, pendingUserTokens: number): number | null => {
577
+ const anchorModelKey = (agentRuntime: AgentRuntime): string => {
578
+ const model = agentRuntime.agent.state.model;
579
+ return JSON.stringify([model?.id, model?.provider, model?.api, model?.baseUrl]);
580
+ };
581
+
582
+ /** Price appended history separately so eviction can retain it without folding in static growth twice. */
583
+ const reconciledHistoryTokens = (agentRuntime: AgentRuntime): number | null => {
562
584
  const anchor = reconciledAnchor;
563
585
  if (!anchor) return null;
564
586
  const messages = agentRuntime.agent.state.messages;
565
- if (anchor.anchoredMessageCount > messages.length) return null;
587
+ if (
588
+ anchor.runtime !== agentRuntime ||
589
+ anchor.model !== agentRuntime.agent.state.model ||
590
+ anchor.modelKey !== anchorModelKey(agentRuntime) ||
591
+ anchor.targetId !== agentRuntime.targetId ||
592
+ anchor.runtimeId !== agentRuntime.runtimeId ||
593
+ anchor.wireModelId !== agentRuntime.wireModelId ||
594
+ anchor.anchoredMessages.length > messages.length ||
595
+ anchor.anchoredMessages.some((message, index) => message !== messages[index])
596
+ ) {
597
+ reconciledAnchor = null;
598
+ return null;
599
+ }
566
600
  let tail = 0;
567
- for (let i = anchor.anchoredMessageCount; i < messages.length; i += 1) {
601
+ for (let i = anchor.anchoredMessages.length; i < messages.length; i += 1) {
568
602
  const message = messages[i];
569
603
  if (message === undefined) continue;
570
604
  tail += estimateAgentMessageTokens(message);
571
605
  }
572
- return anchor.tokens + tail + pendingUserTokens;
606
+ return anchor.tokens + tail;
573
607
  };
574
608
 
575
609
  const liveContextEstimate = (agentRuntime: AgentRuntime, pendingUserText?: string): LiveContextEstimate => {
@@ -581,8 +615,22 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
581
615
  ...(pendingUserText !== undefined ? { pendingUserText } : {}),
582
616
  };
583
617
  const breakdown = estimateAgentContextBreakdown(estimateInput);
584
- const estimatedTokens = estimateAgentContextTokens(estimateInput);
585
- const reconciledTokens = reconciledAnchoredTokens(agentRuntime, breakdown.pendingUserTokens);
618
+ const historyTokens = reconciledHistoryTokens(agentRuntime);
619
+ const anchor = reconciledAnchor;
620
+ // Provider usage already includes the old system prompt and schemas.
621
+ // Price only positive growth, separately: shrinking one must not hide
622
+ // growth in the other when the measured prompt exceeds chars/4.
623
+ const reconciledTokens =
624
+ historyTokens !== null && anchor
625
+ ? historyTokens +
626
+ breakdown.pendingUserTokens +
627
+ Math.max(0, breakdown.systemPromptTokens - anchor.systemPromptTokens) +
628
+ Math.max(0, breakdown.toolSchemaTokens - anchor.toolSchemaTokens)
629
+ : null;
630
+ const estimatedTokens =
631
+ reconciledTokens === null
632
+ ? estimateAgentContextTokens(estimateInput)
633
+ : breakdown.systemPromptTokens + breakdown.messageTokens + breakdown.pendingUserTokens + breakdown.toolSchemaTokens;
586
634
  return {
587
635
  // The estimate is a floor, not a competing verdict: it prices material
588
636
  // the attested call never saw, so a provider count below it would be
@@ -601,13 +649,20 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
601
649
  * what the planner priced out against the same projection and re-anchor on
602
650
  * the refreshed list, instead of discarding the figure and falling back to
603
651
  * pure chars/4 exactly when the accounting matters most (issue #227).
604
- * Call after the message list has been rebuilt.
652
+ * Materialize history before rebuilding the list; otherwise advancing the
653
+ * anchor would lose tool results appended since the last measured call.
654
+ * Static baselines stay tied to that call until the next reconciliation.
605
655
  */
606
- const carryReconciledAnchorThroughProjection = (agentRuntime: AgentRuntime, tokensRemoved: number): void => {
607
- if (!reconciledAnchor) return;
656
+ const carryReconciledAnchorThroughProjection = (
657
+ agentRuntime: AgentRuntime,
658
+ historyTokens: number | null,
659
+ tokensRemoved: number,
660
+ ): void => {
661
+ if (!reconciledAnchor || historyTokens === null) return;
608
662
  reconciledAnchor = {
609
- tokens: Math.max(0, reconciledAnchor.tokens - Math.max(0, tokensRemoved)),
610
- anchoredMessageCount: agentRuntime.agent.state.messages.length,
663
+ ...reconciledAnchor,
664
+ tokens: Math.max(0, historyTokens - Math.max(0, tokensRemoved)),
665
+ anchoredMessages: [...agentRuntime.agent.state.messages],
611
666
  };
612
667
  };
613
668
 
@@ -679,14 +734,57 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
679
734
  instructions?: string,
680
735
  triggerOverride?: CompactionTrigger,
681
736
  pendingUserText?: string,
737
+ pendingSkillPolicy?: PendingSkillToolPolicy,
738
+ signal?: AbortSignal,
682
739
  ): Promise<boolean> => {
683
740
  if (!deps.readSessionEntries) return false;
684
- const activeAutoTurnId = force ? null : state.activeUserTurnId;
685
- if (activeAutoTurnId && emptyAutoCompactTurnId === activeAutoTurnId) return false;
741
+ // Overflow forces a fit attempt even below the automatic threshold, but
742
+ // still needs the request budget and active task. Manual force keeps its defaults.
743
+ const useRequestBudget = !force || triggerOverride === "overflow";
744
+ const activeAutoTurnId = useRequestBudget ? state.activeUserTurnId : null;
745
+ const skillContextState = mainSkillContextState(
746
+ filterEntriesToActivePath(deps.readSessionEntries(), state.lastTurnId ?? undefined),
747
+ pendingSkillPolicy ?? state.currentPendingSkillPolicy ?? state.activeSkillSurface,
748
+ );
686
749
  const settings = deps.getSettings();
687
750
  const cfg = settings.context.compaction;
688
751
  const autoEnabled = cfg?.auto !== false;
689
752
  if (!force && !autoEnabled) return false;
753
+ const compactionThreshold = cfg?.threshold ?? DEFAULT_COMPACTION_THRESHOLD;
754
+ const pressureEstimate = force ? null : liveContextEstimate(agentRuntime, pendingUserText);
755
+ if (
756
+ pressureEstimate &&
757
+ !shouldCompact(pressureEstimate.tokens, compactionThreshold, pressureEstimate.contextWindow).shouldCompact
758
+ )
759
+ return false;
760
+ // Empty cuts are reusable only while their source and provider context
761
+ // remain unchanged. Tools can grow the same user turn into a useful cut.
762
+ const attemptKey =
763
+ !force && activeAutoTurnId
764
+ ? createHash("sha256")
765
+ .update(
766
+ JSON.stringify({
767
+ turn: activeAutoTurnId,
768
+ leaf: state.lastTurnId,
769
+ entries: deps.readSessionEntries(),
770
+ context: {
771
+ systemPrompt: agentRuntime.agent.state.systemPrompt,
772
+ messages: agentRuntime.agent.state.messages,
773
+ tools: agentRuntime.agent.state.tools,
774
+ model: agentRuntime.agent.state.model,
775
+ thinkingLevel: agentRuntime.agent.state.thinkingLevel,
776
+ },
777
+ pendingUserText,
778
+ skillContextState,
779
+ estimate: pressureEstimate,
780
+ compaction: cfg,
781
+ workingSet: settings.context.workingSet,
782
+ output: settings.chat.maxOutputTokens,
783
+ }),
784
+ )
785
+ .digest("hex")
786
+ : null;
787
+ if (attemptKey && emptyAutoCompactContextKey === attemptKey) return false;
690
788
  let preSummaryStageActed = false;
691
789
  // G1 from smoke pass 2: a short session generates all its pressure inside
692
790
  // the protection window, the non-destructive layer finds nothing, and the
@@ -695,16 +793,14 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
695
793
  // actually follows.
696
794
  let evictionSkipNotice: string | null = null;
697
795
  const rememberEmptyAutomaticAttempt = (): void => {
698
- if (!force && !preSummaryStageActed && activeAutoTurnId) emptyAutoCompactTurnId = activeAutoTurnId;
796
+ if (!force && !preSummaryStageActed && attemptKey) emptyAutoCompactContextKey = attemptKey;
699
797
  };
700
798
 
701
- const compactionThreshold = cfg?.threshold ?? DEFAULT_COMPACTION_THRESHOLD;
702
799
  const trigger: CompactionTrigger = triggerOverride ?? (force ? "force" : "auto");
703
800
 
704
- if (!force) {
705
- const estimate = liveContextEstimate(agentRuntime, pendingUserText);
801
+ if (pressureEstimate) {
802
+ const estimate = pressureEstimate;
706
803
  const verdict = shouldCompact(estimate.tokens, compactionThreshold, estimate.contextWindow);
707
- if (!verdict.shouldCompact) return false;
708
804
 
709
805
  // One-release compatibility escape hatch. This is the destructive
710
806
  // pre-stage that working-set eviction replaces; keep it byte-for-byte
@@ -808,6 +904,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
808
904
  middleware.fireCompactionHook("working_set_evict", "pressure", estimate.tokens);
809
905
  emitCompactionActivity("started", "compacting context (working-set eviction)");
810
906
  try {
907
+ const historyTokens = reconciledHistoryTokens(agentRuntime);
811
908
  deps.session.appendEntry({
812
909
  ...buildEvictionFields(planned, {
813
910
  trigger: "pressure",
@@ -820,7 +917,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
820
917
  });
821
918
  noteColdReason("working_set_evict");
822
919
  refreshAgentMessagesFromSession(agentRuntime);
823
- carryReconciledAnchorThroughProjection(agentRuntime, planned.tokensBefore - planned.tokensAfter);
920
+ carryReconciledAnchorThroughProjection(agentRuntime, historyTokens, planned.tokensBefore - planned.tokensAfter);
824
921
 
825
922
  const postEvictionSnapshot = captureRuntimeContextSnapshot(
826
923
  agentRuntime,
@@ -898,13 +995,69 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
898
995
  // useful ahead of it.
899
996
  if (evictionSkipNotice) deps.emitNotice(evictionSkipNotice);
900
997
  let result: CompactResult | null = null;
901
- const beforeSnapshotId = currentContextSnapshot?.snapshotId ?? null;
998
+ // Compare full runtime estimates on both sides. The current snapshot and
999
+ // result.tokensBefore may instead carry provider-calibrated history usage.
1000
+ const snapshotMetadata =
1001
+ currentContextSnapshot && currentContextSnapshot.systemPrompt === agentRuntime.agent.state.systemPrompt
1002
+ ? { promptSegments: currentContextSnapshot.promptSegments, promptHash: currentContextSnapshot.promptHash }
1003
+ : {};
1004
+ const preCompactSnapshot = captureRuntimeContextSnapshot(
1005
+ agentRuntime,
1006
+ state.activeUserTurnId || "compaction",
1007
+ compactionThreshold,
1008
+ snapshotMetadata,
1009
+ );
1010
+ let budget:
1011
+ | Pick<CompactInput, "keepRecentTokens" | "preserveUserTurnId" | "skillContextState" | "signal">
1012
+ | undefined = skillContextState !== undefined ? { skillContextState } : undefined;
1013
+ if (useRequestBudget) {
1014
+ const estimate = liveContextEstimate(agentRuntime, pendingUserText);
1015
+ const output = Math.min(
1016
+ resolveReservedOutputTokens(agentRuntime.agent.state.model?.maxTokens, {
1017
+ api: agentRuntime.agent.state.model?.api ?? "",
1018
+ contextWindow: estimate.contextWindow,
1019
+ inputTokens: estimate.tokens,
1020
+ }),
1021
+ settings.chat.maxOutputTokens > 0 ? settings.chat.maxOutputTokens : Number.POSITIVE_INFINITY,
1022
+ );
1023
+ const inputTarget = Math.min(estimate.contextWindow * compactionThreshold, estimate.contextWindow - output);
1024
+ const staticTokens = estimate.breakdown.systemPromptTokens + estimate.breakdown.toolSchemaTokens;
1025
+ const calibration = Math.max(
1026
+ 0,
1027
+ estimate.tokens - staticTokens - estimate.breakdown.messageTokens - estimate.breakdown.pendingUserTokens,
1028
+ );
1029
+ // Split available history space between the recent suffix and the
1030
+ // checkpoint (including verbatim active instructions). The cut remains
1031
+ // structural, so the unchanged continuation guard verifies the result.
1032
+ const historyBudget = inputTarget - staticTokens - estimate.breakdown.pendingUserTokens - calibration;
1033
+ budget = {
1034
+ ...budget,
1035
+ keepRecentTokens: Math.min(DEFAULT_KEEP_RECENT_TOKENS, Math.max(1, Math.floor(historyBudget / 2))),
1036
+ ...(activeAutoTurnId ? { preserveUserTurnId: activeAutoTurnId } : {}),
1037
+ };
1038
+ }
1039
+ let summarySignal = compactionController?.signal;
902
1040
  try {
903
- result = await compactionTrigger.fire(() => (deps.autoCompact ?? (async () => null))(instructions, trigger));
1041
+ result = await compactionTrigger.fire(async () => {
1042
+ const controller = new AbortController();
1043
+ compactionController = controller;
1044
+ summarySignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
1045
+ try {
1046
+ return (
1047
+ (await deps.autoCompact?.(instructions, trigger, {
1048
+ ...budget,
1049
+ signal: summarySignal,
1050
+ })) ?? null
1051
+ );
1052
+ } finally {
1053
+ if (compactionController === controller) compactionController = null;
1054
+ }
1055
+ });
904
1056
  } catch (error) {
905
1057
  if (!summaryLifecycleStarted) startSummaryLifecycle();
906
1058
  emitCompactionActivity("failed", compactionFailureMessage(error));
907
1059
  deps.bus?.emit(BusChannels.CompactionEnd, { trigger, at: Date.now() });
1060
+ summarySignal?.throwIfAborted();
908
1061
  throw error;
909
1062
  }
910
1063
  if (!result || result.summary.length === 0) {
@@ -934,33 +1087,36 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
934
1087
  agentRuntime,
935
1088
  state.activeUserTurnId || "compaction",
936
1089
  compactionThreshold,
1090
+ snapshotMetadata,
937
1091
  );
938
1092
  currentContextSnapshot = postCompactSnapshot;
1093
+ persistContextSnapshot(preCompactSnapshot);
939
1094
  persistContextSnapshot(postCompactSnapshot);
940
1095
 
1096
+ const tokensBefore = snapshotInputTokens(preCompactSnapshot);
941
1097
  const tokensAfter = snapshotInputTokens(postCompactSnapshot);
942
1098
  lastCompactionEvent = {
943
1099
  stage: "llm_summary",
944
- tokensBefore: result.tokensBefore,
1100
+ tokensBefore,
945
1101
  tokensAfter,
946
1102
  trigger,
947
1103
  };
948
1104
  deps.bus?.emit(BusChannels.ContextPruned, {
949
1105
  stage: "llm_summary",
950
- tokensBefore: result.tokensBefore,
1106
+ tokensBefore,
951
1107
  tokensAfter,
952
1108
  trigger,
953
- snapshotIdBefore: beforeSnapshotId,
1109
+ snapshotIdBefore: preCompactSnapshot.snapshotId,
954
1110
  snapshotIdAfter: postCompactSnapshot.snapshotId,
955
1111
  at: Date.now(),
956
1112
  } satisfies ContextPrunedPayload);
957
- emitCompactionActivity("completed", `compacted ~${result.tokensBefore} -> ~${tokensAfter} tokens`);
1113
+ emitCompactionActivity("completed", `compacted ~${tokensBefore} -> ~${tokensAfter} tokens`);
958
1114
 
959
1115
  deps.emitNotice(
960
1116
  renderCompactionSummaryLine({
961
1117
  messagesSummarized: result.messagesSummarized,
962
1118
  summaryChars: result.summary.length,
963
- tokensBefore: result.tokensBefore,
1119
+ tokensBefore,
964
1120
  isSplitTurn: result.isSplitTurn,
965
1121
  }),
966
1122
  );
@@ -990,6 +1146,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
990
1146
  rememberedLoadedContextWindow,
991
1147
  refreshAgentMessagesFromSession,
992
1148
  runAutoCompact,
1149
+ cancelCompaction: () => compactionController?.abort(),
993
1150
 
994
1151
  setCurrentSnapshot(snapshot: ContextSnapshot): void {
995
1152
  currentContextSnapshot = snapshot;
@@ -1004,13 +1161,22 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
1004
1161
  // Cached prompt tokens still occupy the window; providers report them
1005
1162
  // outside `input`, so the attested prompt is the three summed.
1006
1163
  const promptTokens = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
1007
- const messages = state.runtime?.agent.state.messages;
1008
- if (promptTokens > 0 && messages) {
1164
+ const runtime = state.runtime;
1165
+ if (promptTokens > 0 && runtime) {
1166
+ const breakdown = estimateAgentContextBreakdown({ ...runtime.agent.state, messages: [] });
1009
1167
  // The output of this call is part of the next call's prompt for the
1010
1168
  // same messages, which is why it is folded in here.
1011
1169
  reconciledAnchor = {
1012
1170
  tokens: promptTokens + (usage.output || 0),
1013
- anchoredMessageCount: messages.length,
1171
+ anchoredMessages: [...runtime.agent.state.messages],
1172
+ runtime,
1173
+ model: runtime.agent.state.model,
1174
+ modelKey: anchorModelKey(runtime),
1175
+ targetId: runtime.targetId,
1176
+ runtimeId: runtime.runtimeId,
1177
+ wireModelId: runtime.wireModelId,
1178
+ systemPromptTokens: breakdown.systemPromptTokens,
1179
+ toolSchemaTokens: breakdown.toolSchemaTokens,
1014
1180
  };
1015
1181
  }
1016
1182
  if (!currentContextSnapshot) return;
@@ -1199,7 +1365,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
1199
1365
  let compacted = false;
1200
1366
  if (verdict.shouldCompact) {
1201
1367
  try {
1202
- compacted = await runAutoCompact(agentRuntime, false, undefined, "auto");
1368
+ compacted = await runAutoCompact(agentRuntime, false, undefined, "auto", undefined, undefined, signal);
1203
1369
  } catch (err) {
1204
1370
  throw new Error(
1205
1371
  `[Clio Coder] post-tool context guard could not compact before continuation: ${err instanceof Error ? err.message : String(err)}`,
@@ -1379,6 +1545,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
1379
1545
  },
1380
1546
 
1381
1547
  resetForSession(): void {
1548
+ compactionController?.abort();
1382
1549
  // An in-process switch replaces the whole prefix: the backend's slot
1383
1550
  // still holds the outgoing session's prompt and history, so the first
1384
1551
  // turn on the incoming one is expected-cold on every tier, exactly as
@@ -1397,13 +1564,14 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
1397
1564
  resumedPromptHash = null;
1398
1565
  sessionWorkingContextPaths.clear();
1399
1566
  pendingPromptLogEntry = null;
1400
- emptyAutoCompactTurnId = null;
1567
+ emptyAutoCompactContextKey = null;
1401
1568
  reconciledAnchor = null;
1402
1569
  const session = deps.session?.current();
1403
1570
  currentContextSnapshot = session ? getLatestContextSnapshot(session) : null;
1404
1571
  },
1405
1572
 
1406
1573
  dispose(): void {
1574
+ compactionController?.abort();
1407
1575
  for (const unsubscribe of unsubscribeColdReasonSources) unsubscribe?.();
1408
1576
  },
1409
1577
  };
@@ -268,7 +268,9 @@ export function createTurnMiddleware(deps: TurnMiddlewareDeps): TurnMiddleware {
268
268
 
269
269
  flushPendingReminders(): string {
270
270
  if (pendingReminders.length === 0) return "";
271
- const messages = pendingReminders.map((entry) => entry.message);
271
+ // Severity affects host actions, not the text delivered to the model.
272
+ // A paired continuation/info and reminder/warn still needs one copy.
273
+ const messages = [...new Set(pendingReminders.map((entry) => entry.message))];
272
274
  pendingReminders.length = 0;
273
275
  return `<system-reminder>\n${messages.join("\n\n")}\n</system-reminder>`;
274
276
  },
@@ -17,6 +17,7 @@ import {
17
17
  type AssistantCallTiming,
18
18
  assistantSessionPayload,
19
19
  estimatedUsageForInterruptedTurn,
20
+ explainInterruptedAssistant,
20
21
  extractUserText,
21
22
  hasPersistableAssistantContent,
22
23
  hasStructuredToolCall,
@@ -220,10 +221,12 @@ export function createTurnPersistence(deps: TurnPersistenceDeps): TurnPersistenc
220
221
 
221
222
  const appendAssistantTurn = (message: AgentMessage, timing?: AssistantCallTiming | null): void => {
222
223
  if (message?.role !== "assistant") return;
224
+ if (persistedAssistantMessages.has(message)) return;
223
225
  // A loop-guard interrupt already persisted a durable closing turn with the
224
226
  // stop reason; drop the empty aborted message the abort leaves behind so
225
227
  // the operator does not see a hollow "request aborted" turn after it.
226
228
  if (state.activeInterruptReason !== null && isEmptyAbortedAssistantMessage(message)) return;
229
+ if (explainInterruptedAssistant(message, state.activeInterruptReason)) state.interruptedAssistantMessage = message;
227
230
  const failure = terminalFailureFromAssistantMessage(message);
228
231
  const payload = assistantSessionPayload(message, failure);
229
232
  if (timing) payload.timing = timing;
@@ -32,7 +32,7 @@ import {
32
32
  patchToolChoiceNonePayload,
33
33
  } from "../engine/provider-payload.js";
34
34
  import type { AgentEvent, AgentMessage, EngineModel, Usage } from "../engine/types.js";
35
- import type { resolveAgentTools, ToolOutcome, ToolTelemetry } from "../tools/agent-tools.js";
35
+ import type { resolveAgentTools, ToolFinishEvent, ToolTelemetry } from "../tools/agent-tools.js";
36
36
  import {
37
37
  type AssistantCallTiming,
38
38
  type BackendCacheVerdict,
@@ -162,7 +162,10 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
162
162
  * a call whose end event never arrives leaves at most one stale entry, which
163
163
  * the next run with the same id would overwrite.
164
164
  */
165
- const toolOutcomes = new Map<string, { outcome: ToolOutcome; reason?: string; durationMs: number }>();
165
+ const toolOutcomes = new Map<
166
+ string,
167
+ Pick<ToolFinishEvent, "outcome" | "reason" | "durationMs" | "ruleId" | "reasonCode" | "policySource">
168
+ >();
166
169
  const toolTelemetry: ToolTelemetry = {
167
170
  onFinish(event) {
168
171
  if (event.toolCallId === undefined) return;
@@ -170,6 +173,9 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
170
173
  outcome: event.outcome,
171
174
  ...(event.reason === undefined ? {} : { reason: event.reason }),
172
175
  durationMs: event.durationMs,
176
+ ...(event.ruleId === undefined ? {} : { ruleId: event.ruleId }),
177
+ ...(event.reasonCode === undefined ? {} : { reasonCode: event.reasonCode }),
178
+ ...(event.policySource === undefined ? {} : { policySource: event.policySource }),
173
179
  });
174
180
  },
175
181
  };
@@ -651,6 +657,9 @@ export function createTurnRuntime(deps: TurnRuntimeDeps): TurnRuntime {
651
657
  ? {}
652
658
  : {
653
659
  outcome: admission.outcome,
660
+ ...(admission.ruleId === undefined ? {} : { ruleId: admission.ruleId }),
661
+ ...(admission.reasonCode === undefined ? {} : { reasonCode: admission.reasonCode }),
662
+ ...(admission.policySource === undefined ? {} : { policySource: admission.policySource }),
654
663
  ...(admission.reason === undefined ? {} : { blockReason: admission.reason }),
655
664
  }),
656
665
  } as typeof event;
@@ -88,19 +88,19 @@ export interface ChatTurnState {
88
88
  /** The user turn id of the in-flight submit; null between turns. */
89
89
  activeUserTurnId: string | null;
90
90
  /**
91
- * Set by a loop-guard interrupt (cancel with a reason). While set, the empty
92
- * aborted assistant messages the abort produces are suppressed in both the
93
- * ledger and the live transcript; the durable closing turn carrying the
94
- * reason is persisted when the run settles (submit's finally), after the
95
- * in-flight tool results have landed. Cleared there, and defensively at the
96
- * start of each submit.
91
+ * Set by an operator or explained interrupt. A nonempty aborted assistant
92
+ * carries this reason; hollow abort messages are suppressed and replaced
93
+ * by one durable closing turn after in-flight tool results have landed.
94
+ * Cleared at settlement and defensively at the start of each submit.
97
95
  */
98
96
  activeInterruptReason: string | null;
97
+ /** The provider's nonempty aborted message closes this interrupt without a synthetic second assistant. */
98
+ interruptedAssistantMessage: AgentMessage | null;
99
99
  /**
100
100
  * Estimated spend of the cancelled call whose hollow aborted message the
101
- * interrupt suppressed (thinking streamed, no text). The message never reaches
102
- * the ledger, so the closing turn persisted in submit's finally carries this
103
- * instead of an estimate derived from its own notice text. Cleared with
101
+ * interrupt suppressed. The message never reaches the ledger, so the closing
102
+ * turn persisted in submit's finally carries this instead of an estimate
103
+ * derived from its own notice text. Cleared with
104
104
  * `activeInterruptReason`.
105
105
  */
106
106
  interruptedUsage: Record<string, unknown> | null;
@@ -148,6 +148,7 @@ export function createTurnState(initialThinkingLevel: ThinkingLevel): ChatTurnSt
148
148
  replayedContextMessages: [],
149
149
  activeUserTurnId: null,
150
150
  activeInterruptReason: null,
151
+ interruptedAssistantMessage: null,
151
152
  interruptedUsage: null,
152
153
  synthesisToolLock: false,
153
154
  toolProseAbortReason: null,
@@ -21,7 +21,7 @@
21
21
  import { mkdirSync, renameSync, writeFileSync } from "node:fs";
22
22
  import { dirname, join } from "node:path";
23
23
  import { type ClioDirs, clioCacheDir, clioConfigDir, clioDataDir, clioStateDir } from "../core/xdg.js";
24
- import type { MuxContract, MuxPaneRef } from "../domains/mux/index.js";
24
+ import type { MuxContract, MuxPaneOpenFailure, MuxPaneRef } from "../domains/mux/index.js";
25
25
  import type { PanesWatchController, PanesWatchResult } from "../domains/mux/operations.js";
26
26
  import { watchViewerCommand } from "../domains/mux/viewer-command.js";
27
27
 
@@ -115,8 +115,9 @@ export function createWatchPaneController(deps: WatchPaneDeps): PanesWatchContro
115
115
  * of Clio's pane at the configured share. On a host without the layout tier
116
116
  * the dock request degrades inside the contract to a plain right split.
117
117
  */
118
- const openPane = (): Promise<MuxPaneRef | null> =>
118
+ const openPane = (onFailure?: (failure: MuxPaneOpenFailure) => void): Promise<MuxPaneRef | null> =>
119
119
  deps.mux.openUtilityPane({
120
+ ...(onFailure ? { onFailure } : {}),
120
121
  argv: command(selectionPath, dirs),
121
122
  cwd: deps.getCwd(),
122
123
  label: "watch",
@@ -152,9 +153,22 @@ export function createWatchPaneController(deps: WatchPaneDeps): PanesWatchContro
152
153
  const scanned = await adoptExistingPane();
153
154
  if (!scanned) await adoptExistingPane();
154
155
  if (paneId !== null) return { status: "watching", runId, paneId, opened: false };
155
- const opened = await openPane();
156
+ let reason =
157
+ "cannot open the watch pane: no failure reason was supplied by the pane host; check /panes before trying again";
158
+ const opened = await openPane((failure) => {
159
+ if (failure.source === "local") {
160
+ reason = `cannot open the watch pane locally: ${failure.message}`;
161
+ } else {
162
+ const details = [
163
+ `kind=${failure.kind}`,
164
+ ...(failure.wireCode === null ? [] : [`code=${failure.wireCode}`]),
165
+ ...(failure.method === null ? [] : [`method=${failure.method}`]),
166
+ ];
167
+ reason = `cannot open the watch pane (${details.join(", ")}): ${failure.message || "no failure message was supplied by the pane host"}`;
168
+ }
169
+ });
156
170
  if (opened === null) {
157
- return { status: "unavailable", reason: "the pane host refused to open the watch pane" };
171
+ return { status: "unavailable", reason };
158
172
  }
159
173
  paneId = opened.paneId;
160
174
  return { status: "watching", runId, paneId, opened: true };