@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
@@ -0,0 +1,273 @@
1
+ /**
2
+ * JSON-RPC 2.0 framing for the MCP stdio transport.
3
+ *
4
+ * The transport carries one JSON message per line: UTF-8 text, newline
5
+ * terminated, with no embedded newline. Everything here is pure: the framer
6
+ * accepts byte chunks and yields typed messages or one typed protocol error,
7
+ * and the client decides what to do with either. Invalid UTF-8 is a protocol
8
+ * error rather than a U+FFFD substitution, because a tool result that reached
9
+ * the model with silently replaced bytes would misreport what the server said.
10
+ */
11
+
12
+ export const MCP_PROTOCOL_VERSION = "2025-06-18";
13
+ export const DEFAULT_MAX_LINE_BYTES = 4 * 1024 * 1024;
14
+ export const JSON_RPC_METHOD_NOT_FOUND = -32601;
15
+
16
+ export type McpErrorCode = "timeout" | "closed" | "protocol" | "server" | "spawn" | "aborted" | "overload";
17
+
18
+ /**
19
+ * Every failure the client reports carries one of the codes above. `overload`
20
+ * names an outbound line the client refused to queue: on its own because it
21
+ * exceeds the cap, or fatally because the server stopped reading its stdin.
22
+ */
23
+ export class McpError extends Error {
24
+ override readonly name = "McpError";
25
+ readonly code: McpErrorCode;
26
+ readonly data: unknown;
27
+
28
+ constructor(code: McpErrorCode, message: string, data?: unknown) {
29
+ super(message);
30
+ this.code = code;
31
+ this.data = data;
32
+ }
33
+ }
34
+
35
+ export type JsonRpcId = number | string;
36
+
37
+ export interface JsonRpcRequest {
38
+ jsonrpc: "2.0";
39
+ id: JsonRpcId;
40
+ method: string;
41
+ params?: unknown;
42
+ }
43
+
44
+ export interface JsonRpcNotification {
45
+ jsonrpc: "2.0";
46
+ method: string;
47
+ params?: unknown;
48
+ }
49
+
50
+ export interface JsonRpcErrorObject {
51
+ code: number;
52
+ message: string;
53
+ data?: unknown;
54
+ }
55
+
56
+ export interface JsonRpcResponse {
57
+ jsonrpc: "2.0";
58
+ id: JsonRpcId | null;
59
+ result?: unknown;
60
+ error?: JsonRpcErrorObject;
61
+ }
62
+
63
+ export type JsonRpcMessage =
64
+ | { kind: "request"; message: JsonRpcRequest }
65
+ | { kind: "notification"; message: JsonRpcNotification }
66
+ | { kind: "response"; message: JsonRpcResponse };
67
+
68
+ export type ProtocolFrame = { kind: "message"; message: JsonRpcMessage } | { kind: "error"; error: McpError };
69
+
70
+ function isRecord(value: unknown): value is Record<string, unknown> {
71
+ return value !== null && typeof value === "object" && !Array.isArray(value);
72
+ }
73
+
74
+ function isJsonRpcId(value: unknown): value is JsonRpcId {
75
+ return typeof value === "string" || (typeof value === "number" && Number.isFinite(value));
76
+ }
77
+
78
+ // Transport-only metadata cannot be supplied by a server field. The result
79
+ // object remains the key until its pending request reaches the tool decoder.
80
+ const structuredJson = new WeakMap<object, string>();
81
+
82
+ export function structuredContentJson(result: object): string | undefined {
83
+ return structuredJson.get(result);
84
+ }
85
+
86
+ /** Classify one decoded JSON value as a request, notification, or response, or name why it is none of them. */
87
+ export function classifyJsonRpcMessage(value: unknown): JsonRpcMessage | McpError {
88
+ if (!isRecord(value)) return new McpError("protocol", "message is not a JSON object");
89
+ if (value.jsonrpc !== "2.0") return new McpError("protocol", 'message lacks jsonrpc: "2.0"');
90
+ if (typeof value.method === "string") {
91
+ if (value.id === undefined || value.id === null) {
92
+ const notification: JsonRpcNotification = { jsonrpc: "2.0", method: value.method };
93
+ if (value.params !== undefined) notification.params = value.params;
94
+ return { kind: "notification", message: notification };
95
+ }
96
+ if (!isJsonRpcId(value.id)) return new McpError("protocol", "request id must be a string or a finite number");
97
+ const request: JsonRpcRequest = { jsonrpc: "2.0", id: value.id, method: value.method };
98
+ if (value.params !== undefined) request.params = value.params;
99
+ return { kind: "request", message: request };
100
+ }
101
+ const hasResult = Object.hasOwn(value, "result");
102
+ const hasError = Object.hasOwn(value, "error");
103
+ if (!hasResult && !hasError) return new McpError("protocol", "message has neither method, result, nor error");
104
+ if (hasResult && hasError) return new McpError("protocol", "response carries both result and error");
105
+ if (value.id !== null && !isJsonRpcId(value.id)) {
106
+ return new McpError("protocol", "response id must be a string, a finite number, or null");
107
+ }
108
+ const response: JsonRpcResponse = {
109
+ jsonrpc: "2.0",
110
+ id: value.id === undefined ? null : (value.id as JsonRpcId | null),
111
+ };
112
+ if (hasResult) response.result = value.result;
113
+ if (hasError) {
114
+ const error = value.error;
115
+ if (!isRecord(error) || typeof error.code !== "number" || typeof error.message !== "string") {
116
+ return new McpError("protocol", "response error must carry a numeric code and a message");
117
+ }
118
+ const errorObject: JsonRpcErrorObject = { code: error.code, message: error.message };
119
+ if (error.data !== undefined) errorObject.data = error.data;
120
+ response.error = errorObject;
121
+ }
122
+ return { kind: "response", message: response };
123
+ }
124
+
125
+ /** Decode one complete line (without its terminator) into a message or a protocol error. */
126
+ export function parseJsonRpcLine(line: Buffer): JsonRpcMessage | McpError {
127
+ let text: string;
128
+ try {
129
+ text = new TextDecoder("utf-8", { fatal: true }).decode(line);
130
+ } catch {
131
+ return new McpError("protocol", "message line is not valid UTF-8");
132
+ }
133
+ let parsed: unknown;
134
+ try {
135
+ // Node >=22.19 supports source-aware revivers and rawJSON. Keep numeric
136
+ // source tokens without changing protocol IDs, schemas, or other fields.
137
+ const sources = new WeakMap<object, Map<string, string>>();
138
+ parsed = JSON.parse(text, function (this: object, key: string, value: unknown, context?: { source: string }) {
139
+ if (typeof value === "number") {
140
+ if (context?.source === undefined) throw new Error("JSON numeric source tokens are unavailable");
141
+ let entries = sources.get(this);
142
+ if (entries === undefined) {
143
+ entries = new Map();
144
+ sources.set(this, entries);
145
+ }
146
+ entries.set(key, context.source);
147
+ }
148
+ return value;
149
+ }) as unknown;
150
+ if (isRecord(parsed) && isRecord(parsed.result) && isRecord(parsed.result.structuredContent)) {
151
+ const content = parsed.result.structuredContent;
152
+ // ES2022 typings predate this supported Node runtime API. No custom
153
+ // tokenizer is needed, and the existing incoming-line cap bounds it.
154
+ const rawJSON = (JSON as JSON & { rawJSON(source: string): unknown }).rawJSON;
155
+ const exact = JSON.stringify(content, function (this: object, key: string, value: unknown) {
156
+ const source = sources.get(this)?.get(key);
157
+ return source === undefined ? value : rawJSON(source);
158
+ });
159
+ // Plain JSON evidence must survive cloning and serialization as well.
160
+ // Tag tokens that Number cannot round-trip instead of retaining rounded
161
+ // numbers, Infinity (which serializes to null), or a signless zero.
162
+ parsed.result.structuredContent = JSON.parse(
163
+ JSON.stringify(content, function (this: object, key: string, value: unknown) {
164
+ const source = sources.get(this)?.get(key);
165
+ return source !== undefined && JSON.stringify(value) !== source ? { $literal: source } : value;
166
+ }),
167
+ ) as unknown;
168
+ structuredJson.set(parsed.result, exact);
169
+ }
170
+ } catch (error) {
171
+ return new McpError(
172
+ "protocol",
173
+ `message line is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
174
+ );
175
+ }
176
+ return classifyJsonRpcMessage(parsed);
177
+ }
178
+
179
+ /** Serialize one outbound message as a newline-terminated line. JSON.stringify escapes every newline inside strings. */
180
+ export function encodeJsonRpcMessage(message: JsonRpcRequest | JsonRpcNotification | JsonRpcResponse): Buffer {
181
+ return Buffer.from(`${JSON.stringify(message)}\n`, "utf8");
182
+ }
183
+
184
+ export interface LineFramer {
185
+ /** Accept one chunk and return every frame it completed. After an error frame the framer yields nothing more. */
186
+ push(chunk: Buffer): ProtocolFrame[];
187
+ /** Flush a final unterminated line at end of stream. */
188
+ flush(): ProtocolFrame[];
189
+ /** Bytes held for the line still being assembled. */
190
+ readonly pendingBytes: number;
191
+ /** True once an error frame has been produced. */
192
+ readonly failed: boolean;
193
+ }
194
+
195
+ /**
196
+ * Split a byte stream into newline-delimited messages. A line longer than the
197
+ * cap is refused as soon as its bytes exceed it, before any newline arrives,
198
+ * so an unterminated flood cannot grow the buffer without bound. Blank lines
199
+ * are skipped; a trailing carriage return is tolerated.
200
+ */
201
+ export function createLineFramer(maxLineBytes: number = DEFAULT_MAX_LINE_BYTES): LineFramer {
202
+ const pending: Buffer[] = [];
203
+ let pendingBytes = 0;
204
+ let failed = false;
205
+
206
+ const fail = (message: string): ProtocolFrame[] => {
207
+ failed = true;
208
+ pending.length = 0;
209
+ pendingBytes = 0;
210
+ return [{ kind: "error", error: new McpError("protocol", message) }];
211
+ };
212
+
213
+ const frameLine = (line: Buffer): ProtocolFrame | null => {
214
+ const trimmed = line.length > 0 && line[line.length - 1] === 0x0d ? line.subarray(0, line.length - 1) : line;
215
+ if (trimmed.length === 0) return null;
216
+ const decoded = parseJsonRpcLine(trimmed);
217
+ if (decoded instanceof McpError) return { kind: "error", error: decoded };
218
+ return { kind: "message", message: decoded };
219
+ };
220
+
221
+ return {
222
+ get pendingBytes() {
223
+ return pendingBytes;
224
+ },
225
+ get failed() {
226
+ return failed;
227
+ },
228
+ push(chunk) {
229
+ if (failed) return [];
230
+ const frames: ProtocolFrame[] = [];
231
+ let start = 0;
232
+ for (;;) {
233
+ const newline = chunk.indexOf(0x0a, start);
234
+ if (newline === -1) break;
235
+ const tail = chunk.subarray(start, newline);
236
+ const lineBytes = pendingBytes + tail.length;
237
+ if (lineBytes > maxLineBytes) return fail(`message line exceeds ${maxLineBytes} bytes`);
238
+ const line = pending.length === 0 ? tail : Buffer.concat([...pending, tail], lineBytes);
239
+ pending.length = 0;
240
+ pendingBytes = 0;
241
+ const frame = frameLine(line);
242
+ if (frame !== null) {
243
+ frames.push(frame);
244
+ if (frame.kind === "error") {
245
+ failed = true;
246
+ return frames;
247
+ }
248
+ }
249
+ start = newline + 1;
250
+ }
251
+ if (start < chunk.length) {
252
+ const rest = chunk.subarray(start);
253
+ if (pendingBytes + rest.length > maxLineBytes) {
254
+ frames.push(...fail(`message line exceeds ${maxLineBytes} bytes`));
255
+ return frames;
256
+ }
257
+ pending.push(Buffer.from(rest));
258
+ pendingBytes += rest.length;
259
+ }
260
+ return frames;
261
+ },
262
+ flush() {
263
+ if (failed || pendingBytes === 0) return [];
264
+ const line = Buffer.concat(pending, pendingBytes);
265
+ pending.length = 0;
266
+ pendingBytes = 0;
267
+ const frame = frameLine(line);
268
+ if (frame === null) return [];
269
+ if (frame.kind === "error") failed = true;
270
+ return [frame];
271
+ },
272
+ };
273
+ }
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Explicit trust for project-declared MCP servers. A repository can ship
3
+ * `.clio-coder/mcp.yaml`, and cloning a repository must not launch anything,
4
+ * so a project server runs only once the operator records a trust decision
5
+ * for that exact declaration. The record binds the project root, the server
6
+ * id, and the declaration digest: change the command, arguments, environment,
7
+ * cwd, or timeout and the record is stale until the operator re-trusts it.
8
+ * User-scope declarations are trusted by authorship; they carry no record.
9
+ */
10
+
11
+ import { realpathSync } from "node:fs";
12
+ import path from "node:path";
13
+ import { safeResourceWrite } from "../../../core/safe-resource-write.js";
14
+ import { clioConfigDir } from "../../../core/xdg.js";
15
+ import {
16
+ loadMcpServerConfig,
17
+ type McpConfigDiagnostic,
18
+ type McpServerDeclaration,
19
+ readBoundedFileText,
20
+ } from "./config.js";
21
+
22
+ export const MCP_TRUST_FILENAME = "mcp-trust.json";
23
+ export const MCP_TRUST_VERSION = 1;
24
+
25
+ /** Bounds on the trust file, read on every resolve; a file past either is unusable until repaired. */
26
+ export const MCP_TRUST_CAPS = Object.freeze({
27
+ fileBytes: 1024 * 1024,
28
+ records: 256,
29
+ });
30
+
31
+ export type McpTrustActionClass = "read" | "execute" | "unknown";
32
+ export const MCP_TRUST_ACTION_CLASSES: ReadonlyArray<McpTrustActionClass> = ["read", "execute", "unknown"];
33
+
34
+ export interface McpTrustRecord {
35
+ /** Canonical (realpath) project root the record applies to. */
36
+ projectRoot: string;
37
+ id: string;
38
+ digest: string;
39
+ /** The action class the gateway gives this server's tools. */
40
+ actionClass: McpTrustActionClass;
41
+ trustedAt: string;
42
+ }
43
+
44
+ export interface McpTrustState {
45
+ version: typeof MCP_TRUST_VERSION;
46
+ records: McpTrustRecord[];
47
+ }
48
+
49
+ export type McpTrustStatus =
50
+ | { status: "trusted"; actionClass: McpTrustActionClass }
51
+ | { status: "untrusted"; actionClass: "unknown"; reason: string }
52
+ | { status: "stale"; actionClass: "unknown"; reason: string };
53
+
54
+ export interface ResolvedMcpServer extends McpServerDeclaration {
55
+ trust: McpTrustStatus;
56
+ }
57
+
58
+ export interface McpTrustOptions {
59
+ cwd: string;
60
+ /** Override for the user config directory; defaults to clioConfigDir(). */
61
+ configDir?: string;
62
+ }
63
+
64
+ export interface McpTrustReadResult {
65
+ state: McpTrustState;
66
+ /** Non-empty when the file exists but could not be used; the state is then empty. */
67
+ diagnostics: string[];
68
+ }
69
+
70
+ function isRecord(value: unknown): value is Record<string, unknown> {
71
+ return value !== null && typeof value === "object" && !Array.isArray(value);
72
+ }
73
+
74
+ function isActionClass(value: unknown): value is McpTrustActionClass {
75
+ return typeof value === "string" && (MCP_TRUST_ACTION_CLASSES as ReadonlyArray<string>).includes(value);
76
+ }
77
+
78
+ export function mcpTrustPath(configDir?: string): string {
79
+ return path.join(configDir ?? clioConfigDir(), MCP_TRUST_FILENAME);
80
+ }
81
+
82
+ function canonicalProjectRoot(cwd: string): string {
83
+ const resolved = path.resolve(cwd);
84
+ try {
85
+ return realpathSync(resolved);
86
+ } catch {
87
+ return resolved;
88
+ }
89
+ }
90
+
91
+ function parseTrustState(text: string): McpTrustState | Error {
92
+ let parsed: unknown;
93
+ try {
94
+ parsed = JSON.parse(text) as unknown;
95
+ } catch (error) {
96
+ return new Error(`invalid JSON: ${error instanceof Error ? error.message : String(error)}`);
97
+ }
98
+ if (!isRecord(parsed) || parsed.version !== MCP_TRUST_VERSION) {
99
+ return new Error(`trust state must be a version ${MCP_TRUST_VERSION} object`);
100
+ }
101
+ if (!Array.isArray(parsed.records)) return new Error("trust state records must be an array");
102
+ if (parsed.records.length > MCP_TRUST_CAPS.records) {
103
+ return new Error(`trust state exceeds the ${MCP_TRUST_CAPS.records}-record cap`);
104
+ }
105
+ const records: McpTrustRecord[] = [];
106
+ for (const [index, raw] of parsed.records.entries()) {
107
+ if (!isRecord(raw)) return new Error(`records[${index}] must be an object`);
108
+ for (const field of ["projectRoot", "id", "digest", "trustedAt"] as const) {
109
+ if (typeof raw[field] !== "string" || raw[field].length === 0) {
110
+ return new Error(`records[${index}].${field} must be a non-empty string`);
111
+ }
112
+ }
113
+ if (!isActionClass(raw.actionClass)) {
114
+ return new Error(`records[${index}].actionClass must be one of ${MCP_TRUST_ACTION_CLASSES.join(", ")}`);
115
+ }
116
+ records.push({
117
+ projectRoot: raw.projectRoot as string,
118
+ id: raw.id as string,
119
+ digest: raw.digest as string,
120
+ actionClass: raw.actionClass,
121
+ trustedAt: raw.trustedAt as string,
122
+ });
123
+ }
124
+ return { version: MCP_TRUST_VERSION, records };
125
+ }
126
+
127
+ /**
128
+ * Read the trust file through a bounded read. A missing file is an empty
129
+ * state; an oversized, over-populated, or corrupt one is empty with a
130
+ * diagnostic, and nothing here ever rewrites it.
131
+ */
132
+ export function readMcpTrustState(configDir?: string): McpTrustReadResult {
133
+ const filePath = mcpTrustPath(configDir);
134
+ const empty: McpTrustState = { version: MCP_TRUST_VERSION, records: [] };
135
+ const read = readBoundedFileText(filePath, MCP_TRUST_CAPS.fileBytes);
136
+ if (!read.ok) {
137
+ if (read.reason === "missing") return { state: empty, diagnostics: [] };
138
+ return { state: empty, diagnostics: [`${filePath}: ${read.message}`] };
139
+ }
140
+ const parsed = parseTrustState(read.text);
141
+ if (parsed instanceof Error) return { state: empty, diagnostics: [`${filePath}: ${parsed.message}`] };
142
+ return { state: parsed, diagnostics: [] };
143
+ }
144
+
145
+ /** Persist the state, or name why it would not be readable again under the caps. */
146
+ function writeTrustState(records: ReadonlyArray<McpTrustRecord>, configDir?: string): string | null {
147
+ if (records.length > MCP_TRUST_CAPS.records) {
148
+ return `trust state would exceed the ${MCP_TRUST_CAPS.records}-record cap; untrust servers you no longer use first`;
149
+ }
150
+ const sorted = [...records].sort(
151
+ (left, right) => left.projectRoot.localeCompare(right.projectRoot) || left.id.localeCompare(right.id),
152
+ );
153
+ const text = `${JSON.stringify({ version: MCP_TRUST_VERSION, records: sorted }, null, 2)}\n`;
154
+ if (Buffer.byteLength(text, "utf8") > MCP_TRUST_CAPS.fileBytes) {
155
+ return `trust state would exceed the ${MCP_TRUST_CAPS.fileBytes}-byte cap; untrust servers you no longer use first`;
156
+ }
157
+ safeResourceWrite(mcpTrustPath(configDir), text, { mode: 0o600 });
158
+ return null;
159
+ }
160
+
161
+ function trustStatusFor(server: McpServerDeclaration, projectRoot: string, state: McpTrustState): McpTrustStatus {
162
+ if (server.scope === "user") return { status: "trusted", actionClass: "unknown" };
163
+ const record = state.records.find((entry) => entry.projectRoot === projectRoot && entry.id === server.id);
164
+ if (record === undefined) {
165
+ return {
166
+ status: "untrusted",
167
+ actionClass: "unknown",
168
+ reason: `project-scope server '${server.id}' requires explicit trust: clio-coder mcp trust ${server.id}`,
169
+ };
170
+ }
171
+ if (record.digest !== server.digest) {
172
+ return {
173
+ status: "stale",
174
+ actionClass: "unknown",
175
+ reason: `declaration of '${server.id}' changed (command, args, env, cwd, or timeout) since it was trusted; review it and run clio-coder mcp trust ${server.id} again`,
176
+ };
177
+ }
178
+ return { status: "trusted", actionClass: record.actionClass };
179
+ }
180
+
181
+ export interface ResolvedMcpServers {
182
+ servers: ResolvedMcpServer[];
183
+ diagnostics: McpConfigDiagnostic[];
184
+ /** Trust-file problems, separate from config diagnostics. */
185
+ trustDiagnostics: string[];
186
+ }
187
+
188
+ /** Every declared server with its trust status; the gateway launches only `trusted` entries. */
189
+ export function resolveMcpServers(options: McpTrustOptions): ResolvedMcpServers {
190
+ const loaded = loadMcpServerConfig(options);
191
+ const trust = readMcpTrustState(options.configDir);
192
+ const projectRoot = canonicalProjectRoot(options.cwd);
193
+ return {
194
+ servers: loaded.servers.map((server) => ({ ...server, trust: trustStatusFor(server, projectRoot, trust.state) })),
195
+ diagnostics: loaded.diagnostics,
196
+ trustDiagnostics: trust.diagnostics,
197
+ };
198
+ }
199
+
200
+ export interface TrustMcpServerOptions extends McpTrustOptions {
201
+ id: string;
202
+ actionClass?: McpTrustActionClass;
203
+ now?: () => Date;
204
+ }
205
+
206
+ export type TrustMcpServerResult = { ok: true; record: McpTrustRecord } | { ok: false; message: string };
207
+
208
+ /** Record trust for one project-declared server at its current digest. */
209
+ export function trustMcpServer(options: TrustMcpServerOptions): TrustMcpServerResult {
210
+ const actionClass = options.actionClass ?? "unknown";
211
+ if (!isActionClass(actionClass)) {
212
+ return { ok: false, message: `actionClass must be one of ${MCP_TRUST_ACTION_CLASSES.join(", ")}` };
213
+ }
214
+ const loaded = loadMcpServerConfig(options);
215
+ const server = loaded.servers.find((entry) => entry.id === options.id);
216
+ if (server === undefined) {
217
+ const problems = loaded.diagnostics.map((entry) => `${entry.path}: ${entry.message}`);
218
+ return {
219
+ ok: false,
220
+ message:
221
+ `no declared MCP server with id '${options.id}'` +
222
+ (problems.length > 0 ? `; config diagnostics: ${problems.join("; ")}` : ""),
223
+ };
224
+ }
225
+ if (server.scope !== "project") {
226
+ return { ok: false, message: `server '${options.id}' is a user-scope declaration; it is trusted by authorship` };
227
+ }
228
+ const trust = readMcpTrustState(options.configDir);
229
+ if (trust.diagnostics.length > 0) {
230
+ return { ok: false, message: `trust state is unusable; repair or remove it first: ${trust.diagnostics.join("; ")}` };
231
+ }
232
+ const projectRoot = canonicalProjectRoot(options.cwd);
233
+ const record: McpTrustRecord = {
234
+ projectRoot,
235
+ id: server.id,
236
+ digest: server.digest,
237
+ actionClass,
238
+ trustedAt: (options.now?.() ?? new Date()).toISOString(),
239
+ };
240
+ const records = trust.state.records.filter((entry) => !(entry.projectRoot === projectRoot && entry.id === server.id));
241
+ records.push(record);
242
+ const refused = writeTrustState(records, options.configDir);
243
+ if (refused !== null) return { ok: false, message: refused };
244
+ return { ok: true, record };
245
+ }
246
+
247
+ export type UntrustMcpServerResult = { ok: true; removed: boolean } | { ok: false; message: string };
248
+
249
+ /** Remove the trust record for one server in this project, whether or not it is still declared. */
250
+ export function untrustMcpServer(options: McpTrustOptions & { id: string }): UntrustMcpServerResult {
251
+ const trust = readMcpTrustState(options.configDir);
252
+ if (trust.diagnostics.length > 0) {
253
+ return { ok: false, message: `trust state is unusable; repair or remove it first: ${trust.diagnostics.join("; ")}` };
254
+ }
255
+ const projectRoot = canonicalProjectRoot(options.cwd);
256
+ const records = trust.state.records.filter((entry) => !(entry.projectRoot === projectRoot && entry.id === options.id));
257
+ const removed = records.length !== trust.state.records.length;
258
+ if (removed) {
259
+ const refused = writeTrustState(records, options.configDir);
260
+ if (refused !== null) return { ok: false, message: refused };
261
+ }
262
+ return { ok: true, removed };
263
+ }
@@ -482,7 +482,10 @@ export function formatDoctorReport(findings: DoctorFinding[]): string {
482
482
  * to the durable preflight store that dispatch placement consults. A failing
483
483
  * node is a WARN (ineligible for placement), never fatal.
484
484
  */
485
- export async function runDoctorFleetChecks(projectRoot: string = process.cwd()): Promise<DoctorFinding[]> {
485
+ export async function runDoctorFleetChecks(
486
+ projectRoot: string = process.cwd(),
487
+ options: { fix?: boolean } = {},
488
+ ): Promise<DoctorFinding[]> {
486
489
  let settings: ReturnType<typeof readSettings>;
487
490
  try {
488
491
  settings = readSettings();
@@ -491,7 +494,7 @@ export async function runDoctorFleetChecks(projectRoot: string = process.cwd()):
491
494
  }
492
495
  const nodes = settings.fleet?.nodes ?? [];
493
496
  if (nodes.length === 0) return [];
494
- const { runFleetNodePreflight } = await import("../dispatch/fleet-preflight.js");
497
+ const { recordFleetPreflight, runFleetNodePreflight } = await import("../dispatch/fleet-preflight.js");
495
498
  // Endpoint facts are per node. Every configured target is probed from every
496
499
  // node, because a `localhost` URL names a different machine on each one and
497
500
  // an orchestrator-side probe would describe none of them.
@@ -502,12 +505,23 @@ export async function runDoctorFleetChecks(projectRoot: string = process.cwd()):
502
505
  ...(target.defaultModel !== undefined ? { wireModelId: target.defaultModel } : {}),
503
506
  }));
504
507
  const records = await Promise.all(nodes.map((node) => runFleetNodePreflight(node, projectRoot, { targets })));
508
+ // Placement admits a node only from a stored record. Plain doctor observes;
509
+ // --fix is the run that may write state, so it is the one that records.
510
+ let recorded = options.fix === true;
511
+ if (recorded) {
512
+ try {
513
+ recordFleetPreflight(records);
514
+ } catch {
515
+ recorded = false;
516
+ }
517
+ }
518
+ const admission = recorded ? "recorded for dispatch" : "not recorded, run doctor --fix to admit this node";
505
519
  return records.map((record) => ({
506
520
  ok: true,
507
521
  level: record.ok ? "ok" : "warn",
508
522
  name: `fleet node ${record.nodeId}`,
509
523
  detail: record.ok
510
- ? `eligible: ${record.host} clio ${record.remoteVersion ?? "(custom entry)"}, path parity for ${record.projectRoot}, ${
524
+ ? `eligible (${admission}): ${record.host} clio ${record.remoteVersion ?? "(custom entry)"}, path parity for ${record.projectRoot}, ${
511
525
  record.targets.filter((fact) => fact.reachable === "true").length
512
526
  }/${record.targets.length} targets reachable from the node`
513
527
  : `ineligible: ${record.detail ?? "preflight failed"}`,
@@ -11,16 +11,12 @@
11
11
  * created, tracked in `pane-registry.ts` and tagged with the `clio_coder_owner`
12
12
  * metadata token so `clio-coder doctor` can find orphans. The one documented
13
13
  * exception is Clio's own hosting pane in guest mode, which `reportSelf`
14
- * writes to under SA-3 of the v0.4.0 cycle plan.
14
+ * writes to without requiring Clio ownership.
15
15
  *
16
- * What is deliberately absent: per-run viewer panes. The v0.4.0 phase 3/4
17
- * integration opened a pane per dispatched run in a hidden Fleet tab, with a
18
- * focus ladder, run-state reporting, and resume adoption keyed on run ids. All
19
- * of that projected fleet state the native surfaces already show onto panes
20
- * nobody had asked for. The one run-viewing surface is now the workers-view
21
- * watch pane (src/interactive/watch-pane.ts): a single utility pane following
22
- * a selection file, opened on operator demand and retargeted by file writes
23
- * that never touch this socket.
16
+ * Runs are viewed through the workers-view watch pane
17
+ * (src/interactive/watch-pane.ts). This single utility pane follows a selection
18
+ * file, opens on operator demand, and is retargeted by file writes that never
19
+ * touch this socket. Dispatch does not create per-run viewer panes.
24
20
  */
25
21
 
26
22
  import type { DomainContract } from "../../core/domain-loader.js";
@@ -8,7 +8,7 @@
8
8
  * contract test pins that by making `net.connect` throw for the duration of the
9
9
  * call.
10
10
  *
11
- * Embedded mode resolves to `none` until Phase 5 lands the session bootstrap.
11
+ * Embedded pane hosting is not implemented, so it resolves to `none`.
12
12
  * Asking for it is not an error, but it is a refusal rather than a quiet
13
13
  * degrade: the detection carries `refused: true`, the boot prints the reason on
14
14
  * stderr, and doctor's mode row warns. A session that asked for panes and got
@@ -14,7 +14,7 @@ import { detectMux, type MuxEnablement } from "./detect.js";
14
14
  import type { MuxLog } from "./types.js";
15
15
 
16
16
  export interface MuxDomainOptions {
17
- /** `off` skips detection entirely; `embedded` degrades to `none` until phase 5. */
17
+ /** `off` skips detection; unsupported `embedded` hosting is refused as `none`. */
18
18
  enabled?: MuxEnablement;
19
19
  env?: NodeJS.ProcessEnv;
20
20
  log?: MuxLog;
@@ -1,12 +1,10 @@
1
1
  /**
2
2
  * Protocol floors for the wire methods that are not universal.
3
3
  *
4
- * Phase 1 recorded `protocol` and `version` from the `ping` handshake and gated
5
- * nothing on them, because every method phase 1 used exists across the whole
6
- * protocol range Clio cares about. Phase 3 adds two that do not, and Phase 4
7
- * adds the worktree family: a herdr old
8
- * enough to predate them answers `invalid_request`, and the honest response is
9
- * to take the documented fallback rather than to log a failure per call.
4
+ * The `ping` handshake records the server protocol and version. Notification,
5
+ * pane-control, layout, and worktree methods require the protocol floors below.
6
+ * Older servers answer `invalid_request`, so callers check support and take
7
+ * the documented fallback before making those calls.
10
8
  *
11
9
  * The floors are protocol introductions checked against herdr's changelog and
12
10
  * then re-verified with `herdr api schema --json` on the released artifacts
@@ -24,7 +22,7 @@
24
22
 
25
23
  import type { MuxServerInfo } from "./types.js";
26
24
 
27
- /** Wire methods this file gates. Phase 1 methods are unconditional and absent here. */
25
+ /** Wire methods with explicit protocol floors. Basic discovery methods are unconditional. */
28
26
  export type MuxGatedMethod =
29
27
  | "notification.show"
30
28
  | "pane.rename"
@@ -175,9 +175,9 @@ export interface MuxWorktreeRemovedResult {
175
175
  }
176
176
 
177
177
  /**
178
- * The domain-facing surface. Phase 1 covers exactly the wire methods spec 4.3
179
- * lists for this phase, plus `pane.send_text`, `pane.report_agent`,
180
- * `pane.report_metadata` (see the notes on those methods below).
178
+ * The domain-facing wire surface covers discovery, workspace and pane control,
179
+ * notifications, layouts, worktrees, and agent metadata. Individual methods
180
+ * document their protocol requirements and behavior below.
181
181
  */
182
182
  export interface MuxClient {
183
183
  readonly socketPath: string;
@@ -2,8 +2,8 @@
2
2
  * Accountability read model. A pure aggregation over the sidecar evidence index
3
3
  * (see evidence-index.ts) that yields a rolling first-pass-success rate and a
4
4
  * failure-cause tag histogram for the session. This is presentation-grade
5
- * read-only data: it recomputes nothing, it only folds the rows that Slice 2
6
- * already wrote when each dispatch run finalized. Those rows are
5
+ * read-only data: it recomputes nothing, it only folds the rows written
6
+ * when each dispatch run finalized. Those rows are
7
7
  * forensic-derived and are the authority for user-visible first-pass-success
8
8
  * rates. The receipt summary is the conservative integrity-covered snapshot,
9
9
  * so a false receipt summary and a true forensic row is an intentional