@iowarp/clio-coder 0.3.0 → 0.3.2

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 (1187) hide show
  1. package/CHANGELOG.md +123 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +295 -627
  4. package/dist/acp-BIYHVZIM.js +128 -0
  5. package/dist/{agents-Q4MYPMUW.js → agents-YT6SSRIT.js} +52 -27
  6. package/dist/assets/codewiki.json +1 -0
  7. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
  8. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
  9. package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
  10. package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
  11. package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
  12. package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
  13. package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
  14. package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
  15. package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
  16. package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
  17. package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
  18. package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
  19. package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
  20. package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
  21. package/dist/assets/grammars/tree-sitter.wasm +0 -0
  22. package/dist/{auth-O6HYIJ6J.js → auth-5TWEIYDN.js} +30 -15
  23. package/dist/chunk-2EHAIA3X.js +481 -0
  24. package/dist/{chunk-ME6DNWIU.js → chunk-2IR2NMPA.js} +12 -4
  25. package/dist/chunk-2SFS6XQE.js +122 -0
  26. package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
  27. package/dist/chunk-2VTFPG5O.js +48 -0
  28. package/dist/chunk-3I7MS7N2.js +40 -0
  29. package/dist/chunk-3R73A4XB.js +69 -0
  30. package/dist/{chunk-JPOWPFCU.js → chunk-3ZXDFGR5.js} +52 -23
  31. package/dist/chunk-4BJ5BYCE.js +61 -0
  32. package/dist/{chunk-26BZQOAD.js → chunk-4BPJXDWC.js} +161 -260
  33. package/dist/chunk-4KLWL3UC.js +18 -0
  34. package/dist/{chunk-5LDRNKX2.js → chunk-4VP4KH3K.js} +161 -262
  35. package/dist/chunk-4ZG3XFUR.js +77 -0
  36. package/dist/chunk-5B2AEOW5.js +5407 -0
  37. package/dist/chunk-5TSRNF4G.js +510 -0
  38. package/dist/{chunk-WD6AJM35.js → chunk-5UUP6MWO.js} +48 -69
  39. package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
  40. package/dist/chunk-65DEGPJ6.js +52 -0
  41. package/dist/chunk-6EJMN2Y3.js +17 -0
  42. package/dist/chunk-6EJV5X2W.js +16405 -0
  43. package/dist/chunk-6N5PTWMY.js +136 -0
  44. package/dist/chunk-6XLNIQDB.js +27 -0
  45. package/dist/{chunk-XNISANGE.js → chunk-77VKQEHF.js} +171 -74
  46. package/dist/chunk-7CR24IG7.js +242 -0
  47. package/dist/{chunk-UWIJNAOB.js → chunk-7EYHLWU7.js} +907 -638
  48. package/dist/chunk-7MNJORFF.js +22 -0
  49. package/dist/{chunk-JWHCJDCI.js → chunk-A3CYT5EX.js} +257 -79
  50. package/dist/chunk-AGYYIBLL.js +1069 -0
  51. package/dist/chunk-AO4RKG4M.js +277 -0
  52. package/dist/chunk-APJ265NV.js +7410 -0
  53. package/dist/chunk-ARBGF5F7.js +174 -0
  54. package/dist/{chunk-TFSSEXL6.js → chunk-BMEMKKIT.js} +14 -4
  55. package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
  56. package/dist/chunk-CBCAPZAA.js +229 -0
  57. package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
  58. package/dist/chunk-CMZWFGD2.js +352 -0
  59. package/dist/chunk-ECH6PKUQ.js +39 -0
  60. package/dist/{chunk-67MTHP2E.js → chunk-ED4KHGC3.js} +13 -5
  61. package/dist/chunk-EKMEHE4H.js +340 -0
  62. package/dist/{chunk-O4EJEDHO.js → chunk-EPVUXGXG.js} +50 -35
  63. package/dist/chunk-FCSXB6T2.js +338 -0
  64. package/dist/chunk-FJ3H4MN5.js +48 -0
  65. package/dist/chunk-FQ4SKYE4.js +29 -0
  66. package/dist/chunk-G2DE3C7R.js +644 -0
  67. package/dist/chunk-G4BMMOKF.js +182 -0
  68. package/dist/{chunk-7BHLZB3A.js → chunk-GGXXDWE4.js} +190 -1218
  69. package/dist/chunk-HC4CLZ2Y.js +68 -0
  70. package/dist/{chunk-E3NYWENM.js → chunk-HFSBBKSQ.js} +55 -61
  71. package/dist/chunk-HKIYEGME.js +30 -0
  72. package/dist/chunk-I4HZDVNP.js +73 -0
  73. package/dist/chunk-IGLFWIYI.js +161 -0
  74. package/dist/chunk-IHXBNWMM.js +137 -0
  75. package/dist/chunk-IKCO5N3L.js +162 -0
  76. package/dist/chunk-IR4CFBFN.js +56 -0
  77. package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
  78. package/dist/{chunk-VOO7NYPP.js → chunk-J5HN4RYU.js} +27 -9
  79. package/dist/{chunk-4UQA7NCT.js → chunk-J5Q24KAG.js} +7 -2
  80. package/dist/{chunk-KBR4MZZR.js → chunk-JVCV3ICN.js} +7 -1
  81. package/dist/chunk-KJ5LWLOE.js +1077 -0
  82. package/dist/chunk-LBMZMYH2.js +285 -0
  83. package/dist/{chunk-3DANZDGR.js → chunk-LBNRH5WM.js} +100 -161
  84. package/dist/{chunk-TKHQ4DGZ.js → chunk-LZSJBIVT.js} +7358 -7414
  85. package/dist/{chunk-UGYAX5YI.js → chunk-M6SHUN7Q.js} +13 -8
  86. package/dist/chunk-MAW544W2.js +1882 -0
  87. package/dist/chunk-MBS4V7ZP.js +217 -0
  88. package/dist/{chunk-2J63S4SF.js → chunk-MFFY33HR.js} +167 -140
  89. package/dist/chunk-MNA4JGU4.js +255 -0
  90. package/dist/chunk-MQSRRFWA.js +3428 -0
  91. package/dist/{chunk-RQDWMVRB.js → chunk-MVVUPGPW.js} +138 -137
  92. package/dist/chunk-OAO4GE4M.js +619 -0
  93. package/dist/chunk-OHHN2SO4.js +5135 -0
  94. package/dist/chunk-OKGUZO2U.js +34 -0
  95. package/dist/{chunk-BBUH4VAA.js → chunk-OOJYHWRB.js} +60 -361
  96. package/dist/{chunk-D5YD55AR.js → chunk-OQ33BKR3.js} +12 -1
  97. package/dist/chunk-OQE5J4C6.js +73 -0
  98. package/dist/{chunk-AMFR5YA3.js → chunk-ORBHGJC5.js} +26 -12
  99. package/dist/chunk-POHLU5DW.js +1186 -0
  100. package/dist/chunk-QKMUKYO7.js +4961 -0
  101. package/dist/{chunk-7RBKDI66.js → chunk-QTYWRVRA.js} +104 -12
  102. package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
  103. package/dist/chunk-SRF2PJNW.js +184 -0
  104. package/dist/chunk-SST6Z5JA.js +80 -0
  105. package/dist/{chunk-XV4ZJ6ZM.js → chunk-STBPMHSX.js} +473 -1194
  106. package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
  107. package/dist/chunk-T6YILFSB.js +80 -0
  108. package/dist/chunk-TXOTCRLG.js +15 -0
  109. package/dist/chunk-TZTZS7QK.js +227 -0
  110. package/dist/chunk-UOV2BYIW.js +107 -0
  111. package/dist/{chunk-527KG6XR.js → chunk-V4RXGQ5Q.js} +72 -185
  112. package/dist/chunk-VAKQQHWR.js +434 -0
  113. package/dist/chunk-VG7TBQIY.js +128 -0
  114. package/dist/chunk-VJWL6YS5.js +244 -0
  115. package/dist/chunk-WEH5XRJQ.js +32 -0
  116. package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
  117. package/dist/chunk-WMSVI4G2.js +2095 -0
  118. package/dist/chunk-WVO7V2QY.js +797 -0
  119. package/dist/chunk-X4RCMKVQ.js +641 -0
  120. package/dist/chunk-X75S7HFS.js +374 -0
  121. package/dist/chunk-XN3L4EYL.js +46 -0
  122. package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
  123. package/dist/{chunk-PIDUD6M2.js → chunk-YCWGATWI.js} +12 -5
  124. package/dist/chunk-YHZX5GEU.js +193 -0
  125. package/dist/chunk-YXLYO42X.js +91 -0
  126. package/dist/{chunk-UHTSULZS.js → chunk-ZDOOVTXZ.js} +38 -73
  127. package/dist/chunk-ZI647VB5.js +37 -0
  128. package/dist/{chunk-CLJ5HLUD.js → chunk-ZWLZP4ZT.js} +25 -6
  129. package/dist/cli/index.js +70 -56
  130. package/dist/clio-4LY5K2AC.js +25 -0
  131. package/dist/code-nav-7AX6FYE6.js +600 -0
  132. package/dist/codewiki/build-worker.js +66 -0
  133. package/dist/compile-cache-CVJMMODC.js +18 -0
  134. package/dist/{components-JVHMUBEB.js → components-KELWS457.js} +31 -9
  135. package/dist/{config-ZFCDBMDC.js → config-GTLUW2PR.js} +104 -56
  136. package/dist/configure-R6A64DHX.js +42 -0
  137. package/dist/context-5VKGUVJJ.js +866 -0
  138. package/dist/{context-CDXTP2MP.js → context-JFZEJ7W5.js} +21 -13
  139. package/dist/{context-E3KIFVXI.js → context-RW5HC47S.js} +77 -36
  140. package/dist/{context-clear-3F4PLXOS.js → context-clear-6ZHBAZZT.js} +64 -30
  141. package/dist/{context-index-Q7YSYTR3.js → context-index-BZ4UYMTC.js} +36 -24
  142. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  143. package/dist/{docs-YIETIWZI.js → docs-2C2LTVT2.js} +32 -13
  144. package/dist/doctor-KI767GSN.js +87 -0
  145. package/dist/{eval-B3KZZESM.js → eval-XSSNATB4.js} +93 -27
  146. package/dist/{evidence-V67CHM35.js → evidence-UA6AWDQQ.js} +55 -27
  147. package/dist/{evolve-YDZSUQYA.js → evolve-QNTFGV6Z.js} +59 -26
  148. package/dist/{extensions-SRG7XCAH.js → extensions-QVDOHDGJ.js} +23 -8
  149. package/dist/{fleet-CA2CRTVG.js → fleet-Q7UOMUSG.js} +173 -56
  150. package/dist/fleet-preflight-DDN536IT.js +26 -0
  151. package/dist/{init-2OZDJE2D.js → init-WBB65ZHQ.js} +79 -34
  152. package/dist/{memory-3PIQQAKX.js → memory-MD3O64RI.js} +57 -28
  153. package/dist/{models-DY35XI7Y.js → models-BZU34YWD.js} +49 -24
  154. package/dist/monitor-MEQA5C3I.js +661 -0
  155. package/dist/{chunk-PS4PFJQP.js → orchestrator-CGFKEP27.js} +22837 -18564
  156. package/dist/{paths-5OMXW7Z4.js → paths-UXLN5YYZ.js} +17 -6
  157. package/dist/preload-P6DGH2PZ.js +13 -0
  158. package/dist/{reset-PIFYNOS3.js → reset-L2FQEE3E.js} +25 -13
  159. package/dist/{run-3VSPP24F.js → run-IV4Q6RLN.js} +115 -63
  160. package/dist/{share-D36RQCXM.js → share-S5BZQC5I.js} +23 -10
  161. package/dist/{skills-F2MRLELY.js → skills-LQEKRDTN.js} +42 -15
  162. package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-3DC4HEWS.js} +90 -45
  163. package/dist/steer-GGWFUJUD.js +77 -0
  164. package/dist/{targets-DZMEZAH4.js → targets-C4SSGQOB.js} +78 -60
  165. package/dist/terminal-lease-IT5JW2NR.js +395 -0
  166. package/dist/{trace-7NYCUI2J.js → trace-PNCASAXC.js} +48 -17
  167. package/dist/tree-sitter-HGKH6LG4.js +4673 -0
  168. package/dist/{uninstall-AD3JWHBB.js → uninstall-FZCQCDKC.js} +19 -8
  169. package/dist/{upgrade-WYYBKGDY.js → upgrade-7TT7SQ3G.js} +66 -24
  170. package/dist/{usage-ULIDAGFF.js → usage-GV4PKT3M.js} +71 -32
  171. package/dist/verify-G6V4D2G7.js +716 -0
  172. package/dist/version-KGEG7EPO.js +21 -0
  173. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  174. package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-DQF6Z66B.js} +98 -48
  175. package/dist/worker/entry.js +297 -54
  176. package/dist/workspace-G4ZWUIPR.js +22 -0
  177. package/docs/README.md +29 -21
  178. package/docs/acp.md +191 -16
  179. package/docs/alcf-provider.md +1 -1
  180. package/docs/architecture.md +157 -7
  181. package/docs/artifact-placement.md +101 -0
  182. package/docs/artifact-versions.md +1 -1
  183. package/docs/built-in-agents.md +4 -2
  184. package/docs/capacity-and-scheduling.md +1 -1
  185. package/docs/commands-and-modes.md +224 -97
  186. package/docs/config-knobs-audit.md +1 -3
  187. package/docs/configuration-and-targets.md +236 -38
  188. package/docs/context-engine.md +34 -7
  189. package/docs/development-pipeline.md +102 -0
  190. package/docs/dispatch-architecture-rationale.md +1 -1
  191. package/docs/documentation-coverage.md +4 -4
  192. package/docs/documentation-guide.md +3 -3
  193. package/docs/environment-variables.md +15 -6
  194. package/docs/eval-runner.md +3 -3
  195. package/docs/evals-internal.md +2 -2
  196. package/docs/evidence-and-memory.md +10 -2
  197. package/docs/evolution.md +2 -2
  198. package/docs/exit-codes-and-output.md +15 -9
  199. package/docs/extensions-and-sharing.md +25 -18
  200. package/docs/fleet-demo-runbook.md +22 -23
  201. package/docs/fleet-dispatch.md +117 -16
  202. package/docs/git-commit-provenance.md +120 -0
  203. package/docs/glossary.md +107 -15
  204. package/docs/installation-and-lifecycle.md +75 -17
  205. package/docs/middleware-and-components.md +1 -1
  206. package/docs/model-catalog.md +46 -15
  207. package/docs/observability.md +8 -5
  208. package/docs/performance-methodology.md +491 -0
  209. package/docs/pi-boundary.md +72 -0
  210. package/docs/proactive-memory.md +14 -14
  211. package/docs/prompt-envelope-and-tools.md +25 -4
  212. package/docs/provider-adapter-cookbook.md +57 -4
  213. package/docs/release-cut-checklist.md +129 -111
  214. package/docs/safety-model.md +28 -8
  215. package/docs/scientific-validation.md +3 -3
  216. package/docs/session-lifecycle.md +55 -12
  217. package/docs/skills-marketplace.md +12 -8
  218. package/docs/time-conventions.md +101 -0
  219. package/docs/tool-usage.md +6 -5
  220. package/docs/trace-store.md +1 -1
  221. package/docs/troubleshooting.md +10 -7
  222. package/docs/tui-design.md +121 -28
  223. package/docs/worker-dispatch-mechanics.md +3 -3
  224. package/package.json +33 -36
  225. package/skills/README.md +5 -6
  226. package/skills/coding/ast-grep/SKILL.md +136 -0
  227. package/skills/coding/ast-grep/evals.md +56 -0
  228. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  229. package/skills/coding/coding-standards/SKILL.md +113 -0
  230. package/skills/coding/coding-standards/evals.md +34 -0
  231. package/skills/coding/prototype/SKILL.md +86 -0
  232. package/skills/coding/prototype/evals.md +42 -0
  233. package/skills/coding/prototype/references/LOGIC.md +67 -0
  234. package/skills/coding/prototype/references/UI.md +112 -0
  235. package/skills/coding/tdd/SKILL.md +101 -0
  236. package/skills/coding/tdd/evals.md +41 -0
  237. package/skills/coding/tdd/references/mocking.md +59 -0
  238. package/skills/coding/tdd/references/tests.md +77 -0
  239. package/skills/context/context-handoff/SKILL.md +126 -0
  240. package/skills/context/context-handoff/evals.md +57 -0
  241. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  242. package/skills/context/context-prime/SKILL.md +95 -0
  243. package/skills/context/context-prime/evals.md +54 -0
  244. package/skills/git/file-ticket/SKILL.md +107 -0
  245. package/skills/git/file-ticket/evals.md +54 -0
  246. package/skills/git/fix-issue/SKILL.md +106 -0
  247. package/skills/git/fix-issue/evals.md +71 -0
  248. package/skills/git/ship/SKILL.md +92 -0
  249. package/skills/git/ship/evals.md +72 -0
  250. package/skills/meta/clio-dev/SKILL.md +91 -0
  251. package/skills/meta/clio-dev/evals.md +45 -0
  252. package/skills/meta/clio-test/SKILL.md +130 -0
  253. package/skills/meta/clio-test/evals.md +43 -0
  254. package/skills/meta/clio-test/references/harness.md +97 -0
  255. package/skills/meta/clio-test/references/test-map.md +59 -0
  256. package/skills/meta/credentials/SKILL.md +125 -0
  257. package/skills/meta/credentials/evals.md +104 -0
  258. package/skills/meta/find-skills/SKILL.md +72 -0
  259. package/skills/meta/find-skills/evals.md +47 -0
  260. package/skills/meta/herdr/SKILL.md +127 -0
  261. package/skills/meta/herdr/evals.md +38 -0
  262. package/skills/meta/skill-craft/SKILL.md +102 -0
  263. package/skills/meta/skill-craft/evals.md +41 -0
  264. package/skills/planning/architecture/SKILL.md +129 -0
  265. package/skills/planning/architecture/evals.md +36 -0
  266. package/skills/planning/backlog/SKILL.md +90 -0
  267. package/skills/planning/backlog/evals.md +43 -0
  268. package/skills/planning/prd/SKILL.md +82 -0
  269. package/skills/planning/prd/evals.md +49 -0
  270. package/skills/planning/product-intent/SKILL.md +112 -0
  271. package/skills/planning/product-intent/evals.md +36 -0
  272. package/skills/planning/tech-spec/SKILL.md +115 -0
  273. package/skills/planning/tech-spec/evals.md +47 -0
  274. package/skills/registry.yaml +136 -0
  275. package/skills/research/arxiv-literature/SKILL.md +104 -0
  276. package/skills/research/arxiv-literature/evals.md +58 -0
  277. package/skills/research/experiment-protocol/SKILL.md +122 -0
  278. package/skills/research/experiment-protocol/evals.md +91 -0
  279. package/skills/research/scientific-debugging/SKILL.md +119 -0
  280. package/skills/research/scientific-debugging/evals.md +138 -0
  281. package/skills/research/scientific-modernization/SKILL.md +138 -0
  282. package/skills/research/scientific-modernization/evals.md +84 -0
  283. package/skills/skill-marketplace.json +12 -20
  284. package/skills/workflow/design-council/SKILL.md +139 -0
  285. package/skills/workflow/design-council/evals.md +97 -0
  286. package/skills/workflow/grill-me/SKILL.md +186 -0
  287. package/skills/workflow/grill-me/evals.md +78 -0
  288. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  289. package/skills/workflow/workflow-distiller/evals.md +107 -0
  290. package/src/cli/acp.ts +115 -0
  291. package/src/cli/agents.ts +60 -0
  292. package/src/cli/args.ts +280 -0
  293. package/src/cli/argv.ts +170 -0
  294. package/src/cli/ask.ts +34 -0
  295. package/src/cli/auth.ts +468 -0
  296. package/src/cli/bootstrap-generate.ts +498 -0
  297. package/src/cli/clio.ts +96 -0
  298. package/src/cli/components.ts +195 -0
  299. package/src/cli/config-inspect.ts +336 -0
  300. package/src/cli/config.ts +72 -0
  301. package/src/cli/configure-interop.ts +67 -0
  302. package/src/cli/configure-layout.ts +172 -0
  303. package/src/cli/configure.ts +1525 -0
  304. package/src/cli/context-clear.ts +76 -0
  305. package/src/cli/context-index.ts +100 -0
  306. package/src/cli/context.ts +321 -0
  307. package/src/cli/default-target.ts +55 -0
  308. package/src/cli/docs.ts +346 -0
  309. package/src/cli/doctor.ts +54 -0
  310. package/src/cli/eval.ts +315 -0
  311. package/src/cli/evidence.ts +225 -0
  312. package/src/cli/evolve.ts +219 -0
  313. package/src/cli/extensions.ts +214 -0
  314. package/src/cli/fleet.ts +868 -0
  315. package/src/cli/index.ts +338 -0
  316. package/src/cli/init.ts +219 -0
  317. package/src/cli/initial-message.ts +47 -0
  318. package/src/cli/internal-dispatch.ts +55 -0
  319. package/src/cli/memory.ts +182 -0
  320. package/src/cli/models.ts +257 -0
  321. package/src/cli/modes/json-stream.ts +121 -0
  322. package/src/cli/modes/jsonl.ts +9 -0
  323. package/src/cli/modes/print.ts +604 -0
  324. package/src/cli/oauth-manual-input.ts +72 -0
  325. package/src/cli/oauth-select.ts +36 -0
  326. package/src/cli/output-guard.ts +48 -0
  327. package/src/cli/paths.ts +44 -0
  328. package/src/cli/provider-target.ts +113 -0
  329. package/src/cli/removal.ts +72 -0
  330. package/src/cli/reset.ts +253 -0
  331. package/src/cli/run.ts +497 -0
  332. package/src/cli/share.ts +243 -0
  333. package/src/cli/shared.ts +60 -0
  334. package/src/cli/skills-eval.ts +1240 -0
  335. package/src/cli/skills.ts +485 -0
  336. package/src/cli/steer-channel.ts +86 -0
  337. package/src/cli/targets.ts +1154 -0
  338. package/src/cli/text-layout.ts +112 -0
  339. package/src/cli/trace.ts +322 -0
  340. package/src/cli/uninstall.ts +405 -0
  341. package/src/cli/upgrade.ts +286 -0
  342. package/src/cli/usage.ts +876 -0
  343. package/src/cli/validate-model.ts +28 -0
  344. package/src/cli/version.ts +7 -0
  345. package/src/cli/wiki-generate.ts +510 -0
  346. package/src/core/agent-environment.ts +7 -0
  347. package/src/core/artifact-paths.ts +43 -0
  348. package/src/core/bash-exec.ts +313 -0
  349. package/src/core/boot-trace.ts +42 -0
  350. package/src/core/bus-events.ts +744 -0
  351. package/src/core/bus-trace.ts +53 -0
  352. package/src/core/c-header-language.ts +265 -0
  353. package/src/core/clio-repo.ts +78 -0
  354. package/src/core/commit-attribution.ts +157 -0
  355. package/src/core/compile-cache.ts +159 -0
  356. package/src/core/config.ts +1722 -0
  357. package/src/core/context-floor.ts +33 -0
  358. package/src/core/defaults.ts +659 -0
  359. package/src/core/domain-loader.ts +177 -0
  360. package/src/core/event-bus.ts +94 -0
  361. package/src/core/file-references.ts +282 -0
  362. package/src/core/git-commit-attribution.ts +362 -0
  363. package/src/core/guardrails.ts +185 -0
  364. package/src/core/headless-permission.ts +21 -0
  365. package/src/core/incomplete-installation.ts +45 -0
  366. package/src/core/init.ts +223 -0
  367. package/src/core/json-payload.ts +58 -0
  368. package/src/core/package-root.ts +54 -0
  369. package/src/core/path-canonical.ts +37 -0
  370. package/src/core/process-identity.ts +41 -0
  371. package/src/core/recent-models.ts +91 -0
  372. package/src/core/residency-protection.ts +56 -0
  373. package/src/core/resolve-config-value.ts +88 -0
  374. package/src/core/response-schema.ts +279 -0
  375. package/src/core/run-overrides.ts +77 -0
  376. package/src/core/safe-exec.ts +205 -0
  377. package/src/core/safe-id.ts +37 -0
  378. package/src/core/safe-resource-write.ts +162 -0
  379. package/src/core/session-routing.ts +339 -0
  380. package/src/core/settings-layers.ts +354 -0
  381. package/src/core/shared-bus.ts +8 -0
  382. package/src/core/shell-quote.ts +26 -0
  383. package/src/core/skill-activation.ts +190 -0
  384. package/src/core/startup-timer.ts +37 -0
  385. package/src/core/state-file-lock.ts +219 -0
  386. package/src/core/termination.ts +275 -0
  387. package/src/core/timers.ts +38 -0
  388. package/src/core/tool-names.ts +65 -0
  389. package/src/core/verification-scripts.ts +13 -0
  390. package/src/core/workspace-files.ts +492 -0
  391. package/src/core/xdg.ts +177 -0
  392. package/src/domains/agents/builtins/architect.md +4 -4
  393. package/src/domains/agents/builtins/coder.md +3 -2
  394. package/src/domains/agents/builtins/debugger.md +1 -1
  395. package/src/domains/agents/builtins/documenter.md +1 -1
  396. package/src/domains/agents/builtins/git-master.md +3 -3
  397. package/src/domains/agents/builtins/provenance.md +1 -1
  398. package/src/domains/agents/builtins/researcher.md +1 -1
  399. package/src/domains/agents/builtins/scout.md +1 -1
  400. package/src/domains/agents/builtins/tester.md +1 -1
  401. package/src/domains/agents/builtins/verifier.md +1 -1
  402. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  403. package/src/domains/agents/catalog.ts +172 -0
  404. package/src/domains/agents/contract.ts +16 -0
  405. package/src/domains/agents/extension.ts +110 -0
  406. package/src/domains/agents/fleet-commands.ts +154 -0
  407. package/src/domains/agents/fleet-contract.ts +797 -0
  408. package/src/domains/agents/frontmatter.ts +40 -0
  409. package/src/domains/agents/index.ts +102 -0
  410. package/src/domains/agents/manifest.ts +6 -0
  411. package/src/domains/agents/recipe-schema.ts +202 -0
  412. package/src/domains/agents/recipe.ts +125 -0
  413. package/src/domains/agents/registry.ts +111 -0
  414. package/src/domains/agents/result-contract.ts +1265 -0
  415. package/src/domains/agents/spec.ts +371 -0
  416. package/src/domains/agents/write-boundary.ts +109 -0
  417. package/src/domains/components/diff.ts +99 -0
  418. package/src/domains/components/hash.ts +21 -0
  419. package/src/domains/components/index.ts +3 -0
  420. package/src/domains/components/scan.ts +304 -0
  421. package/src/domains/components/snapshot.ts +108 -0
  422. package/src/domains/components/types.ts +82 -0
  423. package/src/domains/config/agent-namespace.ts +13 -0
  424. package/src/domains/config/classify.ts +106 -0
  425. package/src/domains/config/contract.ts +22 -0
  426. package/src/domains/config/extension.ts +142 -0
  427. package/src/domains/config/index.ts +23 -0
  428. package/src/domains/config/keybindings.ts +200 -0
  429. package/src/domains/config/manifest.ts +6 -0
  430. package/src/domains/config/watcher.ts +41 -0
  431. package/src/domains/context/adoption.ts +880 -0
  432. package/src/domains/context/bootstrap-prompt.ts +273 -0
  433. package/src/domains/context/bootstrap.ts +1502 -0
  434. package/src/domains/context/clear.ts +91 -0
  435. package/src/domains/context/clio-md.ts +429 -0
  436. package/src/domains/context/codewiki/artifact.ts +400 -0
  437. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  438. package/src/domains/context/codewiki/build-worker.ts +54 -0
  439. package/src/domains/context/codewiki/cmake.ts +356 -0
  440. package/src/domains/context/codewiki/cooperative.ts +46 -0
  441. package/src/domains/context/codewiki/coordinator.ts +182 -0
  442. package/src/domains/context/codewiki/digest.ts +135 -0
  443. package/src/domains/context/codewiki/grammar-assets.ts +33 -0
  444. package/src/domains/context/codewiki/indexer.ts +1529 -0
  445. package/src/domains/context/codewiki/paths.ts +67 -0
  446. package/src/domains/context/codewiki/schema.ts +80 -0
  447. package/src/domains/context/codewiki/tree-sitter.ts +771 -0
  448. package/src/domains/context/contract.ts +68 -0
  449. package/src/domains/context/excluded-dirs.ts +1 -0
  450. package/src/domains/context/extension.ts +358 -0
  451. package/src/domains/context/fingerprint.ts +198 -0
  452. package/src/domains/context/index.ts +154 -0
  453. package/src/domains/context/init-options.ts +69 -0
  454. package/src/domains/context/manifest.ts +6 -0
  455. package/src/domains/context/operator-profile.ts +157 -0
  456. package/src/domains/context/project-metadata.ts +529 -0
  457. package/src/domains/context/project-rules.ts +227 -0
  458. package/src/domains/context/prompt-context.ts +61 -0
  459. package/src/domains/context/refresh.ts +178 -0
  460. package/src/domains/context/runtime.ts +17 -0
  461. package/src/domains/context/sibling-files.ts +10 -0
  462. package/src/domains/context/state.ts +237 -0
  463. package/src/domains/context/wiki/assemble.ts +303 -0
  464. package/src/domains/context/wiki/frontmatter.ts +210 -0
  465. package/src/domains/context/wiki/generate.ts +595 -0
  466. package/src/domains/context/wiki/layout.ts +111 -0
  467. package/src/domains/context/wiki/meta.ts +221 -0
  468. package/src/domains/context/wiki/plan-store.ts +217 -0
  469. package/src/domains/context/wiki/plan.ts +250 -0
  470. package/src/domains/context/wiki/prompts.ts +283 -0
  471. package/src/domains/context/wiki/staleness.ts +198 -0
  472. package/src/domains/dispatch/active-route-planner.ts +168 -0
  473. package/src/domains/dispatch/admission-queue.ts +150 -0
  474. package/src/domains/dispatch/admission.ts +334 -0
  475. package/src/domains/dispatch/agent-candidates.ts +307 -0
  476. package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
  477. package/src/domains/dispatch/agent-ledger-store.ts +257 -0
  478. package/src/domains/dispatch/agent-ledger.ts +212 -0
  479. package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
  480. package/src/domains/dispatch/assignment-events.ts +132 -0
  481. package/src/domains/dispatch/assignment-reconcile.ts +76 -0
  482. package/src/domains/dispatch/assignment-store.ts +162 -0
  483. package/src/domains/dispatch/assignment.ts +278 -0
  484. package/src/domains/dispatch/backoff.ts +59 -0
  485. package/src/domains/dispatch/batch-store.ts +134 -0
  486. package/src/domains/dispatch/batch-tracker.ts +66 -0
  487. package/src/domains/dispatch/capability-match.ts +155 -0
  488. package/src/domains/dispatch/capacity-lease.ts +413 -0
  489. package/src/domains/dispatch/code-step-store.ts +52 -0
  490. package/src/domains/dispatch/code-step.ts +387 -0
  491. package/src/domains/dispatch/contract.ts +278 -0
  492. package/src/domains/dispatch/dedup.ts +133 -0
  493. package/src/domains/dispatch/event-pump.ts +251 -0
  494. package/src/domains/dispatch/execution-handoff.ts +29 -0
  495. package/src/domains/dispatch/execution-plan.ts +328 -0
  496. package/src/domains/dispatch/execution-role.ts +277 -0
  497. package/src/domains/dispatch/execution-scheduler.ts +583 -0
  498. package/src/domains/dispatch/extension.ts +6006 -0
  499. package/src/domains/dispatch/failure-classification.ts +147 -0
  500. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  501. package/src/domains/dispatch/fleet-plan.ts +225 -0
  502. package/src/domains/dispatch/fleet-preflight.ts +394 -0
  503. package/src/domains/dispatch/gate-decisions.ts +1040 -0
  504. package/src/domains/dispatch/gate-role-prompts.ts +58 -0
  505. package/src/domains/dispatch/heartbeat.ts +27 -0
  506. package/src/domains/dispatch/index.ts +137 -0
  507. package/src/domains/dispatch/joint-route-adapter.ts +114 -0
  508. package/src/domains/dispatch/joint-route-resolver.ts +283 -0
  509. package/src/domains/dispatch/manifest.ts +6 -0
  510. package/src/domains/dispatch/orphan-recovery.ts +266 -0
  511. package/src/domains/dispatch/outcome.ts +109 -0
  512. package/src/domains/dispatch/phase-timing.ts +47 -0
  513. package/src/domains/dispatch/placement.ts +202 -0
  514. package/src/domains/dispatch/receipt-findings.ts +255 -0
  515. package/src/domains/dispatch/receipt-integrity.ts +383 -0
  516. package/src/domains/dispatch/recovery-candidates.ts +74 -0
  517. package/src/domains/dispatch/reproducibility.ts +48 -0
  518. package/src/domains/dispatch/reservation-store.ts +501 -0
  519. package/src/domains/dispatch/route-approval.ts +177 -0
  520. package/src/domains/dispatch/route-candidates.ts +57 -0
  521. package/src/domains/dispatch/route-decision.ts +1079 -0
  522. package/src/domains/dispatch/route-facts.ts +187 -0
  523. package/src/domains/dispatch/route-history.ts +238 -0
  524. package/src/domains/dispatch/route-observer.ts +488 -0
  525. package/src/domains/dispatch/route-policy.ts +327 -0
  526. package/src/domains/dispatch/route-quality.ts +256 -0
  527. package/src/domains/dispatch/route-readiness.ts +120 -0
  528. package/src/domains/dispatch/routing-intent.ts +287 -0
  529. package/src/domains/dispatch/run-identity.ts +56 -0
  530. package/src/domains/dispatch/scout-transition.ts +130 -0
  531. package/src/domains/dispatch/state.ts +302 -0
  532. package/src/domains/dispatch/tool-stats.ts +132 -0
  533. package/src/domains/dispatch/transport.ts +210 -0
  534. package/src/domains/dispatch/types.ts +799 -0
  535. package/src/domains/dispatch/validation-grounding.ts +154 -0
  536. package/src/domains/dispatch/validation.ts +721 -0
  537. package/src/domains/dispatch/worker-protocol.ts +275 -0
  538. package/src/domains/dispatch/worker-spawn.ts +585 -0
  539. package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
  540. package/src/domains/dispatch/write-boundary.ts +426 -0
  541. package/src/domains/eval/artifacts/redact.ts +42 -0
  542. package/src/domains/eval/artifacts/store.ts +173 -0
  543. package/src/domains/eval/compare/compare.ts +33 -0
  544. package/src/domains/eval/compare/gates.ts +66 -0
  545. package/src/domains/eval/compare/thresholds.ts +92 -0
  546. package/src/domains/eval/harness-metrics.ts +62 -0
  547. package/src/domains/eval/index.ts +66 -0
  548. package/src/domains/eval/metrics/chaos-stream.ts +93 -0
  549. package/src/domains/eval/metrics/context.ts +34 -0
  550. package/src/domains/eval/metrics/coverage.ts +21 -0
  551. package/src/domains/eval/metrics/evidence.ts +182 -0
  552. package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
  553. package/src/domains/eval/metrics/invariants.ts +736 -0
  554. package/src/domains/eval/metrics/latency.ts +4 -0
  555. package/src/domains/eval/metrics/token-stream.ts +139 -0
  556. package/src/domains/eval/metrics/tokens.ts +51 -0
  557. package/src/domains/eval/metrics/tool-calls.ts +7 -0
  558. package/src/domains/eval/proactive-memory.ts +279 -0
  559. package/src/domains/eval/provenance.ts +35 -0
  560. package/src/domains/eval/report.ts +234 -0
  561. package/src/domains/eval/reports/json.ts +5 -0
  562. package/src/domains/eval/reports/junit.ts +23 -0
  563. package/src/domains/eval/reports/markdown.ts +20 -0
  564. package/src/domains/eval/reports/swe-jsonl.ts +16 -0
  565. package/src/domains/eval/reports/text.ts +25 -0
  566. package/src/domains/eval/run-compare.ts +274 -0
  567. package/src/domains/eval/runner.ts +244 -0
  568. package/src/domains/eval/runners/clio-run.ts +148 -0
  569. package/src/domains/eval/runners/context-index.ts +56 -0
  570. package/src/domains/eval/runners/context-init.ts +203 -0
  571. package/src/domains/eval/runners/external-command.ts +350 -0
  572. package/src/domains/eval/runtime-paths.ts +171 -0
  573. package/src/domains/eval/schema/artifact.ts +75 -0
  574. package/src/domains/eval/schema/suite.ts +235 -0
  575. package/src/domains/eval/schema/validate.ts +339 -0
  576. package/src/domains/eval/store.ts +392 -0
  577. package/src/domains/eval/suites/load.ts +74 -0
  578. package/src/domains/eval/suites/matrix.ts +19 -0
  579. package/src/domains/eval/suites/resolve.ts +44 -0
  580. package/src/domains/eval/suites/run.ts +325 -0
  581. package/src/domains/eval/task-file.ts +186 -0
  582. package/src/domains/eval/types.ts +140 -0
  583. package/src/domains/eval/verifiers/command.ts +27 -0
  584. package/src/domains/eval/verifiers/file-exists.ts +6 -0
  585. package/src/domains/eval/verifiers/patch.ts +22 -0
  586. package/src/domains/eval/workspaces/git.ts +41 -0
  587. package/src/domains/eval/workspaces/local.ts +17 -0
  588. package/src/domains/eval/workspaces/temp-copy.ts +29 -0
  589. package/src/domains/evidence/build.ts +1754 -0
  590. package/src/domains/evidence/eval.ts +605 -0
  591. package/src/domains/evidence/failure-attribution.ts +54 -0
  592. package/src/domains/evidence/finish-contract-map.ts +42 -0
  593. package/src/domains/evidence/index.ts +55 -0
  594. package/src/domains/evidence/provenance.ts +200 -0
  595. package/src/domains/evidence/redact.ts +81 -0
  596. package/src/domains/evidence/store.ts +291 -0
  597. package/src/domains/evidence/types.ts +325 -0
  598. package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
  599. package/src/domains/evolution/index.ts +26 -0
  600. package/src/domains/evolution/manifest.ts +154 -0
  601. package/src/domains/evolution/validate.ts +304 -0
  602. package/src/domains/extensions/contract.ts +22 -0
  603. package/src/domains/extensions/discovery.ts +193 -0
  604. package/src/domains/extensions/extension.ts +46 -0
  605. package/src/domains/extensions/index.ts +34 -0
  606. package/src/domains/extensions/manager.ts +30 -0
  607. package/src/domains/extensions/manifest.ts +6 -0
  608. package/src/domains/extensions/resources.ts +38 -0
  609. package/src/domains/extensions/state.ts +224 -0
  610. package/src/domains/extensions/types.ts +83 -0
  611. package/src/domains/interop/consent.ts +185 -0
  612. package/src/domains/interop/contract.ts +29 -0
  613. package/src/domains/interop/detect.ts +173 -0
  614. package/src/domains/interop/extension.ts +59 -0
  615. package/src/domains/interop/index.ts +34 -0
  616. package/src/domains/interop/manifest.ts +6 -0
  617. package/src/domains/interop/registry.ts +139 -0
  618. package/src/domains/interop/state.ts +92 -0
  619. package/src/domains/interop/types.ts +109 -0
  620. package/src/domains/lifecycle/contract.ts +11 -0
  621. package/src/domains/lifecycle/doctor.ts +536 -0
  622. package/src/domains/lifecycle/extension.ts +23 -0
  623. package/src/domains/lifecycle/index.ts +21 -0
  624. package/src/domains/lifecycle/install-method.ts +51 -0
  625. package/src/domains/lifecycle/manifest.ts +6 -0
  626. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  627. package/src/domains/lifecycle/migrations/index.ts +114 -0
  628. package/src/domains/lifecycle/state.ts +93 -0
  629. package/src/domains/lifecycle/upgrade-notice.ts +35 -0
  630. package/src/domains/lifecycle/version.ts +35 -0
  631. package/src/domains/memory/index.ts +128 -0
  632. package/src/domains/memory/operations.ts +143 -0
  633. package/src/domains/memory/prompt-section.ts +86 -0
  634. package/src/domains/memory/proposal.ts +180 -0
  635. package/src/domains/memory/store.ts +163 -0
  636. package/src/domains/memory/task-bank.ts +229 -0
  637. package/src/domains/memory/task-memory-handoff.ts +222 -0
  638. package/src/domains/memory/task-memory-policy.ts +602 -0
  639. package/src/domains/memory/task-memory-status.ts +58 -0
  640. package/src/domains/memory/task-memory-telemetry.ts +346 -0
  641. package/src/domains/memory/task-memory-trace.ts +89 -0
  642. package/src/domains/memory/types.ts +74 -0
  643. package/src/domains/memory/validate.ts +297 -0
  644. package/src/domains/middleware/budget.ts +216 -0
  645. package/src/domains/middleware/contract.ts +35 -0
  646. package/src/domains/middleware/dispatch-nudge.ts +469 -0
  647. package/src/domains/middleware/extension.ts +129 -0
  648. package/src/domains/middleware/hook-receipts.ts +70 -0
  649. package/src/domains/middleware/hooks-io.ts +186 -0
  650. package/src/domains/middleware/hooks.ts +432 -0
  651. package/src/domains/middleware/index.ts +154 -0
  652. package/src/domains/middleware/manifest.ts +6 -0
  653. package/src/domains/middleware/memory-intervention.ts +701 -0
  654. package/src/domains/middleware/rules.ts +42 -0
  655. package/src/domains/middleware/runtime.ts +333 -0
  656. package/src/domains/middleware/skills-reminder.ts +202 -0
  657. package/src/domains/middleware/snapshot.ts +71 -0
  658. package/src/domains/middleware/stalled-turn.ts +71 -0
  659. package/src/domains/middleware/task-board-reminder.ts +87 -0
  660. package/src/domains/middleware/task-nudge.ts +77 -0
  661. package/src/domains/middleware/tool-choice-control.ts +42 -0
  662. package/src/domains/middleware/types.ts +131 -0
  663. package/src/domains/middleware/validate.ts +329 -0
  664. package/src/domains/observability/accountability.ts +67 -0
  665. package/src/domains/observability/contract.ts +168 -0
  666. package/src/domains/observability/cost.ts +206 -0
  667. package/src/domains/observability/evidence-index.ts +123 -0
  668. package/src/domains/observability/extension.ts +281 -0
  669. package/src/domains/observability/index.ts +78 -0
  670. package/src/domains/observability/manifest.ts +10 -0
  671. package/src/domains/observability/metrics.ts +37 -0
  672. package/src/domains/observability/projection.ts +477 -0
  673. package/src/domains/observability/telemetry.ts +89 -0
  674. package/src/domains/observability/trace-store.ts +1454 -0
  675. package/src/domains/prompts/compiler.ts +614 -0
  676. package/src/domains/prompts/contract.ts +46 -0
  677. package/src/domains/prompts/extension.ts +336 -0
  678. package/src/domains/prompts/fragment-loader.ts +138 -0
  679. package/src/domains/prompts/fragments/identity/clio.md +5 -6
  680. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  681. package/src/domains/prompts/fragments/identity/self-awareness.md +19 -0
  682. package/src/domains/prompts/fragments/operating/contract.md +4 -41
  683. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  684. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  685. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  686. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  687. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  688. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  689. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  690. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  691. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  692. package/src/domains/prompts/hash.ts +73 -0
  693. package/src/domains/prompts/index.ts +32 -0
  694. package/src/domains/prompts/manifest.ts +8 -0
  695. package/src/domains/prompts/memory-intervention.ts +57 -0
  696. package/src/domains/prompts/preload.ts +82 -0
  697. package/src/domains/providers/auth/api-key.ts +47 -0
  698. package/src/domains/providers/auth/backend-file.ts +79 -0
  699. package/src/domains/providers/auth/backend-memory.ts +72 -0
  700. package/src/domains/providers/auth/boot-status.ts +65 -0
  701. package/src/domains/providers/auth/index.ts +37 -0
  702. package/src/domains/providers/auth/oauth.ts +37 -0
  703. package/src/domains/providers/auth/storage.ts +726 -0
  704. package/src/domains/providers/capabilities.ts +58 -0
  705. package/src/domains/providers/catalog.ts +162 -0
  706. package/src/domains/providers/contract.ts +162 -0
  707. package/src/domains/providers/credentials.ts +20 -0
  708. package/src/domains/providers/eligibility.ts +24 -0
  709. package/src/domains/providers/errors.ts +64 -0
  710. package/src/domains/providers/extension.ts +548 -0
  711. package/src/domains/providers/index.ts +142 -0
  712. package/src/domains/providers/knowledge-base-path.ts +102 -0
  713. package/src/domains/providers/manifest.ts +6 -0
  714. package/src/domains/providers/model-capabilities.ts +136 -0
  715. package/src/domains/providers/model-discovery.ts +144 -0
  716. package/src/domains/providers/model-family.ts +32 -0
  717. package/src/domains/providers/model-runtime-capabilities.ts +723 -0
  718. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +120 -37
  719. package/src/domains/providers/plugins.ts +61 -0
  720. package/src/domains/providers/probe/fingerprint.ts +64 -0
  721. package/src/domains/providers/probe/http.ts +114 -0
  722. package/src/domains/providers/probe/reasoning.ts +111 -0
  723. package/src/domains/providers/registry.ts +187 -0
  724. package/src/domains/providers/resolver.ts +156 -0
  725. package/src/domains/providers/runtime-resolution.ts +720 -0
  726. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
  727. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  728. package/src/domains/providers/runtimes/builtins.ts +78 -0
  729. package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
  730. package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
  731. package/src/domains/providers/runtimes/claude/common.ts +55 -0
  732. package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
  733. package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
  734. package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
  735. package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
  736. package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
  737. package/src/domains/providers/runtimes/cloud/google.ts +41 -0
  738. package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
  739. package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
  740. package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
  741. package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
  742. package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
  743. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  744. package/src/domains/providers/runtimes/common/local-synth.ts +164 -0
  745. package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
  746. package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
  747. package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
  748. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
  749. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
  750. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
  751. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
  752. package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
  753. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  754. package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
  755. package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
  756. package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
  757. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
  758. package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
  759. package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
  760. package/src/domains/providers/runtimes/protocol/google.ts +27 -0
  761. package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
  762. package/src/domains/providers/support.ts +241 -0
  763. package/src/domains/providers/thinking-control-policy.ts +85 -0
  764. package/src/domains/providers/types/capability-flags.ts +114 -0
  765. package/src/domains/providers/types/cost-provenance.ts +7 -0
  766. package/src/domains/providers/types/inference.ts +41 -0
  767. package/src/domains/providers/types/knowledge-base.ts +156 -0
  768. package/src/domains/providers/types/local-model-quirks.ts +216 -0
  769. package/src/domains/providers/types/runtime-descriptor.ts +181 -0
  770. package/src/domains/providers/types/target-descriptor.ts +60 -0
  771. package/src/domains/resources/collision.ts +92 -0
  772. package/src/domains/resources/common-loader.ts +140 -0
  773. package/src/domains/resources/contract.ts +24 -0
  774. package/src/domains/resources/extension.ts +59 -0
  775. package/src/domains/resources/index.ts +74 -0
  776. package/src/domains/resources/loader.ts +85 -0
  777. package/src/domains/resources/manifest.ts +6 -0
  778. package/src/domains/resources/prompts/loader.ts +246 -0
  779. package/src/domains/resources/prompts/substitute.ts +1 -0
  780. package/src/domains/resources/skills/content-hash.ts +107 -0
  781. package/src/domains/resources/skills/evals.ts +175 -0
  782. package/src/domains/resources/skills/install.ts +427 -0
  783. package/src/domains/resources/skills/loader.ts +985 -0
  784. package/src/domains/resources/skills/marketplace.ts +301 -0
  785. package/src/domains/resources/skills/provenance-pin.ts +115 -0
  786. package/src/domains/safety/action-classifier.ts +270 -0
  787. package/src/domains/safety/approval-axis.ts +23 -0
  788. package/src/domains/safety/audit.ts +493 -0
  789. package/src/domains/safety/autonomy.ts +174 -0
  790. package/src/domains/safety/call-target.ts +59 -0
  791. package/src/domains/safety/contract.ts +65 -0
  792. package/src/domains/safety/damage-control.ts +44 -0
  793. package/src/domains/safety/default-path-policy.ts +117 -0
  794. package/src/domains/safety/extension.ts +383 -0
  795. package/src/domains/safety/finish-contract-registration.ts +128 -0
  796. package/src/domains/safety/finish-contract.ts +554 -0
  797. package/src/domains/safety/index.ts +44 -0
  798. package/src/domains/safety/loop-detector.ts +143 -0
  799. package/src/domains/safety/manifest.ts +6 -0
  800. package/src/domains/safety/path-policy.ts +164 -0
  801. package/src/domains/safety/policy-engine.ts +994 -0
  802. package/src/domains/safety/project-policy.ts +391 -0
  803. package/src/domains/safety/protected-artifacts-registration.ts +189 -0
  804. package/src/domains/safety/protected-artifacts.ts +993 -0
  805. package/src/domains/safety/rejection-feedback.ts +102 -0
  806. package/src/domains/safety/rigor.ts +72 -0
  807. package/src/domains/safety/rule-compiler.ts +48 -0
  808. package/src/domains/safety/rule-pack-loader.ts +92 -0
  809. package/src/domains/safety/run-effects.ts +197 -0
  810. package/src/domains/safety/scope.ts +61 -0
  811. package/src/domains/scheduling/budget.ts +35 -0
  812. package/src/domains/scheduling/cluster.ts +175 -0
  813. package/src/domains/scheduling/contract.ts +30 -0
  814. package/src/domains/scheduling/extension.ts +91 -0
  815. package/src/domains/scheduling/index.ts +12 -0
  816. package/src/domains/scheduling/manifest.ts +6 -0
  817. package/src/domains/session/archive-readers.ts +208 -0
  818. package/src/domains/session/checkpoint.ts +38 -0
  819. package/src/domains/session/compaction/auto.ts +89 -0
  820. package/src/domains/session/compaction/branch-summary.ts +187 -0
  821. package/src/domains/session/compaction/compact.ts +493 -0
  822. package/src/domains/session/compaction/cut-point.ts +172 -0
  823. package/src/domains/session/compaction/defaults.ts +34 -0
  824. package/src/domains/session/compaction/mask-observations.ts +265 -0
  825. package/src/domains/session/compaction/session-entries.ts +18 -0
  826. package/src/domains/session/compaction/tokens.ts +148 -0
  827. package/src/domains/session/context-accounting.ts +583 -0
  828. package/src/domains/session/context-ledger.ts +362 -0
  829. package/src/domains/session/contract.ts +159 -0
  830. package/src/domains/session/cwd-fallback.ts +65 -0
  831. package/src/domains/session/decision-board.ts +190 -0
  832. package/src/domains/session/entries.ts +572 -0
  833. package/src/domains/session/extension.ts +403 -0
  834. package/src/domains/session/history.ts +172 -0
  835. package/src/domains/session/index.ts +84 -0
  836. package/src/domains/session/manager.ts +128 -0
  837. package/src/domains/session/manifest.ts +6 -0
  838. package/src/domains/session/migrations/index.ts +27 -0
  839. package/src/domains/session/prompt-manifest.ts +173 -0
  840. package/src/domains/session/protected-artifact-journal.ts +241 -0
  841. package/src/domains/session/protected-artifacts.ts +90 -0
  842. package/src/domains/session/retry.ts +230 -0
  843. package/src/domains/session/session-artifacts.ts +107 -0
  844. package/src/domains/session/task-board.ts +569 -0
  845. package/src/domains/session/tree/active-path.ts +137 -0
  846. package/src/domains/session/tree/fork.ts +159 -0
  847. package/src/domains/session/tree/manager.ts +128 -0
  848. package/src/domains/session/tree/navigator.ts +177 -0
  849. package/src/domains/session/tree/preview.ts +259 -0
  850. package/src/domains/session/usage.ts +148 -0
  851. package/src/domains/session/workspace/git-probe.ts +167 -0
  852. package/src/domains/session/workspace/index.ts +4 -0
  853. package/src/domains/session/workspace/project-type.ts +217 -0
  854. package/src/domains/session/workspace/snapshot.ts +74 -0
  855. package/src/domains/share/archive.ts +684 -0
  856. package/src/domains/share/contract.ts +9 -0
  857. package/src/domains/share/extension.ts +26 -0
  858. package/src/domains/share/index.ts +28 -0
  859. package/src/domains/share/manifest.ts +6 -0
  860. package/src/domains/user-tasks/store.ts +297 -0
  861. package/src/engine/acp/adapter.ts +397 -0
  862. package/src/engine/acp/errors.ts +128 -0
  863. package/src/engine/acp/event-mapper.ts +154 -0
  864. package/src/engine/acp/server.ts +2238 -0
  865. package/src/engine/acp/tool-mediator.ts +686 -0
  866. package/src/engine/acp/transport.ts +775 -0
  867. package/src/engine/acp/types.ts +196 -0
  868. package/src/engine/agent.ts +29 -0
  869. package/src/engine/ai.ts +207 -0
  870. package/src/engine/alcf-oauth.ts +205 -0
  871. package/src/engine/antigravity/subprocess-runtime.ts +205 -0
  872. package/src/engine/api-registry.ts +223 -0
  873. package/src/engine/apis/degraded-inference.ts +95 -0
  874. package/src/engine/apis/index.ts +16 -0
  875. package/src/engine/apis/llamacpp-residency.ts +292 -0
  876. package/src/engine/apis/lmstudio-residency.ts +76 -0
  877. package/src/engine/apis/lmstudio.ts +243 -0
  878. package/src/engine/apis/ollama-native.ts +528 -0
  879. package/src/engine/apis/openai-completions.ts +795 -0
  880. package/src/engine/apis/output-budget.ts +99 -0
  881. package/src/engine/apis/residency-lock.ts +29 -0
  882. package/src/engine/apis/residency.ts +776 -0
  883. package/src/engine/apis/resident-models.ts +42 -0
  884. package/src/engine/apis/sampling-overrides.ts +38 -0
  885. package/src/engine/apis/types.ts +16 -0
  886. package/src/engine/claude/sdk-runtime.ts +685 -0
  887. package/src/engine/claude/session-id.ts +5 -0
  888. package/src/engine/claude/subprocess-runtime.ts +316 -0
  889. package/src/engine/claude/tool-safety.ts +400 -0
  890. package/src/engine/env-api-keys.ts +98 -0
  891. package/src/engine/external-subprocess.ts +23 -0
  892. package/src/engine/gemma-channel-filter.ts +223 -0
  893. package/src/engine/harmony-response.ts +165 -0
  894. package/src/engine/instrumented-tui.ts +192 -0
  895. package/src/engine/loop-guard.ts +1127 -0
  896. package/src/engine/messages.ts +14 -0
  897. package/src/engine/models.ts +42 -0
  898. package/src/engine/oauth.ts +196 -0
  899. package/src/engine/pi-mono-names.ts +13 -0
  900. package/src/engine/prompt-templates.ts +1 -0
  901. package/src/engine/provider-payload.ts +272 -0
  902. package/src/engine/select-list.ts +53 -0
  903. package/src/engine/session.ts +834 -0
  904. package/src/engine/strip-tokenizer-sentinels.ts +125 -0
  905. package/src/engine/truncate.ts +9 -0
  906. package/src/engine/tui.ts +111 -0
  907. package/src/engine/types.ts +63 -0
  908. package/src/engine/worker-events.ts +100 -0
  909. package/src/engine/worker-runtime-capabilities.ts +5 -0
  910. package/src/engine/worker-runtime.ts +1022 -0
  911. package/src/engine/worker-tools.ts +208 -0
  912. package/src/entry/boot-options.ts +50 -0
  913. package/src/entry/orchestrator.ts +2011 -0
  914. package/src/interactive/application-controller.ts +433 -0
  915. package/src/interactive/bus-notices.ts +265 -0
  916. package/src/interactive/chat-loop-messages.ts +626 -0
  917. package/src/interactive/chat-loop-policy.ts +18 -0
  918. package/src/interactive/chat-loop.ts +1090 -0
  919. package/src/interactive/chat-panel.ts +1820 -0
  920. package/src/interactive/chat-renderer.ts +1228 -0
  921. package/src/interactive/clio-editor.ts +161 -0
  922. package/src/interactive/command-fallbacks.ts +23 -0
  923. package/src/interactive/command-output.ts +85 -0
  924. package/src/interactive/context-activity.ts +203 -0
  925. package/src/interactive/context-meter.ts +223 -0
  926. package/src/interactive/context-overlay.ts +246 -0
  927. package/src/interactive/cost-overlay.ts +279 -0
  928. package/src/interactive/dispatch-board.ts +1319 -0
  929. package/src/interactive/dispatch-steering.ts +86 -0
  930. package/src/interactive/editor-bash.ts +46 -0
  931. package/src/interactive/editor-steer.ts +51 -0
  932. package/src/interactive/editor-submit.ts +507 -0
  933. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  934. package/src/interactive/export-html/index.ts +51 -0
  935. package/src/interactive/export-html/template.ts +45 -0
  936. package/src/interactive/export-html/tool-renderer.ts +54 -0
  937. package/src/interactive/external-editor.ts +67 -0
  938. package/src/interactive/follow-up-queue-panel.ts +75 -0
  939. package/src/interactive/footer/dashboard.ts +538 -0
  940. package/src/interactive/footer/notifications.ts +275 -0
  941. package/src/interactive/footer/widgets.ts +1264 -0
  942. package/src/interactive/footer-panel.ts +187 -0
  943. package/src/interactive/format-time.ts +97 -0
  944. package/src/interactive/index.ts +11 -0
  945. package/src/interactive/interactive-application.ts +939 -0
  946. package/src/interactive/interactive-event-projection.ts +385 -0
  947. package/src/interactive/interactive-input-runtime.ts +307 -0
  948. package/src/interactive/interactive-presentation.ts +584 -0
  949. package/src/interactive/interactive-shell.ts +388 -0
  950. package/src/interactive/interactive-slash-runtime.ts +554 -0
  951. package/src/interactive/interactive-subscriptions.ts +111 -0
  952. package/src/interactive/interactive-tickers.ts +183 -0
  953. package/src/interactive/keybinding-manager.ts +496 -0
  954. package/src/interactive/layout.ts +57 -0
  955. package/src/interactive/leader-key.ts +143 -0
  956. package/src/interactive/loop-guard-interrupt.ts +101 -0
  957. package/src/interactive/memory-overlay.ts +280 -0
  958. package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
  959. package/src/interactive/overlay-auth-lifecycle.ts +308 -0
  960. package/src/interactive/overlay-frame.ts +502 -0
  961. package/src/interactive/overlay-general-openers.ts +274 -0
  962. package/src/interactive/overlay-key-routing.ts +216 -0
  963. package/src/interactive/overlay-lifecycle.ts +426 -0
  964. package/src/interactive/overlay-model-selectors.ts +127 -0
  965. package/src/interactive/overlay-permission-lifecycle.ts +345 -0
  966. package/src/interactive/overlay-resource-openers.ts +112 -0
  967. package/src/interactive/overlay-session-lifecycle.ts +327 -0
  968. package/src/interactive/overlay-transitions.ts +57 -0
  969. package/src/interactive/overlays/agents.ts +69 -0
  970. package/src/interactive/overlays/ask-user.ts +921 -0
  971. package/src/interactive/overlays/auth-dialog.ts +221 -0
  972. package/src/interactive/overlays/context-reset.ts +108 -0
  973. package/src/interactive/overlays/cwd-fallback.ts +141 -0
  974. package/src/interactive/overlays/decisions.ts +300 -0
  975. package/src/interactive/overlays/extensions.ts +54 -0
  976. package/src/interactive/overlays/help-reference.ts +145 -0
  977. package/src/interactive/overlays/interop.ts +139 -0
  978. package/src/interactive/overlays/keybinding-detail.ts +90 -0
  979. package/src/interactive/overlays/list-overlay.ts +606 -0
  980. package/src/interactive/overlays/message-picker.ts +155 -0
  981. package/src/interactive/overlays/model-selector.ts +1109 -0
  982. package/src/interactive/overlays/prompts.ts +72 -0
  983. package/src/interactive/overlays/session-selector-search.ts +31 -0
  984. package/src/interactive/overlays/session-selector.ts +284 -0
  985. package/src/interactive/overlays/settings.ts +3451 -0
  986. package/src/interactive/overlays/skills-hub.ts +237 -0
  987. package/src/interactive/overlays/tree-selector.ts +422 -0
  988. package/src/interactive/permission-overlay.ts +170 -0
  989. package/src/interactive/render-trace.ts +534 -0
  990. package/src/interactive/renderers/branch-summary.ts +86 -0
  991. package/src/interactive/renderers/code-ink.ts +420 -0
  992. package/src/interactive/renderers/compaction-summary.ts +112 -0
  993. package/src/interactive/renderers/diff.ts +137 -0
  994. package/src/interactive/renderers/mermaid.ts +53 -0
  995. package/src/interactive/renderers/notice.ts +28 -0
  996. package/src/interactive/renderers/retry-status.ts +31 -0
  997. package/src/interactive/renderers/structured.ts +89 -0
  998. package/src/interactive/renderers/tool-execution.ts +1357 -0
  999. package/src/interactive/renderers/worker-entry.ts +280 -0
  1000. package/src/interactive/session-last-turn.ts +186 -0
  1001. package/src/interactive/session-switch-settlement.ts +10 -0
  1002. package/src/interactive/session-transcript.ts +105 -0
  1003. package/src/interactive/session-usage-reseed.ts +74 -0
  1004. package/src/interactive/slash-autocomplete.ts +256 -0
  1005. package/src/interactive/slash-commands.ts +1407 -0
  1006. package/src/interactive/slash-spec.ts +424 -0
  1007. package/src/interactive/status/controller.ts +260 -0
  1008. package/src/interactive/status/index.ts +23 -0
  1009. package/src/interactive/status/state-machine.ts +530 -0
  1010. package/src/interactive/status/summary.ts +170 -0
  1011. package/src/interactive/status/types.ts +121 -0
  1012. package/src/interactive/status/verbs.ts +163 -0
  1013. package/src/interactive/status/watchdog.ts +24 -0
  1014. package/src/interactive/stdout-backpressure.ts +99 -0
  1015. package/src/interactive/stream-pacer.ts +530 -0
  1016. package/src/interactive/stream-pacing-policy.ts +66 -0
  1017. package/src/interactive/tasks-overlay.ts +540 -0
  1018. package/src/interactive/terminal-lease.ts +485 -0
  1019. package/src/interactive/theme/components.ts +55 -0
  1020. package/src/interactive/theme/glyphs.ts +70 -0
  1021. package/src/interactive/theme/index.ts +15 -0
  1022. package/src/interactive/theme/labels.ts +88 -0
  1023. package/src/interactive/theme/rules.ts +138 -0
  1024. package/src/interactive/theme/segments.ts +88 -0
  1025. package/src/interactive/theme/tokens.ts +121 -0
  1026. package/src/interactive/thinking-level-policy.ts +6 -0
  1027. package/src/interactive/tool-prose-loop.ts +122 -0
  1028. package/src/interactive/tool-prose-registration.ts +48 -0
  1029. package/src/interactive/turn-context.ts +855 -0
  1030. package/src/interactive/turn-middleware.ts +283 -0
  1031. package/src/interactive/turn-persistence.ts +458 -0
  1032. package/src/interactive/turn-queues.ts +181 -0
  1033. package/src/interactive/turn-recovery.ts +323 -0
  1034. package/src/interactive/turn-runtime.ts +869 -0
  1035. package/src/interactive/turn-state.ts +133 -0
  1036. package/src/interactive/view/artifacts.ts +1452 -0
  1037. package/src/interactive/view/view-overlay.ts +735 -0
  1038. package/src/interactive/welcome-dashboard.ts +537 -0
  1039. package/src/interactive/worker-receipts.ts +143 -0
  1040. package/src/interactive/worker-replay.ts +111 -0
  1041. package/src/interactive/worker-share.ts +100 -0
  1042. package/src/interactive/worker-stream.ts +446 -0
  1043. package/src/interactive/workspace-facts.ts +141 -0
  1044. package/src/tools/agent-tools.ts +402 -0
  1045. package/src/tools/artifact.ts +103 -0
  1046. package/src/tools/ask-user.ts +666 -0
  1047. package/src/tools/bash.ts +204 -0
  1048. package/src/tools/bootstrap.ts +77 -0
  1049. package/src/tools/builtin-tool-catalog.ts +265 -0
  1050. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  1051. package/src/tools/codewiki/code-nav.ts +549 -0
  1052. package/src/tools/codewiki/shared.ts +118 -0
  1053. package/src/tools/compete-worktrees.ts +898 -0
  1054. package/src/tools/context/docs-engine.ts +630 -0
  1055. package/src/tools/context/index.ts +514 -0
  1056. package/src/tools/context/surface.ts +19 -0
  1057. package/src/tools/core-bootstrap.ts +168 -0
  1058. package/src/tools/credential-present.ts +151 -0
  1059. package/src/tools/dispatch-admission.ts +533 -0
  1060. package/src/tools/dispatch-arguments.ts +228 -0
  1061. package/src/tools/dispatch-background.ts +54 -0
  1062. package/src/tools/dispatch-event-text.ts +6 -0
  1063. package/src/tools/dispatch-plan.ts +746 -0
  1064. package/src/tools/dispatch-run-events.ts +238 -0
  1065. package/src/tools/dispatch-runner.ts +2370 -0
  1066. package/src/tools/dispatch-scout-admission.ts +295 -0
  1067. package/src/tools/dispatch-scout.ts +461 -0
  1068. package/src/tools/dispatch-types.ts +77 -0
  1069. package/src/tools/dispatch.ts +244 -0
  1070. package/src/tools/edit-diff.ts +534 -0
  1071. package/src/tools/edit.ts +128 -0
  1072. package/src/tools/executables.ts +22 -0
  1073. package/src/tools/file-mutation-queue.ts +35 -0
  1074. package/src/tools/find.ts +294 -0
  1075. package/src/tools/grep.ts +495 -0
  1076. package/src/tools/ignore-policy.ts +169 -0
  1077. package/src/tools/lazy-tool.ts +60 -0
  1078. package/src/tools/ledger.ts +206 -0
  1079. package/src/tools/ls.ts +110 -0
  1080. package/src/tools/monitor-surface.ts +36 -0
  1081. package/src/tools/monitor.ts +767 -0
  1082. package/src/tools/network-policy.ts +29 -0
  1083. package/src/tools/observation.ts +421 -0
  1084. package/src/tools/observers.ts +99 -0
  1085. package/src/tools/path-utils.ts +79 -0
  1086. package/src/tools/policy.ts +154 -0
  1087. package/src/tools/profiles.ts +108 -0
  1088. package/src/tools/read.ts +173 -0
  1089. package/src/tools/registry.ts +1169 -0
  1090. package/src/tools/result-shaping.ts +204 -0
  1091. package/src/tools/safe-exec.ts +128 -0
  1092. package/src/tools/spawn-hygiene.ts +182 -0
  1093. package/src/tools/steer-surface.ts +17 -0
  1094. package/src/tools/steer.ts +77 -0
  1095. package/src/tools/tasks.ts +265 -0
  1096. package/src/tools/truncate-utf8.ts +17 -0
  1097. package/src/tools/truncate.ts +43 -0
  1098. package/src/tools/verify/frontend.ts +687 -0
  1099. package/src/tools/verify/index.ts +31 -0
  1100. package/src/tools/verify/scripts.ts +108 -0
  1101. package/src/tools/verify/surface.ts +46 -0
  1102. package/src/tools/web-fetch-surface.ts +23 -0
  1103. package/src/tools/web-fetch.ts +759 -0
  1104. package/src/tools/worker-evidence.ts +215 -0
  1105. package/src/tools/write.ts +57 -0
  1106. package/src/utils/exif-orientation.ts +192 -0
  1107. package/src/utils/git.ts +24 -0
  1108. package/src/utils/image-resize.ts +148 -0
  1109. package/src/utils/photon.ts +103 -0
  1110. package/src/worker/control-lane.ts +22 -0
  1111. package/src/worker/entry.ts +294 -0
  1112. package/src/worker/event-projection.ts +56 -0
  1113. package/src/worker/heartbeat.ts +24 -0
  1114. package/src/worker/ledger-mirror.ts +95 -0
  1115. package/src/worker/ndjson.ts +40 -0
  1116. package/src/worker/protocol.ts +529 -0
  1117. package/src/worker/resource-facts.ts +79 -0
  1118. package/src/worker/runtime-registry.ts +12 -0
  1119. package/src/worker/spec-contract.ts +675 -0
  1120. package/src/worker/stdin-demux.ts +316 -0
  1121. package/dist/acp-UMLFVA3F.js +0 -92
  1122. package/dist/chunk-262G75JS.js +0 -35
  1123. package/dist/chunk-6CWDTGUC.js +0 -20
  1124. package/dist/chunk-BYEU76JP.js +0 -899
  1125. package/dist/chunk-GNGDQYDU.js +0 -34688
  1126. package/dist/chunk-GOTUR54M.js +0 -9
  1127. package/dist/chunk-NI4DEJMC.js +0 -88
  1128. package/dist/chunk-TPOCL34A.js +0 -2876
  1129. package/dist/chunk-UU3R62TT.js +0 -128
  1130. package/dist/clio-KIQ5SNDS.js +0 -53
  1131. package/dist/configure-G4E3A2PG.js +0 -27
  1132. package/dist/doctor-M5HJJZOL.js +0 -61
  1133. package/dist/domains/agents/builtins/architect.md +0 -33
  1134. package/dist/domains/agents/builtins/coder.md +0 -31
  1135. package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
  1136. package/dist/domains/agents/builtins/debugger.md +0 -30
  1137. package/dist/domains/agents/builtins/documenter.md +0 -31
  1138. package/dist/domains/agents/builtins/git-master.md +0 -30
  1139. package/dist/domains/agents/builtins/provenance.md +0 -30
  1140. package/dist/domains/agents/builtins/researcher.md +0 -71
  1141. package/dist/domains/agents/builtins/scout.md +0 -42
  1142. package/dist/domains/agents/builtins/tester.md +0 -31
  1143. package/dist/domains/agents/builtins/verifier.md +0 -30
  1144. package/dist/domains/agents/builtins/wiki-writer.md +0 -41
  1145. package/dist/fleet-preflight-CLIAX7YR.js +0 -21
  1146. package/dist/preload-KZVHET2B.js +0 -11
  1147. package/dist/version-ROZ6CZKH.js +0 -16
  1148. package/docs/html/agents_blueprint.html +0 -936
  1149. package/docs/html/alcf_blueprint.html +0 -324
  1150. package/docs/html/architecture_blueprint.html +0 -850
  1151. package/docs/html/commands_blueprint.html +0 -794
  1152. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  1153. package/docs/html/configuration_blueprint.html +0 -1080
  1154. package/docs/html/context_blueprint.html +0 -603
  1155. package/docs/html/documentation_blueprint.html +0 -832
  1156. package/docs/html/environment_blueprint.html +0 -404
  1157. package/docs/html/eval_blueprint.html +0 -743
  1158. package/docs/html/evals_internal_blueprint.html +0 -190
  1159. package/docs/html/evolution_blueprint.html +0 -674
  1160. package/docs/html/extensions_blueprint.html +0 -2065
  1161. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  1162. package/docs/html/index.html +0 -919
  1163. package/docs/html/lifecycle_blueprint.html +0 -723
  1164. package/docs/html/memory_blueprint.html +0 -699
  1165. package/docs/html/middleware_blueprint.html +0 -664
  1166. package/docs/html/models_blueprint.html +0 -2366
  1167. package/docs/html/observability_blueprint.html +0 -683
  1168. package/docs/html/provider_adapter_blueprint.html +0 -245
  1169. package/docs/html/safety_blueprint.html +0 -1386
  1170. package/docs/html/shared.css +0 -571
  1171. package/docs/html/shared.js +0 -143
  1172. package/docs/html/skills_blueprint.html +0 -671
  1173. package/docs/html/soak_blueprint.html +0 -182
  1174. package/docs/html/tool_usage_blueprint.html +0 -350
  1175. package/docs/html/tools_blueprint.html +0 -2249
  1176. package/docs/html/trace_blueprint.html +0 -235
  1177. package/docs/html/tui_design_blueprint.html +0 -314
  1178. package/docs/html/validation_blueprint.html +0 -961
  1179. package/docs/html/worker_dispatch_blueprint.html +0 -231
  1180. package/skills/git/commit-crafting/SKILL.md +0 -79
  1181. package/skills/git/commit-crafting/evals.md +0 -92
  1182. package/skills/git/create-pr/SKILL.md +0 -116
  1183. package/skills/git/create-pr/evals.md +0 -114
  1184. package/skills/git/investigate-issue/SKILL.md +0 -139
  1185. package/skills/git/investigate-issue/evals.md +0 -94
  1186. package/skills/git/review-changes/SKILL.md +0 -103
  1187. package/skills/git/review-changes/evals.md +0 -85
