@iowarp/clio-coder 0.3.3 → 0.3.6

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 (370) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/CONTRIBUTING.md +7 -7
  3. package/README.md +3 -3
  4. package/dist/{acp-P2AQILE2.js → acp-2BEHC4DL.js} +9 -8
  5. package/dist/{agents-72W3BI7I.js → agents-LNNFTM53.js} +29 -24
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-5TWEIYDN.js → auth-KXXFI2VS.js} +14 -10
  8. package/dist/{chunk-GGXXDWE4.js → chunk-22NAGB7X.js} +2 -2
  9. package/dist/{chunk-YCWGATWI.js → chunk-24I7BN55.js} +2 -2
  10. package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
  11. package/dist/chunk-3BPUFZDL.js +37 -0
  12. package/dist/chunk-43AOLP7E.js +375 -0
  13. package/dist/{chunk-ZDOOVTXZ.js → chunk-4OC57DA6.js} +27 -4
  14. package/dist/{chunk-6SGHMWE3.js → chunk-5JGRAMKL.js} +5 -5
  15. package/dist/{chunk-V6RTAOC2.js → chunk-6US73PDB.js} +572 -51
  16. package/dist/{chunk-5UFT4SUX.js → chunk-6XXKFVSN.js} +3 -3
  17. package/dist/{chunk-A3CYT5EX.js → chunk-AD2SYQYC.js} +55 -2
  18. package/dist/chunk-AOCYTWAV.js +449 -0
  19. package/dist/chunk-CFGTUFWB.js +67 -0
  20. package/dist/chunk-CJUB2JJ2.js +1478 -0
  21. package/dist/{chunk-FNTMWMX5.js → chunk-CKXWIANG.js} +14 -12
  22. package/dist/{chunk-PIWWS5BL.js → chunk-CYQKWTG3.js} +63 -78
  23. package/dist/{chunk-LZSJBIVT.js → chunk-DJVECN66.js} +271 -762
  24. package/dist/{chunk-CBCAPZAA.js → chunk-E25LMLRW.js} +2 -2
  25. package/dist/{chunk-ZWMF7253.js → chunk-E2ER4LJF.js} +304 -9
  26. package/dist/{chunk-STBPMHSX.js → chunk-EKY57CSP.js} +51 -84
  27. package/dist/{chunk-DUYJ5IO6.js → chunk-EYPA3EGJ.js} +12 -4
  28. package/dist/{chunk-M6SHUN7Q.js → chunk-FO5ZOVUY.js} +2 -2
  29. package/dist/chunk-FYYLNIL5.js +313 -0
  30. package/dist/{chunk-OQ33BKR3.js → chunk-G7MUEIGA.js} +3 -60
  31. package/dist/chunk-GEYXPTRF.js +613 -0
  32. package/dist/chunk-GOXNB3AO.js +261 -0
  33. package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
  34. package/dist/chunk-HWUFFB6L.js +83 -0
  35. package/dist/{chunk-4XUGQOHA.js → chunk-K7T3E2SR.js} +15 -8
  36. package/dist/chunk-K7VKOLQQ.js +15 -0
  37. package/dist/{chunk-UFIIWP2H.js → chunk-KHSFENX2.js} +8 -8
  38. package/dist/{chunk-BMEMKKIT.js → chunk-KOHPCX4K.js} +2 -2
  39. package/dist/chunk-LCGCVYZ4.js +57 -0
  40. package/dist/chunk-LL4KHSZI.js +22 -0
  41. package/dist/{chunk-PAJK6MAQ.js → chunk-LYF7OHWH.js} +42 -15
  42. package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
  43. package/dist/{chunk-5UUP6MWO.js → chunk-MV3K5QF2.js} +5 -436
  44. package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
  45. package/dist/{chunk-TZK7PACC.js → chunk-NILBFAPG.js} +14 -8
  46. package/dist/chunk-ODFEOB4F.js +1082 -0
  47. package/dist/{chunk-AGYYIBLL.js → chunk-OH3TOQTB.js} +6 -2
  48. package/dist/chunk-OZNBF4L3.js +23 -0
  49. package/dist/{chunk-DSELYM6W.js → chunk-PBTHKCPN.js} +30 -10
  50. package/dist/{verify-375KUB3Y.js → chunk-PCZJO5TI.js} +127 -42
  51. package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
  52. package/dist/{chunk-SRDMMSEP.js → chunk-QM3F2GKX.js} +1063 -1645
  53. package/dist/{chunk-X6IAEBZR.js → chunk-QNQHSOLF.js} +7 -7
  54. package/dist/{chunk-OC7FIQPC.js → chunk-R46L2BIR.js} +10 -7
  55. package/dist/{chunk-2TLUCQVG.js → chunk-RD5U66HV.js} +3 -3
  56. package/dist/{chunk-6N5PTWMY.js → chunk-RY3LY4J5.js} +50 -13
  57. package/dist/{chunk-OKGUZO2U.js → chunk-SPULKLCF.js} +4 -3
  58. package/dist/{chunk-OOJYHWRB.js → chunk-TSHXZTOQ.js} +6 -5
  59. package/dist/chunk-TZSKNMZG.js +434 -0
  60. package/dist/{chunk-7MNJORFF.js → chunk-UL3WSD3F.js} +6 -1
  61. package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
  62. package/dist/{chunk-COU2UHX6.js → chunk-VEZEGCGW.js} +170 -2
  63. package/dist/chunk-W6GROXXM.js +69 -0
  64. package/dist/{chunk-OAO4GE4M.js → chunk-WHGPSPT5.js} +2 -2
  65. package/dist/chunk-WHJYKASB.js +677 -0
  66. package/dist/{chunk-ORBHGJC5.js → chunk-WR67VIZY.js} +3 -3
  67. package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
  68. package/dist/{chunk-TZTZS7QK.js → chunk-XE2VEJHX.js} +5 -3
  69. package/dist/{chunk-LM5TQCJZ.js → chunk-XF5N4U5A.js} +8 -7
  70. package/dist/{chunk-LWLEKMDQ.js → chunk-XXQNGV4M.js} +1073 -552
  71. package/dist/{chunk-KZWTDYJF.js → chunk-XYDYPRZI.js} +7 -7
  72. package/dist/chunk-ZGVHUX3M.js +66 -0
  73. package/dist/{chunk-LW6DSM3M.js → chunk-ZRGEBJ4T.js} +1192 -1119
  74. package/dist/{chunk-2DJ2KNFG.js → chunk-ZXF4XRKW.js} +202 -40
  75. package/dist/chunk-ZZMN5OM4.js +122 -0
  76. package/dist/cli/index.js +34 -30
  77. package/dist/{clio-JOU4FXVA.js → clio-M2KGYUFZ.js} +7 -6
  78. package/dist/{code-nav-7AX6FYE6.js → code-nav-GQNL7XA6.js} +8 -6
  79. package/dist/codewiki/build-worker.js +4 -4
  80. package/dist/{components-KELWS457.js → components-5TTYYX6G.js} +3 -3
  81. package/dist/{config-XCDVKR23.js → config-XUUYQIWO.js} +47 -35
  82. package/dist/{configure-4GAP54ZW.js → configure-IHJ7YOMV.js} +18 -15
  83. package/dist/{context-77FM5DV5.js → context-74JLXAWD.js} +18 -10
  84. package/dist/{context-4UOGGLQ5.js → context-75MIWW3U.js} +41 -29
  85. package/dist/{context-5VKGUVJJ.js → context-ZQ7SIFJV.js} +85 -9
  86. package/dist/{context-clear-XXJRLCJJ.js → context-clear-GYKWNUML.js} +41 -29
  87. package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
  88. package/dist/context-working-set-UX5KEP4J.js +1553 -0
  89. package/dist/{dispatch-runner-QPRDDBDX.js → dispatch-runner-GIJBHNFL.js} +47 -32
  90. package/dist/{docs-2C2LTVT2.js → docs-6FZSCG5B.js} +3 -3
  91. package/dist/{doctor-HR46URBJ.js → doctor-SVJ5BZCW.js} +12 -12
  92. package/dist/{eval-XSSNATB4.js → eval-CG6LLBLD.js} +54 -238
  93. package/dist/{evidence-6HG2PY2B.js → evidence-ZYFIEN42.js} +57 -28
  94. package/dist/{evolve-K7YU3NCY.js → evolve-QGEXEMDW.js} +36 -25
  95. package/dist/{extensions-QVDOHDGJ.js → extensions-ADGNCJJD.js} +3 -3
  96. package/dist/{fleet-VY3HHKN6.js → fleet-S5R4ZOQY.js} +73 -44
  97. package/dist/{fleet-preflight-DDN536IT.js → fleet-preflight-BHSNPBMH.js} +3 -3
  98. package/dist/{init-JYGXI3FK.js → init-5DRU55YR.js} +49 -37
  99. package/dist/memory-7YKKR6UC.js +467 -0
  100. package/dist/{models-I5QWSEOM.js → models-ZPOLRU2C.js} +24 -21
  101. package/dist/{monitor-GE4ID3IA.js → monitor-US5F5YGZ.js} +73 -46
  102. package/dist/{orchestrator-EM5MC3HM.js → orchestrator-E2AL4T5N.js} +1624 -1007
  103. package/dist/{paths-UXLN5YYZ.js → paths-E7KYAQWE.js} +3 -3
  104. package/dist/{reset-L2FQEE3E.js → reset-KZ652EK6.js} +6 -5
  105. package/dist/{run-ZU3QMZPZ.js → run-SRNBKDWD.js} +76 -54
  106. package/dist/{share-S5BZQC5I.js → share-CGZE33UP.js} +7 -6
  107. package/dist/{skills-X5VXCRNQ.js → skills-S2X4DLY5.js} +4 -4
  108. package/dist/{skills-eval-WKIHWTHR.js → skills-eval-W2GGIC4R.js} +40 -29
  109. package/dist/{targets-SNCPI2NR.js → targets-54SWINWB.js} +28 -23
  110. package/dist/{terminal-lease-BNAHVHBS.js → terminal-lease-SAIF2OGY.js} +6 -4
  111. package/dist/{uninstall-FZCQCDKC.js → uninstall-BVLWXKBT.js} +3 -3
  112. package/dist/{upgrade-JQHHPQ4K.js → upgrade-JKAR27XC.js} +20 -19
  113. package/dist/{usage-OR4O5SMZ.js → usage-MSAWCLX4.js} +79 -36
  114. package/dist/verifiers-NCBTHHN2.js +1220 -0
  115. package/dist/verify-X5HDROLA.js +25 -0
  116. package/dist/{wiki-generate-UEXP2ARI.js → wiki-generate-GUSOQ6ZP.js} +50 -37
  117. package/dist/worker/entry.js +90 -70
  118. package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
  119. package/docs/README.md +8 -7
  120. package/docs/acp.md +1 -1
  121. package/docs/alcf-provider.md +1 -1
  122. package/docs/architecture.md +2 -2
  123. package/docs/artifact-placement.md +1 -2
  124. package/docs/artifact-versions.md +1 -1
  125. package/docs/built-in-agents.md +1 -1
  126. package/docs/capacity-and-scheduling.md +1 -1
  127. package/docs/commands-and-modes.md +60 -26
  128. package/docs/config-knobs-audit.md +1 -2
  129. package/docs/configuration-and-targets.md +26 -1
  130. package/docs/context-engine.md +67 -13
  131. package/docs/context-working-set.md +194 -0
  132. package/docs/development-pipeline.md +1 -1
  133. package/docs/documentation-coverage.md +6 -6
  134. package/docs/documentation-guide.md +7 -6
  135. package/docs/environment-variables.md +2 -1
  136. package/docs/eval-runner.md +1 -1
  137. package/docs/evals-internal.md +4 -32
  138. package/docs/evidence-and-memory.md +139 -7
  139. package/docs/evolution.md +1 -1
  140. package/docs/exit-codes-and-output.md +1 -1
  141. package/docs/extensions-and-sharing.md +2 -2
  142. package/docs/fleet-dispatch.md +49 -8
  143. package/docs/glossary.md +21 -1
  144. package/docs/installation-and-lifecycle.md +2 -2
  145. package/docs/middleware-and-components.md +19 -2
  146. package/docs/model-catalog.md +7 -9
  147. package/docs/observability.md +4 -4
  148. package/docs/proactive-memory.md +26 -16
  149. package/docs/prompt-envelope-and-tools.md +7 -5
  150. package/docs/provider-adapter-cookbook.md +1 -1
  151. package/docs/release-cut-checklist.md +43 -40
  152. package/docs/safety-model.md +49 -8
  153. package/docs/scientific-validation.md +21 -3
  154. package/docs/session-lifecycle.md +3 -3
  155. package/docs/skills-marketplace.md +1 -1
  156. package/docs/tool-usage.md +79 -12
  157. package/docs/trace-store.md +1 -1
  158. package/docs/troubleshooting.md +1 -1
  159. package/docs/tui-design.md +38 -4
  160. package/docs/worker-dispatch-mechanics.md +11 -1
  161. package/package.json +13 -13
  162. package/skills/meta/clio-test/SKILL.md +20 -17
  163. package/skills/meta/clio-test/evals.md +3 -3
  164. package/skills/meta/clio-test/references/harness.md +35 -6
  165. package/skills/meta/clio-test/references/test-map.md +20 -10
  166. package/skills/registry.yaml +2 -2
  167. package/skills/skill-marketplace.json +1 -1
  168. package/src/cli/agents.ts +2 -3
  169. package/src/cli/argv.ts +14 -1
  170. package/src/cli/context-working-set.ts +513 -0
  171. package/src/cli/context.ts +8 -0
  172. package/src/cli/evidence.ts +20 -2
  173. package/src/cli/fleet.ts +15 -0
  174. package/src/cli/index.ts +5 -1
  175. package/src/cli/memory.ts +272 -10
  176. package/src/cli/modes/json-stream.ts +2 -2
  177. package/src/cli/modes/print.ts +12 -1
  178. package/src/cli/run.ts +22 -2
  179. package/src/cli/targets.ts +12 -3
  180. package/src/cli/usage.ts +55 -7
  181. package/src/cli/verifiers.ts +325 -0
  182. package/src/core/bash-exec.ts +39 -14
  183. package/src/core/bus-events.ts +22 -4
  184. package/src/core/config.ts +54 -0
  185. package/src/core/defaults.ts +50 -3
  186. package/src/core/response-model-id.ts +134 -0
  187. package/src/core/toml.ts +62 -0
  188. package/src/core/verification-scripts.ts +6 -0
  189. package/src/core/workspace-files.ts +0 -1
  190. package/src/domains/agents/builtins/architect.md +1 -1
  191. package/src/domains/agents/builtins/verifier.md +3 -0
  192. package/src/domains/agents/catalog.ts +5 -4
  193. package/src/domains/agents/recipe.ts +54 -14
  194. package/src/domains/agents/result-contract.ts +7 -4
  195. package/src/domains/config/classify.ts +1 -0
  196. package/src/domains/context/bootstrap.ts +36 -27
  197. package/src/domains/context/project-metadata.ts +19 -63
  198. package/src/domains/context/prompt-context.ts +8 -0
  199. package/src/domains/context/working-set/contract.ts +161 -0
  200. package/src/domains/context/working-set/defaults.ts +28 -0
  201. package/src/domains/context/working-set/engine.ts +203 -0
  202. package/src/domains/context/working-set/fold.ts +62 -0
  203. package/src/domains/context/working-set/horizon.ts +38 -0
  204. package/src/domains/context/working-set/marker.ts +103 -0
  205. package/src/domains/context/working-set/path-index.ts +436 -0
  206. package/src/domains/context/working-set/payload.ts +152 -0
  207. package/src/domains/context/working-set/policies/age-horizon.ts +55 -0
  208. package/src/domains/context/working-set/policies/index.ts +20 -0
  209. package/src/domains/context/working-set/policies/structural.ts +160 -0
  210. package/src/domains/context/working-set/project.ts +132 -0
  211. package/src/domains/context/working-set/protect.ts +109 -0
  212. package/src/domains/context/working-set/recall.ts +177 -0
  213. package/src/domains/context/working-set/replay/controls.ts +112 -0
  214. package/src/domains/context/working-set/replay/load-clio.ts +199 -0
  215. package/src/domains/context/working-set/replay/metrics.ts +185 -0
  216. package/src/domains/context/working-set/replay/reference-graph.ts +79 -0
  217. package/src/domains/context/working-set/replay/report.ts +139 -0
  218. package/src/domains/context/working-set/replay/runner.ts +325 -0
  219. package/src/domains/context/working-set/replay/synthetic.ts +422 -0
  220. package/src/domains/context/working-set/replay/trace.ts +21 -0
  221. package/src/domains/context/working-set/visible.ts +54 -0
  222. package/src/domains/dispatch/budget-envelope.ts +396 -0
  223. package/src/domains/dispatch/contract.ts +2 -0
  224. package/src/domains/dispatch/extension.ts +81 -27
  225. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  226. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  227. package/src/domains/dispatch/state.ts +1 -0
  228. package/src/domains/dispatch/types.ts +10 -3
  229. package/src/domains/dispatch/validation.ts +14 -0
  230. package/src/domains/dispatch/worker-spawn.ts +14 -3
  231. package/src/domains/eval/metrics/evidence.ts +0 -116
  232. package/src/domains/eval/metrics/invariants.ts +1 -1
  233. package/src/domains/eval/runners/clio-run.ts +1 -10
  234. package/src/domains/eval/runners/external-command.ts +2 -29
  235. package/src/domains/eval/schema/suite.ts +0 -7
  236. package/src/domains/eval/suites/run.ts +1 -7
  237. package/src/domains/evidence/build.ts +112 -45
  238. package/src/domains/evidence/eval.ts +24 -7
  239. package/src/domains/evidence/index.ts +53 -0
  240. package/src/domains/evidence/ordering.ts +12 -0
  241. package/src/domains/evidence/run-trust.ts +221 -0
  242. package/src/domains/evidence/store.ts +46 -6
  243. package/src/domains/evidence/trust-status.ts +854 -0
  244. package/src/domains/evidence/types.ts +26 -0
  245. package/src/domains/memory/index.ts +22 -0
  246. package/src/domains/memory/operations.ts +58 -1
  247. package/src/domains/memory/promotion.ts +281 -0
  248. package/src/domains/memory/prompt-section.ts +25 -5
  249. package/src/domains/memory/proposal.ts +51 -7
  250. package/src/domains/memory/task-bank.ts +3 -2
  251. package/src/domains/memory/task-memory-handoff.ts +181 -24
  252. package/src/domains/memory/task-memory-policy.ts +3 -1
  253. package/src/domains/memory/types.ts +37 -0
  254. package/src/domains/memory/validate.ts +178 -0
  255. package/src/domains/middleware/memory-intervention.ts +38 -25
  256. package/src/domains/middleware/runtime.ts +6 -0
  257. package/src/domains/middleware/skills-reminder.ts +19 -4
  258. package/src/domains/middleware/stalled-turn.ts +208 -5
  259. package/src/domains/middleware/types.ts +10 -0
  260. package/src/domains/observability/contract.ts +6 -1
  261. package/src/domains/observability/cost.ts +20 -4
  262. package/src/domains/observability/extension.ts +2 -2
  263. package/src/domains/providers/index.ts +3 -0
  264. package/src/domains/providers/model-discovery.ts +9 -0
  265. package/src/domains/providers/runtime-resolution.ts +38 -1
  266. package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
  267. package/src/domains/providers/types/context-window-slots.ts +18 -0
  268. package/src/domains/providers/types/runtime-descriptor.ts +3 -1
  269. package/src/domains/safety/autonomy.ts +1 -1
  270. package/src/domains/safety/call-target.ts +211 -14
  271. package/src/domains/safety/decision-presentation.ts +268 -0
  272. package/src/domains/safety/default-path-policy.ts +8 -0
  273. package/src/domains/safety/finish-contract.ts +4 -3
  274. package/src/domains/safety/policy-engine.ts +48 -6
  275. package/src/domains/safety/redaction.ts +73 -0
  276. package/src/domains/session/compaction/compact.ts +23 -1
  277. package/src/domains/session/compaction/cut-point.ts +2 -0
  278. package/src/domains/session/compaction/tokens.ts +16 -1
  279. package/src/domains/session/context-ledger.ts +12 -1
  280. package/src/domains/session/decision-board.ts +4 -0
  281. package/src/domains/session/entries.ts +110 -1
  282. package/src/domains/session/history.ts +68 -19
  283. package/src/domains/session/manager.ts +9 -2
  284. package/src/domains/session/migrations/index.ts +22 -3
  285. package/src/domains/session/usage.ts +24 -7
  286. package/src/engine/acp/event-mapper.ts +7 -0
  287. package/src/engine/acp/server.ts +32 -2
  288. package/src/engine/agent.ts +18 -1
  289. package/src/engine/apis/lmstudio.ts +25 -4
  290. package/src/engine/apis/openai-completions.ts +147 -22
  291. package/src/engine/claude/sdk-runtime.ts +8 -2
  292. package/src/engine/claude/tool-safety.ts +13 -0
  293. package/src/engine/loop-guard.ts +27 -3
  294. package/src/engine/session.ts +9 -3
  295. package/src/engine/worker-events.ts +4 -3
  296. package/src/engine/worker-runtime.ts +59 -54
  297. package/src/entry/orchestrator.ts +34 -5
  298. package/src/interactive/chat-loop-messages.ts +40 -6
  299. package/src/interactive/chat-loop.ts +13 -0
  300. package/src/interactive/chat-panel.ts +17 -1
  301. package/src/interactive/chat-renderer.ts +49 -24
  302. package/src/interactive/clio-editor.ts +44 -7
  303. package/src/interactive/context-meter.ts +10 -0
  304. package/src/interactive/context-overlay.ts +120 -7
  305. package/src/interactive/context-recall-command.ts +110 -0
  306. package/src/interactive/cost-overlay.ts +39 -8
  307. package/src/interactive/dispatch-board.ts +212 -35
  308. package/src/interactive/footer/widgets.ts +13 -0
  309. package/src/interactive/interactive-application.ts +6 -1
  310. package/src/interactive/interactive-input-runtime.ts +11 -1
  311. package/src/interactive/interactive-presentation.ts +11 -1
  312. package/src/interactive/interactive-slash-runtime.ts +37 -1
  313. package/src/interactive/memory-overlay.ts +89 -4
  314. package/src/interactive/model-session-replay.ts +21 -0
  315. package/src/interactive/overlay-ask-user-lifecycle.ts +1 -1
  316. package/src/interactive/overlay-frame.ts +5 -2
  317. package/src/interactive/overlay-general-openers.ts +46 -1
  318. package/src/interactive/overlay-key-routing.ts +41 -1
  319. package/src/interactive/overlay-lifecycle.ts +11 -4
  320. package/src/interactive/overlay-permission-lifecycle.ts +23 -8
  321. package/src/interactive/overlay-session-lifecycle.ts +8 -4
  322. package/src/interactive/overlay-transitions.ts +11 -0
  323. package/src/interactive/overlays/ask-user.ts +74 -30
  324. package/src/interactive/overlays/decisions.ts +3 -1
  325. package/src/interactive/permission-hint.ts +35 -0
  326. package/src/interactive/permission-overlay.ts +95 -45
  327. package/src/interactive/renderers/tool-execution.ts +37 -51
  328. package/src/interactive/session-last-turn.ts +8 -1
  329. package/src/interactive/session-transcript.ts +2 -2
  330. package/src/interactive/session-usage-reseed.ts +36 -10
  331. package/src/interactive/slash-commands.ts +31 -4
  332. package/src/interactive/status/summary.ts +5 -0
  333. package/src/interactive/status/types.ts +5 -0
  334. package/src/interactive/terminal-lease.ts +1 -0
  335. package/src/interactive/turn-context.ts +333 -110
  336. package/src/interactive/turn-middleware.ts +7 -6
  337. package/src/interactive/turn-runtime.ts +37 -8
  338. package/src/interactive/turn-state.ts +3 -0
  339. package/src/interactive/worker-progress.ts +440 -0
  340. package/src/interactive/worker-stream.ts +51 -110
  341. package/src/tools/agent-tools.ts +39 -7
  342. package/src/tools/ask-user.ts +21 -1
  343. package/src/tools/bash.ts +144 -82
  344. package/src/tools/builtin-tool-catalog.ts +11 -5
  345. package/src/tools/context/index.ts +107 -5
  346. package/src/tools/context/surface.ts +3 -2
  347. package/src/tools/core-bootstrap.ts +21 -0
  348. package/src/tools/dispatch-arguments.ts +8 -0
  349. package/src/tools/dispatch-event-text.ts +19 -0
  350. package/src/tools/dispatch-runner.ts +9 -7
  351. package/src/tools/dispatch.ts +24 -1
  352. package/src/tools/monitor.ts +43 -20
  353. package/src/tools/registry.ts +72 -10
  354. package/src/tools/result-disposition.ts +706 -0
  355. package/src/tools/result-shaping.ts +321 -20
  356. package/src/tools/safe-exec.ts +2 -0
  357. package/src/tools/verify/authoring.ts +1120 -0
  358. package/src/tools/verify/catalog.ts +346 -0
  359. package/src/tools/verify/index.ts +13 -3
  360. package/src/tools/verify/scripts.ts +135 -37
  361. package/src/tools/verify/surface.ts +9 -5
  362. package/src/tools/worker-evidence.ts +54 -12
  363. package/src/worker/spec-contract.ts +43 -3
  364. package/dist/chunk-J7CWMCQD.js +0 -255
  365. package/dist/chunk-T6YILFSB.js +0 -80
  366. package/dist/chunk-VAKQQHWR.js +0 -434
  367. package/dist/chunk-VPAYEGVX.js +0 -184
  368. package/dist/chunk-XBXAASKX.js +0 -18
  369. package/dist/memory-WFZMGYHX.js +0 -236
  370. package/src/domains/eval/metrics/chaos-stream.ts +0 -93
