@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
@@ -9,9 +9,10 @@ import {
9
9
  type SkillToolSurfaceViolation,
10
10
  } from "../core/skill-activation.js";
11
11
  import { type ToolName, ToolNames } from "../core/tool-names.js";
12
+ import { containsInstructionMarkers, INSTRUCTION_SHAPED_WARNING } from "../core/untrusted-content.js";
12
13
  import type { MiddlewareContract } from "../domains/middleware/contract.js";
13
14
  import type { MiddlewareEffect, MiddlewareHookInput, MiddlewareMetadataValue } from "../domains/middleware/types.js";
14
- import type { ActionClass, ClassifierCall } from "../domains/safety/action-classifier.js";
15
+ import { type ActionClass, type ClassifierCall, webFetchIsOutward } from "../domains/safety/action-classifier.js";
15
16
  import { approvalAxisId } from "../domains/safety/approval-axis.js";
16
17
  import {
17
18
  type AutonomyExposure,
@@ -26,6 +27,7 @@ import type { SafetyContract, SafetyDecision } from "../domains/safety/contract.
26
27
  import type { DecisionPresentation } from "../domains/safety/decision-presentation.js";
27
28
  import { hashToolCall } from "../domains/safety/loop-detector.js";
28
29
  import { detectValidationCommand } from "../domains/safety/protected-artifacts.js";
30
+ import type { ImageContent } from "../engine/types.js";
29
31
  import { askUserExposure } from "./ask-user.js";
30
32
  import { type DispatchPlanView, describeDispatchPlan } from "./dispatch-plan.js";
31
33
  import type { ToolPresentationPolicy } from "./presentation.js";
@@ -105,7 +107,7 @@ export interface ToolMetadata {
105
107
  */
106
108
  promptHint?: ToolPromptHintMetadata;
107
109
  /**
108
- * How transcript surfaces present this tool's block under `/output default`.
110
+ * How transcript surfaces present this tool's block under Standard output style.
109
111
  * Optional: tools that declare nothing fold like every other tool.
110
112
  */
111
113
  presentation?: ToolPresentationPolicy;
@@ -171,6 +173,8 @@ export type ToolResult =
171
173
  | {
172
174
  kind: "ok";
173
175
  output: string;
176
+ /** Bounded visual evidence accompanying the mandatory text result. */
177
+ images?: ImageContent[];
174
178
  details?: ToolResultDetails;
175
179
  /** Internal registry projection consumed only by the agent-tool adapter. */
176
180
  modelContext?: string;
@@ -214,6 +218,12 @@ export interface RegistryDeps {
214
218
  }
215
219
 
216
220
  export interface ToolInvokeOptions {
221
+ /** Registry-owned filter bound to the active compiled safety policy. */
222
+ allowsObservationPath?: (path: string) => boolean;
223
+ /** Trusted submitting host identity for nested dispatch; never model arguments. */
224
+ hostRun?: import("../domains/dispatch/contract.js").DispatchPreparationOptions["hostRun"];
225
+ /** Trusted resolved model capability; never read from tool arguments. */
226
+ supportsImages?: boolean;
217
227
  signal?: AbortSignal;
218
228
  runId?: string;
219
229
  sessionId?: string;
@@ -464,7 +474,12 @@ export function createRegistry(deps: RegistryDeps): ToolRegistry {
464
474
  try {
465
475
  const preparedArgs = prepareToolArgs(spec, call.args ?? {});
466
476
  resultDisposition = resolveToolResultDisposition(spec, preparedArgs);
467
- const result = await spec.run(preparedArgs, options);
477
+ const { allowsObservationPath: _callerPathFilter, ...callerOptions } = options ?? {};
478
+ const allowsObservationPath = deps.safety.policy?.allowsObservationPath;
479
+ const result = await spec.run(preparedArgs, {
480
+ ...callerOptions,
481
+ ...(allowsObservationPath ? { allowsObservationPath } : {}),
482
+ });
468
483
  const digest = toolResultDigestFor(spec, result, resultDisposition, options);
469
484
  const afterEffects = runToolHook("after_tool", spec, call, decision, options, result, digest);
470
485
  const finalResult = shapeToolResult(spec, applyToolResultEffects(result, afterEffects), options, resultDisposition);
@@ -583,10 +598,13 @@ export function createRegistry(deps: RegistryDeps): ToolRegistry {
583
598
  ? (spec.describeDispatchPlan?.(call.args ?? {}) ?? describeDispatchPlan(call.args))
584
599
  : null;
585
600
  const planScale = dispatchPlan?.planScale === true;
586
- // The exposure tier rides on the args of the gate that raised it, so the
587
- // workflow author, not the classifier, decides what counts as outward.
588
- // ask_user is the only tool that declares one today.
589
- const exposure = call.tool === ToolNames.AskUser ? askUserExposure(call.args) : DEFAULT_AUTONOMY_EXPOSURE;
601
+ // Gates declare their tier; write-shaped HTTP requests send data outward.
602
+ const exposure =
603
+ call.tool === ToolNames.AskUser
604
+ ? askUserExposure(call.args)
605
+ : call.tool === ToolNames.WebFetch && webFetchIsOutward(call.args)
606
+ ? "outward"
607
+ : DEFAULT_AUTONOMY_EXPOSURE;
590
608
  const disposition = mapAutonomy(level, actionClass, {
591
609
  executeRecognized: decision.policy?.execRecognition !== "unrecognized",
592
610
  ...(planScale ? { dispatchPlanScale: true } : {}),
@@ -1030,10 +1048,8 @@ const HEADLESS_GUIDANCE_MAX_CHARS = 240;
1030
1048
  * model that hits an unrecognized-bash rail retries the same shape until the run
1031
1049
  * ends. An unrecognized execution decision carries the working form in its
1032
1050
  * reasons, and those reasons reach the audit record and the interactive approval
1033
- * overlay but not the model. The first reason states the axis the denial already
1034
- * implies, so only the reasons after it are candidates, and only the first of
1035
- * those, bounded: this is a nudge toward the recognized spelling, not a dump of
1036
- * the policy's reason list.
1051
+ * overlay but not the model. Preserve one bounded recovery hint separately
1052
+ * from the actual policy cause carried by the terminal denial below.
1037
1053
  */
1038
1054
  function headlessDenialGuidance(decision: SafetyDecision, reason: string): string | null {
1039
1055
  // Interactive denials are left exactly as they were: the operator saw the
@@ -1059,9 +1075,9 @@ function headlessDenialGuidance(decision: SafetyDecision, reason: string): strin
1059
1075
  * it with the standing pivot instruction.
1060
1076
  *
1061
1077
  * A headless answer is the exception: nobody will ever approve it, so the detail
1062
- * carries one line of recovery guidance after the denial sentence. The sentence
1063
- * stays the detail's prefix, which the skill-eval permission-wall recognizer
1064
- * depends on.
1078
+ * carries the policy cause and rule, a terminal settlement statement, and any
1079
+ * recovery guidance. The denial sentence stays the detail's prefix, which the
1080
+ * skill-eval permission-wall recognizer depends on.
1065
1081
  */
1066
1082
  function parkAnsweredBlockedVerdict(
1067
1083
  decision: SafetyDecision,
@@ -1069,12 +1085,25 @@ function parkAnsweredBlockedVerdict(
1069
1085
  reason: string,
1070
1086
  ): Extract<RegistryVerdict, { kind: "blocked" }> {
1071
1087
  const guidance = headlessDenialGuidance(decision, reason);
1088
+ const detail = [reason];
1089
+ if (reason.startsWith(HEADLESS_PERMISSION_DENIED_MARKER)) {
1090
+ if (decision.policy?.ruleId) detail.push(`rule: ${decision.policy.ruleId}`);
1091
+ const cause =
1092
+ decision.policy?.kind === "ask"
1093
+ ? decision.policy.reasons[0]
1094
+ : decision.kind === "allow"
1095
+ ? undefined
1096
+ : decision.rejection.short;
1097
+ if (cause) detail.push(cause);
1098
+ detail.push("This call was denied; no approval is pending.");
1099
+ if (guidance !== null) detail.push(guidance);
1100
+ }
1072
1101
  const blocked: SafetyDecision = {
1073
1102
  kind: "block",
1074
1103
  classification: decision.classification,
1075
1104
  rejection: {
1076
1105
  short: `${tool} blocked: ${decision.classification.actionClass} was not approved`,
1077
- detail: guidance === null ? reason : `${reason}\n${guidance}`,
1106
+ detail: detail.join("\n"),
1078
1107
  hints: [],
1079
1108
  },
1080
1109
  ...(decision.policy !== undefined ? { policy: decision.policy } : {}),
@@ -1206,6 +1235,10 @@ function buildToolHookInput(
1206
1235
  }
1207
1236
  if (call.tool !== spec.name) metadata.requestedToolName = call.tool;
1208
1237
  if (result !== undefined) {
1238
+ if (hook === "after_tool" && ["web_fetch", "read", "bash", "dispatch", "monitor"].includes(spec.name))
1239
+ metadata.untrustedInstructionMarkers = containsInstructionMarkers(
1240
+ result.kind === "ok" ? result.output : result.kind === "error" ? result.message : "",
1241
+ );
1209
1242
  metadata.resultKind = result.kind;
1210
1243
  if (result.kind === "error") metadata.errorMessage = result.message;
1211
1244
  if (result.kind === "ok" && result.terminate === true) metadata.terminate = true;
@@ -1259,14 +1292,18 @@ function firstBlockToolEffect(
1259
1292
  function applyToolResultEffects(result: ToolResult, effects: ReadonlyArray<MiddlewareEffect>): ToolResult {
1260
1293
  const annotations = annotationMessages(effects);
1261
1294
  if (annotations.length === 0) return result;
1262
- const suffix = `\n\n${annotations.join("\n")}`;
1295
+ const warning = `[middleware:warn] ${INSTRUCTION_SHAPED_WARNING}`;
1296
+ const prefix = annotations.includes(warning) ? `${warning}\n\n` : "";
1297
+ const remaining = annotations.filter((annotation) => annotation !== warning);
1298
+ const suffix = remaining.length > 0 ? `\n\n${remaining.join("\n")}` : "";
1263
1299
  if (result.kind === "ok") {
1264
- const annotated: ToolResult = { kind: "ok", output: `${result.output}${suffix}` };
1300
+ const annotated: ToolResult = { kind: "ok", output: `${prefix}${result.output}${suffix}` };
1265
1301
  if (result.details !== undefined) annotated.details = result.details;
1266
1302
  if (result.terminate === true) annotated.terminate = true;
1303
+ if (result.images !== undefined) annotated.images = result.images;
1267
1304
  return annotated;
1268
1305
  }
1269
- const annotated: ToolResult = { kind: "error", message: `${result.message}${suffix}` };
1306
+ const annotated: ToolResult = { kind: "error", message: `${prefix}${result.message}${suffix}` };
1270
1307
  if (result.details !== undefined) annotated.details = result.details;
1271
1308
  return annotated;
1272
1309
  }
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { mkdirSync, readdirSync, rmdirSync, rmSync, statSync, writeFileSync } from "node:fs";
3
3
  import { isAbsolute, join, relative, resolve } from "node:path";
4
+ import { INSTRUCTION_SHAPED_WARNING } from "../core/untrusted-content.js";
4
5
  import { clioStateDir } from "../core/xdg.js";
5
6
  import type { ToolInvokeOptions, ToolResult, ToolResultDetails, ToolSpec } from "./registry.js";
6
7
  import {
@@ -24,7 +25,10 @@ const RESULT_OFFLOAD_MAX_BYTES = 10 * 1024 * 1024;
24
25
  const TAIL_NOTICE_RESERVE_BYTES = 512;
25
26
  export const TOOL_OFFLOAD_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1000;
26
27
 
27
- type ToolResultShapeContext = Pick<ToolInvokeOptions, "sessionId" | "toolCallId" | "toolResultMaxBytes">;
28
+ type ToolResultShapeContext = Pick<
29
+ ToolInvokeOptions,
30
+ "sessionId" | "toolCallId" | "toolResultMaxBytes" | "supportsImages"
31
+ >;
28
32
 
29
33
  function mergeDetails(details: ToolResultDetails | undefined, resultSize: Record<string, unknown>): ToolResultDetails {
30
34
  return { ...(details ?? {}), resultSize };
@@ -419,7 +423,7 @@ function withOffloadMetadata(
419
423
  * Apply legacy shaping or one declared canonical disposition. Registry calls
420
424
  * this once, after middleware annotations have produced the terminal result.
421
425
  */
422
- export function shapeToolResult(
426
+ function shapeTextToolResultBody(
423
427
  spec: ToolSpec,
424
428
  result: ToolResult,
425
429
  context?: ToolResultShapeContext,
@@ -519,3 +523,107 @@ export function shapeToolResult(
519
523
  modelContext: projection.text,
520
524
  };
521
525
  }
526
+
527
+ /** Keep the harness warning visible even when the chosen projection omits the source body. */
528
+ function shapeTextToolResult(
529
+ spec: ToolSpec,
530
+ result: ToolResult,
531
+ context?: ToolResultShapeContext,
532
+ requestedDisposition?: ToolResultDisposition,
533
+ ): ToolResult {
534
+ const shaped = shapeTextToolResultBody(spec, result, context, requestedDisposition);
535
+ const warning = `[middleware:warn] ${INSTRUCTION_SHAPED_WARNING}`;
536
+ if (!resultText(result).includes(warning)) return shaped;
537
+ const hardMaxBytes = maxBytesFor(spec, context);
538
+ const disposition = normalizeToolResultDisposition(spec, hardMaxBytes, requestedDisposition);
539
+ const preserve = (text: string, cap: number, tail: boolean): string => {
540
+ if (text.startsWith(warning) && byteLength(text) <= cap) return text;
541
+ const prefix = `${warning}\n\n`;
542
+ const remainder = text.split(warning).join("").trimStart();
543
+ const allowance = Math.max(0, cap - byteLength(prefix));
544
+ if (allowance === 0) return truncateUtf8(warning, cap, "");
545
+ const body = tail
546
+ ? truncateTail(remainder, { maxBytes: allowance, maxLines: Number.MAX_SAFE_INTEGER }).content
547
+ : truncateUtf8(remainder, allowance, "");
548
+ return prefix + body;
549
+ };
550
+ const output = preserve(
551
+ resultText(shaped),
552
+ Math.min(hardMaxBytes, disposition?.presentation.maxBytes ?? hardMaxBytes),
553
+ disposition?.presentation.overflow === "tail",
554
+ );
555
+ const modelContext =
556
+ shaped.modelContext === undefined
557
+ ? undefined
558
+ : preserve(
559
+ shaped.modelContext,
560
+ Math.min(hardMaxBytes, disposition?.context.maxBytes ?? hardMaxBytes),
561
+ disposition?.context.mode === "bounded" && disposition.context.excerpt === "tail",
562
+ );
563
+ const previous = existingDisposition(shaped.details);
564
+ const details = { ...shaped.details };
565
+ if (previous !== null)
566
+ details.resultDisposition = {
567
+ ...previous,
568
+ presentation: { ...previous.presentation, content: output },
569
+ displayedBytes: byteLength(output),
570
+ contextBytes: byteLength(modelContext ?? output),
571
+ presentationTruncated: previous.presentationTruncated || byteLength(resultText(shaped)) > byteLength(output),
572
+ contextTruncated:
573
+ previous.contextTruncated || byteLength(shaped.modelContext ?? "") > byteLength(modelContext ?? ""),
574
+ };
575
+ const size = detailsRecord(shaped.details, "resultSize");
576
+ if (size !== null) details.resultSize = { ...size, shownBytes: byteLength(output) };
577
+ return {
578
+ ...shaped,
579
+ ...(shaped.kind === "ok" ? { output } : { message: output }),
580
+ ...(modelContext === undefined ? {} : { modelContext }),
581
+ details,
582
+ };
583
+ }
584
+
585
+ /** Image bytes share the same payload cap as text, including after annotation. */
586
+ export function shapeToolResult(
587
+ spec: ToolSpec,
588
+ result: ToolResult,
589
+ context?: ToolResultShapeContext,
590
+ requestedDisposition?: ToolResultDisposition,
591
+ ): ToolResult {
592
+ if (result.kind !== "ok" || !result.images?.length)
593
+ return shapeTextToolResult(spec, result, context, requestedDisposition);
594
+ const hardMaxBytes = maxBytesFor(spec, context);
595
+ const disposition = normalizeToolResultDisposition(spec, hardMaxBytes, requestedDisposition);
596
+ const maxBytes = Math.min(hardMaxBytes, disposition?.context.maxBytes ?? hardMaxBytes);
597
+ const images: NonNullable<typeof result.images> = [];
598
+ let imageBytes = 0;
599
+ for (const image of result.images) {
600
+ const bytes = byteLength(image.data);
601
+ if (
602
+ context?.supportsImages === true &&
603
+ disposition?.context.mode !== "metadata-only" &&
604
+ bytes + imageBytes < maxBytes - 512
605
+ ) {
606
+ images.push(image);
607
+ imageBytes += bytes;
608
+ }
609
+ }
610
+ const omitted = result.images.length - images.length;
611
+ const notice =
612
+ omitted > 0 ? `[${omitted} image(s) omitted: model capability, context policy, or tool result byte cap.]\n` : "";
613
+ const remaining = Math.max(1, maxBytes - imageBytes);
614
+ const shaped = shapeTextToolResult(
615
+ spec,
616
+ { ...result, output: notice + result.output, images },
617
+ { ...context, toolResultMaxBytes: remaining },
618
+ requestedDisposition,
619
+ );
620
+ if (shaped.kind !== "ok") return shaped;
621
+ // Legacy truncation notices may extend beyond their text allowance; the image
622
+ // envelope has a strict combined cap, so bound the final projections too.
623
+ return {
624
+ ...shaped,
625
+ images,
626
+ output: truncateUtf8(shaped.output, remaining, ""),
627
+ ...(shaped.modelContext === undefined ? {} : { modelContext: truncateUtf8(shaped.modelContext, remaining, "") }),
628
+ };
629
+ }
@@ -47,7 +47,8 @@ function waitingTrailer(tasks: ReadonlyArray<UserTask>): string[] {
47
47
  .filter((task) => task.status === "open" || task.status === "handed")
48
48
  .map(
49
49
  (task) =>
50
- `operator tasks waiting: ${task.id} ${JSON.stringify(task.title)} — pick up with action="pick" id="${task.id}"`,
50
+ `operator tasks waiting: ${task.id} ${JSON.stringify(task.title)} — durable status=${task.status}; ` +
51
+ `not completed; pick only if this is the intended operator task, with action="pick" id="${task.id}" before work`,
51
52
  );
52
53
  }
53
54
 
@@ -60,13 +61,30 @@ function renderTaskBoardText(board: TaskBoardSnapshot, userTasks: ReadonlyArray<
60
61
  if (task.status === "blocked" && task.reason) line += ` — blocked: ${task.reason}`;
61
62
  if (task.status === "cancelled" && task.reason) line += ` — dropped: ${task.reason}`;
62
63
  lines.push(line);
63
- const outputs = userTasks.find((item) => item.id === task.userTaskId)?.acceptance?.expectedOutputs;
64
+ const operatorTask = userTasks.find((item) => item.id === task.userTaskId);
65
+ if (task.userTaskId) {
66
+ lines.push(
67
+ ` operator task ${task.userTaskId}: durable status=${operatorTask?.status ?? "unavailable"}; ` +
68
+ `session=${operatorTask?.handedSessionId ?? "unlinked"}; board task=${operatorTask?.boardTaskId ?? "unlinked"}`,
69
+ );
70
+ }
71
+ const outputs = operatorTask?.acceptance?.expectedOutputs;
64
72
  if (outputs?.length) lines.push(` expected outputs: ${outputs.join(", ")}`);
65
- for (const item of task.requiredValidationEvidence ?? [])
66
- lines.push(` acceptance: ${item.command} (${item.status}; ${item.notes})`);
73
+ for (const item of task.requiredValidationEvidence ?? []) {
74
+ if (item.status === "required") {
75
+ lines.push(
76
+ ` acceptance requirement: ${item.command} (${item.notes}; declaration only; execution status is in verification receipts)`,
77
+ );
78
+ } else {
79
+ lines.push(` acceptance: ${item.command} (${item.status}; ${item.notes})`);
80
+ }
81
+ }
67
82
  }
68
83
  if (counts.open > 0 && counts.active === 0) {
69
- lines.push(`next: start a task with action="start" before working it`);
84
+ lines.push(
85
+ `next: start only an authorized task with action="start" before working it; ` +
86
+ `block proposed implementation with a note naming the pending operator decision, or drop it, and wait`,
87
+ );
70
88
  }
71
89
  lines.push(...waitingTrailer(userTasks));
72
90
  return lines.join("\n");
@@ -145,7 +163,12 @@ export function createTasksTool(deps: TasksToolDeps): ToolSpec {
145
163
  "pick moves one operator task uN onto the board; start marks one task active (the current focus); " +
146
164
  "done completes a task (started or still pending) and requires note as the " +
147
165
  "evidence the work actually finished; block parks it with a required reason; drop cancels it; list shows the board. " +
148
- "Work that did not happen is blocked or dropped, never done.",
166
+ "For an operator handoff, pick the intended uN before work and use its returned linked tN; CLI hand alone does not pick it. " +
167
+ "Never pick unrelated inbox tasks. Before claiming operator completion, list and confirm the linked board row is completed " +
168
+ "and the durable operator status is done with the same session/board link; report those IDs and actual states. " +
169
+ "Work that did not happen is blocked or dropped, never done. A self-created plan is not operator authorization. " +
170
+ "For proposal-only work, block deferred implementation with note naming the pending operator decision, or drop it; " +
171
+ "wait for an explicit operator go-ahead before start or implementation. A skill-install choice does not grant that go-ahead.",
149
172
  parameters: Type.Object({
150
173
  action: StringEnum(TASKS_ACTIONS, { description: "Board action." }),
151
174
  title: Type.Optional(Type.String({ description: "Board title (plan)." })),
@@ -192,7 +215,10 @@ export function createTasksTool(deps: TasksToolDeps): ToolSpec {
192
215
  if (typedAction === "list") {
193
216
  const board = deps.board.snapshot();
194
217
  if (!board) {
195
- const output = ['no task board yet; declare one with action="plan"', ...waitingTrailer(userTasks)].join("\n");
218
+ const output = [
219
+ 'no task board yet; for an operator handoff, pick the intended uN before work; otherwise declare one with action="plan"',
220
+ ...waitingTrailer(userTasks),
221
+ ].join("\n");
196
222
  return {
197
223
  kind: "ok",
198
224
  output,
@@ -3,10 +3,12 @@ import { tmpdir } from "node:os";
3
3
  import path from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
5
  import { Script } from "node:vm";
6
+ import { prepareBoundedImage } from "../../core/file-references.js";
6
7
  import { combineSafeOutput, runCommandVector } from "../../core/safe-exec.js";
8
+ import type { ImageContent } from "../../engine/types.js";
7
9
  import { escapeRegExp } from "../ignore-policy.js";
8
10
  import { resolveReadPath } from "../path-utils.js";
9
- import type { ToolResult, ToolResultDetails } from "../registry.js";
11
+ import type { ToolInvokeOptions, ToolResult, ToolResultDetails } from "../registry.js";
10
12
  import { maxOutputArg, timeoutArg } from "../safe-exec.js";
11
13
  import { truncateUtf8 } from "../truncate-utf8.js";
12
14
  import { BROWSER_MODES } from "./surface.js";
@@ -25,6 +27,9 @@ interface FrontendCheck {
25
27
  }
26
28
 
27
29
  interface ValidationOptions {
30
+ supportsImages?: boolean;
31
+ imageMaxBytes?: number;
32
+ images?: ImageContent[];
28
33
  timeoutMs: number;
29
34
  maxOutputBytes: number;
30
35
  signal?: AbortSignal;
@@ -84,7 +89,7 @@ const JAVASCRIPT_TYPES = new Set([
84
89
  */
85
90
  export async function runFrontendCheck(
86
91
  args: Record<string, unknown>,
87
- options?: { signal?: AbortSignal },
92
+ options?: ToolInvokeOptions,
88
93
  ): Promise<ToolResult> {
89
94
  const pathArg = typeof args.path === "string" ? args.path.trim() : "";
90
95
  if (pathArg.length === 0) return { kind: "error", message: "verify: check=frontend requires a path argument" };
@@ -106,6 +111,9 @@ export async function runFrontendCheck(
106
111
  const validateOptions: ValidationOptions = {
107
112
  timeoutMs: timeoutArg(args),
108
113
  maxOutputBytes: maxOutputArg(args),
114
+ supportsImages: options?.supportsImages === true,
115
+ imageMaxBytes: Math.min(maxOutputArg(args), options?.toolResultMaxBytes ?? 50_000) - 4096,
116
+ images: [],
109
117
  };
110
118
  if (options?.signal !== undefined) validateOptions.signal = options.signal;
111
119
 
@@ -131,7 +139,7 @@ export async function runFrontendCheck(
131
139
  details,
132
140
  };
133
141
  }
134
- return { kind: "ok", output, details };
142
+ return { kind: "ok", output, details, ...(validateOptions.images?.length ? { images: validateOptions.images } : {}) };
135
143
  }
136
144
 
137
145
  async function validateArtifact(
@@ -550,38 +558,67 @@ async function validateBrowserLoad(
550
558
  });
551
559
  return;
552
560
  }
553
- const result = await runCommandVector(
554
- browser,
555
- [
556
- "--headless=new",
557
- "--disable-gpu",
558
- "--no-sandbox",
559
- "--disable-dev-shm-usage",
560
- "--dump-dom",
561
- pathToFileURL(artifactPath).href,
562
- ],
563
- {
564
- timeoutMs: options.timeoutMs,
565
- maxOutputBytes: options.maxOutputBytes,
566
- ...(options.signal !== undefined ? { signal: options.signal } : {}),
567
- },
568
- );
569
- if (result.exitCode === 0 && !result.timedOut && !result.aborted && !result.outputCapped) {
561
+ // A DOM dump duplicates the complete artifact on stdout. Large, otherwise
562
+ // valid pages then trip the diagnostic output cap. A private screenshot
563
+ // proves that the browser rendered without charging page bytes to that cap.
564
+ // Vision-capable routes retain bounded pixels before the scratch cleanup.
565
+ const dir = mkdtempSync(path.join(tmpdir(), "clio-coder-browser-check-"));
566
+ const screenshot = path.join(dir, "loaded.png");
567
+ try {
568
+ const result = await runCommandVector(
569
+ browser,
570
+ [
571
+ "--headless=new",
572
+ "--disable-gpu",
573
+ "--no-sandbox",
574
+ "--disable-dev-shm-usage",
575
+ `--user-data-dir=${path.join(dir, "profile")}`,
576
+ `--screenshot=${screenshot}`,
577
+ pathToFileURL(artifactPath).href,
578
+ ],
579
+ {
580
+ timeoutMs: options.timeoutMs,
581
+ maxOutputBytes: options.maxOutputBytes,
582
+ ...(options.signal !== undefined ? { signal: options.signal } : {}),
583
+ },
584
+ );
585
+ let failure: string;
586
+ if (result.aborted) failure = "headless browser aborted";
587
+ else if (result.timedOut) failure = `headless browser timed out after ${options.timeoutMs}ms`;
588
+ else if (result.outputCapped) failure = `headless browser output exceeded ${options.maxOutputBytes} bytes`;
589
+ else if (result.exitCode !== 0) {
590
+ failure = `headless browser exited with ${result.exitCode ?? result.signal ?? "unknown"}`;
591
+ } else if (!existsSync(screenshot) || !statSync(screenshot).isFile() || statSync(screenshot).size === 0) {
592
+ failure = "headless browser exited without a rendered screenshot";
593
+ } else {
594
+ if (options.supportsImages) {
595
+ const image = await prepareBoundedImage(readFileSync(screenshot), options.imageMaxBytes ?? 0);
596
+ if (image) options.images?.push(image);
597
+ else
598
+ checks.push({
599
+ name: "browser image",
600
+ status: "warn",
601
+ message: "Screenshot omitted: could not encode within the tool result byte cap.",
602
+ });
603
+ }
604
+ checks.push({
605
+ name: "browser load",
606
+ status: "pass",
607
+ message: `loaded and rendered with ${path.basename(browser)}`,
608
+ path: artifactPath,
609
+ });
610
+ return;
611
+ }
612
+ const output = truncateUtf8(combineSafeOutput(result).trim(), 800, " [truncated]");
570
613
  checks.push({
571
614
  name: "browser load",
572
- status: "pass",
573
- message: `loaded with ${path.basename(browser)}`,
615
+ status: "fail",
616
+ message: `${failure}${output ? `: ${output}` : ""}`,
574
617
  path: artifactPath,
575
618
  });
576
- return;
619
+ } finally {
620
+ rmSync(dir, { recursive: true, force: true });
577
621
  }
578
- const output = truncateUtf8(combineSafeOutput(result).trim(), 800, " [truncated]");
579
- checks.push({
580
- name: "browser load",
581
- status: "fail",
582
- message: `headless browser exited with ${result.exitCode ?? result.signal ?? "unknown"}${output ? `: ${output}` : ""}`,
583
- path: artifactPath,
584
- });
585
622
  }
586
623
 
587
624
  function parseAttributes(source: string): Record<string, string> {
@@ -133,15 +133,15 @@ export function parseNumericPayload(text: string, label: string): NumericPayload
133
133
  const keys = Object.keys(record);
134
134
  if (keys.length > NUMERIC_PAYLOAD_CAPS.keys)
135
135
  return new Error(`${label} exceeds the ${NUMERIC_PAYLOAD_CAPS.keys}-key cap`);
136
- const payload: NumericPayload = {};
136
+ const entries: Array<[string, number | number[]]> = [];
137
137
  let elements = 0;
138
138
  for (const key of keys) {
139
139
  const value = record[key];
140
140
  if (typeof value === "number") {
141
- payload[key] = value;
141
+ entries.push([key, value]);
142
142
  elements += 1;
143
143
  } else if (Array.isArray(value) && value.every((entry) => typeof entry === "number")) {
144
- payload[key] = [...(value as number[])];
144
+ entries.push([key, [...(value as number[])]]);
145
145
  elements += value.length;
146
146
  } else {
147
147
  return new Error(`${label}.${key} must be a number or an array of numbers`);
@@ -150,13 +150,18 @@ export function parseNumericPayload(text: string, label: string): NumericPayload
150
150
  return new Error(`${label} exceeds the ${NUMERIC_PAYLOAD_CAPS.elements}-element cap`);
151
151
  }
152
152
  }
153
- return payload;
153
+ return Object.fromEntries(entries);
154
154
  }
155
155
 
156
156
  function deviation(actual: number, expected: number, index?: number): NumericDeviation {
157
157
  const finite = Number.isFinite(actual) && Number.isFinite(expected);
158
158
  const absolute = finite ? Math.abs(actual - expected) : Number.POSITIVE_INFINITY;
159
- const relative = !finite ? null : expected === 0 ? (absolute === 0 ? 0 : null) : absolute / Math.abs(expected);
159
+ let relative = !finite ? null : expected === 0 ? (absolute === 0 ? 0 : null) : absolute / Math.abs(expected);
160
+ if (finite && !Number.isFinite(absolute)) {
161
+ // Finite subtraction overflows only across signs, where division first
162
+ // is safe. Keep subtraction first for nearby values to preserve precision.
163
+ relative = Math.abs(actual / expected - 1);
164
+ }
160
165
  return {
161
166
  ...(index !== undefined ? { index } : {}),
162
167
  actual,