@iowarp/clio-coder 0.4.8 → 0.4.9

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 (513) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/README.md +7 -6
  3. package/dist/{acp-JWPQZM2D.js → acp-ZWZCPS2A.js} +13 -13
  4. package/dist/{agents-4GCDIRVX.js → agents-LYSOWZUE.js} +53 -52
  5. package/dist/assets/codewiki.json +1 -1
  6. package/dist/{auth-SYAKTDQE.js → auth-WBQGKWQ5.js} +27 -27
  7. package/dist/{background-OW67WMYR.js → background-BUMOBAQN.js} +4 -4
  8. package/dist/{builtins-TKS63VNV.js → builtins-ODRJOEDI.js} +7 -7
  9. package/dist/{chunk-JLBVCROW.js → chunk-2DRRZ57Q.js} +33 -24
  10. package/dist/chunk-2JBZYUPY.js +105 -0
  11. package/dist/chunk-2KUBKL63.js +336 -0
  12. package/dist/{chunk-K45LHSCI.js → chunk-2VBWFXYE.js} +7 -3
  13. package/dist/{chunk-XTLJDC2X.js → chunk-2X2R3UTH.js} +23 -18
  14. package/dist/{chunk-5HULHKT2.js → chunk-37LW32LZ.js} +5 -5
  15. package/dist/{chunk-W7KNI3F5.js → chunk-3AND2EFU.js} +5 -5
  16. package/dist/{chunk-36XSBPXL.js → chunk-3RDHGNU7.js} +95 -27
  17. package/dist/{chunk-BIY22UUK.js → chunk-3SUDBGEI.js} +11 -10
  18. package/dist/{chunk-3IQOZRQ6.js → chunk-3TQN67I2.js} +7 -7
  19. package/dist/{chunk-KWJXCL2X.js → chunk-3U4BL2EV.js} +3 -3
  20. package/dist/{chunk-RBES4TCZ.js → chunk-3UQADNG2.js} +3 -3
  21. package/dist/{chunk-V4ZKOKRB.js → chunk-434LRQ6Z.js} +61 -53
  22. package/dist/{chunk-MWMW53WW.js → chunk-4ATBOFRP.js} +649 -193
  23. package/dist/{chunk-QGIC5SX5.js → chunk-4DNL43EZ.js} +3 -3
  24. package/dist/{chunk-GVU4CXPJ.js → chunk-4HFJKRGZ.js} +113 -54
  25. package/dist/{chunk-5A6XR3RJ.js → chunk-555E2WVV.js} +16 -2
  26. package/dist/{chunk-LZDLYSUN.js → chunk-5RTEFNBP.js} +3 -3
  27. package/dist/{chunk-HMGAKB7E.js → chunk-64XJW7NT.js} +15 -15
  28. package/dist/{chunk-EXKUF426.js → chunk-7FBCRWVT.js} +280 -280
  29. package/dist/{chunk-K3W6BF5C.js → chunk-7JSOSVLP.js} +2 -2
  30. package/dist/{chunk-WFTSK7N3.js → chunk-7N3OLLSL.js} +4 -4
  31. package/dist/{chunk-JRA6OBHY.js → chunk-A6DULIMH.js} +17 -5
  32. package/dist/{chunk-R5NRX5N4.js → chunk-AB3QXXBC.js} +2 -2
  33. package/dist/chunk-ACCECAH4.js +49 -0
  34. package/dist/{chunk-GJBJHJNY.js → chunk-AM6CEP2K.js} +5 -5
  35. package/dist/{chunk-MUXNDNMZ.js → chunk-AY4XE6GN.js} +19 -13
  36. package/dist/{chunk-MATCRH3M.js → chunk-BBA2TAWV.js} +9 -9
  37. package/dist/{chunk-PMUUAABD.js → chunk-BMNVVKEW.js} +9 -9
  38. package/dist/{chunk-TOPICHGR.js → chunk-CTGZCEI6.js} +2 -2
  39. package/dist/{chunk-L75H5B3B.js → chunk-DIAJYJYG.js} +2 -2
  40. package/dist/{chunk-JIMWEYWO.js → chunk-EHZRAB4U.js} +2 -2
  41. package/dist/{chunk-YXANQGCX.js → chunk-EM2DIQAJ.js} +6 -6
  42. package/dist/{chunk-JCVIL6TY.js → chunk-ETF4ROKH.js} +4 -4
  43. package/dist/{chunk-5W4FRA5Q.js → chunk-F2YM3JY4.js} +483 -253
  44. package/dist/{chunk-YGIV24MF.js → chunk-FEBQWHJT.js} +21 -16
  45. package/dist/{chunk-PGEFOTJB.js → chunk-FPS4R2RN.js} +5 -4
  46. package/dist/{chunk-XC5POIL4.js → chunk-G5R53COU.js} +1 -1
  47. package/dist/chunk-GHXGMFQ5.js +40 -0
  48. package/dist/{chunk-QLKCCC2J.js → chunk-GJDRMBDI.js} +14 -14
  49. package/dist/{chunk-2ZWLMA3T.js → chunk-GREYLTZ5.js} +7 -7
  50. package/dist/{chunk-YXFKLMX2.js → chunk-H2WSCZZT.js} +22 -6
  51. package/dist/{chunk-FNVPQQYT.js → chunk-H6IUCY6Q.js} +2 -2
  52. package/dist/{chunk-5C2OQHLR.js → chunk-H72DCH3E.js} +92 -203
  53. package/dist/{chunk-JYKUMHCQ.js → chunk-H7TXJR23.js} +21 -21
  54. package/dist/chunk-HBJQQTKM.js +40 -0
  55. package/dist/chunk-HCVKSGNZ.js +990 -0
  56. package/dist/{chunk-ARRUMZ7X.js → chunk-I47EJPYL.js} +3 -3
  57. package/dist/{chunk-YKIIWURD.js → chunk-IALGWTLO.js} +3 -3
  58. package/dist/{chunk-FB3KTE2J.js → chunk-IALZJE37.js} +4 -4
  59. package/dist/{chunk-RAUOKUZV.js → chunk-IC7JXLOM.js} +15 -10
  60. package/dist/{chunk-LLCGGVSW.js → chunk-IOSVTTCD.js} +7 -7
  61. package/dist/{chunk-DBREN25X.js → chunk-IPTPMLA6.js} +8 -3
  62. package/dist/{chunk-V552WL53.js → chunk-IZZI3SKQ.js} +3 -67
  63. package/dist/{chunk-UDAK6GR2.js → chunk-JIYWMQZ5.js} +2 -2
  64. package/dist/{chunk-O3HSB2YL.js → chunk-JKU34ACI.js} +2 -2
  65. package/dist/{chunk-6X7VOCDY.js → chunk-JTR3VSV3.js} +3 -3
  66. package/dist/{chunk-O2QJDRWP.js → chunk-JU6MAMRJ.js} +4 -4
  67. package/dist/chunk-JURMQWVJ.js +15 -0
  68. package/dist/{chunk-STC6CWUZ.js → chunk-K3XN4LZ4.js} +5 -5
  69. package/dist/{chunk-ATB3Q7YO.js → chunk-KIVFXGBM.js} +27 -2
  70. package/dist/{chunk-WJWNZXRM.js → chunk-KOAHT3N2.js} +2 -2
  71. package/dist/chunk-KP5BPXR3.js +73 -0
  72. package/dist/{chunk-K53E2PTW.js → chunk-KRJQG47M.js} +3 -3
  73. package/dist/{chunk-IILXVWJY.js → chunk-KW6OJ7IY.js} +19 -21
  74. package/dist/{chunk-A46ILRS2.js → chunk-L3NBWLSN.js} +4 -4
  75. package/dist/{chunk-2U2U5POA.js → chunk-L4RUTLRL.js} +5 -5
  76. package/dist/{chunk-QYSAZMSH.js → chunk-LGTVWPRN.js} +2 -2
  77. package/dist/{chunk-KGP3UQGJ.js → chunk-LSQW6KZO.js} +5 -5
  78. package/dist/{chunk-P4JS3MH5.js → chunk-LWJYOHT3.js} +8 -8
  79. package/dist/{chunk-U3TPUXOQ.js → chunk-M6YLF66Z.js} +74 -40
  80. package/dist/{chunk-5D2FNBMG.js → chunk-MJ4QEJVT.js} +2 -2
  81. package/dist/{chunk-RM3XJX7P.js → chunk-MO65K5CH.js} +5 -5
  82. package/dist/{chunk-H5DPSUBB.js → chunk-MTOZEQHL.js} +3 -3
  83. package/dist/{chunk-6R5MBXBJ.js → chunk-NBPA5QM6.js} +2 -2
  84. package/dist/{chunk-H77XBUBM.js → chunk-NMBEW4PP.js} +3 -3
  85. package/dist/{chunk-QWUSS2QP.js → chunk-NPLLK3HO.js} +67 -87
  86. package/dist/{chunk-K5UJD6MM.js → chunk-NSYGPIVW.js} +5 -5
  87. package/dist/{context-EZZPT2ZV.js → chunk-NXTV5OI5.js} +30 -84
  88. package/dist/{chunk-F7Y6QTPL.js → chunk-NYDG4QP4.js} +4 -4
  89. package/dist/{chunk-PFZJMXIY.js → chunk-OA2GDACN.js} +2 -2
  90. package/dist/{chunk-Q32C6AWI.js → chunk-PJI57EC6.js} +4 -4
  91. package/dist/{chunk-EFXMQYI6.js → chunk-PJJBUGMR.js} +52 -52
  92. package/dist/{chunk-ICYIUNO4.js → chunk-PNJE7JPS.js} +18 -3
  93. package/dist/chunk-PP23PZEV.js +1347 -0
  94. package/dist/chunk-PPIFDSBK.js +409 -0
  95. package/dist/{chunk-RFULVPBX.js → chunk-PTFISXQO.js} +6 -5
  96. package/dist/{chunk-JV25I7ID.js → chunk-QB33Z5S7.js} +5 -5
  97. package/dist/{chunk-D55WO5J7.js → chunk-QGNII5VC.js} +8 -8
  98. package/dist/{chunk-RKFNU5UA.js → chunk-QI72X67S.js} +104 -27
  99. package/dist/chunk-QKHZZFKH.js +98 -0
  100. package/dist/{chunk-5UG6EZI3.js → chunk-RDKX2PME.js} +4 -4
  101. package/dist/{chunk-B5ZTR6KZ.js → chunk-RL7LJYN4.js} +1 -1
  102. package/dist/{chunk-BE4I3UJ2.js → chunk-RQROVOV3.js} +15 -13
  103. package/dist/{chunk-TEHVMHOK.js → chunk-S34A7BSP.js} +3 -3
  104. package/dist/{chunk-4P6M2TTE.js → chunk-SJETVJHX.js} +2 -2
  105. package/dist/{chunk-OPC4DQD6.js → chunk-SJMNU4ZS.js} +2 -2
  106. package/dist/{chunk-2JSCCEKO.js → chunk-SLLG2G44.js} +2 -2
  107. package/dist/{chunk-EPYATQMG.js → chunk-SQAZN2V3.js} +42 -16
  108. package/dist/{chunk-E2NSPYLC.js → chunk-SQBT46OF.js} +5 -5
  109. package/dist/{chunk-WTZVSMQZ.js → chunk-TCUOGIL2.js} +5 -5
  110. package/dist/{chunk-RRZFRIJP.js → chunk-TIWPKCVO.js} +5 -5
  111. package/dist/{chunk-QLAGXTTV.js → chunk-UIU7MGZ3.js} +5 -1
  112. package/dist/{chunk-WLHX3MM5.js → chunk-V4XJWDHR.js} +21 -11
  113. package/dist/{chunk-PJ5H5B7A.js → chunk-VPWGADBG.js} +18 -18
  114. package/dist/{chunk-GEYX2NZ5.js → chunk-VWFCAK34.js} +6 -6
  115. package/dist/{chunk-44U2OUSM.js → chunk-W72LLZAV.js} +2 -2
  116. package/dist/{chunk-ORRNGQDV.js → chunk-WGRDABW7.js} +4 -4
  117. package/dist/{chunk-RNLAPBJL.js → chunk-XFLSL7BT.js} +2 -2
  118. package/dist/{chunk-2SXGG2IV.js → chunk-XJZEDCNT.js} +6 -6
  119. package/dist/{chunk-UB33F3YW.js → chunk-XLLEL3K7.js} +5 -5
  120. package/dist/{chunk-2GPGAE5W.js → chunk-XNIZBOFV.js} +15 -1
  121. package/dist/{chunk-WS4FOGLY.js → chunk-XNZWWDC3.js} +2 -2
  122. package/dist/{chunk-P7GTE4FX.js → chunk-XRECG65F.js} +2 -2
  123. package/dist/chunk-XTQ7MEJG.js +457 -0
  124. package/dist/{chunk-GEVQNST4.js → chunk-XZWSP67B.js} +2 -2
  125. package/dist/{chunk-OEMFEL26.js → chunk-Y3M2T5RO.js} +3 -3
  126. package/dist/{chunk-HP7KJ5O2.js → chunk-YPQOPFP7.js} +6 -6
  127. package/dist/{chunk-MEHBW2SP.js → chunk-YQYINEJI.js} +6 -6
  128. package/dist/{chunk-RXI7K4J5.js → chunk-ZF6CV4WZ.js} +1338 -217
  129. package/dist/{chunk-3XE4NRLF.js → chunk-ZKJU55MX.js} +4 -2
  130. package/dist/{chunk-526ABLHD.js → chunk-ZKQ63XZ5.js} +12 -35
  131. package/dist/{chunk-PAQVETLA.js → chunk-ZKVMDNAN.js} +5 -5
  132. package/dist/cli/index.js +47 -37
  133. package/dist/{clio-BPBAPZGA.js → clio-JUDCLNHC.js} +7 -7
  134. package/dist/clio-context-tools-FT672MNZ.js +136 -0
  135. package/dist/{code-nav-KBQ3RIFK.js → code-nav-7OVCTP2Z.js} +28 -26
  136. package/dist/{components-6DKAXWFN.js → components-OZXZMDWU.js} +5 -5
  137. package/dist/{config-FWL5JK2H.js → config-P3ZQVF63.js} +80 -75
  138. package/dist/{config-graph-ACDB26L2.js → config-graph-GKAOBAS5.js} +74 -70
  139. package/dist/{configure-ZIZ4YV62.js → configure-25LRYZJG.js} +45 -44
  140. package/dist/context-72VQV7JX.js +73 -0
  141. package/dist/{context-VIL5MFRH.js → context-COWRWXP3.js} +74 -70
  142. package/dist/{context-Z3GOBHDK.js → context-WB3D474G.js} +12 -12
  143. package/dist/{context-clear-ZPB3L7MN.js → context-clear-Y4LYMWC6.js} +70 -66
  144. package/dist/{context-working-set-2GLBVF7L.js → context-working-set-TMZYVC7A.js} +15 -14
  145. package/dist/data-tool-KMBWKKWR.js +2987 -0
  146. package/dist/{detail-VSBWYSGZ.js → detail-4GLROGY5.js} +71 -67
  147. package/dist/{dispatch-runner-EEEHGKX4.js → dispatch-runner-TR3LBP5P.js} +92 -88
  148. package/dist/{docs-VMMWFVHL.js → docs-ZK777W2G.js} +3 -3
  149. package/dist/{doctor-V5L4IQGP.js → doctor-WC4OV2OB.js} +61 -59
  150. package/dist/{eval-VJYJ2BV3.js → eval-FUNWJNUJ.js} +45 -45
  151. package/dist/{evals-J2H5V6DD.js → evals-L73EBHSU.js} +4 -4
  152. package/dist/{evidence-Y35YSXH6.js → evidence-AVJ2RTHX.js} +80 -76
  153. package/dist/{evidence-POWAEBEW.js → evidence-P4NZOAK7.js} +70 -66
  154. package/dist/{evidence-XCCCLS36.js → evidence-Y55WKYHH.js} +79 -75
  155. package/dist/{evolve-GPG72VB6.js → evolve-MAWKRYWF.js} +75 -71
  156. package/dist/{extensions-YIZ7W3DA.js → extensions-PYQH3H47.js} +8 -8
  157. package/dist/{fleet-2MDCQ2VK.js → fleet-M4H2QBWT.js} +84 -80
  158. package/dist/{fleet-W2AF3TOJ.js → fleet-ULBXXRDR.js} +123 -119
  159. package/dist/{fleet-commands-WS56G26H.js → fleet-commands-7NNC4JZU.js} +17 -16
  160. package/dist/{fleet-decisions-MYGZ3JW7.js → fleet-decisions-EHEY7KPU.js} +9 -9
  161. package/dist/{fleet-graph-ELTBXBAV.js → fleet-graph-LQ2AHZT3.js} +15 -15
  162. package/dist/{fleet-inspect-45IK73L4.js → fleet-inspect-5IGBIIYZ.js} +76 -72
  163. package/dist/{fleet-preflight-T5NCZKHE.js → fleet-preflight-UTTNOKMG.js} +7 -2
  164. package/dist/{fleet-validate-VG4JBLA4.js → fleet-validate-YGILJKA6.js} +20 -20
  165. package/dist/{fleet-verify-VTSABAYO.js → fleet-verify-AUWTCDKR.js} +70 -66
  166. package/dist/{fleet-view-XC7WMKSS.js → fleet-view-TGUFCY5A.js} +73 -69
  167. package/dist/{init-VTJNNTIP.js → init-GFN2Z7NF.js} +94 -90
  168. package/dist/{interop-IU6BNA7C.js → interop-EF5JUWWK.js} +21 -21
  169. package/dist/{inventory-QPQUTUUZ.js → inventory-I6VJDDYF.js} +73 -69
  170. package/dist/{library-Q3NWL5CM.js → library-3J5IO2OJ.js} +13 -13
  171. package/dist/{library-LF7DLU6S.js → library-IJTOFTDS.js} +16 -15
  172. package/dist/{library-HUTAS57T.js → library-Z3KZSHPE.js} +27 -27
  173. package/dist/{library-import-PPW4YUC5.js → library-import-IMKFLDHX.js} +21 -21
  174. package/dist/{library-inventory-DIRVFRZU.js → library-inventory-CQP5D6GU.js} +13 -13
  175. package/dist/{library-validation-XHUZ3INE.js → library-validation-33UTX7AI.js} +11 -11
  176. package/dist/mcp-5FWZKUS6.js +26 -0
  177. package/dist/{memory-Z2LSKNV6.js → memory-36CWN67Y.js} +75 -71
  178. package/dist/{models-3FTREYPY.js → models-KQ6PQJJQ.js} +49 -49
  179. package/dist/{monitor-HF2MQRB3.js → monitor-XX6ZD6KC.js} +83 -79
  180. package/dist/{orchestrator-UYPA6W4S.js → orchestrator-SK6HDAOP.js} +1337 -772
  181. package/dist/{panes-736XB73K.js → panes-L27QRXUH.js} +12 -12
  182. package/dist/{panes-C4P3PIWT.js → panes-LXZIWNOZ.js} +4 -4
  183. package/dist/{paths-JQ4QYIYB.js → paths-7DJDU4P4.js} +5 -5
  184. package/dist/{preload-XSLRYH3Y.js → preload-K2TDYI4Y.js} +70 -66
  185. package/dist/{reset-V7QSPZYE.js → reset-73VU3XNT.js} +10 -10
  186. package/dist/{resources-OJGDFHYT.js → resources-3BYJYVYL.js} +16 -16
  187. package/dist/{run-T354SMDW.js → run-AR7PY6GW.js} +132 -128
  188. package/dist/run-script-H2KUDIII.js +41 -0
  189. package/dist/{settings-MWZXO6RV.js → settings-3VMBMWID.js} +4 -4
  190. package/dist/{share-Y5ZKJPND.js → share-HVWH4FPF.js} +21 -21
  191. package/dist/{skills-4GLZC4LN.js → skills-5TYEY75Q.js} +22 -22
  192. package/dist/{skills-eval-L5T7GODM.js → skills-eval-CK3MD63Z.js} +96 -87
  193. package/dist/{skills-inventory-LASKXEZI.js → skills-inventory-KSFYG3I6.js} +16 -16
  194. package/dist/{slash-commands-OIMRU36D.js → slash-commands-DMVHML7P.js} +47 -44
  195. package/dist/{steer-KMAM2Y2C.js → steer-XCD6V3EW.js} +4 -4
  196. package/dist/{support-AWC3XKPX.js → support-JAZL6VBR.js} +7 -7
  197. package/dist/{system-CD75NYBU.js → system-3TDQRMZZ.js} +26 -26
  198. package/dist/{targets-VSZX2J2S.js → targets-EZKHAYRN.js} +66 -65
  199. package/dist/{tasks-AN567LYH.js → tasks-SNEFHWYW.js} +12 -12
  200. package/dist/{terminal-lease-6KTWNHVY.js → terminal-lease-BNLFA4OF.js} +8 -7
  201. package/dist/{tools-AGRK3V5J.js → tools-7IM6BDCE.js} +12 -12
  202. package/dist/{trace-P4MQZD33.js → trace-C3MBGD4S.js} +8 -8
  203. package/dist/{tui-primitives-A6MUW32V.js → tui-primitives-36BY2774.js} +2 -2
  204. package/dist/{uninstall-BRUTEPIC.js → uninstall-WWLOSZ42.js} +10 -10
  205. package/dist/{upgrade-SBCGHQGJ.js → upgrade-ETK2JNSJ.js} +37 -47
  206. package/dist/{usage-BIDVTO6V.js → usage-S2HOB7BZ.js} +93 -89
  207. package/dist/{verifiers-LTGCAMXS.js → verifiers-QDTEVH7R.js} +24 -22
  208. package/dist/{verify-OZU4LLNP.js → verify-SUKUK6XM.js} +15 -14
  209. package/dist/web/client/assets/{abnfDiagram-VCTEODGH-C5wfoHm3.js → abnfDiagram-VCTEODGH-BznNOe_I.js} +1 -1
  210. package/dist/web/client/assets/{arc-oH91sfLl.js → arc-Pry-7G1_.js} +1 -1
  211. package/dist/web/client/assets/architecture-7GRP2DOG-BQO9DL_y.js +1 -0
  212. package/dist/web/client/assets/architectureDiagram-5GKGNRK7-CKPbdvyx.js +36 -0
  213. package/dist/web/client/assets/{blockDiagram-I7D4REHJ-wi0_CYHL.js → blockDiagram-I7D4REHJ-prINbpbM.js} +1 -1
  214. package/dist/web/client/assets/{c4Diagram-7LVT6UL2-DV7NYc2W.js → c4Diagram-7LVT6UL2-DkVRKtyU.js} +1 -1
  215. package/dist/web/client/assets/channel-c4EeUUqA.js +1 -0
  216. package/dist/web/client/assets/{chunk-4HAMMTFA-Bhsegh3F.js → chunk-4HAMMTFA-CV0Z1ApC.js} +1 -1
  217. package/dist/web/client/assets/{chunk-75Z2AOVW-RQCckcQG.js → chunk-75Z2AOVW-D34Nohxq.js} +1 -1
  218. package/dist/web/client/assets/chunk-DU6HZSFF-Das_cS-O.js +125 -0
  219. package/dist/web/client/assets/{chunk-F27PBJKO-BcNqv2x1.js → chunk-F27PBJKO-CmRojxkG.js} +1 -1
  220. package/dist/web/client/assets/{chunk-GMAD6QVW-Bq8JWiZT.js → chunk-GMAD6QVW-ClYZmc73.js} +1 -1
  221. package/dist/web/client/assets/{chunk-GVQU2GXP-DbchrAeJ.js → chunk-GVQU2GXP-B2BiHFt-.js} +1 -1
  222. package/dist/web/client/assets/{chunk-IMKFNOWR-DrpvjocK.js → chunk-IMKFNOWR-BGApZ8nP.js} +1 -1
  223. package/dist/web/client/assets/{chunk-L3NEJ4N5-DHLmTnCe.js → chunk-L3NEJ4N5-DIzCgpkY.js} +1 -1
  224. package/dist/web/client/assets/{chunk-OSK3NFVY-CsRbtN9n.js → chunk-OSK3NFVY-BPT-yePv.js} +1 -1
  225. package/dist/web/client/assets/{chunk-P2QGCYS3-aqPbxoMh.js → chunk-P2QGCYS3-BC1WTc2t.js} +1 -1
  226. package/dist/web/client/assets/{chunk-POPQ4Y6H-Dl5vw0h0.js → chunk-POPQ4Y6H-BSjzBmZU.js} +1 -1
  227. package/dist/web/client/assets/{chunk-PWAF6VOD-D7OBRSdO.js → chunk-PWAF6VOD-BIjLs86Z.js} +1 -1
  228. package/dist/web/client/assets/{chunk-SHT3W25Y-CdKCIwuB.js → chunk-SHT3W25Y-CduDz2cm.js} +1 -1
  229. package/dist/web/client/assets/{chunk-SVP7TREG-B94Nu_1-.js → chunk-SVP7TREG-XUn4pPAP.js} +1 -1
  230. package/dist/web/client/assets/{chunk-TICWLB2K-jjRQI_hk.js → chunk-TICWLB2K-DcBy2DKy.js} +1 -1
  231. package/dist/web/client/assets/{chunk-XXDRQBXY-azkbKE37.js → chunk-XXDRQBXY-DqAYeljN.js} +1 -1
  232. package/dist/web/client/assets/classDiagram-ZZMXUADV-C0HR7YKN.js +1 -0
  233. package/dist/web/client/assets/classDiagram-v2-VYDZK3BY-C0HR7YKN.js +1 -0
  234. package/dist/web/client/assets/cose-bilkent-JH36ORCC-CVh1icwb.js +1 -0
  235. package/dist/web/client/assets/{cynefin-OW5HDTMX--i9RDU5f.js → cynefin-OW5HDTMX-BecPbyM6.js} +1 -1
  236. package/dist/web/client/assets/{cynefinDiagram-5FMLGOSQ-cRcvyBdp.js → cynefinDiagram-5FMLGOSQ-BzMzFwyT.js} +1 -1
  237. package/dist/web/client/assets/{dagre-GXQ25YYZ-C9mZmAPe.js → dagre-GXQ25YYZ-CAWJmRMG.js} +1 -1
  238. package/dist/web/client/assets/{diagram-S7CK7UJ4-Oj_zlLDY.js → diagram-S7CK7UJ4--lp0ALmn.js} +1 -1
  239. package/dist/web/client/assets/{diagram-UQ7AKVKN-BWKbbfcR.js → diagram-UQ7AKVKN-gKUnsjcj.js} +1 -1
  240. package/dist/web/client/assets/{diagram-VSXAHHWV-C3N3f7DO.js → diagram-VSXAHHWV-BoN5D1Gh.js} +1 -1
  241. package/dist/web/client/assets/{diagram-VX7I27RA-CtDKDAWe.js → diagram-VX7I27RA-BMtuswQ6.js} +1 -1
  242. package/dist/web/client/assets/{diagram-Z3DM3KII-B8bkBRCz.js → diagram-Z3DM3KII-DtU8LXrA.js} +1 -1
  243. package/dist/web/client/assets/dist-v5Q1xZ2K.js +1 -0
  244. package/dist/web/client/assets/{ebnfDiagram-PWID7BFC-CskW-Whx.js → ebnfDiagram-PWID7BFC-DDcnv9BH.js} +1 -1
  245. package/dist/web/client/assets/{erDiagram-RLTQ6QDP-C-83cgCW.js → erDiagram-RLTQ6QDP-DvRb4iDL.js} +1 -1
  246. package/dist/web/client/assets/eventmodeling-NTZA5JFV-01h4SbTc.js +1 -0
  247. package/dist/web/client/assets/flowDiagram-HODETNUW-Bll_YZ6T.js +1 -0
  248. package/dist/web/client/assets/framework-YGoR34M4.js +9 -0
  249. package/dist/web/client/assets/ganttDiagram-EL5Y4UJY-DdFZ9hvH.js +292 -0
  250. package/dist/web/client/assets/{gitGraph-4MIJSDKK-B40cQtBE.js → gitGraph-4MIJSDKK-DjD_AAMj.js} +1 -1
  251. package/dist/web/client/assets/{gitGraphDiagram-WWUBYQGX-CH-7P7Di.js → gitGraphDiagram-WWUBYQGX-CDyN9n2u.js} +1 -1
  252. package/dist/web/client/assets/index-CVcy0FAn.js +75 -0
  253. package/dist/web/client/assets/{info-A6RAGUB7-eCCE9D_Q.js → info-A6RAGUB7-C_XK8Hq0.js} +1 -1
  254. package/dist/web/client/assets/{infoDiagram-27XIBGKW-DRnvqMjM.js → infoDiagram-27XIBGKW-DIe4tJ1i.js} +1 -1
  255. package/dist/web/client/assets/{ishikawaDiagram-5VMMS53U-DBA_55wp.js → ishikawaDiagram-5VMMS53U-CVl5unKI.js} +1 -1
  256. package/dist/web/client/assets/{journeyDiagram-3NMN7TZE-C-ewpNl7.js → journeyDiagram-3NMN7TZE-CPEB1Vt8.js} +1 -1
  257. package/dist/web/client/assets/{kanban-definition-UXKFOSKX-B1taGsu0.js → kanban-definition-UXKFOSKX-j-9WXjYQ.js} +1 -1
  258. package/dist/web/client/assets/{line-lZ0kyxDI.js → line-BIDAcEtX.js} +1 -1
  259. package/dist/web/client/assets/{linear-DIc8FgZj.js → linear-SzVmGSw4.js} +1 -1
  260. package/dist/web/client/assets/{mermaid-parser.core-SXolxpXw.js → mermaid-parser.core-Ux4vssh0.js} +3 -3
  261. package/dist/web/client/assets/{mermaid.core-DXgQtkNg.js → mermaid.core-CDuwVKeh.js} +4 -4
  262. package/dist/web/client/assets/{mindmap-definition-YA3MSWOX-DXJas9K7.js → mindmap-definition-YA3MSWOX-5MlQEeQ6.js} +1 -1
  263. package/dist/web/client/assets/{packet-AYTQ26CC-OqVl_07o.js → packet-AYTQ26CC-DRO66c9Q.js} +1 -1
  264. package/dist/web/client/assets/{pegDiagram-XKGWAZYB-CPE_zdfN.js → pegDiagram-XKGWAZYB-BakZnSjM.js} +1 -1
  265. package/dist/web/client/assets/{pie-WAS4IAKB-DAxnMBLe.js → pie-WAS4IAKB-BEzcmhz8.js} +1 -1
  266. package/dist/web/client/assets/{pieDiagram-E7YTZNPT-Uwjpufxv.js → pieDiagram-E7YTZNPT-DpmqgoPt.js} +1 -1
  267. package/dist/web/client/assets/prism-core-BtsZdCS6.js +1 -0
  268. package/dist/web/client/assets/{quadrantDiagram-AXDQQJYC-Bjs4yjgs.js → quadrantDiagram-AXDQQJYC-DuMPwwV2.js} +1 -1
  269. package/dist/web/client/assets/{radar-RG4KPBEZ-CuCKjHM3.js → radar-RG4KPBEZ-Djm3oXl5.js} +1 -1
  270. package/dist/web/client/assets/{railroad-74A4TZTK-CnQK-Cc1.js → railroad-74A4TZTK-Cpvkwsao.js} +1 -1
  271. package/dist/web/client/assets/railroad-abnf-HS5TGJTU-CpRQ3ruG.js +1 -0
  272. package/dist/web/client/assets/railroad-ebnf-LZEXJU2U-1Rm5a5eJ.js +1 -0
  273. package/dist/web/client/assets/railroad-peg-WCYAUIDC-C8344cTh.js +1 -0
  274. package/dist/web/client/assets/{railroadDiagram-O6MQD6OU-BDDIPNLL.js → railroadDiagram-O6MQD6OU-CgMS4B6R.js} +1 -1
  275. package/dist/web/client/assets/{requirementDiagram-BXWQKSXE-B5Ydyxc1.js → requirementDiagram-BXWQKSXE-CX5eoNdN.js} +1 -1
  276. package/dist/web/client/assets/rolldown-runtime-hePW80VL.js +1 -0
  277. package/dist/web/client/assets/{sankeyDiagram-P5KCCOFB-Bw2Qym75.js → sankeyDiagram-P5KCCOFB-CODBX2N3.js} +1 -1
  278. package/dist/web/client/assets/{sequenceDiagram-WJ2MYXX4-BZf36nO0.js → sequenceDiagram-WJ2MYXX4-eUhhF8OR.js} +1 -1
  279. package/dist/web/client/assets/src-B6xuSHsQ.js +1 -0
  280. package/dist/web/client/assets/{stateDiagram-D77RDMKH-DnH6JRkp.js → stateDiagram-D77RDMKH-vR6l0NC2.js} +1 -1
  281. package/dist/web/client/assets/stateDiagram-v2-MP3YSRHH-BYUm8jLY.js +1 -0
  282. package/dist/web/client/assets/{swimlanes-42K2YHIH-D9PZmtZg.js → swimlanes-42K2YHIH-v9Tw_zX7.js} +1 -1
  283. package/dist/web/client/assets/swimlanesDiagram-VR7AAH4N-B2jdCvhD.js +8 -0
  284. package/dist/web/client/assets/{timeline-definition-24CTP7MA-CrkZZBo7.js → timeline-definition-24CTP7MA-DxianbhU.js} +1 -1
  285. package/dist/web/client/assets/{treeView-Q6P3EWNA-C9zDShoC.js → treeView-Q6P3EWNA-DLxnZb9R.js} +1 -1
  286. package/dist/web/client/assets/{treemap-WGGIJYW6-B-plj9yK.js → treemap-WGGIJYW6-I7UnZ6xJ.js} +1 -1
  287. package/dist/web/client/assets/{vennDiagram-4TSXK5OY-VeOdaphN.js → vennDiagram-4TSXK5OY-Ar7M8Mrj.js} +1 -1
  288. package/dist/web/client/assets/{wardley-WFR3VGLG-Wl1P_m6L.js → wardley-WFR3VGLG-B8ZSHeDu.js} +1 -1
  289. package/dist/web/client/assets/{wardleyDiagram-VM6X3IG4-B85-R9t2.js → wardleyDiagram-VM6X3IG4-Qks2FmIn.js} +1 -1
  290. package/dist/web/client/assets/{xychartDiagram-S5SC5T6Z-BrD8OW8m.js → xychartDiagram-S5SC5T6Z-BBBjRtiE.js} +1 -1
  291. package/dist/web/client/index.html +3 -1
  292. package/dist/web/reads-worker.js +17 -17
  293. package/dist/web/server.js +25 -25
  294. package/dist/{web-EU6ATJWA.js → web-EMGUGGEI.js} +3 -3
  295. package/dist/{web-fetch-U22Q7HV4.js → web-fetch-6BRRVQON.js} +22 -5
  296. package/dist/{wiki-generate-LZRLFG6I.js → wiki-generate-XHSJTDOP.js} +104 -100
  297. package/dist/{with-panes-X5CZOGML.js → with-panes-Z6BTEHMZ.js} +11 -11
  298. package/dist/worker/entry.js +101 -87
  299. package/docs/README.md +1 -1
  300. package/docs/architecture/artifact-placement.md +12 -1
  301. package/docs/architecture/library.md +1 -1
  302. package/docs/architecture/prompt-envelope-and-tools.md +37 -27
  303. package/docs/architecture/safety-model.md +19 -6
  304. package/docs/architecture/session-lifecycle.md +10 -4
  305. package/docs/architecture/tui-design.md +37 -14
  306. package/docs/guide/commands-and-modes.md +39 -19
  307. package/docs/guide/configuration-and-targets.md +7 -5
  308. package/docs/guide/configuration-reference.md +116 -13
  309. package/docs/guide/environment-variables.md +2 -5
  310. package/docs/guide/fleet-dispatch.md +3 -2
  311. package/docs/guide/glossary.md +1 -1
  312. package/docs/guide/installation-and-lifecycle.md +2 -2
  313. package/docs/guide/resource-library.md +1 -1
  314. package/docs/guide/tool-usage.md +166 -64
  315. package/docs/guide/troubleshooting.md +1 -1
  316. package/docs/process/documentation-guide.md +1 -0
  317. package/docs/process/fleet-demo-runbook.md +6 -6
  318. package/docs/process/scientific-validation.md +22 -2
  319. package/docs/process/tool-audit-v0.4.9.md +357 -0
  320. package/package.json +1 -1
  321. package/src/cli/argv.ts +31 -0
  322. package/src/cli/clio.ts +17 -13
  323. package/src/cli/config.ts +4 -0
  324. package/src/cli/doctor-panes.ts +1 -1
  325. package/src/cli/doctor.ts +3 -1
  326. package/src/cli/index.ts +14 -1
  327. package/src/cli/mcp.ts +106 -0
  328. package/src/cli/skills-eval.ts +8 -2
  329. package/src/cli/upgrade.ts +34 -38
  330. package/src/cli/verifiers.ts +1 -1
  331. package/src/core/bash-exec.ts +27 -4
  332. package/src/core/config.ts +2 -1
  333. package/src/core/defaults.ts +10 -1
  334. package/src/core/event-bus.ts +1 -1
  335. package/src/core/run-records.ts +438 -0
  336. package/src/core/safe-exec.ts +506 -56
  337. package/src/core/skill-activation.ts +5 -3
  338. package/src/core/termination.ts +3 -3
  339. package/src/core/tool-names.ts +33 -12
  340. package/src/domains/context/clio-md.ts +1 -1
  341. package/src/domains/context/worker/pressure.ts +6 -2
  342. package/src/domains/context/working-set/path-index.ts +7 -2
  343. package/src/domains/dispatch/code-step.ts +7 -2
  344. package/src/domains/dispatch/contract.ts +7 -0
  345. package/src/domains/dispatch/execution-role.ts +3 -3
  346. package/src/domains/dispatch/execution-scheduler.ts +204 -79
  347. package/src/domains/dispatch/extension.ts +131 -14
  348. package/src/domains/dispatch/fleet-preflight.ts +18 -3
  349. package/src/domains/dispatch/fleet-run.ts +1 -0
  350. package/src/domains/dispatch/gate-decisions.ts +3 -3
  351. package/src/domains/dispatch/heartbeat.ts +1 -1
  352. package/src/domains/dispatch/host-verification.ts +16 -14
  353. package/src/domains/dispatch/receipt-findings.ts +3 -4
  354. package/src/domains/dispatch/reservation-store.ts +7 -9
  355. package/src/domains/dispatch/route-facts.ts +1 -1
  356. package/src/domains/dispatch/state.ts +3 -3
  357. package/src/domains/dispatch/types.ts +1 -1
  358. package/src/domains/evidence/build.ts +35 -7
  359. package/src/domains/gateway/mcp/client.ts +923 -0
  360. package/src/domains/gateway/mcp/config.ts +456 -0
  361. package/src/domains/gateway/mcp/index.ts +88 -0
  362. package/src/domains/gateway/mcp/protocol.ts +273 -0
  363. package/src/domains/gateway/mcp/trust.ts +263 -0
  364. package/src/domains/lifecycle/doctor.ts +17 -3
  365. package/src/domains/mux/contract.ts +5 -9
  366. package/src/domains/mux/detect.ts +1 -1
  367. package/src/domains/mux/extension.ts +1 -1
  368. package/src/domains/mux/protocol.ts +5 -7
  369. package/src/domains/mux/socket-client.ts +3 -3
  370. package/src/domains/observability/accountability.ts +2 -2
  371. package/src/domains/observability/contract.ts +7 -3
  372. package/src/domains/observability/evidence-index.ts +2 -2
  373. package/src/domains/observability/projection.ts +10 -0
  374. package/src/domains/prompts/compiler.ts +41 -23
  375. package/src/domains/prompts/fragments/identity/docs-routing.md +2 -2
  376. package/src/domains/prompts/fragments/operating/skills.md +12 -10
  377. package/src/domains/providers/index.ts +5 -1
  378. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +42 -10
  379. package/src/domains/providers/probe/http.ts +44 -59
  380. package/src/domains/providers/probe/reasoning.ts +2 -0
  381. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +20 -31
  382. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +9 -4
  383. package/src/domains/safety/action-classifier.ts +17 -1
  384. package/src/domains/safety/call-target.ts +14 -0
  385. package/src/domains/safety/contract.ts +1 -1
  386. package/src/domains/safety/finish-contract.ts +9 -3
  387. package/src/domains/safety/loop-detector.ts +1 -1
  388. package/src/domains/safety/policy-engine.ts +7 -0
  389. package/src/domains/safety/protected-artifacts.ts +3 -4
  390. package/src/domains/safety/rejection-feedback.ts +1 -1
  391. package/src/domains/safety/scope.ts +2 -3
  392. package/src/domains/safety/validation-contract.ts +3 -2
  393. package/src/domains/scheduling/budget.ts +5 -3
  394. package/src/domains/scheduling/contract.ts +2 -1
  395. package/src/domains/scheduling/extension.ts +3 -3
  396. package/src/domains/session/compaction/branch-summary.ts +1 -1
  397. package/src/domains/session/compaction/compact.ts +25 -2
  398. package/src/domains/session/compaction/cut-point.ts +1 -1
  399. package/src/domains/session/compaction/tokens.ts +5 -10
  400. package/src/domains/session/contract.ts +1 -1
  401. package/src/domains/session/cwd-fallback.ts +2 -2
  402. package/src/domains/session/handoff.ts +5 -1
  403. package/src/domains/session/history.ts +6 -0
  404. package/src/domains/session/manager.ts +14 -7
  405. package/src/domains/session/retry.ts +2 -1
  406. package/src/domains/session/session-artifacts.ts +12 -7
  407. package/src/domains/session/task-board.ts +2 -3
  408. package/src/engine/apis/openai-completions.ts +8 -0
  409. package/src/engine/loop-guard.ts +7 -0
  410. package/src/engine/provider-error-body.ts +65 -0
  411. package/src/engine/session.ts +118 -29
  412. package/src/engine/worker-runtime.ts +3 -0
  413. package/src/entry/boot-options.ts +2 -0
  414. package/src/entry/orchestrator.ts +18 -2
  415. package/src/interactive/chat-loop-policy.ts +1 -0
  416. package/src/interactive/chat-loop.ts +8 -4
  417. package/src/interactive/chat-panel.ts +23 -9
  418. package/src/interactive/chat-renderer.ts +33 -11
  419. package/src/interactive/clio-editor.ts +13 -5
  420. package/src/interactive/dispatch-board.ts +70 -30
  421. package/src/interactive/editor-submit.ts +30 -25
  422. package/src/interactive/footer/widgets.ts +12 -9
  423. package/src/interactive/interactive-presentation.ts +2 -3
  424. package/src/interactive/mux-bridge.ts +3 -7
  425. package/src/interactive/overlay-general-openers.ts +14 -7
  426. package/src/interactive/overlays/cwd-fallback.ts +1 -1
  427. package/src/interactive/overlays/library-model.ts +114 -35
  428. package/src/interactive/overlays/library.ts +52 -5
  429. package/src/interactive/overlays/list-overlay.ts +4 -1
  430. package/src/interactive/overlays/session-selector.ts +28 -23
  431. package/src/interactive/overlays/settings.ts +20 -1
  432. package/src/interactive/overlays/tree-selector.ts +47 -10
  433. package/src/interactive/panes-runtime.ts +1 -1
  434. package/src/interactive/renderers/compaction-summary.ts +1 -1
  435. package/src/interactive/renderers/provider-error.ts +118 -0
  436. package/src/interactive/renderers/retry-status.ts +59 -23
  437. package/src/interactive/renderers/tool-execution.ts +67 -7
  438. package/src/interactive/renderers/worker-answer.ts +198 -0
  439. package/src/interactive/renderers/worker-entry.ts +57 -163
  440. package/src/interactive/slash-commands.ts +26 -1
  441. package/src/interactive/slash-spec.ts +2 -2
  442. package/src/interactive/theme/labels.ts +66 -30
  443. package/src/interactive/turn-persistence.ts +6 -1
  444. package/src/interactive/turn-recovery.ts +2 -1
  445. package/src/interactive/turn-runtime.ts +22 -5
  446. package/src/interactive/view/artifacts.ts +3 -2
  447. package/src/interactive/view/view-overlay.ts +96 -20
  448. package/src/tools/agent-tools.ts +21 -7
  449. package/src/tools/artifact.ts +16 -8
  450. package/src/tools/bash.ts +90 -11
  451. package/src/tools/bootstrap.ts +42 -4
  452. package/src/tools/builtin-tool-catalog.ts +72 -7
  453. package/src/tools/context/index.ts +27 -31
  454. package/src/tools/context/library.ts +3 -1
  455. package/src/tools/context/surface.ts +12 -26
  456. package/src/tools/core-bootstrap.ts +72 -1
  457. package/src/tools/data/csv.ts +1189 -0
  458. package/src/tools/data/index.ts +308 -0
  459. package/src/tools/data/json.ts +1799 -0
  460. package/src/tools/data/jsonl.ts +561 -0
  461. package/src/tools/data/shared.ts +452 -0
  462. package/src/tools/edit-diff.ts +0 -7
  463. package/src/tools/edit.ts +115 -18
  464. package/src/tools/file-mutation-queue.ts +114 -4
  465. package/src/tools/find.ts +108 -29
  466. package/src/tools/gateway/caps.ts +11 -0
  467. package/src/tools/gateway/clio-context-surface.ts +41 -0
  468. package/src/tools/gateway/clio-context-tools.ts +77 -0
  469. package/src/tools/gateway/data-surface.ts +138 -0
  470. package/src/tools/gateway/data-tool.ts +201 -0
  471. package/src/tools/gateway/index.ts +342 -0
  472. package/src/tools/gateway/mcp-capabilities.ts +469 -0
  473. package/src/tools/grep.ts +88 -33
  474. package/src/tools/harness-extensions.ts +3 -0
  475. package/src/tools/ignore-policy.ts +7 -5
  476. package/src/tools/ls.ts +111 -20
  477. package/src/tools/policy.ts +35 -13
  478. package/src/tools/presentation.ts +6 -0
  479. package/src/tools/read.ts +634 -156
  480. package/src/tools/registry.ts +94 -6
  481. package/src/tools/run-script.ts +997 -0
  482. package/src/tools/spawn-hygiene.ts +157 -5
  483. package/src/tools/surface.ts +163 -0
  484. package/src/tools/verify/authoring.ts +8 -3
  485. package/src/tools/verify/catalog.ts +14 -1
  486. package/src/tools/verify/numeric.ts +367 -59
  487. package/src/tools/verify/perf.ts +171 -9
  488. package/src/tools/verify/scripts.ts +178 -26
  489. package/src/tools/web-fetch-surface.ts +22 -0
  490. package/src/tools/web-fetch.ts +26 -1
  491. package/src/tools/write.ts +45 -19
  492. package/dist/chunk-B6UM3OZC.js +0 -15
  493. package/dist/chunk-GJ24ODAX.js +0 -196
  494. package/dist/chunk-LZCCBLRC.js +0 -57
  495. package/dist/web/client/assets/architecture-7GRP2DOG-EGozsYEO.js +0 -1
  496. package/dist/web/client/assets/architectureDiagram-5GKGNRK7-z9FokbJl.js +0 -36
  497. package/dist/web/client/assets/channel-CiUWbHN9.js +0 -1
  498. package/dist/web/client/assets/chunk-DU6HZSFF-C5USiOAy.js +0 -125
  499. package/dist/web/client/assets/classDiagram-ZZMXUADV-CMODalmo.js +0 -1
  500. package/dist/web/client/assets/classDiagram-v2-VYDZK3BY-CMODalmo.js +0 -1
  501. package/dist/web/client/assets/cose-bilkent-JH36ORCC-RbQL23qS.js +0 -1
  502. package/dist/web/client/assets/dist-D0_q-A2b.js +0 -1
  503. package/dist/web/client/assets/eventmodeling-NTZA5JFV-DjVq8wKU.js +0 -1
  504. package/dist/web/client/assets/flowDiagram-HODETNUW-BUiCBGXt.js +0 -1
  505. package/dist/web/client/assets/ganttDiagram-EL5Y4UJY-B2lb8lvF.js +0 -292
  506. package/dist/web/client/assets/index-FSIC94pi.js +0 -83
  507. package/dist/web/client/assets/prism-core-BngLtbUd.js +0 -1
  508. package/dist/web/client/assets/railroad-abnf-HS5TGJTU-BcW01NZG.js +0 -1
  509. package/dist/web/client/assets/railroad-ebnf-LZEXJU2U-B7YCEDDd.js +0 -1
  510. package/dist/web/client/assets/railroad-peg-WCYAUIDC-DjNZbSTZ.js +0 -1
  511. package/dist/web/client/assets/src-yeptRXpt.js +0 -1
  512. package/dist/web/client/assets/stateDiagram-v2-MP3YSRHH-C7QtHeK4.js +0 -1
  513. package/dist/web/client/assets/swimlanesDiagram-VR7AAH4N-CBZlPFky.js +0 -8