@@ -1,8 +1,19 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
1
+ import { createHash } from "node:crypto";
2
+ import { mkdirSync, readdirSync, rmdirSync, rmSync, statSync, writeFileSync } from "node:fs";
2
3
  import { isAbsolute, join, relative, resolve } from "node:path";
3
4
  import { clioStateDir } from "../core/xdg.js";
4
5
  import type { ToolInvokeOptions, ToolResult, ToolResultDetails, ToolSpec } from "./registry.js";
5
- import { DEFAULT_MAX_BYTES } from "./truncate.js";
6
+ import {
7
+ deterministicToolResultDigest,
8
+ legacyToolResultDigest,
9
+ normalizeToolResultDisposition,
10
+ projectToolResultContext,
11
+ type ToolResultDigest,
12
+ type ToolResultDisposition,
13
+ type ToolResultDispositionFallback,
14
+ type ToolResultDispositionMetadata,
15
+ } from "./result-disposition.js";
16
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateTail } from "./truncate.js";
6
17
  import { byteLength, truncateUtf8 } from "./truncate-utf8.js";
7
18
 
8
19
  // Backstop for tools without an explicit resultSizePolicy. Sits above the
@@ -12,6 +23,8 @@ import { byteLength, truncateUtf8 } from "./truncate-utf8.js";
12
23
  export const DEFAULT_TOOL_RESULT_MAX_BYTES = DEFAULT_MAX_BYTES + 2 * 1024;
