@iowarp/clio-coder 0.4.1 → 0.4.3

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 (604) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/CONTRIBUTING.md +142 -52
  3. package/README.md +434 -473
  4. package/SECURITY.md +2 -1
  5. package/dist/{acp-ZILU3AUO.js → acp-H2NGRPWO.js} +12 -12
  6. package/dist/{agents-HYWGBGQR.js → agents-TL5LLUQP.js} +56 -55
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-N3QT7CBO.js → auth-E5SW4HMS.js} +23 -21
  9. package/dist/builtins-IA7V7FUC.js +22 -0
  10. package/dist/{chunk-7RY5VZPH.js → chunk-2APPQIER.js} +8 -8
  11. package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
  12. package/dist/{chunk-JA5QWE4Z.js → chunk-2UG5F4C5.js} +1973 -1664
  13. package/dist/{chunk-5YHDIDBP.js → chunk-2UH2KFUP.js} +2 -2
  14. package/dist/{chunk-CTJ4RNAA.js → chunk-2VIKGWFZ.js} +2 -2
  15. package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
  16. package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
  17. package/dist/chunk-3EBYEESD.js +314 -0
  18. package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
  19. package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
  20. package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
  21. package/dist/chunk-4UVU7BJ5.js +39 -0
  22. package/dist/{chunk-VKRH2TCS.js → chunk-4WR7VSYB.js} +2 -2
  23. package/dist/{chunk-BBTJOK6Y.js → chunk-54CBCGIR.js} +5 -5
  24. package/dist/{chunk-AP73CFDC.js → chunk-5ICU3EUH.js} +2 -2
  25. package/dist/chunk-5MEZN6CB.js +1334 -0
  26. package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
  27. package/dist/{chunk-ABLSQ6JX.js → chunk-64I3JVYM.js} +8 -2
  28. package/dist/{chunk-AFKWHWXF.js → chunk-6PTFB5VS.js} +39 -22
  29. package/dist/{chunk-VN3SHNBN.js → chunk-7DICMOS6.js} +2 -2
  30. package/dist/chunk-7DRAWPTZ.js +360 -0
  31. package/dist/chunk-7E7I3WLS.js +3762 -0
  32. package/dist/{chunk-BJGUKIG4.js → chunk-7ZYNNDKC.js} +7 -7
  33. package/dist/{chunk-XKA2ICR3.js → chunk-AF4YM7Z4.js} +652 -252
  34. package/dist/{chunk-GVQJ5CCZ.js → chunk-AX2THNSA.js} +12 -12
  35. package/dist/{chunk-IG7BCQBA.js → chunk-B4OAX3SI.js} +65 -3
  36. package/dist/{chunk-TD3PGPQA.js → chunk-B4VEBZKF.js} +3 -3
  37. package/dist/{chunk-74YWRRU5.js → chunk-BEPZRGGU.js} +10 -10
  38. package/dist/{chunk-FEFIFZTL.js → chunk-CE5AX47J.js} +2 -2
  39. package/dist/{chunk-UAPGZHYC.js → chunk-DWUOQKRU.js} +25 -11
  40. package/dist/{chunk-THYWACCR.js → chunk-E3TPLWFX.js} +3 -3
  41. package/dist/{chunk-7EPLI7VL.js → chunk-EKCHAPYA.js} +2 -2
  42. package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
  43. package/dist/{chunk-PJJ6MY27.js → chunk-F5JHEYZM.js} +7 -7
  44. package/dist/{chunk-6CCS4G3W.js → chunk-FTMGRKEF.js} +3 -3
  45. package/dist/{chunk-SINK3QR6.js → chunk-G76U63X4.js} +17 -17
  46. package/dist/{chunk-EIMVLWB3.js → chunk-GHS5EBTQ.js} +64 -9
  47. package/dist/{chunk-QMXC4JB7.js → chunk-GI7YYQ3F.js} +187 -1419
  48. package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
  49. package/dist/{chunk-6HMJX2VU.js → chunk-GWZNEVM2.js} +44 -12
  50. package/dist/chunk-GYV6VZOC.js +26 -0
  51. package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
  52. package/dist/{chunk-UXN6JT4W.js → chunk-HEQY7ZFI.js} +3 -3
  53. package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
  54. package/dist/{chunk-GCSMB2KY.js → chunk-I7ZPNEJM.js} +145 -102
  55. package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
  56. package/dist/{chunk-QTFGO774.js → chunk-IGLP3ODT.js} +29 -16
  57. package/dist/chunk-IJNZMHLA.js +101 -0
  58. package/dist/{chunk-BDPT6GTK.js → chunk-INY6HTFL.js} +7 -7
  59. package/dist/{chunk-PBP4B7XR.js → chunk-IUE3Y34X.js} +2 -2
  60. package/dist/{chunk-6NJQITNH.js → chunk-IWT4SF4R.js} +6 -3
  61. package/dist/{chunk-R23Z6K6I.js → chunk-JDAY6FIL.js} +19 -19
  62. package/dist/chunk-JEQ3XTHC.js +42 -0
  63. package/dist/{chunk-FSP7CMNU.js → chunk-JGRC33J2.js} +50 -4
  64. package/dist/{chunk-TVH4ONAM.js → chunk-JKKCYP3C.js} +10 -10
  65. package/dist/{chunk-HJWWJ6IL.js → chunk-JSC3U7TI.js} +16 -4
  66. package/dist/{chunk-C537JADH.js → chunk-KK4JZPBQ.js} +19 -141
  67. package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
  68. package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
  69. package/dist/{chunk-6DWBAZ5U.js → chunk-L47TF46W.js} +5 -7
  70. package/dist/{chunk-HUAS7ITX.js → chunk-LDJG7DW3.js} +91 -42
  71. package/dist/{chunk-CDNVLKUX.js → chunk-LLDJM5XK.js} +13 -7
  72. package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
  73. package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
  74. package/dist/{chunk-VKFQTNDV.js → chunk-MUW2BDDH.js} +4 -4
  75. package/dist/{chunk-E67WX76H.js → chunk-MWUZBSAQ.js} +104 -152
  76. package/dist/{chunk-OJTRZGR3.js → chunk-N2Z7HLVY.js} +21 -21
  77. package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
  78. package/dist/{chunk-FYUN5KZ3.js → chunk-NIQJ66N4.js} +21 -21
  79. package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
  80. package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
  81. package/dist/{chunk-VEGN6WIQ.js → chunk-O5CVSAG5.js} +3 -3
  82. package/dist/{chunk-MOPSG2X7.js → chunk-OML5D5V5.js} +8 -8
  83. package/dist/{chunk-2VG7KLYV.js → chunk-PAJQJ7BS.js} +5816 -3255
  84. package/dist/{chunk-ZW55JB7N.js → chunk-PUVDKJ2Y.js} +2 -2
  85. package/dist/{chunk-BTGG6BG2.js → chunk-QWGDJJYJ.js} +158 -19
  86. package/dist/chunk-R6Q67RJH.js +134 -0
  87. package/dist/{chunk-ZJLUDYFY.js → chunk-RRNP2ANY.js} +6 -6
  88. package/dist/{chunk-PVAMAVBB.js → chunk-RSJ25QSL.js} +102 -2
  89. package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
  90. package/dist/chunk-SKHCAU7K.js +385 -0
  91. package/dist/chunk-SZAA6XDG.js +30 -0
  92. package/dist/{chunk-J4HBWF6Y.js → chunk-TM6LQDI3.js} +131 -28
  93. package/dist/chunk-UOIZ7DA4.js +41 -0
  94. package/dist/{chunk-MA3H6DM5.js → chunk-UPZU6GE4.js} +25 -3
  95. package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
  96. package/dist/{chunk-N5UK64DP.js → chunk-V2ANDPVT.js} +4 -4
  97. package/dist/{chunk-AK5XEFVZ.js → chunk-VA5FNYMT.js} +26 -13
  98. package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
  99. package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
  100. package/dist/{chunk-QKIFBZKT.js → chunk-VW6DOEDG.js} +497 -81
  101. package/dist/{chunk-SCYB3HA4.js → chunk-W6RRQCPQ.js} +63 -19
  102. package/dist/{chunk-2NM363SV.js → chunk-WBKFA554.js} +10 -10
  103. package/dist/{chunk-R32CLGZ6.js → chunk-WCXUNS7U.js} +82 -21
  104. package/dist/{chunk-GPPB3JBE.js → chunk-WRBAGUNF.js} +3 -3
  105. package/dist/{chunk-IXJT6DCX.js → chunk-XIVNBFZS.js} +85 -30
  106. package/dist/{chunk-UEDMSP56.js → chunk-XPWWI35G.js} +417 -201
  107. package/dist/chunk-XRZT5WY5.js +47 -0
  108. package/dist/{chunk-3QSOM6PA.js → chunk-Y3CBHOR6.js} +2 -2
  109. package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
  110. package/dist/{chunk-AKB4GYDL.js → chunk-YQWYVTMC.js} +5 -5
  111. package/dist/{chunk-6I5ILFOF.js → chunk-ZA4VCIGV.js} +3 -3
  112. package/dist/{chunk-7OBGU7UB.js → chunk-ZDN3Y73Y.js} +12 -18
  113. package/dist/{chunk-3I5NY75V.js → chunk-ZWPRK62N.js} +8 -5
  114. package/dist/cli/index.js +41 -39
  115. package/dist/{clio-IT3G3VQH.js → clio-CMMK4KRR.js} +9 -9
  116. package/dist/{code-nav-RK6S7F6E.js → code-nav-MDZNQS33.js} +89 -21
  117. package/dist/{components-UBWCQSRW.js → components-UCUQ4QXW.js} +4 -4
  118. package/dist/{config-3QZRWZJF.js → config-SVM5P5YI.js} +131 -84
  119. package/dist/{configure-FL7Y3KJF.js → configure-LE3IK2TJ.js} +28 -26
  120. package/dist/{context-5HE7ODYK.js → context-2OHRKS42.js} +69 -64
  121. package/dist/{context-KYQFRVDC.js → context-E3VC7RX5.js} +15 -11
  122. package/dist/{context-XNHL75JV.js → context-VNCR7KAG.js} +93 -65
  123. package/dist/{context-clear-N545L53A.js → context-clear-BW4O37TG.js} +64 -60
  124. package/dist/context-map-COB37XXN.js +505 -0
  125. package/dist/{context-working-set-QHKXSV2F.js → context-working-set-VDS25HXZ.js} +19 -18
  126. package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-5AHT53RF.js} +93 -82
  127. package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
  128. package/dist/{doctor-ZGPEGHIP.js → doctor-WNNVO6FY.js} +48 -47
  129. package/dist/{eval-GXLL44RD.js → eval-7G7SGAYO.js} +287 -115
  130. package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-Y6QRFOH5.js} +4 -4
  131. package/dist/{evidence-HWLBRH3Q.js → evidence-VD6736FQ.js} +67 -64
  132. package/dist/{evolve-FTZBMNVW.js → evolve-AL3NGVRL.js} +65 -62
  133. package/dist/{extensions-VHRBEID7.js → extensions-MOVJ32NM.js} +9 -7
  134. package/dist/{fleet-CKZHJWZJ.js → fleet-QZHUMAGI.js} +114 -111
  135. package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-BAYT5FJZ.js} +10 -10
  136. package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-IREVMRU4.js} +7 -6
  137. package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-YCTT3HTI.js} +22 -19
  138. package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-QVJTDAVB.js} +58 -55
  139. package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-25QAFPK4.js} +4 -4
  140. package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-5O57AAJ7.js} +26 -23
  141. package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-CPH2W2T6.js} +59 -56
  142. package/dist/{fleet-view-WAMJYNDT.js → fleet-view-SWBR3VGQ.js} +58 -55
  143. package/dist/{init-5XQRBOFV.js → init-J477LKZH.js} +82 -79
  144. package/dist/{interop-34TVO25M.js → interop-3FCM6XLG.js} +11 -11
  145. package/dist/{library-3QY6KF57.js → library-QUQEIUG6.js} +30 -27
  146. package/dist/{memory-L4UTIIIW.js → memory-SGGSEP65.js} +67 -64
  147. package/dist/{models-ZVX3QOWE.js → models-HEKUAXXK.js} +53 -46
  148. package/dist/{monitor-CEKVSYTS.js → monitor-HKU57TYQ.js} +63 -60
  149. package/dist/{orchestrator-77BAP6BC.js → orchestrator-VDFAEFAI.js} +1831 -1057
  150. package/dist/{panes-7STHOAUJ.js → panes-DN2SSFOH.js} +5 -5
  151. package/dist/{panes-SHAUIRXY.js → panes-TALGNPZT.js} +29 -14
  152. package/dist/{paths-L7LGY6RN.js → paths-NBMFAIEZ.js} +5 -5
  153. package/dist/reset-EAJFFJVB.js +344 -0
  154. package/dist/{resources-74GKTLSF.js → resources-OVKSEFVE.js} +29 -20
  155. package/dist/{run-HBAUJNNZ.js → run-7DP7ZF2J.js} +120 -115
  156. package/dist/{share-G3APVLVP.js → share-WML67FT3.js} +32 -27
  157. package/dist/{skills-35HHUKCR.js → skills-SG662R2K.js} +41 -31
  158. package/dist/{skills-eval-QN4HSHDC.js → skills-eval-VVZEUU46.js} +78 -77
  159. package/dist/{skills-inventory-J357J34F.js → skills-inventory-I2E23GET.js} +23 -20
  160. package/dist/{slash-commands-JZZCQA32.js → slash-commands-S7MBJDQK.js} +40 -36
  161. package/dist/{steer-XAVHJM22.js → steer-2LQOMCPB.js} +3 -3
  162. package/dist/{support-U7QOWY26.js → support-CC2UJBJ6.js} +6 -6
  163. package/dist/{targets-DSM6CY3M.js → targets-4QC3HIEW.js} +54 -54
  164. package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-TUHIJ6Y2.js} +5 -5
  165. package/dist/{tools-MKNWVPBH.js → tools-TFGJICCU.js} +10 -10
  166. package/dist/{trace-ECQ7TIYZ.js → trace-FXMXUZUF.js} +55 -7
  167. package/dist/uninstall-5PEVOE5B.js +408 -0
  168. package/dist/upgrade-M4WXY6KN.js +303 -0
  169. package/dist/{usage-X52N3IDJ.js → usage-N7ZNVLEM.js} +151 -104
  170. package/dist/{verifiers-EJTVVSMA.js → verifiers-DJTP4XX6.js} +15 -15
  171. package/dist/{verify-YJL6XET2.js → verify-RWE4PPEK.js} +9 -9
  172. package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
  173. package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-C7IQOXSP.js} +89 -86
  174. package/dist/{with-panes-OBOBFIIR.js → with-panes-4GCGSL7J.js} +53 -257
  175. package/dist/worker/entry.js +90 -74
  176. package/docs/README.md +176 -81
  177. package/docs/{acp.md → architecture/acp.md} +36 -20
  178. package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
  179. package/docs/{architecture.md → architecture/architecture.md} +43 -22
  180. package/docs/{artifact-placement.md → architecture/artifact-placement.md} +27 -23
  181. package/docs/architecture/artifact-versions.md +90 -0
  182. package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
  183. package/docs/{context-engine.md → architecture/context-engine.md} +29 -25
  184. package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
  185. package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
  186. package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
  187. package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
  188. package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
  189. package/docs/{model-catalog.md → architecture/model-catalog.md} +61 -27
  190. package/docs/{observability.md → architecture/observability.md} +38 -14
  191. package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
  192. package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +57 -20
  193. package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +99 -25
  194. package/docs/{safety-model.md → architecture/safety-model.md} +35 -20
  195. package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
  196. package/docs/architecture/time-conventions.md +125 -0
  197. package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
  198. package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
  199. package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
  200. package/docs/{built-in-agents.md → guide/built-in-agents.md} +65 -35
  201. package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +66 -61
  202. package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +323 -297
  203. package/docs/guide/configuration-reference.md +1163 -0
  204. package/docs/{environment-variables.md → guide/environment-variables.md} +33 -28
  205. package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
  206. package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
  207. package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
  208. package/docs/{glossary.md → guide/glossary.md} +14 -11
  209. package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +81 -17
  210. package/docs/guide/panes-and-files.md +290 -0
  211. package/docs/{proactive-memory.md → guide/proactive-memory.md} +131 -107
  212. package/docs/{resource-library.md → guide/resource-library.md} +13 -4
  213. package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +25 -3
  214. package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
  215. package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
  216. package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
  217. package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
  218. package/docs/process/development-pipeline.md +152 -0
  219. package/docs/process/documentation-coverage.md +100 -0
  220. package/docs/process/documentation-guide.md +187 -0
  221. package/docs/{eval-runner.md → process/eval-runner.md} +108 -53
  222. package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
  223. package/docs/{evolution.md → process/evolution.md} +2 -2
  224. package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
  225. package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
  226. package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
  227. package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
  228. package/evals/README.md +2 -2
  229. package/evals/behavioral-model.yaml +3 -2
  230. package/package.json +10 -8
  231. package/skills/README.md +52 -41
  232. package/skills/coding/ast-grep/SKILL.md +102 -31
  233. package/skills/coding/ast-grep/evals.md +26 -0
  234. package/skills/coding/coding-standards/SKILL.md +41 -6
  235. package/skills/coding/coding-standards/evals.md +23 -0
  236. package/skills/coding/prototype/SKILL.md +88 -29
  237. package/skills/coding/prototype/evals.md +19 -0
  238. package/skills/coding/tdd/SKILL.md +81 -54
  239. package/skills/coding/tdd/evals.md +20 -0
  240. package/skills/context/context-handoff/SKILL.md +44 -3
  241. package/skills/context/context-handoff/evals.md +44 -0
  242. package/skills/context/context-prime/SKILL.md +46 -16
  243. package/skills/context/context-prime/evals.md +45 -0
  244. package/skills/git/branch-closeout/SKILL.md +132 -0
  245. package/skills/git/branch-closeout/evals.md +133 -0
  246. package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
  247. package/skills/git/file-ticket/SKILL.md +78 -64
  248. package/skills/git/file-ticket/assets/issue-template.md +22 -0
  249. package/skills/git/file-ticket/evals.md +31 -26
  250. package/skills/git/file-ticket/references/issue-discovery.md +49 -0
  251. package/skills/git/fix-issue/SKILL.md +88 -65
  252. package/skills/git/fix-issue/evals.md +35 -31
  253. package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
  254. package/skills/git/resolve-merge-conflicts/SKILL.md +101 -52
  255. package/skills/git/resolve-merge-conflicts/evals.md +52 -25
  256. package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
  257. package/skills/git/ship/SKILL.md +103 -67
  258. package/skills/git/ship/assets/pr-template.md +21 -0
  259. package/skills/git/ship/evals.md +44 -28
  260. package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
  261. package/skills/git/worktree-create/SKILL.md +80 -50
  262. package/skills/git/worktree-create/evals.md +40 -33
  263. package/skills/git/worktree-create/references/worktree-setup.md +62 -66
  264. package/skills/git/worktree-merge/SKILL.md +112 -65
  265. package/skills/git/worktree-merge/evals.md +42 -34
  266. package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
  267. package/skills/meta/clio-coder-dev/SKILL.md +9 -5
  268. package/skills/meta/clio-coder-dev/evals.md +3 -2
  269. package/skills/meta/clio-coder-test/SKILL.md +102 -95
  270. package/skills/meta/clio-coder-test/evals.md +9 -4
  271. package/skills/meta/clio-coder-test/references/harness.md +100 -124
  272. package/skills/meta/clio-coder-test/references/test-map.md +77 -50
  273. package/skills/meta/credentials/SKILL.md +2 -2
  274. package/skills/meta/find-skills/SKILL.md +2 -2
  275. package/skills/meta/herdr/SKILL.md +2 -2
  276. package/skills/meta/skill-craft/SKILL.md +22 -16
  277. package/skills/planning/archify/SKILL.md +196 -0
  278. package/skills/planning/archify/evals.md +65 -0
  279. package/skills/planning/architecture/SKILL.md +62 -13
  280. package/skills/planning/architecture/evals.md +65 -0
  281. package/skills/planning/backlog/SKILL.md +131 -15
  282. package/skills/planning/backlog/evals.md +142 -0
  283. package/skills/planning/prd/SKILL.md +47 -7
  284. package/skills/planning/prd/evals.md +54 -0
  285. package/skills/planning/product-intent/SKILL.md +58 -3
  286. package/skills/planning/product-intent/evals.md +70 -0
  287. package/skills/planning/tech-spec/SKILL.md +54 -3
  288. package/skills/planning/tech-spec/evals.md +73 -0
  289. package/skills/registry.yaml +70 -62
  290. package/skills/remote.yaml +13 -0
  291. package/skills/research/arxiv-literature/SKILL.md +77 -19
  292. package/skills/research/arxiv-literature/evals.md +50 -0
  293. package/skills/research/experiment-protocol/SKILL.md +21 -2
  294. package/skills/research/experiment-protocol/evals.md +23 -0
  295. package/skills/research/scientific-debugging/SKILL.md +24 -2
  296. package/skills/research/scientific-debugging/evals.md +18 -0
  297. package/skills/research/scientific-modernization/SKILL.md +27 -2
  298. package/skills/research/scientific-modernization/evals.md +27 -0
  299. package/skills/skill-marketplace.json +97 -62
  300. package/skills/workflow/cut-it/SKILL.md +66 -6
  301. package/skills/workflow/cut-it/evals.md +101 -0
  302. package/skills/workflow/design-council/SKILL.md +118 -28
  303. package/skills/workflow/design-council/evals.md +161 -0
  304. package/skills/workflow/grill-me/SKILL.md +87 -11
  305. package/skills/workflow/grill-me/evals.md +153 -0
  306. package/skills/workflow/workflow-distiller/SKILL.md +77 -18
  307. package/skills/workflow/workflow-distiller/evals.md +118 -0
  308. package/src/cli/args.ts +2 -2
  309. package/src/cli/bootstrap-generate.ts +1 -1
  310. package/src/cli/config-inspect.ts +65 -12
  311. package/src/cli/configure-interop.ts +105 -13
  312. package/src/cli/configure-oauth.ts +57 -0
  313. package/src/cli/configure-onboarding.ts +980 -0
  314. package/src/cli/configure-target.ts +594 -0
  315. package/src/cli/configure.ts +1082 -532
  316. package/src/cli/context-map.ts +114 -0
  317. package/src/cli/context.ts +4 -0
  318. package/src/cli/docs.ts +22 -14
  319. package/src/cli/doctor-naming.ts +5 -5
  320. package/src/cli/doctor-toolchain.ts +3 -3
  321. package/src/cli/eval.ts +1 -2
  322. package/src/cli/extensions.ts +2 -1
  323. package/src/cli/fleet.ts +1 -1
  324. package/src/cli/index.ts +3 -1
  325. package/src/cli/internal-dispatch.ts +3 -4
  326. package/src/cli/lifecycle-presenter.ts +436 -0
  327. package/src/cli/models.ts +10 -2
  328. package/src/cli/modes/print.ts +5 -1
  329. package/src/cli/panes.ts +19 -5
  330. package/src/cli/reset.ts +228 -106
  331. package/src/cli/run.ts +9 -4
  332. package/src/cli/select.ts +664 -0
  333. package/src/cli/share.ts +5 -1
  334. package/src/cli/skills-eval.ts +3 -3
  335. package/src/cli/skills.ts +9 -2
  336. package/src/cli/targets.ts +5 -6
  337. package/src/cli/trace.ts +55 -4
  338. package/src/cli/uninstall.ts +233 -165
  339. package/src/cli/upgrade.ts +204 -149
  340. package/src/cli/usage.ts +86 -27
  341. package/src/cli/validate-model.ts +3 -3
  342. package/src/cli/wiki-generate.ts +1 -1
  343. package/src/core/artifact-paths.ts +1 -1
  344. package/src/core/bash-exec.ts +131 -86
  345. package/src/core/bus-events.ts +51 -6
  346. package/src/core/config.ts +61 -1
  347. package/src/core/defaults.ts +7 -4
  348. package/src/core/dispatch-outcome.ts +16 -0
  349. package/src/core/external-diagnostic.ts +44 -0
  350. package/src/core/gateway-routing.ts +157 -0
  351. package/src/core/guardrails.ts +10 -49
  352. package/src/core/prompt-hint.ts +9 -0
  353. package/src/core/safe-exec.ts +17 -2
  354. package/src/core/skill-activation.ts +89 -2
  355. package/src/domains/agents/builtins/architect.md +2 -3
  356. package/src/domains/agents/builtins/coder.md +3 -2
  357. package/src/domains/agents/builtins/debugger.md +2 -2
  358. package/src/domains/agents/builtins/documenter.md +2 -2
  359. package/src/domains/agents/builtins/git-master.md +1 -1
  360. package/src/domains/agents/builtins/oracle.md +1 -1
  361. package/src/domains/agents/builtins/provenance.md +1 -1
  362. package/src/domains/agents/builtins/researcher.md +1 -1
  363. package/src/domains/agents/builtins/scout.md +1 -1
  364. package/src/domains/agents/builtins/tester.md +2 -2
  365. package/src/domains/agents/builtins/verifier.md +2 -2
  366. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  367. package/src/domains/agents/builtins/world-knowledge.md +31 -0
  368. package/src/domains/agents/catalog.ts +13 -15
  369. package/src/domains/agents/contract.ts +2 -0
  370. package/src/domains/agents/extension.ts +23 -1
  371. package/src/domains/agents/result-contract.ts +70 -0
  372. package/src/domains/config/keybindings.ts +8 -0
  373. package/src/domains/context/extension.ts +0 -3
  374. package/src/domains/context/wiki/map-seed.ts +589 -0
  375. package/src/domains/context/wiki/plan.ts +2 -2
  376. package/src/domains/context/working-set/path-index.ts +1 -0
  377. package/src/domains/dispatch/admission.ts +29 -0
  378. package/src/domains/dispatch/agent-candidates.ts +10 -0
  379. package/src/domains/dispatch/budget-envelope.ts +86 -1
  380. package/src/domains/dispatch/capability-match.ts +11 -0
  381. package/src/domains/dispatch/capacity-lease.ts +17 -0
  382. package/src/domains/dispatch/contract.ts +11 -1
  383. package/src/domains/dispatch/extension.ts +237 -49
  384. package/src/domains/dispatch/host-verification.ts +435 -39
  385. package/src/domains/dispatch/intent-requirements.ts +10 -0
  386. package/src/domains/dispatch/intent.ts +18 -1
  387. package/src/domains/dispatch/path-scope.ts +235 -24
  388. package/src/domains/dispatch/run-event-journal.ts +4 -15
  389. package/src/domains/dispatch/state.ts +2 -3
  390. package/src/domains/dispatch/transport.ts +45 -21
  391. package/src/domains/dispatch/types.ts +58 -3
  392. package/src/domains/dispatch/worker-model-metadata.ts +38 -0
  393. package/src/domains/eval/artifacts/store.ts +5 -0
  394. package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
  395. package/src/domains/eval/metrics/token-stream.ts +201 -31
  396. package/src/domains/eval/metrics/tracked.ts +40 -4
  397. package/src/domains/eval/runners/clio-run.ts +5 -2
  398. package/src/domains/eval/schema/suite.ts +28 -0
  399. package/src/domains/eval/schema/verdict.ts +2 -2
  400. package/src/domains/eval/store.ts +8 -1
  401. package/src/domains/eval/suites/resolve.ts +13 -1
  402. package/src/domains/eval/suites/run.ts +24 -3
  403. package/src/domains/evidence/trust-status.ts +10 -1
  404. package/src/domains/extensions/contract.ts +15 -1
  405. package/src/domains/extensions/discovery.ts +238 -41
  406. package/src/domains/extensions/extension.ts +105 -6
  407. package/src/domains/extensions/index.ts +24 -0
  408. package/src/domains/extensions/integrity.ts +189 -0
  409. package/src/domains/extensions/manager.ts +17 -1
  410. package/src/domains/extensions/resource-path.ts +27 -0
  411. package/src/domains/extensions/resources.ts +18 -38
  412. package/src/domains/extensions/snapshot-store.ts +39 -0
  413. package/src/domains/extensions/snapshot.ts +180 -0
  414. package/src/domains/extensions/state.ts +385 -57
  415. package/src/domains/extensions/types.ts +118 -1
  416. package/src/domains/interop/registry.ts +6 -2
  417. package/src/domains/interop/types.ts +4 -0
  418. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
  419. package/src/domains/lifecycle/migrations/index.ts +6 -0
  420. package/src/domains/lifecycle/naming-resources.ts +19 -4
  421. package/src/domains/lifecycle/naming-yazi.ts +10 -5
  422. package/src/domains/memory/task-memory-policy.ts +70 -26
  423. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  424. package/src/domains/middleware/contract.ts +26 -0
  425. package/src/domains/middleware/extension.ts +24 -24
  426. package/src/domains/middleware/hook-receipts.ts +27 -4
  427. package/src/domains/middleware/hooks-io.ts +65 -32
  428. package/src/domains/middleware/hooks.ts +64 -0
  429. package/src/domains/middleware/index.ts +28 -5
  430. package/src/domains/middleware/marketplace-offer.ts +3 -35
  431. package/src/domains/middleware/memory-intervention.ts +127 -32
  432. package/src/domains/middleware/memory-step-endpoint.ts +3 -2
  433. package/src/domains/middleware/registrations.ts +326 -0
  434. package/src/domains/middleware/runtime.ts +28 -0
  435. package/src/domains/middleware/skills-reminder.ts +31 -2
  436. package/src/domains/middleware/snapshot.ts +20 -7
  437. package/src/domains/mux/contract.ts +38 -0
  438. package/src/domains/mux/detect.ts +6 -13
  439. package/src/domains/mux/index.ts +1 -1
  440. package/src/domains/mux/operations.ts +44 -5
  441. package/src/domains/mux/yazi/assets/yazi.toml +2 -2
  442. package/src/domains/mux/yazi/session.ts +53 -4
  443. package/src/domains/mux/yazi/theme.ts +117 -17
  444. package/src/domains/observability/compaction-usage.ts +118 -0
  445. package/src/domains/observability/contract.ts +10 -11
  446. package/src/domains/observability/cost.ts +1 -1
  447. package/src/domains/observability/extension.ts +17 -4
  448. package/src/domains/observability/out-of-turn-usage.ts +52 -21
  449. package/src/domains/observability/projection.ts +14 -90
  450. package/src/domains/observability/trace-store.ts +43 -7
  451. package/src/domains/prompts/compiler.ts +73 -53
  452. package/src/domains/prompts/contract.ts +15 -3
  453. package/src/domains/prompts/extension.ts +97 -9
  454. package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
  455. package/src/domains/prompts/fragments/identity/clio.md +6 -12
  456. package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
  457. package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
  458. package/src/domains/prompts/fragments/operating/contract.md +7 -15
  459. package/src/domains/prompts/fragments/operating/delegation.md +32 -34
  460. package/src/domains/prompts/fragments/operating/skills.md +10 -24
  461. package/src/domains/prompts/fragments/operating/worker.md +1 -8
  462. package/src/domains/providers/contract.ts +4 -1
  463. package/src/domains/providers/extension.ts +40 -9
  464. package/src/domains/providers/index.ts +1 -1
  465. package/src/domains/providers/model-capabilities.ts +9 -0
  466. package/src/domains/providers/model-discovery.ts +2 -0
  467. package/src/domains/providers/model-runtime-capabilities.ts +99 -25
  468. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +699 -114
  469. package/src/domains/providers/runtime-resolution.ts +31 -0
  470. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
  471. package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
  472. package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
  473. package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
  474. package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
  475. package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
  476. package/src/domains/providers/support.ts +11 -5
  477. package/src/domains/providers/target-model-cache.ts +25 -2
  478. package/src/domains/providers/types/capability-flags.ts +2 -0
  479. package/src/domains/providers/types/cost-provenance.ts +19 -0
  480. package/src/domains/providers/types/local-model-quirks.ts +85 -37
  481. package/src/domains/providers/types/runtime-descriptor.ts +20 -1
  482. package/src/domains/providers/types/target-descriptor.ts +19 -0
  483. package/src/domains/resources/index.ts +3 -0
  484. package/src/domains/resources/skills/install.ts +72 -7
  485. package/src/domains/resources/skills/loader.ts +23 -19
  486. package/src/domains/resources/skills/marketplace.ts +63 -11
  487. package/src/domains/safety/autonomy.ts +15 -0
  488. package/src/domains/safety/call-target.ts +1 -1
  489. package/src/domains/safety/index.ts +1 -0
  490. package/src/domains/safety/loop-detector.ts +7 -4
  491. package/src/domains/safety/path-policy.ts +1 -1
  492. package/src/domains/safety/policy-engine.ts +34 -11
  493. package/src/domains/safety/protected-artifacts.ts +191 -88
  494. package/src/domains/safety/run-effects.ts +2 -22
  495. package/src/domains/safety/skill-authority.ts +55 -0
  496. package/src/domains/session/compaction/compact.ts +72 -22
  497. package/src/domains/session/entries.ts +6 -0
  498. package/src/domains/session/task-board.ts +10 -9
  499. package/src/domains/session/usage.ts +3 -3
  500. package/src/domains/share/archive.ts +164 -7
  501. package/src/engine/acp/server.ts +62 -9
  502. package/src/engine/agent.ts +13 -3
  503. package/src/engine/ai.ts +26 -8
  504. package/src/engine/antigravity/subprocess-runtime.ts +386 -120
  505. package/src/engine/api-registry.ts +3 -0
  506. package/src/engine/apis/llamacpp-residency.ts +3 -4
  507. package/src/engine/apis/lmstudio.ts +3 -3
  508. package/src/engine/apis/ollama-native.ts +6 -6
  509. package/src/engine/apis/openai-completions.ts +145 -39
  510. package/src/engine/apis/output-budget.ts +8 -18
  511. package/src/engine/apis/residency.ts +8 -27
  512. package/src/engine/external-subprocess.ts +114 -6
  513. package/src/engine/gemma-channel-filter.ts +19 -0
  514. package/src/engine/loop-guard.ts +92 -12
  515. package/src/engine/worker-runtime.ts +40 -11
  516. package/src/engine/worker-tools.ts +3 -1
  517. package/src/entry/background-model-metadata.ts +18 -0
  518. package/src/entry/compaction-prompt.ts +57 -0
  519. package/src/entry/extension-hook-sources.ts +28 -0
  520. package/src/entry/extension-reload.ts +309 -0
  521. package/src/entry/orchestrator.ts +464 -251
  522. package/src/entry/task-memory-lifecycle.ts +35 -0
  523. package/src/interactive/application-controller.ts +2 -1
  524. package/src/interactive/bus-notices.ts +8 -1
  525. package/src/interactive/chat-loop-messages.ts +16 -17
  526. package/src/interactive/chat-loop.ts +75 -3
  527. package/src/interactive/chat-panel.ts +36 -13
  528. package/src/interactive/chat-renderer.ts +72 -7
  529. package/src/interactive/cost-overlay.ts +26 -2
  530. package/src/interactive/dispatch-board.ts +6 -11
  531. package/src/interactive/footer/widgets.ts +13 -0
  532. package/src/interactive/interactive-application.ts +39 -4
  533. package/src/interactive/interactive-input-runtime.ts +4 -0
  534. package/src/interactive/interactive-presentation.ts +2 -2
  535. package/src/interactive/interactive-slash-runtime.ts +4 -1
  536. package/src/interactive/overlays/extensions.ts +9 -1
  537. package/src/interactive/overlays/help-reference.ts +13 -0
  538. package/src/interactive/overlays/settings.ts +27 -16
  539. package/src/interactive/panes-runtime.ts +111 -35
  540. package/src/interactive/prompt-cache-identity.ts +88 -0
  541. package/src/interactive/renderers/worker-entry.ts +32 -0
  542. package/src/interactive/slash-commands.ts +153 -20
  543. package/src/interactive/stream-pacing-policy.ts +0 -23
  544. package/src/interactive/theme/labels.ts +19 -13
  545. package/src/interactive/turn-context.ts +39 -20
  546. package/src/interactive/turn-recovery.ts +8 -0
  547. package/src/interactive/turn-runtime.ts +27 -11
  548. package/src/interactive/turn-state.ts +7 -0
  549. package/src/interactive/worker-receipts.ts +1 -0
  550. package/src/interactive/worker-stream.ts +6 -1
  551. package/src/interactive/yazi-bridge.ts +60 -6
  552. package/src/tools/agent-tools.ts +30 -1
  553. package/src/tools/artifact.ts +2 -2
  554. package/src/tools/ask-user.ts +3 -3
  555. package/src/tools/bash.ts +1 -1
  556. package/src/tools/bootstrap.ts +4 -0
  557. package/src/tools/builtin-tool-catalog.ts +52 -22
  558. package/src/tools/codewiki/code-nav-surface.ts +6 -0
  559. package/src/tools/codewiki/code-nav.ts +99 -13
  560. package/src/tools/context/docs-engine.ts +20 -7
  561. package/src/tools/context/index.ts +59 -21
  562. package/src/tools/core-bootstrap.ts +28 -6
  563. package/src/tools/credential-present.ts +1 -2
  564. package/src/tools/dispatch-arguments.ts +6 -1
  565. package/src/tools/dispatch-event-text.ts +10 -0
  566. package/src/tools/dispatch-plan.ts +49 -4
  567. package/src/tools/dispatch-run-events.ts +1 -1
  568. package/src/tools/dispatch-runner.ts +12 -0
  569. package/src/tools/dispatch-schema.ts +338 -0
  570. package/src/tools/dispatch-types.ts +3 -0
  571. package/src/tools/dispatch.ts +9 -254
  572. package/src/tools/ledger.ts +3 -5
  573. package/src/tools/monitor-surface.ts +5 -13
  574. package/src/tools/observation.ts +4 -5
  575. package/src/tools/panes-surface.ts +4 -11
  576. package/src/tools/panes.ts +4 -2
  577. package/src/tools/policy.ts +15 -2
  578. package/src/tools/read.ts +5 -6
  579. package/src/tools/registry.ts +41 -12
  580. package/src/tools/result-shaping.ts +18 -14
  581. package/src/tools/steer-surface.ts +1 -1
  582. package/src/tools/tasks.ts +1 -1
  583. package/src/tools/truncate.ts +6 -5
  584. package/src/tools/verify/surface.ts +6 -12
  585. package/src/tools/web-fetch-surface.ts +1 -3
  586. package/src/tools/worker-evidence.ts +3 -1
  587. package/src/worker/spec-contract.ts +4 -0
  588. package/dist/builtins-UJLMOVOV.js +0 -17
  589. package/dist/chunk-5QIAJV2D.js +0 -48
  590. package/dist/chunk-JZWT5J3Y.js +0 -814
  591. package/dist/chunk-K7VKOLQQ.js +0 -15
  592. package/dist/chunk-PMZCIOCJ.js +0 -25
  593. package/dist/chunk-SUW5DORT.js +0 -819
  594. package/dist/chunk-UOV2BYIW.js +0 -107
  595. package/dist/chunk-WR6U3OVP.js +0 -45
  596. package/dist/chunk-Y45G3AXC.js +0 -1558
  597. package/dist/reset-EOLM7GVE.js +0 -230
  598. package/dist/uninstall-N34PCTGJ.js +0 -331
  599. package/dist/upgrade-H7TOM7YL.js +0 -323
  600. package/docs/artifact-versions.md +0 -67
  601. package/docs/development-pipeline.md +0 -121
  602. package/docs/documentation-coverage.md +0 -46
  603. package/docs/documentation-guide.md +0 -167
  604. package/docs/time-conventions.md +0 -101
