@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
@@ -0,0 +1,35 @@
1
+ import { BusChannels } from "../core/bus-events.js";
2
+ import type { SafeEventBus } from "../core/event-bus.js";
3
+ import type { TaskMemoryStepUsage } from "../domains/memory/task-memory-policy.js";
4
+ import type { MemoryInterventionRegistration } from "../domains/middleware/memory-intervention.js";
5
+ import {
6
+ type RecordBackgroundMemoryStepInput,
7
+ recordBackgroundMemoryStep,
8
+ } from "../domains/observability/background-memory-usage.js";
9
+
10
+ /** Explicit navigation owns memory lifetime; ordinary leaf advances and tree reads do not. */
11
+ export function bindTaskMemoryLifecycle(
12
+ bus: SafeEventBus,
13
+ memory: Pick<MemoryInterventionRegistration, "reset" | "dispose">,
14
+ ): () => void {
15
+ const unsubscribe = [
16
+ bus.on(BusChannels.SessionParked, () => memory.reset()),
17
+ bus.on(BusChannels.SessionResumed, () => memory.reset()),
18
+ bus.on(BusChannels.SessionTurnSwitched, () => memory.reset()),
19
+ bus.on(BusChannels.SessionEnd, () => memory.dispose()),
20
+ ];
21
+ return () => {
22
+ memory.dispose();
23
+ for (const off of unsubscribe) off();
24
+ };
25
+ }
26
+
27
+ /** The durable row keeps launch identity even when the live cost tracker has moved on. */
28
+ export function captureTaskMemoryUsage(
29
+ input: Omit<RecordBackgroundMemoryStepInput, "usage">,
30
+ ): (usage: TaskMemoryStepUsage, isCurrent: boolean) => void {
31
+ const { observability, ...origin } = input;
32
+ return (usage, isCurrent) => {
33
+ recordBackgroundMemoryStep({ ...origin, usage, observability: isCurrent ? observability : undefined });
34
+ };
35
+ }
@@ -18,11 +18,12 @@ const CLOSED_ACTION_ORDER = [
18
18
  "clio-coder.thinking.expandAll",
19
19
  ] as const satisfies ReadonlyArray<ClioKeybinding>;
20
20
 