13
24
  const RESULT_TRUNCATION_MARKER = "\n[tool result truncated]";
14
25
  const RESULT_OFFLOAD_MAX_BYTES = 10 * 1024 * 1024;
26
+ const TAIL_NOTICE_RESERVE_BYTES = 512;
27
+ export const TOOL_OFFLOAD_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1000;
15
28
 
16
29
  type ToolResultShapeContext = Pick<ToolInvokeOptions, "sessionId" | "toolCallId">;
17
30
 
@@ -33,6 +46,41 @@ function followUpHint(spec: ToolSpec): string {
33
46
  );
34
47
  }
35
48
 
49
+ function offloadMaxBytesFor(spec: ToolSpec): number {
50
+ const configured = spec.metadata?.resultSizePolicy?.offloadMaxBytes;
51
+ return typeof configured === "number" && Number.isFinite(configured) && configured > 0
52
+ ? Math.floor(configured)
53
+ : RESULT_OFFLOAD_MAX_BYTES;
54
+ }
55
+
56
+ /**
57
+ * Build the task-memory diagnostic from the same normalized disposition that
58
+ * will shape model context. Legacy tools use the explicit compatibility path.
59
+ */
60
+ export function toolResultDigestFor(
61
+ spec: ToolSpec,
62
+ result: ToolResult,
63
+ requestedDisposition?: ToolResultDisposition,
64
+ ): ToolResultDigest {
65
+ const text = resultText(result);
66
+ const disposition = normalizeToolResultDisposition(spec, maxBytesFor(spec), requestedDisposition);
67
+ if (disposition === null) {
68
+ const projected = shapeLegacyToolResult(spec, result);
69
+ return legacyToolResultDigest(resultText(projected), { outcome: result.kind });
70
+ }
71
+ const capturedBytes = capturedBytesFor(result, text);
72
+ return deterministicToolResultDigest({
73
+ text,
74
+ kind: result.kind,
75
+ details: result.details,
76
+ disposition,
77
+ capturedBytes,
78
+ displayedBytes: Math.min(capturedBytes, disposition.presentation.maxBytes),
79
+ offloadPath: existingOffloadPath(result.details),
80
+ followUpHint: followUpHint(spec),
81
+ });
82
+ }
83
+
36
84
  function detailsRecord(details: ToolResultDetails | undefined, key: string): Record<string, unknown> | null {
37
85
  const candidate = details?.[key];
38
86
  return candidate !== null && typeof candidate === "object" && !Array.isArray(candidate)
@@ -41,10 +89,10 @@ function detailsRecord(details: ToolResultDetails | undefined, key: string): Rec
41
89
  }