@@ -10,10 +10,11 @@
10
10
  * boundary; this module does not import pi-ai directly.
11
11
  */
12
12
 
13
- import { stream } from "../../../engine/ai.js";
13
+ import { streamSimple } from "../../../engine/ai.js";
14
14
  import type { EngineModel, Usage } from "../../../engine/types.js";
15
15
  import { foldWorkingSet } from "../../context/working-set/fold.js";
16
16
  import { recallableRefListing } from "../../context/working-set/recall.js";
17
+ import { extractReasoningTokens } from "../context-accounting.js";
17
18
  import type { CompactionUsage, SessionEntry } from "../entries.js";
18
19
  import { serializeConversation } from "./branch-summary.js";
19
20
  import { findCutPoint } from "./cut-point.js";
@@ -86,6 +87,14 @@ In addition to that carried-forward context, summarize ONLY the active-turn deta
86
87
 
87
88
  Do NOT answer the user. Do NOT summarize unrelated older history.`;
88
89
 
90
+ /** One invoked summary stream, including failed calls that produce no checkpoint. */
91
+ export interface CompactionCallObservation {
92
+ outcome: "success" | "error" | "aborted";
93
+ usage: unknown;
94
+ timestamp: string;
95
+ durationMs: number;
96
+ }
97
+
89
98
  export interface CompactInput {
90
99
  /** Ordered session entries to compact. The caller reads these from the session domain. */
91
100
  entries: ReadonlyArray<SessionEntry>;
@@ -105,6 +114,8 @@ export interface CompactInput {
105
114
  reserveTokens?: number;
106
115
  /** Override the built-in keep-recent default (DEFAULT_KEEP_RECENT_TOKENS). */
107
116
  keepRecentTokens?: number;
117
+ /** Accounting observer; called once per invoked stream, including failures. */
118
+ onCall?: (call: CompactionCallObservation) => void;
108
119
  }
109
120
 
110
121
  export interface CompactResult {
@@ -367,6 +378,24 @@ function addCompactionUsage(total: CompactionUsage | undefined, raw: unknown): C
367
378
  };
368
379
  }
369
380
 
381
+ /** Keep attributable partial facts if a failed terminal object resets missing fields to zero. */
382
+ function retainReportedUsage(previous: Record<string, unknown>, raw: unknown): Record<string, unknown> {
383
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return previous;
384
+ const usage = raw as Record<string, unknown>;
385
+ const known = { ...previous };
386
+ for (const field of ["input", "output", "cacheRead", "cacheWrite", "totalTokens"]) {
387
+ const value = numberOrZero(usage[field]);
388
+ if (value > 0) known[field] = value;
389
+ }
390
+ const reasoning = extractReasoningTokens({ ...usage, reasoningTokens: undefined });
391
+ if (reasoning !== null && reasoning > 0) known.reasoning = reasoning;
392
+ if (usage.cost && typeof usage.cost === "object" && "total" in usage.cost) {
393
+ const cost = numberOrZero(usage.cost.total);
394
+ if (cost > 0) known.cost = { total: cost };
395
+ }
396
+ return known;
397
+ }
398
+
370
399
  async function runSummaryStream(
371
400
  input: CompactInput,
372
401
  userText: string,
@@ -383,26 +412,47 @@ async function runSummaryStream(
383
412
  messages: [buildUserMessage(userText)],
384
413
  };
385
414
 
386
- const events = stream(
387
- input.model,
388
- context as unknown as Parameters<typeof stream>[1],
389
- options as unknown as Parameters<typeof stream>[2],
390
- );
391
-
392
- let summary = "";
415
+ const timestamp = new Date().toISOString();
416
+ const started = performance.now();
393
417
  let usage: unknown;
394
- for await (const event of events) {
395
- if (event.type === "done") {
396
- summary = textFromAssistant(event.message);
397
- usage = (event.message as { usage?: unknown }).usage;
398
- break;
399
- }
400
- if (event.type === "error") {
401
- const reason = event.error.errorMessage ?? "unknown error";
402
- throw new Error(`compaction stream failed: ${reason}`);
418
+ let reported: Record<string, unknown> = {};
419
+ let outcome: CompactionCallObservation["outcome"] = "error";
420
+ try {
421
+ // Summarization requests thinking off, as its resolver does. Bare stream
422
+ // infers an active level from model.reasoning and would undo that choice.
423
+ const events = streamSimple(
424
+ input.model,
425
+ context as unknown as Parameters<typeof streamSimple>[1],
426
+ options as unknown as Parameters<typeof streamSimple>[2],
427
+ );
428
+ for await (const event of events) {
429
+ // Some transports throw after yielding a partial response. Retain the
430
+ // last reported usage even without a terminal error message.
431
+ if ("partial" in event) {
432
+ usage = event.partial.usage ?? usage;
433
+ reported = retainReportedUsage(reported, usage);
434
+ }
435
+ if (event.type === "done") {
436
+ usage = event.message.usage ?? usage;
437
+ outcome = "success";
438
+ return { text: textFromAssistant(event.message).trim(), usage };
439
+ }
440
+ if (event.type === "error") {
441
+ usage = event.error.usage ?? usage;
442
+ reported = retainReportedUsage(reported, usage);
443
+ outcome = event.error.stopReason === "aborted" ? "aborted" : "error";
444
+ throw new Error(`compaction stream failed: ${event.error.errorMessage ?? "unknown error"}`);
445
+ }
403
446
  }
447
+ throw new Error("compaction stream ended without a terminal response");
448
+ } finally {
449
+ input.onCall?.({
450
+ outcome: outcome === "error" && input.signal?.aborted ? "aborted" : outcome,
451
+ usage: outcome === "success" ? usage : reported,
452
+ timestamp,
453
+ durationMs: Math.max(0, performance.now() - started),
454
+ });
404
455
  }
405
- return { text: summary.trim(), usage };
406
456
  }
407
457
 
408
458
  /**
@@ -464,16 +514,16 @@ export async function compact(input: CompactInput): Promise<CompactResult> {
464
514
  const userText = buildUserText(conversationText, input.instructions, previousContextText);
465
515
  const historySummary = await runSummaryStream(input, userText, systemPrompt, maxTokens);
466
516
  usage = addCompactionUsage(usage, historySummary.usage);
467
- if (historySummary.text.length > 0) summaryParts.push(historySummary.text);
517
+ if (historySummary.text.length === 0) throw new Error("compaction returned an empty history summary");
518
+ summaryParts.push(historySummary.text);
468
519
  }
469
520
  if (turnPrefix.length > 0) {
470
521
  const conversationText = serializeConversation(turnPrefix);
471
522
  const userText = buildTurnPrefixUserText(conversationText, input.instructions, previousContextText);
472
523
  const prefixSummary = await runSummaryStream(input, userText, systemPrompt, maxTokens);
473
524
  usage = addCompactionUsage(usage, prefixSummary.usage);
474
- if (prefixSummary.text.length > 0) {
475
- summaryParts.push(`**Turn Context (split turn):**\n\n${prefixSummary.text}`);
476
- }
525
+ if (prefixSummary.text.length === 0) throw new Error("compaction returned an empty split-turn summary");
526
+ summaryParts.push(`**Turn Context (split turn):**\n\n${prefixSummary.text}`);
477
527
  }
478
528
 
479
529
  const summary = `${summaryParts.join("\n\n---\n\n").trim()}${formatFileOperations(fileOps)}${formatRecallableRefs(
@@ -101,6 +101,10 @@ export type CompactionTrigger = "auto" | "force" | "overflow";
101
101
  * `usage` carries and the ledger usage fold reads both from one place.
102
102
  */
103
103
  export interface CompactionUsage {
104
+ /** Executing route; absent on legacy checkpoints that used the active chat model. */
105
+ targetId?: string;
106
+ /** Requested wire model ID, not a verified physical backend identity. */
107
+ modelId?: string;
104
108
  input: number;
105
109
  output: number;
106
110
  cacheRead: number;
@@ -515,6 +519,8 @@ function isOptionalCompactionUsage(value: unknown): boolean {
515
519
  if (!isRecord(value)) return false;
516
520
  const cost = value.cost;
517
521
  return (
522
+ isOptionalString(value.targetId) &&
523
+ isOptionalString(value.modelId) &&
518
524
  isNumber(value.input) &&
519
525
  isNumber(value.output) &&
520
526
  isNumber(value.cacheRead) &&
@@ -421,10 +421,8 @@ function applyMutation(
421
421
  // Completion is the ledger's only load-bearing claim, so it carries two
422
422
  // structural conditions rather than a bare status flip. Evidence is
423
423
  // mandatory: a completed row becomes a passed validation record, and a row
424
- // without evidence would assert a validation that nobody performed. The
425
- // task must also have been started, because work that was never entered
426
- // cannot have produced a result; the honest closes for it are block and
427
- // drop, which record a reason instead.
424
+ // without evidence would assert a validation that nobody performed. Work
425
+ // that did not happen is closed with block or drop, which record a reason.
428
426
  if (mutation.op === "done") {
429
427
  if (mutation.evidence.trim().length === 0) {
430
428
  return {
@@ -432,13 +430,16 @@ function applyMutation(
432
430
  "done requires note as the evidence that the task actually finished (the command you ran, the file:line you verified). If the work did not happen, use block with a reason or drop it.",
433
431
  };
434
432
  }
435
- if (target.status === "pending") {
436
- return {
437
- error: `task ${target.id} was never started, so it cannot be completed. Start it and do the work, or record the truth with block (reason) or drop.`,
438
- };
439
- }
440
433
  }
441
434
  const notes: string[] = [];
435
+ // A model that did the work without announcing it on the board closes
436
+ // several tasks in a row at the end of the turn. Refusing done on a pending
437
+ // task cost a live session six start/done pairs of pure ceremony; the
438
+ // evidence note is the load-bearing claim, so the start is recorded
439
+ // implicitly and named in the notes.
440
+ if (mutation.op === "done" && target.status === "pending") {
441
+ notes.push(`started ${target.id} implicitly: done on a pending task records the start and the completion together`);
442
+ }
442
443
  const tasks = board.tasks.map((task): TaskBoardTask => {
443
444
  if (task.id !== target.id) {
444
445
  // One active task at a time: starting a task parks any other active
@@ -101,9 +101,9 @@ export function ledgerUsageCalls(
101
101
  const usage = entry.usage;
102
102
  if (!usage || usage.totalTokens <= 0) continue;
103
103
  calls.push({
104
- providerId: currentTarget ?? "unknown",
105
- attributedModelId: currentModel ?? "unknown",
106
- requestedModelId: currentModel ?? "unknown",
104
+ providerId: usage.targetId ?? currentTarget ?? "unknown",
105
+ attributedModelId: usage.modelId ?? currentModel ?? "unknown",
106
+ requestedModelId: usage.modelId ?? currentModel ?? "unknown",
107
107
  responseModelIdObservation: { state: "not-observed" },
108
108
  input: usage.input,
109
109
  output: usage.output,
@@ -1,5 +1,17 @@
1
1
  import { createHash } from "node:crypto";
2
- import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync, type Stats, statSync } from "node:fs";
2
+ import {
3
+ existsSync,
4
+ lstatSync,
5
+ mkdirSync,
6
+ mkdtempSync,
7
+ readdirSync,
8
+ readFileSync,
9
+ realpathSync,
10
+ rmSync,
11
+ type Stats,
12
+ statSync,
13
+ } from "node:fs";
14
+ import { tmpdir } from "node:os";
3
15
  import path from "node:path";
4
16
  import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
5
17
  import { type ClioSettings, readSettings, settingsPath, updateSettings, validateSettings } from "../../core/config.js";
@@ -18,6 +30,10 @@ import {
18
30
  parseAgentRecipeSchema,
19
31
  parseFleetContract,
20
32
  } from "../agents/index.js";
33
+ import { loadManifestFromRoot } from "../extensions/discovery.js";
34
+ import { extensionContentDigest } from "../extensions/integrity.js";
35
+ import { extensionBaseDir, installExtension, listInstalledExtensions } from "../extensions/state.js";
36
+ import type { ExtensionScope } from "../extensions/types.js";
21
37
  import { migrateSettingsV1Document } from "../lifecycle/migrations/2026-09-01-settings-v2.js";
22
38
 
23
39
  export type ShareScope = "project" | "user";
@@ -331,7 +347,14 @@ export function createShareArchive(options: ShareExportOptions = {}): ClioShareA
331
347
  for (const scope of scopes) {
332
348
  const root =
333
349
  scope === "user" ? path.join(clioConfigDir(), "extensions") : path.join(cwd, ".clio-coder", "extensions");
334
- addTree(files, "extension", scope, root, `${scope}/extensions`, (rel) => path.basename(rel) !== "state.json");
350
+ addTree(
351
+ files,
352
+ "extension",
353
+ scope,
354
+ root,
355
+ `${scope}/extensions`,
356
+ (relativePath) => !relativePath.split("/")[0]?.startsWith(".") && path.basename(relativePath) !== "state.json",
357
+ );
335
358
  }
336
359
  }
337
360
  if (includes.includeSettings) {
@@ -453,6 +476,15 @@ interface ShareImportPreparedPlan {
453
476
  actions: ShareImportAction[];
454
477
  diagnostics: ShareDiagnostic[];
455
478
  targets: ShareImportPreparedTarget[];
479
+ extensionPackages: ShareImportPreparedExtensionPackage[];
480
+ }
481
+
482
+ interface ShareImportPreparedExtensionPackage {
483
+ id: string;
484
+ scope: ExtensionScope;
485
+ files: Array<{ relativePath: string; buffer: Buffer }>;
486
+ contentDigest: string;
487
+ install: boolean;
456
488
  }
457
489
 
458
490
  function configDirPath(): string {
@@ -608,6 +640,91 @@ function preflightImportTargets(
608
640
  return { targets, diagnostics };
609
641
  }
610
642
 
643
+ function withStagedExtensionPackage<T>(
644
+ input: { id: string; files: ReadonlyArray<{ relativePath: string; buffer: Buffer }> },
645
+ fn: (root: string) => T,
646
+ ): T {
647
+ const stagingParent = mkdtempSync(path.join(tmpdir(), "clio-share-extension-"));
648
+ const root = path.join(stagingParent, input.id);
649
+ try {
650
+ mkdirSync(root, { recursive: true });
651
+ for (const file of input.files) safeResourceWrite(path.join(root, file.relativePath), file.buffer);
652
+ return fn(root);
653
+ } finally {
654
+ rmSync(stagingParent, { recursive: true, force: true });
655
+ }
656
+ }
657
+
658
+ function prepareExtensionPackages(
659
+ targets: ReadonlyArray<ShareImportPreparedTarget>,
660
+ options: ShareImportOptions,
661
+ ): { packages: ShareImportPreparedExtensionPackage[]; diagnostics: ShareDiagnostic[] } {
662
+ const diagnostics: ShareDiagnostic[] = [];
663
+ const grouped = new Map<string, Omit<ShareImportPreparedExtensionPackage, "contentDigest" | "install">>();
664
+ for (const target of targets) {
665
+ if (target.entry.type !== "extension") continue;
666
+ const segments = relativePathSegments(target.entry.relativePath);
667
+ const id = segments?.[0];
668
+ const packagePath = segments?.slice(1).join("/");
669
+ if (!id || !packagePath) {
670
+ diagnostics.push({
671
+ type: "error",
672
+ message: `extension archive path must be <id>/<package-path>: ${pathDiagnostic(target.entry)}`,
673
+ path: target.entry.relativePath,
674
+ });
675
+ continue;
676
+ }
677
+ const scope = target.scope as ExtensionScope;
678
+ const key = `${scope}\0${id}`;
679
+ const group = grouped.get(key) ?? { id, scope, files: [] };
680
+ if (group.files.some((file) => file.relativePath === packagePath)) {
681
+ diagnostics.push({ type: "error", message: `duplicate extension archive path ${target.entry.relativePath}` });
682
+ continue;
683
+ }
684
+ group.files.push({ relativePath: packagePath, buffer: target.buffer });
685
+ grouped.set(key, group);
686
+ }
687
+
688
+ const packages: ShareImportPreparedExtensionPackage[] = [];
689
+ for (const group of [...grouped.values()].sort((a, b) => `${a.scope}/${a.id}`.localeCompare(`${b.scope}/${b.id}`))) {
690
+ try {
691
+ const contentDigest = withStagedExtensionPackage(group, (root) => {
692
+ const candidate = loadManifestFromRoot(root);
693
+ if (!candidate.valid || !candidate.manifest) {
694
+ throw new Error(candidate.diagnostics.map((diagnostic) => diagnostic.message).join("; ") || "manifest is invalid");
695
+ }
696
+ if (candidate.manifest.id !== group.id) {
697
+ throw new Error(`manifest id ${candidate.manifest.id} does not match archive package ${group.id}`);
698
+ }
699
+ return extensionContentDigest(root);
700
+ });
701
+ const cwd = path.resolve(options.cwd ?? process.cwd());
702
+ const targetRoot = path.join(extensionBaseDir(group.scope, cwd), group.id);
703
+ const existing = listInstalledExtensions(cwd, { scope: group.scope, all: true }).find(
704
+ (extension) => extension.id === group.id && extension.rootPath === targetRoot,
705
+ );
706
+ const alreadyVerified =
707
+ existing?.valid === true &&
708
+ existing.provenance?.contentDigest === contentDigest &&
709
+ existing.observedContentDigest === contentDigest;
710
+ if (existsSync(targetRoot) && !alreadyVerified && !options.force) {
711
+ diagnostics.push({
712
+ type: "conflict",
713
+ message: `extension ${group.id} is not already installed with the archive's verified digest; re-run with --force to use the canonical installer`,
714
+ path: targetRoot,
715
+ });
716
+ }
717
+ packages.push({ ...group, contentDigest, install: !alreadyVerified });
718
+ } catch (error) {
719
+ diagnostics.push({
720
+ type: "error",
721
+ message: `extension ${group.id} in share archive is invalid: ${error instanceof Error ? error.message : String(error)}`,
722
+ });
723
+ }
724
+ }
725
+ return { packages, diagnostics };
726
+ }
727
+
611
728
  function versionDiagnostics(archive: ClioShareArchive): ShareDiagnostic[] {
612
729
  const current = readClioVersion();
613
730
  const [curMajor, curMinor] = current.split(".");
@@ -657,13 +774,20 @@ function prepareShareImport(filePath: string, options: ShareImportOptions = {}):
657
774
  actions: [],
658
775
  diagnostics: [{ type: "error", message: err instanceof Error ? err.message : String(err), path: filePath }],
659
776
  targets: [],
777
+ extensionPackages: [],
660
778
  };
661
779
  }
662
780
  const diagnostics: ShareDiagnostic[] = [...versionDiagnostics(archive)];
663
781
  const actions: ShareImportAction[] = [];
664
782
  const preflight = preflightImportTargets(archive, options);
665
783
  if (preflight.diagnostics.length > 0) {
666
- return { archive, actions: [], diagnostics: [...diagnostics, ...preflight.diagnostics], targets: [] };
784
+ return {
785
+ archive,
786
+ actions: [],
787
+ diagnostics: [...diagnostics, ...preflight.diagnostics],
788
+ targets: [],
789
+ extensionPackages: [],
790
+ };
667
791
  }
668
792
  for (const targetInfo of preflight.targets) {
669
793
  const { entry, target, scope, buffer } = targetInfo;
@@ -706,7 +830,9 @@ function prepareShareImport(filePath: string, options: ShareImportOptions = {}):
706
830
  }
707
831
  actions.push({ action: "write", type: entry.type, scope, path: target });
708
832
  }
709
- return { archive, actions, diagnostics, targets: preflight.targets };
833
+ const extensions = prepareExtensionPackages(preflight.targets, options);
834
+ diagnostics.push(...extensions.diagnostics);
835
+ return { archive, actions, diagnostics, targets: preflight.targets, extensionPackages: extensions.packages };
710
836
  }
711
837
 
712
838
  function publicImportPlan(prepared: ShareImportPreparedPlan, recovery?: ShareImportRecovery): ShareImportPlan {
@@ -750,10 +876,41 @@ export function importShareArchive(filePath: string, options: ShareImportOptions
750
876
  };
751
877
  let failed: string | undefined;
752
878
  try {
879
+ for (const extensionPackage of prepared.extensionPackages) {
880
+ if (!extensionPackage.install) continue;
881
+ const cwd = path.resolve(options.cwd ?? process.cwd());
882
+ failed = path.join(extensionBaseDir(extensionPackage.scope, cwd), extensionPackage.id);
883
+ const result = withStagedExtensionPackage(extensionPackage, (root) =>
884
+ installExtension(root, {
885
+ cwd,
886
+ scope: extensionPackage.scope,
887
+ ...(options.force !== undefined ? { force: options.force } : {}),
888
+ }),
889
+ );
890
+ for (const backup of [result.recovery?.stateBackup, result.recovery?.packageBackup]) {
891
+ if (backup && !backups.includes(backup)) backups.push(backup);
892
+ }
893
+ const errors = result.diagnostics.filter((diagnostic) => diagnostic.type === "error");
894
+ if (!result.extension || errors.length > 0) {
895
+ throw new Error(errors.map((diagnostic) => diagnostic.message).join("; ") || "canonical install failed");
896
+ }
897
+ if (result.extension.provenance?.contentDigest !== extensionPackage.contentDigest) {
898
+ throw new Error(`canonical install digest mismatch for extension ${extensionPackage.id}`);
899
+ }
900
+ for (const diagnostic of result.diagnostics) {
901
+ prepared.diagnostics.push({
902
+ type: "warning",
903
+ message: diagnostic.message,
904
+ ...(diagnostic.path ? { path: diagnostic.path } : {}),
905
+ });
906
+ }
907
+ if (!written.includes(result.extension.rootPath)) written.push(result.extension.rootPath);
908
+ failed = undefined;
909
+ }
753
910
  for (let index = 0; index < prepared.targets.length; index += 1) {
754
911
  const targetInfo = prepared.targets[index];
755
912
  const action = prepared.actions[index];
756
- if (!targetInfo || !action || action.action === "skip") continue;
913
+ if (!targetInfo || !action || action.action === "skip" || targetInfo.entry.type === "extension") continue;
757
914
  failed = targetInfo.target;
758
915
  if (targetInfo.entry.type === "settings") {
759
916
  const path = mergeSettingsFragment(targetInfo.buffer);
@@ -768,7 +925,7 @@ export function importShareArchive(filePath: string, options: ShareImportOptions
768
925
  );
769
926
  failed = undefined;
770
927
  }
771
- return plan;
928
+ return publicImportPlan(prepared, backups.length > 0 ? { written, backups } : undefined);
772
929
  } catch (err) {
773
930
  if (failed) {
774
931
  const expectedBackup = safeResourceBackupPath(failed);
@@ -787,7 +944,7 @@ export function importShareArchive(filePath: string, options: ShareImportOptions
787
944
  ...prepared.diagnostics,
788
945
  {
789
946
  type: "error",
790
- message: `share import failed while writing${failed ? ` ${failed}` : ""}: ${reason}`,
947
+ message: `share import failed${failed ? ` while importing ${failed}` : ""}: ${reason}`,
791
948
  ...(failed ? { path: failed } : {}),
792
949
  },
793
950
  ],
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import { realpathSync } from "node:fs";
3
3
  import { isAbsolute, resolve as resolvePath } from "node:path";
4
4
  import {
5
+ type AccountabilityEvidenceReadyPayload,
5
6
  BusChannels,
6
7
  type DispatchCompletedPayload,
7
8
  type DispatchEnqueuedPayload,
@@ -209,6 +210,8 @@ interface AcpServerUsage {
209
210
  cacheRead: number;
210
211
  cacheWrite: number;
211
212
  reasoning: number;
213
+ totalTokens: number;
214
+ costUsd: number;
212
215
  }
213
216
 
214
217
  function isRecord(value: unknown): value is Record<string, unknown> {
@@ -333,7 +336,10 @@ const ACP_MAX_REPLAY_TOOL_CALLS = 8192;
333
336
  * the list is the allowlist, and a client's requested kinds are intersected
334
337
  * with it rather than trusted. `safety.loopBlocked` was the first member; the
335
338
  * dispatch lifecycle joined it so a client can draw a live fleet board from
336
- * reported facts instead of inferring one from tool titles or timing.
339
+ * reported facts instead of inferring one from tool titles or timing;
340
+ * `accountability.evidenceReady` follows a run's terminal event once its
341
+ * evidence bundle has landed, so the board can show first-pass success and a
342
+ * finding count without reading Clio's state tree.
337
343
  */
338
344
  const ACP_FORWARDABLE_EVENT_KINDS = [
339
345
  "safety.loopBlocked",
@@ -342,6 +348,7 @@ const ACP_FORWARDABLE_EVENT_KINDS = [
342
348
  "dispatch.progress",
343
349
  "dispatch.completed",
344
350
  "dispatch.failed",
351
+ "accountability.evidenceReady",
345
352
  ] as const;
346
353
 
347
354
  type AcpForwardableEventKind = (typeof ACP_FORWARDABLE_EVENT_KINDS)[number];
@@ -359,6 +366,9 @@ const ACP_MAX_DISPATCH_TASK_PREVIEW_BYTES = 160;
359
366
 
360
367
  /** Wire bound for the short identifiers a dispatch event carries. */
361
368
  const ACP_MAX_DISPATCH_ID_BYTES = 128;
369
+ /** Evidence tags are a closed vocabulary of short identifiers; anything wider is not a tag. */
370
+ const ACP_MAX_EVIDENCE_TAGS = 32;
371
+ const ACP_MAX_EVIDENCE_TAG_BYTES = 64;
362
372
 
363
373
  /**
364
374
  * Progress events forwarded per run before the stream is capped. One run
@@ -521,8 +531,8 @@ function utf8Bytes(value: string): number {
521
531
  return Buffer.byteLength(value, "utf8");
522
532
  }
523
533
 
524
- function emptyUsage(): AcpServerUsage {
525
- return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0 };
534
+ export function emptyUsage(): AcpServerUsage {
535
+ return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, totalTokens: 0, costUsd: 0 };
526
536
  }
527
537
 
528
538
  function createActivePromptState(): ActivePrompt {
@@ -552,15 +562,33 @@ function finite(value: unknown): number {
552
562
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
553
563
  }
554
564
 
555
- function mergeUsage(into: AcpServerUsage, usage: unknown): void {
565
+ /** Only field `sumRunUsage` (chat-loop-messages.ts) reads for a dollar figure; matched here so ACP never re-derives cost through a separate path. */
566
+ function costTotal(usage: Record<string, unknown>): number {
567
+ const cost = usage.cost;
568
+ return isRecord(cost) ? finite(cost.total) : 0;
569
+ }
570
+
571
+ export function mergeUsage(into: AcpServerUsage, usage: unknown): void {
556
572
  if (!isRecord(usage)) return;
557
- into.input +=
573
+ const input =
558
574
  finite(usage.input) + finite(usage.inputTokens) + finite(usage.input_tokens) + finite(usage.prompt_tokens);
559
- into.output +=
575
+ const output =
560
576
  finite(usage.output) + finite(usage.outputTokens) + finite(usage.output_tokens) + finite(usage.completion_tokens);
561
- into.cacheRead += finite(usage.cacheRead) + finite(usage.cacheReadTokens) + finite(usage.cache_read_tokens);
562
- into.cacheWrite += finite(usage.cacheWrite) + finite(usage.cacheWriteTokens) + finite(usage.cache_write_tokens);
563
- into.reasoning += finite(usage.reasoning) + finite(usage.reasoningTokens) + finite(usage.reasoning_tokens);
577
+ const cacheRead = finite(usage.cacheRead) + finite(usage.cacheReadTokens) + finite(usage.cache_read_tokens);
578
+ const cacheWrite = finite(usage.cacheWrite) + finite(usage.cacheWriteTokens) + finite(usage.cache_write_tokens);
579
+ const reasoning = finite(usage.reasoning) + finite(usage.reasoningTokens) + finite(usage.reasoning_tokens);
580
+ into.input += input;
581
+ into.output += output;
582
+ into.cacheRead += cacheRead;
583
+ into.cacheWrite += cacheWrite;
584
+ into.reasoning += reasoning;
585
+ // Same fallback sumRunUsage uses: prefer the provider's own total, otherwise
586
+ // sum the four merged categories for this message (reasoning excluded,
587
+ // matching sumRunUsage, since a provider that reports reasoning separately
588
+ // still counts it inside output for billing).
589
+ const explicitTotal = finite(usage.totalTokens) + finite(usage.total_tokens);
590
+ into.totalTokens += explicitTotal > 0 ? explicitTotal : input + output + cacheRead + cacheWrite;
591
+ into.costUsd += costTotal(usage);
564
592
  }
565
593
 
566
594
  function mergeMessageUsage(into: AcpServerUsage, message: unknown, seen?: WeakSet<object>): void {
@@ -1857,6 +1885,29 @@ export async function serveClioAcpAgent(options: ClioAcpServerOptions): Promise<
1857
1885
  });
1858
1886
  }),
1859
1887
  );
1888
+ unsubscribeEvents.push(
1889
+ bus.on(BusChannels.AccountabilityEvidenceReady, (payload: AccountabilityEvidenceReadyPayload) => {
1890
+ // Arrives after dispatch.completed or dispatch.failed for the same run,
1891
+ // so it is terminal too: nothing about that run follows it. The
1892
+ // bundle's prose (findings, overview) stays behind; only the summary
1893
+ // counters the projection itself carries cross, and the tags are
1894
+ // filtered to bounded identifiers rather than truncated into new ones.
1895
+ const runId = safeStoredIdentifier(payload.runId, ACP_MAX_DISPATCH_ID_BYTES);
1896
+ const evidenceId = safeStoredIdentifier(payload.evidenceId, ACP_MAX_DISPATCH_ID_BYTES);
1897
+ if (runId === null || evidenceId === null) return;
1898
+ const tags = (Array.isArray(payload.tags) ? payload.tags : [])
1899
+ .map((tag) => safeStoredIdentifier(tag, ACP_MAX_EVIDENCE_TAG_BYTES))
1900
+ .filter((tag): tag is string => tag !== null)
1901
+ .slice(0, ACP_MAX_EVIDENCE_TAGS);
1902
+ forwardEvent("accountability.evidenceReady", null, true, {
1903
+ runId,
1904
+ evidenceId,
1905
+ firstPassSuccess: payload.firstPassSuccess === true,
1906
+ findingCount: safeCount(payload.findingCount),
1907
+ tags,
1908
+ });
1909
+ }),
1910
+ );
1860
1911
  }
1861
1912
  const unsubscribeEventStream = (): void => {
1862
1913
  for (const unsubscribe of unsubscribeEvents) unsubscribe();
@@ -2607,6 +2658,8 @@ function promptResponse(stopReason: string, active: ActivePrompt): AcpPromptResp
2607
2658
  cacheRead: active.usage.cacheRead,
2608
2659
  cacheWrite: active.usage.cacheWrite,
2609
2660
  reasoning: active.usage.reasoning,
2661
+ totalTokens: active.usage.totalTokens,
2662
+ costUsd: active.usage.costUsd,
2610
2663
  },
2611
2664
  },
2612
2665
  };
@@ -14,7 +14,11 @@ import { Agent, type AgentOptions, type StreamFn } from "@earendil-works/pi-agen
14
14
  import { isDispositionedToolResultError } from "../tools/result-disposition.js";
15
15
  import { engineStreamSimple } from "./api-registry.js";
16
16
 
17
- export type EngineAgentOptions = Omit<AgentOptions, "streamFn"> & { streamFn?: StreamFn };
17
+ export type EngineAgentOptions = Omit<AgentOptions, "streamFn"> & {
18
+ streamFn?: StreamFn;
19
+ /** Called immediately before each native stream delegate invocation. */
20
+ onStreamInvocation?: () => void;
21
+ };
18
22
 
19
23
  export interface EngineAgentHandle {
20
24
  agent: Agent;
@@ -34,9 +38,15 @@ function dispositionAwareAfterToolCall(
34
38
  }
35
39
 
36
40
  export function createEngineAgent(options: EngineAgentOptions = {}): EngineAgentHandle {
41
+ const { streamFn = engineStreamSimple, onStreamInvocation, ...agentOptions } = options;
37
42
  const agent = new Agent({
38
- streamFn: engineStreamSimple,
39
- ...options,
43
+ ...agentOptions,
44
+ streamFn: onStreamInvocation
45
+ ? (...args) => {
46
+ onStreamInvocation();
47
+ return streamFn(...args);
48
+ }
49
+ : streamFn,
40
50
  afterToolCall: dispositionAwareAfterToolCall(options.afterToolCall),
41
51
  });
42
52
  return {