package/src/tools/grep.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { readdirSync, readFileSync, statSync } from "node:fs";
1
+ import { statSync } from "node:fs";
2
+ import { readdir, readFile, stat } from "node:fs/promises";
2
3
  import path, { join, relative } from "node:path";
4
+ import { setImmediate as yieldToLoop } from "node:timers/promises";
3
5
  import { Type } from "typebox";
4
6
  import { ToolNames } from "../core/tool-names.js";
5
7
  import { StringEnum } from "../engine/ai.js";
@@ -18,7 +20,16 @@ import {
18
20
  } from "./observation.js";
19
21
  import { resolveReadPath, toPosixPath } from "./path-utils.js";
20
22
  import type { ToolInvokeOptions, ToolResult, ToolSpec } from "./registry.js";
21
- import { SEARCH_SPAWN_TIMEOUT_MS, spawnLineStream, validateSearchPatternSize } from "./spawn-hygiene.js";
23
+ import {
24
+ createSearchDiagnostics,
25
+ finishSearch,
26
+ newSearchCompleteness,
27
+ type SearchCompleteness,
28
+ searchNotice,
29
+ skipSearchPath,
30
+ spawnLineStream,
31
+ validateSearchPatternSize,
32
+ } from "./spawn-hygiene.js";
22
33
  import { GREP_MAX_LINE_LENGTH, truncateHead, truncateLine } from "./truncate.js";
