@iowarp/clio-coder 0.4.4 → 0.4.6

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 (598) hide show
  1. package/CHANGELOG.md +116 -2
  2. package/CONTRIBUTING.md +39 -24
  3. package/NOTICE +16 -0
  4. package/README.md +343 -403
  5. package/dist/{acp-WNAYYF4F.js → acp-UVEVWSDL.js} +25 -24
  6. package/dist/{agents-3OKXHLOI.js → agents-VWY37DTK.js} +78 -77
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-VKNNMGPU.js → auth-PCV2XQDV.js} +38 -38
  9. package/dist/builtins-PD652MTK.js +22 -0
  10. package/dist/{chunk-TQAHXW6Y.js → chunk-22PQ4TX4.js} +4 -4
  11. package/dist/{chunk-NRO2BJRH.js → chunk-24T2YZ7A.js} +10686 -4464
  12. package/dist/{chunk-Y55JBDO5.js → chunk-2AKYFREM.js} +38 -23
  13. package/dist/{chunk-NEDJ26B5.js → chunk-2GPGAE5W.js} +6 -51
  14. package/dist/{chunk-IKCO5N3L.js → chunk-2QPI3TR3.js} +3 -3
  15. package/dist/{chunk-HRQMFLJP.js → chunk-32KJPXAM.js} +6 -6
  16. package/dist/{chunk-65DEGPJ6.js → chunk-3A3CUMKA.js} +6 -4
  17. package/dist/{chunk-UXCU4E3T.js → chunk-3BJGMT2D.js} +35 -14
  18. package/dist/{chunk-5ICU3EUH.js → chunk-3HQVBIKD.js} +5 -5
  19. package/dist/{chunk-GWZNEVM2.js → chunk-3JLFK5MW.js} +9 -9
  20. package/dist/{chunk-XXYSBZIQ.js → chunk-3O2ZAUGQ.js} +4 -4
  21. package/dist/{chunk-GX5WYQO4.js → chunk-3QKXHCGS.js} +8 -8
  22. package/dist/{chunk-JCI2ROMZ.js → chunk-3T4DXWP6.js} +7 -7
  23. package/dist/{chunk-DR52UMZW.js → chunk-3UW3KU4A.js} +2 -2
  24. package/dist/{chunk-OEJSLEPW.js → chunk-3WBALRQH.js} +337 -337
  25. package/dist/{chunk-ELWDPP3Y.js → chunk-4DU2TVI4.js} +8 -8
  26. package/dist/{chunk-JSD46VO2.js → chunk-4U4TKZFR.js} +43 -36
  27. package/dist/{chunk-FEAXX7B6.js → chunk-4VMV6OS6.js} +4 -4
  28. package/dist/{chunk-2ZSONWVL.js → chunk-536HXRFE.js} +13 -13
  29. package/dist/{chunk-W54I7H25.js → chunk-5A6XR3RJ.js} +44 -19
  30. package/dist/{chunk-YPC6ZR5L.js → chunk-5CMARGPF.js} +119 -5
  31. package/dist/{chunk-KXDSS5WJ.js → chunk-5CY4Q6QI.js} +4 -4
  32. package/dist/{chunk-D4CJV46V.js → chunk-5GZICIYO.js} +3 -3
  33. package/dist/{chunk-4IUZQIJ3.js → chunk-5PHVPU4G.js} +2 -2
  34. package/dist/{chunk-Q4WO54TA.js → chunk-5QRX7SLS.js} +11 -11
  35. package/dist/{chunk-3ODX73FK.js → chunk-5VTJP36Q.js} +4 -4
  36. package/dist/chunk-5ZSZEYJK.js +119 -0
  37. package/dist/{chunk-EBY63B7G.js → chunk-6EXUUOSN.js} +2 -2
  38. package/dist/{chunk-DT3LWJOB.js → chunk-6HAO6X5B.js} +24 -6
  39. package/dist/{chunk-SVNXH4L2.js → chunk-6ICZKDUC.js} +2 -2
  40. package/dist/{chunk-K6T2ZAMZ.js → chunk-6OII3LOK.js} +6 -6
  41. package/dist/{chunk-36CT5VVL.js → chunk-6RYDAVQT.js} +138 -89
  42. package/dist/{chunk-I7XBWTYH.js → chunk-6VRRJT7L.js} +5 -5
  43. package/dist/{chunk-DQOVN6KV.js → chunk-6YA46L5A.js} +4 -4
  44. package/dist/{chunk-NZMNUPZZ.js → chunk-77CZRFTE.js} +3 -3
  45. package/dist/{chunk-NAI6ZFCY.js → chunk-7JSSKXG2.js} +122 -11
  46. package/dist/{chunk-2VTFPG5O.js → chunk-7WLRF2U5.js} +2 -2
  47. package/dist/chunk-7WUZEB2M.js +165 -0
  48. package/dist/{chunk-3UUXNFEX.js → chunk-7YJWEF2L.js} +61 -34
  49. package/dist/{chunk-3EBYEESD.js → chunk-A46ILRS2.js} +5 -5
  50. package/dist/{chunk-IXIY2H4R.js → chunk-ACCKVSHU.js} +5 -5
  51. package/dist/{chunk-UOIZ7DA4.js → chunk-AP7HDJOP.js} +2 -2
  52. package/dist/{chunk-JEIYHLOR.js → chunk-B3MOMLJ4.js} +12 -12
  53. package/dist/{chunk-APJ265NV.js → chunk-B5GGDIHT.js} +146 -146
  54. package/dist/{chunk-PMZVFWSR.js → chunk-B5ZTR6KZ.js} +2 -2
  55. package/dist/{chunk-I5FWO7L5.js → chunk-B6UM3OZC.js} +2 -2
  56. package/dist/{chunk-2CU2H6KE.js → chunk-BBV5TKE6.js} +5 -5
  57. package/dist/{chunk-23L32XTI.js → chunk-BLTEAUCB.js} +68 -39
  58. package/dist/{chunk-4O6MANBS.js → chunk-BS4GAMUB.js} +14 -10
  59. package/dist/{chunk-XULDXHTN.js → chunk-BT7HGDOX.js} +105 -53
  60. package/dist/{chunk-S66XZJOF.js → chunk-C27U2TYG.js} +2 -2
  61. package/dist/{chunk-QZWQA4DE.js → chunk-CBSKDFWL.js} +3 -3
  62. package/dist/{chunk-2LEAKD4C.js → chunk-CKK25WN3.js} +3 -3
  63. package/dist/{chunk-BYP5D4HI.js → chunk-CTTI7G3T.js} +2 -2
  64. package/dist/{chunk-XAKHZX5N.js → chunk-CVDAFGPW.js} +4 -4
  65. package/dist/{chunk-RKKLTLYB.js → chunk-CXQ37WJH.js} +3 -3
  66. package/dist/{chunk-GTUD2WMY.js → chunk-DBREN25X.js} +44 -9
  67. package/dist/{chunk-NDDGJUXD.js → chunk-DNCE23JJ.js} +2 -2
  68. package/dist/{chunk-HVDIIIQW.js → chunk-DNHVRBH4.js} +3 -3
  69. package/dist/{chunk-D7E7WCDF.js → chunk-DVNAPPXU.js} +2 -2
  70. package/dist/{chunk-6UINWWS6.js → chunk-DXLUVUD4.js} +16 -16
  71. package/dist/{chunk-YXLYO42X.js → chunk-DXVMLM3Z.js} +3 -2
  72. package/dist/{chunk-5MEZN6CB.js → chunk-DZK63TZJ.js} +6 -6
  73. package/dist/{chunk-IWHMRKLL.js → chunk-E3LEPLQ2.js} +2 -2
  74. package/dist/{chunk-JT2RFCC5.js → chunk-E7RF4KBO.js} +5 -5
  75. package/dist/{chunk-3R73A4XB.js → chunk-ECBHH7LU.js} +3 -3
  76. package/dist/chunk-ECOMVOHP.js +139 -0
  77. package/dist/chunk-EFSEIZE6.js +56 -0
  78. package/dist/{chunk-4NSRCOYP.js → chunk-EHOSNVVM.js} +3 -2
  79. package/dist/chunk-EM2WNQS2.js +93 -0
  80. package/dist/{chunk-57XXR6DR.js → chunk-F5Z7EWMN.js} +967 -246
  81. package/dist/{chunk-HAXOFFRH.js → chunk-FQOOGXBH.js} +7 -7
  82. package/dist/{chunk-ZTJUVLTU.js → chunk-FXFVDPWY.js} +2 -2
  83. package/dist/{chunk-XPLRXC72.js → chunk-GD55RTIW.js} +3 -3
  84. package/dist/{chunk-5B2AEOW5.js → chunk-GH5ZR6JP.js} +472 -472
  85. package/dist/{chunk-TOIVGRUX.js → chunk-GJ24ODAX.js} +5 -5
  86. package/dist/{chunk-EXLD33WO.js → chunk-GLYBJ4RQ.js} +24 -9
  87. package/dist/{chunk-26QSH3EJ.js → chunk-HHVJNVUJ.js} +5 -5
  88. package/dist/{chunk-F4EKGO4N.js → chunk-HL26ADLH.js} +4 -2
  89. package/dist/{chunk-FFUPXJC4.js → chunk-HPTJF6DG.js} +32 -56
  90. package/dist/{chunk-ID64D7PE.js → chunk-HXHFDHB6.js} +24 -24
  91. package/dist/{chunk-CUSRQKPU.js → chunk-HZ2T2YED.js} +299 -89
  92. package/dist/{chunk-YD5GIKET.js → chunk-HZFBVU5X.js} +49 -580
  93. package/dist/{chunk-6QOTUPRG.js → chunk-I2K2NCZQ.js} +65 -17
  94. package/dist/{chunk-SZAA6XDG.js → chunk-IFDRAD6F.js} +2 -2
  95. package/dist/{chunk-I2DWJ4GM.js → chunk-IGLVVNEG.js} +54 -42
  96. package/dist/{chunk-6Q3CYFD3.js → chunk-IKRWLEDA.js} +186 -35
  97. package/dist/{chunk-2JH2WHGE.js → chunk-J2FYEQ5L.js} +4 -4
  98. package/dist/{chunk-BMS5RKQY.js → chunk-JABWPKFY.js} +3 -3
  99. package/dist/{chunk-2DSOYNFC.js → chunk-JMPL7NUB.js} +7 -7
  100. package/dist/{chunk-QDC3K2U3.js → chunk-K2BLQC5E.js} +3 -3
  101. package/dist/{chunk-AUPNRN7C.js → chunk-K2HL3GBL.js} +4 -4
  102. package/dist/{chunk-54X7T7DK.js → chunk-KAFMW7WM.js} +72 -81
  103. package/dist/{chunk-OZNBF4L3.js → chunk-KECNXMDE.js} +2 -2
  104. package/dist/{chunk-BTK3SSSK.js → chunk-KMF54VH3.js} +2 -2
  105. package/dist/chunk-KPRLAMP4.js +32 -0
  106. package/dist/{chunk-ECH6PKUQ.js → chunk-KQ6IDQIB.js} +2 -2
  107. package/dist/{chunk-3UNOLWNZ.js → chunk-KTFSFCVN.js} +20 -9
  108. package/dist/{chunk-IRXAATOX.js → chunk-L4N3DWNW.js} +3 -3
  109. package/dist/{chunk-JQLNNIKT.js → chunk-LIN2K3EL.js} +6 -6
  110. package/dist/{chunk-2STGEDFV.js → chunk-LK2FN5JY.js} +2 -2
  111. package/dist/{chunk-LCGCVYZ4.js → chunk-LQTKDAUO.js} +2 -2
  112. package/dist/{chunk-U6TMQNSI.js → chunk-LTR5QCLS.js} +4 -4
  113. package/dist/chunk-LUL5Z66S.js +221 -0
  114. package/dist/{chunk-ELZVTCGV.js → chunk-LVFANMOH.js} +151 -327
  115. package/dist/{chunk-H7IXIC72.js → chunk-LY4N4TTL.js} +17 -3
  116. package/dist/{chunk-VKPAQYEB.js → chunk-LZBMXNLP.js} +5 -5
  117. package/dist/{chunk-UL3WSD3F.js → chunk-M4KFUXS7.js} +2 -2
  118. package/dist/{chunk-NXYCB2VD.js → chunk-M6TAYK66.js} +6 -6
  119. package/dist/{chunk-CFGTUFWB.js → chunk-MCJKEGHO.js} +2 -2
  120. package/dist/{chunk-6XLNIQDB.js → chunk-MYI32N4R.js} +2 -2
  121. package/dist/{chunk-4WR7VSYB.js → chunk-N2OKBREN.js} +23 -9
  122. package/dist/{chunk-3GY4F45V.js → chunk-NC4KV7EL.js} +6 -6
  123. package/dist/{chunk-LLXSDWXS.js → chunk-NF3BK5WR.js} +5 -5
  124. package/dist/{chunk-4M6Z5QVF.js → chunk-NNWJYUNO.js} +11 -11
  125. package/dist/chunk-NTK3WTHM.js +141 -0
  126. package/dist/{chunk-GYV6VZOC.js → chunk-NTTS3O53.js} +2 -2
  127. package/dist/{chunk-4BJ5BYCE.js → chunk-O3VV6IVK.js} +2 -2
  128. package/dist/{chunk-W6GROXXM.js → chunk-O5F25NIE.js} +2 -2
  129. package/dist/{chunk-NXIMQY5W.js → chunk-ODUTYZIU.js} +5 -5
  130. package/dist/{chunk-KFV5L5SK.js → chunk-OQM5IVJY.js} +118 -232
  131. package/dist/{chunk-75W7L2E2.js → chunk-P5JMBPDJ.js} +1052 -171
  132. package/dist/{chunk-XRZT5WY5.js → chunk-P5SC4DLJ.js} +4 -4
  133. package/dist/{chunk-S6PYF2XF.js → chunk-P6M7RKMI.js} +4 -4
  134. package/dist/{chunk-R6Q67RJH.js → chunk-PECBKCDK.js} +34 -6
  135. package/dist/{chunk-33YXPOE3.js → chunk-PPEZJWUG.js} +2 -2
  136. package/dist/{chunk-RXTN6AKH.js → chunk-PWWSIB2A.js} +5 -5
  137. package/dist/{chunk-DXKJURES.js → chunk-PZN2LQY6.js} +14 -11
  138. package/dist/{chunk-N56KALIC.js → chunk-Q7NNUHQV.js} +62 -35
  139. package/dist/{chunk-RQCKCSRL.js → chunk-QCOV5DFY.js} +22 -22
  140. package/dist/{chunk-3DPEIQKN.js → chunk-QH3ZTUOA.js} +2 -2
  141. package/dist/{chunk-NEKRRTYW.js → chunk-QJMRYTCX.js} +8 -8
  142. package/dist/{chunk-YNFKXPEC.js → chunk-QNWRHOMF.js} +35 -66
  143. package/dist/{chunk-YAKGTXEV.js → chunk-QRFXEO6Y.js} +2 -2
  144. package/dist/{chunk-35MSIRKH.js → chunk-QUIJZSDW.js} +2 -2
  145. package/dist/{chunk-72YIHOZQ.js → chunk-QXFBABFJ.js} +10 -10
  146. package/dist/chunk-R2CT5YDO.js +66 -0
  147. package/dist/{chunk-HHV2GANA.js → chunk-R2P2U3ZS.js} +2 -2
  148. package/dist/{chunk-IGLP3ODT.js → chunk-RGZNQ5CT.js} +15 -15
  149. package/dist/chunk-SD7SHNDW.js +15 -0
  150. package/dist/chunk-SL2RDHKO.js +19 -0
  151. package/dist/{chunk-NUGM5KR6.js → chunk-SRCEQKQS.js} +2 -2
  152. package/dist/{chunk-OMQNJVKW.js → chunk-SRZOW5L2.js} +43 -13
  153. package/dist/{chunk-UEPWCCTY.js → chunk-SXQKNKRA.js} +12 -12
  154. package/dist/{chunk-3M6DQK6S.js → chunk-T334FW2H.js} +7 -7
  155. package/dist/{chunk-V76WTFTW.js → chunk-T52TPHYC.js} +6 -6
  156. package/dist/{chunk-5636DCO5.js → chunk-TJFDL26W.js} +59 -12
  157. package/dist/{chunk-3I7MS7N2.js → chunk-TK2BMCBZ.js} +2 -2
  158. package/dist/{chunk-5OIVVPHF.js → chunk-TN5FW4XY.js} +13 -6
  159. package/dist/{chunk-LL4KHSZI.js → chunk-U2MSJ57E.js} +2 -2
  160. package/dist/{chunk-FTMGRKEF.js → chunk-U44YYLVV.js} +4 -4
  161. package/dist/{chunk-YECAMM3D.js → chunk-U7H5WRG5.js} +5 -5
  162. package/dist/{chunk-5TUB6SLS.js → chunk-UFYNOQK4.js} +7 -7
  163. package/dist/{chunk-R346GLFC.js → chunk-UHW5V7HC.js} +2 -2
  164. package/dist/{chunk-VIA6RFQZ.js → chunk-UQIVHSE4.js} +4 -4
  165. package/dist/{chunk-RAY4OVGZ.js → chunk-URBGEOH3.js} +5 -5
  166. package/dist/chunk-USZA7GWL.js +341 -0
  167. package/dist/{chunk-ZA4VCIGV.js → chunk-UUQ5G6EZ.js} +60 -41
  168. package/dist/{chunk-VG7TBQIY.js → chunk-V552WL53.js} +68 -4
  169. package/dist/{chunk-7UGL4MB5.js → chunk-VAHLPXPY.js} +10 -10
  170. package/dist/{chunk-25QBEXRS.js → chunk-VANN3GDP.js} +7 -26
  171. package/dist/{chunk-BWH6N36D.js → chunk-VHKTOLEW.js} +272 -42
  172. package/dist/{chunk-QUFRYSWI.js → chunk-VHMX7SXF.js} +129 -48
  173. package/dist/{chunk-336NSSKI.js → chunk-VNBICSS2.js} +2 -2
  174. package/dist/{chunk-VAVR4IJY.js → chunk-VQD7NH7Z.js} +3 -3
  175. package/dist/{chunk-LBMZMYH2.js → chunk-W2RJEH6Q.js} +3 -3
  176. package/dist/{chunk-7CR24IG7.js → chunk-WDV62RKY.js} +2 -2
  177. package/dist/{chunk-BJVFZO5U.js → chunk-WJIMKGD6.js} +7 -7
  178. package/dist/{chunk-USR47QNF.js → chunk-WKUYQBCG.js} +14 -14
  179. package/dist/{chunk-GHS5EBTQ.js → chunk-WNGF5AJX.js} +36 -22
  180. package/dist/{chunk-MXHC5QYU.js → chunk-WTQGRBHV.js} +5 -144
  181. package/dist/{chunk-6OSVSQL5.js → chunk-WV6TDAPN.js} +41 -23
  182. package/dist/chunk-WXA2CFJO.js +23 -0
  183. package/dist/{chunk-2ASED4PZ.js → chunk-X3BI7HTV.js} +26 -26
  184. package/dist/{chunk-QSNYB6ZV.js → chunk-XCUDZQLX.js} +3 -3
  185. package/dist/{chunk-RZDWV63N.js → chunk-XWMSPJYN.js} +6 -6
  186. package/dist/chunk-YGDMBK7O.js +567 -0
  187. package/dist/{chunk-6PAZTBPA.js → chunk-YPRSNUTC.js} +15 -6
  188. package/dist/{chunk-2IR2NMPA.js → chunk-ZIDFQJRB.js} +2 -2
  189. package/dist/{chunk-LTIKRKFL.js → chunk-ZS43Y2FT.js} +4 -4
  190. package/dist/{chunk-6EJMN2Y3.js → chunk-ZTNFYMIO.js} +2 -2
  191. package/dist/{chunk-WEPFGWHJ.js → chunk-ZZFWWYLX.js} +2 -2
  192. package/dist/cli/index.js +44 -44
  193. package/dist/clio-QQCMTUZE.js +26 -0
  194. package/dist/{code-nav-IJR2DBPR.js → code-nav-GUPM6766.js} +48 -32
  195. package/dist/codewiki/build-worker.js +76 -29
  196. package/dist/{compile-cache-OQAVB7Y5.js → compile-cache-WJEPUZEJ.js} +4 -4
  197. package/dist/{components-2TGAI2RC.js → components-TNIKXCBH.js} +13 -13
  198. package/dist/{config-IUA6OYNS.js → config-IIM7YOD3.js} +211 -124
  199. package/dist/configure-4ZM5HWJX.js +73 -0
  200. package/dist/{context-BOYF5EJM.js → context-44BZLJ3J.js} +62 -31
  201. package/dist/{context-4MPR7WKB.js → context-AIDVQKMW.js} +126 -121
  202. package/dist/{context-2DKHWH2T.js → context-OL5P3HEP.js} +92 -62
  203. package/dist/context-clear-OQV76MYP.js +184 -0
  204. package/dist/{context-index-HNG3MOME.js → context-index-HP2JFUWA.js} +13 -11
  205. package/dist/{context-map-COB37XXN.js → context-map-INTXD54D.js} +71 -21
  206. package/dist/{context-working-set-3I3FYX6Y.js → context-working-set-ZUW3EGLS.js} +32 -31
  207. package/dist/detail-UXPWRANG.js +115 -0
  208. package/dist/{dispatch-runner-RJ5I2F2O.js → dispatch-runner-P3ZW6G77.js} +192 -116
  209. package/dist/{docs-SPOV3BAN.js → docs-BL7ROUFN.js} +4 -4
  210. package/dist/{doctor-DKICC2SN.js → doctor-JJVGPZWT.js} +59 -58
  211. package/dist/{eval-OQOQUDHK.js → eval-V2RTN3UH.js} +476 -170
  212. package/dist/{eval-inventory-Y6QRFOH5.js → eval-inventory-QOYZERXJ.js} +7 -7
  213. package/dist/evidence-35PYWGSO.js +225 -0
  214. package/dist/{evidence-4DQ25GUQ.js → evidence-CIGGKI6J.js} +111 -94
  215. package/dist/{evolve-GSS52E5J.js → evolve-33SM3NJP.js} +108 -91
  216. package/dist/{extensions-G7MFLYHT.js → extensions-YVRHX6ZI.js} +16 -16
  217. package/dist/{fleet-Q37YHHAQ.js → fleet-LFO7SIPC.js} +147 -146
  218. package/dist/{fleet-commands-G7E4N7SM.js → fleet-commands-RLK72GU3.js} +27 -26
  219. package/dist/{fleet-decisions-O7M6QBA2.js → fleet-decisions-3SBSCTCW.js} +16 -15
  220. package/dist/{fleet-graph-TOUBW6OW.js → fleet-graph-JZIBCGMW.js} +39 -38
  221. package/dist/{fleet-inspect-SW33JJNI.js → fleet-inspect-2L5YGGZJ.js} +108 -91
  222. package/dist/{fleet-new-RDVJLHHH.js → fleet-new-RCKGSRDV.js} +3 -3
  223. package/dist/{fleet-preflight-CV2655TW.js → fleet-preflight-QRSHIIDE.js} +10 -9
  224. package/dist/{fleet-validate-KESZX2YH.js → fleet-validate-LIAVKDUU.js} +46 -42
  225. package/dist/{fleet-verify-UQPMTVE3.js → fleet-verify-JIK3OQZR.js} +106 -89
  226. package/dist/fleet-view-IWHYGQKK.js +118 -0
  227. package/dist/{init-PXEXQSBF.js → init-NJEDOTQW.js} +124 -123
  228. package/dist/{install-NKNG7KD4.js → install-3RZDDP23.js} +5 -5
  229. package/dist/{interop-ZG5T62U3.js → interop-RVCAYECG.js} +25 -25
  230. package/dist/inventory-74UL7UHU.js +118 -0
  231. package/dist/{library-B2W4N74O.js → library-CTKZA7K3.js} +45 -44
  232. package/dist/{memory-YCANYS5A.js → memory-I76I5VUH.js} +108 -93
  233. package/dist/{models-GERTU3YI.js → models-D4YDIQZQ.js} +64 -62
  234. package/dist/{monitor-CPNIUULB.js → monitor-NKVD55HX.js} +137 -107
  235. package/dist/{orchestrator-J4BSH4WQ.js → orchestrator-I6OATVPK.js} +1715 -1687
  236. package/dist/{panes-BOHAEGYC.js → panes-7BTYH3XQ.js} +8 -8
  237. package/dist/{panes-NXSLDQZ2.js → panes-WPOMEMRH.js} +22 -22
  238. package/dist/{paths-VSUWNC22.js → paths-J3KN7UAO.js} +12 -12
  239. package/dist/preload-EJAWJEIO.js +116 -0
  240. package/dist/{registry-LG64LTF4.js → registry-DESGAXWK.js} +3 -3
  241. package/dist/{reset-TNWTB5LU.js → reset-4XMQKDNZ.js} +22 -20
  242. package/dist/{resources-4PXNMD5G.js → resources-TVYVXK3Q.js} +41 -40
  243. package/dist/{run-D6XJ34CN.js → run-OWQNNSJU.js} +164 -157
  244. package/dist/{share-2NWMJJEE.js → share-NPZZMUXG.js} +43 -42
  245. package/dist/{skills-KR7WON5G.js → skills-OXFEAWMT.js} +47 -46
  246. package/dist/{skills-eval-O2ZNOLDS.js → skills-eval-J5TCKSJA.js} +128 -107
  247. package/dist/{skills-inventory-ZZOUBK7O.js → skills-inventory-7II4DM57.js} +41 -40
  248. package/dist/slash-commands-MDSDSWYF.js +92 -0
  249. package/dist/{steer-XA25PSCS.js → steer-S7D7IKPU.js} +7 -7
  250. package/dist/{support-7EMVWYG2.js → support-5VAEC32W.js} +14 -14
  251. package/dist/{targets-OMH2XCSN.js → targets-KILZEOCE.js} +161 -94
  252. package/dist/tasks-R6P6OV22.js +36 -0
  253. package/dist/{terminal-lease-C2J3JYRE.js → terminal-lease-LZCG2KN3.js} +12 -11
  254. package/dist/tools-6OCQ6SVB.js +28 -0
  255. package/dist/{trace-FXMXUZUF.js → trace-JHLXWUMN.js} +18 -17
  256. package/dist/{tree-sitter-HGKH6LG4.js → tree-sitter-AQUUOSYM.js} +6 -6
  257. package/dist/{tui-primitives-K5PASC3O.js → tui-primitives-RCY2HN7G.js} +3 -3
  258. package/dist/{uninstall-HALS6BLF.js → uninstall-FXYMFFRT.js} +17 -17
  259. package/dist/{upgrade-MS72RJEP.js → upgrade-D2OZH6IQ.js} +42 -41
  260. package/dist/{usage-NHG6MCJM.js → usage-PIASNUS4.js} +137 -105
  261. package/dist/{verifiers-7AUNVXDY.js → verifiers-LTHUY2PX.js} +28 -27
  262. package/dist/verify-HYF7KBVE.js +30 -0
  263. package/dist/{version-KGEG7EPO.js → version-RFPKO6T7.js} +4 -4
  264. package/dist/{web-fetch-V4FKSDAV.js → web-fetch-MQN4FH3X.js} +169 -18
  265. package/dist/wiki-generate-RK7JQ5NP.js +615 -0
  266. package/dist/{with-panes-BDQEWBRT.js → with-panes-OFTNAR4Y.js} +34 -20
  267. package/dist/worker/entry.js +108 -95
  268. package/dist/{workspace-ZJ6BFM3Q.js → workspace-DZ7JADBG.js} +6 -6
  269. package/docs/README.md +7 -6
  270. package/docs/architecture/acp.md +10 -0
  271. package/docs/architecture/architecture.md +5 -5
  272. package/docs/architecture/context-engine.md +45 -60
  273. package/docs/architecture/context-working-set.md +7 -9
  274. package/docs/architecture/dispatch-architecture-rationale.md +1 -1
  275. package/docs/architecture/evidence-and-memory.md +10 -0
  276. package/docs/architecture/pi-boundary.md +37 -7
  277. package/docs/architecture/prompt-envelope-and-tools.md +7 -7
  278. package/docs/architecture/session-lifecycle.md +4 -4
  279. package/docs/architecture/tui-design.md +45 -30
  280. package/docs/architecture/worker-dispatch-mechanics.md +4 -0
  281. package/docs/guide/commands-and-modes.md +75 -61
  282. package/docs/guide/configuration-and-targets.md +126 -26
  283. package/docs/guide/configuration-reference.md +22 -7
  284. package/docs/guide/environment-variables.md +6 -2
  285. package/docs/guide/fleet-dispatch.md +13 -6
  286. package/docs/guide/glossary.md +1 -1
  287. package/docs/guide/installation-and-lifecycle.md +79 -20
  288. package/docs/guide/proactive-memory.md +1 -1
  289. package/docs/guide/skills-marketplace.md +11 -3
  290. package/docs/guide/tool-usage.md +9 -2
  291. package/docs/process/development-pipeline.md +11 -11
  292. package/docs/process/documentation-coverage.md +1 -1
  293. package/docs/process/documentation-guide.md +2 -2
  294. package/docs/process/eval-runner.md +15 -0
  295. package/docs/process/evals-internal.md +1 -1
  296. package/docs/process/release-cut-checklist.md +24 -12
  297. package/evals/README.md +4 -0
  298. package/evals/behavioral-corpus-grader.mjs +147 -14
  299. package/evals/behavioral-model-negative-control.yaml +1 -0
  300. package/evals/behavioral-model.yaml +266 -1
  301. package/evals/fixtures/docs-retrieval.json +102 -0
  302. package/evals/fixtures/scalar-decision.json +17 -0
  303. package/evals/fixtures/scout-citation-pipeline.json +55 -0
  304. package/evals/fixtures/source-explanation.json +74 -0
  305. package/evals/fixtures/tool-arguments.json +18 -0
  306. package/evals/fixtures/tool-surface/read.txt +4 -0
  307. package/evals/fixtures/tool-surface/subdir/keep.txt +1 -0
  308. package/evals/no-edit-memory-grader.mjs +149 -0
  309. package/evals/scalar-decision-grader.py +41 -0
  310. package/evals/scalar-decision-machinery.ts +145 -0
  311. package/evals/source-explanation-grader.mjs +118 -0
  312. package/evals/tool-surface-grader.mjs +53 -0
  313. package/evals/tool-surface-model.yaml +274 -0
  314. package/package.json +14 -14
  315. package/skills/README.md +6 -6
  316. package/skills/registry.yaml +1 -1
  317. package/skills/skill-marketplace.json +1 -1
  318. package/src/cli/ask.ts +10 -10
  319. package/src/cli/bootstrap-generate.ts +6 -0
  320. package/src/cli/config-inspect.ts +24 -7
  321. package/src/cli/config-trust.ts +62 -0
  322. package/src/cli/config.ts +8 -0
  323. package/src/cli/configure-editor.ts +51 -0
  324. package/src/cli/configure-interop.ts +1 -1
  325. package/src/cli/configure-oauth.ts +1 -1
  326. package/src/cli/configure-onboarding.ts +232 -96
  327. package/src/cli/configure-prompts.ts +76 -0
  328. package/src/cli/configure-quick.ts +274 -0
  329. package/src/cli/configure-target.ts +14 -2
  330. package/src/cli/configure.ts +413 -174
  331. package/src/cli/context-map.ts +75 -14
  332. package/src/cli/context.ts +46 -17
  333. package/src/cli/eval.ts +17 -3
  334. package/src/cli/modes/print.ts +32 -4
  335. package/src/cli/oauth-manual-input.ts +1 -1
  336. package/src/cli/reset.ts +2 -0
  337. package/src/cli/run.ts +16 -14
  338. package/src/cli/select.ts +35 -4
  339. package/src/cli/skills-eval.ts +10 -8
  340. package/src/cli/steer-channel.ts +31 -18
  341. package/src/cli/targets.ts +83 -31
  342. package/src/cli/tasks.ts +10 -1
  343. package/src/cli/upgrade.ts +11 -8
  344. package/src/cli/usage.ts +24 -0
  345. package/src/cli/wiki-generate.ts +239 -96
  346. package/src/core/bash-exec.ts +43 -15
  347. package/src/core/bus-events.ts +15 -0
  348. package/src/core/config.ts +39 -15
  349. package/src/core/defaults.ts +38 -15
  350. package/src/{interactive → core}/external-editor.ts +4 -4
  351. package/src/core/file-references.ts +11 -1
  352. package/src/core/incomplete-installation.ts +3 -1
  353. package/src/core/settings-layers.ts +21 -5
  354. package/src/core/termination.ts +26 -9
  355. package/src/core/untrusted-content.ts +16 -0
  356. package/src/core/workspace-trust.ts +179 -0
  357. package/src/domains/agents/builtins/coder.md +4 -2
  358. package/src/domains/agents/builtins/context-bootstrap.md +3 -1
  359. package/src/domains/agents/builtins/documenter.md +7 -4
  360. package/src/domains/agents/builtins/researcher.md +1 -0
  361. package/src/domains/agents/builtins/scout.md +7 -1
  362. package/src/domains/agents/result-contract.ts +199 -26
  363. package/src/domains/config/classify.ts +1 -1
  364. package/src/domains/config/keybindings.ts +3 -31
  365. package/src/domains/context/bootstrap-prompt.ts +11 -9
  366. package/src/domains/context/bootstrap.ts +74 -39
  367. package/src/domains/context/clio-md.ts +88 -26
  368. package/src/domains/context/codewiki/build-operation.ts +121 -0
  369. package/src/domains/context/codewiki/build-worker-protocol.ts +37 -3
  370. package/src/domains/context/codewiki/build-worker.ts +3 -35
  371. package/src/domains/context/codewiki/coordinator.ts +36 -6
  372. package/src/domains/context/codewiki/indexer.ts +59 -19
  373. package/src/domains/context/contract.ts +6 -2
  374. package/src/domains/context/extension.ts +72 -10
  375. package/src/domains/context/fingerprint.ts +39 -34
  376. package/src/domains/context/index.ts +7 -1
  377. package/src/domains/context/prompt-context.ts +55 -14
  378. package/src/domains/context/refresh.ts +9 -57
  379. package/src/domains/context/wiki/assemble.ts +14 -10
  380. package/src/domains/context/wiki/evidence.ts +209 -0
  381. package/src/domains/context/wiki/generate.ts +201 -67
  382. package/src/domains/context/wiki/meta.ts +10 -2
  383. package/src/domains/context/wiki/plan-store.ts +70 -14
  384. package/src/domains/context/wiki/plan.ts +71 -14
  385. package/src/domains/context/wiki/prompts.ts +42 -1
  386. package/src/domains/context/wiki/source-content.ts +106 -0
  387. package/src/domains/context/wiki/staleness.ts +33 -22
  388. package/src/domains/context/working-set/contract.ts +8 -2
  389. package/src/domains/context/working-set/engine.ts +17 -4
  390. package/src/domains/context/working-set/fold.ts +15 -2
  391. package/src/domains/context/working-set/marker.ts +2 -1
  392. package/src/domains/context/working-set/project.ts +18 -7
  393. package/src/domains/context/working-set/recall.ts +82 -56
  394. package/src/domains/dispatch/active-route-planner.ts +6 -3
  395. package/src/domains/dispatch/admission-queue.ts +19 -7
  396. package/src/domains/dispatch/admission.ts +3 -3
  397. package/src/domains/dispatch/budget-envelope.ts +47 -82
  398. package/src/domains/dispatch/capacity-lease.ts +57 -19
  399. package/src/domains/dispatch/contract.ts +10 -2
  400. package/src/domains/dispatch/event-pump.ts +28 -7
  401. package/src/domains/dispatch/execution-role.ts +49 -2
  402. package/src/domains/dispatch/execution-scheduler.ts +2 -0
  403. package/src/domains/dispatch/extension.ts +190 -105
  404. package/src/domains/dispatch/fleet-run.ts +20 -0
  405. package/src/domains/dispatch/gate-role-prompts.ts +4 -2
  406. package/src/domains/dispatch/parallel-writers.ts +34 -0
  407. package/src/domains/dispatch/reservation-store.ts +8 -34
  408. package/src/domains/dispatch/route-approval.ts +3 -3
  409. package/src/domains/dispatch/route-observer.ts +4 -2
  410. package/src/domains/dispatch/route-quality.ts +6 -1
  411. package/src/domains/dispatch/types.ts +4 -3
  412. package/src/domains/dispatch/worker-spawn.ts +58 -21
  413. package/src/domains/dispatch/workspace-checkpoint.ts +57 -0
  414. package/src/domains/eval/compare/behavioral.ts +81 -14
  415. package/src/domains/eval/compare/compare.ts +15 -5
  416. package/src/domains/eval/compare/envelope.ts +12 -5
  417. package/src/domains/eval/metrics/context.ts +24 -1
  418. package/src/domains/eval/metrics/tracked.ts +4 -28
  419. package/src/domains/eval/reports/comparison.ts +9 -9
  420. package/src/domains/eval/runners/clio-run.ts +5 -1
  421. package/src/domains/eval/schema/suite.ts +2 -0
  422. package/src/domains/eval/schema/validate.ts +1 -0
  423. package/src/domains/eval/suites/run.ts +189 -13
  424. package/src/domains/eval/verifiers/integrity.ts +39 -0
  425. package/src/domains/eval/verifiers/patch.ts +58 -2
  426. package/src/domains/eval/workspaces/temp-copy.ts +3 -0
  427. package/src/domains/evidence/build.ts +4 -2
  428. package/src/domains/interop/registry.ts +2 -2
  429. package/src/domains/middleware/hooks-io.ts +45 -26
  430. package/src/domains/middleware/hooks.ts +6 -0
  431. package/src/domains/middleware/injection-screen.ts +23 -0
  432. package/src/domains/middleware/rules.ts +5 -1
  433. package/src/domains/middleware/stalled-turn.ts +18 -3
  434. package/src/domains/middleware/task-board-reminder.ts +4 -2
  435. package/src/domains/middleware/task-nudge.ts +4 -1
  436. package/src/domains/mux/contract.ts +34 -1
  437. package/src/domains/mux/dock-controller.ts +8 -1
  438. package/src/domains/mux/index.ts +1 -0
  439. package/src/domains/mux/socket-client.ts +13 -3
  440. package/src/domains/observability/contract.ts +2 -2
  441. package/src/domains/observability/projection.ts +30 -9
  442. package/src/domains/prompts/compiler.ts +10 -2
  443. package/src/domains/prompts/contract.ts +7 -4
  444. package/src/domains/prompts/extension.ts +28 -64
  445. package/src/domains/prompts/fragments/identity/clio.md +23 -0
  446. package/src/domains/prompts/fragments/operating/contract.md +10 -0
  447. package/src/domains/prompts/fragments/operating/delegation.md +5 -0
  448. package/src/domains/prompts/fragments/wiki/page.md +28 -15
  449. package/src/domains/prompts/fragments/wiki/plan.md +4 -4
  450. package/src/domains/prompts/preload-prefix.ts +31 -0
  451. package/src/domains/prompts/preload.ts +135 -61
  452. package/src/domains/providers/auth/backend-file.ts +15 -11
  453. package/src/domains/providers/auth/storage.ts +3 -5
  454. package/src/domains/providers/catalog.ts +18 -3
  455. package/src/domains/providers/probe/fingerprint.ts +13 -6
  456. package/src/domains/providers/probe/reasoning.ts +2 -0
  457. package/src/domains/providers/runtime-resolution.ts +11 -9
  458. package/src/domains/providers/runtimes/cloud/openrouter.ts +2 -0
  459. package/src/domains/providers/runtimes/common/probe-helpers.ts +23 -7
  460. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +7 -2
  461. package/src/domains/providers/runtimes/protocol/openai-compat.ts +10 -4
  462. package/src/domains/resources/skills/promotion.ts +8 -1
  463. package/src/domains/safety/action-classifier.ts +9 -0
  464. package/src/domains/safety/autonomy.ts +10 -1
  465. package/src/domains/safety/contract.ts +5 -1
  466. package/src/domains/safety/default-path-policy.ts +11 -0
  467. package/src/domains/safety/extension.ts +11 -2
  468. package/src/domains/safety/policy-engine.ts +189 -32
  469. package/src/domains/safety/project-policy.ts +7 -2
  470. package/src/domains/safety/workspace-trust.ts +43 -0
  471. package/src/domains/session/compaction/compact.ts +384 -21
  472. package/src/domains/session/compaction/cut-point.ts +42 -5
  473. package/src/domains/session/compaction/tokens.ts +9 -1
  474. package/src/domains/session/decision-board.ts +43 -33
  475. package/src/domains/session/entries.ts +169 -4
  476. package/src/domains/session/prompt-manifest.ts +47 -8
  477. package/src/domains/session/task-board.ts +21 -3
  478. package/src/domains/user-tasks/handoff.ts +16 -0
  479. package/src/engine/acp/adapter.ts +44 -12
  480. package/src/engine/acp/server.ts +1 -0
  481. package/src/engine/acp/transport.ts +2 -1
  482. package/src/engine/acp/types.ts +6 -1
  483. package/src/engine/antigravity/subprocess-runtime.ts +20 -4
  484. package/src/engine/api-registry.ts +19 -2
  485. package/src/engine/apis/openai-completions.ts +13 -6
  486. package/src/engine/apis/output-budget.ts +26 -10
  487. package/src/engine/claude/sdk-runtime.ts +4 -3
  488. package/src/engine/env-api-keys.ts +2 -1
  489. package/src/engine/external-subprocess.ts +14 -3
  490. package/src/engine/loop-guard.ts +19 -2
  491. package/src/engine/provider-diagnostics.ts +129 -0
  492. package/src/engine/provider-payload.ts +3 -1
  493. package/src/engine/worker-runtime.ts +13 -2
  494. package/src/engine/worker-tools.ts +5 -1
  495. package/src/entry/extension-reload.ts +1 -0
  496. package/src/entry/orchestrator.ts +53 -15
  497. package/src/interactive/application-controller.ts +1 -31
  498. package/src/interactive/chat-loop-messages.ts +12 -4
  499. package/src/interactive/chat-loop.ts +115 -45
  500. package/src/interactive/chat-panel.ts +163 -637
  501. package/src/interactive/chat-renderer.ts +73 -30
  502. package/src/interactive/context-recall-command.ts +2 -1
  503. package/src/interactive/dispatch-board.ts +18 -5
  504. package/src/interactive/editor-submit.ts +21 -31
  505. package/src/interactive/footer/dashboard.ts +8 -3
  506. package/src/interactive/footer/widgets.ts +50 -91
  507. package/src/interactive/interactive-application.ts +24 -44
  508. package/src/interactive/interactive-event-projection.ts +9 -45
  509. package/src/interactive/interactive-input-runtime.ts +3 -28
  510. package/src/interactive/interactive-presentation.ts +45 -16
  511. package/src/interactive/interactive-slash-runtime.ts +5 -40
  512. package/src/interactive/layout.ts +31 -5
  513. package/src/interactive/model-session-replay.ts +2 -2
  514. package/src/interactive/overlay-frame.ts +1 -0
  515. package/src/interactive/overlay-general-openers.ts +5 -1
  516. package/src/interactive/overlay-lifecycle.ts +1 -0
  517. package/src/interactive/overlay-session-lifecycle.ts +7 -1
  518. package/src/interactive/overlays/ask-user.ts +1 -0
  519. package/src/interactive/overlays/message-picker.ts +1 -1
  520. package/src/interactive/overlays/settings.ts +9 -8
  521. package/src/interactive/renderers/preview.ts +16 -0
  522. package/src/interactive/renderers/tool-execution.ts +84 -161
  523. package/src/interactive/renderers/worker-entry.ts +74 -43
  524. package/src/interactive/slash-autocomplete.ts +1 -6
  525. package/src/interactive/slash-commands.ts +16 -46
  526. package/src/interactive/status/controller.ts +0 -5
  527. package/src/interactive/status/state-machine.ts +44 -26
  528. package/src/interactive/status/types.ts +3 -0
  529. package/src/interactive/status/verbs.ts +13 -12
  530. package/src/interactive/transcript-detail.ts +50 -112
  531. package/src/interactive/turn-context.ts +221 -53
  532. package/src/interactive/turn-middleware.ts +3 -1
  533. package/src/interactive/turn-persistence.ts +3 -0
  534. package/src/interactive/turn-runtime.ts +11 -2
  535. package/src/interactive/turn-state.ts +10 -9
  536. package/src/interactive/view/artifacts.ts +4 -0
  537. package/src/interactive/view/view-overlay.ts +44 -34
  538. package/src/interactive/watch-pane.ts +18 -4
  539. package/src/interactive/worker-stream.ts +7 -7
  540. package/src/tools/agent-tools.ts +6 -3
  541. package/src/tools/bash.ts +1 -1
  542. package/src/tools/builtin-tool-catalog.ts +9 -2
  543. package/src/tools/codewiki/code-nav.ts +4 -10
  544. package/src/tools/compete-judge-task.ts +71 -0
  545. package/src/tools/compete-worktrees.ts +34 -0
  546. package/src/tools/context/index.ts +32 -7
  547. package/src/tools/context/surface.ts +15 -4
  548. package/src/tools/decide.ts +1 -1
  549. package/src/tools/dispatch-admission.ts +12 -1
  550. package/src/tools/dispatch-arguments.ts +38 -1
  551. package/src/tools/dispatch-plan.ts +7 -7
  552. package/src/tools/dispatch-runner.ts +48 -32
  553. package/src/tools/dispatch-schema.ts +30 -23
  554. package/src/tools/dispatch-scout-admission.ts +10 -44
  555. package/src/tools/dispatch-scout.ts +2 -3
  556. package/src/tools/find.ts +13 -4
  557. package/src/tools/grep.ts +13 -1
  558. package/src/tools/ls.ts +7 -1
  559. package/src/tools/monitor.ts +26 -11
  560. package/src/tools/network-policy.ts +11 -24
  561. package/src/tools/observation.ts +39 -2
  562. package/src/tools/presentation.ts +1 -1
  563. package/src/tools/read.ts +112 -15
  564. package/src/tools/registry.ts +55 -18
  565. package/src/tools/result-shaping.ts +110 -2
  566. package/src/tools/tasks.ts +33 -7
  567. package/src/tools/verify/frontend.ts +67 -30
  568. package/src/tools/verify/numeric.ts +10 -5
  569. package/src/tools/web-fetch-network.ts +179 -0
  570. package/src/tools/web-fetch-surface.ts +2 -1
  571. package/src/tools/web-fetch.ts +15 -13
  572. package/src/tools/worker-evidence.ts +27 -0
  573. package/src/worker/spec-contract.ts +12 -8
  574. package/dist/builtins-WGALA46I.js +0 -22
  575. package/dist/chunk-2WZ546HR.js +0 -792
  576. package/dist/chunk-5PSMVOLM.js +0 -56
  577. package/dist/chunk-EL24TAU4.js +0 -1560
  578. package/dist/chunk-IZXGRF7P.js +0 -4048
  579. package/dist/chunk-JVCV3ICN.js +0 -47
  580. package/dist/chunk-MNJGS2IN.js +0 -33
  581. package/dist/chunk-O5CVSAG5.js +0 -122
  582. package/dist/chunk-ODGTEFFI.js +0 -50
  583. package/dist/chunk-OQE5J4C6.js +0 -73
  584. package/dist/chunk-UUVG37B4.js +0 -244
  585. package/dist/chunk-V6HJFQZE.js +0 -228
  586. package/dist/clio-QLICPCF5.js +0 -25
  587. package/dist/configure-VEPX4NMX.js +0 -55
  588. package/dist/context-clear-S4ZJCQUX.js +0 -182
  589. package/dist/detail-A7JAVSIG.js +0 -98
  590. package/dist/evidence-4F5USFKH.js +0 -208
  591. package/dist/fleet-view-MN2VG4MR.js +0 -101
  592. package/dist/inventory-C26CFDRR.js +0 -101
  593. package/dist/preload-P6DGH2PZ.js +0 -13
  594. package/dist/slash-commands-ZXPJD64J.js +0 -92
  595. package/dist/tasks-IPAGMEIX.js +0 -36
  596. package/dist/tools-EFFEAIDP.js +0 -28
  597. package/dist/verify-FWYGPKMR.js +0 -29
  598. package/dist/wiki-generate-743CIGJW.js +0 -476