42
90
 
43
91
  /**
44
- * A result that already spilled its full text to scratch (bash's tail-biased
45
- * shaping via `resultSize.offloadPath`, or an OBSERVE tool's envelope via
46
- * `observation.offloadPath`) is left alone; the tool shaped it deliberately
47
- * and the backstop would only cut the tool's own continuation notice.
92
+ * A result that already spilled its full text to scratch (the canonical
93
+ * tail-biased presentation path via `resultSize.offloadPath`, or an OBSERVE
94
+ * tool's envelope via `observation.offloadPath`) is left alone; a second pass
95
+ * would only cut the deliberate continuation notice.
48
96
  */
49
97
  function existingOffloadPath(details: ToolResultDetails | undefined): string | null {
50
98
  const fromResultSize = detailsRecord(details, "resultSize")?.offloadPath;
@@ -53,6 +101,13 @@ function existingOffloadPath(details: ToolResultDetails | undefined): string | n
53
101
  return typeof fromObservation === "string" && fromObservation.length > 0 ? fromObservation : null;
54
102
  }
55
103
 
104
+ function existingDisposition(details: ToolResultDetails | undefined): ToolResultDispositionMetadata | null {
105
+ const disposition = detailsRecord(details, "resultDisposition");
106
+ return disposition?.version === 1 && disposition.applications === 1
107
+ ? (disposition as unknown as ToolResultDispositionMetadata)
108
+ : null;
109
+ }
110
+
56
111
  function safePathSegment(value: string): string {
57
112
  const safe = value
58
113
  .trim()
@@ -61,10 +116,6 @@ function safePathSegment(value: string): string {
61
116
  return safe.length > 0 ? safe : "unnamed";
62
117
  }
63
118
 
64
- function timestampSegment(): string {
65
- return new Date().toISOString().replace(/[^A-Za-z0-9._-]/g, "_");
66
- }
67
-
68
119
  function offloadBody(text: string, bytes: number, maxBytes: number): string {
69
120
  if (bytes <= maxBytes) return text;
70
121
  const notice = `\n[clio-coder scratch output truncated at ${maxBytes} bytes; original size ${bytes} bytes]`;
@@ -72,24 +123,56 @@ function offloadBody(text: string, bytes: number, maxBytes: number): string {
72
123
  return `${truncateUtf8(text, Math.max(0, prefixBudget), "")}${notice}`;
73
124
  }
74
125
 
126
+ /** Remove regular offload files older than the boot retention cap. */
127
+ export function sweepExpiredToolOffloads(now = Date.now()): number {
128
+ const root = join(clioStateDir(), "scratch");
129
+ const cutoff = now - TOOL_OFFLOAD_MAX_AGE_MS;
130
+ let removed = 0;
131
+ try {
132
+ for (const session of readdirSync(root, { withFileTypes: true })) {
133
+ if (!session.isDirectory()) continue;
134
+ const sessionDir = join(root, session.name);
135
+ for (const entry of readdirSync(sessionDir, { withFileTypes: true })) {
136
+ if (!entry.isFile()) continue;
137
+ const path = join(sessionDir, entry.name);
138
+ try {
139
+ if (statSync(path).mtimeMs >= cutoff) continue;
140
+ rmSync(path, { force: true });
141
+ removed += 1;
142
+ } catch {}
143
+ }
144
+ try {
145
+ if (readdirSync(sessionDir).length === 0) rmdirSync(sessionDir);
146
+ } catch {}
147
+ }
148
+ } catch {}
149
+ return removed;
150
+ }
151
+
75
152
  /**
76
153
  * Persist the full text of a tool result to a per-session scratch file and
77
- * return its path (or null if the write fails). Callers that truncate their own
78
- * display output (for example bash's tail-biased shaping) use this to spill the
79
- * complete output before truncating, then set `details.resultSize.offloadPath`
80
- * so the registry re-truncation pass leaves the already-shaped result alone.
154
+ * return its path (or null if the write fails). Self-shaping callers use this
155
+ * to spill complete output before truncating and set
156
+ * `details.resultSize.offloadPath`; canonical disposition shaping also uses it
157
+ * once when presentation or model context omits captured content.
158
+ *
159
+ * The file is named by the sha256 of the captured text, so the path is a pure
160
+ * function of the bytes: identical captures share one file and the
161
+ * `retrieve=` header, the eviction marker, and the resume transcript carry the
162
+ * same bytes every time, which is what keeps the prompt-cache prefix stable
163
+ * across runs. Pass `digest` when the caller already hashed the text.
81
164
  */
82
165
  export function writeToolOffload(
83
166
  text: string,
84
167
  context: ToolResultShapeContext | undefined,
85
168
  maxBytes: number = RESULT_OFFLOAD_MAX_BYTES,
169
+ digest: string = createHash("sha256").update(text).digest("hex"),
86
170
  ): string | null {
87
171
  try {
88
172
  const bytes = byteLength(text);
89
173
  const sessionId = safePathSegment(context?.sessionId ?? "no-session");
90
- const callId = safePathSegment(context?.toolCallId ?? timestampSegment());
91
174
  const dir = join(clioStateDir(), "scratch", sessionId);
92
- const path = join(dir, `${callId}.txt`);
175
+ const path = join(dir, `${digest}.txt`);
93
176
  mkdirSync(dir, { recursive: true });
94
177
  writeFileSync(path, offloadBody(text, bytes, maxBytes), "utf8");
95
178
  return path;
@@ -145,9 +228,10 @@ function shapeJsonOverflow(
145
228
  bytes: number,
146
229
  maxBytes: number,
147
230
  context: ToolResultShapeContext | undefined,
231
+ offloadMaxBytes: number,
148
232
  ): ToolResult {
149
233
  const observation = detailsRecord(result.details, "observation");
150
- const offloadPath = writeToolOffload(text, context);
234
+ const offloadPath = writeToolOffload(text, context, offloadMaxBytes);
151
235
  const next =
152
236
  typeof observation?.next === "string" && observation.next.length > 0 ? observation.next : followUpHint(spec);
153
237
  const stub = JSON.stringify({
@@ -170,16 +254,64 @@ function shapeJsonOverflow(
170
254
  return { ...result, message: stub, details: mergeDetails(result.details, resultSize) };
171
255
  }
172
256
 
173
- export function shapeToolResult(spec: ToolSpec, result: ToolResult, context?: ToolResultShapeContext): ToolResult {
257
+ function shapeTailOverflow(
258
+ spec: ToolSpec,
259
+ result: ToolResult,
260
+ text: string,
261
+ bytes: number,
262
+ maxBytes: number,
263
+ context: ToolResultShapeContext | undefined,
264
+ offloadMaxBytes: number,
265
+ ): ToolResult {
266
+ const truncation = truncateTail(text, {
267
+ maxLines: DEFAULT_MAX_LINES,
268
+ maxBytes: Math.max(1, maxBytes - TAIL_NOTICE_RESERVE_BYTES),
269
+ });
270
+ const offloadPath = writeToolOffload(text, context, offloadMaxBytes);
271
+ const startLine = truncation.totalLines - truncation.outputLines + 1;
272
+ const scope = truncation.lastLinePartial
273
+ ? `last ${formatSize(truncation.outputBytes)} of line ${truncation.totalLines} (line is large)`
274
+ : `lines ${startLine}-${truncation.totalLines} of ${truncation.totalLines}`;
275
+ const location =
276
+ offloadPath === null
277
+ ? ""
278
+ : ` Full output saved to ${offloadPath}; ${OFFLOAD_POINTER_NOTE}; read it with offset/limit.`;
279
+ const note = `[Output tail-truncated: showing ${scope} (${formatSize(maxBytes)} display limit).${location}]`;
280
+ const resultSize = {
281
+ bytes,
282
+ shownBytes: truncation.outputBytes,
283
+ maxBytes,
284
+ truncated: true,
285
+ policy: "tail",
286
+ followUpHint: followUpHint(spec),
287
+ ...(offloadPath === null ? {} : { offloadPath }),
288
+ };
289
+ const displayed = `${truncation.content}\n\n${note}`;
290
+ if (result.kind === "ok") return { ...result, output: displayed, details: mergeDetails(result.details, resultSize) };
291
+ return { ...result, message: displayed, details: mergeDetails(result.details, resultSize) };
292
+ }
293
+
294
+ function shapeLegacyToolResult(
295
+ spec: ToolSpec,
296
+ result: ToolResult,
297
+ context?: ToolResultShapeContext,
298
+ overflow: "head" | "tail" = "head",
299
+ ): ToolResult {
174
300
  if (existingOffloadPath(result.details) !== null) return result;
175
301
  const maxBytes = maxBytesFor(spec);
302
+ const offloadMaxBytes = offloadMaxBytesFor(spec);
176
303
  const text = result.kind === "ok" ? result.output : result.message;
177
304
  const bytes = byteLength(text);
178
305
  if (bytes <= maxBytes) return result;
179
306
  const observation = detailsRecord(result.details, "observation");
180
- if (observation?.format === "json") return shapeJsonOverflow(spec, result, text, bytes, maxBytes, context);
307
+ if (observation?.format === "json") {
308
+ return shapeJsonOverflow(spec, result, text, bytes, maxBytes, context, offloadMaxBytes);
309
+ }
310
+ if (overflow === "tail") {
311
+ return shapeTailOverflow(spec, result, text, bytes, maxBytes, context, offloadMaxBytes);
312
+ }
181
313
  const truncated = truncateUtf8(text, maxBytes, RESULT_TRUNCATION_MARKER);
182
- const offloadPath = writeToolOffload(text, context);
314
+ const offloadPath = writeToolOffload(text, context, offloadMaxBytes);
183
315
  const resultSize = {
184
316
  bytes,
185
317
  shownBytes: byteLength(truncated),
@@ -202,3 +334,172 @@ export function shapeToolResult(spec: ToolSpec, result: ToolResult, context?: To
202
334
  details: mergeDetails(result.details, resultSize),
203
335
  };
204
336
  }
337
+
338
+ function specWithDisplayCap(spec: ToolSpec, maxBytes: number): ToolSpec {
339
+ const metadata = spec.metadata;
340
+ if (metadata === undefined) return spec;
341
+ return {
342
+ ...spec,
343
+ metadata: {
344
+ ...metadata,
345
+ resultSizePolicy: { ...metadata.resultSizePolicy, maxBytes },
346
+ },
347
+ };
348
+ }
349
+
350
+ function resultText(result: ToolResult): string {
351
+ return result.kind === "ok" ? result.output : result.message;
352
+ }
353
+
354
+ /**
355
+ * The operator-facing trace of a disposition that was narrowed rather than
356
+ * requested. Without it a throwing resolver degrades every call of that tool
357
+ * to metadata-only with nothing on the transcript row to say so.
358
+ */
359
+ function withFallbackNotice(result: ToolResult, fallback: ToolResultDispositionFallback): ToolResult {
360
+ const note = `\n\n[result disposition fell back to metadata-only: ${fallback.reason} (${fallback.message}); the model received facts and retrieval only]`;
361
+ return result.kind === "ok"
362
+ ? { ...result, output: `${result.output}${note}` }
363
+ : { ...result, message: `${result.message}${note}` };
364
+ }
365
+
366
+ function numberField(record: Record<string, unknown> | null, key: string): number | null {
367
+ const value = record?.[key];
368
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
369
+ }
370
+
371
+ function capturedBytesFor(result: ToolResult, text: string): number {
372
+ const declared = numberField(detailsRecord(result.details, "resultSize"), "bytes");
373
+ return Math.max(byteLength(text), declared ?? 0);
374
+ }
375
+
376
+ function resultWasTruncated(result: ToolResult): boolean {
377
+ return detailsRecord(result.details, "resultSize")?.truncated === true;
378
+ }
379
+
380
+ function withOffloadMetadata(
381
+ result: ToolResult,
382
+ offloadPath: string,
383
+ capturedBytes: number,
384
+ displayedBytes: number,
385
+ maxBytes: number,
386
+ hint: string,
387
+ ): ToolResult {
388
+ const current = detailsRecord(result.details, "resultSize") ?? {};
389
+ const resultSize = {
390
+ bytes: numberField(current, "bytes") ?? capturedBytes,
391
+ shownBytes: numberField(current, "shownBytes") ?? displayedBytes,
392
+ maxBytes: numberField(current, "maxBytes") ?? maxBytes,
393
+ truncated: current.truncated === true,
394
+ policy: typeof current.policy === "string" ? current.policy : "disposition",
395
+ followUpHint: typeof current.followUpHint === "string" ? current.followUpHint : hint,
396
+ ...current,
397
+ offloadPath,
398
+ };
399
+ return { ...result, details: mergeDetails(result.details, resultSize) };
400
+ }
401
+
402
+ /**
403
+ * Apply legacy shaping or one declared canonical disposition. Registry calls
404
+ * this once, after middleware annotations have produced the terminal result.
405
+ */
406
+ export function shapeToolResult(
407
+ spec: ToolSpec,
408
+ result: ToolResult,
409
+ context?: ToolResultShapeContext,
410
+ requestedDisposition?: ToolResultDisposition,
411
+ ): ToolResult {
412
+ if (existingDisposition(result.details) !== null) return result;
413
+ const hardMaxBytes = maxBytesFor(spec);
414
+ const disposition = normalizeToolResultDisposition(spec, hardMaxBytes, requestedDisposition);
415
+ if (disposition === null) return shapeLegacyToolResult(spec, result, context);
416
+
417
+ const capturedText = resultText(result);
418
+ const capturedBytes = capturedBytesFor(result, capturedText);
419
+ let displayed = shapeLegacyToolResult(
420
+ specWithDisplayCap(spec, disposition.presentation.maxBytes),
421
+ result,
422
+ context,
423
+ disposition.presentation.overflow,
424
+ );
425
+ if (disposition.fallback !== undefined) displayed = withFallbackNotice(displayed, disposition.fallback);
426
+ let displayedText = resultText(displayed);
427
+ let displayedBytes = byteLength(displayedText);
428
+ let offloadPath = existingOffloadPath(displayed.details);
429
+ const projectionInput = {
430
+ text: capturedText,
431
+ kind: result.kind,
432
+ details: displayed.details,
433
+ disposition,
434
+ capturedBytes,
435
+ displayedBytes,
436
+ offloadPath,
437
+ followUpHint: followUpHint(spec),
438
+ };
439
+ // Project first, then decide on retrieval. A projection that already carries
440
+ // every captured byte (a short `summary`, a `full` inside budget) needs no
441
+ // scratch artifact and must not claim truncation; anything that genuinely
442
+ // omits content earns one offload and the honest omission facts with it.
443
+ let projection = projectToolResultContext(projectionInput);
444
+ if (offloadPath === null && projection.truncated) {
445
+ offloadPath = writeToolOffload(
446
+ capturedText,
447
+ context,
448
+ offloadMaxBytesFor(spec),
449
+ projection.summaryProvenance?.sourceSha256,
450
+ );
451
+ if (offloadPath !== null) {
452
+ displayed = withOffloadMetadata(
453
+ displayed,
454
+ offloadPath,
455
+ capturedBytes,
456
+ displayedBytes,
457
+ disposition.presentation.maxBytes,
458
+ followUpHint(spec),
459
+ );
460
+ displayedText = resultText(displayed);
461
+ displayedBytes = byteLength(displayedText);
462
+ projection = projectToolResultContext({
463
+ ...projectionInput,
464
+ details: displayed.details,
465
+ displayedBytes,
466
+ offloadPath,
467
+ });
468
+ }
469
+ }
470
+ const metadata: ToolResultDispositionMetadata = {
471
+ version: 1,
472
+ applications: 1,
473
+ presentation: { ...disposition.presentation, content: displayedText },
474
+ context: {
475
+ requestedMode: disposition.context.mode,
476
+ appliedMode: projection.appliedMode,
477
+ maxBytes: disposition.context.maxBytes,
478
+ ...(disposition.context.mode === "bounded" && disposition.context.excerpt !== undefined
479
+ ? { excerpt: disposition.context.excerpt }
480
+ : {}),
481
+ ...(disposition.context.mode === "full" && disposition.context.downgradeExcerpt !== undefined
482
+ ? { excerpt: disposition.context.downgradeExcerpt }
483
+ : {}),
484
+ ...(disposition.context.mode === "summary" && disposition.context.strategy !== undefined
485
+ ? { summaryStrategy: disposition.context.strategy }
486
+ : {}),
487
+ },
488
+ capturedBytes,
489
+ displayedBytes,
490
+ contextBytes: byteLength(projection.text),
491
+ presentationTruncated: resultWasTruncated(displayed),
492
+ contextTruncated: projection.truncated,
493
+ ...(projection.downgrade === undefined ? {} : { downgrade: projection.downgrade }),
494
+ ...(offloadPath === null ? {} : { offloadPath }),
495
+ retrieval:
496
+ offloadPath === null ? followUpHint(spec) : `read ${offloadPath} with offset and limit to retrieve omitted content`,
497
+ ...(projection.summaryProvenance === undefined ? {} : { summaryProvenance: projection.summaryProvenance }),
498
+ ...(disposition.fallback === undefined ? {} : { fallback: disposition.fallback }),
499
+ };
500
+ return {
501
+ ...displayed,
502
+ details: { ...(displayed.details ?? {}), resultDisposition: metadata },
503
+ modelContext: projection.text,
504
+ };
505
+ }
@@ -35,9 +35,11 @@ export function maxOutputArg(args: Record<string, unknown>): number {
35
35
  function resultDetails(result: SafeCommandResult): ToolResultDetails {
36
36
  return {
37
37
  command: [result.file, ...result.args].join(" "),
38
+ argv: [result.file, ...result.args],
38
39
  cwd: result.cwd,
39
40
  exitCode: result.exitCode,
40
41
  durationMs: result.durationMs,
42
+ aborted: result.aborted,
41
43
  timedOut: result.timedOut,
42
44
  outputCapped: result.outputCapped,
43
45
  };