21
- const GLOBAL_ACTION_ORDER = [
21
+ export const GLOBAL_ACTION_ORDER = [
22
22
  "clio-coder.status.toggle",
23
23
  "clio-coder.thinking.cycle",
24
24
  "clio-coder.session.tree",
25
25
  "clio-coder.dispatchBoard.toggle",
26
+ "clio-coder.files.toggle",
26
27
  "clio-coder.tasks.open",
27
28
  "clio-coder.decisions.open",
28
29
  "clio-coder.dispatch.background",
@@ -72,7 +72,7 @@ function isSafetyBlockedPayload(value: unknown): value is SafetyBlockedPayload {
72
72
  function isMiddlewareHookFailedPayload(value: unknown): value is MiddlewareHookFailedPayload {
73
73
  if (!value || typeof value !== "object") return false;
74
74
  const p = value as Record<string, unknown>;
75
- if (p.kind !== "hook_failed" && p.kind !== "budget_exceeded") return false;
75
+ if (p.kind !== "hook_failed" && p.kind !== "budget_exceeded" && p.kind !== "registration_conflict") return false;
76
76
  if (typeof p.registrationId !== "string" || p.registrationId.length === 0) return false;
77
77
  if (typeof p.hook !== "string" || p.hook.length === 0) return false;
78
78
  if (p.message !== undefined && typeof p.message !== "string") return false;
@@ -142,6 +142,13 @@ function middlewareHookFailedNotice(
142
142
  options: MiddlewareHookFailedNoticeOptions = {},
143
143
  ): BusNotice | null {
144
144
  if (!isMiddlewareHookFailedPayload(payload)) return null;
145
+ if (payload.kind === "registration_conflict") {
146
+ const detail =
147
+ payload.message !== undefined && payload.message.length > 0
148
+ ? payload.message
149
+ : `registration '${payload.registrationId}' conflicts with an existing id`;
150
+ return { level: "warn", text: `[middleware] ${detail}` };
151
+ }
145
152
  if (payload.kind === "hook_failed") {
146
153
  const detail = payload.message !== undefined && payload.message.length > 0 ? `: ${payload.message}` : "";
147
154
  return {
@@ -21,12 +21,13 @@ import {
21
21
  } from "../core/response-model-id.js";
22
22
  import type { PendingSkillRequest, PendingSkillToolPolicy, SkillDeclaredToolPolicy } from "../core/skill-activation.js";
23
23
  import { ToolNames } from "../core/tool-names.js";
24
- import { canonicalJson, sha256 } from "../domains/prompts/hash.js";
24
+ import { sha256 } from "../domains/prompts/hash.js";
25
25
  import { toContextOverflowError } from "../domains/providers/errors.js";
26
26
  import type { ResolvedRuntimeTarget } from "../domains/providers/index.js";
27
27
  import { ceilChars, extractReasoningTokens } from "../domains/session/context-accounting.js";
28
28
  import type { AgentMessage } from "../engine/types.js";
29
29
  import type { AskUserToolPolicy } from "../tools/registry.js";
30
+ import { attachedToolSchemaBytes, attachedToolSchemasFromState } from "./prompt-cache-identity.js";
30
31
 
31
32
  /** Minimal structural view of the engine agent used by state-inspection helpers. */
32
33
  export interface AgentStateView {
@@ -291,18 +292,7 @@ export function pendingSkillRequestPreamble(requests: ReadonlyArray<PendingSkill
291
292
  * tool-surface change.
292
293
  */
293
294
  export function toolSignatureFromState(tools: ReadonlyArray<unknown>): string {
294
- const schemas: Array<{ name: string; description: string; parameters: unknown }> = [];
295
- for (const tool of tools) {
296
- if (!tool || typeof tool !== "object" || Array.isArray(tool)) continue;
297
- const record = tool as Record<string, unknown>;
298
- schemas.push({
299
- name: typeof record.name === "string" ? record.name : "",
300
- description: typeof record.description === "string" ? record.description : "",
301
- parameters: record.parameters ?? null,
302
- });
303
- }
304
- schemas.sort((a, b) => a.name.localeCompare(b.name));
305
- return sha256(canonicalJson(schemas));
295
+ return sha256(attachedToolSchemaBytes(attachedToolSchemasFromState(tools)));
306
296
  }
307
297
 
308
298
  /**
@@ -481,11 +471,11 @@ export function backendCacheVerdict(
481
471
  return classifyCacheUsage(input, cacheRead);
482
472
  }
483
473
 
484
- /** Per-API-call latency captured from the agent event stream (T3.2). */
474
+ /** Native stream-invocation latency, measured on one monotonic clock. */
485
475
  export interface AssistantCallTiming {
486
- /** message_start first assistant delta; null when no delta arrived. */
476
+ /** Invocation to first assistant output; null when no output arrived. */
487
477
  ttftMs: number | null;
488
- /** message_start message_end for the same assistant API call. */
478
+ /** Invocation to message_end for the same assistant API call. */
489
479
  apiMs: number;
490
480
  }
491
481
 
@@ -500,7 +490,16 @@ export function assistantSessionPayload(
500
490
  if (Array.isArray(raw.content)) payload.content = raw.content;
501
491
  if (thinking.length > 0) payload.thinking = thinking;
502
492
  payload.responseModelIdObservation = responseModelIdObservationFromRecord(raw, "not-observed");
503
- for (const key of ["usage", "api", "provider", "model", "responseModel", "responseId", "diagnostics"]) {
493
+ for (const key of [
494
+ "usage",
495
+ "api",
496
+ "provider",
497
+ "model",
498
+ "responseModel",
499
+ "responseId",
500
+ "gatewayRouting",
501
+ "diagnostics",
502
+ ]) {
504
503
  if (raw[key] !== undefined) payload[key] = raw[key];
505
504
  }
506
505
  if (failure && !isSelfExplainingAbort({ stopReason: raw.stopReason, errorMessage: raw.errorMessage, text })) {
@@ -16,7 +16,14 @@
16
16
  import { BusChannels, type RunAbortSource } from "../core/bus-events.js";
17
17
  import type { ClioSettings } from "../core/config.js";
18
18
  import type { SafeEventBus } from "../core/event-bus.js";
19
- import type { PendingSkillRequest } from "../core/skill-activation.js";
19
+ import {
20
+ armedSkillSurface,
21
+ type PendingSkillRequest,
22
+ type PendingSkillToolPolicy,
23
+ skillSurfaceLabels,
24
+ skillSurfaceNames,
25
+ withModelSkillActivation,
26
+ } from "../core/skill-activation.js";
20
27
  import { clioStateDir } from "../core/xdg.js";
21
28
  import {
22
29
  createMiddlewareToolChoiceControl,
@@ -36,6 +43,7 @@ import {
36
43
  runtimeTargetSnapshot,
37
44
  targetRequiresAuth,
38
45
  } from "../domains/providers/index.js";
46
+ import { type AutonomyLevel, modelMayActivateSkills } from "../domains/safety/autonomy.js";
39
47
  import type { ProtectedArtifactState } from "../domains/safety/protected-artifacts.js";
40
48
  import type { CompactResult } from "../domains/session/compaction/compact.js";
41
49
  import type { ContextSnapshot, ContextUsageSnapshot } from "../domains/session/context-accounting.js";
@@ -285,6 +293,12 @@ export interface ChatLoop {
285
293
  * queues the text for the next slot instead.
286
294
  */
287
295
  interruptRefusal(): string | null;
296
+ /**
297
+ * `/skill off`: drop the tool surface an activated skill armed, so the next
298
+ * turn runs with the full surface again. Returns the skill names that were
299
+ * armed, or an empty list when nothing was.
300
+ */
301
+ clearSkillSurface(): ReadonlyArray<string>;
288
302
  clearQueuedFollowUps(): string[];
289
303
  queuedMessages(): QueuedMessagesSnapshot;
290
304
  cancel(options?: ChatCancelOptions): void;
@@ -368,6 +382,12 @@ export interface ChatLoop {
368
382
 
369
383
  export interface CreateChatLoopDeps {
370
384
  getSettings: () => Readonly<ClioSettings>;
385
+ /**
386
+ * The same effective autonomy level registry admission resolves, so the
387
+ * skill-activation gate and the tool gate can never disagree. Absent falls
388
+ * back to the settings value.
389
+ */
390
+ getAutonomy?: () => AutonomyLevel;
371
391
  providers: ProvidersContract;
372
392
  /**
373
393
  * Whitelist of target ids that the chat-loop is allowed to drive. The
@@ -622,6 +642,31 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
622
642
  emit({ type: "notice", level, surface: "transcript", text, ...(key === undefined ? {} : { key }) });
623
643
  };
624
644
 
645
+ /**
646
+ * Carry (or drop) the tool surface a skill declared once the turn that
647
+ * loaded it settles, and say so once on the transcript. The operator needs
648
+ * to know a narrowing is armed across their next messages, and needs one
649
+ * line back when it lifts; the skill-activation ledger entry already
650
+ * records provenance, so this is the notice, not a second UI.
651
+ */
652
+ const armSkillSurface = (policy: PendingSkillToolPolicy | undefined, loadedBefore?: ReadonlySet<string>): void => {
653
+ const previous = skillSurfaceNames(state.activeSkillSurface).join(", ");
654
+ const next = armedSkillSurface(policy);
655
+ const current = skillSurfaceNames(next).join(", ");
656
+ state.activeSkillSurface = next;
657
+ const activated = skillSurfaceLabels(policy).filter((label) => !loadedBefore?.has(label.split(" ")[0] ?? label));
658
+ if (activated.length > 0) {
659
+ emitNotice(
660
+ current.length > 0
661
+ ? `[Clio Coder] Skill activated: ${activated.join(", ")}. Its tool surface stays armed across your next turns until another skill replaces it or you run /skill off.`
662
+ : `[Clio Coder] Skill activated: ${activated.join(", ")}. It declares no tool narrowing.`,
663
+ );
664
+ }
665
+ if (current !== previous && current.length === 0 && previous.length > 0) {
666
+ emitNotice(`[Clio Coder] Skill tool surface cleared: ${previous}. The full tool surface is back.`);
667
+ }
668
+ };
669
+
625
670
  /**
626
671
  * The same transcript notice every admission exit already emitted, carrying
627
672
  * the reason the turn never started. Text, level, and surface are unchanged,
@@ -648,7 +693,9 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
648
693
  const retrySettings = (): RetrySettings => normalizeRetrySettings(deps.getSettings().chat.retry);
649
694
 
650
695
  const currentToolInvokeOptions = (): Partial<ToolInvokeOptions> => {
651
- const options: Partial<ToolInvokeOptions> = {};
696
+ const options: Partial<ToolInvokeOptions> = {
697
+ toolResultMaxBytes: deps.getSettings().context.toolResultMaxBytes,
698
+ };
652
699
  const sessionId = deps.session?.current()?.id ?? null;
653
700
  if (sessionId) options.sessionId = sessionId;
654
701
  const turnId = state.activeUserTurnId ?? state.lastTurnId;
@@ -743,6 +790,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
743
790
  context,
744
791
  middleware,
745
792
  retrySettings,
793
+ sessionId: () => deps.session?.current()?.id,
746
794
  emit: emitRuntimeEvent,
747
795
  emitNotice,
748
796
  toolStartTimes,
@@ -764,6 +812,12 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
764
812
  deps.bus?.on(BusChannels.ConfigHotReload, () => {
765
813
  context.invalidateSessionPromptCache();
766
814
  }) ?? null;
815
+ // A committed extension generation with new content can change the skill
816
+ // and prompt inputs the session prompt compiles from; same invalidation.
817
+ const unsubscribeExtensionsReload =
818
+ deps.bus?.on(BusChannels.ExtensionsReloaded, (payload) => {
819
+ if (payload.changed) context.invalidateSessionPromptCache();
820
+ }) ?? null;
767
821
 
768
822
  const unsubscribeSynthesisLock =
769
823
  deps.bus?.on(BusChannels.LoopBlocked, (payload) => {
@@ -951,6 +1005,11 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
951
1005
  steer: (text) => queues.steer(text),
952
1006
  queueFollowUp: (text) => queues.queueFollowUp(text),
953
1007
  interruptRefusal: () => (state.streaming ? interruptRefusalReason() : null),
1008
+ clearSkillSurface: () => {
1009
+ const cleared = skillSurfaceNames(state.activeSkillSurface);
1010
+ armSkillSurface(undefined);
1011
+ return cleared;
1012
+ },
954
1013
  clearQueuedFollowUps: () => queues.clearQueuedMirror().map((entry) => entry.text),
955
1014
  queuedMessages: () => queues.queuedMessages(),
956
1015
 
@@ -1035,7 +1094,18 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
1035
1094
  const images = options.images && options.images.length > 0 ? [...options.images] : undefined;
1036
1095
  const pendingSkillRequests = options.pendingSkillRequests ?? [];
1037
1096
  context.addWorkingContextPaths(options.workingContextPaths ?? []);
1038
- const pendingSkillPolicy = createPendingSkillToolPolicy(pendingSkillRequests);
1097
+ // A skill the operator activated narrows the tools for the workflow
1098
+ // it started, and that workflow outlives the turn it began in. A
1099
+ // fresh /skill this turn replaces the armed surface; otherwise the
1100
+ // armed surface is what this turn runs under.
1101
+ const pendingSkillPolicy = withModelSkillActivation(
1102
+ createPendingSkillToolPolicy(pendingSkillRequests) ?? state.activeSkillSurface,
1103
+ modelMayActivateSkills(deps.getAutonomy?.() ?? deps.getSettings().safety.autonomy),
1104
+ );
1105
+ // What was already loaded when this turn started, so the settle-time
1106
+ // notice names the skills this turn activated and not the ones a
1107
+ // carried surface has been holding since an earlier message.
1108
+ const skillsLoadedBeforeTurn = new Set(pendingSkillPolicy?.loadedSkillNames ?? []);
1039
1109
  // Resolve the frozen session tool surface before turn_start so intent
1040
1110
  // middleware sees the exact tools this request can actually call.
1041
1111
  agentRuntime.agent.state.tools = resolveSessionTools(
@@ -1302,6 +1372,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
1302
1372
  }
1303
1373
  state.currentPendingSkillPolicy = priorPendingSkillPolicy;
1304
1374
  state.currentAskUserPolicy = priorAskUserPolicy;
1375
+ armSkillSurface(pendingSkillPolicy, skillsLoadedBeforeTurn);
1305
1376
  state.activeUserTurnId = null;
1306
1377
  // Safety net for thrown paths where agent_end never delivered;
1307
1378
  // no-op when the agent_end flush already ran.
@@ -1417,6 +1488,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
1417
1488
 
1418
1489
  dispose(): void {
1419
1490
  unsubscribeConfigReload?.();
1491
+ unsubscribeExtensionsReload?.();
1420
1492
  unsubscribeSynthesisLock?.();
1421
1493
  unsubscribePrewarmCompaction();
1422
1494
  prewarm.dispose();
@@ -603,30 +603,53 @@ function hasStreamingText(entry: Extract<TranscriptEntry, { role: "assistant" }>
603
603
  }
604
604
 
605
605
  /**
606
- * Split a reply that opens with the skill-suggestion protocol line into that
607
- * line and the answer beneath it.
606
+ * Locate the skill-suggestion protocol line inside a reply.
608
607
  *
609
- * The prompt asks the model to *begin its reply* with the suggestion, so the
610
- * usual shape is one segment holding both. Classifying that whole segment as
611
- * advisory left the turn with no voice glyph at all: the suggestion did not
612
- * claim it and the answer never got the chance. Returns null when the segment
613
- * is only a suggestion, which stays advisory in full.
608
+ * The prompt asks the model to begin its reply with the line, but a model
609
+ * that narrates its work first puts the line at the end of the final message
610
+ * about half the time (round-4 skill batches: 1/2 and 0/2 opened, 2/2 fired).
611
+ * The line is recognized at the start of any line, provided it is complete
612
+ * (a newline follows it, or the segment is finalized), so a partially
613
+ * streamed line stays ordinary prose until it is whole. Returns the line's
614
+ * byte range or null.
615
+ */
616
+ function findSkillSuggestionLine(seg: TextSegment): { start: number; end: number } | null {
617
+ const text = seg.text;
618
+ let at = text.startsWith(SKILL_SUGGESTION_PREFIX) ? 0 : text.indexOf(`\n${SKILL_SUGGESTION_PREFIX}`);
619
+ if (at < 0) return null;
620
+ if (at > 0) at += 1;
621
+ const lineEnd = text.indexOf("\n", at);
622
+ if (lineEnd < 0) return seg.finalized ? { start: at, end: text.length } : null;
623
+ return { start: at, end: lineEnd };
624
+ }
625
+
626
+ /**
627
+ * Split a reply that carries the skill-suggestion protocol line into that
628
+ * line and the answer around it.
629
+ *
630
+ * The usual shape is one segment holding both. Classifying that whole segment
631
+ * as advisory left the turn with no voice glyph at all: the suggestion did not
632
+ * claim it and the answer never got the chance. The suggestion renders first
633
+ * wherever the model put it, and the answer is the rest of the segment with
634
+ * that line removed. Returns null when the segment is only a suggestion,
635
+ * which stays advisory in full.
614
636
  */
615
637
  function skillSuggestionSplit(seg: TextSegment): { suggestion: string; answer: TextSegment } | null {
616
- if (!seg.text.startsWith(SKILL_SUGGESTION_PREFIX)) return null;
617
- const breakIndex = seg.text.indexOf("\n");
618
- if (breakIndex < 0) return null;
638
+ const found = findSkillSuggestionLine(seg);
639
+ if (!found) return null;
640
+ const before = seg.text.slice(0, found.start).replace(/\n+$/, "");
641
+ const after = seg.text.slice(found.end + 1).replace(/^\n+/, "");
619
642
  // A model that puts a blank line between the suggestion and the answer left
620
643
  // the remainder opening with a newline, so the first rendered row was empty
621
644
  // and took the glyph the answer's own text row was owed.
622
- const answerText = seg.text.slice(breakIndex + 1).replace(/^\n+/, "");
645
+ const answerText = before.length > 0 && after.length > 0 ? `${before}\n${after}` : before + after;
623
646
  if (answerText.trim().length === 0) return null;
624
647
  const split = seg.suggestionSplit ?? {
625
648
  suggestion: "",
626
649
  answer: { kind: "text", text: answerText, finalized: seg.finalized } as TextSegment,
627
650
  };
628
651
  seg.suggestionSplit = split;
629
- split.suggestion = seg.text.slice(0, breakIndex);
652
+ split.suggestion = seg.text.slice(found.start, found.end).replace(/\r$/, "");
630
653
  const answer = split.answer;
631
654
  if (answer.text === answerText && answer.finalized === seg.finalized) return split;
632
655
  // The answer half follows the same cache rules as any other segment: the
@@ -1113,7 +1136,7 @@ function renderEntryLines(
1113
1136
  const rendered =
1114
1137
  seg.kind === "text" ? renderTextSegmentLines(seg, proseWidth) : renderErrorSegmentLines(seg, proseWidth);
1115
1138
  if (rendered.length === 0) continue;
1116
- const isSkillSuggestion = seg.kind === "text" && seg.text.startsWith(SKILL_SUGGESTION_PREFIX);
1139
+ const isSkillSuggestion = seg.kind === "text" && findSkillSuggestionLine(seg) !== null;
1117
1140
  if (!labeled && !isSkillSuggestion) {
1118
1141
  lines.push(...hangProseLines(rendered, clioPrefix));
1119
1142
  labeled = true;
@@ -451,6 +451,7 @@ function richMessageFromEntry(entry: MessageEntry, maxTextChars?: number): Agent
451
451
  "responseModelIdObservation",
452
452
  "responseModel",
453
453
  "responseId",
454
+ "gatewayRouting",
454
455
  "diagnostics",
455
456
  "contextUsageInvalidated",
456
457
  ]) {
@@ -460,15 +461,73 @@ function richMessageFromEntry(entry: MessageEntry, maxTextChars?: number): Agent
460
461
  return message as unknown as AgentMessage;
461
462
  }
462
463
 
463
- function recordToolCallsFromMessage(message: AgentMessage, seen: Set<string>): void {
464
+ function toolCallIdsFromMessage(message: AgentMessage): string[] {
464
465
  const content = (message as { content?: unknown }).content;
465
- if (!Array.isArray(content)) return;
466
+ if (!Array.isArray(content)) return [];
467
+ const ids: string[] = [];
466
468
  for (const block of content) {
467
469
  if (!block || typeof block !== "object") continue;
468
470
  const b = block as Record<string, unknown>;
469
471
  if (b.type !== "toolCall") continue;
470
- if (typeof b.id === "string" && b.id.length > 0) seen.add(b.id);
472
+ if (typeof b.id === "string" && b.id.length > 0) ids.push(b.id);
471
473
  }
474
+ return ids;
475
+ }
476
+
477
+ function recordToolCallsFromMessage(message: AgentMessage, seen: Set<string>): void {
478
+ for (const id of toolCallIdsFromMessage(message)) seen.add(id);
479
+ }
480
+
481
+ /**
482
+ * Replay sink that hands tool results to the model in the order the assistant
483
+ * issued the calls.
484
+ *
485
+ * The ledger appends a tool result when its tool finishes, while the live loop
486
+ * appends a parallel batch's results by call index (pi executes the batch and
487
+ * pushes results in the assistant's order). A two-call turn whose second call
488
+ * finished first is therefore recorded as [b, a] and was sent as [a, b]. A
489
+ * resume that replayed the ledger order sent different bytes from that point
490
+ * on, and the provider's prefix cache missed for the rest of the session.
491
+ * Results are staged until the next non-result message and released in call
492
+ * order; an id the staged assistant turn never issued keeps its ledger order
493
+ * after the known ones.
494
+ */
495
+ function createOrderedReplaySink(): {
496
+ messages: AgentMessage[];
497
+ push(message: AgentMessage): void;
498
+ stageToolResult(message: AgentMessage): void;
499
+ flush(): void;
500
+ } {
501
+ const messages: AgentMessage[] = [];
502
+ let callOrder: string[] = [];
503
+ let staged: AgentMessage[] = [];
504
+ const rank = (message: AgentMessage): number => {
505
+ const id = (message as { toolCallId?: unknown }).toolCallId;
506
+ const index = typeof id === "string" ? callOrder.indexOf(id) : -1;
507
+ return index < 0 ? Number.MAX_SAFE_INTEGER : index;
508
+ };
509
+ const flush = (): void => {
510
+ if (staged.length === 0) return;
511
+ staged.sort((a, b) => rank(a) - rank(b));
512
+ messages.push(...staged);
513
+ staged = [];
514
+ callOrder = [];
515
+ };
516
+ return {
517
+ messages,
518
+ flush,
519
+ push(message) {
520
+ flush();
521
+ messages.push(message);
522
+ // Consecutive assistant messages (one legacy standalone tool_call entry
523
+ // per call) share one batch; anything else starts a new one.
524
+ if (message.role === "assistant") callOrder.push(...toolCallIdsFromMessage(message));
525
+ else callOrder = [];
526
+ },
527
+ stageToolResult(message) {
528
+ staged.push(message);
529
+ },
530
+ };
472
531
  }
473
532
 
474
533
  function toolCallMessageFromEntry(entry: MessageEntry): AgentMessage {
@@ -998,7 +1057,12 @@ function bashContextText(entry: BashExecutionEntry): string {
998
1057
  return bashExecutionToText(message);
999
1058
  }
1000
1059
 
1001
- function appendContextMessage(out: AgentMessage[], role: "user" | "assistant", text: string, timestamp: string): void {
1060
+ function appendContextMessage(
1061
+ out: { push(message: AgentMessage): void },
1062
+ role: "user" | "assistant",
1063
+ text: string,
1064
+ timestamp: string,
1065
+ ): void {
1002
1066
  const trimmed = text.trim();
1003
1067
  if (trimmed.length === 0) return;
1004
1068
  out.push(makeTextMessage(role, truncateReplayText(trimmed), timestamp));
@@ -1014,7 +1078,7 @@ export function buildReplayAgentMessagesFromTurns(
1014
1078
  turns: ReadonlyArray<SessionEntry>,
1015
1079
  options: RehydrateChatPanelOptions = {},
1016
1080
  ): AgentMessage[] {
1017
- const out: AgentMessage[] = [];
1081
+ const out = createOrderedReplaySink();
1018
1082
  const seenToolCalls = new Set<string>();
1019
1083
  for (const entry of selectReplayEntries(turns, options)) {
1020
1084
  switch (entry.kind) {
@@ -1035,7 +1099,7 @@ export function buildReplayAgentMessagesFromTurns(
1035
1099
  recordToolCallsFromMessage(message, seenToolCalls);
1036
1100
  }
1037
1101
  } else if (entry.role === "tool_result") {
1038
- out.push(toolResultMessageFromEntry(entry));
1102
+ out.stageToolResult(toolResultMessageFromEntry(entry));
1039
1103
  } else if (entry.role === "system") {
1040
1104
  appendContextMessage(out, "user", `System note: ${text}`, entry.timestamp);
1041
1105
  }
@@ -1082,7 +1146,8 @@ export function buildReplayAgentMessagesFromTurns(
1082
1146
  break;
1083
1147
  }
1084
1148
  }
1085
- return out;
1149
+ out.flush();
1150
+ return out.messages;
1086
1151
  }
1087
1152
 
1088
1153
  /**
@@ -46,6 +46,7 @@ export interface CostRow {
46
46
  prewarms: number;
47
47
  /** Calls in this row that were proactive-memory steps on the background target. */
48
48
  backgroundMemory: number;
49
+ failedCompaction: number;
49
50
  cost: CostAggregate;
50
51
  }
51
52
 
@@ -79,6 +80,7 @@ export function aggregateCostEntries(entries: ReadonlyArray<CostEntry>): CostRow
79
80
  if (entry.label === "handoff") existing.row.handoffs += 1;
80
81
  if (entry.label === "prewarm") existing.row.prewarms += 1;
81
82
  if (entry.label === "background-memory") existing.row.backgroundMemory += 1;
83
+ if (entry.label === "failed-compaction") existing.row.failedCompaction += 1;
82
84
  for (const requestedModelId of entry.requestedModelIds) existing.requestedModelIds.add(requestedModelId);
83
85
  addResponseModelIdObservationCounts(
84
86
  existing.responseModelIdObservationCounts,
@@ -103,6 +105,7 @@ export function aggregateCostEntries(entries: ReadonlyArray<CostEntry>): CostRow
103
105
  handoffs: entry.label === "handoff" ? 1 : 0,
104
106
  prewarms: entry.label === "prewarm" ? 1 : 0,
105
107
  backgroundMemory: entry.label === "background-memory" ? 1 : 0,
108
+ failedCompaction: entry.label === "failed-compaction" ? 1 : 0,
106
109
  },
107
110
  requestedModelIds: new Set(entry.requestedModelIds),
108
111
  responseModelIdObservationCounts: { ...entry.responseModelIdObservationCounts },
@@ -143,6 +146,7 @@ function sumRows(
143
146
  handoffs: acc.handoffs + row.handoffs,
144
147
  prewarms: acc.prewarms + row.prewarms,
145
148
  backgroundMemory: acc.backgroundMemory + row.backgroundMemory,
149
+ failedCompaction: acc.failedCompaction + row.failedCompaction,
146
150
  }),
147
151
  {
148
152
  runs: 0,
@@ -157,6 +161,7 @@ function sumRows(
157
161
  handoffs: 0,
158
162
  prewarms: 0,
159
163
  backgroundMemory: 0,
164
+ failedCompaction: 0,
160
165
  },
161
166
  );
162
167
  }
@@ -229,13 +234,26 @@ function summaryBlock(
229
234
  return kvBlock([
230
235
  [
231
236
  "turns",
232
- formatTokens(totals.runs - totals.sideQuestions - totals.handoffs - totals.prewarms - totals.backgroundMemory),
237
+ formatTokens(
238
+ totals.runs -
239
+ totals.sideQuestions -
240
+ totals.handoffs -
241
+ totals.prewarms -
242
+ totals.backgroundMemory -
243
+ totals.failedCompaction,
244
+ ),
233
245
  ],
234
246
  ["model calls", formatTokens(totals.apiCalls)],
235
247
  ...(totals.sideQuestions > 0 ? [["side questions", formatTokens(totals.sideQuestions)] as const] : []),
236
248
  ...(totals.handoffs > 0 ? [["handoffs", formatTokens(totals.handoffs)] as const] : []),
237
249
  ...(totals.prewarms > 0 ? [["pre-warms", formatTokens(totals.prewarms)] as const] : []),
238
250
  ...(totals.backgroundMemory > 0 ? [["memory steps", formatTokens(totals.backgroundMemory)] as const] : []),
251
+ ...(totals.failedCompaction > 0
252
+ ? [
253
+ ["failed compaction calls", formatTokens(totals.failedCompaction)] as const,
254
+ ["compaction usage", "known subtotals; missing usage is unknown"] as const,
255
+ ]
256
+ : []),
239
257
  ...(cost === null ? [] : [["cost", cost] as const]),
240
258
  ["input", formatTokens(totals.input)],
241
259
  ["output", formatTokens(totals.output)],
@@ -255,12 +273,18 @@ function modelBlock(row: CostRow): string[] {
255
273
  return kvBlock([
256
274
  ["requested model ids", row.requestedModelIds.join(", ")],
257
275
  ["response model id observation", responseModelIdObservationCountsLabel(row.responseModelIdObservationCounts)],
258
- ["turns", formatTokens(row.runs - row.sideQuestions - row.handoffs - row.prewarms - row.backgroundMemory)],
276
+ [
277
+ "turns",
278
+ formatTokens(
279
+ row.runs - row.sideQuestions - row.handoffs - row.prewarms - row.backgroundMemory - row.failedCompaction,
280
+ ),
281
+ ],
259
282
  ["model calls", formatTokens(row.apiCalls)],
260
283
  ...(row.sideQuestions > 0 ? [["side questions", formatTokens(row.sideQuestions)] as const] : []),
261
284
  ...(row.handoffs > 0 ? [["handoffs", formatTokens(row.handoffs)] as const] : []),
262
285
  ...(row.prewarms > 0 ? [["pre-warms", formatTokens(row.prewarms)] as const] : []),
263
286
  ...(row.backgroundMemory > 0 ? [["memory steps", formatTokens(row.backgroundMemory)] as const] : []),
287
+ ...(row.failedCompaction > 0 ? [["failed compaction calls", formatTokens(row.failedCompaction)] as const] : []),
264
288
  ...(cost === null ? [] : [["cost", cost] as const]),
265
289
  ["input", formatTokens(row.input)],
266
290
  ["output", formatTokens(row.output)],
@@ -6,6 +6,7 @@ import {
6
6
  type DispatchProgressPayload,
7
7
  type DispatchRunIdentity,
8
8
  } from "../core/bus-events.js";
9
+ import { resolveDispatchFailureStatus } from "../core/dispatch-outcome.js";
9
10
  import type { SafeEventBus } from "../core/event-bus.js";
10
11
  import { rawDurationMs } from "../core/timers.js";
11
12
  import type { AgentAudience } from "../domains/agents/spec.js";
@@ -37,7 +38,7 @@ import {
37
38
  type ObservabilityNotice,
38
39
  type ObservabilitySnapshot,
39
40
  } from "../domains/observability/index.js";
40
- import { type CostProvenance, foregroundStreamUsage } from "../domains/providers/index.js";
41
+ import { type CostProvenance, foregroundStreamUsage, resolveCostProvenance } from "../domains/providers/index.js";
41
42
  import { sanitizeCallTargetText } from "../domains/safety/call-target.js";
42
43
  import { type Component, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "../engine/tui.js";
43
44
  import { formatWorkerContextMeter } from "./context-meter.js";
@@ -121,7 +122,7 @@ export interface DispatchBoardRow {
121
122
  gate?: { role: string; cycle: number };
122
123
  council?: { group: string; label: string; color?: string; round: number };
123
124
  /** Orchestrator-executed declared verification status. */
124
- hostVerification?: "verified" | "rejected" | "skipped";
125
+ hostVerification?: "verified" | "rejected" | "skipped" | "not_implicated";
125
126
  /**
126
127
  * The canonical trust projection of the sealed receipt, read back from
127
128
  * disk and authenticated against the ledger row. Absent while the run is
@@ -1285,12 +1286,6 @@ function resolveAgentEndStatus(rawMessages: unknown): DispatchBoardStatus | null
1285
1286
  return null;
1286
1287
  }
1287
1288
 
1288
- function resolveFailedStatus(reason: unknown): DispatchBoardStatus {
1289
- if (reason === "dead" || reason === "stalled") return "dead";
1290
- if (reason === "interrupted" || reason === "canceled") return "aborted";
1291
- return "failed";
1292
- }
1293
-
1294
1289
  function resolveFailureDetail(
1295
1290
  payload: Partial<DispatchFailedPayload>,
1296
1291
  fallback: string | null | undefined,
@@ -1601,7 +1596,7 @@ export function createDispatchBoardStore(
1601
1596
  entry.durationMs = parseFiniteNumber(payload.durationMs, Math.max(0, rawDurationMs(entry.startedAtMs, now)));
1602
1597
  entry.tokenCount = parseFiniteNumber(payload.tokenCount, entry.tokenCount);
1603
1598
  entry.costUsd = parseFiniteNumber(payload.costUsd, entry.costUsd);
1604
- entry.costProvenance = payload.costProvenance ?? "unknown";
1599
+ entry.costProvenance = resolveCostProvenance(payload.costProvenance, entry.costProvenance ?? "unknown");
1605
1600
  entry.outcomeDetail = null;
1606
1601
  if (payload.hostVerification !== undefined) entry.hostVerification = payload.hostVerification;
1607
1602
  settleFromReceipt(entry);
@@ -1621,7 +1616,7 @@ export function createDispatchBoardStore(
1621
1616
  const payload: Partial<DispatchFailedPayload> = raw ?? {};
1622
1617
  const runId = parseRunId(payload.runId);
1623
1618
  const previousStatus = runId !== null ? entries.get(runId)?.status : undefined;
1624
- const resolvedStatus = resolveFailedStatus(payload.reason);
1619
+ const resolvedStatus = resolveDispatchFailureStatus(payload.reason);
1625
1620
  const status = previousStatus === "dead" && resolvedStatus === "failed" ? "dead" : resolvedStatus;
1626
1621
  const entry = upsertBase(payload, status, now);
1627
1622
  if (!entry) return;
@@ -1630,7 +1625,7 @@ export function createDispatchBoardStore(
1630
1625
  entry.durationMs = parseFiniteNumber(payload.durationMs, Math.max(0, rawDurationMs(entry.startedAtMs, now)));
1631
1626
  entry.tokenCount = parseFiniteNumber(payload.tokenCount, entry.tokenCount);
1632
1627
  entry.costUsd = parseFiniteNumber(payload.costUsd, entry.costUsd);
1633
- entry.costProvenance = payload.costProvenance ?? "unknown";
1628
+ entry.costProvenance = resolveCostProvenance(payload.costProvenance, entry.costProvenance ?? "unknown");
1634
1629
  entry.outcomeDetail = resolveFailureDetail(payload, entry.outcomeDetail);
1635
1630
  if (payload.hostVerification !== undefined) entry.hostVerification = payload.hostVerification;
1636
1631
  settleFromReceipt(entry);