package/src/tools/find.ts CHANGED
@@ -8,6 +8,7 @@ import { resolveFdBinary } from "./executables.js";
8
8
  import { compileGlobRegex, fallbackIgnoredDirs, fdIgnoreArgs, normalizeGlobInput } from "./ignore-policy.js";
9
9
  import {
10
10
  commitObservationReservation,
11
+ createObservationPathFilter,
11
12
  finalizeObservation,
12
13
  OBSERVE_SELF_CAPS,
13
14
  type ObservationReservation,
@@ -148,6 +149,7 @@ function orderByMtime(paths: string[], searchPath: string, limit: number, candid
148
149
  }
149
150
 
150
151
  function renderFindResult(input: {
152
+ withheldPaths: number;
151
153
  ordered: OrderedPaths;
152
154
  collected: number;
153
155
  collectLimit: number;
@@ -160,11 +162,13 @@ function renderFindResult(input: {
160
162
  if (ordered.paths.length === 0) {
161
163
  return finalizeObservation({
162
164
  tool: ToolNames.Find,
165
+ withheldPaths: input.withheldPaths,
163
166
  unit: "paths",
164
- output: "No files found matching pattern",
167
+ output: "No visible files found matching pattern",
165
168
  shownCount: 0,
166
- totalCount: 0,
167
- truncated: false,
169
+ totalCount: collected >= collectLimit ? null : 0,
170
+ truncated: collected >= collectLimit,
171
+ ...(collected >= collectLimit ? { next: `limit=${limit * 2}` } : {}),
168
172
  reservation,
169
173
  ...(options ? { options } : {}),
170
174
  });
@@ -191,6 +195,7 @@ function renderFindResult(input: {
191
195
  }
192
196
  return finalizeObservation({
193
197
  tool: ToolNames.Find,
198
+ withheldPaths: input.withheldPaths,
194
199
  unit: "paths",
195
200
  output: truncation.content,
196
201
  // Offload only when the byte cap cut collected paths; a bare result
@@ -269,13 +274,17 @@ export const findTool: ToolSpec = {
269
274
  }
270
275
  }
271
276
 
277
+ const collectedCount = collectedPaths.length;
278
+ const pathFilter = createObservationPathFilter(process.cwd(), options?.allowsObservationPath);
279
+ collectedPaths = collectedPaths.filter((entry) => pathFilter.allows(join(searchPath, entry)));
272
280
  const ordered: OrderedPaths =
273
281
  order === "mtime"
274
282
  ? orderByMtime(collectedPaths, searchPath, limit, collectLimit)
275
283
  : { paths: collectedPaths.slice(0, limit), candidateCapHit: false, candidateCap: null };
276
284
  return renderFindResult({
285
+ withheldPaths: pathFilter.withheldPaths,
277
286
  ordered,
278
- collected: collectedPaths.length,
287
+ collected: collectedCount,
279
288
  collectLimit,
280
289
  limit,
281
290
  order,
package/src/tools/grep.ts CHANGED
@@ -7,6 +7,7 @@ import { resolveRgBinary } from "./executables.js";
7
7
  import { compileGlobRegex, fallbackIgnoredDirs, normalizeGlobInput, rgIgnoreArgs } from "./ignore-policy.js";
8
8
  import {
9
9
  commitObservationReservation,
10
+ createObservationPathFilter,
10
11
  finalizeObservation,
11
12
  OBSERVE_SELF_CAPS,
12
13
  type ObservationReservation,
@@ -67,6 +68,7 @@ interface RenderedLine {
67
68
  }
68
69
 
69
70
  interface GrepRenderInput {
71
+ withheldPaths: number;
70
72
  mode: GrepMode;
71
73
  lines: RenderedLine[];
72
74
  matchCount: number;
@@ -90,6 +92,7 @@ function renderGrepResult(input: GrepRenderInput): ToolResult {
90
92
  if (lines.length === 0) {
91
93
  return finalizeObservation({
92
94
  tool: ToolNames.Grep,
95
+ withheldPaths: input.withheldPaths,
93
96
  unit: MODE_UNITS[mode],
94
97
  output: NO_MATCH_OUTPUT,
95
98
  shownCount: 0,
@@ -120,6 +123,7 @@ function renderGrepResult(input: GrepRenderInput): ToolResult {
120
123
  }
121
124
  return finalizeObservation({
122
125
  tool: ToolNames.Grep,
126
+ withheldPaths: input.withheldPaths,
123
127
  unit: MODE_UNITS[mode],
124
128
  output,
125
129
  // Offload only when the byte cap cut collected content; a bare match
@@ -139,6 +143,7 @@ function sanitizeMatchText(text: string): string {
139
143
  }
140
144
 
141
145
  interface RgSearchInput {
146
+ pathFilter: ReturnType<typeof createObservationPathFilter>;
142
147
  rgPath: string;
143
148
  mode: GrepMode;
144
149
  pattern: string;
@@ -195,6 +200,7 @@ async function runRipgrep(input: RgSearchInput): Promise<ToolResult> {
195
200
  const lineNumber = data?.line_number;
196
201
  const lineText = (data?.lines as { text?: unknown } | undefined)?.text;
197
202
  if (typeof filePath !== "string" || typeof lineNumber !== "number" || typeof lineText !== "string") return;
203
+ if (!input.pathFilter.allows(filePath)) return;
198
204
  const { text, wasTruncated } = truncateLine(sanitizeMatchText(lineText));
199
205
  if (wasTruncated) linesTruncated = true;
200
206
  const isMatch = type === "match";
@@ -214,6 +220,8 @@ async function runRipgrep(input: RgSearchInput): Promise<ToolResult> {
214
220
  const onListLine = (line: string, stop: () => void): void => {
215
221
  const trimmed = line.replace(/\r$/, "");
216
222
  if (trimmed.length === 0) return;
223
+ const filePath = input.mode === "count" ? trimmed.slice(0, trimmed.lastIndexOf(":")) : trimmed;
224
+ if (!input.pathFilter.allows(filePath)) return;
217
225
  let text: string;
218
226
  if (input.mode === "count") {
219
227
  const sep = trimmed.lastIndexOf(":");
@@ -245,6 +253,7 @@ async function runRipgrep(input: RgSearchInput): Promise<ToolResult> {
245
253
  return { kind: "error", message: `grep: ${result.stderr.trim() || `ripgrep exited with code ${result.exitCode}`}` };
246
254
  }
247
255
  return renderGrepResult({
256
+ withheldPaths: input.pathFilter.withheldPaths,
248
257
  mode: input.mode,
249
258
  lines: rendered,
250
259
  matchCount,
@@ -279,6 +288,7 @@ function looksBinary(buffer: Buffer): boolean {
279
288
  }
280
289
 
281
290
  interface FallbackSearchInput {
291
+ pathFilter: ReturnType<typeof createObservationPathFilter>;
282
292
  mode: GrepMode;
283
293
  pattern: string;
284
294
  searchPath: string;
@@ -328,7 +338,7 @@ function fallbackGrep(input: FallbackSearchInput): ToolResult {
328
338
  };
329
339
 
330
340
  const searchFile = (filePath: string): void => {
331
- if (limitHit) return;
341
+ if (limitHit || !input.pathFilter.allows(filePath)) return;
332
342
  let buffer: Buffer;
333
343
  try {
334
344
  const stat = statSync(filePath);
@@ -403,6 +413,7 @@ function fallbackGrep(input: FallbackSearchInput): ToolResult {
403
413
  else searchFile(input.searchPath);
404
414
  if (signal?.aborted) return { kind: "error", message: "grep: operation aborted" };
405
415
  return renderGrepResult({
416
+ withheldPaths: input.pathFilter.withheldPaths,
406
417
  mode: input.mode,
407
418
  lines: rendered,
408
419
  matchCount,
@@ -463,6 +474,7 @@ export const grepTool: ToolSpec = {
463
474
  });
464
475
  }
465
476
  const shared = {
477
+ pathFilter: createObservationPathFilter(process.cwd(), options?.allowsObservationPath),
466
478
  mode,
467
479
  pattern,
468
480
  searchPath,
package/src/tools/ls.ts CHANGED
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import { Type } from "typebox";
4
4
  import { ToolNames } from "../core/tool-names.js";
5
5
  import {
6
+ createObservationPathFilter,
6
7
  finalizeObservation,
7
8
  OBSERVE_SELF_CAPS,
8
9
  observationBudgetExhausted,
@@ -53,7 +54,10 @@ export const lsTool: ToolSpec = {
53
54
  }
54
55
 
55
56
  try {
56
- const entries = readdirSync(root).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
57
+ const pathFilter = createObservationPathFilter(process.cwd(), options?.allowsObservationPath);
58
+ const entries = readdirSync(root)
59
+ .filter((entry) => pathFilter.allows(path.join(root, entry)))
60
+ .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
57
61
  const outputEntries: string[] = [];
58
62
  let entryLimitReached = false;
59
63
  for (const entry of entries) {
@@ -72,6 +76,7 @@ export const lsTool: ToolSpec = {
72
76
  if (outputEntries.length === 0) {
73
77
  return finalizeObservation({
74
78
  tool: ToolNames.Ls,
79
+ withheldPaths: pathFilter.withheldPaths,
75
80
  unit: "entries",
76
81
  output: "(empty directory)",
77
82
  shownCount: 0,
@@ -90,6 +95,7 @@ export const lsTool: ToolSpec = {
90
95
  const truncated = entryLimitReached || truncation.truncated;
91
96
  return finalizeObservation({
92
97
  tool: ToolNames.Ls,
98
+ withheldPaths: pathFilter.withheldPaths,
93
99
  unit: "entries",
94
100
  output: truncation.content,
95
101
  // Offload only when the byte cap cut collected entries; a bare
@@ -17,7 +17,7 @@ import {
17
17
  type RunReceipt,
18
18
  type RunReceiptVerification,
19
19
  } from "../domains/dispatch/types.js";
20
- import { summarizeTrustStatus } from "../domains/evidence/trust-projection.js";
20
+ import { summarizeTrustStatus, trustStateWord } from "../domains/evidence/trust-projection.js";
21
21
  import {
22
22
  adaptRunReceiptTrustStatus,
23
23
  type CanonicalTrustStatus,
@@ -100,13 +100,19 @@ function listRuns(deps: MonitorToolDeps, options: ToolInvokeOptions | undefined)
100
100
 
101
101
  function runStatus(deps: MonitorToolDeps, runId: string): ToolResult {
102
102
  const requestedRun = deps.dispatch.getRun(runId);
103
- const rootRunId = requestedRun?.lineage?.rootRunId ?? runId;
104
- const assignment = deps.dispatch.assignments?.getStored(rootRunId) ?? null;
103
+ const assignment = deps.dispatch.assignments?.getStored(runId) ?? null;
104
+ const rootRunId = assignment?.assignmentId ?? requestedRun?.lineage?.rootRunId ?? runId;
105
105
  const resolvedRunId = assignment?.terminalRunId ?? runId;
106
106
  const run = deps.dispatch.getRun(resolvedRunId) ?? requestedRun;
107
107
  if (!run && !assignment) return { kind: "error", message: `monitor: unknown run or assignment '${runId}'` };
108
108
  if (!run) return { kind: "error", message: `monitor: assignment '${runId}' has no available attempt` };
109
- const live = deps.dispatch.snapshot().running.find((entry) => entry.lineage.rootRunId === rootRunId) ?? null;
109
+ const live =
110
+ deps.dispatch
111
+ .snapshot()
112
+ .running.find(
113
+ (entry) =>
114
+ (deps.dispatch.assignments?.getStored(entry.runId)?.assignmentId ?? entry.lineage.rootRunId) === rootRunId,
115
+ ) ?? null;
110
116
  const reroutes =
111
117
  run.reroutes !== undefined && run.reroutes.length > 0
112
118
  ? ` reroutes=${run.reroutes.map((hop) => `${hop.fromNode}>${hop.toNode}`).join(",")}`
@@ -142,11 +148,18 @@ function runStatus(deps: MonitorToolDeps, runId: string): ToolResult {
142
148
  `live: phase=${live.outcomePhase} heartbeat=${live.heartbeat} elapsed=${Math.round(live.elapsedMs / 1000)}s tokens=${live.tokens.total}`,
143
149
  );
144
150
  }
151
+ const trust = isTerminalRunEnvelope(run) ? summarizeTrustStatus(durableRunEvidence(run).trustStatus) : null;
152
+ if (trust)
153
+ lines.push(
154
+ `quality: ${trustStateWord("validationGrounding", trust.axes.validationGrounding)}`,
155
+ `trust: ${trust.text}`,
156
+ );
145
157
  return {
146
158
  kind: "ok",
147
159
  output: lines.join("\n"),
148
160
  details: {
149
161
  mode: "status",
162
+ ...(trust ? { trust } : {}),
150
163
  ...(assignment
151
164
  ? {
152
165
  assignmentId: assignment.assignmentId,
@@ -289,8 +302,7 @@ function receiptToolLines(receipt: RunReceipt): string[] {
289
302
  */
290
303
  function runTools(deps: MonitorToolDeps, runId: string): ToolResult {
291
304
  const requestedRun = deps.dispatch.getRun(runId);
292
- const rootRunId = requestedRun?.lineage?.rootRunId ?? runId;
293
- const assignment = deps.dispatch.assignments?.getStored(rootRunId) ?? null;
305
+ const assignment = deps.dispatch.assignments?.getStored(runId) ?? null;
294
306
  const resolvedRunId = assignment?.terminalRunId ?? runId;
295
307
  const run = deps.dispatch.getRun(resolvedRunId) ?? requestedRun ?? null;
296
308
  if (run === null && assignment === null) return { kind: "error", message: `monitor: unknown run '${runId}'` };
@@ -504,8 +516,8 @@ async function runWait(
504
516
  const startedAt = performance.now();
505
517
  let run = deps.dispatch.getRun(runId);
506
518
  if (!run) return { kind: "error", message: `monitor: unknown run '${runId}'` };
507
- const rootRunId = run.lineage?.rootRunId ?? runId;
508
- let assignment = deps.dispatch.assignments?.getStored(rootRunId) ?? null;
519
+ let assignment = deps.dispatch.assignments?.getStored(runId) ?? null;
520
+ const rootRunId = assignment?.assignmentId ?? runId;
509
521
  while (assignment?.status === "running" || (assignment === null && !isTerminalRunEnvelope(run))) {
510
522
  if (signal?.aborted) return { kind: "error", message: "monitor: wait aborted" };
511
523
  const elapsed = Math.round(performance.now() - startedAt);
@@ -587,7 +599,11 @@ function collectRunLine(row: CollectedRunRow): string[] {
587
599
  lines.push(` ${workerTextLabel(row.evidence.trustStatus)}`);
588
600
  const output = row.evidence.output;
589
601
  if (output) {
590
- const capped = truncateUtf8(output.text, COLLECT_TEXT_BYTES, "...");
602
+ const capped = truncateUtf8(
603
+ output.text,
604
+ COLLECT_TEXT_BYTES,
605
+ `\n[preview clipped at ${COLLECT_TEXT_BYTES} bytes; the complete sealed text is output.text in ${row.run?.receiptPath ?? "the receipt"}]`,
606
+ );
591
607
  const qualifier = output.state === "partial" ? " (partial; the run did not complete this message)" : "";
592
608
  const truncatedNote = output.truncated ? ` (stored output truncated; full text was ${output.bytes} bytes)` : "";
593
609
  lines.push(` agent output${qualifier}${truncatedNote}:`, ...capped.split("\n").map((line) => ` ${line}`));
@@ -606,11 +622,10 @@ function collectRunLine(row: CollectedRunRow): string[] {
606
622
 
607
623
  function resolveCollectRow(deps: MonitorToolDeps, originalRunId: string, agentId: string): CollectRow {
608
624
  const original = deps.dispatch.getRun(originalRunId);
609
- const rootRunId = original?.lineage?.rootRunId ?? originalRunId;
610
625
  // The durable assignment record is written asynchronously at admission, so a
611
626
  // collect issued in that window sees none yet and reads the attempt directly.
612
627
  // terminalRunId is null while the assignment is still running.
613
- const assignment = deps.dispatch.assignments?.getStored(rootRunId) ?? null;
628
+ const assignment = deps.dispatch.assignments?.getStored(originalRunId) ?? null;
614
629
  const runId = assignment?.terminalRunId ?? originalRunId;
615
630
  const run = deps.dispatch.getRun(runId) ?? original;
616
631
  return {
@@ -1,29 +1,16 @@
1
1
  /**
2
- * Per-process switch for the RETRIEVE plane, the only builtin plane that
3
- * leaves the machine.
4
- *
5
- * There is no per-run tool allowlist on the main-agent path: a headless
6
- * `clio-coder run` gets whatever `registerAllTools` registered, and the registry
7
- * answers an unregistered name with a `not_visible` verdict. So the existing
8
- * lever for "this run has no network" is registration itself, the same lever
9
- * that already keeps `ask_user` out of headless and worker registries. This
10
- * module carries the switch that lever reads.
11
- *
12
- * The channel is an environment variable because the process that needs the
13
- * policy is a child: the skill-eval harness spawns `clio-coder run` for each arm,
14
- * and any worker those runs dispatch is a grandchild. Env inherits down the
15
- * whole tree, so one setting at spawn time covers every registry built below
16
- * it (`src/tools/bootstrap.ts`, `src/engine/worker-tools.ts`) without a flag
17
- * threaded through four call layers.
18
- *
19
- * What this does not cover: a runtime that executes its own tool surface
20
- * outside Clio's mediation (an external CLI subprocess) never consults this
21
- * registry, so its network access is its own to answer for.
2
+ * Process-wide registration switch for the RETRIEVE tool plane (web_fetch).
3
+ * This removes retrieval tools from main and worker registries. It does not
4
+ * restrict bash, hooks, external CLIs, or provider traffic. Hermetic execution
5
+ * requires an OS network sandbox supplied by the operator or eval harness.
6
+ * The environment setting propagates to child registries without per-run wiring.
22
7
  */
8
+ export const NO_NETWORK_TOOLS_ENV = "CLIO_CODER_DISABLE_RETRIEVE_TOOLS";
23
9
 
24
- /** Set to "1" to strip network tools from every registry built in this process. */
25
- export const NO_NETWORK_TOOLS_ENV = "CLIO_CODER_NO_NETWORK_TOOLS";
26
-
10
+ /** Legacy spelling remains accepted for existing harnesses; neither is a sandbox. */
27
11
  export function networkToolsDisabled(env: NodeJS.ProcessEnv = process.env): boolean {
28
- return env[NO_NETWORK_TOOLS_ENV] === "1";
12
+ return env[NO_NETWORK_TOOLS_ENV] === "1" || env.CLIO_CODER_NO_NETWORK_TOOLS === "1";
29
13
  }
14
+
15
+ /** Operator process opt-in; never accepted from model arguments or project settings. */
16
+ export const WEB_FETCH_ALLOW_PRIVATE_NETWORK_ENV = "CLIO_CODER_WEB_FETCH_ALLOW_PRIVATE_NETWORK";
@@ -1,4 +1,6 @@
1
1
  import { GUARDRAIL_DEFAULTS, resolveGuardrail } from "../core/guardrails.js";
2
+ import { createSafetyPolicyEngine } from "../domains/safety/policy-engine.js";
3
+ import type { ImageContent } from "../engine/types.js";
2
4
  import type { ToolInvokeOptions, ToolResult } from "./registry.js";
3
5
  import { offloadPointer, writeToolOffload } from "./result-shaping.js";
4
6
  import { formatSize } from "./truncate.js";
@@ -337,6 +339,8 @@ export function observationBudgetExhausted(input: {
337
339
  }
338
340
 
339
341
  export interface ObservationInput {
342
+ images?: ImageContent[];
343
+ withheldPaths?: number;
340
344
  tool: string;
341
345
  unit: ObservationUnit;
342
346
  format?: ObservationFormat;
@@ -446,7 +450,10 @@ export function finalizeObservation(input: ObservationInput): ToolResult {
446
450
  }
447
451
  }
448
452
 
449
- const shownBytes = byteLength(output);
453
+ if ((input.withheldPaths ?? 0) > 0 && format === "text")
454
+ output += `\n\n[${input.withheldPaths} protected paths withheld by zero-access policy]`;
455
+ const shownBytes =
456
+ byteLength(output) + (input.images ?? []).reduce((bytes, image) => bytes + byteLength(image.data), 0);
450
457
  recordSpentBytes(input.reservation, shownBytes);
451
458
  const budget = budgetDetails(input.reservation);
452
459
  const observation: Observation = {
@@ -466,5 +473,35 @@ export function finalizeObservation(input: ObservationInput): ToolResult {
466
473
  ...(offloadPath !== null ? { offloadPath } : {}),
467
474
  ...(budget !== null ? { budget } : {}),
468
475
  };
469
- return { kind: "ok", output, details: { ...(input.details ?? {}), observation } };
476
+ return {
477
+ kind: "ok",
478
+ output,
479
+ ...(input.images?.length ? { images: input.images } : {}),
480
+ details: { ...(input.details ?? {}), observation },
481
+ };
482
+ }
483
+
484
+ /** Producers pass structured paths before rendering or offloading any content. */
485
+ export function createObservationPathFilter(
486
+ cwd = process.cwd(),
487
+ allowsPath?: (path: string) => boolean,
488
+ ): {
489
+ allows(path: string): boolean;
490
+ readonly withheldPaths: number;
491
+ } {
492
+ const policy = allowsPath ? undefined : createSafetyPolicyEngine({ cwd });
493
+ const allows =
494
+ allowsPath ??
495
+ ((path: string) => policy?.evaluate({ tool: "read", args: { path } }).reasonCode !== "path-policy:zeroAccessPaths");
496
+ const withheld = new Set<string>();
497
+ return {
498
+ allows(path) {
499
+ if (allows(path)) return true;
500
+ withheld.add(path);
501
+ return false;
502
+ },
503
+ get withheldPaths() {
504
+ return withheld.size;
505
+ },
506
+ };
470
507
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Typed tool presentation policy. Answers, per tool, what the transcript's
3
- * balanced (`/output default`) view needs to know: does the block open folded
3
+ * Standard view needs to know: does the block open folded
4
4
  * or expanded, does the folded row keep a mutation diff visible, and does a
5
5
  * failed folded row carry an output excerpt.
6
6
  *
package/src/tools/read.ts CHANGED
@@ -1,8 +1,15 @@
1
1
  import { readFileSync, statSync } from "node:fs";
2
2
  import { Type } from "typebox";
3
+ import { detectSupportedImageMimeType, prepareBoundedImage } from "../core/file-references.js";
3
4
  import { GUARDRAIL_DEFAULTS, resolveGuardrail } from "../core/guardrails.js";
4
5
  import { ToolNames } from "../core/tool-names.js";
5
- import { finalizeObservation, observationBudgetExhausted, reserveObservation } from "./observation.js";
6
+ import {
7
+ commitObservationReservation,
8
+ finalizeObservation,
9
+ observationBudgetExhausted,
10
+ releaseObservation,
11
+ reserveObservation,
12
+ } from "./observation.js";
6
13
  import { resolveReadPath } from "./path-utils.js";
7
14
  import type { ToolResult, ToolSpec } from "./registry.js";
8
15
  import { isSessionOffloadPath } from "./result-shaping.js";
@@ -28,13 +35,35 @@ export function readMaxBytes(): number {
28
35
  return Math.max(MIN_READ_CAP_BYTES, resolveGuardrail("readMaxBytes"));
29
36
  }
30
37
 
38
+ // Number only an already bounded slice, retaining its explicit physical line
39
+ // count: a truncated slice ending in a blank line can look like a terminator.
40
+ function numberSourceLines(content: string, firstLine: number, lineCount: number): string {
41
+ return content
42
+ .split("\n")
43
+ .map((line, index) => (index < lineCount ? `${firstLine + index} | ${line}` : line))
44
+ .join("\n");
45
+ }
46
+
47
+ function numberedPrefixBytes(totalLines: number): number {
48
+ let bytes = totalLines * 3; // " | " after each decimal source line number.
49
+ for (let first = 1, digits = 1; first <= totalLines; first *= 10, digits++) {
50
+ bytes += (Math.min(totalLines + 1, first * 10) - first) * digits;
51
+ }
52
+ return bytes;
53
+ }
54
+
31
55
  export const readTool: ToolSpec = {
32
56
  name: ToolNames.Read,
33
- description: `Read a UTF-8 text file. Output is capped at ${DEFAULT_MAX_LINES} lines or ${
57
+ description: `Read a UTF-8 text file or a PNG, JPEG, GIF, or WebP image when the routed model supports vision. Output is capped at ${DEFAULT_MAX_LINES} lines or ${
34
58
  DEFAULT_READ_MAX_BYTES / 1024
35
- }KB per call; truncated results say how to continue with offset/limit. Pass tail=N to read the last N lines (jump to EOF) instead of paging from the top.`,
59
+ }KB per call; truncated results say how to continue with offset/limit. Pass tail=N to read the last N lines (jump to EOF) instead of paging from the top. Set line_numbers=true for citations: each source line is prefixed with its physical 1-based line number and " | "; these labels are not file content.`,
36
60
  parameters: Type.Object({
37
61
  path: Type.String({ description: "File path (relative or absolute)." }),
62
+ line_numbers: Type.Optional(
63
+ Type.Boolean({
64
+ description: "Display physical source line numbers for citations. Default false preserves plain text.",
65
+ }),
66
+ ),
38
67
  offset: Type.Optional(Type.Number({ description: "1-indexed start line." })),
39
68
  limit: Type.Optional(Type.Number({ description: "Max lines to read." })),
40
69
  tail: Type.Optional(
@@ -47,6 +76,7 @@ export const readTool: ToolSpec = {
47
76
  const pathArg = typeof args.path === "string" ? args.path : null;
48
77
  if (!pathArg) return { kind: "error", message: "read: missing path argument" };
49
78
  const filePath = resolveReadPath(pathArg);
79
+ const numbered = args.line_numbers === true;
50
80
  const offset = typeof args.offset === "number" && args.offset > 0 ? Math.floor(args.offset) : 1;
51
81
  const limit = typeof args.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : null;
52
82
  const tail = typeof args.tail === "number" && args.tail > 0 ? Math.floor(args.tail) : null;
@@ -76,13 +106,44 @@ export const readTool: ToolSpec = {
76
106
  hint: "Use offset/limit in a follow-up turn or grep/find for a narrower section.",
77
107
  });
78
108
  }
79
- const content = readFileSync(filePath, "utf8");
109
+ const bytes = readFileSync(filePath);
110
+ if (detectSupportedImageMimeType(bytes) !== null) {
111
+ if (options?.supportsImages !== true)
112
+ return {
113
+ kind: "error",
114
+ message:
115
+ "IMAGE_INPUT_UNSUPPORTED: the routed model does not support image input. Choose a vision-capable model to inspect this file.",
116
+ };
117
+ const output = `Image: ${pathArg}`;
118
+ commitObservationReservation(reservation);
119
+ const image = await prepareBoundedImage(
120
+ bytes,
121
+ Math.min(reservation.callCapBytes, options.toolResultMaxBytes ?? readMaxBytes()) - Buffer.byteLength(output) - 512,
122
+ );
123
+ if (image === null)
124
+ return {
125
+ kind: "error",
126
+ message: "IMAGE_RESULT_TOO_LARGE: image could not be encoded within the tool result byte cap.",
127
+ };
128
+ return finalizeObservation({
129
+ tool: ToolNames.Read,
130
+ unit: "results",
131
+ output,
132
+ images: [image],
133
+ shownCount: 1,
134
+ totalCount: 1,
135
+ truncated: false,
136
+ reservation,
137
+ ...(options ? { options } : {}),
138
+ });
139
+ }
140
+ const content = bytes.toString("utf8");
80
141
  // Slice from the raw split (keeps the trailing newline on selections that
81
142
  // reach EOF); count lines honestly (a trailing "\n" is a terminator, not
82
143
  // a phantom extra line) so continuation notices never over-report by one.
83
144
  const allLines = content.split("\n");
84
145
  const totalLines = splitLinesForCounting(content).length;
85
- const totalBytes = Buffer.byteLength(content, "utf8");
146
+ const totalBytes = Buffer.byteLength(content, "utf8") + (numbered ? numberedPrefixBytes(totalLines) : 0);
86
147
  const startIndex = Math.min(offset - 1, totalLines);
87
148
  if (tail === null && offset > 1 && startIndex >= totalLines) {
88
149
  // The anchor matters for weak models: a bare "beyond end of file"
@@ -104,10 +165,26 @@ export const readTool: ToolSpec = {
104
165
  // the end (reusing truncateTail) so the very tail always survives.
105
166
  const startLine = Math.max(0, totalLines - tail);
106
167
  const tailContent = allLines.slice(startLine).join("\n");
107
- const truncation = truncateTail(tailContent, { maxBytes: cap, maxLines: tail });
168
+ const sourceTruncation = truncateTail(tailContent, { maxBytes: cap, maxLines: tail });
169
+ let truncation = sourceTruncation;
170
+ if (numbered) {
171
+ const numberedContent = numberSourceLines(
172
+ sourceTruncation.content,
173
+ totalLines - sourceTruncation.outputLines + 1,
174
+ sourceTruncation.outputLines,
175
+ );
176
+ truncation = truncateTail(numberedContent, { maxBytes: cap, maxLines: tail });
177
+ if (sourceTruncation.lastLinePartial || truncation.lastLinePartial) {
178
+ // Never return a tail fragment with a lost or fabricated complete
179
+ // line label. Keep the suffix within the cap and mark it partial.
180
+ const label = `${totalLines} | [partial line suffix] `;
181
+ const suffix = truncateTail(allLines[totalLines - 1] ?? "", { maxBytes: cap - Buffer.byteLength(label) });
182
+ truncation = { ...truncation, content: label + suffix.content, outputLines: 0, truncated: true };
183
+ }
184
+ }
108
185
  const shownLines = truncation.outputLines;
109
186
  const firstShown = Math.max(1, totalLines - shownLines + 1);
110
- const truncated = startLine > 0 || truncation.truncated;
187
+ const truncated = startLine > 0 || sourceTruncation.truncated || truncation.truncated;
111
188
  return finalizeObservation({
112
189
  tool: ToolNames.Read,
113
190
  unit: "lines",
@@ -116,19 +193,37 @@ export const readTool: ToolSpec = {
116
193
  totalCount: totalLines,
117
194
  totalBytes,
118
195
  truncated,
119
- ...(truncated ? { next: `offset=${Math.max(1, firstShown - shownLines)} limit=${shownLines}` } : {}),
196
+ ...(truncated && shownLines > 0
197
+ ? {
198
+ next: `offset=${Math.max(1, firstShown - shownLines)} limit=${shownLines}${numbered ? " line_numbers=true" : ""}`,
199
+ }
200
+ : {}),
120
201
  reservation,
121
202
  ...(options ? { options } : {}),
122
203
  });
123
204
  }
124
205
 
206
+ const endIndex = limit !== null ? Math.min(startIndex + limit, totalLines) : totalLines;
207
+ // Preserve the last selected source line's terminator when it exists.
208
+ // Joining a limited slice alone turns ["x", ""] into "x\n", which
209
+ // truncateHead counts as one line; [""] even becomes an empty file.
210
+ // The raw split's final entry tells us whether that newline is real,
211
+ // without inventing a line at EOF or changing shared text counting.
125
212
  const selected =
126
- limit !== null ? allLines.slice(startIndex, startIndex + limit).join("\n") : allLines.slice(startIndex).join("\n");
127
- const truncation: TruncationResult = truncateHead(selected, { maxBytes: cap });
213
+ allLines.slice(startIndex, endIndex).join("\n") + (endIndex > startIndex && endIndex < allLines.length ? "\n" : "");
214
+ const sourceTruncation = truncateHead(selected, { maxBytes: cap });
215
+ const truncation: TruncationResult =
216
+ numbered && !sourceTruncation.firstLineExceedsLimit
217
+ ? truncateHead(numberSourceLines(sourceTruncation.content, startIndex + 1, sourceTruncation.outputLines), {
218
+ maxBytes: cap,
219
+ })
220
+ : sourceTruncation;
128
221
  if (truncation.firstLineExceedsLimit) {
129
- const firstLineSize = formatSize(Buffer.byteLength(allLines[startIndex] ?? "", "utf8"));
130
- const linePrefix = truncateUtf8(allLines[startIndex] ?? "", cap, "\n[line truncated]");
131
- const output = `${linePrefix}\n\n[Line ${startIndex + 1} is ${firstLineSize}, exceeding the ${formatSize(cap)} read limit. Showing the UTF-8 prefix only. Use grep with a narrower literal/regex or edit with exact surrounding text; use shell access only when byte-level inspection is required.]`;
222
+ const label = numbered ? `${startIndex + 1} | ` : "";
223
+ const firstLineSize = formatSize(Buffer.byteLength(label + (allLines[startIndex] ?? ""), "utf8"));
224
+ const linePrefix =
225
+ label + truncateUtf8(allLines[startIndex] ?? "", cap - Buffer.byteLength(label), "\n[line truncated]");
226
+ const output = `${linePrefix}\n\n[${numbered ? "Numbered line" : "Line"} ${startIndex + 1} is ${firstLineSize}, exceeding the ${formatSize(cap)} read limit. Showing the UTF-8 prefix only. Use grep with a narrower literal/regex or edit with exact surrounding text; use shell access only when byte-level inspection is required.]`;
132
227
  return finalizeObservation({
133
228
  tool: ToolNames.Read,
134
229
  unit: "lines",
@@ -144,7 +239,7 @@ export const readTool: ToolSpec = {
144
239
  }
145
240
  const endDisplay = startIndex + truncation.outputLines;
146
241
  const moreAfter = endDisplay < totalLines;
147
- const truncated = truncation.truncated || (limit !== null && moreAfter);
242
+ const truncated = sourceTruncation.truncated || truncation.truncated || (limit !== null && moreAfter);
148
243
  return finalizeObservation({
149
244
  tool: ToolNames.Read,
150
245
  unit: "lines",
@@ -153,7 +248,7 @@ export const readTool: ToolSpec = {
153
248
  totalCount: totalLines,
154
249
  totalBytes,
155
250
  truncated,
156
- ...(truncated && moreAfter ? { next: `offset=${endDisplay + 1}` } : {}),
251
+ ...(truncated && moreAfter ? { next: `offset=${endDisplay + 1}${numbered ? " line_numbers=true" : ""}` } : {}),
157
252
  reservation,
158
253
  ...(options ? { options } : {}),
159
254
  });
@@ -167,6 +262,8 @@ export const readTool: ToolSpec = {
167
262
  };
168
263
  }
169
264
  return { kind: "error", message: `read: ${msg}` };
265
+ } finally {
266
+ releaseObservation(reservation);
170
267
  }
171
268
  },
172
269
  };