@@ -0,0 +1,1264 @@
1
+ import type { OutputVerbosity } from "../../core/defaults.js";
2
+ import { ToolNames } from "../../core/tool-names.js";
3
+ import {
4
+ type CostAggregate,
5
+ formatCostAggregate,
6
+ type TokenThroughputSnapshot,
7
+ type UsageBreakdown,
8
+ } from "../../domains/observability/index.js";
9
+ import type { ContextUsageBreakdown } from "../../domains/session/context-accounting.js";
10
+ import type { ContextLedger, ContextLedgerCategory } from "../../domains/session/context-ledger.js";
11
+ import { type TaskBoardSnapshot, taskBoardCounts } from "../../domains/session/task-board.js";
12
+ import { truncateToWidth, visibleWidth } from "../../engine/tui.js";
13
+ import { CONTEXT_CATEGORY_TOKEN, contextCategorySwatch, renderContextMeterBar } from "../context-meter.js";
14
+ import {
15
+ agentDisplayLabel,
16
+ type DispatchBoardRow,
17
+ dispatchOriginPresentation,
18
+ dispatchRowPrefix,
19
+ dispatchStatusPresentation,
20
+ } from "../dispatch-board.js";
21
+ import { buildSegmentedContextBar, CONTEXT_BAR_LABEL_WIDTH, formatFooterTokens } from "../footer-panel.js";
22
+ import { type AgentStatus, spinnerFrame, type TurnSummary } from "../status/index.js";
23
+ import {
24
+ type ClioTheme,
25
+ type ClioToken,
26
+ clioTheme,
27
+ fitUnits,
28
+ formatCompactMs,
29
+ formatContextPercent,
30
+ GLYPH,
31
+ joinChips,
32
+ joinSections,
33
+ sectionTag,
34
+ } from "../theme/index.js";
35
+
36
+ export interface ToolTallySnapshot {
37
+ tools: Readonly<Record<string, number>>;
38
+ errors: number;
39
+ active?: number;
40
+ truncatedResults?: number;
41
+ }
42
+
43
+ /** Live workspace facts. Owned by the footer (the welcome header no longer repeats the branch). */
44
+ export interface WorkspaceFacts {
45
+ cwd: string;
46
+ branch: string | null;
47
+ dirty: boolean | null;
48
+ projectType: string | null;
49
+ remote: string | null;
50
+ }
51
+
52
+ export interface SessionFacts {
53
+ name: string | null;
54
+ id: string | null;
55
+ version: string;
56
+ turns: number | null;
57
+ tokens: string | null;
58
+ throughput: string | null;
59
+ throughputDetail: string | null;
60
+ cost: string | null;
61
+ target: string | null;
62
+ thinking: string | null;
63
+ capabilities: string[] | null;
64
+ safety: string | null;
65
+ toolProfile: string | null;
66
+ /** Active transcript detail mode, shown in the dashboard so visibility is never implicit. */
67
+ outputVerbosity?: OutputVerbosity | null;
68
+ /**
69
+ * Ctrl+G armed the portable leader and is waiting for the next key. Shown
70
+ * because the frame between the two keystrokes was otherwise identical to
71
+ * the idle frame, on the fallback whose users have no working Alt to check
72
+ * it against.
73
+ */
74
+ leaderArmed?: boolean;
75
+ /**
76
+ * A Ctrl+C landed on an idle empty prompt and the 500ms window that quits is
77
+ * open. Shown for the same reason as the leader above: the arming press left
78
+ * the frame identical to the idle frame, so the operator had no way to learn
79
+ * that a second press quits, and no way to tell the first press registered.
80
+ */
81
+ shutdownArmed?: boolean;
82
+ /** Proactive-memory status; kept as one atomic fact row in the expanded dashboard. */
83
+ memoryIntervention?: {
84
+ enabled: boolean;
85
+ tier: "rules" | "llm";
86
+ size: number;
87
+ stepInFlight?: boolean;
88
+ lastDecision?: string | null;
89
+ } | null;
90
+ }
91
+
92
+ /** Context engine telemetry. */
93
+ export interface ContextEngineFacts {
94
+ label: string | null;
95
+ used: number | null;
96
+ contextWindow: number | null;
97
+ toolSchemaTokens: number | null;
98
+ compactionThreshold: number | null;
99
+ compactionAuto: boolean | null;
100
+ compactionActive?: boolean;
101
+ clioMd: string | null;
102
+ memory: string | null;
103
+ extensions: { active: number; installed: number } | null;
104
+ breakdown?: ContextUsageBreakdown | null;
105
+ /** Full categorized ledger; when present the quadrant renders the richer meter. */
106
+ ledger?: ContextLedger | null;
107
+ }
108
+
109
+ /** Dynamic agent work: the live action quadrant. */
110
+ export interface AgentWorkFacts {
111
+ statusText: string | null;
112
+ dispatchSummary: string | null;
113
+ toolTally: string;
114
+ dispatchRows: ReadonlyArray<DispatchBoardRow>;
115
+ contextActivity?: {
116
+ message: string;
117
+ detail: string | null;
118
+ status: "started" | "running" | "completed" | "failed";
119
+ } | null;
120
+ /** Metrics for the most recent completed turn, surfaced when the agent is idle. */
121
+ lastTurn: TurnSummary | null;
122
+ /** Session task board declared through the tasks tool; null before any plan. */
123
+ taskBoard?: TaskBoardSnapshot | null;
124
+ }
125
+
126
+ /** Responsive bands for the expanded footer. */
127
+ export const EXPANDED_WIDE = 80;
128
+ export const EXPANDED_MID = 70;
129
+ export const EXPANDED_ULTRAWIDE = 120;
130
+
131
+ /** Compact footer shows the git section only when there is room for it. */
132
+ const COMPACT_GIT_MIN_WIDTH = 72;
133
+
134
+ /**
135
+ * The `visibleWidth` guard looks redundant against `truncateToWidth`, which
136
+ * measures internally, but it is not: dropping it pads wide-char truncations
137
+ * with a trailing space and strips a bare ANSI reset at width 0. Both are
138
+ * visible output, so the extra measurement stays.
139
+ */
140
+ export function fitDashboardLine(line: string, width: number): string {
141
+ return visibleWidth(line) > width ? truncateToWidth(line, width, "…", true) : line;
142
+ }
143
+
144
+ /**
145
+ * Pad or truncate an already styled string to an exact column width. A cut is
146
+ * marked with an ellipsis so a clipped value ("proj 1.", "read 14 · bash 9 ")
147
+ * never reads as a complete fact.
148
+ */
149
+ function cell(text: string, width: number): string {
150
+ const safe = Math.max(0, width);
151
+ const clipped = truncateToWidth(text, safe, "…", true);
152
+ return `${clipped}${" ".repeat(Math.max(0, safe - visibleWidth(clipped)))}`;
153
+ }
154
+
155
+ function joinColumns(left: string, right: string, width: number): string {
156
+ const safe = Math.max(0, Math.floor(width));
157
+ if (safe === 0) return "";
158
+ if (visibleWidth(right) === 0) return cell(left, safe);
159
+ const rightWidth = visibleWidth(right);
160
+ if (rightWidth >= safe) return cell(right, safe);
161
+ const leftBudget = Math.max(0, safe - rightWidth - 1);
162
+ const fittedLeft = visibleWidth(left) > leftBudget ? truncateToWidth(left, leftBudget, "…", true) : left;
163
+ const gap = Math.max(1, safe - visibleWidth(fittedLeft) - rightWidth);
164
+ return cell(`${fittedLeft}${" ".repeat(gap)}${right}`, safe);
165
+ }
166
+
167
+ function finiteNonNegative(value: number | null | undefined): number {
168
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : 0;
169
+ }
170
+
171
+ /**
172
+ * The tools row answers two different questions and used to answer only the
173
+ * second: what the model can reach, and what it has called. `registered` is the
174
+ * count of tool schemas sent to the provider this turn, so a session that has
175
+ * only dispatched still reports the tools it holds instead of reading "none",
176
+ * which said the model had no tools at all.
177
+ */
178
+ export function formatToolTally(snapshot: ToolTallySnapshot | null | undefined, registered?: number | null): string {
179
+ const available =
180
+ typeof registered === "number" && Number.isFinite(registered) && registered > 0
181
+ ? `${Math.floor(registered)} avail`
182
+ : null;
183
+ if (!snapshot) return `${available ?? "none"} · 0${GLYPH.error}`;
184
+ const entries = Object.entries(snapshot.tools)
185
+ .filter(([name, count]) => count > 0 && name.toLowerCase() !== "dispatch")
186
+ .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
187
+ .slice(0, 4)
188
+ .map(([name, count]) => `${name} ${formatFooterTokens(count)}`);
189
+ const called = entries.length > 0 ? entries.join(" · ") : available !== null ? null : "none";
190
+ const prefix = [available, called].filter((part): part is string => part !== null).join(" · ");
191
+ const active =
192
+ typeof snapshot.active === "number" && snapshot.active > 0 ? ` · active ${formatFooterTokens(snapshot.active)}` : "";
193
+ const truncated =
194
+ typeof snapshot.truncatedResults === "number" && snapshot.truncatedResults > 0
195
+ ? ` · trunc ${formatFooterTokens(snapshot.truncatedResults)}`
196
+ : "";
197
+ return `${prefix}${active}${truncated} · ${formatFooterTokens(snapshot.errors)}${GLYPH.error}`;
198
+ }
199
+
200
+ export function formatUsd(value: number): string {
201
+ if (!Number.isFinite(value) || value <= 0) return "$0.00";
202
+ if (value < 0.01) return `$${value.toFixed(4)}`;
203
+ return `$${value.toFixed(2)}`;
204
+ }
205
+
206
+ function gitMarker(theme: ClioTheme, dirty: boolean | null): string {
207
+ if (dirty === false) return theme.fg("success", "✓");
208
+ if (dirty === true) return theme.fg("warning", "!");
209
+ return theme.fg("dim", "?");
210
+ }
211
+
212
+ /** Git chip carrying a `git` label so a version-shaped branch never reads as a duplicate version. */
213
+ function gitChip(theme: ClioTheme, branch: string | null, dirty: boolean | null): string | null {
214
+ if (!branch) return null;
215
+ return `${theme.fg("dim", "git ")}${theme.fg("success", branch)} ${gitMarker(theme, dirty)}`;
216
+ }
217
+
218
+ function gitValue(theme: ClioTheme, branch: string | null, dirty: boolean | null): string | null {
219
+ if (!branch) return null;
220
+ return `${theme.fg("success", branch)} ${gitMarker(theme, dirty)}`;
221
+ }
222
+
223
+ /** `github.com/owner/repo` → `owner/repo`; otherwise the host or the raw value, trimmed. */
224
+ function collapseRemote(remote: string | null): string | null {
225
+ if (!remote) return null;
226
+ const cleaned = remote
227
+ .replace(/^git@/, "")
228
+ .replace(/^[a-z]+:\/\//, "")
229
+ .replace(/\.git$/, "");
230
+ const parts = cleaned.split(/[/:]/).filter(Boolean);
231
+ if (parts.length >= 2) return parts.slice(-2).join("/");
232
+ return parts[0] ?? null;
233
+ }
234
+
235
+ /**
236
+ * Compact primary row: workspace identity on the left and a meaningful work
237
+ * phase on the right. The editor rail owns model and thinking labels. The
238
+ * branch appears here, and only here, across the whole screen.
239
+ */
240
+ export function compactPrimaryLine(
241
+ workspace: WorkspaceFacts,
242
+ _session: SessionFacts,
243
+ width: number,
244
+ theme: ClioTheme = clioTheme(),
245
+ status: AgentStatus = {
246
+ phase: "idle",
247
+ since: 0,
248
+ lastMeaningfulAt: 0,
249
+ watchdogTier: 0,
250
+ watchdogPeak: 0,
251
+ localRuntime: false,
252
+ },
253
+ toolCounts: ToolTallySnapshot = { tools: {}, errors: 0 },
254
+ dispatchRows: ReadonlyArray<DispatchBoardRow> = [],
255
+ tick = 0,
256
+ now = Date.now(),
257
+ ): string {
258
+ const safeWidth = Math.max(1, Math.floor(width));
259
+ let git = safeWidth >= COMPACT_GIT_MIN_WIDTH ? gitChip(theme, workspace.branch, workspace.dirty) : null;
260
+ let right = buildHarnessStatePill(theme, status, toolCounts, dispatchRows, tick, now, safeWidth, true);
261
+ let left = joinSections(theme, [theme.fg("muted", workspace.cwd), git]);
262
+
263
+ if (visibleWidth(left) + 1 + visibleWidth(right) > safeWidth) {
264
+ right = buildHarnessStatePill(theme, status, toolCounts, dispatchRows, tick, now, safeWidth, false);
265
+ }
266
+
267
+ if (git && visibleWidth(left) + 1 + visibleWidth(right) > safeWidth) {
268
+ git = null;
269
+ left = theme.fg("muted", workspace.cwd);
270
+ }
271
+
272
+ if (visibleWidth(left) + 1 + visibleWidth(right) > safeWidth) {
273
+ const maxCwdWidth = Math.max(1, safeWidth - visibleWidth(right) - 1);
274
+ left = theme.fg("muted", truncateToWidth(workspace.cwd, maxCwdWidth, "…", true));
275
+ }
276
+
277
+ return joinColumns(left, right, safeWidth);
278
+ }
279
+
280
+ /**
281
+ * Compact secondary row: context fill + the single most important activity on
282
+ * the left, dispatch summary + tool tally on the right.
283
+ */
284
+ function compactMetricChipLimit(width: number): number {
285
+ if (width < 48) return 1;
286
+ if (width < 72) return 2;
287
+ if (width < 100) return 4;
288
+ return 6;
289
+ }
290
+
291
+ function contextBarCellBounds(width: number): { min: number; max: number } {
292
+ if (width < 48) return { min: 6, max: 6 };
293
+ if (width < 72) return { min: 8, max: 8 };
294
+ if (width < 100) return { min: 12, max: 12 };
295
+ return { min: 14, max: 16 };
296
+ }
297
+
298
+ function compactContextBarWidth(width: number): number {
299
+ const bounds = contextBarCellBounds(width);
300
+ const leftHalfBudget = Math.max(0, Math.floor(width / 2));
301
+ const budgetCells = Math.max(0, leftHalfBudget - CONTEXT_BAR_LABEL_WIDTH);
302
+ const wideScale = width >= 100 ? 14 + Math.min(2, Math.max(0, Math.floor((width - 100) / 10))) : bounds.max;
303
+ return Math.max(bounds.min, Math.min(bounds.max, budgetCells, wideScale));
304
+ }
305
+
306
+ function contextBreakdownForBar(context: ContextEngineFacts): ContextUsageBreakdown | undefined {
307
+ const reportedUsed = finiteNonNegative(context.used);
308
+ const toolTokens = finiteNonNegative(context.toolSchemaTokens);
309
+ const source = context.breakdown;
310
+ if (!source) {
311
+ if (reportedUsed <= 0 && toolTokens <= 0) return undefined;
312
+ return {
313
+ systemPromptTokens: 0,
314
+ toolSchemaTokens: Math.min(toolTokens, reportedUsed),
315
+ messageTokens: Math.max(0, reportedUsed - toolTokens),
316
+ pendingUserTokens: 0,
317
+ };
318
+ }
319
+ const system = finiteNonNegative(source.systemPromptTokens);
320
+ const tools = finiteNonNegative(source.toolSchemaTokens);
321
+ const conversation = finiteNonNegative(source.messageTokens) + finiteNonNegative(source.pendingUserTokens);
322
+ const total = system + tools + conversation;
323
+ if (reportedUsed <= 0 || total <= 0) {
324
+ return {
325
+ systemPromptTokens: system,
326
+ toolSchemaTokens: tools,
327
+ messageTokens: conversation,
328
+ pendingUserTokens: 0,
329
+ };
330
+ }
331
+ if (reportedUsed >= total) {
332
+ return {
333
+ systemPromptTokens: system,
334
+ toolSchemaTokens: tools,
335
+ messageTokens: conversation + (reportedUsed - total),
336
+ pendingUserTokens: 0,
337
+ };
338
+ }
339
+ const scale = reportedUsed / total;
340
+ return {
341
+ systemPromptTokens: system * scale,
342
+ toolSchemaTokens: tools * scale,
343
+ messageTokens: conversation * scale,
344
+ pendingUserTokens: 0,
345
+ };
346
+ }
347
+
348
+ function contextComposition(context: ContextEngineFacts): {
349
+ system: number;
350
+ tools: number;
351
+ chat: number;
352
+ free: number | null;
353
+ } {
354
+ const used = finiteNonNegative(context.used);
355
+ const window = finiteNonNegative(context.contextWindow);
356
+ const breakdown = contextBreakdownForBar(context);
357
+ return {
358
+ system: finiteNonNegative(breakdown?.systemPromptTokens),
359
+ tools: finiteNonNegative(breakdown?.toolSchemaTokens),
360
+ chat: finiteNonNegative(breakdown?.messageTokens) + finiteNonNegative(breakdown?.pendingUserTokens),
361
+ free: window > 0 ? Math.max(0, window - used) : null,
362
+ };
363
+ }
364
+
365
+ export function compactSecondaryLine(
366
+ context: ContextEngineFacts,
367
+ agent: AgentWorkFacts,
368
+ width: number,
369
+ theme: ClioTheme = clioTheme(),
370
+ status: AgentStatus = {
371
+ phase: "idle",
372
+ since: 0,
373
+ lastMeaningfulAt: 0,
374
+ watchdogTier: 0,
375
+ watchdogPeak: 0,
376
+ localRuntime: false,
377
+ },
378
+ throughput: TokenThroughputSnapshot | null = null,
379
+ sessionTokens: UsageBreakdown | null = null,
380
+ sessionCost: CostAggregate | null = null,
381
+ outputVerbosity?: OutputVerbosity | null,
382
+ leaderArmed = false,
383
+ shutdownArmed = false,
384
+ ): string {
385
+ const safeWidth = Math.max(1, Math.floor(width));
386
+ const barCells = compactContextBarWidth(safeWidth);
387
+ let left = "";
388
+ if (context.ledger) {
389
+ // The row follows the kv grammar: dim key, muted value. An unmeasured
390
+ // percent renders the ?% placeholder dim because it is scaffolding for a
391
+ // number that has not arrived, not a measurement.
392
+ const percent = theme.fg(
393
+ context.ledger.percent !== null ? "muted" : "dim",
394
+ formatContextPercent(context.ledger.percent),
395
+ );
396
+ left = `${theme.fg("dim", "ctx")} ${renderContextMeterBar(context.ledger, barCells, theme)} ${percent}`;
397
+ } else {
398
+ left = buildSegmentedContextBar(theme, barCells, context.contextWindow ?? 0, contextBreakdownForBar(context));
399
+ }
400
+ const maxRightWidth = Math.max(0, safeWidth - visibleWidth(left) - 1);
401
+ const right = buildMetricStrip(
402
+ theme,
403
+ status,
404
+ throughput,
405
+ agent.lastTurn,
406
+ sessionTokens,
407
+ sessionCost,
408
+ context.used ?? undefined,
409
+ maxRightWidth,
410
+ compactMetricChipLimit(safeWidth),
411
+ outputVerbosity,
412
+ leaderArmed,
413
+ shutdownArmed,
414
+ );
415
+ // At the smallest widths the context meter consumes the entire secondary
416
+ // row, so keep a compact mode marker on the left instead of silently hiding
417
+ // the active transcript setting.
418
+ if (outputVerbosity && outputVerbosity !== "default" && visibleWidth(right) === 0) {
419
+ const marker = outputVerbosity === "minimal" ? "m" : outputVerbosity === "verbose" ? "v" : "d";
420
+ left = `${left}${theme.fg("dim", ` out:${marker}`)}`;
421
+ }
422
+ return joinColumns(left, right, safeWidth);
423
+ }
424
+
425
+ type DashboardRow =
426
+ | { kind: "kv"; key: string; value: string | null | undefined; valueToken?: ClioToken; styled?: boolean }
427
+ | { kind: "status"; value: string | null | undefined }
428
+ | { kind: "legend"; value: string | null | undefined };
429
+
430
+ interface ExpandedQuadrantOptions {
431
+ width?: number;
432
+ }
433
+
434
+ function renderDashboardRow(theme: ClioTheme, row: DashboardRow, keyWidth: number): string | null {
435
+ if (!row.value) return null;
436
+ if (row.kind !== "kv") return row.value;
437
+ const key = theme.fg("dim", `${row.key.padEnd(keyWidth)} `);
438
+ const value = row.styled ? row.value : theme.fg(row.valueToken ?? "muted", row.value);
439
+ return `${key}${value}`;
440
+ }
441
+
442
+ function dashboardBlock(theme: ClioTheme, label: string, rows: ReadonlyArray<DashboardRow>): string[] {
443
+ const keyWidth = rows.reduce((max, row) => (row.kind === "kv" ? Math.max(max, row.key.length) : max), 0);
444
+ const body = rows
445
+ .map((row) => renderDashboardRow(theme, row, keyWidth))
446
+ .filter((row): row is string => typeof row === "string" && row.length > 0);
447
+ // Every quadrant tag shares one structure color. The tag names the quadrant;
448
+ // the color is not a per-quadrant signal, so all four render bold accentDeep
449
+ // rather than the old info/accent/reason/success carnival.
450
+ return [sectionTag(theme, "accentDeep", label.toUpperCase(), 0), ...body];
451
+ }
452
+
453
+ function kv(key: string, value: string | null | undefined, valueToken: ClioToken = "muted"): DashboardRow {
454
+ return { kind: "kv", key, value, valueToken };
455
+ }
456
+
457
+ function styledKv(key: string, value: string | null | undefined): DashboardRow {
458
+ return { kind: "kv", key, value, styled: true };
459
+ }
460
+
461
+ function statusRow(value: string | null | undefined): DashboardRow {
462
+ return { kind: "status", value };
463
+ }
464
+
465
+ function legendRow(value: string | null | undefined): DashboardRow {
466
+ return { kind: "legend", value };
467
+ }
468
+
469
+ export function workspaceQuadrant(facts: WorkspaceFacts, _options: ExpandedQuadrantOptions = {}): string[] {
470
+ const theme = clioTheme();
471
+ const remote = collapseRemote(facts.remote);
472
+ return dashboardBlock(theme, "Workspace", [
473
+ kv("cwd", facts.cwd),
474
+ styledKv("git", gitValue(theme, facts.branch, facts.dirty)),
475
+ kv("type", facts.projectType),
476
+ kv("remote", remote),
477
+ ]);
478
+ }
479
+
480
+ function sessionIdentity(facts: SessionFacts): { key: string; value: string } | null {
481
+ if (facts.id) return { key: "id", value: facts.id };
482
+ if (facts.name) return { key: "name", value: facts.name };
483
+ return null;
484
+ }
485
+
486
+ function capabilitiesValue(theme: ClioTheme, capabilities: string[] | null): string | null {
487
+ if (!capabilities || capabilities.length === 0) return null;
488
+ return joinChips(
489
+ theme,
490
+ capabilities.map((capability) => theme.fg("muted", capability)),
491
+ );
492
+ }
493
+
494
+ export function sessionQuadrant(facts: SessionFacts, options: ExpandedQuadrantOptions = {}): string[] {
495
+ const theme = clioTheme();
496
+ const identity = sessionIdentity(facts);
497
+ const memory = facts.memoryIntervention;
498
+ const memoryValue = memory
499
+ ? fitUnits(
500
+ theme,
501
+ "",
502
+ [
503
+ theme.fg(memory.enabled ? "success" : "dim", memory.enabled ? "on" : "off"),
504
+ theme.fg(memory.tier === "llm" ? "reason" : "muted", `tier ${memory.tier === "llm" ? "LLM" : "rules"}`),
505
+ theme.fg("muted", `bank ${memory.size}`),
506
+ // A background step runs for tens of seconds on a small local model.
507
+ // Saying so is the difference between a quiet feature and a dead one.
508
+ ...(memory.stepInFlight ? [theme.fg("reason", "working")] : []),
509
+ ...(memory.lastDecision ? [theme.fg("dim", memory.lastDecision)] : []),
510
+ ],
511
+ Math.max(1, (options.width ?? Number.POSITIVE_INFINITY) - 9),
512
+ )
513
+ : null;
514
+ return dashboardBlock(theme, "Session", [
515
+ identity ? kv(identity.key, identity.value, "accent") : statusRow(null),
516
+ kv("target", facts.target, "accent"),
517
+ kv("think", facts.thinking, "reason"),
518
+ styledKv("caps", capabilitiesValue(theme, facts.capabilities)),
519
+ // accentDeep is a structure color reserved for the section tag; the autonomy
520
+ // value is a plain fact and reads muted like the other neutral values.
521
+ kv("autonomy", facts.safety),
522
+ kv("profile", facts.toolProfile),
523
+ kv(
524
+ "output",
525
+ facts.outputVerbosity && facts.outputVerbosity !== "default" ? facts.outputVerbosity : null,
526
+ facts.outputVerbosity === "verbose" ? "accent" : "muted",
527
+ ),
528
+ styledKv("memory", memoryValue),
529
+ ]);
530
+ }
531
+
532
+ function expandedContextBarCells(width: number | undefined): number {
533
+ if (typeof width !== "number" || !Number.isFinite(width) || width <= 0) return 12;
534
+ const budget = Math.max(6, Math.floor(width) - CONTEXT_BAR_LABEL_WIDTH - 1);
535
+ // A wider quadrant earns a finer meter: every extra cell is real resolution,
536
+ // up to 24 cells so the bar never dwarfs the facts beneath it.
537
+ const desired = width >= 48 ? 24 : width >= 36 ? 16 : width >= 32 ? 14 : 12;
538
+ return Math.max(8, Math.min(24, desired, budget));
539
+ }
540
+
541
+ function formatUsedWindow(used: number | null, contextWindow: number | null): string | null {
542
+ if (used === null || !contextWindow) return null;
543
+ return `${formatFooterTokens(used)} / ${formatFooterTokens(contextWindow)}`;
544
+ }
545
+
546
+ function formatCompaction(facts: ContextEngineFacts): string | null {
547
+ if (facts.compactionThreshold === null) return null;
548
+ const mode = facts.compactionAuto ? "auto" : "manual";
549
+ const threshold = Math.round(facts.compactionThreshold * 100);
550
+ return `${facts.compactionActive ? "active " : ""}${mode} @${threshold}%`;
551
+ }
552
+
553
+ function sourceState(theme: ClioTheme, facts: ContextEngineFacts): string | null {
554
+ const value = joinChips(theme, [
555
+ facts.clioMd ? theme.fg("muted", facts.clioMd) : null,
556
+ facts.memory ? theme.fg("muted", facts.memory) : null,
557
+ ]);
558
+ return value.length > 0 ? value : null;
559
+ }
560
+
561
+ /** Short labels for the dense footer; the overlay carries the full names. */
562
+ const CONTEXT_SHORT_LABEL: Readonly<Record<ContextLedgerCategory, string>> = {
563
+ system: "sys",
564
+ tools: "tools",
565
+ agents: "agt",
566
+ skills: "skl",
567
+ memory: "mem",
568
+ project: "proj",
569
+ messages: "chat",
570
+ pending: "input",
571
+ reserve: "rsv",
572
+ free: "free",
573
+ streaming: "stream",
574
+ };
575
+
576
+ /** Static-side cost chips (system prompt, tools, agents, skills, memory, project), heaviest first. */
577
+ function ledgerSystemChips(theme: ClioTheme, ledger: ContextLedger): string {
578
+ const statics = new Set<ContextLedgerCategory>(["system", "tools", "agents", "skills", "memory", "project"]);
579
+ const chips = ledger.groups
580
+ .filter((group) => statics.has(group.category))
581
+ .sort((a, b) => b.tokens - a.tokens)
582
+ .slice(0, 4)
583
+ .map((group) =>
584
+ theme.fg(
585
+ CONTEXT_CATEGORY_TOKEN[group.category],
586
+ `${CONTEXT_SHORT_LABEL[group.category]} ${formatFooterTokens(group.tokens)}`,
587
+ ),
588
+ );
589
+ return joinChips(theme, chips);
590
+ }
591
+
592
+ /** Conversation, autocompact reserve, and free-space chips. */
593
+ function ledgerChatChips(theme: ClioTheme, ledger: ContextLedger): string {
594
+ const chat = ledger.groups.find((group) => group.category === "messages")?.tokens ?? 0;
595
+ return joinChips(theme, [
596
+ theme.fg("accent", `chat ${formatFooterTokens(chat)}`),
597
+ ledger.reserveTokens > 0 ? theme.fg("dim", `rsv ${formatFooterTokens(ledger.reserveTokens)}`) : null,
598
+ ledger.contextWindow > 0
599
+ ? theme.style("frame", `free ${formatFooterTokens(ledger.freeTokens)}`, { dim: true })
600
+ : null,
601
+ ]);
602
+ }
603
+
604
+ /**
605
+ * Swatch legend covering exactly the categories present in the meter, packed
606
+ * into as many rows as the quadrant needs. A ledger can carry ten categories,
607
+ * more than one quadrant row holds, and dropping tail entries would hide
608
+ * whole categories, so the legend wraps by whole chips instead of clipping.
609
+ */
610
+ function ledgerLegendRows(theme: ClioTheme, ledger: ContextLedger, width: number | undefined): string[] {
611
+ const chips = ledger.meter.map((group) => {
612
+ const labelToken: ClioToken = group.category === "free" || group.category === "reserve" ? "dim" : "muted";
613
+ return `${contextCategorySwatch(group.category, theme)} ${theme.fg(labelToken, CONTEXT_SHORT_LABEL[group.category])}`;
614
+ });
615
+ const budget =
616
+ typeof width === "number" && Number.isFinite(width) && width > 0 ? Math.floor(width) : Number.POSITIVE_INFINITY;
617
+ const rows: string[] = [];
618
+ let current = "";
619
+ for (const chip of chips) {
620
+ const candidate = current.length > 0 ? `${current} ${chip}` : chip;
621
+ if (current.length > 0 && visibleWidth(candidate) > budget) {
622
+ rows.push(current);
623
+ current = chip;
624
+ } else {
625
+ current = candidate;
626
+ }
627
+ }
628
+ if (current.length > 0) rows.push(current);
629
+ return rows;
630
+ }
631
+
632
+ function ledgerBar(theme: ClioTheme, ledger: ContextLedger, cells: number): string {
633
+ const percent = theme.fg(ledger.percent !== null ? "muted" : "dim", formatContextPercent(ledger.percent));
634
+ return `${renderContextMeterBar(ledger, cells, theme)} ${percent}`;
635
+ }
636
+
637
+ export function contextQuadrant(facts: ContextEngineFacts, options: ExpandedQuadrantOptions = {}): string[] {
638
+ const theme = clioTheme();
639
+ const ledger = facts.ledger ?? null;
640
+ const hasLedger = ledger !== null && ledger.contextWindow > 0;
641
+ const barCells = expandedContextBarCells(options.width);
642
+
643
+ let bar: string;
644
+ let fill: string;
645
+ let chatFree: string;
646
+ let legendRows: string[];
647
+ if (hasLedger && ledger) {
648
+ bar = ledgerBar(theme, ledger, barCells);
649
+ fill = ledgerSystemChips(theme, ledger);
650
+ chatFree = ledgerChatChips(theme, ledger);
651
+ legendRows = ledgerLegendRows(theme, ledger, options.width);
652
+ } else {
653
+ const composition = contextComposition(facts);
654
+ fill = joinChips(theme, [
655
+ composition.system > 0 ? theme.fg("info", `sys ${formatFooterTokens(composition.system)}`) : null,
656
+ composition.tools > 0 ? theme.fg("warning", `tools ${formatFooterTokens(composition.tools)}`) : null,
657
+ ]);
658
+ chatFree = joinChips(theme, [
659
+ composition.chat > 0 ? theme.fg("accent", formatFooterTokens(composition.chat)) : null,
660
+ composition.free !== null
661
+ ? theme.style("frame", `free ${formatFooterTokens(composition.free)}`, { dim: true })
662
+ : null,
663
+ ]);
664
+ bar = buildSegmentedContextBar(theme, barCells, facts.contextWindow ?? 0, contextBreakdownForBar(facts));
665
+ const filledChar = visibleWidth(GLYPH.contextFull) === 1 ? GLYPH.contextFull : GLYPH.barFull;
666
+ const freeChar = visibleWidth(GLYPH.contextFree) === 1 ? GLYPH.contextFree : GLYPH.barEmpty;
667
+ legendRows = [
668
+ `${theme.fg("info", `${filledChar} sys`)} ${theme.fg("warning", `${filledChar} tools`)} ${theme.fg("accent", `${filledChar} chat`)} ${theme.style("frame", `${freeChar} free`, { dim: true })}`,
669
+ ];
670
+ }
671
+
672
+ const usedTokens = hasLedger && ledger ? ledger.usedTokens : facts.used;
673
+ const windowTokens = hasLedger && ledger ? ledger.contextWindow : facts.contextWindow;
674
+ return dashboardBlock(theme, "Context", [
675
+ statusRow(bar),
676
+ kv("used", formatUsedWindow(usedTokens, windowTokens)),
677
+ fill ? styledKv("fill", fill) : statusRow(null),
678
+ chatFree ? styledKv("chat", chatFree) : statusRow(null),
679
+ kv("compact", formatCompaction(facts)),
680
+ styledKv("source", sourceState(theme, facts)),
681
+ facts.extensions && facts.extensions.installed > 0
682
+ ? kv("ext", `${facts.extensions.active}/${facts.extensions.installed}`)
683
+ : statusRow(null),
684
+ ...legendRows.map((row) => legendRow(row)),
685
+ ]);
686
+ }
687
+
688
+ function stopReasonStyle(reason: TurnSummary["stopReason"]): { glyph: string; token: ClioToken } {
689
+ if (reason === "error") return { glyph: GLYPH.error, token: "error" };
690
+ if (reason === "aborted" || reason === "cancelled") return { glyph: GLYPH.cancelled, token: "dim" };
691
+ if (reason === "length") return { glyph: GLYPH.warn, token: "warning" };
692
+ return { glyph: GLYPH.ok, token: "success" };
693
+ }
694
+
695
+ /**
696
+ * Elegant single-line readout of the most recent completed turn. This is the
697
+ * footer home for the metrics that used to print faintly under each assistant
698
+ * reply: stop outcome, wall time, token in/out, reasoning, and tool work. The
699
+ * model is intentionally omitted because the editor rail already carries it.
700
+ */
701
+ export function formatLastTurn(theme: ClioTheme, summary: TurnSummary): string {
702
+ const stop = stopReasonStyle(summary.stopReason);
703
+ const parts: string[] = [
704
+ theme.fg(stop.token, `${stop.glyph} ${formatCompactMs(summary.elapsedMs)}`),
705
+ theme.fg("muted", `${GLYPH.up}${summary.inputTokens} ${GLYPH.down}${summary.outputTokens}`),
706
+ ];
707
+ // Zero suppresses the chip, the same rule the chat panel's turn line follows:
708
+ // a turn that spent no reasoning tokens states nothing by printing `r0`.
709
+ if (typeof summary.reasoningTokens === "number" && summary.reasoningTokens > 0) {
710
+ const marker =
711
+ summary.reasoningTokenProvenance === "estimated" || summary.reasoningTokenProvenance === "mixed" ? "≈" : "";
712
+ parts.push(theme.fg("reason", `r${marker}${summary.reasoningTokens}`));
713
+ }
714
+ if (summary.cacheReadTokens > 0 || summary.cacheWriteTokens > 0) {
715
+ parts.push(theme.fg("dim", `cache ${summary.cacheReadTokens}/${summary.cacheWriteTokens}`));
716
+ }
717
+ if (summary.toolCount > 0) {
718
+ const label = `${summary.toolCount} tool${summary.toolCount === 1 ? "" : "s"}`;
719
+ const errors = summary.toolErrorCount > 0 ? theme.fg("error", ` ${summary.toolErrorCount}${GLYPH.error}`) : "";
720
+ parts.push(`${theme.fg("muted", label)}${errors}`);
721
+ }
722
+ if (summary.watchdogPeak >= 2) parts.push(theme.fg("warning", "slow"));
723
+ if (summary.truncated) parts.push(theme.fg("warning", "trunc"));
724
+ return parts.join(theme.fg("dim", " · "));
725
+ }
726
+
727
+ /**
728
+ * One row per live worker: the origin glyph, the sub-process glyph when Clio
729
+ * started the run for itself, the agent's own name, the fleet node it landed
730
+ * on, its status glyph, elapsed, and the receipt id once the run has sealed
731
+ * one. Units are fitted whole, so a narrow quadrant closes on a dim ellipsis
732
+ * rather than clipping a receipt id into a string that still reads like a valid
733
+ * trace argument.
734
+ */
735
+ function workerLine(theme: ClioTheme, row: DispatchBoardRow, width: number): string {
736
+ const presentation = dispatchStatusPresentation(row.status, { compact: true });
737
+ // The Activity section already promotes the fleet summary (or dispatch phase)
738
+ // to action orange. Worker rows remain readable without repeating that signal.
739
+ const token = presentation.token === "action" ? "accent" : presentation.token;
740
+ const units = [
741
+ theme.fg("muted", agentDisplayLabel(row)),
742
+ theme.fg("dim", row.node ?? "local"),
743
+ theme.fg(token, presentation.glyph),
744
+ theme.fg("dim", formatCompactMs(row.elapsedMs)),
745
+ ...(row.receiptId !== undefined ? [theme.fg("dim", row.receiptId)] : []),
746
+ ];
747
+ return fitUnits(theme, dispatchRowPrefix(theme, row).text, units, Math.max(1, Math.floor(width)));
748
+ }
749
+
750
+ interface ActivityQuadrantOptions extends ExpandedQuadrantOptions {
751
+ status?: AgentStatus;
752
+ toolCounts?: ToolTallySnapshot;
753
+ throughput?: TokenThroughputSnapshot | null;
754
+ sessionTokens?: UsageBreakdown | null;
755
+ sessionCost?: CostAggregate | null;
756
+ contextUsed?: number | null;
757
+ tick?: number;
758
+ now?: number;
759
+ maxWorkers?: number;
760
+ }
761
+
762
+ function defaultIdleStatus(): AgentStatus {
763
+ return {
764
+ phase: "idle",
765
+ since: 0,
766
+ lastMeaningfulAt: 0,
767
+ watchdogTier: 0,
768
+ watchdogPeak: 0,
769
+ localRuntime: false,
770
+ };
771
+ }
772
+
773
+ function formattedThroughput(theme: ClioTheme, throughput: TokenThroughputSnapshot | null | undefined): string | null {
774
+ const tps = finiteNonNegative(throughput?.tokensPerSecond);
775
+ if (tps <= 0) return null;
776
+ const rounded = tps >= 10 ? Math.round(tps) : Math.round(tps * 10) / 10;
777
+ const parts = [theme.fg("success", `${GLYPH.speed}${rounded}/s`)];
778
+ const ttft = finiteNonNegative(throughput?.ttftMs);
779
+ if (ttft > 0) parts.push(theme.fg("muted", `ttft ${formatCompactMs(ttft)}`));
780
+ return joinChips(theme, parts);
781
+ }
782
+
783
+ function liveTokenValue(
784
+ theme: ClioTheme,
785
+ status: AgentStatus,
786
+ throughput: TokenThroughputSnapshot | null | undefined,
787
+ lastTurn: TurnSummary | null,
788
+ sessionTokens: UsageBreakdown | null | undefined,
789
+ contextUsed: number | null | undefined,
790
+ ): string | null {
791
+ const output = finiteNonNegative(throughput?.outputTokens);
792
+ const input =
793
+ finiteNonNegative(contextUsed) ||
794
+ finiteNonNegative(status.summary?.inputTokens) ||
795
+ finiteNonNegative(lastTurn?.inputTokens) ||
796
+ finiteNonNegative(sessionTokens?.input);
797
+ const parts = [
798
+ output > 0 ? theme.fg("success", `${GLYPH.down}${formatFooterTokens(output)}`) : null,
799
+ input > 0 ? theme.fg("muted", `${GLYPH.up}${formatFooterTokens(input)}`) : null,
800
+ ];
801
+ const joined = joinChips(theme, parts);
802
+ return joined.length > 0 ? joined : null;
803
+ }
804
+
805
+ function lastTurnOutcome(theme: ClioTheme, lastTurn: TurnSummary): string {
806
+ const stop = stopReasonStyle(lastTurn.stopReason);
807
+ return theme.fg(stop.token, `${stop.glyph} ${formatCompactMs(lastTurn.elapsedMs)}`);
808
+ }
809
+
810
+ function lastTurnDetails(theme: ClioTheme, lastTurn: TurnSummary): string {
811
+ const parts: Array<string | null> = [
812
+ theme.fg(
813
+ "muted",
814
+ `${GLYPH.up}${formatFooterTokens(lastTurn.inputTokens)} ${GLYPH.down}${formatFooterTokens(lastTurn.outputTokens)}`,
815
+ ),
816
+ lastTurn.reasoningTokens !== undefined && lastTurn.reasoningTokens > 0
817
+ ? theme.fg(
818
+ "reason",
819
+ `r${lastTurn.reasoningTokenProvenance === "estimated" || lastTurn.reasoningTokenProvenance === "mixed" ? "≈" : ""}${formatFooterTokens(lastTurn.reasoningTokens)}`,
820
+ )
821
+ : null,
822
+ lastTurn.cacheReadTokens > 0 || lastTurn.cacheWriteTokens > 0
823
+ ? theme.fg(
824
+ "dim",
825
+ `cache ${formatFooterTokens(lastTurn.cacheReadTokens)}/${formatFooterTokens(lastTurn.cacheWriteTokens)}`,
826
+ )
827
+ : null,
828
+ ];
829
+ if (lastTurn.toolCount > 0) {
830
+ const label = `${lastTurn.toolCount} tool${lastTurn.toolCount === 1 ? "" : "s"}`;
831
+ const errors = lastTurn.toolErrorCount > 0 ? theme.fg("error", ` ${lastTurn.toolErrorCount}${GLYPH.error}`) : "";
832
+ parts.push(`${theme.fg("muted", label)}${errors}`);
833
+ }
834
+ if (lastTurn.watchdogPeak >= 2) parts.push(theme.fg("warning", "slow"));
835
+ if (lastTurn.truncated) parts.push(theme.fg("warning", "trunc"));
836
+ return joinChips(theme, parts);
837
+ }
838
+
839
+ function cumulativeTokens(sessionTokens: UsageBreakdown | null | undefined): number {
840
+ const fallback = finiteNonNegative(sessionTokens?.input) + finiteNonNegative(sessionTokens?.output);
841
+ return finiteNonNegative(sessionTokens?.totalTokens) || fallback;
842
+ }
843
+
844
+ function fleetValue(dispatchSummary: string | null, dispatchRows: ReadonlyArray<DispatchBoardRow>): string | null {
845
+ if (dispatchSummary) return dispatchSummary.replace(/^dispatch\s+/, "");
846
+ return dispatchRows.length > 0 ? `${dispatchRows.length} runs` : null;
847
+ }
848
+
849
+ function meaningfulToolTally(value: string): string | null {
850
+ return /^(?:none(?: · 0✗)?|0✗)$/u.test(value.trim()) ? null : value;
851
+ }
852
+
853
+ /** Task-board progress chips: `2/5 done`, with a warning chip when tasks are blocked. */
854
+ function taskBoardValue(theme: ClioTheme, board: TaskBoardSnapshot): string {
855
+ const counts = taskBoardCounts(board);
856
+ const progress = theme.fg(counts.open > 0 ? "muted" : "success", `${counts.completed}/${counts.total} done`);
857
+ const blocked = counts.blocked > 0 ? theme.fg("warning", `${counts.blocked} blocked`) : null;
858
+ return joinChips(theme, [progress, blocked]);
859
+ }
860
+
861
+ /** The board's current focus: the single active task, glyph-led like a worker row. */
862
+ function activeTaskLine(theme: ClioTheme, board: TaskBoardSnapshot): string | null {
863
+ const active = board.tasks.find((task) => task.status === "active");
864
+ if (!active) return null;
865
+ return `${theme.fg("accent", GLYPH.running)} ${theme.fg("dim", active.id)} ${theme.fg("muted", active.title)}`;
866
+ }
867
+
868
+ export function activityQuadrant(facts: AgentWorkFacts, options: ActivityQuadrantOptions = {}): string[] {
869
+ const theme = clioTheme();
870
+ const maxWorkers = Math.max(0, options.maxWorkers ?? 3);
871
+ const status = options.status ?? defaultIdleStatus();
872
+ const toolCounts = options.toolCounts ?? { tools: {}, errors: 0 };
873
+ const statusWidth = Math.max(options.width ?? 120, 48);
874
+ const isStreaming = status.phase !== "idle" && status.phase !== "ended";
875
+ const fleetSummaryIsAction = facts.dispatchSummary !== null && status.phase !== "dispatching";
876
+ const rows: DashboardRow[] = [
877
+ statusRow(
878
+ buildHarnessStatePill(
879
+ theme,
880
+ status,
881
+ toolCounts,
882
+ facts.dispatchRows,
883
+ options.tick ?? 0,
884
+ options.now ?? Date.now(),
885
+ statusWidth,
886
+ true,
887
+ fleetSummaryIsAction,
888
+ ),
889
+ ),
890
+ ];
891
+ if (facts.contextActivity) {
892
+ const token =
893
+ facts.contextActivity.status === "failed"
894
+ ? "error"
895
+ : facts.contextActivity.status === "completed"
896
+ ? "success"
897
+ : "accent";
898
+ rows.push(kv("context", facts.contextActivity.message, token));
899
+ if (facts.contextActivity.detail) rows.push(kv("ctx detail", facts.contextActivity.detail, "dim"));
900
+ }
901
+ if (isStreaming && facts.statusText) rows.push(kv("state", facts.statusText, "accent"));
902
+ if (isStreaming) {
903
+ rows.push(styledKv("speed", formattedThroughput(theme, options.throughput)));
904
+ rows.push(
905
+ styledKv(
906
+ "live",
907
+ liveTokenValue(theme, status, options.throughput, facts.lastTurn, options.sessionTokens, options.contextUsed),
908
+ ),
909
+ );
910
+ } else if (facts.lastTurn) {
911
+ rows.push(styledKv("last", lastTurnOutcome(theme, facts.lastTurn)));
912
+ rows.push(styledKv("turn", lastTurnDetails(theme, facts.lastTurn)));
913
+ rows.push(styledKv("speed", formattedThroughput(theme, options.throughput)));
914
+ }
915
+ const total = cumulativeTokens(options.sessionTokens);
916
+ rows.push(total > 0 ? styledKv("totals", theme.fg("muted", `Σ${formatFooterTokens(total)}`)) : statusRow(null));
917
+ // Null until something has actually been priced, and an absent row is the
918
+ // only honest rendering of that. See formatCostAggregate.
919
+ const cost = formatCostAggregate(options.sessionCost);
920
+ rows.push(cost === null ? statusRow(null) : styledKv("cost", theme.fg("muted", cost)));
921
+ rows.push(kv("fleet", fleetValue(facts.dispatchSummary, facts.dispatchRows), fleetSummaryIsAction ? "action" : "dim"));
922
+ // Every worker up to the panel bound gets its own row; what the bound cuts is
923
+ // counted out loud instead of vanishing, so the row count an operator sees
924
+ // always reconciles with the `fleet` line above it.
925
+ const workerWidth = options.width !== undefined && Number.isFinite(options.width) ? options.width : 48;
926
+ for (const row of facts.dispatchRows.slice(0, maxWorkers)) rows.push(statusRow(workerLine(theme, row, workerWidth)));
927
+ const hiddenWorkers = facts.dispatchRows.length - maxWorkers;
928
+ if (hiddenWorkers > 0) rows.push(statusRow(theme.fg("dim", `+${hiddenWorkers} more`)));
929
+ if (facts.taskBoard && facts.taskBoard.tasks.length > 0) {
930
+ rows.push(styledKv("tasks", taskBoardValue(theme, facts.taskBoard)));
931
+ rows.push(statusRow(activeTaskLine(theme, facts.taskBoard)));
932
+ }
933
+ rows.push(kv("tools", meaningfulToolTally(facts.toolTally)));
934
+ return dashboardBlock(theme, "Activity", rows);
935
+ }
936
+
937
+ /**
938
+ * Zip two quadrant blocks into a side-by-side row, padding the shorter block so
939
+ * both columns stay aligned, and clamping each cell to its column width.
940
+ */
941
+ export function zipColumns(
942
+ left: string[],
943
+ right: string[],
944
+ leftWidth: number,
945
+ rightWidth: number,
946
+ sep: string,
947
+ ): string[] {
948
+ const rowCount = Math.max(left.length, right.length);
949
+ const lines: string[] = [];
950
+ for (let i = 0; i < rowCount; i += 1) {
951
+ lines.push(`${cell(left[i] ?? "", leftWidth)}${sep}${cell(right[i] ?? "", rightWidth)}`);
952
+ }
953
+ return lines;
954
+ }
955
+
956
+ export function zipColumnBlocks(blocks: ReadonlyArray<string[]>, widths: ReadonlyArray<number>, sep: string): string[] {
957
+ const rowCount = blocks.reduce((max, block) => Math.max(max, block.length), 0);
958
+ const lines: string[] = [];
959
+ for (let row = 0; row < rowCount; row += 1) {
960
+ const cells = blocks.map((block, index) => cell(block[row] ?? "", widths[index] ?? 0));
961
+ lines.push(cells.join(sep));
962
+ }
963
+ return lines;
964
+ }
965
+
966
+ type HarnessPhasePresentation = {
967
+ glyph: string;
968
+ label: string;
969
+ token: ClioToken;
970
+ live: boolean;
971
+ };
972
+
973
+ function shortToolLabel(status: AgentStatus, width: number): string {
974
+ const name = status.tool?.toolName?.trim();
975
+ if (name === ToolNames.AskUser) return width < 72 ? "ask" : "waiting for user";
976
+ if (!name || width < 72) return "tool";
977
+ const nameWidth = width >= 100 ? 18 : 12;
978
+ // The pill label is never padded; truncate without pad so the tool name is
979
+ // followed by a single space before the badge, not a column of blanks.
980
+ return `tool ${truncateToWidth(name, nameWidth, "…", false)}`;
981
+ }
982
+
983
+ function harnessPhasePresentation(status: AgentStatus, width: number, now: number): HarnessPhasePresentation {
984
+ const ultraNarrow = width < 48;
985
+ switch (status.phase) {
986
+ case "idle":
987
+ return { glyph: GLYPH.queued, label: "idle", token: "muted", live: false };
988
+ case "preparing":
989
+ return { glyph: GLYPH.phaseWaiting, label: "prep", token: "info", live: true };
990
+ case "waiting_model":
991
+ return { glyph: GLYPH.phaseWaiting, label: "waiting", token: "info", live: true };
992
+ case "thinking":
993
+ return { glyph: GLYPH.phaseThinking, label: "thinking", token: "reason", live: true };
994
+ case "writing":
995
+ return { glyph: GLYPH.phaseWriting, label: "writing", token: "accent", live: true };
996
+ case "tool_running":
997
+ return { glyph: GLYPH.phaseTool, label: shortToolLabel(status, width), token: "accent", live: true };
998
+ case "tool_blocked":
999
+ // Attention states hold a static glyph rather than spinning: the work
1000
+ // has paused for a human, so the pill should not read as live progress.
1001
+ // The phase fires only on PermissionRequested, so the pill names the
1002
+ // wait for confirmation; "blocked" would contradict the ask overlay.
1003
+ return { glyph: GLYPH.phaseBlocked, label: "confirm", token: "warning", live: false };
1004
+ case "retrying": {
1005
+ const attempt = status.retry?.attempt ?? 0;
1006
+ const maxAttempts = status.retry?.maxAttempts ?? 0;
1007
+ return {
1008
+ glyph: GLYPH.phaseRetry,
1009
+ label: ultraNarrow ? "retry" : `retry ${attempt}/${maxAttempts}`,
1010
+ token: "warning",
1011
+ live: false,
1012
+ };
1013
+ }
1014
+ case "compacting":
1015
+ return { glyph: GLYPH.phaseCompact, label: "compacting", token: "reason", live: true };
1016
+ case "dispatching":
1017
+ return { glyph: GLYPH.phaseDispatch, label: "dispatch", token: "action", live: true };
1018
+ case "stuck": {
1019
+ const seconds = Math.max(0, Math.floor((now - status.since) / 1000));
1020
+ return { glyph: GLYPH.warn, label: ultraNarrow ? "stuck" : `stuck ${seconds}s`, token: "error", live: false };
1021
+ }
1022
+ case "ended":
1023
+ return { glyph: GLYPH.ok, label: "done", token: "success", live: false };
1024
+ }
1025
+ }
1026
+
1027
+ function activeWorkerRows(rows: ReadonlyArray<DispatchBoardRow>): ReadonlyArray<DispatchBoardRow> {
1028
+ return rows.filter((row) => row.status === "running" || row.status === "stale" || row.status === "enqueued");
1029
+ }
1030
+
1031
+ /**
1032
+ * The live worker count, split by who asked once more than one kind is running:
1033
+ * `◇1 ◆3` says the operator has one run of their own alongside three the model
1034
+ * started, which `fleet 4` cannot. A single kind keeps the plain count, and so
1035
+ * does a set holding a run whose origin never reached the projection, because a
1036
+ * split that cannot name every active run would report a total that is short.
1037
+ *
1038
+ * The chip keeps one color. Its token says the fleet is busy; origin is carried
1039
+ * by glyph shape, which is the same pair the board rows and the transcript
1040
+ * blocks use.
1041
+ */
1042
+ function activeWorkerChip(rows: ReadonlyArray<DispatchBoardRow>): string {
1043
+ const active = activeWorkerRows(rows);
1044
+ const counts = new Map<string, number>();
1045
+ for (const row of active) {
1046
+ const glyph = dispatchOriginPresentation(row)?.glyph;
1047
+ if (glyph === undefined) return `fleet ${active.length}`;
1048
+ counts.set(glyph, (counts.get(glyph) ?? 0) + 1);
1049
+ }
1050
+ if (counts.size < 2) return `fleet ${active.length}`;
1051
+ const order = [GLYPH.workerHuman, GLYPH.workerAgent, GLYPH.workerInternal];
1052
+ return order
1053
+ .filter((glyph) => counts.has(glyph))
1054
+ .map((glyph) => `${glyph}${counts.get(glyph)}`)
1055
+ .join(" ");
1056
+ }
1057
+
1058
+ function harnessBadge(
1059
+ theme: ClioTheme,
1060
+ status: AgentStatus,
1061
+ toolCounts: ToolTallySnapshot,
1062
+ dispatchRows: ReadonlyArray<DispatchBoardRow>,
1063
+ fleetSummaryIsAction = false,
1064
+ ): string {
1065
+ const workers = activeWorkerRows(dispatchRows).length;
1066
+ const activeTools = finiteNonNegative(toolCounts.active);
1067
+ // Active fleet work is a Clio-signature state; it gets the action color.
1068
+ if (workers > 0) {
1069
+ const token = status.phase === "dispatching" ? "muted" : fleetSummaryIsAction ? "accent" : "action";
1070
+ return theme.fg(token, activeWorkerChip(dispatchRows));
1071
+ }
1072
+ const badgeText = activeTools > 0 ? `tools ${activeTools}` : null;
1073
+ return badgeText ? theme.fg("muted", badgeText) : "";
1074
+ }
1075
+
1076
+ function outputVerbosityLabel(verbosity: OutputVerbosity): string {
1077
+ return verbosity === "minimal" ? "min" : verbosity === "verbose" ? "verbose" : "default";
1078
+ }
1079
+
1080
+ export function buildHarnessStatePill(
1081
+ theme: ClioTheme,
1082
+ status: AgentStatus,
1083
+ toolCounts: ToolTallySnapshot,
1084
+ dispatchRows: ReadonlyArray<DispatchBoardRow>,
1085
+ tick: number,
1086
+ now: number,
1087
+ width: number,
1088
+ showBadge = true,
1089
+ fleetSummaryIsAction = false,
1090
+ ): string {
1091
+ const safeWidth = Math.max(1, Math.floor(width));
1092
+ const badge =
1093
+ showBadge && safeWidth >= 48 ? harnessBadge(theme, status, toolCounts, dispatchRows, fleetSummaryIsAction) : "";
1094
+ // Idleness is absence of work, not a phase worth narrating. If a tool or
1095
+ // fleet remains live while the harness settles, keep that activity without
1096
+ // prefixing it with an idle glyph.
1097
+ if (status.phase === "idle") return badge;
1098
+ const phase = harnessPhasePresentation(status, safeWidth, now);
1099
+ // A live phase leads with the animated spinner; the spinner stands in for the
1100
+ // static phase glyph rather than sitting beside it. Static glyphs render only
1101
+ // for the attention states and ended forms; idle returned quietly above.
1102
+ const lead = phase.live ? spinnerFrame(tick) : phase.glyph;
1103
+ const mainPill = theme.style(phase.token, `${lead} ${phase.label}`);
1104
+ return badge ? `${mainPill} ${theme.fg("dim", "·")} ${badge}` : mainPill;
1105
+ }
1106
+
1107
+ /**
1108
+ * Drop order for the metric strip. The chip budget and the width budget both cut
1109
+ * from the highest rank down, so one ordering decides what an 80-column footer
1110
+ * keeps.
1111
+ *
1112
+ * The session total sits alone at the top. It is measured, it does not depend on
1113
+ * pricing, and it does not go stale between turns, which is not true of anything
1114
+ * else on the strip. At 80 columns the budget is four chips and the per-turn
1115
+ * detail used to spend all of it, so a session holding 9.7k measured tokens
1116
+ * showed none of them.
1117
+ */
1118
+ const CHIP_RANK_SHUTDOWN = -2;
1119
+ const CHIP_RANK_LEADER = -1;
1120
+ const CHIP_RANK_TOTALS = 0;
1121
+ const CHIP_RANK_DETAIL = 1;
1122
+ const CHIP_RANK_DEFERRED = 2;
1123
+
1124
+ interface RankedChip {
1125
+ text: string;
1126
+ rank: number;
1127
+ }
1128
+
1129
+ function pushChip(chips: RankedChip[], text: string | null, rank: number): void {
1130
+ if (typeof text === "string" && text.length > 0) chips.push({ text, rank });
1131
+ }
1132
+
1133
+ /**
1134
+ * Cut the strip to the chip budget and then to the width, dropping the
1135
+ * lowest-priority chip still standing each time. Within one rank the rightmost
1136
+ * goes first, which keeps the surviving chips in the order they were built.
1137
+ */
1138
+ function selectChips(
1139
+ theme: ClioTheme,
1140
+ chips: ReadonlyArray<RankedChip>,
1141
+ chipLimit: number,
1142
+ maxWidth: number,
1143
+ ): string[] {
1144
+ const dropOrder = chips
1145
+ .map((chip, index) => ({ rank: chip.rank, index }))
1146
+ .sort((a, b) => b.rank - a.rank || b.index - a.index);
1147
+ const dropped = new Set<number>();
1148
+ const surviving = (): string[] => chips.filter((_, index) => !dropped.has(index)).map((chip) => chip.text);
1149
+ for (const { index } of dropOrder) {
1150
+ if (chips.length - dropped.size <= chipLimit && visibleWidth(joinChips(theme, surviving())) <= maxWidth) break;
1151
+ dropped.add(index);
1152
+ }
1153
+ return surviving();
1154
+ }
1155
+
1156
+ export function buildMetricStrip(
1157
+ theme: ClioTheme,
1158
+ status: AgentStatus,
1159
+ throughput: TokenThroughputSnapshot | null | undefined,
1160
+ lastTurn: TurnSummary | null | undefined,
1161
+ sessionTokens: UsageBreakdown | null | undefined,
1162
+ sessionCost: CostAggregate | null | undefined,
1163
+ liveInputTokens: number | null | undefined,
1164
+ maxWidth: number,
1165
+ maxChipsCount = 6,
1166
+ outputVerbosity?: OutputVerbosity | null,
1167
+ leaderArmed = false,
1168
+ shutdownArmed = false,
1169
+ ): string {
1170
+ const safeMaxWidth = Math.max(0, Math.floor(maxWidth));
1171
+ if (safeMaxWidth <= 0) return "";
1172
+ const isStreaming = status.phase !== "idle" && status.phase !== "ended";
1173
+ const meaningfulVerbosity = outputVerbosity && outputVerbosity !== "default" ? outputVerbosity : null;
1174
+ if (!isStreaming && !lastTurn && !meaningfulVerbosity && !leaderArmed && !shutdownArmed) return "";
1175
+
1176
+ const candidates: Array<string | null> = [];
1177
+ /** Per-turn detail that ranks below the session totals when the strip is cut. */
1178
+ const deferred: Array<string | null> = [];
1179
+ if (isStreaming) {
1180
+ const tps = finiteNonNegative(throughput?.tokensPerSecond);
1181
+ const rounded = tps > 0 ? (tps >= 10 ? Math.round(tps) : Math.round(tps * 10) / 10) : null;
1182
+ candidates.push(rounded !== null ? theme.fg("success", `${GLYPH.speed}${rounded}/s`) : null);
1183
+
1184
+ const liveOutput = finiteNonNegative(throughput?.outputTokens);
1185
+ candidates.push(liveOutput > 0 ? theme.fg("success", `${GLYPH.down}${formatFooterTokens(liveOutput)}`) : null);
1186
+
1187
+ const ttftMs = finiteNonNegative(throughput?.ttftMs);
1188
+ candidates.push(ttftMs > 0 ? theme.fg("muted", `ttft ${formatCompactMs(ttftMs)}`) : null);
1189
+
1190
+ const inputTokens =
1191
+ finiteNonNegative(liveInputTokens) ||
1192
+ finiteNonNegative(status.summary?.inputTokens) ||
1193
+ finiteNonNegative(lastTurn?.inputTokens) ||
1194
+ finiteNonNegative(sessionTokens?.input);
1195
+ candidates.push(inputTokens > 0 ? theme.fg("muted", `${GLYPH.up}${formatFooterTokens(inputTokens)}`) : null);
1196
+ } else if (lastTurn) {
1197
+ const stop = stopReasonStyle(lastTurn.stopReason);
1198
+ candidates.push(theme.fg(stop.token, `${stop.glyph} ${formatCompactMs(lastTurn.elapsedMs)}`));
1199
+ candidates.push(
1200
+ theme.fg(
1201
+ "muted",
1202
+ `${GLYPH.up}${formatFooterTokens(lastTurn.inputTokens)} ${GLYPH.down}${formatFooterTokens(lastTurn.outputTokens)}`,
1203
+ ),
1204
+ );
1205
+ candidates.push(
1206
+ lastTurn.reasoningTokens !== undefined && lastTurn.reasoningTokens > 0
1207
+ ? theme.fg(
1208
+ "reason",
1209
+ `r${lastTurn.reasoningTokenProvenance === "estimated" || lastTurn.reasoningTokenProvenance === "mixed" ? "≈" : ""}${formatFooterTokens(lastTurn.reasoningTokens)}`,
1210
+ )
1211
+ : null,
1212
+ );
1213
+ // Held back so the session totals below outrank them. The chip list is cut
1214
+ // to `maxChipsCount` before it is measured, and with cache and tools ahead
1215
+ // of the totals an 80-column terminal spent the whole budget on per-turn
1216
+ // detail: the cost field disappeared from the footer at the exact moment
1217
+ // it acquired a value, while `/cost` on the same session read `cost
1218
+ // unknown`. Two surfaces, two answers, because of a slice.
1219
+ deferred.push(
1220
+ lastTurn.cacheReadTokens > 0 || lastTurn.cacheWriteTokens > 0
1221
+ ? theme.fg(
1222
+ "dim",
1223
+ `cache ${formatFooterTokens(lastTurn.cacheReadTokens)}/${formatFooterTokens(lastTurn.cacheWriteTokens)}`,
1224
+ )
1225
+ : null,
1226
+ );
1227
+ if (lastTurn.toolCount > 0) {
1228
+ const label = `${lastTurn.toolCount} tool${lastTurn.toolCount === 1 ? "" : "s"}`;
1229
+ const errors = lastTurn.toolErrorCount > 0 ? theme.fg("error", ` ${lastTurn.toolErrorCount}${GLYPH.error}`) : "";
1230
+ deferred.push(`${theme.fg("muted", label)}${errors}`);
1231
+ } else {
1232
+ deferred.push(null);
1233
+ }
1234
+ }
1235
+ if (meaningfulVerbosity) deferred.push(theme.fg("muted", `out ${outputVerbosityLabel(meaningfulVerbosity)}`));
1236
+
1237
+ const fallbackTotal = finiteNonNegative(sessionTokens?.input) + finiteNonNegative(sessionTokens?.output);
1238
+ const cumulativeTotal = finiteNonNegative(sessionTokens?.totalTokens) || fallbackTotal;
1239
+ const totalChip = cumulativeTotal > 0 ? theme.fg("muted", `Σ${formatFooterTokens(cumulativeTotal)}`) : null;
1240
+ // Null when nothing priced these tokens, and an absent chip is the honest
1241
+ // rendering of that. `$0.00` on a session that had made no call was a number
1242
+ // nothing measured, and `cost unknown` beside a real Σ read as doubt about
1243
+ // the tokens. See formatCostAggregate.
1244
+ const cost = formatCostAggregate(sessionCost);
1245
+ const costChip = cost === null ? null : theme.fg("muted", cost);
1246
+
1247
+ const chipLimit = Math.max(0, Math.floor(maxChipsCount));
1248
+ const chips: RankedChip[] = [];
1249
+ // Ranked above every measurement: the strip is cut by dropping the
1250
+ // lowest-ranked chip, and these two are the answer to "did that key
1251
+ // register". The quit hint outranks the leader because its window is
1252
+ // 500ms wide and the leader's is open until the next keystroke.
1253
+ // Two rungs rather than one: the strip drops a chip it cannot fit whole, and
1254
+ // a terminal narrow enough to lose the sentence is exactly the one where the
1255
+ // operator most needs to be told the press registered.
1256
+ const shutdownHint = safeMaxWidth >= 20 ? "Ctrl+C again to quit" : "Ctrl+C again";
1257
+ pushChip(chips, shutdownArmed ? theme.fg("warning", shutdownHint) : null, CHIP_RANK_SHUTDOWN);
1258
+ pushChip(chips, leaderArmed ? theme.fg("accent", "leader armed") : null, CHIP_RANK_LEADER);
1259
+ for (const chip of candidates) pushChip(chips, chip, CHIP_RANK_DETAIL);
1260
+ pushChip(chips, totalChip, CHIP_RANK_TOTALS);
1261
+ pushChip(chips, costChip, CHIP_RANK_DETAIL);
1262
+ for (const chip of deferred) pushChip(chips, chip, CHIP_RANK_DEFERRED);
1263
+ return joinChips(theme, selectChips(theme, chips, chipLimit, safeMaxWidth));
1264
+ }