23
34
 
24
35
  const DEFAULT_LIMIT = 100;
@@ -68,6 +79,8 @@ interface RenderedLine {
68
79
  }
69
80
 
70
81
  interface GrepRenderInput {
82
+ search: SearchCompleteness;
83
+ fallback?: boolean;
71
84
  withheldPaths: number;
72
85
  mode: GrepMode;
73
86
  lines: RenderedLine[];
@@ -88,16 +101,21 @@ const NO_MATCH_OUTPUT = "No matches found";
88
101
  * rendering when anything was cut, and close the envelope.
89
102
  */
90
103
  function renderGrepResult(input: GrepRenderInput): ToolResult {
91
- const { mode, lines, matchCount, limitHit, limit, linesTruncated, reservation, options } = input;
104
+ const { mode, lines, matchCount, limitHit, limit, linesTruncated, reservation, options, search } = input;
105
+ const fallbackNotice = input.fallback
106
+ ? "\n[Fallback search uses GENERATED_DIRS only; .gitignore is not applied.]"
107
+ : "";
92
108
  if (lines.length === 0) {
93
109
  return finalizeObservation({
94
110
  tool: ToolNames.Grep,
95
111
  withheldPaths: input.withheldPaths,
96
112
  unit: MODE_UNITS[mode],
97
- output: NO_MATCH_OUTPUT,
113
+ output:
114
+ (search.complete ? NO_MATCH_OUTPUT : "Search incomplete") + searchNotice(search, 0, "matches") + fallbackNotice,
115
+ details: { search },
98
116
  shownCount: 0,
99
- totalCount: 0,
100
- truncated: false,
117
+ totalCount: search.complete ? 0 : null,
118
+ truncated: !search.complete,
101
119
  reservation,
102
120
  ...(options ? { options } : {}),
103
121
  });
@@ -115,7 +133,11 @@ function renderGrepResult(input: GrepRenderInput): ToolResult {
115
133
  } else {
116
134
  shownCount = truncation.outputLines;
117
135
  }
118
- const truncated = limitHit || truncation.truncated;
136
+ if (truncation.truncated && search.complete) {
137
+ search.complete = false;
138
+ search.reason = "limit";
139
+ }
140
+ const truncated = !search.complete || limitHit || truncation.truncated;
119
141
  const next = limitHit ? `limit=${limit * 2}` : truncation.truncated && mode === "content" ? "mode=files" : undefined;
120
142
  let output = truncation.content;
121
143
  if (linesTruncated) {
@@ -125,12 +147,13 @@ function renderGrepResult(input: GrepRenderInput): ToolResult {
125
147
  tool: ToolNames.Grep,
126
148
  withheldPaths: input.withheldPaths,
127
149
  unit: MODE_UNITS[mode],
128
- output,
150
+ output: output + searchNotice(search, shownCount, "matches") + fallbackNotice,
151
+ details: { search },
129
152
  // Offload only when the byte cap cut collected content; a bare match
130
153
  // limit continues via `next`, and the offload would duplicate the body.
131
154
  ...(truncation.truncated ? { fullOutput } : {}),
132
155
  shownCount,
133
- totalCount: limitHit ? null : matchCount,
156
+ totalCount: search.complete ? matchCount : null,
134
157
  truncated,
135
158
  ...(next !== undefined ? { next } : {}),
136
159
  reservation,
@@ -237,22 +260,31 @@ async function runRipgrep(input: RgSearchInput): Promise<ToolResult> {
237
260
  }
238
261
  };
239
262
 
263
+ const search = newSearchCompleteness();
264
+ const diagnostics = createSearchDiagnostics(search, (filePath) => input.pathFilter.allows(path.resolve(filePath)));
240
265
  const result = await spawnLineStream(input.rgPath, buildRgArgs(input), {
241
266
  ...(input.options?.signal ? { signal: input.options.signal } : {}),
242
267
  onLine: input.mode === "content" ? onContentLine : onListLine,
268
+ onStderrLine: diagnostics.onLine,
243
269
  });
244
- if (result.aborted) return { kind: "error", message: "grep: operation aborted" };
245
- if (result.timedOut) {
270
+ finishSearch(search, result);
271
+ if (result.spawnError !== null) return { kind: "error", message: `grep: failed to run rg: ${result.spawnError}` };
272
+ if (
273
+ !result.aborted &&
274
+ !result.timedOut &&
275
+ !result.stoppedEarly &&
276
+ result.exitCode !== 0 &&
277
+ result.exitCode !== 1 &&
278
+ matchCount === 0 &&
279
+ (diagnostics.realError || (search.skipped.count === 0 && !search.skipped.unknown))
280
+ ) {
246
281
  return {
247
282
  kind: "error",
248
- message: `grep: rg timed out after ${SEARCH_SPAWN_TIMEOUT_MS / 1000}s. Narrow the pattern, path, or glob, lower context, or use mode=files.`,
283
+ message: `grep: rg rejected the search or failed (exit code ${result.exitCode}). Check the pattern and search path.`,
249
284
  };
250
285
  }
251
- if (result.spawnError !== null) return { kind: "error", message: `grep: failed to run rg: ${result.spawnError}` };
252
- if (!result.stoppedEarly && result.exitCode !== 0 && result.exitCode !== 1) {
253
- return { kind: "error", message: `grep: ${result.stderr.trim() || `ripgrep exited with code ${result.exitCode}`}` };
254
- }
255
286
  return renderGrepResult({
287
+ search,
256
288
  withheldPaths: input.pathFilter.withheldPaths,
257
289
  mode: input.mode,
258
290
  lines: rendered,
@@ -310,7 +342,8 @@ interface FallbackSearchInput {
310
342
  * already-in-memory file content, never a second read. Aggregates the same
311
343
  * three mode shapes as the rg path.
312
344
  */
313
- function fallbackGrep(input: FallbackSearchInput): ToolResult {
345
+ async function fallbackGrep(input: FallbackSearchInput): Promise<ToolResult> {
346
+ const search = newSearchCompleteness();
314
347
  const built = buildMatchRegex(input.pattern, input.literal, input.ignoreCase);
315
348
  if (!built.ok) return { kind: "error", message: built.message };
316
349
  const regex = built.regex;
@@ -337,21 +370,32 @@ function fallbackGrep(input: FallbackSearchInput): ToolResult {
337
370
  rendered.push({ text: truncatedLine.text, isMatch });
338
371
  };
339
372
 
340
- const searchFile = (filePath: string): void => {
341
- if (limitHit || !input.pathFilter.allows(filePath)) return;
373
+ const searchFile = async (filePath: string): Promise<void> => {
374
+ if (limitHit || signal?.aborted || !input.pathFilter.allows(filePath)) return;
342
375
  let buffer: Buffer;
343
376
  try {
344
- const stat = statSync(filePath);
345
- if (!stat.isFile() || stat.size > FALLBACK_MAX_FILE_BYTES) return;
346
- buffer = readFileSync(filePath);
377
+ const fileStat = await stat(filePath);
378
+ if (!fileStat.isFile() || fileStat.size > FALLBACK_MAX_FILE_BYTES) {
379
+ skipSearchPath(search, filePath, input.pathFilter.allows);
380
+ return;
381
+ }
382
+ buffer = await readFile(filePath);
347
383
  } catch {
384
+ skipSearchPath(search, filePath, input.pathFilter.allows);
385
+ return;
386
+ }
387
+ if (looksBinary(buffer)) {
388
+ skipSearchPath(search, filePath, input.pathFilter.allows);
348
389
  return;
349
390
  }
350
- if (looksBinary(buffer)) return;
351
391
  const lines = buffer.toString("utf8").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
352
392
  const rel = formatPath(filePath, input.searchPath, input.isDirectory);
353
393
  let fileMatches = 0;
354
394
  for (let i = 0; i < lines.length; i += 1) {
395
+ if (i % 1024 === 0) {
396
+ await yieldToLoop();
397
+ if (signal?.aborted) return;
398
+ }
355
399
  const lineText = lines[i] ?? "";
356
400
  regex.lastIndex = 0;
357
401
  if (!regex.test(lineText)) continue;
@@ -384,35 +428,46 @@ function fallbackGrep(input: FallbackSearchInput): ToolResult {
384
428
  }
385
429
  };
386
430
 
387
- const walk = (dir: string): void => {
431
+ const walk = async (dir: string): Promise<void> => {
432
+ await yieldToLoop();
388
433
  if (limitHit || signal?.aborted) return;
389
434
  let entries: import("node:fs").Dirent[];
390
435
  try {
391
- entries = readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
436
+ entries = (await readdir(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
392
437
  } catch {
438
+ skipSearchPath(search, dir, input.pathFilter.allows);
393
439
  return;
394
440
  }
395
441
  for (const entry of entries) {
396
442
  if (limitHit || signal?.aborted) return;
397
443
  const absPath = join(dir, entry.name);
444
+ if (!input.pathFilter.allows(absPath)) continue;
398
445
  if (entry.isDirectory()) {
399
446
  if (ignored.has(entry.name)) continue;
400
- walk(absPath);
447
+ await walk(absPath);
448
+ continue;
449
+ }
450
+ if (!entry.isFile()) {
451
+ skipSearchPath(search, absPath, input.pathFilter.allows);
401
452
  continue;
402
453
  }
403
- if (!entry.isFile()) continue;
404
454
  if (globMatcher) {
405
455
  const relPath = normalizeGlobInput(relative(input.searchPath, absPath));
406
456
  if (!globMatcher.test(relPath)) continue;
407
457
  }
408
- searchFile(absPath);
458
+ await searchFile(absPath);
409
459
  }
410
460
  };
411
461
 
412
- if (input.isDirectory) walk(input.searchPath);
413
- else searchFile(input.searchPath);
414
- if (signal?.aborted) return { kind: "error", message: "grep: operation aborted" };
462
+ if (input.isDirectory) await walk(input.searchPath);
463
+ else await searchFile(input.searchPath);
464
+ if (signal?.aborted || limitHit) {
465
+ search.complete = false;
466
+ search.reason = signal?.aborted ? "cancelled" : "limit";
467
+ }
415
468
  return renderGrepResult({
469
+ fallback: true,
470
+ search,
416
471
  withheldPaths: input.pathFilter.withheldPaths,
417
472
  mode: input.mode,
418
473
  lines: rendered,
@@ -427,7 +482,7 @@ function fallbackGrep(input: FallbackSearchInput): ToolResult {
427
482
 
428
483
  export const grepTool: ToolSpec = {
429
484
  name: ToolNames.Grep,
430
- description: `Search file contents with ripgrep. mode=content (default) returns matching lines with paths and line numbers, mode=files returns only matching file paths, mode=count returns per-file match counts. Respects .gitignore and skips generated dirs unless include_ignored=true. Capped at ${DEFAULT_LIMIT} matches by default; truncated results say how to continue and where the full output was saved.`,
485
+ description: `Search file contents with ripgrep. mode=content (default) returns matching lines with paths and line numbers, mode=files returns only matching file paths, mode=count returns per-file match counts. Respects .gitignore and skips generated dirs unless include_ignored=true. Without rg, the async fallback uses GENERATED_DIRS only and does not apply .gitignore; unreadable, binary, oversized files and symlinks are reported as skipped. Capped at ${DEFAULT_LIMIT} matches by default; truncated results say how to continue and where the full output was saved.`,
431
486
  parameters: Type.Object({
432
487
  pattern: Type.String({ description: "Search pattern (regex by default)." }),
433
488
  path: Type.Optional(Type.String({ description: "Directory or file to search." })),
@@ -499,7 +554,7 @@ export const grepTool: ToolSpec = {
499
554
  if (rgPath) return await runRipgrep({ rgPath, ...shared });
500
555
  // rg absent (offline/weak node): degrade to a bounded pure-Node search
501
556
  // instead of failing content search outright.
502
- return fallbackGrep(shared);
557
+ return await fallbackGrep(shared);
503
558
  } finally {
504
559
  releaseObservation(reservation);
505
560
  }
@@ -64,6 +64,9 @@ function createCommandTool(extension: LoadableExtension, tool: ExtensionCommandT
64
64
  parameters: tool.inputSchema as TSchema,
65
65
  baseActionClass: "execute",
66
66
  executionMode: "sequential",
67
+ // Reached through gateway find/describe/call; the spec, its execute
68
+ // class, and its bash projection are unchanged by the placement.
69
+ placement: "gateway",
67
70
  sourceInfo: { path: extension.manifestPath, scope: "domain", extension: extension.provenance },
68
71
  metadata: {
69
72
  objective: tool.description,
@@ -3,10 +3,11 @@ import { dirname, join } from "node:path";
3
3
  import { toPosixPath } from "./path-utils.js";
4
4
 
5
5
  /**
6
- * One ignore policy for every path-walking OBSERVE tool. grep (rg), find (fd),
7
- * and the pure-Node fallback walkers all answer "which parts of the tree are
8
- * visible" from this module so the three surfaces never disagree about
9
- * gitignored, generated, or clio-internal paths.
6
+ * Shared exclusions for path-walking OBSERVE tools. Native rg/fd searches
7
+ * honor gitignore rules as well as generated-directory and internal-state
8
+ * exclusions. Pure-Node fallback walkers apply GENERATED_DIRS and internal
9
+ * exclusions only; they do not interpret .gitignore or .ignore files, so their
10
+ * visible paths can differ from native searches.
10
11
  *
11
12
  * The policy has three layers:
12
13
  * 1. ALWAYS excluded: clio-internal state and .git. Never searchable unless
@@ -14,7 +15,8 @@ import { toPosixPath } from "./path-utils.js";
14
15
  * .clio-coder explicitly means the caller wants those paths).
15
16
  * 2. .gitignore: honored natively by rg/fd. Outside a git repo the binaries
16
17
  * get --no-require-git so plain .gitignore/.ignore files still apply;
17
- * inside a repo the default git-aware behavior keeps parent ignore rules
18
+ * fallback walkers do not apply this layer. Inside a repo the default
19
+ * git-aware behavior keeps parent ignore rules
18
20
  * from leaking across nested-repo boundaries.
19
21
  * 3. GENERATED_DIRS: universal build/dependency noise force-excluded even
20
22
  * when a project forgets to gitignore it.
package/src/tools/ls.ts CHANGED
@@ -1,27 +1,84 @@
1
- import { readdirSync, statSync } from "node:fs";
1
+ import { lstat, opendir, readlink, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { setImmediate as yieldToLoop } from "node:timers/promises";
3
4
  import { Type } from "typebox";
4
5
  import { ToolNames } from "../core/tool-names.js";
6
+ import { createSafetyPolicyEngine } from "../domains/safety/policy-engine.js";
5
7
  import {
6
- createObservationPathFilter,
8
+ commitObservationReservation,
7
9
  finalizeObservation,
8
10
  OBSERVE_SELF_CAPS,
9
11
  observationBudgetExhausted,
12
+ releaseObservation,
10
13
  reserveObservation,
11
14
  } from "./observation.js";
12
15
  import { resolveReadPath } from "./path-utils.js";
13
16
  import type { ToolResult, ToolSpec } from "./registry.js";
17
+ import { newSearchCompleteness, skipSearchPath } from "./spawn-hygiene.js";
14
18
  import { truncateHead } from "./truncate.js";
15
19
 
16
20
  const DEFAULT_LIMIT = 500;
17
21
 
18
22
  function parseLimit(value: unknown): number {
19
- return typeof value === "number" && value > 0 ? Math.floor(value) : DEFAULT_LIMIT;
23
+ return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : DEFAULT_LIMIT;
24
+ }
25
+
26
+ interface ListingEntry {
27
+ name: string;
28
+ order: number;
29
+ }
30
+
31
+ const compareEntries = (a: ListingEntry, b: ListingEntry): number =>
32
+ a.name.toLowerCase().localeCompare(b.name.toLowerCase()) || a.order - b.order;
33
+
34
+ /** A max heap retains the earliest names, preserving directory read order for collation ties. */
35
+ export class BoundedListingSelection {
36
+ private readonly entries: ListingEntry[] = [];
37
+ private nextOrder = 0;
38
+ constructor(private readonly limit: number) {}
39
+ get retained(): number {
40
+ return this.entries.length;
41
+ }
42
+ private entryAt(index: number): ListingEntry {
43
+ const entry = this.entries[index];
44
+ if (!entry) throw new Error("Invalid listing heap index");
45
+ return entry;
46
+ }
47
+ add(name: string): void {
48
+ const entry = { name, order: this.nextOrder++ };
49
+ if (this.entries.length < this.limit) {
50
+ this.entries.push(entry);
51
+ let i = this.entries.length - 1;
52
+ while (i > 0) {
53
+ const parent = Math.floor((i - 1) / 2);
54
+ if (compareEntries(this.entryAt(parent), entry) >= 0) break;
55
+ this.entries[i] = this.entryAt(parent);
56
+ i = parent;
57
+ }
58
+ this.entries[i] = entry;
59
+ return;
60
+ }
61
+ if (compareEntries(entry, this.entryAt(0)) >= 0) return;
62
+ this.entries[0] = entry;
63
+ let i = 0;
64
+ while (2 * i + 1 < this.entries.length) {
65
+ let child = 2 * i + 1;
66
+ if (child + 1 < this.entries.length && compareEntries(this.entryAt(child + 1), this.entryAt(child)) > 0) child++;
67
+ if (compareEntries(entry, this.entryAt(child)) >= 0) break;
68
+ this.entries[i] = this.entryAt(child);
69
+ i = child;
70
+ }
71
+ this.entries[i] = entry;
72
+ }
73
+ sorted(): string[] {
74
+ return [...this.entries].sort(compareEntries).map((entry) => entry.name);
75
+ }
20
76
  }
21
77
 
22
78
  export const lsTool: ToolSpec = {
23
79
  name: ToolNames.Ls,
24
- description: 'List directory entries sorted alphabetically, "/" suffix for directories, dotfiles included.',
80
+ description:
81
+ 'List directory entries sorted alphabetically, "/" suffix for directories, dotfiles included. Symlinks render as name@ -> target, broken links as name@ (broken), and inaccessible entries are marked and counted.',
25
82
  parameters: Type.Object({
26
83
  path: Type.Optional(Type.String({ description: "Directory to list." })),
27
84
  limit: Type.Optional(Type.Number({ description: `Max entries (default ${DEFAULT_LIMIT}).` })),
@@ -34,7 +91,7 @@ export const lsTool: ToolSpec = {
34
91
  const limit = parseLimit(args.limit);
35
92
 
36
93
  try {
37
- const rootStat = statSync(root);
94
+ const rootStat = await stat(root);
38
95
  if (!rootStat.isDirectory()) {
39
96
  return { kind: "error", message: `ls: not a directory: ${root}` };
40
97
  }
@@ -53,32 +110,63 @@ export const lsTool: ToolSpec = {
53
110
  });
54
111
  }
55
112
 
113
+ commitObservationReservation(reservation);
56
114
  try {
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()));
115
+ const policy = options?.allowsObservationPath ? undefined : createSafetyPolicyEngine({ cwd: process.cwd() });
116
+ const allows =
117
+ options?.allowsObservationPath ??
118
+ ((entryPath: string) =>
119
+ policy?.evaluate({ tool: "read", args: { path: entryPath } }).reasonCode !== "path-policy:zeroAccessPaths");
120
+ let withheldPaths = 0;
121
+ let visibleCount = 0;
122
+ let scanned = 0;
123
+ const selection = new BoundedListingSelection(limit);
124
+ // Alphabetical selection requires examining every name, but only limit
125
+ // names are retained. No metadata calls are made for unselected entries.
126
+ for await (const entry of await opendir(root)) {
127
+ if (++scanned % 128 === 0) await yieldToLoop();
128
+ if (options?.signal?.aborted) return { kind: "error", message: "ls: operation aborted during enumeration" };
129
+ if (!allows(path.join(root, entry.name))) {
130
+ withheldPaths++;
131
+ continue;
132
+ }
133
+ visibleCount++;
134
+ selection.add(entry.name);
135
+ }
136
+ const entries = selection.sorted();
61
137
  const outputEntries: string[] = [];
62
- let entryLimitReached = false;
138
+ const entryLimitReached = visibleCount > limit;
139
+ const search = newSearchCompleteness();
63
140
  for (const entry of entries) {
64
- if (outputEntries.length >= limit) {
65
- entryLimitReached = true;
66
- break;
67
- }
141
+ const entryPath = path.join(root, entry);
68
142
  try {
69
- const entryStat = statSync(path.join(root, entry));
70
- outputEntries.push(entryStat.isDirectory() ? `${entry}/` : entry);
143
+ const entryStat = await lstat(entryPath);
144
+ if (entryStat.isSymbolicLink()) {
145
+ const target = await readlink(entryPath);
146
+ try {
147
+ await stat(entryPath);
148
+ outputEntries.push(`${entry}@ -> ${target}`);
149
+ } catch (error) {
150
+ const code = (error as NodeJS.ErrnoException).code;
151
+ outputEntries.push(`${entry}@ (${code === "ENOENT" || code === "ENOTDIR" ? "broken" : "unreadable"})`);
152
+ skipSearchPath(search, entryPath);
153
+ }
154
+ } else {
155
+ outputEntries.push(entryStat.isDirectory() ? `${entry}/` : entry);
156
+ }
71
157
  } catch {
72
- // Mirror the reference tool: skip entries that disappear or cannot be statted.
158
+ outputEntries.push(`${entry} (unreadable)`);
159
+ skipSearchPath(search, entryPath);
73
160
  }
74
161
  }
75
162
 
76
163
  if (outputEntries.length === 0) {
77
164
  return finalizeObservation({
78
165
  tool: ToolNames.Ls,
79
- withheldPaths: pathFilter.withheldPaths,
166
+ withheldPaths,
80
167
  unit: "entries",
81
168
  output: "(empty directory)",
169
+ details: { skipped: search.skipped, selection: { scanned, retained: selection.retained } },
82
170
  shownCount: 0,
83
171
  totalCount: 0,
84
172
  truncated: false,
@@ -95,14 +183,15 @@ export const lsTool: ToolSpec = {
95
183
  const truncated = entryLimitReached || truncation.truncated;
96
184
  return finalizeObservation({
97
185
  tool: ToolNames.Ls,
98
- withheldPaths: pathFilter.withheldPaths,
186
+ withheldPaths,
99
187
  unit: "entries",
100
188
  output: truncation.content,
189
+ details: { skipped: search.skipped, selection: { scanned, retained: selection.retained } },
101
190
  // Offload only when the byte cap cut collected entries; a bare
102
191
  // entry limit continues via `next`.
103
192
  ...(truncation.truncated ? { fullOutput } : {}),
104
193
  shownCount: truncation.outputLines,
105
- totalCount: entries.length,
194
+ totalCount: visibleCount,
106
195
  truncated,
107
196
  ...(entryLimitReached ? { next: `limit=${limit * 2}` } : {}),
108
197
  reservation,
@@ -111,6 +200,8 @@ export const lsTool: ToolSpec = {
111
200
  } catch (err) {
112
201
  const msg = err instanceof Error ? err.message : String(err);
113
202
  return { kind: "error", message: `ls: ${msg}` };
203
+ } finally {
204
+ releaseObservation(reservation);
114
205
  }
115
206
  },
116
207
  };
@@ -1,5 +1,6 @@
1
1
  import { type BuiltinToolName, isBuiltinToolName, type ToolName, ToolNames } from "../core/tool-names.js";
2
2
  import { type ActionClass, classify } from "../domains/safety/action-classifier.js";
3
+ import { DATA_OBSERVATION_SELF_CAP_BYTES, GATEWAY_FIND_SELF_CAP_BYTES } from "./gateway/caps.js";
3
4
  import { OBSERVATION_POLICY_SLACK_BYTES, OBSERVE_SELF_CAPS } from "./observation.js";
4
5
  import { readMaxBytes } from "./read.js";
5
6
  import type { ToolExecutionMode, ToolSpec } from "./registry.js";
@@ -11,7 +12,15 @@ import type { ToolExecutionMode, ToolSpec } from "./registry.js";
11
12
  * differently from what the policy engine assumes.
12
13
  */
13
14
 
14
- export type ToolPlane = "observe" | "mutate" | "execute" | "orchestrate" | "retrieve" | "interact" | "artifact";
15
+ export type ToolPlane =
16
+ | "observe"
17
+ | "mutate"
18
+ | "execute"
19
+ | "orchestrate"
20
+ | "retrieve"
21
+ | "interact"
22
+ | "artifact"
23
+ | "gateway";
15
24
 
16
25
  interface PlaneExpectation {
17
26
  plane: ToolPlane;
@@ -29,6 +38,12 @@ export const TOOL_PLANES: Readonly<Record<BuiltinToolName, PlaneExpectation>> =
29
38
  [ToolNames.CodeNav]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
30
39
  [ToolNames.Context]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
31
40
  [ToolNames.CredentialPresent]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
41
+ // clio_docs and clio_library are the bundled-documentation and recipe-catalog
42
+ // reads that used to be context scopes; same envelope, same read class.
43
+ [ToolNames.ClioDocs]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
44
+ [ToolNames.ClioLibrary]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
45
+ // data streams structured files and never writes; parallel like read.
46
+ [ToolNames.Data]: { plane: "observe", actionClass: "read", executionMode: "parallel" },
32
47
  [ToolNames.Write]: { plane: "mutate", actionClass: "write", executionMode: "sequential" },
33
48
  [ToolNames.Edit]: { plane: "mutate", actionClass: "write", executionMode: "sequential" },
34
49
  [ToolNames.Bash]: { plane: "execute", actionClass: "execute", executionMode: "sequential" },
@@ -36,6 +51,9 @@ export const TOOL_PLANES: Readonly<Record<BuiltinToolName, PlaneExpectation>> =
36
51
  // its containment posture, read class for its safety disposition.
37
52
  [ToolNames.Git]: { plane: "execute", actionClass: "read", executionMode: "parallel" },
38
53
  [ToolNames.Verify]: { plane: "execute", actionClass: "execute", executionMode: "sequential" },
54
+ // run_script runs one interpreter over one workspace script and projects
55
+ // itself to a bash command for the policy engine; execute class, sequential.
56
+ [ToolNames.RunScript]: { plane: "execute", actionClass: "execute", executionMode: "sequential" },
39
57
  [ToolNames.Dispatch]: { plane: "orchestrate", actionClass: "dispatch", executionMode: "sequential" },
40
58
  // monitor never mutates a run, so it stays read class and parallel.
41
59
  [ToolNames.Monitor]: { plane: "orchestrate", actionClass: "read", executionMode: "parallel" },
@@ -62,16 +80,25 @@ export const TOOL_PLANES: Readonly<Record<BuiltinToolName, PlaneExpectation>> =
62
80
  // nothing else. Read class so it never trips a safety gate; sequential so
63
81
  // two decisions in one batch never race the supersede lookup.
64
82
  [ToolNames.Decide]: { plane: "orchestrate", actionClass: "read", executionMode: "sequential" },
83
+ // web_read is the GET-only half of the split: no method, headers, or body,
84
+ // so it is never an outward action.
85
+ [ToolNames.WebRead]: { plane: "retrieve", actionClass: "read", executionMode: "parallel" },
65
86
  [ToolNames.WebFetch]: { plane: "retrieve", actionClass: "read", executionMode: "parallel" },
66
87
  [ToolNames.AskUser]: { plane: "interact", actionClass: "read", executionMode: "sequential" },
67
88
  [ToolNames.Artifact]: { plane: "artifact", actionClass: "write", executionMode: "sequential" },
89
+ // gateway lists, describes, and calls secondary capabilities. Its own class
90
+ // is read; a call carries the capability's class through the same admission.
91
+ // Sequential because a call may park for approval or run a sequential
92
+ // capability, and two such calls in one batch must not interleave.
93
+ [ToolNames.Gateway]: { plane: "gateway", actionClass: "read", executionMode: "sequential" },
68
94
  };
69
95
 
70
96
  /**
71
97
  * OBSERVE envelope members and their self-caps. The registry policy cap must
72
98
  * sit at or above self cap + slack so the envelope's own notice line survives
73
99
  * the backstop. credential_present sits in the OBSERVE plane but returns a
74
- * typed boolean, so it carries no envelope cap.
100
+ * typed boolean, so it carries no envelope cap. The gateway is listed for its
101
+ * find listing, which uses the envelope's JSON stub rule.
75
102
  */
76
103
  const OBSERVE_ENVELOPE_SELF_CAPS: ReadonlyArray<[BuiltinToolName, () => number]> = [
77
104
  [ToolNames.Read, () => readMaxBytes()],
@@ -79,16 +106,11 @@ const OBSERVE_ENVELOPE_SELF_CAPS: ReadonlyArray<[BuiltinToolName, () => number]>
79
106
  [ToolNames.Find, () => OBSERVE_SELF_CAPS.find],
80
107
  [ToolNames.Ls, () => OBSERVE_SELF_CAPS.ls],
81
108
  [ToolNames.CodeNav, () => OBSERVE_SELF_CAPS.codeNav],
82
- [
83
- ToolNames.Context,
84
- () =>
85
- Math.max(
86
- OBSERVE_SELF_CAPS.contextDocs,
87
- OBSERVE_SELF_CAPS.contextSkills,
88
- OBSERVE_SELF_CAPS.contextWorkspace,
89
- OBSERVE_SELF_CAPS.contextLibrary,
90
- ),
91
- ],
109
+ [ToolNames.Context, () => Math.max(OBSERVE_SELF_CAPS.contextSkills, OBSERVE_SELF_CAPS.contextWorkspace)],
110
+ [ToolNames.ClioDocs, () => OBSERVE_SELF_CAPS.contextDocs],
111
+ [ToolNames.ClioLibrary, () => OBSERVE_SELF_CAPS.contextLibrary],
112
+ [ToolNames.Data, () => DATA_OBSERVATION_SELF_CAP_BYTES],
113
+ [ToolNames.Gateway, () => GATEWAY_FIND_SELF_CAP_BYTES],
92
114
  ];
93
115
 
94
116
  const SESSION_BOUND_TOOLS = new Set<ToolName>([]);
@@ -104,7 +126,7 @@ const PANES_BOUND_TOOLS = new Set<ToolName>([ToolNames.Panes]);
104
126
  */
105
127
  const LEDGER_BOUND_TOOLS = new Set<ToolName>([ToolNames.Ledger]);
106
128
  /** The RETRIEVE plane, omitted wholesale by a hermetic run (tools/network-policy.ts). */
107
- const NETWORK_BOUND_TOOLS = new Set<ToolName>([ToolNames.WebFetch]);
129
+ const NETWORK_BOUND_TOOLS = new Set<ToolName>([ToolNames.WebRead, ToolNames.WebFetch]);
108
130
 
109
131
  export interface BuiltinToolPolicyOptions {
110
132
  includeSessionTools?: boolean;
@@ -58,11 +58,15 @@ export const TOOL_PRESENTATION: Readonly<Record<string, ToolPresentationPolicy>>
58
58
  [ToolNames.CodeNav]: FOLDED,
59
59
  [ToolNames.Context]: FOLDED,
60
60
  [ToolNames.CredentialPresent]: FOLDED,
61
+ [ToolNames.ClioDocs]: FOLDED,
62
+ [ToolNames.ClioLibrary]: FOLDED,
63
+ [ToolNames.Data]: FOLDED,
61
64
  [ToolNames.Write]: FOLDED_WITH_DIFF,
62
65
  [ToolNames.Edit]: FOLDED_WITH_DIFF,
63
66
  [ToolNames.Bash]: FOLDED,
64
67
  [ToolNames.Git]: FOLDED,
65
68
  [ToolNames.Verify]: FOLDED,
69
+ [ToolNames.RunScript]: FOLDED,
66
70
  [ToolNames.Dispatch]: FOLDED,
67
71
  [ToolNames.Monitor]: FOLDED,
68
72
  [ToolNames.Steer]: FOLDED,
@@ -71,9 +75,11 @@ export const TOOL_PRESENTATION: Readonly<Record<string, ToolPresentationPolicy>>
71
75
  [ToolNames.Panes]: FOLDED,
72
76
  [ToolNames.Limitation]: FOLDED,
73
77
  [ToolNames.Decide]: FOLDED,
78
+ [ToolNames.WebRead]: FOLDED,
74
79
  [ToolNames.WebFetch]: FOLDED,
75
80
  [ToolNames.AskUser]: FOLDED,
76
81
  [ToolNames.Artifact]: FOLDED,
82
+ [ToolNames.Gateway]: FOLDED,
77
83
  };
78
84
 
79
85
  function readStringField(args: unknown, key: string): string | null {