@iowarp/clio-coder 0.4.2 → 0.4.4

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 (523) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/CONTRIBUTING.md +86 -19
  3. package/README.md +35 -6
  4. package/dist/{acp-TMDQZDIG.js → acp-WNAYYF4F.js} +12 -13
  5. package/dist/{agents-5N5NG3XG.js → agents-3OKXHLOI.js} +60 -57
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-Z5CCBXKQ.js → auth-VKNNMGPU.js} +21 -19
  8. package/dist/{builtins-K6TNDT24.js → builtins-WGALA46I.js} +9 -4
  9. package/dist/{chunk-XE3PCIXH.js → chunk-23L32XTI.js} +12 -9
  10. package/dist/{chunk-I64IFBLB.js → chunk-25QBEXRS.js} +18 -11
  11. package/dist/{chunk-CDNVLKUX.js → chunk-26QSH3EJ.js} +13 -7
  12. package/dist/{chunk-QQLGQY2A.js → chunk-2ASED4PZ.js} +22 -22
  13. package/dist/{chunk-MCEPRMZW.js → chunk-2CU2H6KE.js} +2 -2
  14. package/dist/chunk-2DSOYNFC.js +108 -0
  15. package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
  16. package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
  17. package/dist/{chunk-O3YUNJZ2.js → chunk-2ZSONWVL.js} +82 -25
  18. package/dist/{chunk-2NHR3NAY.js → chunk-36CT5VVL.js} +331 -42
  19. package/dist/{chunk-2X4RYJTJ.js → chunk-3GY4F45V.js} +3 -3
  20. package/dist/{chunk-ZW55JB7N.js → chunk-3ODX73FK.js} +4 -6
  21. package/dist/{chunk-PBP4B7XR.js → chunk-3UNOLWNZ.js} +3 -3
  22. package/dist/{chunk-4JDLP6ZS.js → chunk-3UUXNFEX.js} +14 -10
  23. package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
  24. package/dist/{chunk-ZW4HH5JJ.js → chunk-4M6Z5QVF.js} +6 -6
  25. package/dist/{chunk-K6BSR66V.js → chunk-4NSRCOYP.js} +4 -1
  26. package/dist/{chunk-M2DAX4F6.js → chunk-4WR7VSYB.js} +2 -2
  27. package/dist/{chunk-FSP7CMNU.js → chunk-54X7T7DK.js} +61 -6
  28. package/dist/{chunk-54ODD65L.js → chunk-5636DCO5.js} +4 -4
  29. package/dist/chunk-57XXR6DR.js +3763 -0
  30. package/dist/{chunk-3KIPBMUA.js → chunk-5ICU3EUH.js} +2 -2
  31. package/dist/{chunk-77QIVUZB.js → chunk-5MEZN6CB.js} +4 -4
  32. package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
  33. package/dist/{chunk-YJISEZKC.js → chunk-5TUB6SLS.js} +6 -6
  34. package/dist/{chunk-IMXMHHMQ.js → chunk-6OSVSQL5.js} +341 -57
  35. package/dist/{chunk-Q4XWMHX6.js → chunk-6PAZTBPA.js} +14 -2
  36. package/dist/{chunk-FVDGR2ZL.js → chunk-6Q3CYFD3.js} +112 -39
  37. package/dist/{chunk-IDNA72AH.js → chunk-6QOTUPRG.js} +155 -36
  38. package/dist/{chunk-X7IARSHT.js → chunk-6UINWWS6.js} +16 -10
  39. package/dist/{chunk-CYZW7JHJ.js → chunk-72YIHOZQ.js} +9 -9
  40. package/dist/{chunk-IKSLQ4XV.js → chunk-75W7L2E2.js} +752 -861
  41. package/dist/{chunk-CRFOIAX3.js → chunk-7UGL4MB5.js} +6 -6
  42. package/dist/{chunk-HIICAHCJ.js → chunk-AUPNRN7C.js} +2 -2
  43. package/dist/{chunk-7BHIY2MW.js → chunk-BJVFZO5U.js} +8 -50
  44. package/dist/{chunk-B74PXLU7.js → chunk-CUSRQKPU.js} +65 -3
  45. package/dist/chunk-DQOVN6KV.js +386 -0
  46. package/dist/{chunk-E7GT7O5N.js → chunk-DT3LWJOB.js} +7 -4
  47. package/dist/chunk-DXKJURES.js +671 -0
  48. package/dist/{chunk-JBCS7CRR.js → chunk-EL24TAU4.js} +10 -10
  49. package/dist/{chunk-TPEQIQIE.js → chunk-ELWDPP3Y.js} +8 -8
  50. package/dist/{chunk-NDINPTJ4.js → chunk-ELZVTCGV.js} +5 -4
  51. package/dist/chunk-EXLD33WO.js +381 -0
  52. package/dist/chunk-FEAXX7B6.js +101 -0
  53. package/dist/{chunk-RLYRBIYQ.js → chunk-FFUPXJC4.js} +90 -331
  54. package/dist/{chunk-5PFYMY2V.js → chunk-FTMGRKEF.js} +2 -2
  55. package/dist/{chunk-34BHNEE3.js → chunk-GHS5EBTQ.js} +58 -7
  56. package/dist/{chunk-DYHAXKHD.js → chunk-GWZNEVM2.js} +12 -8
  57. package/dist/chunk-GX5WYQO4.js +59 -0
  58. package/dist/chunk-GYV6VZOC.js +26 -0
  59. package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
  60. package/dist/chunk-I2DWJ4GM.js +390 -0
  61. package/dist/{chunk-TXOTCRLG.js → chunk-I5FWO7L5.js} +5 -5
  62. package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
  63. package/dist/{chunk-XQRY4DTA.js → chunk-IGLP3ODT.js} +10 -10
  64. package/dist/chunk-IRXAATOX.js +539 -0
  65. package/dist/chunk-IXIY2H4R.js +44 -0
  66. package/dist/{chunk-SSEYRH53.js → chunk-IZXGRF7P.js} +92 -147
  67. package/dist/{chunk-5TSRNF4G.js → chunk-JCI2ROMZ.js} +164 -6
  68. package/dist/{chunk-JWJGP5DQ.js → chunk-JEIYHLOR.js} +7 -7
  69. package/dist/{chunk-F2I26BDK.js → chunk-JQLNNIKT.js} +4 -4
  70. package/dist/{chunk-BYMNWQ7O.js → chunk-JSD46VO2.js} +315 -63
  71. package/dist/{chunk-AK5XEFVZ.js → chunk-JT2RFCC5.js} +64 -14
  72. package/dist/{chunk-MCMZMDAC.js → chunk-K6T2ZAMZ.js} +168 -6
  73. package/dist/{chunk-PGF63K6I.js → chunk-KFV5L5SK.js} +73 -4
  74. package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
  75. package/dist/{chunk-PJX3WQUQ.js → chunk-LLXSDWXS.js} +3 -3
  76. package/dist/{chunk-DZAW46HP.js → chunk-LTIKRKFL.js} +3 -3
  77. package/dist/{chunk-DZEK6CJN.js → chunk-N56KALIC.js} +21 -21
  78. package/dist/{chunk-B7HM5Z7T.js → chunk-NAI6ZFCY.js} +9 -5
  79. package/dist/{chunk-I66ZTYNP.js → chunk-NRO2BJRH.js} +2656 -2213
  80. package/dist/{chunk-ZGNYYXQ6.js → chunk-NXIMQY5W.js} +3 -3
  81. package/dist/{chunk-IKOZFYBN.js → chunk-NXYCB2VD.js} +149 -106
  82. package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
  83. package/dist/{chunk-462T4EGZ.js → chunk-O5CVSAG5.js} +2 -2
  84. package/dist/chunk-ODGTEFFI.js +50 -0
  85. package/dist/{chunk-3F7VUY77.js → chunk-OEJSLEPW.js} +2 -2
  86. package/dist/{chunk-KKOJXO6R.js → chunk-OMQNJVKW.js} +4 -2
  87. package/dist/{chunk-5KW52TEP.js → chunk-Q4WO54TA.js} +132 -77
  88. package/dist/{chunk-W6NIE6OW.js → chunk-QUFRYSWI.js} +13 -7
  89. package/dist/{chunk-42FMPA75.js → chunk-QZWQA4DE.js} +2 -2
  90. package/dist/chunk-R6Q67RJH.js +134 -0
  91. package/dist/{chunk-W4YEMFBX.js → chunk-RAY4OVGZ.js} +3 -3
  92. package/dist/{chunk-ZNT2M6TG.js → chunk-RQCKCSRL.js} +17 -17
  93. package/dist/{chunk-LJID3DYZ.js → chunk-RXTN6AKH.js} +3 -3
  94. package/dist/{chunk-P75RZCJW.js → chunk-RZDWV63N.js} +3 -3
  95. package/dist/{chunk-UH632ZYL.js → chunk-S6PYF2XF.js} +2 -2
  96. package/dist/{chunk-HJWWJ6IL.js → chunk-TOIVGRUX.js} +17 -5
  97. package/dist/{chunk-HLAFFSEK.js → chunk-TQAHXW6Y.js} +2 -2
  98. package/dist/{chunk-JIEGK6UF.js → chunk-U6TMQNSI.js} +48 -4
  99. package/dist/{chunk-2HFQNRV3.js → chunk-UEPWCCTY.js} +12 -12
  100. package/dist/chunk-UOIZ7DA4.js +41 -0
  101. package/dist/{chunk-UH347SHR.js → chunk-USR47QNF.js} +11 -11
  102. package/dist/{chunk-AZ4WMN4W.js → chunk-V6HJFQZE.js} +2 -2
  103. package/dist/chunk-V76WTFTW.js +318 -0
  104. package/dist/{chunk-NMJXSHBJ.js → chunk-W54I7H25.js} +2 -2
  105. package/dist/{chunk-KPXDY6QF.js → chunk-XRZT5WY5.js} +2 -2
  106. package/dist/{chunk-UBRFI4HS.js → chunk-XULDXHTN.js} +142 -50
  107. package/dist/chunk-XXYSBZIQ.js +283 -0
  108. package/dist/{chunk-HKMD33FO.js → chunk-Y55JBDO5.js} +405 -122
  109. package/dist/{chunk-XOXV5GKE.js → chunk-YD5GIKET.js} +17 -8
  110. package/dist/{chunk-XGDPUNND.js → chunk-YECAMM3D.js} +2 -2
  111. package/dist/{chunk-BO7Y52RY.js → chunk-YNFKXPEC.js} +7 -7
  112. package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
  113. package/dist/{chunk-M2WXEHER.js → chunk-ZA4VCIGV.js} +2 -2
  114. package/dist/cli/index.js +42 -40
  115. package/dist/{clio-7VB377CC.js → clio-QLICPCF5.js} +7 -7
  116. package/dist/{code-nav-YVLCYA7V.js → code-nav-IJR2DBPR.js} +9 -9
  117. package/dist/{components-UBWCQSRW.js → components-2TGAI2RC.js} +5 -6
  118. package/dist/{config-4HVOS65E.js → config-IUA6OYNS.js} +88 -81
  119. package/dist/{configure-PIWO7B24.js → configure-VEPX4NMX.js} +26 -25
  120. package/dist/{context-KQYIWPWT.js → context-2DKHWH2T.js} +60 -45
  121. package/dist/{context-IYEHL3WQ.js → context-4MPR7WKB.js} +78 -69
  122. package/dist/{context-N6ZE3LGJ.js → context-BOYF5EJM.js} +15 -11
  123. package/dist/{context-clear-G4OGZJDS.js → context-clear-S4ZJCQUX.js} +73 -65
  124. package/dist/context-map-COB37XXN.js +505 -0
  125. package/dist/{context-working-set-BWLF6LJP.js → context-working-set-3I3FYX6Y.js} +18 -17
  126. package/dist/detail-A7JAVSIG.js +98 -0
  127. package/dist/{dispatch-runner-2QQAITS3.js → dispatch-runner-RJ5I2F2O.js} +99 -75
  128. package/dist/{docs-PD3EXDKU.js → docs-SPOV3BAN.js} +3 -5
  129. package/dist/{doctor-LHBD36VU.js → doctor-DKICC2SN.js} +71 -48
  130. package/dist/{eval-C45FYRJ6.js → eval-OQOQUDHK.js} +308 -146
  131. package/dist/{eval-inventory-6DEJPLBF.js → eval-inventory-Y6QRFOH5.js} +4 -4
  132. package/dist/{evidence-6SHONYAF.js → evidence-4DQ25GUQ.js} +79 -175
  133. package/dist/evidence-4F5USFKH.js +208 -0
  134. package/dist/{evolve-KRKMV72X.js → evolve-GSS52E5J.js} +71 -67
  135. package/dist/{extensions-KPZ2UHBB.js → extensions-G7MFLYHT.js} +8 -9
  136. package/dist/{fleet-IVTCKDHT.js → fleet-Q37YHHAQ.js} +126 -118
  137. package/dist/{fleet-commands-EDWL3IT7.js → fleet-commands-G7E4N7SM.js} +16 -13
  138. package/dist/{fleet-decisions-YP3YEFGK.js → fleet-decisions-O7M6QBA2.js} +9 -8
  139. package/dist/{fleet-graph-ZFWKHY2M.js → fleet-graph-TOUBW6OW.js} +21 -20
  140. package/dist/{fleet-inspect-FVUNCBML.js → fleet-inspect-SW33JJNI.js} +65 -60
  141. package/dist/{fleet-preflight-UN5XED4R.js → fleet-preflight-CV2655TW.js} +4 -5
  142. package/dist/{fleet-validate-XOWC4HSX.js → fleet-validate-KESZX2YH.js} +25 -24
  143. package/dist/{fleet-verify-UN3SODEL.js → fleet-verify-UQPMTVE3.js} +66 -61
  144. package/dist/{fleet-view-TWHJKCN6.js → fleet-view-MN2VG4MR.js} +65 -60
  145. package/dist/{init-T2QORQ3Y.js → init-PXEXQSBF.js} +90 -82
  146. package/dist/{interop-IN5I2A66.js → interop-ZG5T62U3.js} +12 -13
  147. package/dist/inventory-C26CFDRR.js +101 -0
  148. package/dist/{library-LSCATDLZ.js → library-B2W4N74O.js} +29 -29
  149. package/dist/{memory-HYOKAGGJ.js → memory-YCANYS5A.js} +73 -69
  150. package/dist/{models-2GPMFYCM.js → models-GERTU3YI.js} +51 -47
  151. package/dist/{monitor-E4ASVUJH.js → monitor-CPNIUULB.js} +74 -67
  152. package/dist/{orchestrator-DDMPR3PY.js → orchestrator-J4BSH4WQ.js} +1288 -1606
  153. package/dist/{panes-E3RUXOW5.js → panes-BOHAEGYC.js} +4 -4
  154. package/dist/{panes-IXKLOKA2.js → panes-NXSLDQZ2.js} +10 -11
  155. package/dist/{paths-L7LGY6RN.js → paths-VSUWNC22.js} +6 -7
  156. package/dist/reset-TNWTB5LU.js +343 -0
  157. package/dist/{resources-OTRSN34L.js → resources-4PXNMD5G.js} +29 -22
  158. package/dist/{run-5DEYH5QK.js → run-D6XJ34CN.js} +132 -132
  159. package/dist/{share-IHWTLO3M.js → share-2NWMJJEE.js} +27 -27
  160. package/dist/{skills-IYMXMKW4.js → skills-KR7WON5G.js} +40 -33
  161. package/dist/{skills-eval-DROHSJAR.js → skills-eval-O2ZNOLDS.js} +81 -77
  162. package/dist/{skills-inventory-D7X4L4ZX.js → skills-inventory-ZZOUBK7O.js} +23 -22
  163. package/dist/{slash-commands-QBM7UZ3B.js → slash-commands-ZXPJD64J.js} +47 -37
  164. package/dist/{steer-Z5DO23FJ.js → steer-XA25PSCS.js} +4 -4
  165. package/dist/{support-U7QOWY26.js → support-7EMVWYG2.js} +6 -6
  166. package/dist/{targets-P2FUC4IL.js → targets-OMH2XCSN.js} +50 -49
  167. package/dist/tasks-IPAGMEIX.js +36 -0
  168. package/dist/{terminal-lease-YREJ3JX2.js → terminal-lease-C2J3JYRE.js} +4 -4
  169. package/dist/{tools-5B7RO6MV.js → tools-EFFEAIDP.js} +8 -9
  170. package/dist/{trace-YMGMUM6A.js → trace-FXMXUZUF.js} +7 -7
  171. package/dist/uninstall-HALS6BLF.js +407 -0
  172. package/dist/upgrade-MS72RJEP.js +306 -0
  173. package/dist/{usage-ME5MPXGX.js → usage-NHG6MCJM.js} +162 -108
  174. package/dist/{verifiers-BVZ7IWOO.js → verifiers-7AUNVXDY.js} +155 -22
  175. package/dist/{verify-5K7ZKQFC.js → verify-FWYGPKMR.js} +14 -12
  176. package/dist/{web-fetch-MPARV2K7.js → web-fetch-V4FKSDAV.js} +4 -4
  177. package/dist/{wiki-generate-F5W5QTYY.js → wiki-generate-743CIGJW.js} +99 -90
  178. package/dist/{with-panes-BYOJCLAM.js → with-panes-BDQEWBRT.js} +10 -10
  179. package/dist/worker/entry.js +72 -68
  180. package/docs/README.md +3 -2
  181. package/docs/architecture/acp.md +17 -0
  182. package/docs/architecture/artifact-placement.md +1 -0
  183. package/docs/architecture/artifact-versions.md +2 -2
  184. package/docs/architecture/context-engine.md +4 -0
  185. package/docs/architecture/dispatch-typed-intent.md +1 -1
  186. package/docs/architecture/evidence-and-memory.md +1 -1
  187. package/docs/architecture/middleware-and-components.md +1 -1
  188. package/docs/architecture/model-catalog.md +21 -10
  189. package/docs/architecture/observability.md +19 -2
  190. package/docs/architecture/prompt-envelope-and-tools.md +17 -5
  191. package/docs/architecture/provider-adapter-cookbook.md +63 -0
  192. package/docs/architecture/safety-model.md +25 -22
  193. package/docs/architecture/tui-design.md +1 -1
  194. package/docs/guide/built-in-agents.md +25 -11
  195. package/docs/guide/commands-and-modes.md +18 -3
  196. package/docs/guide/configuration-and-targets.md +100 -10
  197. package/docs/guide/configuration-reference.md +17 -7
  198. package/docs/guide/environment-variables.md +4 -2
  199. package/docs/guide/installation-and-lifecycle.md +37 -4
  200. package/docs/guide/proactive-memory.md +66 -55
  201. package/docs/guide/skills-marketplace.md +18 -0
  202. package/docs/guide/tool-usage.md +78 -3
  203. package/docs/history/config-knobs-audit.md +2 -2
  204. package/docs/process/development-pipeline.md +40 -2
  205. package/docs/process/eval-runner.md +67 -3
  206. package/docs/process/git-commit-provenance.md +15 -0
  207. package/docs/process/release-cut-checklist.md +207 -0
  208. package/docs/process/scientific-validation.md +18 -17
  209. package/evals/behavioral-machinery-support.ts +1 -0
  210. package/evals/behavioral-machinery.yaml +1 -1
  211. package/evals/behavioral-model.yaml +3 -2
  212. package/package.json +2 -2
  213. package/skills/README.md +7 -5
  214. package/skills/coding/ast-grep/SKILL.md +101 -30
  215. package/skills/coding/ast-grep/evals.md +26 -0
  216. package/skills/coding/coding-standards/SKILL.md +47 -2
  217. package/skills/coding/coding-standards/evals.md +23 -0
  218. package/skills/coding/prototype/SKILL.md +87 -28
  219. package/skills/coding/prototype/evals.md +19 -0
  220. package/skills/coding/tdd/SKILL.md +80 -53
  221. package/skills/coding/tdd/evals.md +20 -0
  222. package/skills/context/context-handoff/SKILL.md +43 -2
  223. package/skills/context/context-handoff/evals.md +44 -0
  224. package/skills/context/context-prime/SKILL.md +45 -15
  225. package/skills/context/context-prime/evals.md +45 -0
  226. package/skills/git/branch-closeout/SKILL.md +132 -0
  227. package/skills/git/branch-closeout/evals.md +133 -0
  228. package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
  229. package/skills/git/file-ticket/SKILL.md +77 -63
  230. package/skills/git/file-ticket/assets/issue-template.md +22 -0
  231. package/skills/git/file-ticket/evals.md +31 -26
  232. package/skills/git/file-ticket/references/issue-discovery.md +49 -0
  233. package/skills/git/fix-issue/SKILL.md +87 -64
  234. package/skills/git/fix-issue/evals.md +35 -31
  235. package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
  236. package/skills/git/resolve-merge-conflicts/SKILL.md +100 -51
  237. package/skills/git/resolve-merge-conflicts/evals.md +52 -25
  238. package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
  239. package/skills/git/ship/SKILL.md +103 -67
  240. package/skills/git/ship/assets/pr-template.md +21 -0
  241. package/skills/git/ship/evals.md +44 -28
  242. package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
  243. package/skills/git/worktree-create/SKILL.md +80 -50
  244. package/skills/git/worktree-create/evals.md +40 -33
  245. package/skills/git/worktree-create/references/worktree-setup.md +62 -66
  246. package/skills/git/worktree-merge/SKILL.md +112 -65
  247. package/skills/git/worktree-merge/evals.md +42 -34
  248. package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
  249. package/skills/planning/archify/SKILL.md +196 -0
  250. package/skills/planning/archify/evals.md +65 -0
  251. package/skills/planning/architecture/SKILL.md +61 -12
  252. package/skills/planning/architecture/evals.md +65 -0
  253. package/skills/planning/backlog/SKILL.md +130 -14
  254. package/skills/planning/backlog/evals.md +142 -0
  255. package/skills/planning/prd/SKILL.md +47 -6
  256. package/skills/planning/prd/evals.md +54 -0
  257. package/skills/planning/product-intent/SKILL.md +57 -2
  258. package/skills/planning/product-intent/evals.md +70 -0
  259. package/skills/planning/tech-spec/SKILL.md +53 -2
  260. package/skills/planning/tech-spec/evals.md +73 -0
  261. package/skills/registry.yaml +58 -50
  262. package/skills/remote.yaml +13 -0
  263. package/skills/research/arxiv-literature/SKILL.md +76 -18
  264. package/skills/research/arxiv-literature/evals.md +50 -0
  265. package/skills/research/experiment-protocol/SKILL.md +20 -1
  266. package/skills/research/experiment-protocol/evals.md +23 -0
  267. package/skills/research/scientific-debugging/SKILL.md +24 -1
  268. package/skills/research/scientific-debugging/evals.md +18 -0
  269. package/skills/research/scientific-modernization/SKILL.md +26 -1
  270. package/skills/research/scientific-modernization/evals.md +27 -0
  271. package/skills/skill-marketplace.json +63 -28
  272. package/skills/workflow/cut-it/SKILL.md +64 -5
  273. package/skills/workflow/cut-it/evals.md +101 -0
  274. package/skills/workflow/design-council/SKILL.md +112 -27
  275. package/skills/workflow/design-council/evals.md +161 -0
  276. package/skills/workflow/grill-me/SKILL.md +85 -10
  277. package/skills/workflow/grill-me/evals.md +153 -0
  278. package/skills/workflow/workflow-distiller/SKILL.md +76 -17
  279. package/skills/workflow/workflow-distiller/evals.md +118 -0
  280. package/src/cli/args.ts +0 -8
  281. package/src/cli/configure-interop.ts +105 -13
  282. package/src/cli/configure-oauth.ts +57 -0
  283. package/src/cli/configure-onboarding.ts +980 -0
  284. package/src/cli/configure-target.ts +594 -0
  285. package/src/cli/configure.ts +1084 -529
  286. package/src/cli/context-map.ts +114 -0
  287. package/src/cli/context.ts +4 -0
  288. package/src/cli/doctor-state-size.ts +1 -12
  289. package/src/cli/doctor-validation-contract.ts +28 -0
  290. package/src/cli/doctor.ts +5 -0
  291. package/src/cli/evidence-detail.ts +1 -75
  292. package/src/cli/evidence-inventory.ts +1 -167
  293. package/src/cli/index.ts +3 -0
  294. package/src/cli/lifecycle-presenter.ts +436 -0
  295. package/src/cli/models.ts +10 -2
  296. package/src/cli/modes/print.ts +5 -1
  297. package/src/cli/reset.ts +228 -106
  298. package/src/cli/run.ts +7 -4
  299. package/src/cli/select.ts +664 -0
  300. package/src/cli/skills.ts +9 -2
  301. package/src/cli/targets.ts +3 -0
  302. package/src/cli/tasks.ts +84 -0
  303. package/src/cli/uninstall.ts +233 -165
  304. package/src/cli/upgrade.ts +210 -150
  305. package/src/cli/usage.ts +92 -27
  306. package/src/cli/validate-model.ts +3 -3
  307. package/src/cli/verifiers.ts +147 -1
  308. package/src/cli/wiki-generate.ts +1 -0
  309. package/src/core/commit-attribution.ts +41 -1
  310. package/src/core/config.ts +56 -0
  311. package/src/core/external-diagnostic.ts +44 -0
  312. package/src/core/gateway-routing.ts +157 -0
  313. package/src/core/git-commit-attribution.ts +46 -3
  314. package/src/core/run-overrides.ts +0 -5
  315. package/src/core/safe-exec.ts +17 -2
  316. package/src/core/skill-activation.ts +92 -2
  317. package/src/core/tool-names.ts +5 -2
  318. package/src/domains/agents/builtins/architect.md +1 -1
  319. package/src/domains/agents/builtins/coder.md +1 -1
  320. package/src/domains/agents/builtins/documenter.md +1 -1
  321. package/src/domains/agents/builtins/git-master.md +1 -1
  322. package/src/domains/agents/builtins/provenance.md +7 -7
  323. package/src/domains/agents/builtins/tester.md +1 -1
  324. package/src/domains/agents/builtins/verifier.md +2 -2
  325. package/src/domains/agents/builtins/wiki-writer.md +4 -3
  326. package/src/domains/agents/builtins/world-knowledge.md +31 -0
  327. package/src/domains/agents/catalog.ts +1 -1
  328. package/src/domains/agents/result-contract.ts +70 -0
  329. package/src/domains/context/extension.ts +31 -7
  330. package/src/domains/context/refresh.ts +3 -0
  331. package/src/domains/context/wiki/frontmatter.ts +5 -2
  332. package/src/domains/context/wiki/generate.ts +6 -0
  333. package/src/domains/context/wiki/map-seed.ts +589 -0
  334. package/src/domains/context/wiki/plan.ts +2 -2
  335. package/src/domains/context/wiki/prompts.ts +43 -0
  336. package/src/domains/dispatch/active-route-planner.ts +4 -0
  337. package/src/domains/dispatch/admission.ts +29 -0
  338. package/src/domains/dispatch/agent-candidates.ts +10 -0
  339. package/src/domains/dispatch/budget-envelope.ts +86 -1
  340. package/src/domains/dispatch/capability-match.ts +1 -0
  341. package/src/domains/dispatch/capacity-lease.ts +17 -0
  342. package/src/domains/dispatch/code-step.ts +11 -4
  343. package/src/domains/dispatch/contract.ts +42 -8
  344. package/src/domains/dispatch/execution-scheduler.ts +2 -0
  345. package/src/domains/dispatch/extension.ts +184 -56
  346. package/src/domains/dispatch/fleet-commit-attribution.ts +5 -0
  347. package/src/domains/dispatch/fleet-run.ts +1 -0
  348. package/src/domains/dispatch/host-verification.ts +114 -13
  349. package/src/domains/dispatch/intent.ts +28 -18
  350. package/src/domains/dispatch/orphan-recovery.ts +2 -0
  351. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  352. package/src/domains/dispatch/reservation-store.ts +5 -3
  353. package/src/domains/dispatch/state.ts +15 -2
  354. package/src/domains/dispatch/types.ts +20 -2
  355. package/src/domains/dispatch/worker-model-metadata.ts +38 -0
  356. package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
  357. package/src/domains/eval/metrics/token-stream.ts +201 -31
  358. package/src/domains/eval/metrics/tracked.ts +40 -4
  359. package/src/domains/eval/runners/clio-run.ts +17 -11
  360. package/src/domains/eval/runners/context-index.ts +2 -7
  361. package/src/domains/eval/runners/context-init.ts +3 -6
  362. package/src/domains/eval/runners/external-command.ts +29 -11
  363. package/src/domains/eval/schema/suite.ts +28 -0
  364. package/src/domains/eval/schema/verdict.ts +2 -2
  365. package/src/domains/eval/suites/resolve.ts +13 -1
  366. package/src/domains/eval/suites/run.ts +24 -3
  367. package/src/domains/evidence/build.ts +102 -15
  368. package/src/domains/evidence/detail.ts +69 -0
  369. package/src/domains/evidence/eval.ts +13 -1
  370. package/src/domains/evidence/finish-contract-map.ts +5 -1
  371. package/src/domains/evidence/inventory.ts +167 -0
  372. package/src/domains/evidence/store.ts +16 -0
  373. package/src/domains/evidence/types.ts +12 -0
  374. package/src/domains/extensions/resources.ts +7 -0
  375. package/src/domains/interop/registry.ts +6 -2
  376. package/src/domains/interop/types.ts +4 -0
  377. package/src/domains/lifecycle/migrations/index.ts +4 -0
  378. package/src/domains/memory/task-memory-policy.ts +70 -26
  379. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  380. package/src/domains/middleware/index.ts +0 -1
  381. package/src/domains/middleware/marketplace-offer.ts +22 -35
  382. package/src/domains/middleware/memory-intervention.ts +127 -32
  383. package/src/domains/middleware/memory-step-endpoint.ts +3 -2
  384. package/src/domains/middleware/runtime.ts +7 -3
  385. package/src/domains/middleware/skills-reminder.ts +31 -2
  386. package/src/domains/mux/detect.ts +3 -6
  387. package/src/domains/observability/accountability.ts +15 -1
  388. package/src/domains/observability/compaction-usage.ts +118 -0
  389. package/src/domains/observability/contract.ts +52 -7
  390. package/src/domains/observability/cost.ts +1 -1
  391. package/src/domains/observability/evidence-index.ts +10 -0
  392. package/src/domains/observability/extension.ts +15 -6
  393. package/src/domains/observability/out-of-turn-usage.ts +52 -21
  394. package/src/domains/observability/projection.ts +394 -45
  395. package/src/{interactive → domains/observability}/worker-progress.ts +3 -3
  396. package/src/domains/prompts/fragments/operating/contract.md +2 -0
  397. package/src/domains/prompts/fragments/wiki/page.md +8 -0
  398. package/src/domains/providers/contract.ts +4 -1
  399. package/src/domains/providers/extension.ts +40 -9
  400. package/src/domains/providers/model-capabilities.ts +9 -0
  401. package/src/domains/providers/model-discovery.ts +3 -4
  402. package/src/domains/providers/model-runtime-capabilities.ts +15 -5
  403. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +48 -26
  404. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
  405. package/src/domains/providers/runtimes/claude/claude-code.ts +9 -0
  406. package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
  407. package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
  408. package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
  409. package/src/domains/providers/support.ts +11 -5
  410. package/src/domains/providers/target-model-cache.ts +25 -2
  411. package/src/domains/providers/types/capability-flags.ts +2 -0
  412. package/src/domains/providers/types/runtime-descriptor.ts +20 -1
  413. package/src/domains/providers/types/target-descriptor.ts +19 -0
  414. package/src/domains/resources/index.ts +3 -0
  415. package/src/domains/resources/skills/install.ts +72 -7
  416. package/src/domains/resources/skills/loader.ts +7 -0
  417. package/src/domains/resources/skills/marketplace.ts +63 -11
  418. package/src/domains/safety/action-classifier.ts +7 -0
  419. package/src/domains/safety/autonomy.ts +15 -0
  420. package/src/domains/safety/default-path-policy.ts +2 -0
  421. package/src/domains/safety/finish-contract-registration.ts +29 -14
  422. package/src/domains/safety/finish-contract.ts +252 -40
  423. package/src/domains/safety/index.ts +21 -1
  424. package/src/domains/safety/path-policy.ts +1 -1
  425. package/src/domains/safety/policy-engine.ts +60 -17
  426. package/src/domains/safety/protected-artifacts.ts +191 -88
  427. package/src/domains/safety/rigor.ts +53 -39
  428. package/src/domains/safety/run-effects.ts +2 -22
  429. package/src/domains/safety/skill-authority.ts +55 -0
  430. package/src/domains/safety/validation-contract.ts +388 -0
  431. package/src/domains/session/archive-readers.ts +10 -1
  432. package/src/domains/session/compaction/compact.ts +72 -22
  433. package/src/domains/session/decision-board.ts +101 -2
  434. package/src/domains/session/entries.ts +50 -7
  435. package/src/domains/session/extension.ts +4 -4
  436. package/src/domains/session/handoff.ts +2 -1
  437. package/src/domains/session/manager.ts +2 -3
  438. package/src/domains/session/task-board.ts +14 -1
  439. package/src/domains/session/tree/fork.ts +1 -2
  440. package/src/domains/session/tree/navigator.ts +1 -1
  441. package/src/domains/session/usage.ts +3 -3
  442. package/src/domains/user-tasks/acceptance.ts +56 -0
  443. package/src/domains/user-tasks/active-acceptance.ts +40 -0
  444. package/src/domains/user-tasks/store.ts +34 -3
  445. package/src/engine/acp/adapter.ts +24 -6
  446. package/src/engine/acp/server.ts +21 -4
  447. package/src/engine/acp/transport.ts +53 -8
  448. package/src/engine/acp/types.ts +4 -0
  449. package/src/engine/agent.ts +13 -3
  450. package/src/engine/ai.ts +26 -8
  451. package/src/engine/antigravity/subprocess-runtime.ts +386 -120
  452. package/src/engine/api-registry.ts +3 -0
  453. package/src/engine/apis/ollama-native.ts +15 -0
  454. package/src/engine/apis/openai-completions.ts +117 -14
  455. package/src/engine/claude/subprocess-runtime.ts +107 -60
  456. package/src/engine/external-subprocess.ts +122 -6
  457. package/src/entry/background-model-metadata.ts +18 -0
  458. package/src/entry/compaction-prompt.ts +57 -0
  459. package/src/entry/orchestrator.ts +416 -218
  460. package/src/entry/task-memory-lifecycle.ts +35 -0
  461. package/src/interactive/chat-loop-messages.ts +13 -4
  462. package/src/interactive/chat-loop.ts +65 -2
  463. package/src/interactive/chat-renderer.ts +1 -0
  464. package/src/interactive/cost-overlay.ts +26 -2
  465. package/src/interactive/dispatch-board.ts +46 -717
  466. package/src/interactive/fleet-run-preview.ts +2 -1
  467. package/src/interactive/interactive-application.ts +3 -2
  468. package/src/interactive/interactive-presentation.ts +55 -12
  469. package/src/interactive/interactive-slash-runtime.ts +4 -2
  470. package/src/interactive/oracle.ts +5 -2
  471. package/src/interactive/overlays/fleet-run-approval.ts +3 -2
  472. package/src/interactive/overlays/message-picker.ts +2 -2
  473. package/src/interactive/overlays/settings.ts +2 -2
  474. package/src/interactive/overlays/tree-selector.ts +2 -2
  475. package/src/interactive/renderers/branch-summary.ts +1 -1
  476. package/src/interactive/renderers/worker-entry.ts +32 -0
  477. package/src/interactive/slash-autocomplete.ts +4 -6
  478. package/src/interactive/slash-commands.ts +49 -45
  479. package/src/interactive/slash-spec.ts +28 -0
  480. package/src/interactive/theme/labels.ts +19 -13
  481. package/src/interactive/turn-context.ts +9 -5
  482. package/src/interactive/turn-recovery.ts +8 -0
  483. package/src/interactive/turn-runtime.ts +27 -11
  484. package/src/interactive/turn-state.ts +7 -0
  485. package/src/interactive/view/artifacts.ts +2 -0
  486. package/src/interactive/worker-receipts.ts +1 -0
  487. package/src/interactive/worker-stream.ts +13 -4
  488. package/src/tools/bootstrap.ts +4 -0
  489. package/src/tools/builtin-tool-catalog.ts +31 -0
  490. package/src/tools/compete-worktrees.ts +7 -1
  491. package/src/tools/context/index.ts +30 -9
  492. package/src/tools/core-bootstrap.ts +16 -0
  493. package/src/tools/decide.ts +136 -0
  494. package/src/tools/dispatch-admission.ts +21 -0
  495. package/src/tools/dispatch-arguments.ts +1 -0
  496. package/src/tools/dispatch-event-text.ts +10 -0
  497. package/src/tools/dispatch-plan.ts +6 -2
  498. package/src/tools/dispatch-runner.ts +27 -1
  499. package/src/tools/dispatch-types.ts +6 -0
  500. package/src/tools/evidence.ts +96 -0
  501. package/src/tools/limitation.ts +76 -0
  502. package/src/tools/policy.ts +9 -0
  503. package/src/tools/presentation.ts +3 -0
  504. package/src/tools/registry.ts +11 -5
  505. package/src/tools/result-shaping.ts +17 -5
  506. package/src/tools/task-worktree.ts +13 -3
  507. package/src/tools/tasks.ts +10 -1
  508. package/src/tools/verify/authoring.ts +170 -83
  509. package/src/tools/verify/catalog.ts +122 -5
  510. package/src/tools/verify/index.ts +2 -1
  511. package/src/tools/verify/numeric.ts +298 -0
  512. package/src/tools/verify/perf.ts +143 -0
  513. package/src/tools/verify/scripts.ts +229 -2
  514. package/src/tools/worker-evidence.ts +3 -1
  515. package/src/worker/spec-contract.ts +4 -0
  516. package/dist/chunk-2Z2IKEXI.js +0 -1554
  517. package/dist/chunk-RVG5JXAL.js +0 -41
  518. package/dist/chunk-T56WDKA5.js +0 -183
  519. package/dist/chunk-VN3SHNBN.js +0 -313
  520. package/dist/chunk-VPKWYKEY.js +0 -169
  521. package/dist/reset-OAQP3W4O.js +0 -230
  522. package/dist/uninstall-N34PCTGJ.js +0 -331
  523. package/dist/upgrade-PXK3S2YM.js +0 -325
@@ -1,18 +1,4 @@
1
1
  import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
- import {
3
- DEFAULT_KEEP_RECENT_TOKENS,
4
- DEFAULT_RESERVE_TOKENS,
5
- buildEvictionFields,
6
- calculateContextTokens,
7
- compactionCut,
8
- estimateTokens,
9
- findCutPoint,
10
- getLastAssistantUsage,
11
- planEviction,
12
- projectWorkingSet,
13
- resolveWorkingSetPolicy,
14
- selectVisibleEntries
15
- } from "./chunk-M2WXEHER.js";
16
2
  import {
17
3
  assistantSessionPayload,
18
4
  attachedToolSchemasFromState,
@@ -47,198 +33,103 @@ import {
47
33
  toolNamesFromAgentState,
48
34
  toolResultSummary,
49
35
  toolSignatureFromState
50
- } from "./chunk-XOXV5GKE.js";
51
- import {
52
- ToolchainDomainModule
53
- } from "./chunk-HRQMFLJP.js";
36
+ } from "./chunk-YD5GIKET.js";
54
37
  import {
55
38
  ShareDomainModule
56
- } from "./chunk-UH347SHR.js";
39
+ } from "./chunk-USR47QNF.js";
57
40
  import {
58
41
  bootstrapInputFromInitOptions,
59
42
  modelBootstrapGenerate,
60
43
  resolveBootstrapRoute
61
- } from "./chunk-DZEK6CJN.js";
44
+ } from "./chunk-N56KALIC.js";
62
45
  import "./chunk-MNJGS2IN.js";
46
+ import {
47
+ DEFAULT_KEEP_RECENT_TOKENS,
48
+ DEFAULT_RESERVE_TOKENS,
49
+ buildEvictionFields,
50
+ calculateContextTokens,
51
+ compactionCut,
52
+ estimateTokens,
53
+ findCutPoint,
54
+ getLastAssistantUsage,
55
+ planEviction,
56
+ projectWorkingSet,
57
+ resolveWorkingSetPolicy,
58
+ selectVisibleEntries
59
+ } from "./chunk-ZA4VCIGV.js";
63
60
  import {
64
61
  SchedulingDomainModule,
65
62
  createPromptsDomainModule,
66
63
  renderAgentCatalogSectionsFromSpecs
67
- } from "./chunk-BO7Y52RY.js";
68
- import {
69
- capturedHookSourcesFor
70
- } from "./chunk-SZAA6XDG.js";
71
- import {
72
- SafetyDomainModule
73
- } from "./chunk-54ODD65L.js";
64
+ } from "./chunk-YNFKXPEC.js";
74
65
  import {
75
- LifecycleDomainModule,
76
- describeUpgradeNotice
77
- } from "./chunk-F2I26BDK.js";
78
- import "./chunk-DYHAXKHD.js";
79
- import "./chunk-QQLGQY2A.js";
80
- import {
81
- ensureClioState,
82
- takeUpgradeNotice
83
- } from "./chunk-XQRY4DTA.js";
84
- import "./chunk-3KIPBMUA.js";
85
- import {
86
- ConfigDomainModule,
87
- createConfigDomainModule,
88
- loadDomains
89
- } from "./chunk-CYZW7JHJ.js";
90
- import {
91
- steerToolSurface
92
- } from "./chunk-W4YEMFBX.js";
93
- import {
94
- panesToolSurface
95
- } from "./chunk-2X4RYJTJ.js";
66
+ recordFailedCompactionCalls
67
+ } from "./chunk-FEAXX7B6.js";
96
68
  import {
97
69
  describePanesLeftBehind,
98
70
  paneWatchDecision
99
71
  } from "./chunk-3EBYEESD.js";
100
- import "./chunk-3M6DQK6S.js";
101
72
  import {
102
73
  flushRawStdout,
103
74
  writeRawStdout
104
75
  } from "./chunk-2VTFPG5O.js";
105
- import "./chunk-M2DAX4F6.js";
106
- import "./chunk-D4CJV46V.js";
107
76
  import {
108
- BUILTIN_SLASH_COMMANDS,
109
- COMPLETION_SLOT_NAMES,
110
- COUNCIL_SYNTHESIS_LABEL,
111
- LIBRARY_TABS,
112
- SETTINGS_AREA_IDS,
113
- SLASH_COMMAND_GROUPS,
114
- boundSettledText,
115
- commandReference,
116
- completeArgs,
117
- createWorkerProgressFold,
118
- createWorkerStream,
119
- dispatchSlashCommand,
120
- formatUserTaskHandoff,
121
- isWorkerShareNote,
122
- parseSlashCommand,
123
- renderArgsSpec,
124
- workerAskedByModel,
125
- workerReceiptSummary,
126
- workerTargetLabel
127
- } from "./chunk-RLYRBIYQ.js";
128
- import "./chunk-35MSIRKH.js";
77
+ capturedHookSourcesFor
78
+ } from "./chunk-SZAA6XDG.js";
129
79
  import {
130
- discoverDeclaredChecks
131
- } from "./chunk-MCMZMDAC.js";
80
+ LifecycleDomainModule,
81
+ describeUpgradeNotice
82
+ } from "./chunk-JQLNNIKT.js";
83
+ import "./chunk-GWZNEVM2.js";
84
+ import "./chunk-5ICU3EUH.js";
85
+ import {
86
+ ConfigDomainModule,
87
+ createConfigDomainModule,
88
+ loadDomains
89
+ } from "./chunk-72YIHOZQ.js";
90
+ import "./chunk-4WR7VSYB.js";
132
91
  import {
133
92
  buildRecallFields,
134
93
  recallErrorMessage,
135
94
  recallParentTurnId,
136
95
  recallableRefListing,
137
96
  resolveRecall
138
- } from "./chunk-462T4EGZ.js";
97
+ } from "./chunk-O5CVSAG5.js";
139
98
  import {
140
99
  foldWorkingSet,
141
100
  isTurnStart
142
101
  } from "./chunk-GTUD2WMY.js";
143
102
  import {
144
103
  compileScoutTransition
145
- } from "./chunk-UH632ZYL.js";
104
+ } from "./chunk-S6PYF2XF.js";
146
105
  import {
147
106
  monitorToolSurface
148
- } from "./chunk-PJX3WQUQ.js";
107
+ } from "./chunk-LLXSDWXS.js";
149
108
  import {
150
109
  ObservabilityDomainModule,
151
- readAccountabilitySummary,
152
- recordBackgroundMemoryStep,
153
- resolveDispatchFailureStatus
154
- } from "./chunk-HKMD33FO.js";
110
+ recordBackgroundMemoryStep
111
+ } from "./chunk-Y55JBDO5.js";
155
112
  import {
156
- appendOutOfTurnUsageRow
157
- } from "./chunk-AK5XEFVZ.js";
158
- import "./chunk-VKPAQYEB.js";
113
+ appendOutOfTurnUsageRow,
114
+ readAccountabilitySummary
115
+ } from "./chunk-JT2RFCC5.js";
159
116
  import {
160
- ClioEditor,
161
- CombinedAutocompleteProvider,
162
- Container,
163
- DEFAULT_SELECT_THEME,
164
- FILTER_HINT,
165
- FocusBox,
166
- GLYPH,
167
- Input,
168
- MUTATION_PREVIEW_KEY,
169
- Markdown,
170
- Marked,
171
- SGR_DIM,
172
- SGR_RESET,
173
- ScrollView,
174
- SelectList,
175
- Text,
176
- VStack,
177
- abbreviateModelId,
178
- barSep,
179
- bashExecutionEntryInput,
180
- brandMark,
181
- buildHint,
182
- buildResponsiveHint,
183
- clioError,
184
- clioTheme,
185
- collapseHomePath,
186
- createAgentProgress,
187
- createKeybindingManager,
188
- createProcessInteractiveShell,
189
- detectPlatformKeybindingWarnings,
190
- detectTerminalKeySupport,
191
- diagnosticSeverityToken,
192
- dotSep,
193
- fgSequence,
194
- fitHintEntries,
195
- fitUnits,
196
- formatCompactMs,
197
- formatContextPercent,
198
- formatInvalidKeybindingNotice,
199
- formatPlatformKeybindingNotice,
200
- formatRuntimeResolutionDiagnostic,
201
- formatTargetLabel,
202
- frame,
203
- fuzzyFilter,
204
- getActiveRenderTrace,
205
- getKeybindings,
206
- innerDivider,
207
- isClioToken,
208
- isKeyRelease,
209
- joinChips,
210
- joinSections,
211
- listGroupHeader,
212
- markdownTheme,
213
- matchesKey,
214
- padAnsi,
215
- paintHex,
216
- parseEditorBashCommand,
217
- permissionHintEntries,
218
- rule,
219
- screenTitle,
220
- sectionTag,
221
- selectListTheme,
222
- showClioOverlayFrame,
223
- spinnerFrame,
224
- stripTerminalSequences,
225
- truncateToWidth,
226
- unguardPastedEditorOperator,
227
- validateKeybindings,
228
- visibleWidth,
229
- wrapTextWithAnsi,
230
- writeInputWedgeDump
231
- } from "./chunk-I64IFBLB.js";
117
+ steerToolSurface
118
+ } from "./chunk-RAY4OVGZ.js";
232
119
  import {
233
- getTerminationCoordinator
234
- } from "./chunk-4O6MANBS.js";
120
+ panesToolSurface
121
+ } from "./chunk-3GY4F45V.js";
235
122
  import {
236
123
  createContextDomainModule,
237
124
  loadProjectClioMd
238
- } from "./chunk-SSEYRH53.js";
125
+ } from "./chunk-IZXGRF7P.js";
126
+ import "./chunk-R6Q67RJH.js";
127
+ import {
128
+ SafetyDomainModule
129
+ } from "./chunk-5636DCO5.js";
239
130
  import {
240
131
  renderCodewikiDigest
241
- } from "./chunk-AZ4WMN4W.js";
132
+ } from "./chunk-V6HJFQZE.js";
242
133
  import {
243
134
  buildMemoryPromptSection,
244
135
  canonicalMemoryRepositoryIdentity,
@@ -254,15 +145,57 @@ import {
254
145
  taskMemoryBankSize,
255
146
  taskMemoryHandoffSeedOffer,
256
147
  taskMemoryTracePath
257
- } from "./chunk-JBCS7CRR.js";
258
- import "./chunk-LCGCVYZ4.js";
148
+ } from "./chunk-EL24TAU4.js";
259
149
  import {
260
150
  listWikiPages,
261
151
  wikiCompleteness,
262
152
  wikiStaleness,
263
153
  wikiStalenessAsync
264
- } from "./chunk-NDINPTJ4.js";
154
+ } from "./chunk-ELZVTCGV.js";
265
155
  import "./chunk-MXHC5QYU.js";
156
+ import {
157
+ BUILTIN_SLASH_COMMANDS,
158
+ COMPLETION_SLOT_NAMES,
159
+ COUNCIL_SYNTHESIS_LABEL,
160
+ LIBRARY_TABS,
161
+ SETTINGS_AREA_IDS,
162
+ SLASH_COMMAND_GROUPS,
163
+ commandReference,
164
+ completeArgs,
165
+ createWorkerStream,
166
+ dispatchSlashCommand,
167
+ formatUserTaskHandoff,
168
+ isWorkerShareNote,
169
+ parseSlashCommand,
170
+ renderArgsSpec,
171
+ workerAskedByModel,
172
+ workerReceiptSummary,
173
+ workerTargetLabel
174
+ } from "./chunk-FFUPXJC4.js";
175
+ import {
176
+ boundSettledText
177
+ } from "./chunk-XXYSBZIQ.js";
178
+ import "./chunk-35MSIRKH.js";
179
+ import {
180
+ classifyLibraryRequirements,
181
+ createResourcesDomainModule,
182
+ discoverLibrary,
183
+ installLibraryPlan,
184
+ libraryEntryInstalled,
185
+ libraryEntryPin,
186
+ libraryEntryRef,
187
+ libraryInstallPath,
188
+ planLibraryInstall
189
+ } from "./chunk-RQCKCSRL.js";
190
+ import {
191
+ AgentsDomainModule
192
+ } from "./chunk-RZDWV63N.js";
193
+ import "./chunk-7UGL4MB5.js";
194
+ import "./chunk-DR52UMZW.js";
195
+ import {
196
+ createUserTasksStore
197
+ } from "./chunk-EXLD33WO.js";
198
+ import "./chunk-YAKGTXEV.js";
266
199
  import {
267
200
  ACP_AGENT_META_KEY,
268
201
  ACP_MAX_CHUNK_BYTES,
@@ -283,6 +216,7 @@ import {
283
216
  createDispatchRunEventRegistry,
284
217
  createRunReceiptQuality,
285
218
  createStdioServerTransport,
219
+ endpointCapacityUsage,
286
220
  evidenceDirectory,
287
221
  executeFleetRun,
288
222
  formatCostAggregate,
@@ -292,11 +226,28 @@ import {
292
226
  protectedResidencyModels,
293
227
  renderCostAggregate,
294
228
  renderDispatchReviewerTask
295
- } from "./chunk-I66ZTYNP.js";
229
+ } from "./chunk-NRO2BJRH.js";
296
230
  import {
297
231
  readGateDecisionArtifacts,
298
232
  readPendingGateDecisions
299
- } from "./chunk-ZGNYYXQ6.js";
233
+ } from "./chunk-NXIMQY5W.js";
234
+ import "./chunk-XRZT5WY5.js";
235
+ import {
236
+ describeWriteBoundaryAttributionDowngrade,
237
+ gitCheckoutRoot,
238
+ isGitRepository,
239
+ preflightWriteBoundaries,
240
+ recoverCleanupReadyCompeteGroups
241
+ } from "./chunk-QUFRYSWI.js";
242
+ import {
243
+ bindExecutionPlanEndpoints,
244
+ compileFleetExecutionPlan,
245
+ requireAgentSteps
246
+ } from "./chunk-LTIKRKFL.js";
247
+ import {
248
+ parseRigorOverride,
249
+ resolveRigor
250
+ } from "./chunk-ODGTEFFI.js";
300
251
  import {
301
252
  TRUST_STATUS_AXES,
302
253
  formatTrustSummaryLine,
@@ -304,10 +255,9 @@ import {
304
255
  isReceiptIntegrity,
305
256
  retiredReceiptIntegrity,
306
257
  retiredReceiptIntegrityReason,
307
- summarizeTrustStatus,
308
258
  trustStateWord,
309
259
  verifyReceiptIntegrity
310
- } from "./chunk-B74PXLU7.js";
260
+ } from "./chunk-CUSRQKPU.js";
311
261
  import {
312
262
  SessionDomainModule,
313
263
  addResponseModelIdObservationCount,
@@ -321,72 +271,20 @@ import {
321
271
  readAuditRows,
322
272
  responseModelIdObservationCountsLabel,
323
273
  responseModelIdObservationFromRecord
324
- } from "./chunk-X7IARSHT.js";
325
- import "./chunk-KPXDY6QF.js";
326
- import {
327
- describeWriteBoundaryAttributionDowngrade,
328
- gitCheckoutRoot,
329
- isGitRepository,
330
- preflightWriteBoundaries,
331
- recoverCleanupReadyCompeteGroups
332
- } from "./chunk-W6NIE6OW.js";
333
- import {
334
- bindExecutionPlanEndpoints,
335
- compileFleetExecutionPlan,
336
- requireAgentSteps
337
- } from "./chunk-DZAW46HP.js";
338
- import {
339
- parseRigorOverride,
340
- resolveRigor
341
- } from "./chunk-RVG5JXAL.js";
342
- import {
343
- foldPromptCacheTelemetry,
344
- hasPromptCacheTelemetry,
345
- uncachedPrefillTokens
346
- } from "./chunk-3DPEIQKN.js";
347
- import "./chunk-5PFYMY2V.js";
274
+ } from "./chunk-6UINWWS6.js";
275
+ import "./chunk-FTMGRKEF.js";
348
276
  import {
349
277
  configureRunEventJournal
350
278
  } from "./chunk-VIA6RFQZ.js";
351
- import "./chunk-T56WDKA5.js";
352
279
  import {
353
280
  filterEntriesToActivePath
354
281
  } from "./chunk-W6GROXXM.js";
355
- import "./chunk-JVCV3ICN.js";
356
- import "./chunk-4JDLP6ZS.js";
357
- import {
358
- shellQuote
359
- } from "./chunk-TXOTCRLG.js";
360
- import {
361
- emptyWorkspaceSnapshot,
362
- probeGitStatusAsync,
363
- probeWorkspaceAsync
364
- } from "./chunk-HVDIIIQW.js";
365
- import {
366
- classifyLibraryRequirements,
367
- createResourcesDomainModule,
368
- discoverLibrary,
369
- installLibraryPlan,
370
- libraryEntryInstalled,
371
- libraryEntryPin,
372
- libraryEntryRef,
373
- libraryInstallPath,
374
- planLibraryInstall
375
- } from "./chunk-ZNT2M6TG.js";
376
282
  import {
377
- AgentsDomainModule
378
- } from "./chunk-P75RZCJW.js";
379
- import "./chunk-CRFOIAX3.js";
380
- import "./chunk-DR52UMZW.js";
381
- import {
382
- MARKETPLACE_UNCONFIGURED,
383
- discoverMarketplaceSkills,
384
- getMarketplaceSkills,
385
- installSkill,
386
- modelVisibleSkills
387
- } from "./chunk-O3YUNJZ2.js";
388
- import "./chunk-NDDGJUXD.js";
389
- import "./chunk-XGDPUNND.js";
283
+ activeDecisionRefs,
284
+ createDecisionBoardStore,
285
+ decisionRationale,
286
+ foldDecisionBoard
287
+ } from "./chunk-I2DWJ4GM.js";
390
288
  import {
391
289
  FLEET_COMMANDS_REMEDY,
392
290
  FleetCommandRegistryMissingError,
@@ -396,17 +294,142 @@ import {
396
294
  renderFleetPrompt,
397
295
  validateFleetCommands,
398
296
  validateFleetGraph
399
- } from "./chunk-3F7VUY77.js";
297
+ } from "./chunk-OEJSLEPW.js";
400
298
  import "./chunk-RKKLTLYB.js";
299
+ import {
300
+ discoverDeclaredChecks
301
+ } from "./chunk-K6T2ZAMZ.js";
302
+ import {
303
+ shellQuote
304
+ } from "./chunk-3UUXNFEX.js";
305
+ import {
306
+ ToolchainDomainModule
307
+ } from "./chunk-HRQMFLJP.js";
308
+ import "./chunk-2ASED4PZ.js";
309
+ import {
310
+ ensureClioState,
311
+ takeUpgradeNotice
312
+ } from "./chunk-IGLP3ODT.js";
313
+ import "./chunk-3M6DQK6S.js";
314
+ import "./chunk-VKPAQYEB.js";
315
+ import "./chunk-LCGCVYZ4.js";
316
+ import {
317
+ MARKETPLACE_UNCONFIGURED,
318
+ discoverMarketplaceSkills,
319
+ installSkill,
320
+ modelVisibleSkills
321
+ } from "./chunk-2ZSONWVL.js";
322
+ import "./chunk-NDDGJUXD.js";
323
+ import "./chunk-YECAMM3D.js";
324
+ import "./chunk-V76WTFTW.js";
325
+ import {
326
+ foldPromptCacheTelemetry,
327
+ hasPromptCacheTelemetry,
328
+ uncachedPrefillTokens
329
+ } from "./chunk-3DPEIQKN.js";
401
330
  import {
402
331
  EXTENSION_SNAPSHOT_DIAGNOSTIC_MESSAGE_CAP,
403
332
  ExtensionsDomainModule
404
- } from "./chunk-HLAFFSEK.js";
405
- import "./chunk-77QIVUZB.js";
333
+ } from "./chunk-TQAHXW6Y.js";
334
+ import "./chunk-5MEZN6CB.js";
335
+ import "./chunk-D4CJV46V.js";
336
+ import "./chunk-NEKRRTYW.js";
337
+ import {
338
+ INHERITED_PROJECT_CONTEXT,
339
+ InteropDomainModule,
340
+ delegationEntryForKind,
341
+ renderProposalEntry
342
+ } from "./chunk-JEIYHLOR.js";
343
+ import "./chunk-I7XBWTYH.js";
344
+ import {
345
+ ClioEditor,
346
+ CombinedAutocompleteProvider,
347
+ Container,
348
+ DEFAULT_SELECT_THEME,
349
+ FILTER_HINT,
350
+ FocusBox,
351
+ GLYPH,
352
+ Input,
353
+ MUTATION_PREVIEW_KEY,
354
+ Markdown,
355
+ Marked,
356
+ SGR_DIM,
357
+ SGR_RESET,
358
+ ScrollView,
359
+ SelectList,
360
+ Text,
361
+ VStack,
362
+ abbreviateModelId,
363
+ barSep,
364
+ bashExecutionEntryInput,
365
+ brandMark,
366
+ buildHint,
367
+ buildResponsiveHint,
368
+ clioError,
369
+ clioTheme,
370
+ collapseHomePath,
371
+ createAgentProgress,
372
+ createKeybindingManager,
373
+ createProcessInteractiveShell,
374
+ detectPlatformKeybindingWarnings,
375
+ detectTerminalKeySupport,
376
+ diagnosticSeverityToken,
377
+ dotSep,
378
+ fgSequence,
379
+ fitHintEntries,
380
+ fitUnits,
381
+ formatCompactMs,
382
+ formatContextPercent,
383
+ formatInvalidKeybindingNotice,
384
+ formatPlatformKeybindingNotice,
385
+ formatRuntimeResolutionDiagnostic,
386
+ formatTargetLabel,
387
+ frame,
388
+ fuzzyFilter,
389
+ getActiveRenderTrace,
390
+ getKeybindings,
391
+ innerDivider,
392
+ isClioToken,
393
+ isKeyRelease,
394
+ joinChips,
395
+ joinSections,
396
+ listGroupHeader,
397
+ markdownTheme,
398
+ matchesKey,
399
+ padAnsi,
400
+ paintHex,
401
+ parseEditorBashCommand,
402
+ permissionHintEntries,
403
+ rule,
404
+ screenTitle,
405
+ sectionTag,
406
+ selectListTheme,
407
+ showClioOverlayFrame,
408
+ spinnerFrame,
409
+ stripTerminalSequences,
410
+ truncateToWidth,
411
+ unguardPastedEditorOperator,
412
+ validateKeybindings,
413
+ visibleWidth,
414
+ wrapTextWithAnsi,
415
+ writeInputWedgeDump
416
+ } from "./chunk-25QBEXRS.js";
417
+ import {
418
+ getTerminationCoordinator
419
+ } from "./chunk-4O6MANBS.js";
420
+ import "./chunk-JVCV3ICN.js";
421
+ import {
422
+ emptyWorkspaceSnapshot,
423
+ probeGitStatusAsync,
424
+ probeWorkspaceAsync
425
+ } from "./chunk-HVDIIIQW.js";
406
426
  import {
407
427
  formatBootTrace,
408
428
  traceBoot
409
429
  } from "./chunk-ZTJUVLTU.js";
430
+ import {
431
+ source_default
432
+ } from "./chunk-JCI2ROMZ.js";
410
433
  import {
411
434
  INTERACTIVE_LOOP_BLOCK_BUDGET,
412
435
  applyEditsToNormalizedContent,
@@ -427,7 +450,10 @@ import {
427
450
  resolveSessionTools,
428
451
  sanitizeLockedSynthesisMessage,
429
452
  stripBom
430
- } from "./chunk-2NHR3NAY.js";
453
+ } from "./chunk-36CT5VVL.js";
454
+ import {
455
+ resolveFdBinary
456
+ } from "./chunk-BMS5RKQY.js";
431
457
  import {
432
458
  MIDDLEWARE_HOOK_TEXT_MAX_CHARS,
433
459
  MiddlewareDomainModule,
@@ -449,21 +475,17 @@ import {
449
475
  openDetachedBatchViews,
450
476
  watchdogBriefing,
451
477
  writeMiddlewareDiagnosticToStderr
452
- } from "./chunk-UBRFI4HS.js";
478
+ } from "./chunk-XULDXHTN.js";
479
+ import "./chunk-2CU2H6KE.js";
480
+ import "./chunk-GX5WYQO4.js";
481
+ import "./chunk-RXTN6AKH.js";
482
+ import "./chunk-3UNOLWNZ.js";
453
483
  import "./chunk-5PSMVOLM.js";
454
- import {
455
- resolveFdBinary
456
- } from "./chunk-BMS5RKQY.js";
457
- import "./chunk-QSNYB6ZV.js";
458
- import "./chunk-QDC3K2U3.js";
459
- import "./chunk-MCEPRMZW.js";
460
- import "./chunk-7BHIY2MW.js";
461
- import "./chunk-LJID3DYZ.js";
462
- import "./chunk-PBP4B7XR.js";
463
484
  import {
464
485
  TaskMemoryBank,
486
+ TaskMemoryEndpointBusyError,
465
487
  createTaskMemoryTelemetrySink
466
- } from "./chunk-I66EAJFY.js";
488
+ } from "./chunk-2WZ546HR.js";
467
489
  import {
468
490
  escapeRegExp
469
491
  } from "./chunk-VG7TBQIY.js";
@@ -485,7 +507,6 @@ import {
485
507
  cancelledAskUserResult,
486
508
  classifyDecisionPresentation,
487
509
  classifyResourceRead,
488
- cloneRunToolBudgetEnvelope,
489
510
  createRegistry,
490
511
  decisionActionClass,
491
512
  decisionFactsForAnswer,
@@ -499,8 +520,6 @@ import {
499
520
  formatEffectiveBudget,
500
521
  isResponseSchemaRejection,
501
522
  maxOutputBytesArg,
502
- narrowDispatchIntentToReadOnly,
503
- normalizeDispatchIntent,
504
523
  prepareDispatchArguments,
505
524
  renderCouncilVoteMemberTask,
506
525
  resolveToolPromptHint,
@@ -511,22 +530,23 @@ import {
511
530
  timeoutMsArg,
512
531
  toolPresentationPolicy,
513
532
  withResolvedDispatchPlan
514
- } from "./chunk-IKSLQ4XV.js";
533
+ } from "./chunk-75W7L2E2.js";
534
+ import {
535
+ DEFAULT_RECENT_ENTRY_LIMIT,
536
+ assessFinishContract,
537
+ recentEntries
538
+ } from "./chunk-6QOTUPRG.js";
515
539
  import {
516
540
  defaultRoutingIntent,
517
541
  sameRouteIdentity
518
- } from "./chunk-HIICAHCJ.js";
542
+ } from "./chunk-AUPNRN7C.js";
519
543
  import {
520
544
  createTaskBoardStore,
521
545
  foldSessionTaskHistory,
522
546
  foldTaskBoard,
523
547
  taskBoardCounts
524
- } from "./chunk-Q4XWMHX6.js";
525
- import {
526
- DEFAULT_RECENT_ENTRY_LIMIT,
527
- assessFinishContract
528
- } from "./chunk-IDNA72AH.js";
529
- import "./chunk-FVDGR2ZL.js";
548
+ } from "./chunk-6PAZTBPA.js";
549
+ import "./chunk-6Q3CYFD3.js";
530
550
  import {
531
551
  describeCallTarget,
532
552
  redactSecretString,
@@ -534,90 +554,72 @@ import {
534
554
  sanitizeCallTargetText,
535
555
  sanitizeMultilineDisplayText
536
556
  } from "./chunk-NEDJ26B5.js";
537
- import {
538
- TOOL_PROFILE_NAMES
539
- } from "./chunk-42FMPA75.js";
540
- import {
541
- agentRoleFactsResolver,
542
- gateDeciderAgentId,
543
- requestExecutionRole,
544
- withAttemptRole
545
- } from "./chunk-H7IXIC72.js";
546
- import "./chunk-VN3SHNBN.js";
547
557
  import {
548
558
  resolveToCwd
549
559
  } from "./chunk-OQE5J4C6.js";
550
- import {
551
- DEFAULT_AUTONOMY_LEVEL,
552
- SKILL_SUGGESTION_PREFIX,
553
- isSkillActivation,
554
- skillActivationFromToolDetails
555
- } from "./chunk-FSP7CMNU.js";
556
560
  import {
557
561
  sweepExpiredToolOffloads,
558
562
  toolResultPresentationPolicy,
559
563
  toolResultPresentationText
560
- } from "./chunk-B7HM5Z7T.js";
564
+ } from "./chunk-NAI6ZFCY.js";
561
565
  import {
562
566
  formatSize
563
567
  } from "./chunk-OZNBF4L3.js";
564
- import "./chunk-4BJ5BYCE.js";
565
- import "./chunk-6XLNIQDB.js";
566
568
  import {
567
- combineBashOutput,
568
- runBashCommand
569
- } from "./chunk-NMJXSHBJ.js";
570
- import "./chunk-VAVR4IJY.js";
571
- import "./chunk-2LEAKD4C.js";
572
- import "./chunk-HHV2GANA.js";
569
+ TOOL_PROFILE_NAMES
570
+ } from "./chunk-QZWQA4DE.js";
571
+ import {
572
+ agentRoleFactsResolver,
573
+ gateDeciderAgentId,
574
+ requestExecutionRole,
575
+ withAttemptRole
576
+ } from "./chunk-H7IXIC72.js";
573
577
  import {
578
+ isUserVisibleAgent,
574
579
  parseJsonObjectPayload,
575
580
  parseScoutResult,
576
581
  parseVerifierResult,
577
582
  resultContractSourceId
578
- } from "./chunk-PGF63K6I.js";
583
+ } from "./chunk-KFV5L5SK.js";
579
584
  import {
580
- CLIO_PROJECT_DIR,
581
585
  toolMutationPaths
582
- } from "./chunk-IKOZFYBN.js";
586
+ } from "./chunk-NXYCB2VD.js";
587
+ import "./chunk-ECH6PKUQ.js";
588
+ import {
589
+ narrowDispatchIntentToReadOnly,
590
+ normalizeDispatchIntent
591
+ } from "./chunk-IRXAATOX.js";
592
+ import "./chunk-BJVFZO5U.js";
593
+ import "./chunk-DXKJURES.js";
594
+ import "./chunk-HHV2GANA.js";
595
+ import "./chunk-GYV6VZOC.js";
583
596
  import {
584
597
  VERIFICATION_SCRIPT_FAMILY_HINT
585
598
  } from "./chunk-UL3WSD3F.js";
586
- import "./chunk-ECH6PKUQ.js";
587
599
  import {
588
600
  typebox_exports
589
601
  } from "./chunk-5B2AEOW5.js";
602
+ import "./chunk-VAVR4IJY.js";
603
+ import "./chunk-QSNYB6ZV.js";
604
+ import "./chunk-4BJ5BYCE.js";
590
605
  import {
591
- ToolNames
592
- } from "./chunk-K6BSR66V.js";
593
- import {
594
- incompleteInstallationAdvice
595
- } from "./chunk-65DEGPJ6.js";
596
- import "./chunk-BWH6N36D.js";
597
- import "./chunk-UUVG37B4.js";
598
- import {
599
- readCodewiki,
600
- readCodewikiAsync
601
- } from "./chunk-LBMZMYH2.js";
602
- import "./chunk-XAKHZX5N.js";
603
- import {
604
- enumerateWorkspaceFilesAsync
605
- } from "./chunk-33YXPOE3.js";
606
- import "./chunk-7CR24IG7.js";
607
- import {
608
- getVersionInfo
609
- } from "./chunk-XPLRXC72.js";
610
- import "./chunk-NEKRRTYW.js";
611
- import {
612
- INHERITED_PROJECT_CONTEXT,
613
- InteropDomainModule,
614
- delegationEntryForKind,
615
- renderProposalEntry
616
- } from "./chunk-JWJGP5DQ.js";
617
- import "./chunk-I7XBWTYH.js";
606
+ DEFAULT_AUTONOMY_LEVEL,
607
+ SKILL_SUGGESTION_PREFIX,
608
+ armedSkillSurface,
609
+ isSessionEntry,
610
+ isSkillActivation,
611
+ modelMayActivateSkills,
612
+ skillActivationFromToolDetails,
613
+ skillSurfaceLabels,
614
+ skillSurfaceNames,
615
+ withModelSkillActivation
616
+ } from "./chunk-54X7T7DK.js";
617
+ import "./chunk-I5FWO7L5.js";
618
+ import "./chunk-6XLNIQDB.js";
618
619
  import {
619
- source_default
620
- } from "./chunk-5TSRNF4G.js";
620
+ ToolNames
621
+ } from "./chunk-4NSRCOYP.js";
622
+ import "./chunk-QDC3K2U3.js";
621
623
  import {
622
624
  ProvidersDomainModule,
623
625
  applyModelCapabilityPatch,
@@ -626,6 +628,9 @@ import {
626
628
  endpointCapacityForStatus,
627
629
  firstRuntimeResolutionError,
628
630
  foregroundStreamUsage,
631
+ gatewayRoutingObservationFromRecord,
632
+ gatewayRoutingObservationLabel,
633
+ hasLiveModelCatalog,
629
634
  isDispatchEligibleRuntime,
630
635
  isOrchestratorEligibleRuntime,
631
636
  memoryInterventionModelMaxTokens,
@@ -636,8 +641,9 @@ import {
636
641
  refineRuntimeTargetWithModelHints,
637
642
  registerForegroundStream,
638
643
  residencyTargetKey,
639
- resolveCostProvenance,
644
+ resolveEndpointCapacities,
640
645
  resolveModelCapabilities,
646
+ resolveModelReference,
641
647
  resolveModelRuntimeCapabilitiesForProviders,
642
648
  resolveReservedOutputTokens,
643
649
  resolveRuntimeTarget,
@@ -647,9 +653,8 @@ import {
647
653
  thinkingLevelChoiceLabel,
648
654
  thinkingLevelFromChoiceLabel,
649
655
  withRunOverrides
650
- } from "./chunk-BYMNWQ7O.js";
656
+ } from "./chunk-JSD46VO2.js";
651
657
  import "./chunk-CFGTUFWB.js";
652
- import "./chunk-72GZI5EV.js";
653
658
  import {
654
659
  AutoCompactionTrigger,
655
660
  DEFAULT_COMPACTION_THRESHOLD,
@@ -669,23 +674,11 @@ import {
669
674
  reconcileSnapshot,
670
675
  shouldCompact,
671
676
  snapshotInputTokens
672
- } from "./chunk-CWVRRIEI.js";
673
- import {
674
- atomicWrite,
675
- cwdHash,
676
- openSession,
677
- readSessionTailTurns,
678
- sessionCurrentPath,
679
- sessionPaths
680
- } from "./chunk-MQXIVJ35.js";
681
- import "./chunk-R346GLFC.js";
682
- import {
683
- getSharedBus
684
- } from "./chunk-PMZVFWSR.js";
685
- import "./chunk-BTK3SSSK.js";
677
+ } from "./chunk-NZMNUPZZ.js";
678
+ import "./chunk-2JH2WHGE.js";
686
679
  import {
687
680
  interopAgentKind
688
- } from "./chunk-IHXBNWMM.js";
681
+ } from "./chunk-KXDSS5WJ.js";
689
682
  import {
690
683
  SETTINGS_V1_PATH_MOVES,
691
684
  bindAgentProfileInSettings,
@@ -695,21 +688,46 @@ import {
695
688
  setFleetProfileInSettings,
696
689
  updateSettings,
697
690
  useTargetInSettings
698
- } from "./chunk-34BHNEE3.js";
691
+ } from "./chunk-GHS5EBTQ.js";
699
692
  import "./chunk-D7E7WCDF.js";
700
- import "./chunk-HJWWJ6IL.js";
693
+ import {
694
+ atomicWrite,
695
+ cwdHash,
696
+ openSession,
697
+ readSessionTailTurns,
698
+ sessionCurrentPath,
699
+ sessionPaths
700
+ } from "./chunk-HAXOFFRH.js";
701
+ import "./chunk-R346GLFC.js";
702
+ import "./chunk-BTK3SSSK.js";
703
+ import {
704
+ combineBashOutput,
705
+ runBashCommand
706
+ } from "./chunk-W54I7H25.js";
707
+ import {
708
+ getSharedBus
709
+ } from "./chunk-PMZVFWSR.js";
701
710
  import {
702
711
  BusChannels,
703
712
  isRunAbortedPayload
704
713
  } from "./chunk-F4EKGO4N.js";
705
714
  import {
706
- setGitCommitAttributionEnabled
707
- } from "./chunk-JIEGK6UF.js";
715
+ incompleteInstallationAdvice
716
+ } from "./chunk-65DEGPJ6.js";
717
+ import "./chunk-BWH6N36D.js";
718
+ import "./chunk-UUVG37B4.js";
708
719
  import {
709
- MAX_TIMER_DELAY_MS,
710
- rawDurationMs
711
- } from "./chunk-EBY63B7G.js";
712
- import "./chunk-6EJMN2Y3.js";
720
+ readCodewiki,
721
+ readCodewikiAsync
722
+ } from "./chunk-LBMZMYH2.js";
723
+ import "./chunk-XAKHZX5N.js";
724
+ import {
725
+ enumerateWorkspaceFilesAsync
726
+ } from "./chunk-33YXPOE3.js";
727
+ import "./chunk-7CR24IG7.js";
728
+ import {
729
+ getVersionInfo
730
+ } from "./chunk-XPLRXC72.js";
713
731
  import {
714
732
  readClioVersion,
715
733
  readPiMonoVersion
@@ -718,7 +736,7 @@ import {
718
736
  VALID_THINKING_LEVELS,
719
737
  formatContextWindowSlots,
720
738
  registerBuiltinRuntimes
721
- } from "./chunk-IMXMHHMQ.js";
739
+ } from "./chunk-6OSVSQL5.js";
722
740
  import {
723
741
  ACTIVE_ROUTING_POSTURES,
724
742
  ACTIVE_ROUTING_ROLES,
@@ -731,22 +749,26 @@ import {
731
749
  configureGuardrails,
732
750
  guardrailValuesFromSettings
733
751
  } from "./chunk-S66XZJOF.js";
752
+ import "./chunk-TOIVGRUX.js";
753
+ import {
754
+ setCommitDecisionRefsProvider,
755
+ setGitCommitAttributionEnabled
756
+ } from "./chunk-U6TMQNSI.js";
757
+ import {
758
+ MAX_TIMER_DELAY_MS,
759
+ rawDurationMs
760
+ } from "./chunk-EBY63B7G.js";
761
+ import "./chunk-6EJMN2Y3.js";
734
762
  import {
735
763
  resolveProviderReference
736
- } from "./chunk-CDNVLKUX.js";
764
+ } from "./chunk-26QSH3EJ.js";
737
765
  import {
738
766
  targetRequiresAuth
739
- } from "./chunk-WNP7O5WZ.js";
767
+ } from "./chunk-ID64D7PE.js";
740
768
  import "./chunk-336NSSKI.js";
741
769
  import "./chunk-IKCO5N3L.js";
742
770
  import "./chunk-3I7MS7N2.js";
743
771
  import "./chunk-APJ265NV.js";
744
- import {
745
- clioConfigDir,
746
- clioDataDir,
747
- clioStateDir,
748
- stateRootRemoved
749
- } from "./chunk-BYP5D4HI.js";
750
772
  import {
751
773
  safeResourceWrite
752
774
  } from "./chunk-WEPFGWHJ.js";
@@ -756,7 +778,7 @@ import {
756
778
  import {
757
779
  AGENT_ROLE_TOOLS_REQUIRED_REASON,
758
780
  supportsAgentRoleTools
759
- } from "./chunk-O42A54GG.js";
781
+ } from "./chunk-5OIVVPHF.js";
760
782
  import {
761
783
  StringEnum,
762
784
  cleanupEngineSessionResources,
@@ -764,15 +786,24 @@ import {
764
786
  isEngineRetryableAssistantError,
765
787
  stream,
766
788
  streamSimple
767
- } from "./chunk-VXMFAE2W.js";
789
+ } from "./chunk-YPC6ZR5L.js";
768
790
  import "./chunk-YXLYO42X.js";
791
+ import "./chunk-2LEAKD4C.js";
792
+ import {
793
+ clioConfigDir,
794
+ clioDataDir,
795
+ clioStateDir,
796
+ stateRootRemoved
797
+ } from "./chunk-BYP5D4HI.js";
769
798
  import {
770
799
  init_esm_shims
771
800
  } from "./chunk-3R73A4XB.js";
772
801
 
773
802
  // src/entry/orchestrator.ts
774
803
  init_esm_shims();
775
- import { join as join12 } from "node:path";
804
+ import { randomUUID as randomUUID3 } from "node:crypto";
805
+ import { readFileSync as readFileSync9 } from "node:fs";
806
+ import { join as join11 } from "node:path";
776
807
 
777
808
  // src/cli/modes/print.ts
778
809
  init_esm_shims();
@@ -823,10 +854,11 @@ function resultFromEvent(event, current) {
823
854
  }
824
855
  if (event.type !== "message_end") return current;
825
856
  const message = event.message;
857
+ if (message?.role !== "assistant") return current;
826
858
  const error = assistantError(message);
827
859
  if (error) return { ...current, text: "", error };
828
860
  const text = assistantText(message).trimEnd();
829
- if (text.length === 0) return current;
861
+ if (text.length === 0) return { ...current, error: null };
830
862
  return { ...current, text, error: null };
831
863
  }
832
864
  function blankToolStat(tool) {
@@ -1593,19 +1625,18 @@ function stableJson(value) {
1593
1625
  // src/domains/safety/finish-contract-registration.ts
1594
1626
  init_esm_shims();
1595
1627
  var FINISH_CONTRACT_REGISTRATION_ID = "assessor.finish-contract";
1596
- var HIGH_RIGOR_REVALIDATION_MESSAGE = `[Clio Coder] high-rigor finish gate: this completion claim has no validation evidence. Before claiming done, run a verification command (the ${VERIFICATION_SCRIPT_FAMILY_HINT} family, e.g. "npm run test", "npm run lint", "npm run build") or explicitly state what could not be verified and why. Do not end the turn until you have validated or recorded the limitation.`;
1628
+ var HIGH_RIGOR_REVALIDATION_MESSAGE = `[Clio Coder] high-rigor finish gate: this completion claim has no validation evidence. Before claiming done, run a verification command (the ${VERIFICATION_SCRIPT_FAMILY_HINT} family, e.g. "npm run test", "npm run lint", "npm run build") or call the limitation tool with the scope and reason of what could not be verified. Do not end the turn until you have validated or recorded the limitation.`;
1597
1629
  function createFinishContractRegistration(options) {
1598
1630
  return {
1599
1631
  id: FINISH_CONTRACT_REGISTRATION_ID,
1600
- description: "advise when a turn mutated files without validation evidence or an explicit limitation",
1632
+ description: "advise when a turn mutated files without validation evidence or a limitation receipt",
1601
1633
  hooks: ["turn_end"],
1602
1634
  evaluate(input, context) {
1603
1635
  if (input.hook !== "turn_end") return [];
1604
1636
  if (context?.priorEffects.some(isHardBlockEffect) === true) return [];
1605
1637
  const stopReason = input.metadata?.stopReason;
1606
1638
  if (stopReason !== void 0 && stopReason !== "stop") return [];
1607
- const assistantText3 = input.text?.trim() ?? "";
1608
- if (assistantText3.length === 0) return [];
1639
+ if ((input.text?.trim() ?? "").length === 0) return [];
1609
1640
  let entries;
1610
1641
  try {
1611
1642
  entries = options.readSessionEntries();
@@ -1613,18 +1644,22 @@ function createFinishContractRegistration(options) {
1613
1644
  return [];
1614
1645
  }
1615
1646
  if (entries === null) return [];
1647
+ const rigor = options.resolveRigor?.() ?? "normal";
1648
+ const activeAcceptance = rigor === "high" ? options.readActiveAcceptance?.(recentEntries(entries, input.turnId ?? null, DEFAULT_RECENT_ENTRY_LIMIT)) : void 0;
1616
1649
  const assessment = assessFinishContract({
1617
- assistantText: assistantText3,
1618
1650
  sessionEntries: entries,
1651
+ workspaceRoot: process.cwd(),
1652
+ rigor,
1653
+ ...activeAcceptance ? { activeAcceptance } : {},
1619
1654
  assistantTurnId: input.turnId ?? null
1620
1655
  });
1621
- const rigor = options.resolveRigor?.() ?? "normal";
1622
1656
  recordDecision(options, input.turnId ?? null, assessment, rigor);
1623
1657
  if (assessment.kind !== "engage") return [];
1624
1658
  if (rigor === "high") {
1659
+ const message = activeAcceptance?.verification.length ? assessment.message : HIGH_RIGOR_REVALIDATION_MESSAGE;
1625
1660
  return [
1626
- { kind: "request_continuation", message: HIGH_RIGOR_REVALIDATION_MESSAGE },
1627
- { kind: "inject_reminder", message: HIGH_RIGOR_REVALIDATION_MESSAGE, severity: "warn" }
1661
+ { kind: "request_continuation", message },
1662
+ { kind: "inject_reminder", message, severity: "warn" }
1628
1663
  ];
1629
1664
  }
1630
1665
  return [{ kind: "inject_reminder", message: assessment.message, severity: "warn" }];
@@ -2045,6 +2080,22 @@ function addCompactionUsage(total, raw) {
2045
2080
  apiCalls: base.apiCalls + 1
2046
2081
  };
2047
2082
  }
2083
+ function retainReportedUsage(previous, raw) {
2084
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return previous;
2085
+ const usage = raw;
2086
+ const known = { ...previous };
2087
+ for (const field2 of ["input", "output", "cacheRead", "cacheWrite", "totalTokens"]) {
2088
+ const value = numberOrZero(usage[field2]);
2089
+ if (value > 0) known[field2] = value;
2090
+ }
2091
+ const reasoning = extractReasoningTokens({ ...usage, reasoningTokens: void 0 });
2092
+ if (reasoning !== null && reasoning > 0) known.reasoning = reasoning;
2093
+ if (usage.cost && typeof usage.cost === "object" && "total" in usage.cost) {
2094
+ const cost = numberOrZero(usage.cost.total);
2095
+ if (cost > 0) known.cost = { total: cost };
2096
+ }
2097
+ return known;
2098
+ }
2048
2099
  async function runSummaryStream(input, userText, systemPrompt, maxTokens) {
2049
2100
  const options = { maxTokens };
2050
2101
  if (input.apiKey !== void 0) options.apiKey = input.apiKey;
@@ -2054,25 +2105,43 @@ async function runSummaryStream(input, userText, systemPrompt, maxTokens) {
2054
2105
  systemPrompt,
2055
2106
  messages: [buildUserMessage(userText)]
2056
2107
  };
2057
- const events = stream(
2058
- input.model,
2059
- context,
2060
- options
2061
- );
2062
- let summary = "";
2108
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
2109
+ const started = performance.now();
2063
2110
  let usage;
2064
- for await (const event of events) {
2065
- if (event.type === "done") {
2066
- summary = textFromAssistant(event.message);
2067
- usage = event.message.usage;
2068
- break;
2069
- }
2070
- if (event.type === "error") {
2071
- const reason = event.error.errorMessage ?? "unknown error";
2072
- throw new Error(`compaction stream failed: ${reason}`);
2111
+ let reported = {};
2112
+ let outcome = "error";
2113
+ try {
2114
+ const events = streamSimple(
2115
+ input.model,
2116
+ context,
2117
+ options
2118
+ );
2119
+ for await (const event of events) {
2120
+ if ("partial" in event) {
2121
+ usage = event.partial.usage ?? usage;
2122
+ reported = retainReportedUsage(reported, usage);
2123
+ }
2124
+ if (event.type === "done") {
2125
+ usage = event.message.usage ?? usage;
2126
+ outcome = "success";
2127
+ return { text: textFromAssistant(event.message).trim(), usage };
2128
+ }
2129
+ if (event.type === "error") {
2130
+ usage = event.error.usage ?? usage;
2131
+ reported = retainReportedUsage(reported, usage);
2132
+ outcome = event.error.stopReason === "aborted" ? "aborted" : "error";
2133
+ throw new Error(`compaction stream failed: ${event.error.errorMessage ?? "unknown error"}`);
2134
+ }
2073
2135
  }
2136
+ throw new Error("compaction stream ended without a terminal response");
2137
+ } finally {
2138
+ input.onCall?.({
2139
+ outcome: outcome === "error" && input.signal?.aborted ? "aborted" : outcome,
2140
+ usage: outcome === "success" ? usage : reported,
2141
+ timestamp,
2142
+ durationMs: Math.max(0, performance.now() - started)
2143
+ });
2074
2144
  }
2075
- return { text: summary.trim(), usage };
2076
2145
  }
2077
2146
  async function compact(input) {
2078
2147
  const reserveTokens = input.reserveTokens ?? DEFAULT_RESERVE_TOKENS;
@@ -2112,18 +2181,18 @@ async function compact(input) {
2112
2181
  const userText = buildUserText(conversationText, input.instructions, previousContextText);
2113
2182
  const historySummary = await runSummaryStream(input, userText, systemPrompt, maxTokens);
2114
2183
  usage = addCompactionUsage(usage, historySummary.usage);
2115
- if (historySummary.text.length > 0) summaryParts.push(historySummary.text);
2184
+ if (historySummary.text.length === 0) throw new Error("compaction returned an empty history summary");
2185
+ summaryParts.push(historySummary.text);
2116
2186
  }
2117
2187
  if (turnPrefix.length > 0) {
2118
2188
  const conversationText = serializeConversation(turnPrefix);
2119
2189
  const userText = buildTurnPrefixUserText(conversationText, input.instructions, previousContextText);
2120
2190
  const prefixSummary = await runSummaryStream(input, userText, systemPrompt, maxTokens);
2121
2191
  usage = addCompactionUsage(usage, prefixSummary.usage);
2122
- if (prefixSummary.text.length > 0) {
2123
- summaryParts.push(`**Turn Context (split turn):**
2192
+ if (prefixSummary.text.length === 0) throw new Error("compaction returned an empty split-turn summary");
2193
+ summaryParts.push(`**Turn Context (split turn):**
2124
2194
 
2125
2195
  ${prefixSummary.text}`);
2126
- }
2127
2196
  }
2128
2197
  const summary = `${summaryParts.join("\n\n---\n\n").trim()}${formatFileOperations(fileOps)}${formatRecallableRefs(
2129
2198
  input.entries,
@@ -2149,142 +2218,6 @@ function textFromAssistant(message) {
2149
2218
  ).map((c) => c.text).join("\n");
2150
2219
  }
2151
2220
 
2152
- // src/domains/session/decision-board.ts
2153
- init_esm_shims();
2154
- function answeredAtForDecision(policy, sourceQuestion) {
2155
- for (let index = policy.rounds.length - 1; index >= 0; index -= 1) {
2156
- const round = policy.rounds[index];
2157
- if (!round?.answeredAt) continue;
2158
- if (round.answers.some((answer) => answer.question === sourceQuestion)) return round.answeredAt;
2159
- if (round.questions.some((question) => question.question === sourceQuestion)) return round.answeredAt;
2160
- }
2161
- return void 0;
2162
- }
2163
- function finalizedInterviewEntryFields(policy) {
2164
- if (policy.rounds.length === 0 && policy.decisions.length === 0) return null;
2165
- if (!policy.turnId) throw new Error(`decision board: interview ${policy.id} has no originating user turn`);
2166
- if (policy.status !== "complete" && policy.status !== "cancelled") {
2167
- throw new Error(`decision board: interview ${policy.id} finalized with status ${policy.status}`);
2168
- }
2169
- const endedAt = policy.endedAt ?? policy.updatedAt;
2170
- const decisionsByKey = /* @__PURE__ */ new Map();
2171
- for (const decision of policy.decisions) {
2172
- const decidedAt = decision.source_question ? answeredAtForDecision(policy, decision.source_question) ?? endedAt : endedAt;
2173
- decisionsByKey.set(decision.key, {
2174
- key: decision.key,
2175
- value: decision.value,
2176
- ...decision.label ? { label: decision.label } : {},
2177
- ...decision.source_question ? { source_question: decision.source_question } : {},
2178
- status: "active",
2179
- decidedAt
2180
- });
2181
- }
2182
- return {
2183
- kind: "decisionLedger",
2184
- parentTurnId: policy.turnId,
2185
- interviewId: policy.id,
2186
- interviewStatus: policy.status,
2187
- startedAt: policy.startedAt,
2188
- endedAt,
2189
- roundCount: policy.rounds.length,
2190
- ...policy.summary ? { summary: policy.summary } : {},
2191
- ...policy.transcriptPath ? { transcriptPath: policy.transcriptPath } : {},
2192
- exposure: policy.exposure ?? "local",
2193
- decisions: [...decisionsByKey.values()]
2194
- };
2195
- }
2196
- function isDecisionLedgerEntry(value) {
2197
- return !!value && typeof value === "object" && value.kind === "decisionLedger";
2198
- }
2199
- function foldDecisionBoard(entries) {
2200
- const lastByInterview = /* @__PURE__ */ new Map();
2201
- for (let index = 0; index < entries.length; index += 1) {
2202
- const raw = entries[index];
2203
- if (!isDecisionLedgerEntry(raw)) continue;
2204
- lastByInterview.set(raw.interviewId, { entry: raw, index });
2205
- }
2206
- return [...lastByInterview.values()].sort((left, right) => {
2207
- const byEndedAt = right.entry.endedAt.localeCompare(left.entry.endedAt);
2208
- return byEndedAt !== 0 ? byEndedAt : right.index - left.index;
2209
- }).map(({ entry }) => entry);
2210
- }
2211
- function activeLeafFromEntries(entries) {
2212
- for (let index = entries.length - 1; index >= 0; index -= 1) {
2213
- const entry = entries[index];
2214
- if (entry && typeof entry === "object" && entry.kind === "message") {
2215
- const turnId = entry.turnId;
2216
- if (typeof turnId === "string" && turnId.length > 0) return turnId;
2217
- }
2218
- }
2219
- return null;
2220
- }
2221
- function createDecisionBoardStore(deps = {}) {
2222
- let cachedSessionId;
2223
- let dirty = true;
2224
- let interviews = [];
2225
- const syncToSession = () => {
2226
- const sessionId = deps.getSessionId?.() ?? null;
2227
- if (!dirty && sessionId === cachedSessionId) return;
2228
- const entries = deps.readEntries?.() ?? [];
2229
- interviews = foldDecisionBoard(entries);
2230
- cachedSessionId = sessionId;
2231
- dirty = false;
2232
- };
2233
- const append = (entry) => {
2234
- if (!deps.appendEntry) throw new Error("decision board: no session ledger is available");
2235
- deps.appendEntry(entry);
2236
- dirty = true;
2237
- };
2238
- return {
2239
- snapshot() {
2240
- syncToSession();
2241
- return interviews;
2242
- },
2243
- recordFinalizedInterview(policy) {
2244
- const entry = finalizedInterviewEntryFields(policy);
2245
- if (entry === null) return false;
2246
- append(entry);
2247
- return true;
2248
- },
2249
- supersede(interviewId, key, correction) {
2250
- syncToSession();
2251
- const interview = interviews.find((candidate) => candidate.interviewId === interviewId);
2252
- if (!interview) throw new Error(`decision board: interview ${interviewId} was not found on the active branch`);
2253
- const selected = interview.decisions.find((decision) => decision.key === key);
2254
- if (!selected) throw new Error(`decision board: decision ${key} was not found in interview ${interviewId}`);
2255
- const revisedAt = (deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
2256
- const normalizedCorrection = correction?.trim();
2257
- const entries = deps.readEntries?.() ?? [];
2258
- const parentTurnId = deps.getActiveLeafTurnId?.() ?? activeLeafFromEntries(entries);
2259
- if (!parentTurnId) throw new Error("decision board: no active branch leaf is available for the revision");
2260
- const revision = {
2261
- kind: "decisionLedger",
2262
- parentTurnId,
2263
- interviewId: interview.interviewId,
2264
- interviewStatus: interview.interviewStatus,
2265
- startedAt: interview.startedAt,
2266
- endedAt: interview.endedAt,
2267
- roundCount: interview.roundCount,
2268
- ...interview.summary ? { summary: interview.summary } : {},
2269
- ...interview.transcriptPath ? { transcriptPath: interview.transcriptPath } : {},
2270
- ...interview.exposure ? { exposure: interview.exposure } : {},
2271
- decisions: interview.decisions.map((decision) => {
2272
- if (decision.key !== selected.key) return { ...decision };
2273
- const next = { ...decision, status: "superseded", revisedAt };
2274
- if (normalizedCorrection) next.correction = normalizedCorrection;
2275
- else delete next.correction;
2276
- return next;
2277
- })
2278
- };
2279
- append(revision);
2280
- return revision;
2281
- },
2282
- invalidate() {
2283
- dirty = true;
2284
- }
2285
- };
2286
- }
2287
-
2288
2221
  // src/domains/session/protected-artifact-journal.ts
2289
2222
  init_esm_shims();
2290
2223
  import { createHash, randomBytes } from "node:crypto";
@@ -2449,211 +2382,26 @@ function reconcilePendingProtectedArtifacts(session) {
2449
2382
  return pending.records.length;
2450
2383
  }
2451
2384
 
2452
- // src/domains/user-tasks/store.ts
2385
+ // src/domains/user-tasks/active-acceptance.ts
2453
2386
  init_esm_shims();
2454
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
2455
- import { join as join3 } from "node:path";
2456
- var USER_TASKS_FILE_VERSION = 1;
2457
- var USER_TASKS_RELATIVE_PATH = `${CLIO_PROJECT_DIR}/user-tasks.json`;
2458
- var UserTasksStoreError = class extends Error {
2459
- constructor(message, options) {
2460
- super(message, options);
2461
- this.name = "UserTasksStoreError";
2462
- }
2463
- };
2464
- var USER_TASK_STATUSES = ["open", "handed", "picked", "done", "dropped"];
2465
- var FILE_KEYS = /* @__PURE__ */ new Set(["version", "nextId", "tasks"]);
2466
- var TASK_KEYS = /* @__PURE__ */ new Set([
2467
- "id",
2468
- "title",
2469
- "note",
2470
- "status",
2471
- "createdAt",
2472
- "updatedAt",
2473
- "handedSessionId",
2474
- "boardTaskId"
2475
- ]);
2476
- function isRecord2(value) {
2477
- return typeof value === "object" && value !== null && !Array.isArray(value);
2478
- }
2479
- function hasOnlyKeys(value, allowed) {
2480
- return Object.keys(value).every((key) => allowed.has(key));
2481
- }
2482
- function isOptionalString(value) {
2483
- return value === void 0 || typeof value === "string";
2484
- }
2485
- function isUserTask(value) {
2486
- if (!isRecord2(value) || !hasOnlyKeys(value, TASK_KEYS)) return false;
2487
- return typeof value.id === "string" && /^u[1-9]\d*$/.test(value.id) && typeof value.title === "string" && value.title.trim().length > 0 && typeof value.status === "string" && USER_TASK_STATUSES.includes(value.status) && typeof value.createdAt === "string" && typeof value.updatedAt === "string" && isOptionalString(value.note) && isOptionalString(value.handedSessionId) && isOptionalString(value.boardTaskId);
2488
- }
2489
- function parseFile(body, path2) {
2490
- let parsed;
2491
- try {
2492
- parsed = JSON.parse(body);
2493
- } catch (error) {
2494
- throw new UserTasksStoreError(`user tasks file is corrupt JSON: ${path2}`, { cause: error });
2495
- }
2496
- if (!isRecord2(parsed) || !hasOnlyKeys(parsed, FILE_KEYS)) {
2497
- throw new UserTasksStoreError(`user tasks file has an invalid top-level shape: ${path2}`);
2498
- }
2499
- if (parsed.version !== USER_TASKS_FILE_VERSION || !Number.isSafeInteger(parsed.nextId) || parsed.nextId < 1 || !Array.isArray(parsed.tasks) || !parsed.tasks.every(isUserTask)) {
2500
- throw new UserTasksStoreError(`user tasks file failed schema validation: ${path2}`);
2501
- }
2502
- const ids = /* @__PURE__ */ new Set();
2503
- let maxId = 0;
2504
- for (const task of parsed.tasks) {
2505
- if (ids.has(task.id)) throw new UserTasksStoreError(`user tasks file contains duplicate id ${task.id}: ${path2}`);
2506
- ids.add(task.id);
2507
- maxId = Math.max(maxId, Number(task.id.slice(1)));
2508
- }
2509
- if (parsed.nextId <= maxId) {
2510
- throw new UserTasksStoreError(`user tasks file nextId would reuse an existing id: ${path2}`);
2511
- }
2512
- return {
2513
- version: USER_TASKS_FILE_VERSION,
2514
- nextId: parsed.nextId,
2515
- tasks: parsed.tasks.map(copyTask)
2516
- };
2517
- }
2518
- function copyTask(task) {
2519
- return { ...task };
2520
- }
2521
- function initialFile() {
2522
- return { version: USER_TASKS_FILE_VERSION, nextId: 1, tasks: [] };
2523
- }
2524
- function createUserTasksStore(deps) {
2525
- const path2 = join3(deps.cwd, USER_TASKS_RELATIVE_PATH);
2526
- const exists = deps.exists ?? existsSync3;
2527
- const read = deps.read ?? ((target) => readFileSync3(target, "utf8"));
2528
- const write = deps.write ?? ((target, body) => atomicWrite(target, body));
2529
- const now = () => (deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
2530
- const load = () => {
2531
- if (!exists(path2)) return initialFile();
2532
- try {
2533
- return parseFile(read(path2), path2);
2534
- } catch (error) {
2535
- if (error instanceof UserTasksStoreError) throw error;
2536
- throw new UserTasksStoreError(`could not read user tasks file: ${path2}`, { cause: error });
2537
- }
2538
- };
2539
- const save = (file) => {
2540
- try {
2541
- write(path2, `${JSON.stringify(file, null, 2)}
2542
- `);
2543
- } catch (error) {
2544
- throw new UserTasksStoreError(`could not write user tasks file: ${path2}`, { cause: error });
2545
- }
2546
- };
2547
- const mutate = (id, allowed, status, sessionId) => {
2548
- const file = load();
2549
- const index = file.tasks.findIndex((task) => task.id === id);
2550
- const current = file.tasks[index];
2551
- if (!current) throw new UserTasksStoreError(`operator task ${id} was not found`);
2552
- if (!allowed.includes(current.status)) {
2553
- throw new UserTasksStoreError(`operator task ${id} is ${current.status}; it cannot move to ${status}`);
2554
- }
2555
- const updated = { ...current, status, updatedAt: now() };
2556
- if (status === "handed" && sessionId) updated.handedSessionId = sessionId;
2557
- file.tasks[index] = updated;
2558
- save(file);
2559
- return copyTask(updated);
2560
- };
2561
- const recordLink = (id, status, sessionId, boardTaskId) => {
2562
- const file = load();
2563
- const index = file.tasks.findIndex((task) => task.id === id);
2564
- const current = file.tasks[index];
2565
- if (!current) throw new UserTasksStoreError(`operator task ${id} was not found`);
2566
- if (current.status === "done" || current.status === "dropped") {
2567
- throw new UserTasksStoreError(`operator task ${id} is ${current.status}; it cannot move to ${status}`);
2568
- }
2569
- const updated = {
2570
- ...current,
2571
- status,
2572
- updatedAt: now(),
2573
- handedSessionId: sessionId,
2574
- boardTaskId
2575
- };
2576
- file.tasks[index] = updated;
2577
- save(file);
2578
- return copyTask(updated);
2579
- };
2580
- return {
2581
- path: path2,
2582
- snapshot() {
2583
- return load().tasks.map(copyTask);
2584
- },
2585
- get(id) {
2586
- const task = load().tasks.find((candidate) => candidate.id === id);
2587
- return task ? copyTask(task) : null;
2588
- },
2589
- add(title, note) {
2590
- const normalizedTitle = title.trim();
2591
- if (normalizedTitle.length === 0) throw new UserTasksStoreError("operator task title cannot be empty");
2592
- const normalizedNote = note?.trim();
2593
- const file = load();
2594
- const timestamp = now();
2595
- const task = {
2596
- id: `u${file.nextId}`,
2597
- title: normalizedTitle,
2598
- ...normalizedNote ? { note: normalizedNote } : {},
2599
- status: "open",
2600
- createdAt: timestamp,
2601
- updatedAt: timestamp
2602
- };
2603
- file.nextId += 1;
2604
- file.tasks.push(task);
2605
- save(file);
2606
- return copyTask(task);
2607
- },
2608
- hand(id, sessionId) {
2609
- return mutate(id, ["open"], "handed", sessionId);
2610
- },
2611
- done(id) {
2612
- return mutate(id, ["open", "handed", "picked"], "done");
2613
- },
2614
- drop(id) {
2615
- return mutate(id, ["open", "handed", "picked"], "dropped");
2616
- },
2617
- recordPicked(id, sessionId, boardTaskId) {
2618
- return recordLink(id, "picked", sessionId, boardTaskId);
2619
- },
2620
- recordDone(id, sessionId, boardTaskId) {
2621
- return recordLink(id, "done", sessionId, boardTaskId);
2622
- },
2623
- reconcile(links, sessionId) {
2624
- const file = load();
2625
- let changed = false;
2626
- for (const [index, current] of file.tasks.entries()) {
2627
- if (current.status === "done" || current.status === "dropped") continue;
2628
- const candidates = links.filter((link2) => link2.userTaskId === current.id);
2629
- const completed = candidates.find((link2) => link2.status === "completed");
2630
- const open2 = candidates.find((link2) => link2.status === "active" || link2.status === "pending");
2631
- const link = completed ?? open2;
2632
- if (link) {
2633
- const status = completed ? "done" : "picked";
2634
- if (current.status !== status || current.boardTaskId !== link.boardTaskId || current.handedSessionId !== sessionId) {
2635
- file.tasks[index] = {
2636
- ...current,
2637
- status,
2638
- boardTaskId: link.boardTaskId,
2639
- handedSessionId: sessionId,
2640
- updatedAt: now()
2641
- };
2642
- changed = true;
2643
- }
2644
- continue;
2645
- }
2646
- if (current.status === "picked" && current.handedSessionId === sessionId) {
2647
- const repaired = { ...current, status: "handed", updatedAt: now() };
2648
- delete repaired.boardTaskId;
2649
- file.tasks[index] = repaired;
2650
- changed = true;
2651
- }
2652
- }
2653
- if (changed) save(file);
2654
- return file.tasks.map(copyTask);
2655
- }
2656
- };
2387
+ function activeUserTaskAcceptance(tasks, board, sessionId, window) {
2388
+ if (!board || !sessionId) return void 0;
2389
+ const touched = /* @__PURE__ */ new Set();
2390
+ for (const entry of window) {
2391
+ if (!isSessionEntry(entry) || entry.kind !== "message" || entry.role !== "tool_call") continue;
2392
+ if (!entry.payload || typeof entry.payload !== "object") continue;
2393
+ const payload = entry.payload;
2394
+ if ((payload.name ?? payload.toolName) === "tasks" && payload.args?.id && ["done", "block", "drop"].includes(payload.args.action ?? ""))
2395
+ touched.add(payload.args.id);
2396
+ }
2397
+ const linked = new Set(
2398
+ board.tasks.filter((task) => task.status === "pending" || task.status === "active" || touched.has(task.id)).map((task) => task.userTaskId)
2399
+ );
2400
+ const acceptance = tasks.filter((task) => task.handedSessionId === sessionId && linked.has(task.id)).flatMap((task) => task.acceptance ? [task.acceptance] : []);
2401
+ return acceptance.length > 0 ? {
2402
+ expectedOutputs: [...new Set(acceptance.flatMap((item) => item.expectedOutputs))],
2403
+ verification: acceptance.flatMap((item) => item.verification)
2404
+ } : void 0;
2657
2405
  }
2658
2406
 
2659
2407
  // src/engine/acp/server.ts
@@ -2661,11 +2409,11 @@ init_esm_shims();
2661
2409
  import { randomUUID } from "node:crypto";
2662
2410
  import { realpathSync } from "node:fs";
2663
2411
  import { isAbsolute, resolve as resolvePath } from "node:path";
2664
- function isRecord3(value) {
2412
+ function isRecord2(value) {
2665
2413
  return typeof value === "object" && value !== null && !Array.isArray(value);
2666
2414
  }
2667
2415
  function eventRecord(value) {
2668
- return isRecord3(value) ? value : {};
2416
+ return isRecord2(value) ? value : {};
2669
2417
  }
2670
2418
  function textContent(text) {
2671
2419
  return { type: "text", text };
@@ -2713,17 +2461,17 @@ function toolCallContent(text) {
2713
2461
  function contentText(value) {
2714
2462
  if (typeof value === "string") return value;
2715
2463
  if (Array.isArray(value)) return value.map(contentText).filter(Boolean).join("\n");
2716
- if (!isRecord3(value)) return "";
2464
+ if (!isRecord2(value)) return "";
2717
2465
  if (value.type === "text" && typeof value.text === "string") return value.text;
2718
2466
  if (Array.isArray(value.content)) return contentText(value.content);
2719
2467
  if (typeof value.content === "string") return value.content;
2720
2468
  return "";
2721
2469
  }
2722
2470
  function promptText(params) {
2723
- if (!isRecord3(params) || !Array.isArray(params.prompt)) return "";
2471
+ if (!isRecord2(params) || !Array.isArray(params.prompt)) return "";
2724
2472
  const parts = [];
2725
2473
  for (const block of params.prompt) {
2726
- if (!isRecord3(block) || block.type !== "text" || typeof block.text !== "string") continue;
2474
+ if (!isRecord2(block) || block.type !== "text" || typeof block.text !== "string") continue;
2727
2475
  parts.push(block.text);
2728
2476
  }
2729
2477
  return parts.join("\n").trim();
@@ -2798,7 +2546,7 @@ function boundRawValue(value, depth) {
2798
2546
  if (depth >= ACP_MAX_RAW_RECORD_DEPTH) return "[depth]";
2799
2547
  return value.map((entry) => boundRawValue(entry, depth + 1));
2800
2548
  }
2801
- if (isRecord3(value)) {
2549
+ if (isRecord2(value)) {
2802
2550
  if (depth >= ACP_MAX_RAW_RECORD_DEPTH) return "[depth]";
2803
2551
  const bounded = {};
2804
2552
  for (const [key, entry] of Object.entries(value)) bounded[key] = boundRawValue(entry, depth + 1);
@@ -2815,7 +2563,7 @@ function originalRawRecordBytes(value) {
2815
2563
  }
2816
2564
  }
2817
2565
  function boundRawRecord(value) {
2818
- const bounded = isRecord3(value) ? boundRawValue(value, 0) : {};
2566
+ const bounded = isRecord2(value) ? boundRawValue(value, 0) : {};
2819
2567
  let serialized;
2820
2568
  try {
2821
2569
  serialized = JSON.stringify(bounded);
@@ -2830,7 +2578,7 @@ function boundRawRecord(value) {
2830
2578
  var PATH_BEARING_TOOLS = /* @__PURE__ */ new Set(["read", "write", "edit", "ls", "grep", "find"]);
2831
2579
  function toolLocations(toolName, args, cwd) {
2832
2580
  if (toolName === void 0 || !PATH_BEARING_TOOLS.has(toolName)) return null;
2833
- if (!isRecord3(args)) return null;
2581
+ if (!isRecord2(args)) return null;
2834
2582
  const path2 = args.path;
2835
2583
  if (typeof path2 !== "string" || path2.length === 0) return null;
2836
2584
  return [{ path: boundString(resolvePath(cwd, path2), ACP_MAX_LOCATION_PATH_BYTES) }];
@@ -2868,10 +2616,10 @@ function finite(value) {
2868
2616
  }
2869
2617
  function costTotal(usage) {
2870
2618
  const cost = usage.cost;
2871
- return isRecord3(cost) ? finite(cost.total) : 0;
2619
+ return isRecord2(cost) ? finite(cost.total) : 0;
2872
2620
  }
2873
2621
  function mergeUsage(into, usage) {
2874
- if (!isRecord3(usage)) return;
2622
+ if (!isRecord2(usage)) return;
2875
2623
  const input = finite(usage.input) + finite(usage.inputTokens) + finite(usage.input_tokens) + finite(usage.prompt_tokens);
2876
2624
  const output = finite(usage.output) + finite(usage.outputTokens) + finite(usage.output_tokens) + finite(usage.completion_tokens);
2877
2625
  const cacheRead = finite(usage.cacheRead) + finite(usage.cacheReadTokens) + finite(usage.cache_read_tokens);
@@ -2887,7 +2635,7 @@ function mergeUsage(into, usage) {
2887
2635
  into.costUsd += costTotal(usage);
2888
2636
  }
2889
2637
  function mergeMessageUsage(into, message, seen) {
2890
- if (!isRecord3(message)) return;
2638
+ if (!isRecord2(message)) return;
2891
2639
  if (seen) {
2892
2640
  if (seen.has(message)) return;
2893
2641
  seen.add(message);
@@ -2899,13 +2647,13 @@ function mergeMessagesUsage(into, messages, seen) {
2899
2647
  for (const message of messages) mergeMessageUsage(into, message, seen);
2900
2648
  }
2901
2649
  function assistantText2(message) {
2902
- if (!isRecord3(message) || message.role !== "assistant") return "";
2650
+ if (!isRecord2(message) || message.role !== "assistant") return "";
2903
2651
  return contentText(message.content);
2904
2652
  }
2905
2653
  function assistantThinking(message) {
2906
- if (!isRecord3(message) || message.role !== "assistant" || !Array.isArray(message.content)) return "";
2654
+ if (!isRecord2(message) || message.role !== "assistant" || !Array.isArray(message.content)) return "";
2907
2655
  return message.content.map((block) => {
2908
- if (!isRecord3(block)) return "";
2656
+ if (!isRecord2(block)) return "";
2909
2657
  if (block.type === "thinking" && typeof block.thinking === "string") return block.thinking;
2910
2658
  if (block.type === "thinking" && typeof block.text === "string") return block.text;
2911
2659
  return "";
@@ -2932,10 +2680,10 @@ function mapAcpStopReason(raw) {
2932
2680
  }
2933
2681
  }
2934
2682
  function applyStopReason(active, message) {
2935
- const mapped = mapAcpStopReason(isRecord3(message) ? message.stopReason : void 0);
2683
+ const mapped = mapAcpStopReason(isRecord2(message) ? message.stopReason : void 0);
2936
2684
  if (mapped === "error") {
2937
2685
  active.errored = true;
2938
- const explicit = isRecord3(message) && typeof message.errorMessage === "string" ? message.errorMessage : "";
2686
+ const explicit = isRecord2(message) && typeof message.errorMessage === "string" ? message.errorMessage : "";
2939
2687
  const text = explicit.length > 0 ? explicit : assistantText2(message);
2940
2688
  if (text.length > 0) active.errorMessage = text;
2941
2689
  return;
@@ -2945,7 +2693,7 @@ function applyStopReason(active, message) {
2945
2693
  }
2946
2694
  function outputText(value) {
2947
2695
  if (typeof value === "string") return value;
2948
- if (!isRecord3(value)) return "";
2696
+ if (!isRecord2(value)) return "";
2949
2697
  const presentationText = toolResultPresentationText(value);
2950
2698
  if (presentationText !== null) return presentationText;
2951
2699
  if (Array.isArray(value.content)) return contentText(value.content);
@@ -2970,7 +2718,7 @@ function eventString(event, ...keys) {
2970
2718
  function eventTextDelta(event) {
2971
2719
  const direct = eventString(event, "delta", "text");
2972
2720
  if (direct !== void 0) return direct;
2973
- const assistantEvent = isRecord3(event.assistantMessageEvent) ? event.assistantMessageEvent : null;
2721
+ const assistantEvent = isRecord2(event.assistantMessageEvent) ? event.assistantMessageEvent : null;
2974
2722
  if (assistantEvent) {
2975
2723
  const nested = assistantEvent.delta;
2976
2724
  if (typeof nested === "string") return nested;
@@ -3025,8 +2773,8 @@ function endToolCallId(active, engineId) {
3025
2773
  if (engineId === void 0 || engineId.length === 0) {
3026
2774
  return newestOpenToolCallId(active) ?? active.lastEmittedToolCallId;
3027
2775
  }
3028
- const open2 = openWireIdFor(active, engineId);
3029
- if (open2 !== null) return open2;
2776
+ const open3 = openWireIdFor(active, engineId);
2777
+ if (open3 !== null) return open3;
3030
2778
  const wireIds = active.toolCallWireIds.get(engineId);
3031
2779
  if (wireIds === void 0) return null;
3032
2780
  return wireIds[wireIds.length - 1] ?? null;
@@ -3077,7 +2825,7 @@ function handleChatEvent(rawEvent, transport, sessionId, active, cwd, diagnostic
3077
2825
  return;
3078
2826
  }
3079
2827
  if (event.type === "notice") {
3080
- const admission = isRecord3(event.admission) ? event.admission : null;
2828
+ const admission = isRecord2(event.admission) ? event.admission : null;
3081
2829
  const reason = admission !== null && typeof admission.reason === "string" ? admission.reason : "";
3082
2830
  if (reason.length > 0 && active.admissionReason === void 0) active.admissionReason = admissionReason(reason);
3083
2831
  return;
@@ -3165,7 +2913,7 @@ function handleChatEvent(rawEvent, transport, sessionId, active, cwd, diagnostic
3165
2913
  active.sawTurnEnd = true;
3166
2914
  mergeMessagesUsage(active.usage, event.messages, active.usageMessages);
3167
2915
  const messages = Array.isArray(event.messages) ? event.messages : [];
3168
- const last = [...messages].reverse().find((message) => isRecord3(message) && message.role === "assistant");
2916
+ const last = [...messages].reverse().find((message) => isRecord2(message) && message.role === "assistant");
3169
2917
  if (last !== void 0) applyStopReason(active, last);
3170
2918
  return;
3171
2919
  }
@@ -3225,7 +2973,7 @@ function safeIso(value) {
3225
2973
  return (/* @__PURE__ */ new Date(0)).toISOString();
3226
2974
  }
3227
2975
  function payloadRecord(payload) {
3228
- return isRecord3(payload) ? payload : null;
2976
+ return isRecord2(payload) ? payload : null;
3229
2977
  }
3230
2978
  function replayTextBlocks(entry) {
3231
2979
  const text = [];
@@ -3237,7 +2985,7 @@ function replayTextBlocks(entry) {
3237
2985
  if (!Array.isArray(payload.content)) return { text, thinking };
3238
2986
  if (payload.content.length > 0) text.length = 0;
3239
2987
  for (const block of payload.content) {
3240
- if (!isRecord3(block)) continue;
2988
+ if (!isRecord2(block)) continue;
3241
2989
  if (block.type === "text" && typeof block.text === "string") text.push(block.text);
3242
2990
  if (block.type === "thinking") {
3243
2991
  if (typeof block.thinking === "string") thinking.push(block.thinking);
@@ -3579,6 +3327,15 @@ function installPermissionBridge(input) {
3579
3327
  }
3580
3328
  if (outcome.kind === "response") {
3581
3329
  const answer = outcome.response.outcome;
3330
+ if (answer.outcome === "cancelled") {
3331
+ const reason = "ACP client cancelled permission";
3332
+ input.cancelActivePrompt(reason);
3333
+ emitResolution({ status: "denied", decidedBy: "cancelled", reason });
3334
+ queuedRequestIds.clear();
3335
+ queuedRequestDetails.clear();
3336
+ input.toolRegistry?.cancelParkedCalls(reason);
3337
+ return;
3338
+ }
3582
3339
  if (answer.outcome === "selected" && answer.optionId === "allow-once") {
3583
3340
  emitResolution({ status: "granted", decidedBy: "acp-client" });
3584
3341
  await input.toolRegistry?.resumeParkedCalls({
@@ -3671,6 +3428,10 @@ async function serveClioAcpAgent(options) {
3671
3428
  if (activePromptState === null) return;
3672
3429
  activePromptState.permissionExpired = true;
3673
3430
  options.chat.cancel();
3431
+ },
3432
+ cancelActivePrompt: (reason) => {
3433
+ const session = activeSessionId === null ? void 0 : sessions.get(activeSessionId);
3434
+ if (session) cancelSession(session, reason);
3674
3435
  }
3675
3436
  });
3676
3437
  const forwardEvent = (kind, turnId, terminal, payload) => {
@@ -3869,14 +3630,14 @@ async function serveClioAcpAgent(options) {
3869
3630
  };
3870
3631
  const sessionIdOf = (params) => {
3871
3632
  return requireBoundedClientString(
3872
- isRecord3(params) ? params.sessionId : void 0,
3633
+ isRecord2(params) ? params.sessionId : void 0,
3873
3634
  "sessionId",
3874
3635
  ACP_MAX_SESSION_ID_BYTES
3875
3636
  );
3876
3637
  };
3877
3638
  const assertParamKeys = (params, allowed) => {
3878
3639
  if (params === void 0) return {};
3879
- if (!isRecord3(params) || Object.keys(params).some((key) => !allowed.has(key))) {
3640
+ if (!isRecord2(params) || Object.keys(params).some((key) => !allowed.has(key))) {
3880
3641
  throw new AcpRequestError(-32602, "invalid method parameters", { code: "invalid_params" });
3881
3642
  }
3882
3643
  return params;
@@ -3926,16 +3687,16 @@ async function serveClioAcpAgent(options) {
3926
3687
  };
3927
3688
  options.transport.onRequest("initialize", (params) => {
3928
3689
  if (initialized) throw new AcpRequestError(-32e3, "already initialized", { code: "already_initialized" });
3929
- const version = isRecord3(params) ? params.protocolVersion : void 0;
3690
+ const version = isRecord2(params) ? params.protocolVersion : void 0;
3930
3691
  if (version !== 1) {
3931
3692
  throw new AcpRequestError(-32602, "unsupported ACP protocol version", {
3932
3693
  code: "protocol_version_unsupported",
3933
3694
  supported: [1]
3934
3695
  });
3935
3696
  }
3936
- const clientCapabilities = isRecord3(params) && isRecord3(params.clientCapabilities) ? params.clientCapabilities : null;
3937
- const clientMeta = clientCapabilities !== null && isRecord3(clientCapabilities._meta) ? clientCapabilities._meta : null;
3938
- const eventRequest = clientMeta !== null && isRecord3(clientMeta["clio-coder/events"]) ? clientMeta["clio-coder/events"] : null;
3697
+ const clientCapabilities = isRecord2(params) && isRecord2(params.clientCapabilities) ? params.clientCapabilities : null;
3698
+ const clientMeta = clientCapabilities !== null && isRecord2(clientCapabilities._meta) ? clientCapabilities._meta : null;
3699
+ const eventRequest = clientMeta !== null && isRecord2(clientMeta["clio-coder/events"]) ? clientMeta["clio-coder/events"] : null;
3939
3700
  const requestedEventKinds = eventRequest !== null ? eventRequest.kinds : null;
3940
3701
  enabledEventKinds.clear();
3941
3702
  if (eventRequest !== null && eventRequest.version === 1 && Array.isArray(requestedEventKinds) && requestedEventKinds.length <= ACP_MAX_REQUESTED_EVENT_KINDS && requestedEventKinds.every((kind) => typeof kind === "string" && utf8Bytes(kind) <= 64 && !hasControlCharacters(kind))) {
@@ -4007,7 +3768,7 @@ async function serveClioAcpAgent(options) {
4007
3768
  if (sessionCreated) {
4008
3769
  throw new AcpRequestError(-32e3, "this server hosts one session per process", { code: "session_limit" });
4009
3770
  }
4010
- const sessionCwd = canonicalSessionCwd(isRecord3(params) ? params.cwd : void 0);
3771
+ const sessionCwd = canonicalSessionCwd(isRecord2(params) ? params.cwd : void 0);
4011
3772
  const route = routingSnapshot();
4012
3773
  const createInput = { cwd: sessionCwd };
4013
3774
  if (route.target !== null) createInput.target = route.target;
@@ -4017,6 +3778,7 @@ async function serveClioAcpAgent(options) {
4017
3778
  if (safeStoredIdentifier(id, ACP_MAX_SESSION_ID_BYTES) === null) {
4018
3779
  throw new AcpRequestError(-32e3, "session creation failed", { code: "internal_error" });
4019
3780
  }
3781
+ options.chat.resetForSession?.(null);
4020
3782
  const autonomy = options.autonomy?.() ?? DEFAULT_AUTONOMY_LEVEL;
4021
3783
  const boundTarget = safeConfiguredIdentifier(meta?.target ?? route.target, ACP_MAX_TARGET_ID_BYTES);
4022
3784
  const boundModel = safeConfiguredIdentifier(meta?.model ?? route.model, ACP_MAX_MODEL_ID_BYTES);
@@ -4206,7 +3968,7 @@ async function serveClioAcpAgent(options) {
4206
3968
  options.transport.onRequest("clio-coder/settings/patch_safe", (params) => {
4207
3969
  requireInitialized();
4208
3970
  const request = assertParamKeys(params, /* @__PURE__ */ new Set(["patch"]));
4209
- if (!isRecord3(request.patch)) {
3971
+ if (!isRecord2(request.patch)) {
4210
3972
  throw new AcpRequestError(-32602, "patch must be an object", { code: "invalid_params" });
4211
3973
  }
4212
3974
  if (activePromptState !== null) {
@@ -4340,7 +4102,7 @@ async function serveClioAcpAgent(options) {
4340
4102
  options.transport.onRequest("session/cancel", cancel);
4341
4103
  options.transport.onNotification("session/cancel", (params) => {
4342
4104
  if (!initialized) return;
4343
- const id = isRecord3(params) && typeof params.sessionId === "string" ? params.sessionId : null;
4105
+ const id = isRecord2(params) && typeof params.sessionId === "string" ? params.sessionId : null;
4344
4106
  const session = id === null ? void 0 : sessions.get(id);
4345
4107
  if (session) cancelSession(session, "prompt cancelled");
4346
4108
  });
@@ -4357,6 +4119,7 @@ async function serveClioAcpAgent(options) {
4357
4119
  if (options.session?.current()?.id === session.id) await options.session.close();
4358
4120
  sessions.delete(session.id);
4359
4121
  if (boundSessionId === session.id) boundSessionId = null;
4122
+ sessionCreated = false;
4360
4123
  closedSessionIds.add(session.id);
4361
4124
  return {};
4362
4125
  });
@@ -4429,7 +4192,7 @@ async function serveClioAcpAgent(options) {
4429
4192
  }
4430
4193
  return promptResponse(active.stopReason, active);
4431
4194
  });
4432
- return await new Promise((resolve8) => {
4195
+ return await new Promise((resolve9) => {
4433
4196
  options.transport.onClose(() => {
4434
4197
  permission.unregister();
4435
4198
  unsubscribeEventStream();
@@ -4437,14 +4200,14 @@ async function serveClioAcpAgent(options) {
4437
4200
  for (const session of sessions.values()) cancelSession(session, "ACP transport closed");
4438
4201
  const inFlight = promptSettled;
4439
4202
  if (inFlight === null) {
4440
- resolve8(0);
4203
+ resolve9(0);
4441
4204
  return;
4442
4205
  }
4443
- const timer = setTimeout(() => resolve8(0), ACP_PROMPT_SETTLE_BOUND_MS);
4206
+ const timer = setTimeout(() => resolve9(0), ACP_PROMPT_SETTLE_BOUND_MS);
4444
4207
  timer.unref?.();
4445
4208
  void inFlight.then(() => {
4446
4209
  clearTimeout(timer);
4447
- resolve8(0);
4210
+ resolve9(0);
4448
4211
  });
4449
4212
  });
4450
4213
  });
@@ -4641,7 +4404,7 @@ var HANDOFF_RESPONSE_SCHEMA = {
4641
4404
  openQuestions: { type: "array", items: { type: "string" } }
4642
4405
  }
4643
4406
  };
4644
- function isRecord4(value) {
4407
+ function isRecord3(value) {
4645
4408
  return typeof value === "object" && value !== null && !Array.isArray(value);
4646
4409
  }
4647
4410
  function boundHandoffString(value) {
@@ -4664,7 +4427,7 @@ function stringsFrom(value) {
4664
4427
  }
4665
4428
  function recordsFrom(value) {
4666
4429
  if (!Array.isArray(value)) return [];
4667
- return value.filter(isRecord4);
4430
+ return value.filter(isRecord3);
4668
4431
  }
4669
4432
  function requiredField(record2, key) {
4670
4433
  const value = record2[key];
@@ -4706,7 +4469,7 @@ function parseHandoffExtraction(text) {
4706
4469
  } catch (error) {
4707
4470
  return { ok: false, reason: `the extraction round returned invalid JSON: ${error.message}` };
4708
4471
  }
4709
- if (!isRecord4(parsed)) return { ok: false, reason: "the extraction round returned a non-object" };
4472
+ if (!isRecord3(parsed)) return { ok: false, reason: "the extraction round returned a non-object" };
4710
4473
  const truncations = [];
4711
4474
  let stringsCut = 0;
4712
4475
  const bound = (value) => {
@@ -4781,7 +4544,7 @@ function stringField(record2, ...keys) {
4781
4544
  }
4782
4545
  function pathFromCall(toolName, args, cwd, into) {
4783
4546
  if (!READ_LEDGER_TOOLS.has(toolName)) return;
4784
- const record2 = isRecord4(args) ? args : null;
4547
+ const record2 = isRecord3(args) ? args : null;
4785
4548
  const named = stringField(record2, "path", "file_path", "filePath");
4786
4549
  const raw = named ?? (toolName === "grep" || toolName === "find" || toolName === "ls" ? "." : null);
4787
4550
  if (raw === null) return;
@@ -4799,7 +4562,7 @@ function buildHandoffReadLedger(entries, options = {}) {
4799
4562
  continue;
4800
4563
  }
4801
4564
  if (entry.kind !== "message") continue;
4802
- const payload = isRecord4(entry.payload) ? entry.payload : null;
4565
+ const payload = isRecord3(entry.payload) ? entry.payload : null;
4803
4566
  if (payload === null) continue;
4804
4567
  if (entry.role === "tool_call") {
4805
4568
  const name = stringField(payload, "name", "toolName", "tool");
@@ -4808,7 +4571,7 @@ function buildHandoffReadLedger(entries, options = {}) {
4808
4571
  }
4809
4572
  if (entry.role !== "assistant" || !Array.isArray(payload.content)) continue;
4810
4573
  for (const block of payload.content) {
4811
- if (!isRecord4(block) || block.type !== "toolCall") continue;
4574
+ if (!isRecord3(block) || block.type !== "toolCall") continue;
4812
4575
  const name = stringField(block, "name", "toolName");
4813
4576
  if (name !== null) pathFromCall(name, block.arguments ?? block.args ?? block.input, cwd, paths);
4814
4577
  }
@@ -4836,7 +4599,7 @@ function mergeHandoffDecisions(extracted, board) {
4836
4599
  if (decision.status !== "active") continue;
4837
4600
  const name = decision.label ?? decision.key;
4838
4601
  const summary = boundHandoffString(`${name}: ${decision.value}`).text;
4839
- const rationale = decision.source_question ?? decision.correction;
4602
+ const rationale = decisionRationale(decision);
4840
4603
  settled.push({
4841
4604
  summary,
4842
4605
  ...rationale ? { rationale: boundHandoffString(rationale).text } : {},
@@ -4924,10 +4687,10 @@ function handoffSeedContextText(data) {
4924
4687
  ].join("\n");
4925
4688
  }
4926
4689
  function isHandoffSeedData(value) {
4927
- return isRecord4(value) && typeof value.fromSessionId === "string" && typeof value.goal === "string" && typeof value.document === "string";
4690
+ return isRecord3(value) && typeof value.fromSessionId === "string" && typeof value.goal === "string" && typeof value.document === "string";
4928
4691
  }
4929
4692
  function isHandoffNoteData(value) {
4930
- return isRecord4(value) && typeof value.toSessionId === "string" && typeof value.goal === "string";
4693
+ return isRecord3(value) && typeof value.toSessionId === "string" && typeof value.goal === "string";
4931
4694
  }
4932
4695
 
4933
4696
  // src/interactive/side-question.ts
@@ -5080,7 +4843,7 @@ init_esm_shims();
5080
4843
 
5081
4844
  // src/domains/session/compaction/mask-observations.ts
5082
4845
  init_esm_shims();
5083
- function isRecord5(value) {
4846
+ function isRecord4(value) {
5084
4847
  return !!value && typeof value === "object" && !Array.isArray(value);
5085
4848
  }
5086
4849
  function cloneEntry(entry) {
@@ -5090,7 +4853,7 @@ function textFromContent(content) {
5090
4853
  if (!Array.isArray(content)) return "";
5091
4854
  const parts = [];
5092
4855
  for (const block of content) {
5093
- if (!isRecord5(block)) continue;
4856
+ if (!isRecord4(block)) continue;
5094
4857
  if (block.type === "text" && typeof block.text === "string") parts.push(block.text);
5095
4858
  }
5096
4859
  return parts.join("");
@@ -5109,7 +4872,7 @@ function stringifyPreview2(value, limit = 1e4) {
5109
4872
  }
5110
4873
  function resultText(result) {
5111
4874
  if (typeof result === "string") return result;
5112
- if (!isRecord5(result)) return stringifyPreview2(result);
4875
+ if (!isRecord4(result)) return stringifyPreview2(result);
5113
4876
  const contentText2 = textFromContent(result.content);
5114
4877
  if (contentText2.length > 0) return contentText2;
5115
4878
  if (typeof result.text === "string") return result.text;
@@ -5118,7 +4881,7 @@ function resultText(result) {
5118
4881
  return stringifyPreview2(result);
5119
4882
  }
5120
4883
  function extractToolResultPayload(payload) {
5121
- const obj = isRecord5(payload) ? payload : { result: payload };
4884
+ const obj = isRecord4(payload) ? payload : { result: payload };
5122
4885
  const result = obj.result ?? obj.output ?? obj.out ?? obj.content ?? payload;
5123
4886
  const toolName = typeof obj.toolName === "string" && obj.toolName || typeof obj.name === "string" && obj.name || typeof obj.tool === "string" && obj.tool || "tool";
5124
4887
  return { obj, result, toolName };
@@ -5133,7 +4896,7 @@ function observationMarker(toolName, text) {
5133
4896
  return `[Observation masked: ${toolName} output was ${lineCount(text)} lines, ${text.length} chars - contents masked to save context. Re-run the tool for current content.]${suffix}`;
5134
4897
  }
5135
4898
  function maskedToolResult(original, marker) {
5136
- const details = isRecord5(original) && isRecord5(original.details) ? { ...original.details } : {};
4899
+ const details = isRecord4(original) && isRecord4(original.details) ? { ...original.details } : {};
5137
4900
  return {
5138
4901
  content: [{ type: "text", text: marker }],
5139
4902
  details: {
@@ -5143,12 +4906,12 @@ function maskedToolResult(original, marker) {
5143
4906
  };
5144
4907
  }
5145
4908
  function alreadyCompacted(payload) {
5146
- if (!isRecord5(payload)) return false;
5147
- if (isRecord5(payload.contextCompaction)) return true;
4909
+ if (!isRecord4(payload)) return false;
4910
+ if (isRecord4(payload.contextCompaction)) return true;
5148
4911
  const summary = payload.resultSummary;
5149
- if (isRecord5(summary) && isRecord5(summary.contextCompaction)) return true;
4912
+ if (isRecord4(summary) && isRecord4(summary.contextCompaction)) return true;
5150
4913
  const result = payload.result ?? payload.output ?? payload.out;
5151
- if (isRecord5(result) && isRecord5(result.details) && isRecord5(result.details.contextCompaction)) return true;
4914
+ if (isRecord4(result) && isRecord4(result.details) && isRecord4(result.details.contextCompaction)) return true;
5152
4915
  return false;
5153
4916
  }
5154
4917
  function maskObservation(entry) {
@@ -5163,7 +4926,7 @@ function maskObservation(entry) {
5163
4926
  out: void 0,
5164
4927
  content: void 0,
5165
4928
  resultSummary: {
5166
- ...isRecord5(obj.resultSummary) ? obj.resultSummary : {},
4929
+ ...isRecord4(obj.resultSummary) ? obj.resultSummary : {},
5167
4930
  bytes: 0,
5168
4931
  truncated: true,
5169
4932
  contextCompaction: {
@@ -5177,14 +4940,14 @@ function maskObservation(entry) {
5177
4940
  return next;
5178
4941
  }
5179
4942
  function maskThinking(entry) {
5180
- const obj = isRecord5(entry.payload) ? entry.payload : null;
4943
+ const obj = isRecord4(entry.payload) ? entry.payload : null;
5181
4944
  if (!obj) return null;
5182
4945
  let blocks = 0;
5183
4946
  let chars = 0;
5184
4947
  let content;
5185
4948
  if (Array.isArray(obj.content)) {
5186
4949
  content = obj.content.filter((block) => {
5187
- if (!isRecord5(block) || block.type !== "thinking") return true;
4950
+ if (!isRecord4(block) || block.type !== "thinking") return true;
5188
4951
  blocks += 1;
5189
4952
  if (typeof block.thinking === "string") chars += block.thinking.length;
5190
4953
  return false;
@@ -5201,7 +4964,7 @@ function maskThinking(entry) {
5201
4964
  ...content !== void 0 ? { content } : {},
5202
4965
  thinking: void 0,
5203
4966
  contextCompaction: {
5204
- ...isRecord5(obj.contextCompaction) ? obj.contextCompaction : {},
4967
+ ...isRecord4(obj.contextCompaction) ? obj.contextCompaction : {},
5205
4968
  stage: "mask_thinking",
5206
4969
  maskedThinkingChars: chars,
5207
4970
  at: (/* @__PURE__ */ new Date()).toISOString()
@@ -5226,7 +4989,7 @@ function recentTurnCutoff(entries, excludeLastTurns) {
5226
4989
  }
5227
4990
  function invalidateUsage(entry) {
5228
4991
  if (entry.kind !== "message" || entry.role !== "assistant") return entry;
5229
- const obj = isRecord5(entry.payload) ? entry.payload : null;
4992
+ const obj = isRecord4(entry.payload) ? entry.payload : null;
5230
4993
  if (!obj || obj.contextUsageInvalidated === true) return entry;
5231
4994
  const next = cloneEntry(entry);
5232
4995
  next.payload = {
@@ -5274,8 +5037,8 @@ function maskStaleObservations(entries, excludeLastTurns) {
5274
5037
 
5275
5038
  // src/domains/session/prompt-manifest.ts
5276
5039
  init_esm_shims();
5277
- import { appendFileSync, existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
5278
- import { dirname, join as join4 } from "node:path";
5040
+ import { appendFileSync, existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
5041
+ import { dirname, join as join3 } from "node:path";
5279
5042
  var PROMPT_MANIFEST_VERSION = 2;
5280
5043
  var SHA256_HEX = /^[a-f0-9]{64}$/;
5281
5044
  function isCanonicalUtcTimestamp(value) {
@@ -5283,7 +5046,7 @@ function isCanonicalUtcTimestamp(value) {
5283
5046
  const timestamp = Date.parse(value);
5284
5047
  return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value;
5285
5048
  }
5286
- function isRecord6(value) {
5049
+ function isRecord5(value) {
5287
5050
  return value !== null && typeof value === "object" && !Array.isArray(value);
5288
5051
  }
5289
5052
  function isNonNegativeInteger(value) {
@@ -5293,20 +5056,20 @@ function isSha256(value) {
5293
5056
  return typeof value === "string" && SHA256_HEX.test(value);
5294
5057
  }
5295
5058
  function isPromptManifestSection(value) {
5296
- return isRecord6(value) && typeof value.id === "string" && isNonNegativeInteger(value.tokenEstimate);
5059
+ return isRecord5(value) && typeof value.id === "string" && isNonNegativeInteger(value.tokenEstimate);
5297
5060
  }
5298
5061
  function isPromptManifestFragment(value) {
5299
- return isRecord6(value) && typeof value.id === "string" && typeof value.relPath === "string" && isSha256(value.contentHash) && typeof value.dynamic === "boolean";
5062
+ return isRecord5(value) && typeof value.id === "string" && typeof value.relPath === "string" && isSha256(value.contentHash) && typeof value.dynamic === "boolean";
5300
5063
  }
5301
5064
  function isProjectPreloadClass(value) {
5302
- if (!isRecord6(value)) return false;
5065
+ if (!isRecord5(value)) return false;
5303
5066
  return (value.mode === "full" || value.mode === "synopsis" || value.mode === "none") && isNonNegativeInteger(value.chars) && isNonNegativeInteger(value.lines) && (value.reason === null || value.reason === "size" || value.reason === "lines" || value.reason === "no-clio-md") && typeof value.nearLimit === "boolean" && typeof value.label === "string";
5304
5067
  }
5305
5068
  function isOptional(value, guard) {
5306
5069
  return value === void 0 || guard(value);
5307
5070
  }
5308
5071
  function isSessionPromptCompileRecord(value) {
5309
- if (!isRecord6(value)) return false;
5072
+ if (!isRecord5(value)) return false;
5310
5073
  return isOptional(value.version, isNonNegativeInteger) && isOptional(
5311
5074
  value.contextWindow,
5312
5075
  (candidate) => candidate === null ? true : isNonNegativeInteger(candidate)
@@ -5321,10 +5084,10 @@ function getPromptManifestFilePath(meta, stateDir) {
5321
5084
  cwdHash: meta.cwdHash || cwdHash(meta.cwd || process.cwd())
5322
5085
  };
5323
5086
  if (stateDir !== void 0) {
5324
- return join4(stateDir, "sessions", safeMeta.cwdHash, safeMeta.id, "prompt-manifest.jsonl");
5087
+ return join3(stateDir, "sessions", safeMeta.cwdHash, safeMeta.id, "prompt-manifest.jsonl");
5325
5088
  }
5326
5089
  const paths = sessionPaths(safeMeta);
5327
- return join4(dirname(paths.current), "prompt-manifest.jsonl");
5090
+ return join3(dirname(paths.current), "prompt-manifest.jsonl");
5328
5091
  }
5329
5092
  function appendPromptCompileRecord(meta, record2) {
5330
5093
  try {
@@ -5337,10 +5100,10 @@ function appendPromptCompileRecord(meta, record2) {
5337
5100
  function readPromptCompileManifest(meta, stateDir) {
5338
5101
  const file = getPromptManifestFilePath(meta, stateDir);
5339
5102
  try {
5340
- if (!existsSync4(file)) return { records: [], errors: [] };
5103
+ if (!existsSync3(file)) return { records: [], errors: [] };
5341
5104
  const records = [];
5342
5105
  const errors = [];
5343
- for (const [index, line] of readFileSync4(file, "utf8").split("\n").entries()) {
5106
+ for (const [index, line] of readFileSync3(file, "utf8").split("\n").entries()) {
5344
5107
  if (line.trim().length === 0) continue;
5345
5108
  try {
5346
5109
  const parsed = JSON.parse(line);
@@ -5370,7 +5133,7 @@ init_esm_shims();
5370
5133
 
5371
5134
  // src/interactive/chat-renderer.ts
5372
5135
  init_esm_shims();
5373
- import { existsSync as existsSync6 } from "node:fs";
5136
+ import { existsSync as existsSync5 } from "node:fs";
5374
5137
 
5375
5138
  // src/engine/messages.ts
5376
5139
  init_esm_shims();
@@ -5495,7 +5258,7 @@ init_esm_shims();
5495
5258
  // src/interactive/mutation-preview.ts
5496
5259
  init_esm_shims();
5497
5260
  import { createHash as createHash2 } from "node:crypto";
5498
- import { readFileSync as readFileSync5 } from "node:fs";
5261
+ import { readFileSync as readFileSync4 } from "node:fs";
5499
5262
  var MUTATION_PREVIEW_VISIBLE_ROWS = 16;
5500
5263
  var MUTATION_PREVIEW_MAX_CHARS = 262144;
5501
5264
  function canonicalJson(value) {
@@ -5610,7 +5373,7 @@ function editPreview(facts, path2, edits, read) {
5610
5373
  }
5611
5374
  }
5612
5375
  function createMutationInspector(tool, args, facts, options = {}) {
5613
- const read = options.readFile ?? ((path2) => readFileSync5(path2, "utf8"));
5376
+ const read = options.readFile ?? ((path2) => readFileSync4(path2, "utf8"));
5614
5377
  return () => {
5615
5378
  const current = mutationFacts(tool, args);
5616
5379
  if (current === null || current.digest !== facts.digest) {
@@ -7159,19 +6922,19 @@ function toggledFold(effective) {
7159
6922
 
7160
6923
  // src/interactive/worker-receipts.ts
7161
6924
  init_esm_shims();
7162
- import { existsSync as existsSync5, readFileSync as readFileSync7 } from "node:fs";
7163
- import { join as join6 } from "node:path";
6925
+ import { existsSync as existsSync4, readFileSync as readFileSync6 } from "node:fs";
6926
+ import { join as join5 } from "node:path";
7164
6927
 
7165
6928
  // src/interactive/view/artifacts.ts
7166
6929
  init_esm_shims();
7167
- import { createReadStream, readFileSync as readFileSync6, statSync } from "node:fs";
6930
+ import { createReadStream, readFileSync as readFileSync5, statSync } from "node:fs";
7168
6931
  import { readFile, realpath, stat } from "node:fs/promises";
7169
- import { basename, isAbsolute as isAbsolute4, join as join5, relative as relative4, resolve as resolve3, sep } from "node:path";
6932
+ import { basename, isAbsolute as isAbsolute4, join as join4, relative as relative4, resolve as resolve3, sep } from "node:path";
7170
6933
 
7171
6934
  // src/domains/session/session-artifacts.ts
7172
6935
  init_esm_shims();
7173
6936
  import { isAbsolute as isAbsolute3, relative as relative2, resolve as resolve2 } from "node:path";
7174
- function isRecord7(value) {
6937
+ function isRecord6(value) {
7175
6938
  return !!value && typeof value === "object" && !Array.isArray(value);
7176
6939
  }
7177
6940
  function isSessionArtifactTool(value) {
@@ -7193,15 +6956,15 @@ function foldSessionArtifacts(entries, options = {}) {
7193
6956
  const writeCounts = /* @__PURE__ */ new Map();
7194
6957
  let writeIndex = 0;
7195
6958
  for (const raw of entries) {
7196
- if (!isRecord7(raw) || raw.kind !== "message" || raw.role !== "tool_result") continue;
6959
+ if (!isRecord6(raw) || raw.kind !== "message" || raw.role !== "tool_result") continue;
7197
6960
  if (typeof raw.turnId !== "string" || typeof raw.timestamp !== "string") continue;
7198
6961
  const payload = raw.payload;
7199
- if (!isRecord7(payload) || !isSessionArtifactTool(payload.toolName)) continue;
6962
+ if (!isRecord6(payload) || !isSessionArtifactTool(payload.toolName)) continue;
7200
6963
  if (payload.isError === true || payload.outcome === "error" || payload.outcome === "blocked" || payload.outcome === "aborted" || payload.outcome === "orphaned") {
7201
6964
  continue;
7202
6965
  }
7203
6966
  const result = payload.result;
7204
- if (!isRecord7(result) || !isRecord7(result.details) || !Array.isArray(result.details.paths)) continue;
6967
+ if (!isRecord6(result) || !isRecord6(result.details) || !Array.isArray(result.details.paths)) continue;
7205
6968
  const artifactKind = payload.toolName === "artifact" && isSessionArtifactKind(result.details.kind) ? result.details.kind : void 0;
7206
6969
  const pathsSeenInResult = /* @__PURE__ */ new Set();
7207
6970
  for (const recordedPath of result.details.paths) {
@@ -7365,7 +7128,6 @@ function formatWorkerContextMeter(usedTokens, contextWindow, theme6 = clioTheme(
7365
7128
 
7366
7129
  // src/interactive/dispatch-board.ts
7367
7130
  init_esm_shims();
7368
- import { performance as performance3 } from "node:perf_hooks";
7369
7131
 
7370
7132
  // src/interactive/council-grid.ts
7371
7133
  init_esm_shims();
@@ -7664,7 +7426,6 @@ function isDispatchBoardRowSteerable(row2) {
7664
7426
  function isDispatchBoardRowCancellable(row2) {
7665
7427
  return row2.status === "running" || row2.status === "stale" || row2.status === "enqueued" || row2.status === "retrying";
7666
7428
  }
7667
- var TASK_SUMMARY_MAX_WIDTH = 240;
7668
7429
  var WORKER_PROGRESS_CARD_ROWS = 6;
7669
7430
  var TASK_ISLAND_WIDTH = 44;
7670
7431
  var STATUS_ORDER = {
@@ -7678,7 +7439,6 @@ var STATUS_ORDER = {
7678
7439
  aborted: 7,
7679
7440
  completed: 8
7680
7441
  };
7681
- var MAX_DISPATCH_BOARD_ROWS = 50;
7682
7442
  function agentDisplayLabel(row2) {
7683
7443
  return row2.agentId;
7684
7444
  }
@@ -7788,12 +7548,6 @@ function evidenceCardLine(theme6, evidence, contentWidth) {
7788
7548
  units.push(theme6.fg("dim", evidence.viewFilter));
7789
7549
  return cardUnitsLine(theme6, "proof", units, contentWidth);
7790
7550
  }
7791
- function sanitizeDispatchTaskSummary(value) {
7792
- if (typeof value !== "string") return void 0;
7793
- const sanitized = sanitizeCallTargetText(value);
7794
- if (sanitized.length === 0) return void 0;
7795
- return sanitizeCallTargetText(truncateToWidth(sanitized, TASK_SUMMARY_MAX_WIDTH, "\u2026", false));
7796
- }
7797
7551
  function retryCountdown(retry, now = Date.now()) {
7798
7552
  const remainingMs = Math.max(0, retry.dueAtMs - now);
7799
7553
  return remainingMs === 0 ? "now" : `in ${formatCompactMs(remainingMs)}`;
@@ -8226,68 +7980,6 @@ function formatTaskIslandLines(rows, maxRows = 4) {
8226
7980
  }
8227
7981
  return frame(clioTheme(), "Fleet runs", body, TASK_ISLAND_WIDTH + 4);
8228
7982
  }
8229
- function parseRunId(value) {
8230
- return typeof value === "string" && value.length > 0 ? value : null;
8231
- }
8232
- function parseText(value, fallback) {
8233
- return typeof value === "string" && value.length > 0 ? value : fallback;
8234
- }
8235
- function parseRuntimeKind(value) {
8236
- if (value === "sdk" || value === "subprocess" || value === "acp-delegation") return value;
8237
- return "http";
8238
- }
8239
- function parseAgentAudience(value, fallback) {
8240
- if (value === "base" || value === "shadow" || value === "custom" || value === "internal") return value;
8241
- return fallback;
8242
- }
8243
- function parseRequestOrigin(value, fallback) {
8244
- if (value === "user" || value === "agent" || value === "internal") return value;
8245
- return fallback;
8246
- }
8247
- function parseFiniteNumber(value, fallback) {
8248
- return typeof value === "number" && Number.isFinite(value) ? value : fallback;
8249
- }
8250
- function parseNonEmptyString(value) {
8251
- return typeof value === "string" && value.length > 0 ? value : void 0;
8252
- }
8253
- function parseTaskSummary(raw, fallback) {
8254
- return sanitizeDispatchTaskSummary(raw.task) ?? sanitizeDispatchTaskSummary(raw.taskSummary) ?? fallback;
8255
- }
8256
- function parsePositiveInt(value) {
8257
- return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : void 0;
8258
- }
8259
- function parseGateBadge(value) {
8260
- if (typeof value !== "object" || value === null) return void 0;
8261
- const record2 = value;
8262
- if (typeof record2.role !== "string" || record2.role.length === 0) return void 0;
8263
- const cycle = parsePositiveInt(record2.cycle) ?? 1;
8264
- return { role: record2.role, cycle };
8265
- }
8266
- function parseEndpointCapacity(value) {
8267
- if (typeof value !== "object" || value === null) return void 0;
8268
- const record2 = value;
8269
- const key = parseNonEmptyString(record2.key);
8270
- const label = parseNonEmptyString(record2.label);
8271
- const limit = parsePositiveInt(record2.limit);
8272
- return key === void 0 || label === void 0 || limit === void 0 ? void 0 : { key, label, limit };
8273
- }
8274
- function parseCouncilBadge(value) {
8275
- if (typeof value !== "object" || value === null) return void 0;
8276
- const record2 = value;
8277
- const group = parseNonEmptyString(record2.group);
8278
- const label = parseNonEmptyString(record2.label);
8279
- const round = parsePositiveInt(record2.round);
8280
- if (group === void 0 || label === void 0 || round === void 0) return void 0;
8281
- return {
8282
- group,
8283
- label,
8284
- ...typeof record2.color === "string" && record2.color.length > 0 ? { color: record2.color } : {},
8285
- round
8286
- };
8287
- }
8288
- function parseFiniteNumberOrZero(value) {
8289
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
8290
- }
8291
7983
  function parseOptionalDetail(value) {
8292
7984
  if (typeof value !== "string") return null;
8293
7985
  const detail = value.replace(/\s+/g, " ").trim();
@@ -8321,113 +8013,33 @@ function terminalDetail(row2) {
8321
8013
  if (row2.status !== "failed" && row2.status !== "dead" && row2.status !== "aborted") return null;
8322
8014
  return parseOptionalDetail(row2.outcomeDetail);
8323
8015
  }
8324
- function resolveAgentEndStatus(rawMessages) {
8325
- if (!Array.isArray(rawMessages)) return null;
8326
- for (let index = rawMessages.length - 1; index >= 0; index -= 1) {
8327
- const message = rawMessages[index] ?? {};
8328
- if (message.role !== "assistant") continue;
8329
- if (message.stopReason === "stop") return "completed";
8330
- if (message.stopReason === "error") return "failed";
8331
- if (message.stopReason === "aborted") return "aborted";
8332
- return null;
8333
- }
8334
- return null;
8335
- }
8336
- function resolveFailureDetail(payload, fallback) {
8337
- const detail = parseOptionalDetail(payload.outcomeDetail);
8338
- if (detail !== null) return detail;
8339
- if (payload.reason === "timed_out") return "turn timeout exceeded";
8340
- return fallback ?? null;
8341
- }
8342
- function resolveHeartbeatStatus(status) {
8343
- if (status === "alive") return "running";
8344
- if (status === "stale" || status === "dead") return status;
8345
- return null;
8346
- }
8347
8016
  function isTerminalStatus(status) {
8348
8017
  return status === "completed" || status === "failed" || status === "aborted" || status === "dead";
8349
8018
  }
8350
- function parseRetrySnapshot(value) {
8351
- const attempt = parsePositiveInt(value.attempt);
8352
- const dueAtMs = Date.parse(value.dueAt);
8353
- if (attempt === void 0 || !Number.isFinite(dueAtMs)) return null;
8354
- return {
8355
- attempt,
8356
- dueAtMs,
8357
- reason: sanitizeCallTargetText(value.reason)
8358
- };
8359
- }
8360
- function readRetrySnapshot(snapshot) {
8361
- const retrying = /* @__PURE__ */ new Map();
8362
- try {
8363
- for (const value of snapshot.retrying) {
8364
- const runId = parseRunId(value.runId);
8365
- const agentId = parseNonEmptyString(value.agentId);
8366
- const retry = parseRetrySnapshot(value);
8367
- const taskSummary = sanitizeDispatchTaskSummary(value.task);
8368
- if (runId && agentId && retry) {
8369
- retrying.set(runId, {
8370
- agentId,
8371
- ...taskSummary !== void 0 ? { taskSummary } : {},
8372
- retry
8373
- });
8374
- }
8375
- }
8376
- } catch {
8377
- }
8378
- return retrying;
8379
- }
8380
- function readRunningSnapshot(snapshot) {
8381
- const running = /* @__PURE__ */ new Map();
8382
- try {
8383
- for (const value of snapshot.running) {
8384
- const runId = parseRunId(value.runId);
8385
- if (!runId) continue;
8386
- const budget = cloneRunToolBudgetEnvelope(value.budget);
8387
- running.set(runId, {
8388
- inputTokens: parseFiniteNumberOrZero(value.tokens.input),
8389
- outputTokens: parseFiniteNumberOrZero(value.tokens.output),
8390
- tokenCount: parseFiniteNumberOrZero(value.tokens.total),
8391
- costUsd: parseFiniteNumberOrZero(value.costUsd),
8392
- costProvenance: value.costProvenance ?? "unknown",
8393
- outcomePhase: value.outcomePhase,
8394
- ...budget !== void 0 ? { budget } : {}
8395
- });
8396
- }
8397
- } catch {
8398
- }
8399
- return running;
8400
- }
8401
- function resolveElapsedMs(entry, now) {
8402
- const startedAtMs = entry.startedAtMs ?? entry.enqueuedAtMs;
8403
- if (entry.durationMs !== null) return entry.durationMs;
8404
- const endMs = entry.finishedAtMs ?? now;
8405
- return Math.max(0, rawDurationMs(startedAtMs, endMs));
8406
- }
8407
8019
  function toRow(entry, now) {
8408
8020
  const retry = entry.retry;
8409
- const progress = entry.progress.snapshot();
8021
+ const progress = entry.progress;
8410
8022
  return {
8411
- progress,
8023
+ ...progress !== void 0 ? { progress } : {},
8412
8024
  runId: entry.runId,
8413
8025
  agentId: entry.agentId,
8414
8026
  ...entry.agentAudience !== void 0 ? { agentAudience: entry.agentAudience } : {},
8415
8027
  ...entry.requestOrigin !== void 0 ? { requestOrigin: entry.requestOrigin } : {},
8416
- runtimeKind: entry.runtimeKind,
8417
- runtimeId: entry.runtimeId,
8418
- targetId: entry.targetId,
8419
- wireModelId: entry.wireModelId,
8028
+ runtimeKind: entry.runtimeKind ?? "http",
8029
+ runtimeId: entry.runtimeId ?? "-",
8030
+ targetId: entry.targetId ?? "-",
8031
+ wireModelId: entry.modelId ?? "-",
8420
8032
  ...entry.endpoint !== void 0 ? { endpoint: { ...entry.endpoint } } : {},
8421
8033
  ...entry.taskSummary !== void 0 ? { taskSummary: entry.taskSummary } : {},
8422
8034
  ...entry.budget !== void 0 ? { budget: entry.budget } : {},
8423
- status: retry ? "retrying" : entry.status,
8424
- elapsedMs: resolveElapsedMs(entry, now),
8425
- tokenCount: entry.tokenCount,
8035
+ status: entry.status,
8036
+ elapsedMs: entry.durationMs ?? Math.max(0, (entry.finishedAtMs ?? now) - entry.startedAtMs),
8037
+ tokenCount: entry.tokens.total,
8426
8038
  costUsd: entry.costUsd,
8427
8039
  ...entry.costProvenance !== void 0 ? { costProvenance: entry.costProvenance } : {},
8428
- inputTokens: entry.inputTokens,
8429
- outputTokens: entry.outputTokens,
8430
- ttftMs: entry.ttftMs,
8040
+ inputTokens: entry.tokens.input,
8041
+ outputTokens: entry.tokens.output,
8042
+ ttftMs: entry.ttftMs ?? null,
8431
8043
  ...entry.outcomeDetail !== void 0 ? { outcomeDetail: entry.outcomeDetail } : {},
8432
8044
  ...entry.node !== void 0 ? { node: entry.node } : {},
8433
8045
  ...entry.gate !== void 0 ? { gate: { ...entry.gate } } : {},
@@ -8437,352 +8049,40 @@ function toRow(entry, now) {
8437
8049
  ...entry.rerouteCount !== void 0 ? { rerouteCount: entry.rerouteCount } : {},
8438
8050
  ...entry.failoverHops !== void 0 ? { failoverHops: entry.failoverHops } : {},
8439
8051
  ...entry.contextWindow !== void 0 ? { contextWindow: entry.contextWindow } : {},
8440
- lastContextTokens: entry.lastContextTokens,
8052
+ lastContextTokens: entry.lastContextTokens ?? 0,
8441
8053
  ...entry.receiptId !== void 0 ? { receiptId: entry.receiptId } : {},
8442
8054
  ...entry.phase !== void 0 ? { phase: { ...entry.phase } } : {},
8443
8055
  // Both tool fields are views of the one projection, so the compact card and
8444
8056
  // the expanded detail can never disagree about what is running.
8445
- currentTool: retry ? null : progress.currentAction?.tool ?? null,
8446
- recentTools: progress.recentActions.map((action) => action.tool),
8057
+ currentTool: retry ? null : progress?.currentAction?.tool ?? null,
8058
+ recentTools: progress?.recentActions.map((action) => action.tool) ?? [],
8447
8059
  ...retry ? { retry: { ...retry } } : {},
8448
8060
  ...entry.steerAcknowledgement ? { steerAcknowledgement: { ...entry.steerAcknowledgement } } : {},
8449
8061
  ...entry.writeRecordDowngrade ? { writeRecordDowngrade: { ...entry.writeRecordDowngrade } } : {}
8450
8062
  };
8451
8063
  }
8452
- function sortEntries(a, b) {
8453
- const aStatus = a.retry ? "retrying" : a.status;
8454
- const bStatus = b.retry ? "retrying" : b.status;
8455
- const rank = STATUS_ORDER[aStatus] - STATUS_ORDER[bStatus];
8456
- if (rank !== 0) return rank;
8457
- const aTime = a.finishedAtMs ?? a.startedAtMs ?? a.enqueuedAtMs;
8458
- const bTime = b.finishedAtMs ?? b.startedAtMs ?? b.enqueuedAtMs;
8459
- if (aTime !== bTime) return bTime - aTime;
8460
- return a.sequence - b.sequence;
8461
- }
8462
- function pruneEntries(entries, onEvict) {
8463
- if (entries.size <= MAX_DISPATCH_BOARD_ROWS) return;
8464
- const terminalEntries = [...entries.values()].filter((entry) => !entry.retry && isTerminalStatus(entry.status)).sort((a, b) => a.sequence - b.sequence);
8465
- const evictionQueue = terminalEntries.length > 0 ? terminalEntries : [...entries.values()].sort((a, b) => a.sequence - b.sequence);
8466
- for (const entry of evictionQueue) {
8467
- if (entries.size <= MAX_DISPATCH_BOARD_ROWS) break;
8468
- entries.delete(entry.runId);
8469
- onEvict?.(entry.runId);
8470
- }
8471
- }
8472
- function createDispatchBoardStore(bus, snapshot, readReceipt) {
8473
- const entries = /* @__PURE__ */ new Map();
8474
- const fleetPhases = /* @__PURE__ */ new Map();
8475
- let nextSequence = 0;
8476
- let reconciledAtMs = Date.now();
8477
- const settleFromReceipt = (entry) => {
8478
- const facts = readReceipt?.(entry.runId);
8479
- const text = facts?.text;
8480
- entry.progress.settle(typeof text === "string" && text.trim().length > 0 ? text : void 0);
8481
- if (facts?.trust !== void 0) entry.trust = summarizeTrustStatus(facts.trust);
8482
- };
8483
- const upsertBase = (raw, status, now) => {
8484
- const runId = parseRunId(raw.runId);
8485
- if (!runId) return null;
8486
- const previous = entries.get(runId);
8487
- const agentAudience = parseAgentAudience(raw.agentAudience, previous?.agentAudience);
8488
- const requestOrigin = parseRequestOrigin(raw.requestOrigin, previous?.requestOrigin);
8489
- const node = parseNonEmptyString(raw.node) ?? previous?.node;
8490
- const endpoint = parseEndpointCapacity(raw.endpoint) ?? previous?.endpoint;
8491
- const gate = parseGateBadge(raw.gate) ?? previous?.gate;
8492
- const council = parseCouncilBadge(raw.council) ?? previous?.council;
8493
- const rerouteCount = parsePositiveInt(raw.rerouteCount) ?? previous?.rerouteCount;
8494
- const contextWindow = parsePositiveInt(raw.contextWindow) ?? previous?.contextWindow;
8495
- const taskSummary = parseTaskSummary(raw, previous?.taskSummary);
8496
- const budget = cloneRunToolBudgetEnvelope(raw.budget) ?? previous?.budget;
8497
- const phase = fleetPhases.get(runId) ?? previous?.phase;
8498
- const entry = {
8499
- runId,
8500
- agentId: parseText(raw.agentId, previous?.agentId ?? "-"),
8501
- ...agentAudience !== void 0 ? { agentAudience } : {},
8502
- ...requestOrigin !== void 0 ? { requestOrigin } : {},
8503
- runtimeKind: parseRuntimeKind(raw.runtimeKind ?? previous?.runtimeKind),
8504
- runtimeId: parseText(raw.runtimeId, previous?.runtimeId ?? "-"),
8505
- targetId: parseText(raw.targetId, previous?.targetId ?? "-"),
8506
- wireModelId: parseText(raw.wireModelId, previous?.wireModelId ?? "-"),
8507
- ...endpoint !== void 0 ? { endpoint } : {},
8508
- ...taskSummary !== void 0 ? { taskSummary } : {},
8509
- ...budget !== void 0 ? { budget } : {},
8510
- status,
8511
- tokenCount: previous?.tokenCount ?? 0,
8512
- costUsd: previous?.costUsd ?? 0,
8513
- costProvenance: previous?.costProvenance ?? "unknown",
8514
- sequence: previous?.sequence ?? nextSequence++,
8515
- enqueuedAtMs: previous?.enqueuedAtMs ?? now,
8516
- startedAtMs: previous?.startedAtMs ?? null,
8517
- startedAtClockMs: previous?.startedAtClockMs ?? null,
8518
- finishedAtMs: previous?.finishedAtMs ?? null,
8519
- durationMs: previous?.durationMs ?? null,
8520
- inputTokens: previous?.inputTokens ?? 0,
8521
- outputTokens: previous?.outputTokens ?? 0,
8522
- ttftMs: previous?.ttftMs ?? null,
8523
- outcomeDetail: previous?.outcomeDetail ?? null,
8524
- ...node !== void 0 ? { node } : {},
8525
- ...gate !== void 0 ? { gate } : {},
8526
- ...council !== void 0 ? { council } : {},
8527
- ...previous?.hostVerification !== void 0 ? { hostVerification: previous.hostVerification } : {},
8528
- ...rerouteCount !== void 0 ? { rerouteCount } : {},
8529
- ...contextWindow !== void 0 ? { contextWindow } : {},
8530
- lastContextTokens: previous?.lastContextTokens ?? 0,
8531
- ...previous?.receiptId !== void 0 ? { receiptId: previous.receiptId } : {},
8532
- ...phase !== void 0 ? { phase } : {},
8533
- progress: previous?.progress ?? createWorkerProgressFold(),
8534
- ...previous?.retry ? { retry: { ...previous.retry } } : {},
8535
- ...previous?.steerAcknowledgement ? { steerAcknowledgement: { ...previous.steerAcknowledgement } } : {},
8536
- ...previous?.writeRecordDowngrade ? { writeRecordDowngrade: { ...previous.writeRecordDowngrade } } : {}
8537
- };
8538
- entries.set(runId, entry);
8539
- pruneEntries(entries, (evicted) => fleetPhases.delete(evicted));
8540
- return entry;
8541
- };
8542
- const unsubscribers = [
8543
- bus.on(BusChannels.DispatchEnqueued, (raw) => {
8544
- const entry = upsertBase(raw ?? {}, "enqueued", Date.now());
8545
- if (entry) delete entry.retry;
8546
- }),
8547
- bus.on(BusChannels.DispatchStarted, (raw) => {
8548
- const now = Date.now();
8549
- const entry = upsertBase(raw ?? {}, "running", now);
8550
- if (!entry) return;
8551
- entry.startedAtMs ??= now;
8552
- entry.startedAtClockMs ??= performance3.now();
8553
- entry.finishedAtMs = null;
8554
- entry.durationMs = null;
8555
- delete entry.retry;
8556
- }),
8557
- bus.on(BusChannels.DispatchCompleted, (raw) => {
8558
- const now = Date.now();
8559
- const payload = raw ?? {};
8560
- const entry = upsertBase(payload, "completed", now);
8561
- if (!entry) return;
8562
- entry.startedAtMs ??= entry.enqueuedAtMs;
8563
- entry.finishedAtMs = now;
8564
- entry.durationMs = parseFiniteNumber(payload.durationMs, Math.max(0, rawDurationMs(entry.startedAtMs, now)));
8565
- entry.tokenCount = parseFiniteNumber(payload.tokenCount, entry.tokenCount);
8566
- entry.costUsd = parseFiniteNumber(payload.costUsd, entry.costUsd);
8567
- entry.costProvenance = resolveCostProvenance(payload.costProvenance, entry.costProvenance ?? "unknown");
8568
- entry.outcomeDetail = null;
8569
- if (payload.hostVerification !== void 0) entry.hostVerification = payload.hostVerification;
8570
- settleFromReceipt(entry);
8571
- entry.receiptId = entry.runId;
8572
- delete entry.retry;
8573
- if (typeof payload.inputTokenCount === "number") {
8574
- entry.inputTokens = payload.inputTokenCount + parseFiniteNumberOrZero(payload.cacheReadTokenCount);
8575
- }
8576
- if (typeof payload.outputTokenCount === "number") {
8577
- entry.outputTokens = payload.outputTokenCount;
8578
- }
8579
- }),
8580
- bus.on(BusChannels.DispatchFailed, (raw) => {
8581
- const now = Date.now();
8582
- const payload = raw ?? {};
8583
- const runId = parseRunId(payload.runId);
8584
- const previousStatus = runId !== null ? entries.get(runId)?.status : void 0;
8585
- const resolvedStatus = resolveDispatchFailureStatus(payload.reason);
8586
- const status = previousStatus === "dead" && resolvedStatus === "failed" ? "dead" : resolvedStatus;
8587
- const entry = upsertBase(payload, status, now);
8588
- if (!entry) return;
8589
- entry.startedAtMs ??= entry.enqueuedAtMs;
8590
- entry.finishedAtMs = now;
8591
- entry.durationMs = parseFiniteNumber(payload.durationMs, Math.max(0, rawDurationMs(entry.startedAtMs, now)));
8592
- entry.tokenCount = parseFiniteNumber(payload.tokenCount, entry.tokenCount);
8593
- entry.costUsd = parseFiniteNumber(payload.costUsd, entry.costUsd);
8594
- entry.costProvenance = resolveCostProvenance(payload.costProvenance, entry.costProvenance ?? "unknown");
8595
- entry.outcomeDetail = resolveFailureDetail(payload, entry.outcomeDetail);
8596
- if (payload.hostVerification !== void 0) entry.hostVerification = payload.hostVerification;
8597
- settleFromReceipt(entry);
8598
- if (payload.reason !== "retry_denied") entry.receiptId = entry.runId;
8599
- delete entry.retry;
8600
- if (typeof payload.inputTokenCount === "number") {
8601
- entry.inputTokens = payload.inputTokenCount + parseFiniteNumberOrZero(payload.cacheReadTokenCount);
8602
- }
8603
- if (typeof payload.outputTokenCount === "number") {
8604
- entry.outputTokens = payload.outputTokenCount;
8605
- }
8606
- }),
8607
- bus.on(BusChannels.RunAborted, (raw) => {
8608
- const runId = parseRunId(raw?.runId);
8609
- if (!runId) return;
8610
- const entry = entries.get(runId);
8611
- if (!entry) return;
8612
- const wasRetrying = entry.retry !== void 0;
8613
- delete entry.retry;
8614
- if (wasRetrying && raw?.startedAt === null) {
8615
- entry.status = "aborted";
8616
- entry.finishedAtMs = Date.now();
8617
- entry.progress.settle();
8618
- } else {
8619
- if (isTerminalStatus(entry.status) && !wasRetrying) return;
8620
- entry.status = "cancelling";
8621
- }
8622
- entry.outcomeDetail = parseOptionalDetail(raw?.reason) ?? entry.outcomeDetail ?? null;
8623
- }),
8624
- bus.on(BusChannels.DispatchProgress, (raw) => {
8625
- const payload = raw ?? {};
8626
- const runId = parseRunId(payload.runId);
8627
- if (!runId) return;
8628
- const entry = entries.get(runId);
8629
- if (!entry) return;
8630
- const workerEvent = payload.event ?? {};
8631
- const type = typeof workerEvent.type === "string" ? workerEvent.type : "";
8632
- if (type === "heartbeat_status") {
8633
- if (isTerminalStatus(entry.status) || entry.status === "cancelling") return;
8634
- const status = resolveHeartbeatStatus(workerEvent.status);
8635
- if (!status) return;
8636
- entry.status = status;
8637
- if (status === "dead") {
8638
- entry.finishedAtMs ??= Date.now();
8639
- entry.progress.settle();
8640
- delete entry.retry;
8641
- }
8642
- return;
8643
- }
8644
- if (type === "attempt_start") {
8645
- entry.failoverHops = (entry.failoverHops ?? 0) + 1;
8646
- entry.status = "running";
8647
- entry.finishedAtMs = null;
8648
- entry.progress.restart();
8649
- delete entry.retry;
8650
- return;
8651
- }
8652
- if (type === "agent_start") {
8653
- entry.startedAtMs = Date.now();
8654
- entry.startedAtClockMs = performance3.now();
8655
- }
8656
- if (type === "message_update") {
8657
- const assistantEvent = "assistantMessageEvent" in workerEvent && typeof workerEvent.assistantMessageEvent === "object" && workerEvent.assistantMessageEvent !== null ? workerEvent.assistantMessageEvent : {};
8658
- const hasDelta = assistantEvent.type === "text_delta" || assistantEvent.type === "thinking_delta" || assistantEvent.type === "toolcall_start" || assistantEvent.type === "toolcall_delta";
8659
- if (hasDelta && entry.ttftMs === null && entry.startedAtClockMs !== null) {
8660
- entry.ttftMs = Math.round(performance3.now() - entry.startedAtClockMs);
8661
- }
8662
- }
8663
- if (type === "clio_coder_write_record_downgraded") {
8664
- const rawPayload = workerEvent.payload;
8665
- const payload2 = typeof rawPayload === "object" && rawPayload !== null ? rawPayload : null;
8666
- const tool = payload2 === null ? void 0 : parseNonEmptyString(payload2.tool);
8667
- const toolCallId = payload2 === null ? void 0 : parseNonEmptyString(payload2.toolCallId);
8668
- if (payload2?.reason === "opaque_tool_succeeded" && tool !== void 0 && toolCallId !== void 0) {
8669
- entry.writeRecordDowngrade = {
8670
- reason: "opaque_tool_succeeded",
8671
- tool: sanitizeCallTargetText(tool),
8672
- toolCallId: sanitizeCallTargetText(toolCallId)
8673
- };
8674
- }
8675
- }
8676
- entry.progress.observe(payload.event);
8677
- if (type === "clio_coder_steer_received") {
8678
- const steerPayload = workerEvent.payload;
8679
- entry.steerAcknowledgement = {
8680
- receivedAtMs: Date.now(),
8681
- chars: Math.max(0, Math.floor(parseFiniteNumberOrZero(steerPayload?.chars)))
8682
- };
8683
- }
8684
- if (isTerminalStatus(entry.status)) return;
8685
- if (type === "message_end" && workerEvent.message?.role === "assistant") {
8686
- const usage = workerEvent.message.usage;
8687
- const input = parseFiniteNumberOrZero(usage?.input) + parseFiniteNumberOrZero(usage?.cacheRead);
8688
- const output = parseFiniteNumberOrZero(usage?.output);
8689
- entry.inputTokens += input;
8690
- entry.outputTokens += output;
8691
- entry.tokenCount += input + output + parseFiniteNumberOrZero(usage?.cacheWrite);
8692
- entry.lastContextTokens = input + output;
8693
- }
8694
- if (type === "agent_end") {
8695
- const status = resolveAgentEndStatus(workerEvent.messages);
8696
- if (!status) return;
8697
- entry.status = status;
8698
- entry.finishedAtMs ??= Date.now();
8699
- entry.progress.settle();
8700
- delete entry.retry;
8701
- }
8702
- })
8703
- ];
8704
- let closed = false;
8705
- const reconcile = () => {
8706
- const now = Date.now();
8707
- if (!snapshot) {
8708
- reconciledAtMs = now;
8709
- return;
8710
- }
8711
- let currentSnapshot;
8712
- try {
8713
- currentSnapshot = snapshot();
8714
- } catch {
8715
- return;
8716
- }
8717
- if (!Array.isArray(currentSnapshot?.retrying) || !Array.isArray(currentSnapshot?.running)) return;
8718
- reconciledAtMs = now;
8719
- const retrying = readRetrySnapshot(currentSnapshot);
8720
- const running = readRunningSnapshot(currentSnapshot);
8721
- for (const entry of entries.values()) {
8722
- if (entry.retry && !retrying.has(entry.runId)) {
8723
- delete entry.retry;
8724
- }
8725
- }
8726
- for (const [runId, projection] of retrying) {
8727
- const existing = entries.get(runId);
8728
- if (existing && existing.status !== "failed" && existing.status !== "dead") {
8729
- continue;
8730
- }
8731
- const entry = existing ?? upsertBase(
8732
- {
8733
- runId,
8734
- agentId: projection.agentId,
8735
- ...projection.taskSummary !== void 0 ? { task: projection.taskSummary } : {}
8736
- },
8737
- "failed",
8738
- now
8739
- );
8740
- if (entry) {
8741
- entry.retry = { ...projection.retry };
8742
- if (entry.taskSummary === void 0 && projection.taskSummary !== void 0) {
8743
- entry.taskSummary = projection.taskSummary;
8744
- }
8745
- }
8746
- }
8747
- for (const [runId, live] of running) {
8748
- const entry = entries.get(runId);
8749
- if (!entry) continue;
8750
- if (isTerminalStatus(entry.status) && live.outcomePhase !== "aborting") continue;
8751
- entry.inputTokens = live.inputTokens;
8752
- entry.outputTokens = live.outputTokens;
8753
- entry.tokenCount = live.tokenCount;
8754
- entry.costUsd = live.costUsd;
8755
- entry.costProvenance = live.costProvenance;
8756
- if (live.budget !== void 0) entry.budget = live.budget;
8757
- if (live.outcomePhase === "aborting") {
8758
- if (entry.status !== "completed" && entry.status !== "aborted") {
8759
- entry.status = "cancelling";
8760
- delete entry.retry;
8761
- }
8762
- }
8763
- }
8764
- };
8064
+ function createDispatchBoardStore(projection) {
8065
+ let current = projection.snapshot();
8066
+ const unsubscribe = projection.subscribe((snapshot) => {
8067
+ current = snapshot;
8068
+ });
8765
8069
  const projectRows = (activeOnly) => {
8766
- return [...entries.values()].sort(sortEntries).map((entry) => toRow(entry, reconciledAtMs)).filter((row2) => !activeOnly || !isTerminalStatus(row2.status));
8070
+ return [...current.runs].reverse().sort(
8071
+ (a, b) => STATUS_ORDER[a.status] - STATUS_ORDER[b.status] || (b.finishedAtMs ?? b.startedAtMs) - (a.finishedAtMs ?? a.startedAtMs)
8072
+ ).map((run) => toRow(run, current.generatedAt)).filter((row2) => !activeOnly || !isTerminalStatus(row2.status));
8767
8073
  };
8768
8074
  return {
8769
- rows() {
8770
- return projectRows(false);
8771
- },
8772
- activeRows() {
8773
- return projectRows(true);
8075
+ rows: () => projectRows(false),
8076
+ activeRows: () => projectRows(true),
8077
+ reconcile() {
8078
+ projection.reconcileRuns();
8079
+ current = projection.snapshot();
8774
8080
  },
8775
- reconcile,
8776
8081
  setFleetPhase(runId, phase) {
8777
- fleetPhases.set(runId, phase);
8778
- const entry = entries.get(runId);
8779
- if (entry) entry.phase = { ...phase };
8082
+ projection.setFleetPhase(runId, phase);
8083
+ current = projection.snapshot();
8780
8084
  },
8781
- unsubscribe() {
8782
- if (closed) return;
8783
- closed = true;
8784
- for (const unsubscribe of unsubscribers) unsubscribe();
8785
- }
8085
+ unsubscribe
8786
8086
  };
8787
8087
  }
8788
8088
 
@@ -10501,7 +9801,7 @@ var ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{
10501
9801
  function isIso8601(value) {
10502
9802
  return typeof value === "string" && ISO_8601_REGEX.test(value) && !Number.isNaN(Date.parse(value));
10503
9803
  }
10504
- function isRecord8(value) {
9804
+ function isRecord7(value) {
10505
9805
  return !!value && typeof value === "object" && !Array.isArray(value);
10506
9806
  }
10507
9807
  function isNonEmptyString(value) {
@@ -10564,23 +9864,23 @@ function maybeSizeBytes(path2) {
10564
9864
  }
10565
9865
  function sessionCurrentPath2(stateDir, meta) {
10566
9866
  if (!meta) return void 0;
10567
- return join5(stateDir, "sessions", meta.cwdHash, meta.id, "current.jsonl");
9867
+ return join4(stateDir, "sessions", meta.cwdHash, meta.id, "current.jsonl");
10568
9868
  }
10569
9869
  function protectedArtifactPath(path2) {
10570
9870
  return isAbsolute4(path2) ? path2 : void 0;
10571
9871
  }
10572
9872
  function receiptFilePath(stateDir, runId) {
10573
- return join5(stateDir, "receipts", `${runId}.json`);
9873
+ return join4(stateDir, "receipts", `${runId}.json`);
10574
9874
  }
10575
9875
  function runLedgerPath(stateDir) {
10576
- return join5(stateDir, "runs.json");
9876
+ return join4(stateDir, "runs.json");
10577
9877
  }
10578
9878
  function readRunLedger(stateDir) {
10579
9879
  try {
10580
- const raw = readFileSync6(runLedgerPath(stateDir), "utf8").trim();
9880
+ const raw = readFileSync5(runLedgerPath(stateDir), "utf8").trim();
10581
9881
  if (raw.length === 0) return [];
10582
9882
  const parsed = JSON.parse(raw);
10583
- return Array.isArray(parsed) ? parsed.filter(isRecord8) : [];
9883
+ return Array.isArray(parsed) ? parsed.filter(isRecord7) : [];
10584
9884
  } catch {
10585
9885
  return [];
10586
9886
  }
@@ -10602,7 +9902,7 @@ function validateToolStats(value) {
10602
9902
  }
10603
9903
  for (let i = 0; i < value.length; i++) {
10604
9904
  const entry = value[i];
10605
- if (!isRecord8(entry)) {
9905
+ if (!isRecord7(entry)) {
10606
9906
  return { ok: false, reason: `toolStats[${i}] not an object` };
10607
9907
  }
10608
9908
  if (!isNonEmptyString(entry.tool)) {
@@ -10621,7 +9921,7 @@ function validateToolStats(value) {
10621
9921
  }
10622
9922
  function receiptTrustDetail(stateDir, runId) {
10623
9923
  try {
10624
- const receipt = JSON.parse(readFileSync6(receiptFilePath(stateDir, runId), "utf8"));
9924
+ const receipt = JSON.parse(readFileSync5(receiptFilePath(stateDir, runId), "utf8"));
10625
9925
  const ledger = readRunEnvelope(stateDir, runId);
10626
9926
  return formatTrustSummaryLine(inspectRunReceiptTrustStatus(receipt, ledger.ok ? ledger.envelope : null).status);
10627
9927
  } catch {
@@ -10639,7 +9939,7 @@ function verifyReceiptFile(stateDir, runId) {
10639
9939
  const target = receiptFilePath(stateDir, runId);
10640
9940
  let raw;
10641
9941
  try {
10642
- raw = readFileSync6(target, "utf8");
9942
+ raw = readFileSync5(target, "utf8");
10643
9943
  } catch (err) {
10644
9944
  const e = err;
10645
9945
  if (e.code === "ENOENT") return { ok: false, reason: "receipt file not found" };
@@ -10651,7 +9951,7 @@ function verifyReceiptFile(stateDir, runId) {
10651
9951
  } catch (err) {
10652
9952
  return { ok: false, reason: `invalid json: ${err.message}` };
10653
9953
  }
10654
- if (!isRecord8(parsed)) {
9954
+ if (!isRecord7(parsed)) {
10655
9955
  return { ok: false, reason: "receipt is not an object" };
10656
9956
  }
10657
9957
  const r = parsed;
@@ -10751,7 +10051,7 @@ var RECEIPT_FILE_FAILURE = /^(?:receipt file not found|read error:)/u;
10751
10051
  var RECEIPT_CONTRACT_FAILURE = /^(?:invalid json:|receipt is not an object|missing field:|runId invalid:|runId mismatch:|agentId invalid:|task invalid:|targetId invalid:|wireModelId invalid:|runtimeId invalid:|runtimeKind invalid:|exitCode out of range:|tokenCount out of range:|inputTokenCount out of range:|outputTokenCount out of range:|cacheReadTokenCount out of range:|cacheWriteTokenCount out of range:|costUsd out of range:|reasoningTokenCount out of range:|startedAt not ISO-8601:|endedAt not ISO-8601:|clioCoderVersion empty|piMonoVersion invalid:|platform invalid:|nodeVersion invalid:|toolCalls out of range:|toolStats\[|compiledPromptHash invalid:|staticCompositionHash invalid:|sessionId invalid:|integrity invalid|execution role invalid|routing intent invalid|route decision invalid)/u;
10752
10052
  var LEDGER_FAILURE = /^(?:run ledger not found|run not found in ledger|ledger mismatch:)/u;
10753
10053
  function receiptIntegrityDigest(value) {
10754
- if (!isRecord8(value) || value.algorithm !== "sha256" || !isNonEmptyString(value.digest)) return null;
10054
+ if (!isRecord7(value) || value.algorithm !== "sha256" || !isNonEmptyString(value.digest)) return null;
10755
10055
  return `sha256:${value.digest}`;
10756
10056
  }
10757
10057
  function trustCheckEvidence(status, axis) {
@@ -10777,7 +10077,7 @@ function verifyReceiptFileReport(stateDir, runId) {
10777
10077
  const result = verifyReceiptFile(stateDir, runId);
10778
10078
  let receipt = null;
10779
10079
  try {
10780
- receipt = JSON.parse(readFileSync6(receiptPath, "utf8"));
10080
+ receipt = JSON.parse(readFileSync5(receiptPath, "utf8"));
10781
10081
  } catch {
10782
10082
  }
10783
10083
  const sealedDigest = receiptIntegrityDigest(receipt?.integrity);
@@ -11086,17 +10386,17 @@ var ReceiptArtifactProvider = class {
11086
10386
  }
11087
10387
  };
11088
10388
  function resultText3(result) {
11089
- if (!isRecord8(result)) return "";
10389
+ if (!isRecord7(result)) return "";
11090
10390
  if (result.kind === "ok" && typeof result.output === "string") return result.output;
11091
10391
  if (result.kind === "error" && typeof result.message === "string") return result.message;
11092
10392
  return "";
11093
10393
  }
11094
10394
  function resultDetails(result) {
11095
- return isRecord8(result) && isRecord8(result.details) ? result.details : null;
10395
+ return isRecord7(result) && isRecord7(result.details) ? result.details : null;
11096
10396
  }
11097
10397
  function messagePayload(entry) {
11098
10398
  if (entry.kind !== "message") return null;
11099
- return isRecord8(entry.payload) ? entry.payload : null;
10399
+ return isRecord7(entry.payload) ? entry.payload : null;
11100
10400
  }
11101
10401
  function toolNameFor(entry) {
11102
10402
  const payload = messagePayload(entry);
@@ -11122,7 +10422,7 @@ function dispatchResultForRun(entries, runId) {
11122
10422
  const details = resultDetails(payload.result);
11123
10423
  const detailRunId = details?.runId;
11124
10424
  const runIds = details?.runIds;
11125
- const matches = detailRunId === runId || Array.isArray(runIds) && runIds.some((item) => item === runId) || Array.isArray(details?.runs) && details.runs.some((item) => isRecord8(item) && item.runId === runId);
10425
+ const matches = detailRunId === runId || Array.isArray(runIds) && runIds.some((item) => item === runId) || Array.isArray(details?.runs) && details.runs.some((item) => isRecord7(item) && item.runId === runId);
11126
10426
  if (!matches) continue;
11127
10427
  const text = resultText3(payload.result);
11128
10428
  if (text.length > 0) return text;
@@ -11604,6 +10904,8 @@ function renderAccountabilitySummary(summary) {
11604
10904
  "# Accountability",
11605
10905
  "",
11606
10906
  `first-pass success: ${summary.firstPassRuns}/${summary.totalRuns} (${pct}%)`,
10907
+ `unverified successes: ${summary.unverifiedSuccesses}`,
10908
+ `ungrounded claims: ${summary.ungroundedClaims}`,
11607
10909
  "",
11608
10910
  "## Top failure causes",
11609
10911
  ""
@@ -11687,7 +10989,7 @@ function auditRowPayload(row2) {
11687
10989
  }
11688
10990
  function auditReadErrorsArtifact(stateDir, errors) {
11689
10991
  if (errors.length === 0) return null;
11690
- const path2 = join5(stateDir, "audit");
10992
+ const path2 = join4(stateDir, "audit");
11691
10993
  return {
11692
10994
  id: "audit:read-errors",
11693
10995
  category: "audit",
@@ -11715,7 +11017,7 @@ var SafetyAuditArtifactProvider = class {
11715
11017
  }
11716
11018
  const selected = [...currentSessionAuditRows(read.rows, this.deps.sessionMeta?.id)].sort(compareAuditRowsNewestFirst).slice(0, SAFETY_AUDIT_ARTIFACT_LIMIT);
11717
11019
  const artifacts = selected.map((row2) => {
11718
- const path2 = join5(this.deps.stateDir, "audit", row2.file);
11020
+ const path2 = join4(this.deps.stateDir, "audit", row2.file);
11719
11021
  const runId = readStringField2(row2.row, "runId");
11720
11022
  const sessionId = readStringField2(row2.row, "sessionId");
11721
11023
  const correlationId = readStringField2(row2.row, "correlationId") ?? row2.correlationId;
@@ -11799,7 +11101,7 @@ async function listViewArtifacts(providers) {
11799
11101
  }
11800
11102
 
11801
11103
  // src/interactive/worker-receipts.ts
11802
- function isRecord9(value) {
11104
+ function isRecord8(value) {
11803
11105
  return typeof value === "object" && value !== null && !Array.isArray(value);
11804
11106
  }
11805
11107
  function optionalString(value) {
@@ -11815,12 +11117,12 @@ function elapsedMsFrom(receipt) {
11815
11117
  return Math.max(0, endedAt - startedAt);
11816
11118
  }
11817
11119
  function contractFrom(receipt) {
11818
- const quality = isRecord9(receipt.quality) ? receipt.quality : null;
11120
+ const quality = isRecord8(receipt.quality) ? receipt.quality : null;
11819
11121
  if (quality === null) return void 0;
11820
11122
  if (!Object.hasOwn(quality, "resultContract")) return void 0;
11821
11123
  const fact = quality.resultContract;
11822
11124
  if (fact === null) return "unmeasured";
11823
- if (!isRecord9(fact)) return void 0;
11125
+ if (!isRecord8(fact)) return void 0;
11824
11126
  const conformance = fact.conformance;
11825
11127
  return conformance === "pass" || conformance === "fail" || conformance === "not-reached" ? conformance : void 0;
11826
11128
  }
@@ -11828,11 +11130,12 @@ var PRESENTED_RESULT_CONTRACTS = [
11828
11130
  "debugger-report",
11829
11131
  "verifier-report",
11830
11132
  "research-report",
11133
+ "world-knowledge-report",
11831
11134
  "scout-report"
11832
11135
  ];
11833
11136
  function contractKindFrom(receipt) {
11834
- const quality = isRecord9(receipt.quality) ? receipt.quality : null;
11835
- const fact = quality !== null && isRecord9(quality.resultContract) ? quality.resultContract : null;
11137
+ const quality = isRecord8(receipt.quality) ? receipt.quality : null;
11138
+ const fact = quality !== null && isRecord8(quality.resultContract) ? quality.resultContract : null;
11836
11139
  const sourceId = optionalString(fact?.sourceId);
11837
11140
  if (sourceId === void 0) return void 0;
11838
11141
  return PRESENTED_RESULT_CONTRACTS.find((kind) => sourceId.startsWith(`agent-result-contract:${kind}:`));
@@ -11840,7 +11143,7 @@ function contractKindFrom(receipt) {
11840
11143
  function workerReceiptFacts(receipt) {
11841
11144
  const outcome = optionalString(receipt.outcome);
11842
11145
  if (outcome === void 0) return null;
11843
- const output = isRecord9(receipt.output) ? receipt.output : null;
11146
+ const output = isRecord8(receipt.output) ? receipt.output : null;
11844
11147
  const contract = contractFrom(receipt);
11845
11148
  const contractKind = contractKindFrom(receipt);
11846
11149
  const text = optionalString(output?.text);
@@ -11866,11 +11169,11 @@ function workerReceiptFacts(receipt) {
11866
11169
  function readReceiptFileFacts(runId, stateDir) {
11867
11170
  let parsed;
11868
11171
  try {
11869
- parsed = JSON.parse(readFileSync7(receiptFilePath(stateDir, runId), "utf8"));
11172
+ parsed = JSON.parse(readFileSync6(receiptFilePath(stateDir, runId), "utf8"));
11870
11173
  } catch {
11871
11174
  return null;
11872
11175
  }
11873
- if (!isRecord9(parsed)) return null;
11176
+ if (!isRecord8(parsed)) return null;
11874
11177
  const facts = workerReceiptFacts(parsed);
11875
11178
  if (facts === null) return null;
11876
11179
  const row2 = findRunRow(runId, stateDir);
@@ -11882,13 +11185,13 @@ function readWorkerReceiptFacts(runId, stateDir = clioStateDir()) {
11882
11185
  return readReceiptFileFacts(runId, stateDir);
11883
11186
  }
11884
11187
  function findRunRow(runId, stateDir) {
11885
- const path2 = join6(stateDir, "runs.json");
11886
- if (!existsSync5(path2)) return null;
11188
+ const path2 = join5(stateDir, "runs.json");
11189
+ if (!existsSync4(path2)) return null;
11887
11190
  try {
11888
- const parsed = JSON.parse(readFileSync7(path2, "utf8"));
11191
+ const parsed = JSON.parse(readFileSync6(path2, "utf8"));
11889
11192
  if (!Array.isArray(parsed)) return null;
11890
11193
  for (const entry of parsed) {
11891
- if (isRecord9(entry) && entry.id === runId) return entry;
11194
+ if (isRecord8(entry) && entry.id === runId) return entry;
11892
11195
  }
11893
11196
  return null;
11894
11197
  } catch {
@@ -12231,6 +11534,7 @@ function richMessageFromEntry(entry, maxTextChars) {
12231
11534
  "responseModelIdObservation",
12232
11535
  "responseModel",
12233
11536
  "responseId",
11537
+ "gatewayRouting",
12234
11538
  "diagnostics",
12235
11539
  "contextUsageInvalidated"
12236
11540
  ]) {
@@ -12423,7 +11727,7 @@ function replayResultSummary(result) {
12423
11727
  const summary = result.resultSummary ?? toolResultSummary(result.result);
12424
11728
  const offloadPath = typeof summary.offloadPath === "string" && summary.offloadPath.length > 0 ? summary.offloadPath : null;
12425
11729
  if (offloadPath === null) return result.resultSummary;
12426
- return { ...summary, offloadFileMissing: !existsSync6(offloadPath) };
11730
+ return { ...summary, offloadFileMissing: !existsSync5(offloadPath) };
12427
11731
  }
12428
11732
  function extractToolResult(entry) {
12429
11733
  const payload = entry.payload;
@@ -13163,8 +12467,8 @@ function createTurnContext(deps) {
13163
12467
  if (!usage || !deps.observability) return;
13164
12468
  if (usage.totalTokens <= 0 && usage.cost.total <= 0) return;
13165
12469
  deps.observability.recordTokens(
13166
- agentRuntime.targetId,
13167
- agentRuntime.wireModelId,
12470
+ usage.targetId ?? agentRuntime.targetId,
12471
+ usage.modelId ?? agentRuntime.wireModelId,
13168
12472
  usage.totalTokens,
13169
12473
  usage.cost.total,
13170
12474
  {
@@ -13176,7 +12480,7 @@ function createTurnContext(deps) {
13176
12480
  totalTokens: usage.totalTokens,
13177
12481
  apiCalls: Math.max(1, Math.round(usage.apiCalls))
13178
12482
  },
13179
- agentRuntime.runtimeResolution.costProvenance
12483
+ usage.targetId === void 0 && usage.modelId === void 0 ? agentRuntime.runtimeResolution.costProvenance : usage.cost.total > 0 ? "estimated" : "unknown"
13180
12484
  );
13181
12485
  };
13182
12486
  const runAutoCompact = async (agentRuntime, force, instructions, triggerOverride, pendingUserText) => {
@@ -14512,9 +13816,9 @@ function createTurnPrewarm(deps) {
14512
13816
  releaseActiveRound();
14513
13817
  },
14514
13818
  settled() {
14515
- return new Promise((resolve8) => {
13819
+ return new Promise((resolve9) => {
14516
13820
  setTimeout(() => {
14517
- resolve8(inFlight.catch(() => null));
13821
+ resolve9(inFlight.catch(() => null));
14518
13822
  }, 0);
14519
13823
  });
14520
13824
  },
@@ -14675,7 +13979,7 @@ function createTurnRecovery(deps) {
14675
13979
  deps.emitFailureMessage(message);
14676
13980
  };
14677
13981
  const waitForRetryCountdown = async (status) => {
14678
- return new Promise((resolve8) => {
13982
+ return new Promise((resolve9) => {
14679
13983
  let settled = false;
14680
13984
  let currentHandle = null;
14681
13985
  const handle = createRetryCountdown({
@@ -14692,12 +13996,12 @@ function createTurnRecovery(deps) {
14692
13996
  onDone: () => {
14693
13997
  settled = true;
14694
13998
  if (retryCountdown2 === currentHandle) retryCountdown2 = null;
14695
- resolve8("done");
13999
+ resolve9("done");
14696
14000
  },
14697
14001
  onCancel: () => {
14698
14002
  settled = true;
14699
14003
  if (retryCountdown2 === currentHandle) retryCountdown2 = null;
14700
- resolve8("cancelled");
14004
+ resolve9("cancelled");
14701
14005
  }
14702
14006
  });
14703
14007
  currentHandle = handle;
@@ -14733,6 +14037,10 @@ function createTurnRecovery(deps) {
14733
14037
  }
14734
14038
  };
14735
14039
  const runTransientRetryChain = async (agentRuntime, text, initialFailure) => {
14040
+ if (agentRuntime.runtimeId === "litellm") {
14041
+ ensureFailureVisibleAndPersisted(initialFailure);
14042
+ return true;
14043
+ }
14736
14044
  const settings = deps.retrySettings();
14737
14045
  if (!settings.enabled || settings.maxRetries <= 0) return false;
14738
14046
  if (initialFailure.stopReason === "aborted" || !isRetryableErrorMessage(initialFailure.errorMessage)) return false;
@@ -14829,7 +14137,7 @@ function createTurnRecovery(deps) {
14829
14137
 
14830
14138
  // src/interactive/turn-runtime.ts
14831
14139
  init_esm_shims();
14832
- import { performance as performance4 } from "node:perf_hooks";
14140
+ import { performance as performance3 } from "node:perf_hooks";
14833
14141
 
14834
14142
  // src/interactive/tool-prose-loop.ts
14835
14143
  init_esm_shims();
@@ -15127,6 +14435,9 @@ function createTurnRuntime(deps) {
15127
14435
  cleanupSessionResources(state.runtime.agent.sessionId);
15128
14436
  }
15129
14437
  let getCurrentAgentSignal = () => void 0;
14438
+ const gatewaySessionId = target.runtime.id === "litellm" ? deps.sessionId?.() : void 0;
14439
+ let apiCallStartedAt = null;
14440
+ let apiCallFirstDeltaAt = null;
15130
14441
  const handle = deps.createAgent({
15131
14442
  initialState: {
15132
14443
  systemPrompt: fallbackIdentityPrompt(),
@@ -15136,6 +14447,11 @@ function createTurnRuntime(deps) {
15136
14447
  messages: priorMessages
15137
14448
  },
15138
14449
  maxRetryDelayMs: deps.retrySettings().maxDelayMs,
14450
+ ...gatewaySessionId ? { sessionId: gatewaySessionId } : {},
14451
+ onStreamInvocation: () => {
14452
+ apiCallStartedAt = performance3.now();
14453
+ apiCallFirstDeltaAt = null;
14454
+ },
15139
14455
  onPayload: async (payload, currentModel) => {
15140
14456
  const thinkingPatched = patchProviderThinkingPayload(payload, currentModel, state.currentThinkingLevel);
15141
14457
  const basePayload = thinkingPatched ?? payload;
@@ -15173,7 +14489,7 @@ function createTurnRuntime(deps) {
15173
14489
  runtimeResolution: target.runtimeResolution
15174
14490
  };
15175
14491
  emitThinkingClampNotice(target.runtimeResolution);
15176
- let lastActivityAt = performance4.now();
14492
+ let lastActivityAt = performance3.now();
15177
14493
  let toolsInFlight = 0;
15178
14494
  let stallSuspendDepth = 0;
15179
14495
  let stallTimer = null;
@@ -15192,7 +14508,7 @@ function createTurnRuntime(deps) {
15192
14508
  armStallTimer(stallMs);
15193
14509
  return;
15194
14510
  }
15195
- const idleMs = performance4.now() - lastActivityAt;
14511
+ const idleMs = performance3.now() - lastActivityAt;
15196
14512
  if (idleMs < stallMs) {
15197
14513
  armStallTimer(stallMs - idleMs);
15198
14514
  return;
@@ -15210,20 +14526,18 @@ function createTurnRuntime(deps) {
15210
14526
  return await context.postToolContinuationGuard(localRuntime, signal);
15211
14527
  } finally {
15212
14528
  stallSuspendDepth -= 1;
15213
- lastActivityAt = performance4.now();
14529
+ lastActivityAt = performance3.now();
15214
14530
  }
15215
14531
  };
15216
14532
  let streamStartedAt = null;
15217
14533
  let firstAssistantDeltaAt = null;
15218
- let apiCallStartedAt = null;
15219
- let apiCallFirstDeltaAt = null;
15220
14534
  let runFirstCallVerdict = null;
15221
14535
  let pendingTerminalToolResult = null;
15222
14536
  let runStartMessageCount = 0;
15223
14537
  const interruptedUsageByMessage = /* @__PURE__ */ new WeakMap();
15224
14538
  handle.agent.subscribe(async (event) => {
15225
14539
  const eventAt = Date.now();
15226
- const eventClock = performance4.now();
14540
+ const eventClock = performance3.now();
15227
14541
  lastActivityAt = eventClock;
15228
14542
  let enrichedEvent = event;
15229
14543
  if (event.type === "tool_execution_start") {
@@ -15261,6 +14575,12 @@ function createTurnRuntime(deps) {
15261
14575
  }
15262
14576
  let publicEvent = enrichedEvent;
15263
14577
  if (enrichedEvent.type === "message_end" && enrichedEvent.message?.role === "assistant") {
14578
+ const gatewayRouting = gatewayRoutingObservationFromRecord(
14579
+ enrichedEvent.message
14580
+ );
14581
+ if (gatewayRouting !== null && ((gatewayRouting.attemptedFallbacks ?? 0) > 0 || (gatewayRouting.attemptedRetries ?? 0) > 0)) {
14582
+ deps.emitNotice(`[Clio Coder] ${gatewayRoutingObservationLabel(gatewayRouting)}`);
14583
+ }
15264
14584
  const interruptedUsage = estimatedUsageForInterruptedTurn(enrichedEvent.message, context.promptSideTokens());
15265
14585
  if (interruptedUsage !== null) {
15266
14586
  interruptedUsageByMessage.set(enrichedEvent.message, interruptedUsage);
@@ -15295,13 +14615,9 @@ function createTurnRuntime(deps) {
15295
14615
  if (stallMs > 0) armStallTimer(stallMs);
15296
14616
  }
15297
14617
  if (publicEvent?.type === "turn_end") toolsInFlight = 0;
15298
- if (publicEvent?.type === "message_start" && publicEvent.message?.role === "assistant") {
15299
- apiCallStartedAt = eventClock;
15300
- apiCallFirstDeltaAt = null;
15301
- }
15302
14618
  if (publicEvent?.type === "message_update") {
15303
14619
  const assistantEvent = publicEvent.assistantMessageEvent;
15304
- const hasDelta = assistantEvent.type === "text_delta" || assistantEvent.type === "thinking_delta" || assistantEvent.type === "toolcall_start" || assistantEvent.type === "toolcall_delta";
14620
+ const hasDelta = assistantEvent.type === "toolcall_start" || (assistantEvent.type === "text_delta" || assistantEvent.type === "thinking_delta" || assistantEvent.type === "toolcall_delta") && typeof assistantEvent.delta === "string" && assistantEvent.delta.length > 0;
15305
14621
  if (hasDelta && firstAssistantDeltaAt === null) firstAssistantDeltaAt = eventClock;
15306
14622
  if (hasDelta && apiCallFirstDeltaAt === null) apiCallFirstDeltaAt = eventClock;
15307
14623
  }
@@ -15466,6 +14782,7 @@ function createTurnState(initialThinkingLevel) {
15466
14782
  stalledTurnNudgeSpent: false,
15467
14783
  pendingRequestContinuation: false,
15468
14784
  currentPendingSkillPolicy: void 0,
14785
+ activeSkillSurface: void 0,
15469
14786
  currentAskUserPolicy: void 0,
15470
14787
  lastRunSnapshot: null
15471
14788
  };
@@ -15533,6 +14850,21 @@ function createChatLoop(deps) {
15533
14850
  const emitNotice = (text, level = "info", key) => {
15534
14851
  emit({ type: "notice", level, surface: "transcript", text, ...key === void 0 ? {} : { key } });
15535
14852
  };
14853
+ const armSkillSurface = (policy, loadedBefore) => {
14854
+ const previous = skillSurfaceNames(state.activeSkillSurface).join(", ");
14855
+ const next = armedSkillSurface(policy);
14856
+ const current = skillSurfaceNames(next).join(", ");
14857
+ state.activeSkillSurface = next;
14858
+ const activated = skillSurfaceLabels(policy).filter((label) => !loadedBefore?.has(label.split(" ")[0] ?? label));
14859
+ if (activated.length > 0) {
14860
+ emitNotice(
14861
+ current.length > 0 ? `[Clio Coder] Skill activated: ${activated.join(", ")}. Its tool surface stays armed across your next turns until another skill replaces it or you run /skill off.` : `[Clio Coder] Skill activated: ${activated.join(", ")}. It declares no tool narrowing.`
14862
+ );
14863
+ }
14864
+ if (current !== previous && current.length === 0 && previous.length > 0) {
14865
+ emitNotice(`[Clio Coder] Skill tool surface cleared: ${previous}. The full tool surface is back.`);
14866
+ }
14867
+ };
15536
14868
  const emitAdmissionNotice = (text, reason) => {
15537
14869
  emit({ type: "notice", level: "info", surface: "transcript", text, admission: { reason } });
15538
14870
  };
@@ -15630,6 +14962,7 @@ function createChatLoop(deps) {
15630
14962
  context,
15631
14963
  middleware,
15632
14964
  retrySettings,
14965
+ sessionId: () => deps.session?.current()?.id,
15633
14966
  emit: emitRuntimeEvent,
15634
14967
  emitNotice,
15635
14968
  toolStartTimes
@@ -15765,6 +15098,11 @@ function createChatLoop(deps) {
15765
15098
  steer: (text) => queues.steer(text),
15766
15099
  queueFollowUp: (text) => queues.queueFollowUp(text),
15767
15100
  interruptRefusal: () => state.streaming ? interruptRefusalReason() : null,
15101
+ clearSkillSurface: () => {
15102
+ const cleared = skillSurfaceNames(state.activeSkillSurface);
15103
+ armSkillSurface(void 0);
15104
+ return cleared;
15105
+ },
15768
15106
  clearQueuedFollowUps: () => queues.clearQueuedMirror().map((entry) => entry.text),
15769
15107
  queuedMessages: () => queues.queuedMessages(),
15770
15108
  async submit(text, options = {}) {
@@ -15831,7 +15169,11 @@ function createChatLoop(deps) {
15831
15169
  const images = options.images && options.images.length > 0 ? [...options.images] : void 0;
15832
15170
  const pendingSkillRequests = options.pendingSkillRequests ?? [];
15833
15171
  context.addWorkingContextPaths(options.workingContextPaths ?? []);
15834
- const pendingSkillPolicy = createPendingSkillToolPolicy(pendingSkillRequests);
15172
+ const pendingSkillPolicy = withModelSkillActivation(
15173
+ createPendingSkillToolPolicy(pendingSkillRequests) ?? state.activeSkillSurface,
15174
+ modelMayActivateSkills(deps.getAutonomy?.() ?? deps.getSettings().safety.autonomy)
15175
+ );
15176
+ const skillsLoadedBeforeTurn = new Set(pendingSkillPolicy?.loadedSkillNames ?? []);
15835
15177
  agentRuntime.agent.state.tools = resolveSessionTools(
15836
15178
  agentRuntime,
15837
15179
  deps.toolRegistry,
@@ -16027,6 +15369,7 @@ function createChatLoop(deps) {
16027
15369
  }
16028
15370
  state.currentPendingSkillPolicy = priorPendingSkillPolicy;
16029
15371
  state.currentAskUserPolicy = priorAskUserPolicy;
15372
+ armSkillSurface(pendingSkillPolicy, skillsLoadedBeforeTurn);
16030
15373
  state.activeUserTurnId = null;
16031
15374
  context.flushReconciledSnapshot();
16032
15375
  if (!await queues.resubmitStrandedSteers()) await queues.resubmitRequestContinuation();
@@ -16231,8 +15574,8 @@ function createChatLoop(deps) {
16231
15574
  const previous = admissionTail;
16232
15575
  let release = () => {
16233
15576
  };
16234
- const ticket = new Promise((resolve8) => {
16235
- release = resolve8;
15577
+ const ticket = new Promise((resolve9) => {
15578
+ release = resolve9;
16236
15579
  });
16237
15580
  admissionTail = ticket;
16238
15581
  const releaseTicket = () => {
@@ -17091,8 +16434,8 @@ var AskUserOverlayView = class {
17091
16434
  this.setSurface(askUserSurface(this.questions, this.history.length));
17092
16435
  this.rebuildControl();
17093
16436
  this.deps.requestRender();
17094
- return new Promise((resolve8) => {
17095
- this.resolveCurrent = resolve8;
16437
+ return new Promise((resolve9) => {
16438
+ this.resolveCurrent = resolve9;
17096
16439
  });
17097
16440
  }
17098
16441
  cancel() {
@@ -17329,7 +16672,7 @@ var AskUserOverlayView = class {
17329
16672
  this.deps.onSurface(next);
17330
16673
  }
17331
16674
  finish(result) {
17332
- const resolve8 = this.resolveCurrent;
16675
+ const resolve9 = this.resolveCurrent;
17333
16676
  this.resolveCurrent = null;
17334
16677
  this.list = null;
17335
16678
  this.input = null;
@@ -17338,7 +16681,7 @@ var AskUserOverlayView = class {
17338
16681
  if (this.phase !== "closed") this.phase = "waiting";
17339
16682
  if (this.history.length > 0) this.setSurface("interview");
17340
16683
  this.deps.requestRender();
17341
- resolve8?.(result);
16684
+ resolve9?.(result);
17342
16685
  }
17343
16686
  renderWaiting(width, maxRows) {
17344
16687
  const theme6 = clioTheme();
@@ -18073,14 +17416,14 @@ function createAuthDialogController(title, onCancel) {
18073
17416
  });
18074
17417
  input.onSubmit = () => {
18075
17418
  if (!resolver) return;
18076
- const resolve8 = resolver;
17419
+ const resolve9 = resolver;
18077
17420
  resolver = void 0;
18078
17421
  rejecter = void 0;
18079
17422
  const value = input.getValue();
18080
17423
  promptLabel = null;
18081
17424
  input.setValue("");
18082
17425
  rebuild();
18083
- resolve8(value);
17426
+ resolve9(value);
18084
17427
  };
18085
17428
  input.onEscape = () => {
18086
17429
  cancel();
@@ -18134,8 +17477,8 @@ function createAuthDialogController(title, onCancel) {
18134
17477
  promptLabel = label;
18135
17478
  input.setValue("");
18136
17479
  rebuild();
18137
- return new Promise((resolve8, reject) => {
18138
- resolver = resolve8;
17480
+ return new Promise((resolve9, reject) => {
17481
+ resolver = resolve9;
18139
17482
  rejecter = reject;
18140
17483
  });
18141
17484
  }
@@ -18359,10 +17702,10 @@ function createOverlayAuthLifecycle(deps) {
18359
17702
  },
18360
17703
  onPrompt: async (prompt) => (await dialog.controller.prompt(prompt.message)).trim(),
18361
17704
  onSelect: (prompt) => selectOAuthOption(prompt, [`Target: ${targetId}`, `Runtime: ${runtime.id}`]),
18362
- onManualCodeInput: async () => await new Promise((resolve8, reject) => {
17705
+ onManualCodeInput: async () => await new Promise((resolve9, reject) => {
18363
17706
  manualCodeTimer = setTimeout(() => {
18364
17707
  manualCodeTimer = null;
18365
- dialog.controller.prompt("Verification code").then((value) => resolve8(value.trim())).catch(reject);
17708
+ dialog.controller.prompt("Verification code").then((value) => resolve9(value.trim())).catch(reject);
18366
17709
  }, 1e4);
18367
17710
  manualCodeTimer.unref?.();
18368
17711
  }),
@@ -18667,6 +18010,7 @@ function aggregateCostEntries(entries) {
18667
18010
  if (entry.label === "handoff") existing.row.handoffs += 1;
18668
18011
  if (entry.label === "prewarm") existing.row.prewarms += 1;
18669
18012
  if (entry.label === "background-memory") existing.row.backgroundMemory += 1;
18013
+ if (entry.label === "failed-compaction") existing.row.failedCompaction += 1;
18670
18014
  for (const requestedModelId of entry.requestedModelIds) existing.requestedModelIds.add(requestedModelId);
18671
18015
  addResponseModelIdObservationCounts(
18672
18016
  existing.responseModelIdObservationCounts,
@@ -18690,7 +18034,8 @@ function aggregateCostEntries(entries) {
18690
18034
  sideQuestions: entry.label === "side-question" ? 1 : 0,
18691
18035
  handoffs: entry.label === "handoff" ? 1 : 0,
18692
18036
  prewarms: entry.label === "prewarm" ? 1 : 0,
18693
- backgroundMemory: entry.label === "background-memory" ? 1 : 0
18037
+ backgroundMemory: entry.label === "background-memory" ? 1 : 0,
18038
+ failedCompaction: entry.label === "failed-compaction" ? 1 : 0
18694
18039
  },
18695
18040
  requestedModelIds: new Set(entry.requestedModelIds),
18696
18041
  responseModelIdObservationCounts: { ...entry.responseModelIdObservationCounts },
@@ -18724,7 +18069,8 @@ function sumRows(rows) {
18724
18069
  sideQuestions: acc.sideQuestions + row2.sideQuestions,
18725
18070
  handoffs: acc.handoffs + row2.handoffs,
18726
18071
  prewarms: acc.prewarms + row2.prewarms,
18727
- backgroundMemory: acc.backgroundMemory + row2.backgroundMemory
18072
+ backgroundMemory: acc.backgroundMemory + row2.backgroundMemory,
18073
+ failedCompaction: acc.failedCompaction + row2.failedCompaction
18728
18074
  }),
18729
18075
  {
18730
18076
  runs: 0,
@@ -18738,7 +18084,8 @@ function sumRows(rows) {
18738
18084
  sideQuestions: 0,
18739
18085
  handoffs: 0,
18740
18086
  prewarms: 0,
18741
- backgroundMemory: 0
18087
+ backgroundMemory: 0,
18088
+ failedCompaction: 0
18742
18089
  }
18743
18090
  );
18744
18091
  }
@@ -18777,13 +18124,19 @@ function summaryBlock(totalCost, totalTokens, rows, promptCache) {
18777
18124
  return kvBlock([
18778
18125
  [
18779
18126
  "turns",
18780
- formatTokens2(totals.runs - totals.sideQuestions - totals.handoffs - totals.prewarms - totals.backgroundMemory)
18127
+ formatTokens2(
18128
+ totals.runs - totals.sideQuestions - totals.handoffs - totals.prewarms - totals.backgroundMemory - totals.failedCompaction
18129
+ )
18781
18130
  ],
18782
18131
  ["model calls", formatTokens2(totals.apiCalls)],
18783
18132
  ...totals.sideQuestions > 0 ? [["side questions", formatTokens2(totals.sideQuestions)]] : [],
18784
18133
  ...totals.handoffs > 0 ? [["handoffs", formatTokens2(totals.handoffs)]] : [],
18785
18134
  ...totals.prewarms > 0 ? [["pre-warms", formatTokens2(totals.prewarms)]] : [],
18786
18135
  ...totals.backgroundMemory > 0 ? [["memory steps", formatTokens2(totals.backgroundMemory)]] : [],
18136
+ ...totals.failedCompaction > 0 ? [
18137
+ ["failed compaction calls", formatTokens2(totals.failedCompaction)],
18138
+ ["compaction usage", "known subtotals; missing usage is unknown"]
18139
+ ] : [],
18787
18140
  ...cost === null ? [] : [["cost", cost]],
18788
18141
  ["input", formatTokens2(totals.input)],
18789
18142
  ["output", formatTokens2(totals.output)],
@@ -18799,12 +18152,18 @@ function modelBlock(row2) {
18799
18152
  return kvBlock([
18800
18153
  ["requested model ids", row2.requestedModelIds.join(", ")],
18801
18154
  ["response model id observation", responseModelIdObservationCountsLabel(row2.responseModelIdObservationCounts)],
18802
- ["turns", formatTokens2(row2.runs - row2.sideQuestions - row2.handoffs - row2.prewarms - row2.backgroundMemory)],
18155
+ [
18156
+ "turns",
18157
+ formatTokens2(
18158
+ row2.runs - row2.sideQuestions - row2.handoffs - row2.prewarms - row2.backgroundMemory - row2.failedCompaction
18159
+ )
18160
+ ],
18803
18161
  ["model calls", formatTokens2(row2.apiCalls)],
18804
18162
  ...row2.sideQuestions > 0 ? [["side questions", formatTokens2(row2.sideQuestions)]] : [],
18805
18163
  ...row2.handoffs > 0 ? [["handoffs", formatTokens2(row2.handoffs)]] : [],
18806
18164
  ...row2.prewarms > 0 ? [["pre-warms", formatTokens2(row2.prewarms)]] : [],
18807
18165
  ...row2.backgroundMemory > 0 ? [["memory steps", formatTokens2(row2.backgroundMemory)]] : [],
18166
+ ...row2.failedCompaction > 0 ? [["failed compaction calls", formatTokens2(row2.failedCompaction)]] : [],
18808
18167
  ...cost === null ? [] : [["cost", cost]],
18809
18168
  ["input", formatTokens2(row2.input)],
18810
18169
  ["output", formatTokens2(row2.output)],
@@ -19003,7 +18362,7 @@ function compileFleetRunPreview(input) {
19003
18362
  };
19004
18363
  if (input.budget) {
19005
18364
  if (input.budget.verdict === "over" || input.budget.verdict === "at") {
19006
- diagnostics.push(`budget ceiling crossed: $${budget.currentUsd.toFixed(4)} / $${budget.ceilingUsd.toFixed(4)}`);
18365
+ diagnostics.push(`budget ceiling crossed: ${formatUsd(budget.currentUsd)} / ${formatUsd(budget.ceilingUsd)}`);
19007
18366
  } else if (contract.budgetUsd !== null) {
19008
18367
  const remaining = budget.ceilingUsd - budget.currentUsd;
19009
18368
  if (contract.budgetUsd > remaining) {
@@ -20273,7 +19632,7 @@ function formatFleetRunPreviewStep(step) {
20273
19632
  }
20274
19633
  function formatBudgetLine(preview) {
20275
19634
  const contract = preview.budget.contractUsd === null ? "contract declares no ceiling" : `contract ceiling $${preview.budget.contractUsd.toFixed(2)}`;
20276
- return `budget: admitted under $${preview.budget.ceilingUsd.toFixed(2)} session ceiling, $${preview.budget.currentUsd.toFixed(4)} spent, ${contract}`;
19635
+ return `budget: admitted under $${preview.budget.ceilingUsd.toFixed(2)} session ceiling, ${formatUsd(preview.budget.currentUsd)} spent, ${contract}`;
20277
19636
  }
20278
19637
  function formatFleetRunApprovalBody(subject, width, scroll) {
20279
19638
  const theme6 = clioTheme();
@@ -22520,10 +21879,10 @@ var SETTINGS_VALUE_HELP_BY_ID = {
22520
21879
  false: "context is only compacted when you run /context compact"
22521
21880
  },
22522
21881
  // `embedded` is a declared rung with no implementation behind it yet; it
22523
- // runs as `auto` until Clio can own a pane host, and the hint says so.
21882
+ // refuses until Clio can own a pane host, and the hint says so.
22524
21883
  "panes.enabled": {
22525
21884
  auto: "detect a herdr session and join it as a guest; no pane host, no panes",
22526
- embedded: "not implemented yet; behaves as auto (guest mode inside herdr) until Clio can own a pane host",
21885
+ embedded: "not implemented yet; use auto or guest",
22527
21886
  off: "never detect or open a pane"
22528
21887
  },
22529
21888
  "retry.enabled": {
@@ -23011,12 +22370,12 @@ function scopedModelsSubmenu(selectedRefs, providers) {
23011
22370
  "Target entries cycle by target, using its default model when switching targets. Model entries pin one exact target/model reference."
23012
22371
  );
23013
22372
  }
23014
- function chainSubmenus(first, second, join13) {
22373
+ function chainSubmenus(first, second, join12) {
23015
22374
  return (_currentValue, done) => {
23016
22375
  let active = first("", (head) => {
23017
22376
  const trimmed = head?.trim() ?? "";
23018
22377
  if (!trimmed) return done();
23019
- active = second(trimmed)("", (tail) => done(tail?.trim() ? join13(trimmed, tail.trim()) : void 0));
22378
+ active = second(trimmed)("", (tail) => done(tail?.trim() ? join12(trimmed, tail.trim()) : void 0));
23020
22379
  });
23021
22380
  return {
23022
22381
  render: (width) => active.render(width),
@@ -24327,11 +23686,11 @@ function applyEntrySettingChange(settings, id, value) {
24327
23686
  }
24328
23687
  function changedLeafPaths(before, after) {
24329
23688
  const out = [];
24330
- const isRecord11 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
23689
+ const isRecord10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
24331
23690
  const visit = (a, b, path2) => {
24332
23691
  if (a === b) return;
24333
23692
  const profileLeaf = path2.startsWith("fleet.profiles.") && path2.split(".").length === 3;
24334
- if (!isRecord11(a) || !isRecord11(b) || profileLeaf) {
23693
+ if (!isRecord10(a) || !isRecord10(b) || profileLeaf) {
24335
23694
  if (JSON.stringify(a) !== JSON.stringify(b)) out.push(path2);
24336
23695
  return;
24337
23696
  }
@@ -27092,14 +26451,14 @@ function openSkillsHub(tui, deps) {
27092
26451
  let pendingWithRequirements = null;
27093
26452
  const columns = () => typeof process.stdout.columns === "number" ? process.stdout.columns : 100;
27094
26453
  let handle;
27095
- const confirmInstall = deps.confirmInstall ?? ((subject) => new Promise((resolve8) => {
26454
+ const confirmInstall = deps.confirmInstall ?? ((subject) => new Promise((resolve9) => {
27096
26455
  handle.setHidden(true);
27097
26456
  const settle = (accepted) => {
27098
26457
  if (!closed) {
27099
26458
  handle.setHidden(false);
27100
26459
  handle.focus();
27101
26460
  }
27102
- resolve8(accepted);
26461
+ resolve9(accepted);
27103
26462
  };
27104
26463
  const confirmation = openLibraryInstallConfirmOverlay(tui, {
27105
26464
  subject,
@@ -27301,9 +26660,9 @@ init_esm_shims();
27301
26660
 
27302
26661
  // src/domains/session/cwd-fallback.ts
27303
26662
  init_esm_shims();
27304
- import { existsSync as existsSync7, statSync as statSync2 } from "node:fs";
26663
+ import { existsSync as existsSync6, statSync as statSync2 } from "node:fs";
27305
26664
  var defaultFsProbe = {
27306
- exists: (p) => existsSync7(p),
26665
+ exists: (p) => existsSync6(p),
27307
26666
  isDirectory: (p) => {
27308
26667
  try {
27309
26668
  return statSync2(p).isDirectory();
@@ -27341,9 +26700,9 @@ function runCompactWithNotice(onCompact, notice, instructions) {
27341
26700
  init_esm_shims();
27342
26701
  import { spawnSync } from "node:child_process";
27343
26702
  import { randomUUID as randomUUID2 } from "node:crypto";
27344
- import { readFileSync as readFileSync8, unlinkSync, writeFileSync } from "node:fs";
26703
+ import { readFileSync as readFileSync7, unlinkSync, writeFileSync } from "node:fs";
27345
26704
  import { tmpdir } from "node:os";
27346
- import { join as join7 } from "node:path";
26705
+ import { join as join6 } from "node:path";
27347
26706
  function defaultProbe(candidates) {
27348
26707
  for (const candidate of candidates) {
27349
26708
  const result = spawnSync("sh", ["-lc", `command -v ${candidate}`], {
@@ -27375,13 +26734,13 @@ function resolveExternalEditor(env = process.env, probe = defaultProbe) {
27375
26734
  }
27376
26735
  function editTextExternally(initialText, command) {
27377
26736
  if (!command) return { ok: false, error: "no external editor configured; set VISUAL or EDITOR" };
27378
- const tmpFile = join7(tmpdir(), `clio-coder-editor-${process.pid}-${randomUUID2()}.md`);
26737
+ const tmpFile = join6(tmpdir(), `clio-coder-editor-${process.pid}-${randomUUID2()}.md`);
27379
26738
  try {
27380
26739
  writeFileSync(tmpFile, initialText, "utf8");
27381
26740
  const result = runEditor(command, tmpFile);
27382
26741
  if (result.error) return { ok: false, error: result.error.message };
27383
26742
  if (result.status !== 0) return { ok: false, error: `external editor exited with code ${result.status ?? "?"}` };
27384
- return { ok: true, text: readFileSync8(tmpFile, "utf8").replace(/\n$/, "") };
26743
+ return { ok: true, text: readFileSync7(tmpFile, "utf8").replace(/\n$/, "") };
27385
26744
  } finally {
27386
26745
  try {
27387
26746
  unlinkSync(tmpFile);
@@ -28729,9 +28088,9 @@ function createOverlaySessionLifecycle(deps) {
28729
28088
  openHandoffReview(session, fromSessionId, goal, document);
28730
28089
  }
28731
28090
  function editHandoffDocument(current) {
28732
- const resolve8 = deps.resolveEditor ?? resolveExternalEditor;
28091
+ const resolve9 = deps.resolveEditor ?? resolveExternalEditor;
28733
28092
  const edit = deps.editExternally ?? editTextExternally;
28734
- const command = resolve8();
28093
+ const command = resolve9();
28735
28094
  if (!command) {
28736
28095
  deps.notify("warning", "handoff: no external editor configured; set VISUAL or EDITOR", "handoff:no-editor");
28737
28096
  return null;
@@ -29426,8 +28785,8 @@ function resolveApplicationCtrlCAction(state) {
29426
28785
  function createApplicationController(deps) {
29427
28786
  let resolveRun = () => {
29428
28787
  };
29429
- const run = new Promise((resolve8) => {
29430
- resolveRun = resolve8;
28788
+ const run = new Promise((resolve9) => {
28789
+ resolveRun = resolve9;
29431
28790
  });
29432
28791
  const keepAlive = deps.intervals.setInterval(() => {
29433
28792
  }, 1 << 30);
@@ -30204,16 +29563,16 @@ function createInteractiveDesktopNotifications(deps) {
30204
29563
  } catch {
30205
29564
  return;
30206
29565
  }
30207
- const open2 = /* @__PURE__ */ new Set();
29566
+ const open3 = /* @__PURE__ */ new Set();
30208
29567
  for (const view of views) {
30209
- open2.add(view.id);
29568
+ open3.add(view.id);
30210
29569
  if (view.total <= 0 || view.terminal < view.total) continue;
30211
29570
  if (announcedBatches.has(view.id)) continue;
30212
29571
  announcedBatches.add(view.id);
30213
29572
  notifier.notify({ kind: "batch-settled", shortId: view.id.slice(0, BATCH_SHORT_ID_CHARS) });
30214
29573
  }
30215
29574
  for (const id of [...announcedBatches]) {
30216
- if (!open2.has(id)) announcedBatches.delete(id);
29575
+ if (!open3.has(id)) announcedBatches.delete(id);
30217
29576
  }
30218
29577
  },
30219
29578
  approvalParked() {
@@ -30983,11 +30342,11 @@ function classifyInputAction(data, deps) {
30983
30342
 
30984
30343
  // src/interactive/interactive-presentation.ts
30985
30344
  init_esm_shims();
30986
- import { performance as performance6 } from "node:perf_hooks";
30345
+ import { performance as performance5 } from "node:perf_hooks";
30987
30346
 
30988
30347
  // src/interactive/chat-panel.ts
30989
30348
  init_esm_shims();
30990
- import { performance as performance5 } from "node:perf_hooks";
30349
+ import { performance as performance4 } from "node:perf_hooks";
30991
30350
 
30992
30351
  // src/interactive/renderers/code-ink.ts
30993
30352
  init_esm_shims();
@@ -31480,6 +30839,27 @@ function researchReport(value) {
31480
30839
  }
31481
30840
  return { lines: lines.length === 0 ? ["No findings reported."] : lines, footer: `source ${value.source}` };
31482
30841
  }
30842
+ function worldKnowledgeReport(value) {
30843
+ if (value.discovery !== "performed" && value.discovery !== "caller-supplied-only" && value.discovery !== "unavailable" || !Array.isArray(value.facts) || !isStringArray(value.synthesis) || !isStringArray(value.uncertainties) || !isStringArray(value.followUpVerification)) {
30844
+ return null;
30845
+ }
30846
+ const lines = [];
30847
+ for (const raw of value.facts) {
30848
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return null;
30849
+ const fact = raw;
30850
+ const claim = reportString(fact.claim);
30851
+ const evidence = reportString(fact.evidence);
30852
+ if (claim === null || evidence === null || !isStringArray(fact.sources)) return null;
30853
+ lines.push(`- ${claim}`, ` support: ${evidence}`);
30854
+ if (fact.sources.length > 0) lines.push(` sources: ${fact.sources.join(", ")}`);
30855
+ }
30856
+ if (value.synthesis.length > 0) lines.push("Synthesis:", ...value.synthesis.map((item) => `- ${item}`));
30857
+ if (value.uncertainties.length > 0) lines.push("Uncertainties:", ...value.uncertainties.map((item) => `- ${item}`));
30858
+ if (value.followUpVerification.length > 0) {
30859
+ lines.push("Verify next:", ...value.followUpVerification.map((item) => `- ${item}`));
30860
+ }
30861
+ return { lines: lines.length === 0 ? ["No findings reported."] : lines, footer: `discovery ${value.discovery}` };
30862
+ }
31483
30863
  function scoutReport(value) {
31484
30864
  if (!Array.isArray(value.findings) || typeof value.needsSplit !== "boolean") return null;
31485
30865
  const lines = [];
@@ -31523,6 +30903,8 @@ function presentedContractAnswer(entry) {
31523
30903
  return verifierReport(value);
31524
30904
  case "research-report":
31525
30905
  return researchReport(value);
30906
+ case "world-knowledge-report":
30907
+ return worldKnowledgeReport(value);
31526
30908
  case "scout-report":
31527
30909
  return scoutReport(value);
31528
30910
  }
@@ -32198,17 +31580,17 @@ function createChatPanel(options = {}) {
32198
31580
  return entry;
32199
31581
  };
32200
31582
  const closeOpenThinking = (entry) => {
32201
- const open2 = openThinkingSegment(entry);
32202
- if (open2 === null) return;
32203
- open2.finalized = true;
31583
+ const open3 = openThinkingSegment(entry);
31584
+ if (open3 === null) return;
31585
+ open3.finalized = true;
32204
31586
  invalidateEntryCache(entry);
32205
31587
  };
32206
31588
  const appendThinkingDelta = (entry, delta) => {
32207
31589
  if (delta.length === 0) return;
32208
31590
  invalidateEntryCache(entry);
32209
- const open2 = openThinkingSegment(entry);
32210
- if (open2 !== null) {
32211
- open2.text += delta;
31591
+ const open3 = openThinkingSegment(entry);
31592
+ if (open3 !== null) {
31593
+ open3.text += delta;
32212
31594
  return;
32213
31595
  }
32214
31596
  entry.segments.push({ kind: "thinking", text: delta, finalized: false, startedAtMs: now() });
@@ -32301,7 +31683,7 @@ function createChatPanel(options = {}) {
32301
31683
  ) || entry.pending && openThinkingSegment(entry)?.startedAtMs !== void 0) || entry.role === "replayBlock" && entry.isLive?.() === true || entry.role === "user" && (entry.status?.() ?? "committed") !== "committed";
32302
31684
  const entryIsStable = (entry) => entry.role === "user" && (entry.status?.() ?? "committed") === "committed" || entry.role === "replayBlock" && entry.isLive?.() !== true || entry.role === "worker" && !entry.state.pending || entry.role === "assistant" && !entry.pending && !entry.segments.some((segment) => segment.kind === "tool" && !segment.finished);
32303
31685
  const render2 = (width) => {
32304
- const startedAt = performance5.now();
31686
+ const startedAt = performance4.now();
32305
31687
  const expandKey = resolveExpandKey();
32306
31688
  const verbosity = options.getOutputVerbosity?.();
32307
31689
  if (lastVerbosity !== null && verbosity !== lastVerbosity) dropFoldOverrides();
@@ -32310,7 +31692,7 @@ function createChatPanel(options = {}) {
32310
31692
  const nowMs = now();
32311
31693
  const tick = renderedRunningTool ? Math.floor(nowMs / 100) : 0;
32312
31694
  if (!dirty && cachedWidth === width && cachedExpandKey === expandKey && cachedDetail === detail && cachedLiveToolOutput === liveToolOutput && cachedTick === tick) {
32313
- options.onRenderMetrics?.({ durationMs: performance5.now() - startedAt, cacheHit: true, entriesRendered: 0 });
31695
+ options.onRenderMetrics?.({ durationMs: performance4.now() - startedAt, cacheHit: true, entriesRendered: 0 });
32314
31696
  return cachedLines;
32315
31697
  }
32316
31698
  const { toolId: latestHintToolId, workerId: latestFoldedWorkerId } = expandHintOwner(detail);
@@ -32377,7 +31759,7 @@ function createChatPanel(options = {}) {
32377
31759
  cachedTick = tick;
32378
31760
  renderedRunningTool = sawRunningTool;
32379
31761
  dirty = false;
32380
- options.onRenderMetrics?.({ durationMs: performance5.now() - startedAt, cacheHit: false, entriesRendered });
31762
+ options.onRenderMetrics?.({ durationMs: performance4.now() - startedAt, cacheHit: false, entriesRendered });
32381
31763
  return out;
32382
31764
  };
32383
31765
  return {
@@ -33412,7 +32794,7 @@ init_esm_shims();
33412
32794
  import { execFile as execFile2 } from "node:child_process";
33413
32795
  import { open, readdir, stat as stat2 } from "node:fs/promises";
33414
32796
  import { homedir as homedir2 } from "node:os";
33415
- import { basename as basename3, dirname as dirname2, join as join8, relative as relative7, resolve as resolve5, sep as sep2 } from "node:path";
32797
+ import { basename as basename3, dirname as dirname2, join as join7, relative as relative7, resolve as resolve5, sep as sep2 } from "node:path";
33416
32798
  var MAX_COMPLETION_ROWS = 40;
33417
32799
  var PREVIEW_BYTES = 2048;
33418
32800
  var PREVIEW_CHARS = 120;
@@ -33460,7 +32842,7 @@ function buildWorkspaceSnapshot(basePath, visibleFiles, trackedFiles) {
33460
32842
  const tracked = trackedFiles.has(path2);
33461
32843
  files.push({
33462
32844
  path: path2,
33463
- absolutePath: join8(basePath, path2),
32845
+ absolutePath: join7(basePath, path2),
33464
32846
  isDirectory: false,
33465
32847
  tracked,
33466
32848
  descendantFiles: 0,
@@ -33478,7 +32860,7 @@ function buildWorkspaceSnapshot(basePath, visibleFiles, trackedFiles) {
33478
32860
  const directories = [...directoryFacts].map(
33479
32861
  ([path2, facts]) => ({
33480
32862
  path: path2,
33481
- absolutePath: join8(basePath, path2),
32863
+ absolutePath: join7(basePath, path2),
33482
32864
  isDirectory: true,
33483
32865
  tracked: facts.tracked,
33484
32866
  descendantFiles: facts.descendantFiles,
@@ -33553,7 +32935,7 @@ async function explicitCandidates(basePath, query, trackedFiles) {
33553
32935
  const candidates = [];
33554
32936
  for (const entry of await readdir(directory, { withFileTypes: true })) {
33555
32937
  if (entry.name === ".git" || /[\r\n\0]/u.test(entry.name)) continue;
33556
- const absolutePath = join8(directory, entry.name);
32938
+ const absolutePath = join7(directory, entry.name);
33557
32939
  let isDirectory = entry.isDirectory();
33558
32940
  let isFile = entry.isFile();
33559
32941
  if (!isDirectory && !isFile && entry.isSymbolicLink()) {
@@ -33676,7 +33058,7 @@ function createFileReferenceCompletionSource(options) {
33676
33058
  // src/interactive/slash-autocomplete.ts
33677
33059
  var ARGUMENT_HINT_BUDGET = 44;
33678
33060
  var COMPLETION_DESCRIPTION_BUDGET = 80;
33679
- function stubCompletionSources() {
33061
+ function emptyCompletionSources() {
33680
33062
  const sources = {};
33681
33063
  for (const slot of COMPLETION_SLOT_NAMES) sources[slot] = async () => [];
33682
33064
  return sources;
@@ -33862,7 +33244,7 @@ var ClioAutocompleteProvider = class {
33862
33244
  constructor(basePath, fdPath, sources, fileReferenceSource) {
33863
33245
  this.files = new CombinedAutocompleteProvider([], basePath, fdPath);
33864
33246
  this.fileReferences = fileReferenceSource ?? createFileReferenceCompletionSource({ basePath });
33865
- this.sourceBySlot = { ...stubCompletionSources(), ...sources };
33247
+ this.sourceBySlot = { ...emptyCompletionSources(), ...sources };
33866
33248
  }
33867
33249
  async getSuggestions(lines, cursorLine, cursorCol, options) {
33868
33250
  const generation = ++this.generation;
@@ -34099,8 +33481,8 @@ function processAutoPacingAllowed(backpressureObserved, env = process.env) {
34099
33481
 
34100
33482
  // src/interactive/welcome-dashboard.ts
34101
33483
  init_esm_shims();
34102
- import { existsSync as existsSync8, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
34103
- import { basename as basename4, join as join9 } from "node:path";
33484
+ import { existsSync as existsSync7, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
33485
+ import { basename as basename4, join as join8 } from "node:path";
34104
33486
  function activeStatus(status) {
34105
33487
  return status.available && status.health.status !== "down";
34106
33488
  }
@@ -34166,14 +33548,14 @@ function wikiFactsFrom(cwd, staleness) {
34166
33548
  };
34167
33549
  }
34168
33550
  function handoffFacts(cwd) {
34169
- const handoffsDir = join9(cwd, ".clio-coder", "handoffs");
34170
- if (!existsSync8(handoffsDir)) return { handoffCount: 0, handoffFreshness: "none" };
33551
+ const handoffsDir = join8(cwd, ".clio-coder", "handoffs");
33552
+ if (!existsSync7(handoffsDir)) return { handoffCount: 0, handoffFreshness: "none" };
34171
33553
  try {
34172
33554
  const files = readdirSync2(handoffsDir).filter((f) => f.startsWith("handoff-") && f.endsWith(".md"));
34173
33555
  if (files.length === 0) return { handoffCount: 0, handoffFreshness: "none" };
34174
33556
  let newestMtime = 0;
34175
33557
  for (const file of files) {
34176
- const mtime = statSync3(join9(handoffsDir, file)).mtimeMs;
33558
+ const mtime = statSync3(join8(handoffsDir, file)).mtimeMs;
34177
33559
  if (mtime > newestMtime) newestMtime = mtime;
34178
33560
  }
34179
33561
  return {
@@ -34211,7 +33593,7 @@ async function readWelcomeRepositoryFactsAsync(cwd) {
34211
33593
  function placeholderRepositoryFacts(cwd) {
34212
33594
  return {
34213
33595
  clioMdStatus: clioMdStatusFor(cwd),
34214
- hasCodewiki: existsSync8(join9(cwd, ".clio-coder", "codewiki.json")),
33596
+ hasCodewiki: existsSync7(join8(cwd, ".clio-coder", "codewiki.json")),
34215
33597
  codewikiCount: 0,
34216
33598
  wikiPageCount: 0,
34217
33599
  wikiStatus: NO_WIKI_STATUS,
@@ -34463,7 +33845,7 @@ function willEnterSteerActiveWork(deps, text) {
34463
33845
  function createInteractivePresentation(deps) {
34464
33846
  const factories = { ...DEFAULT_FACTORIES, ...deps.factories };
34465
33847
  const getCwd = deps.getCwd ?? (() => process.cwd());
34466
- const now = deps.now ?? performance6.now.bind(performance6);
33848
+ const now = deps.now ?? performance5.now.bind(performance5);
34467
33849
  const requestRender = () => deps.tui.requestRender();
34468
33850
  const settings = deps.getSettings?.() ?? structuredClone(DEFAULT_SETTINGS);
34469
33851
  const keybindings = deps.keybindings ?? factories.createKeybindings(settings);
@@ -34501,11 +33883,11 @@ function createInteractivePresentation(deps) {
34501
33883
  bus: deps.bus,
34502
33884
  ...deps.getSettings ? { getSettings: deps.getSettings } : {}
34503
33885
  });
34504
- const dispatchBoardStore = factories.createDispatchBoardStore(
34505
- deps.bus,
34506
- () => deps.dispatch.snapshot(),
34507
- (runId) => readWorkerReceiptFacts(runId)
34508
- );
33886
+ const unbindRunReaders = deps.observability.bindRunReaders({
33887
+ dispatchSnapshot: () => deps.dispatch.snapshot(),
33888
+ readReceipt: (runId) => readWorkerReceiptFacts(runId)
33889
+ });
33890
+ const dispatchBoardStore = factories.createDispatchBoardStore(deps.observability);
34509
33891
  const contextActivityStore = factories.createContextActivityStore(deps.bus);
34510
33892
  const footerToolCounts = /* @__PURE__ */ new Map();
34511
33893
  const footerActiveTools = /* @__PURE__ */ new Set();
@@ -34662,10 +34044,47 @@ function createInteractivePresentation(deps) {
34662
34044
  const editor = deps.editor ?? factories.createEditor(deps.tui, editorChrome);
34663
34045
  editor.focused = true;
34664
34046
  const autocomplete = factories.createAutocomplete({
34665
- listSkills: () => ({
34666
- installed: deps.resources?.skills(getCwd()).items ?? [],
34667
- marketplace: getMarketplaceSkills()
34668
- })
34047
+ completionSources: {
34048
+ agents: async () => (deps.agents?.listSpecs() ?? []).filter(isUserVisibleAgent).map((agent) => ({
34049
+ id: agent.id,
34050
+ value: agent.id,
34051
+ label: agent.id,
34052
+ description: agent.description
34053
+ })),
34054
+ targets: async () => deps.providers.list().map(({ target, reason }) => ({
34055
+ id: target.id,
34056
+ value: target.id,
34057
+ label: target.id,
34058
+ description: reason
34059
+ })),
34060
+ models: async () => deps.providers.list().flatMap(
34061
+ ({ target, discoveredModels, discoveredModelLabels }) => [
34062
+ .../* @__PURE__ */ new Set([
34063
+ ...target.defaultModel ? [target.defaultModel] : [],
34064
+ ...target.wireModels ?? [],
34065
+ ...discoveredModels
34066
+ ])
34067
+ ].map((model) => ({
34068
+ id: `${target.id}/${model}`,
34069
+ value: model,
34070
+ label: discoveredModelLabels?.[model] ?? model,
34071
+ description: target.id
34072
+ }))
34073
+ ),
34074
+ skills: async () => (deps.resources?.skills(getCwd()).items ?? []).map((skill) => ({
34075
+ id: skill.name,
34076
+ value: skill.name,
34077
+ label: skill.name,
34078
+ description: skill.description
34079
+ })),
34080
+ tasks: async () => (deps.getTaskBoard?.()?.tasks ?? []).map((task) => ({
34081
+ id: task.id,
34082
+ value: task.id,
34083
+ label: task.title,
34084
+ description: task.status
34085
+ }))
34086
+ // Other slots remain empty when this presentation has no read-only catalog for them.
34087
+ }
34669
34088
  });
34670
34089
  editor.setAutocompleteProvider(autocomplete);
34671
34090
  const dispatchBoard = factories.createDispatchBoardView(
@@ -34756,6 +34175,7 @@ function createInteractivePresentation(deps) {
34756
34175
  unsubscribeObservability();
34757
34176
  contextActivityStore.unsubscribe();
34758
34177
  dispatchBoardStore.unsubscribe();
34178
+ unbindRunReaders();
34759
34179
  };
34760
34180
  const disposeStatus = () => {
34761
34181
  if (statusDisposed) return;
@@ -34822,7 +34242,7 @@ function createInteractivePresentation(deps) {
34822
34242
  // src/interactive/interactive-slash-runtime.ts
34823
34243
  init_esm_shims();
34824
34244
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
34825
- import { join as join10, resolve as resolve6 } from "node:path";
34245
+ import { join as join9, resolve as resolve6 } from "node:path";
34826
34246
 
34827
34247
  // src/interactive/context-recall-command.ts
34828
34248
  init_esm_shims();
@@ -35169,8 +34589,8 @@ function createInteractiveSlashRuntime(deps) {
35169
34589
  deps.requestRender();
35170
34590
  let acknowledgeAdmission = () => {
35171
34591
  };
35172
- const admitted = new Promise((resolve8) => {
35173
- acknowledgeAdmission = resolve8;
34592
+ const admitted = new Promise((resolve9) => {
34593
+ acknowledgeAdmission = resolve9;
35174
34594
  });
35175
34595
  const turn = deps.chat.submit(sub.text, {
35176
34596
  ...sub.images.length > 0 ? { images: sub.images } : {},
@@ -35291,6 +34711,7 @@ function createInteractiveSlashRuntime(deps) {
35291
34711
  listPrompts: () => deps.resources?.prompts(cwd()) ?? { items: [], diagnostics: [] },
35292
34712
  ...resources ? { expandPromptTemplate: (text) => resources.expandPromptTemplate(text, cwd()) } : {},
35293
34713
  openSkillsHub: deps.openSkillsHub,
34714
+ clearSkillSurface: () => deps.chat.clearSkillSurface(),
35294
34715
  listExtensions: () => deps.extensions?.list(cwd(), { all: true }) ?? [],
35295
34716
  listAgents: () => deps.agents?.listSpecs().filter((spec) => spec.audience !== "internal") ?? [],
35296
34717
  listDelegationAgents: () => deps.getSettings?.().integrations.externalAgents.entries ?? [],
@@ -35330,7 +34751,7 @@ function createInteractiveSlashRuntime(deps) {
35330
34751
  openDecisions: deps.openDecisions,
35331
34752
  ...userTasks ? {
35332
34753
  userTasks: {
35333
- add: (title) => userTasks.add(title),
34754
+ add: (title, acceptance) => userTasks.add(title, void 0, acceptance),
35334
34755
  hand: (id) => userTasks.hand(id, deps.chat.getSessionId() ?? void 0),
35335
34756
  done: (id) => userTasks.done(id),
35336
34757
  drop: (id) => userTasks.drop(id)
@@ -35473,7 +34894,7 @@ function createInteractiveSlashRuntime(deps) {
35473
34894
  const requestedPath = pathArg?.trim() ?? "";
35474
34895
  const markdown = requestedPath.toLowerCase().endsWith(".md");
35475
34896
  const target = resolve6(
35476
- requestedPath.length > 0 ? requestedPath : join10(".clio-coder", "exports", `${sessionId}-${date}.html`)
34897
+ requestedPath.length > 0 ? requestedPath : join9(".clio-coder", "exports", `${sessionId}-${date}.html`)
35477
34898
  );
35478
34899
  mkdirSync2(resolve6(target, ".."), { recursive: true });
35479
34900
  if (markdown) {
@@ -36099,6 +35520,7 @@ async function createInteractiveApplication(deps) {
36099
35520
  } : {},
36100
35521
  ...deps.getSettings ? { getSettings: deps.getSettings } : {},
36101
35522
  ...deps.resources ? { resources: deps.resources } : {},
35523
+ ...deps.agents ? { agents: deps.agents } : {},
36102
35524
  ...deps.session ? { session: deps.session } : {},
36103
35525
  ...deps.getSessionId ? { getSessionId: deps.getSessionId } : {},
36104
35526
  ...deps.getTaskBoard ? { getTaskBoard: deps.getTaskBoard } : {},
@@ -36652,6 +36074,66 @@ async function startInteractive(deps) {
36652
36074
  return createInteractiveApplication(deps);
36653
36075
  }
36654
36076
 
36077
+ // src/entry/background-model-metadata.ts
36078
+ init_esm_shims();
36079
+ async function prepareBackgroundModelMetadata(providers, targetId, signal) {
36080
+ signal?.throwIfAborted();
36081
+ const status = providers.list().find((entry) => entry.target.id === targetId);
36082
+ if (status?.target.runtime === "litellm" && status.health.lastCheckAt === null) {
36083
+ await providers.probeTarget(targetId, { reasoning: false, ...signal ? { signal } : {} });
36084
+ }
36085
+ signal?.throwIfAborted();
36086
+ }
36087
+
36088
+ // src/entry/compaction-prompt.ts
36089
+ init_esm_shims();
36090
+ import { constants } from "node:fs";
36091
+ import { open as open2 } from "node:fs/promises";
36092
+ import { resolve as resolve7 } from "node:path";
36093
+ var MAX_PROMPT_BYTES = 64 * 1024;
36094
+ async function readCompactionSystemPrompt(path2, workspace) {
36095
+ if (path2 === void 0 || path2 === null) return void 0;
36096
+ const quotedPath = JSON.stringify(path2).replace(
36097
+ /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu,
36098
+ (character) => `\\u{${character.codePointAt(0)?.toString(16)}}`
36099
+ );
36100
+ const displayPath = quotedPath.length <= 1024 ? quotedPath : `${quotedPath.slice(0, 1024)}...`;
36101
+ const failure2 = (reason) => new Error(
36102
+ `context.compaction.systemPrompt ${displayPath} ${reason}; set a readable, nonempty UTF-8 file of at most ${MAX_PROMPT_BYTES} bytes (relative to the session workspace), or unset the override`
36103
+ );
36104
+ if (!path2.trim()) throw failure2("path is empty");
36105
+ let file;
36106
+ try {
36107
+ file = await open2(resolve7(workspace, path2), constants.O_RDONLY | constants.O_NONBLOCK);
36108
+ } catch {
36109
+ throw failure2("cannot be opened");
36110
+ }
36111
+ try {
36112
+ if (!(await file.stat()).isFile()) throw failure2("must refer to a regular file");
36113
+ const buffer = Buffer.alloc(MAX_PROMPT_BYTES + 1);
36114
+ let length = 0;
36115
+ while (length < buffer.length) {
36116
+ const { bytesRead } = await file.read(buffer, length, buffer.length - length, null);
36117
+ if (bytesRead === 0) break;
36118
+ length += bytesRead;
36119
+ }
36120
+ if (length > MAX_PROMPT_BYTES) throw failure2("file is oversized");
36121
+ let text;
36122
+ try {
36123
+ text = new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, length));
36124
+ } catch {
36125
+ throw failure2("file is not valid UTF-8");
36126
+ }
36127
+ if (!text.trim()) throw failure2("file is empty");
36128
+ return text;
36129
+ } catch (error) {
36130
+ if (error instanceof Error && error.message.startsWith("context.compaction.systemPrompt ")) throw error;
36131
+ throw failure2("file cannot be read");
36132
+ } finally {
36133
+ await file.close();
36134
+ }
36135
+ }
36136
+
36655
36137
  // src/entry/extension-reload.ts
36656
36138
  init_esm_shims();
36657
36139
  import { realpathSync as realpathSync2 } from "node:fs";
@@ -36862,6 +36344,27 @@ function resolvePanesEnablement(flag, setting) {
36862
36344
  return setting ?? "off";
36863
36345
  }
36864
36346
 
36347
+ // src/entry/task-memory-lifecycle.ts
36348
+ init_esm_shims();
36349
+ function bindTaskMemoryLifecycle(bus, memory) {
36350
+ const unsubscribe = [
36351
+ bus.on(BusChannels.SessionParked, () => memory.reset()),
36352
+ bus.on(BusChannels.SessionResumed, () => memory.reset()),
36353
+ bus.on(BusChannels.SessionTurnSwitched, () => memory.reset()),
36354
+ bus.on(BusChannels.SessionEnd, () => memory.dispose())
36355
+ ];
36356
+ return () => {
36357
+ memory.dispose();
36358
+ for (const off of unsubscribe) off();
36359
+ };
36360
+ }
36361
+ function captureTaskMemoryUsage(input) {
36362
+ const { observability, ...origin } = input;
36363
+ return (usage, isCurrent) => {
36364
+ recordBackgroundMemoryStep({ ...origin, usage, observability: isCurrent ? observability : void 0 });
36365
+ };
36366
+ }
36367
+
36865
36368
  // src/interactive/tool-prose-registration.ts
36866
36369
  init_esm_shims();
36867
36370
  var TOOL_PROSE_REGISTRATION_ID = "assessor.tool-prose-loop";
@@ -36939,12 +36442,12 @@ init_esm_shims();
36939
36442
 
36940
36443
  // src/tools/dispatch-admission.ts
36941
36444
  init_esm_shims();
36942
- import { isAbsolute as isAbsolute6, relative as relative8, resolve as resolve7 } from "node:path";
36445
+ import { isAbsolute as isAbsolute6, relative as relative8, resolve as resolve8 } from "node:path";
36943
36446
 
36944
36447
  // src/tools/dispatch-scout-admission.ts
36945
36448
  init_esm_shims();
36946
- import { existsSync as existsSync9, readFileSync as readFileSync9 } from "node:fs";
36947
- import { join as join11 } from "node:path";
36449
+ import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
36450
+ import { join as join10 } from "node:path";
36948
36451
  var MAX_SCOUT_PLAN_DEADLINE_MS = 36e5;
36949
36452
  function record(value) {
36950
36453
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -36991,11 +36494,11 @@ function validateScoutSource(receipt, envelope, agentSpecs) {
36991
36494
  function loadVerifiedScoutSource(input) {
36992
36495
  const envelope = input.dispatch.getRun(input.ref.runId);
36993
36496
  if (envelope === null) throw new Error(`dispatch: Scout source run '${input.ref.runId}' is unavailable`);
36994
- const receiptPath = envelope.receiptPath ?? join11(clioStateDir(), "receipts", `${input.ref.runId}.json`);
36995
- if (!existsSync9(receiptPath)) throw new Error(`dispatch: Scout source receipt '${input.ref.runId}' is unavailable`);
36497
+ const receiptPath = envelope.receiptPath ?? join10(clioStateDir(), "receipts", `${input.ref.runId}.json`);
36498
+ if (!existsSync8(receiptPath)) throw new Error(`dispatch: Scout source receipt '${input.ref.runId}' is unavailable`);
36996
36499
  let receipt;
36997
36500
  try {
36998
- receipt = JSON.parse(readFileSync9(receiptPath, "utf8"));
36501
+ receipt = JSON.parse(readFileSync8(receiptPath, "utf8"));
36999
36502
  } catch (error) {
37000
36503
  throw new Error(
37001
36504
  `dispatch: Scout source receipt is unreadable: ${error instanceof Error ? error.message : String(error)}`
@@ -37193,7 +36696,7 @@ function councilSettingsFromArgs(args, deps) {
37193
36696
  if (!Array.isArray(args.members)) return { ok: false, message: "council_members_out_of_range" };
37194
36697
  members = [];
37195
36698
  for (const raw of args.members) {
37196
- if (!isRecord10(raw)) return { ok: false, message: "council_members_out_of_range" };
36699
+ if (!isRecord9(raw)) return { ok: false, message: "council_members_out_of_range" };
37197
36700
  const label = stringArg(raw, "label");
37198
36701
  const target = stringArg(raw, "target");
37199
36702
  if (label === void 0 || target === void 0 || !COUNCIL_LABEL.test(label)) {
@@ -37223,7 +36726,7 @@ function councilSettingsFromArgs(args, deps) {
37223
36726
  if (!Number.isInteger(rounds) || Number(rounds) < 1 || Number(rounds) > 3) {
37224
36727
  return { ok: false, message: "dispatch: rounds must be an integer 1..3" };
37225
36728
  }
37226
- const judge = isRecord10(args.judge) ? Object.fromEntries(
36729
+ const judge = isRecord9(args.judge) ? Object.fromEntries(
37227
36730
  ["agent", "model", "target", "node"].flatMap((key) => {
37228
36731
  const value = stringArg(args.judge, key);
37229
36732
  return value === void 0 ? [] : [[key, value]];
@@ -37231,13 +36734,13 @@ function councilSettingsFromArgs(args, deps) {
37231
36734
  ) : void 0;
37232
36735
  return { ok: true, council: { members, synthesis, rounds: Number(rounds), ...judge ? { judge } : {} } };
37233
36736
  }
37234
- function isRecord10(value) {
36737
+ function isRecord9(value) {
37235
36738
  return typeof value === "object" && value !== null && !Array.isArray(value);
37236
36739
  }
37237
36740
  function reviewSettingsFromArgs(args) {
37238
36741
  const raw = args.review;
37239
36742
  if (raw === void 0 || raw === false) return { ok: true, review: void 0 };
37240
- const record2 = raw === true ? {} : isRecord10(raw) ? raw : null;
36743
+ const record2 = raw === true ? {} : isRecord9(raw) ? raw : null;
37241
36744
  if (record2 === null) return { ok: false, message: "dispatch: review must be true or an options object" };
37242
36745
  const review = { maxCycles: REVIEW_MAX_CYCLES_DEFAULT };
37243
36746
  const reviewer = stringArg(record2, "reviewer", "agent");
@@ -37268,10 +36771,10 @@ function competeSettingsFromArgs(args) {
37268
36771
  }
37269
36772
  candidates = args.candidates;
37270
36773
  }
37271
- if (args.judge !== void 0 && !isRecord10(args.judge)) {
36774
+ if (args.judge !== void 0 && !isRecord9(args.judge)) {
37272
36775
  return { ok: false, message: "dispatch: judge must be an options object" };
37273
36776
  }
37274
- if (!isRecord10(args.judge)) return { ok: true, compete: { candidates } };
36777
+ if (!isRecord9(args.judge)) return { ok: true, compete: { candidates } };
37275
36778
  const judge = {};
37276
36779
  for (const key of ["agent", "model", "target", "node"]) {
37277
36780
  const value = stringArg(args.judge, key);
@@ -37316,8 +36819,25 @@ function createDispatchAdmissionController(deps) {
37316
36819
  return {
37317
36820
  check: entry.check,
37318
36821
  argv: [...check.command],
37319
- cwd: resolve7(process.cwd(), check.cwd),
37320
- timeoutMs: entry.timeoutMs
36822
+ cwd: resolve8(process.cwd(), check.cwd),
36823
+ timeoutMs: entry.timeoutMs,
36824
+ // A judged check seals its kind and absolute file paths here, so
36825
+ // host verification judges against what the catalog declared at
36826
+ // admission rather than whatever the file says at run time.
36827
+ ...check.kind !== "command" ? { kind: check.kind } : {},
36828
+ ...check.numeric !== void 0 ? {
36829
+ numeric: {
36830
+ reference: resolve8(process.cwd(), check.numeric.reference),
36831
+ tolerance: { ...check.numeric.tolerance }
36832
+ }
36833
+ } : {},
36834
+ ...check.perf !== void 0 ? {
36835
+ perf: {
36836
+ ...check.perf.budget !== void 0 ? { budget: structuredClone(check.perf.budget) } : {},
36837
+ ...check.perf.baseline !== void 0 ? { baseline: resolve8(process.cwd(), check.perf.baseline) } : {},
36838
+ ...check.perf.tolerance !== void 0 ? { tolerance: { ...check.perf.tolerance } } : {}
36839
+ }
36840
+ } : {}
37321
36841
  };
37322
36842
  })
37323
36843
  };
@@ -37379,7 +36899,7 @@ function createDispatchAdmissionController(deps) {
37379
36899
  ...request.worktree === true ? {
37380
36900
  worktree: true,
37381
36901
  apply: request.apply ?? "merge",
37382
- ...gitCheckoutRoot(resolve7(request.cwd ?? process.cwd())) === null ? {} : { worktreeDestination: gitCheckoutRoot(resolve7(request.cwd ?? process.cwd())) }
36902
+ ...gitCheckoutRoot(resolve8(request.cwd ?? process.cwd())) === null ? {} : { worktreeDestination: gitCheckoutRoot(resolve8(request.cwd ?? process.cwd())) }
37383
36903
  } : {},
37384
36904
  target: resolution.targetId,
37385
36905
  model: resolution.wireModelId,
@@ -37496,7 +37016,7 @@ function createDispatchAdmissionController(deps) {
37496
37016
  }
37497
37017
  }
37498
37018
  if (args.apply_winner !== void 0) {
37499
- if (!isRecord10(args.apply_winner)) {
37019
+ if (!isRecord9(args.apply_winner)) {
37500
37020
  return shapeRejection(args, "dispatch: apply_winner must be an options object");
37501
37021
  }
37502
37022
  const branch = stringArg(args.apply_winner, "branch");
@@ -37506,7 +37026,7 @@ function createDispatchAdmissionController(deps) {
37506
37026
  return shapeRejection(args, "dispatch: apply_winner.branch must be a clio-coder/compete/<group>/<n> branch");
37507
37027
  }
37508
37028
  try {
37509
- const cwd = resolve7(stringArg(args.apply_winner, "cwd") ?? process.cwd());
37029
+ const cwd = resolve8(stringArg(args.apply_winner, "cwd") ?? process.cwd());
37510
37030
  return trustExecution(
37511
37031
  markPrepared(
37512
37032
  withResolvedDispatchPlan(args, {
@@ -37550,7 +37070,7 @@ function createDispatchAdmissionController(deps) {
37550
37070
  const spec = deps.getAgentSpecs().find((candidate) => candidate.id === request.agentId);
37551
37071
  if (spec?.capabilityClass === "read-only") return shapeRejection(args, "worktree_read_only_agent");
37552
37072
  if (request.cwd !== void 0) {
37553
- const requested = resolve7(request.cwd);
37073
+ const requested = resolve8(request.cwd);
37554
37074
  const rel = relative8(parentCheckout, requested);
37555
37075
  if (rel === ".." || rel.startsWith("../") || isAbsolute6(rel)) {
37556
37076
  return shapeRejection(args, "worktree_cwd_outside_checkout");
@@ -38068,7 +37588,7 @@ function createDispatchTool(inputDeps, surfaceOptions = {}) {
38068
37588
  const admission = createDispatchAdmissionController(deps);
38069
37589
  let runnerPromise = null;
38070
37590
  const loadRunner = () => {
38071
- runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-2QQAITS3.js")))();
37591
+ runnerPromise ??= (surfaceOptions.loadRunner ?? (() => import("./dispatch-runner-RJ5I2F2O.js")))();
38072
37592
  return runnerPromise;
38073
37593
  };
38074
37594
  return {
@@ -38123,6 +37643,7 @@ function registerAllTools(registry, deps = {}) {
38123
37643
  ...deps.getWorkerRosters ? { getWorkerRosters: deps.getWorkerRosters } : {},
38124
37644
  ...deps.getDispatchSchemaComposition ? { getSchemaComposition: deps.getDispatchSchemaComposition } : {},
38125
37645
  ...deps.dispatchBackground ? { background: deps.dispatchBackground } : {},
37646
+ ...deps.getDecisionBoard ? { getDecisionBoard: deps.getDecisionBoard } : {},
38126
37647
  ...deps.competeMuxWorktrees ? { competeWorktrees: { mux: deps.competeMuxWorktrees } } : {}
38127
37648
  };
38128
37649
  registry.register({
@@ -38135,7 +37656,7 @@ function registerAllTools(registry, deps = {}) {
38135
37656
  ...builtin(
38136
37657
  lazyTool(
38137
37658
  monitorToolSurface,
38138
- async () => (await import("./monitor-E4ASVUJH.js")).createMonitorTool({ dispatch, runEvents: dispatchRunEvents })
37659
+ async () => (await import("./monitor-CPNIUULB.js")).createMonitorTool({ dispatch, runEvents: dispatchRunEvents })
38139
37660
  ),
38140
37661
  {
38141
37662
  path: "src/tools/monitor.ts",
@@ -38145,7 +37666,7 @@ function registerAllTools(registry, deps = {}) {
38145
37666
  });
38146
37667
  registry.register({
38147
37668
  ...builtin(
38148
- lazyTool(steerToolSurface, async () => (await import("./steer-Z5DO23FJ.js")).createSteerTool({ dispatch })),
37669
+ lazyTool(steerToolSurface, async () => (await import("./steer-XA25PSCS.js")).createSteerTool({ dispatch })),
38149
37670
  {
38150
37671
  path: "src/tools/steer.ts",
38151
37672
  scope: "core"
@@ -38157,7 +37678,7 @@ function registerAllTools(registry, deps = {}) {
38157
37678
  const panes = deps.panes;
38158
37679
  registry.register({
38159
37680
  ...builtin(
38160
- lazyTool(panesToolSurface, async () => (await import("./panes-E3RUXOW5.js")).createPanesTool({ panes })),
37681
+ lazyTool(panesToolSurface, async () => (await import("./panes-BOHAEGYC.js")).createPanesTool({ panes })),
38161
37682
  { path: "src/tools/panes.ts", scope: "core" }
38162
37683
  )
38163
37684
  });
@@ -38294,18 +37815,40 @@ function advanceThinkingLevel(current, available) {
38294
37815
  return levels[(idx + 1) % levels.length] ?? "off";
38295
37816
  }
38296
37817
  var LOCAL_API_KEY_FALLBACK2 = "clio-coder-local-target";
38297
- async function resolveApiKeyForTarget(target, providers, signal) {
38298
- const runtime = providers.getRuntime(target.runtime);
38299
- if (!runtime) return void 0;
38300
- if (!targetRequiresAuth(target, runtime)) return LOCAL_API_KEY_FALLBACK2;
38301
- const resolved = await providers.auth.resolveForTarget(target, runtime, signal ? { signal } : void 0);
38302
- return resolved.apiKey;
38303
- }
38304
- function createBackgroundMemoryModelClient(providers, settings, timeoutMs, bus) {
38305
- const targetId = settings.context.memory.target?.trim();
38306
- const wireModelId = settings.context.memory.model?.trim();
38307
- if (!targetId || !wireModelId) return null;
38308
- if (backgroundSharesReasoningModelWithOrchestrator(providers, settings)) return null;
37818
+ function createBackgroundMemoryModelClient(providers, settings, timeoutMs, bus, fallbackOnly = false) {
37819
+ const configuredTarget = settings.context.memory.target?.trim();
37820
+ const configuredModel = settings.context.memory.model?.trim();
37821
+ if (!configuredTarget || !configuredModel) return null;
37822
+ const chatTarget = settings.chat.target?.trim();
37823
+ const chatModel = settings.chat.model?.trim();
37824
+ const sameRoute = configuredTarget === chatTarget && configuredModel === chatModel;
37825
+ if (fallbackOnly && sameRoute) return null;
37826
+ let fallbackReason;
37827
+ if (!fallbackOnly) {
37828
+ try {
37829
+ return prepareBackgroundMemoryRoute(providers, configuredTarget, configuredModel, timeoutMs, bus, "dedicated");
37830
+ } catch {
37831
+ fallbackReason = "configured route unavailable";
37832
+ }
37833
+ } else fallbackReason = "configured route client error";
37834
+ if (!chatTarget || !chatModel || sameRoute) {
37835
+ if (fallbackOnly) return null;
37836
+ throw new Error("configured memory route is unavailable and no distinct chat fallback can run");
37837
+ }
37838
+ try {
37839
+ return {
37840
+ ...prepareBackgroundMemoryRoute(providers, chatTarget, chatModel, timeoutMs, bus, "chat-fallback"),
37841
+ fallbackReason
37842
+ };
37843
+ } catch {
37844
+ if (fallbackOnly) return null;
37845
+ throw new Error("neither the configured memory route nor the active chat fallback is available");
37846
+ }
37847
+ }
37848
+ function prepareBackgroundMemoryModel(providers, targetId, wireModelId) {
37849
+ const status = providers.list().find((entry) => entry.target.id === targetId);
37850
+ if (status && (!status.available || status.health.status === "down" || hasLiveModelCatalog(status) && !status.discoveredModels.includes(wireModelId) || modelResidencyForStatus(status, wireModelId) === "absent" || modelResidencyForStatus(status, wireModelId) === "loading"))
37851
+ throw new Error("background memory route is unavailable");
38309
37852
  const resolved = resolveRuntimeTarget(providers, {
38310
37853
  targetId,
38311
37854
  wireModelId,
@@ -38325,9 +37868,23 @@ function createBackgroundMemoryModelClient(providers, settings, timeoutMs, bus)
38325
37868
  const model = resolved.target.runtime.synthesizeModel(resolved.target.target, resolved.target.wireModelId, kbHit);
38326
37869
  const refined = refineRuntimeTargetWithModelHints(resolved.target, model, providers.knowledgeBase);
38327
37870
  applyModelCapabilityPatch(model, refined.capabilities);
38328
- const costProvenance = normalizeCostProvenance(refined.costProvenance);
37871
+ return { model, refined };
37872
+ }
37873
+ function backgroundMemoryEndpointBusy(providers, endpointKey, targets) {
37874
+ if (endpointKey === null) return false;
37875
+ const capacity = resolveEndpointCapacities({
37876
+ statuses: providers.list(),
37877
+ targets,
37878
+ runtimeFor: (id) => providers.getRuntime(id)
37879
+ })[endpointKey];
37880
+ return capacity !== void 0 && (endpointCapacityUsage()[endpointKey] ?? 0) >= capacity.limit;
37881
+ }
37882
+ function prepareBackgroundMemoryRoute(providers, targetId, wireModelId, timeoutMs, bus, selection) {
37883
+ const initial = prepareBackgroundMemoryModel(providers, targetId, wireModelId);
37884
+ const { refined } = initial;
38329
37885
  const endpointKey = canonicalEndpointKey(refined.target);
38330
37886
  return {
37887
+ selection,
38331
37888
  targetId,
38332
37889
  wireModelId: refined.wireModelId,
38333
37890
  endpointKey,
@@ -38340,42 +37897,100 @@ function createBackgroundMemoryModelClient(providers, settings, timeoutMs, bus)
38340
37897
  // Wrapped at the layer that knows a request left the process: the step
38341
37898
  // holds endpoint capacity while it is out and publishes the cache
38342
37899
  // disturbance even when a timeout means the usage sink never sees it.
38343
- complete: announceMemoryStepEndpoint({ bus, endpointKey, targetId }, async (request) => {
38344
- const apiKey = targetRequiresAuth(refined.target, refined.runtime) ? (await providers.auth.resolveForTarget(refined.target, refined.runtime, { signal: request.signal })).apiKey : LOCAL_API_KEY_FALLBACK2;
38345
- const startedAt = Date.now();
38346
- const completion = await completeEngineText({
38347
- model,
38348
- systemPrompt: request.systemPrompt,
38349
- userPrompt: request.userPrompt,
38350
- maxTokens: request.maxTokens,
38351
- // Always off, never the operator's chat thinking level. A model that
38352
- // reasons anyway still works: `completeEngineText` keeps only text
38353
- // blocks, and the memory output budget leaves room for the preamble.
38354
- thinkingLevel: "off",
38355
- signal: request.signal,
38356
- timeoutMs,
38357
- ...apiKey === void 0 ? {} : { apiKey }
38358
- });
38359
- return {
38360
- text: completion.text,
38361
- inputTokens: completion.inputTokens,
38362
- outputTokens: completion.outputTokens,
38363
- usage: {
37900
+ complete: async (request) => {
37901
+ await prepareBackgroundModelMetadata(providers, targetId, request.signal);
37902
+ const { model, refined: refined2 } = prepareBackgroundMemoryModel(providers, targetId, wireModelId);
37903
+ if (refined2.runtimeId !== initial.refined.runtimeId || canonicalEndpointKey(refined2.target) !== endpointKey) {
37904
+ throw new Error("background memory target changed during preparation");
37905
+ }
37906
+ const costProvenance = normalizeCostProvenance(refined2.costProvenance);
37907
+ const apiKey = targetRequiresAuth(refined2.target, refined2.runtime) ? (await providers.auth.resolveForTarget(refined2.target, refined2.runtime, { signal: request.signal })).apiKey : LOCAL_API_KEY_FALLBACK2;
37908
+ request.signal.throwIfAborted();
37909
+ if (backgroundMemoryEndpointBusy(providers, endpointKey, [refined2.target])) {
37910
+ throw new TaskMemoryEndpointBusyError("background memory endpoint is busy");
37911
+ }
37912
+ return announceMemoryStepEndpoint({ bus, endpointKey, targetId }, async () => {
37913
+ const startedAt = Date.now();
37914
+ let observedUsage;
37915
+ const mapUsage = (completion2) => ({
37916
+ ...completion2.usage,
38364
37917
  targetId,
38365
- attributedModelId: refined.wireModelId,
38366
- input: completion.usage.input,
38367
- output: completion.usage.output,
38368
- cacheRead: completion.usage.cacheRead,
38369
- cacheWrite: completion.usage.cacheWrite,
38370
- reasoning: completion.usage.reasoning,
38371
- totalTokens: completion.usage.totalTokens,
38372
- costUsd: completion.usage.costUsd,
37918
+ attributedModelId: refined2.wireModelId,
38373
37919
  costProvenance,
38374
37920
  durationMs: Date.now() - startedAt,
38375
- backend: completion.backend
38376
- }
38377
- };
38378
- })
37921
+ backend: completion2.backend
37922
+ });
37923
+ const completion = await completeEngineText({
37924
+ model,
37925
+ systemPrompt: request.systemPrompt,
37926
+ userPrompt: request.userPrompt,
37927
+ maxTokens: refined2.capabilityDecisions.maxTokens > 0 ? Math.min(request.maxTokens, refined2.capabilityDecisions.maxTokens) : request.maxTokens,
37928
+ // Always off, never the operator's chat thinking level. A model that
37929
+ // reasons anyway still works: `completeEngineText` keeps only text
37930
+ // blocks, and the memory output budget leaves room for the preamble.
37931
+ thinkingLevel: "off",
37932
+ signal: request.signal,
37933
+ timeoutMs,
37934
+ onUsage: (observation) => {
37935
+ observedUsage = mapUsage(observation);
37936
+ request.onUsage?.(observedUsage);
37937
+ },
37938
+ ...apiKey === void 0 ? {} : { apiKey },
37939
+ ...refined2.target.auth?.headers ? { headers: refined2.target.auth.headers } : {}
37940
+ });
37941
+ return {
37942
+ text: completion.text,
37943
+ inputTokens: completion.inputTokens,
37944
+ outputTokens: completion.outputTokens,
37945
+ usage: observedUsage ?? mapUsage(completion)
37946
+ };
37947
+ })(request);
37948
+ }
37949
+ }
37950
+ };
37951
+ }
37952
+ function createBackgroundMemoryRouting(providers, getSettings, bus) {
37953
+ let route = null;
37954
+ let snapshot;
37955
+ let lastNotice = null;
37956
+ const noteFallback = () => {
37957
+ if (route?.selection !== "chat-fallback") {
37958
+ lastNotice = null;
37959
+ return;
37960
+ }
37961
+ const message = `Memory: ${route.fallbackReason}; selected chat fallback ${route.targetId}/${route.wireModelId} for this step, subject to available endpoint capacity.`;
37962
+ if (message === lastNotice) return;
37963
+ lastNotice = message;
37964
+ try {
37965
+ bus?.emit(BusChannels.RuntimeNotice, {
37966
+ kind: "degraded",
37967
+ level: "info",
37968
+ message,
37969
+ targetId: route.targetId,
37970
+ runtimeId: providers.getTarget(route.targetId)?.runtime ?? "unknown",
37971
+ model: route.wireModelId
37972
+ });
37973
+ } catch {
37974
+ }
37975
+ };
37976
+ return {
37977
+ getModelClient: () => {
37978
+ const current = getSettings();
37979
+ snapshot = current === void 0 ? void 0 : structuredClone(current);
37980
+ route = snapshot === void 0 ? null : createBackgroundMemoryModelClient(providers, snapshot, snapshot.context.memory.timeoutMs, bus);
37981
+ noteFallback();
37982
+ return route?.client ?? null;
37983
+ },
37984
+ getFallbackModelClient: () => {
37985
+ if (route?.selection !== "dedicated" || snapshot === void 0) return null;
37986
+ route = createBackgroundMemoryModelClient(providers, snapshot, snapshot.context.memory.timeoutMs, bus, true);
37987
+ noteFallback();
37988
+ return route?.client ?? null;
37989
+ },
37990
+ getModelMaxTokens: (configured) => route?.modelMaxTokens(configured) ?? configured,
37991
+ backgroundEndpointBusy: () => {
37992
+ if (route?.endpointKey == null || snapshot === void 0) return false;
37993
+ return backgroundMemoryEndpointBusy(providers, route.endpointKey, snapshot.targets);
38379
37994
  }
38380
37995
  };
38381
37996
  }
@@ -38402,53 +38017,79 @@ function agentRoleToolWarnings(providers, settings) {
38402
38017
  }
38403
38018
  return warnings;
38404
38019
  }
38405
- function backgroundSharesReasoningModelWithOrchestrator(providers, settings) {
38406
- const backgroundModel = settings.context.memory.model?.trim();
38407
- const orchestratorModel = settings.chat.model?.trim();
38408
- if (!backgroundModel || backgroundModel !== orchestratorModel) return false;
38409
- if (settings.context.memory.target?.trim() !== settings.chat.target?.trim()) return false;
38410
- try {
38411
- const status = providers.list().find((entry) => entry.target.id === settings.context.memory.target?.trim());
38412
- if (!status) return false;
38413
- return resolveModelCapabilities(status, backgroundModel, providers.knowledgeBase).reasoning === true;
38414
- } catch {
38415
- return false;
38020
+ async function resolveCompactionModel(settings, providers) {
38021
+ const override = settings.context.compaction.model;
38022
+ let targetId = settings.chat.target;
38023
+ let wireModelId = settings.chat.model;
38024
+ if (override !== void 0 && override !== null) {
38025
+ let selected;
38026
+ try {
38027
+ selected = resolveModelReference(override, providers);
38028
+ } catch {
38029
+ throw new Error("context.compaction.model is an invalid pattern; set a unique target/model reference");
38030
+ }
38031
+ if (!selected.ref || selected.warning) {
38032
+ throw new Error(
38033
+ "context.compaction.model must match exactly one configured model; set a unique target/model reference"
38034
+ );
38035
+ }
38036
+ targetId = selected.ref.target;
38037
+ wireModelId = selected.ref.model;
38416
38038
  }
38417
- }
38418
- function synthesizeOrchestratorModel(providers, target, wireModelId) {
38419
- const runtime = providers.getRuntime(target.runtime);
38420
- if (!runtime) return null;
38039
+ if (!targetId || !wireModelId) return null;
38040
+ await prepareBackgroundModelMetadata(providers, targetId);
38041
+ const status = providers.list().find((entry) => entry.target.id === targetId);
38042
+ if (!status?.available) {
38043
+ throw new Error("context.compaction.model target is unavailable; check the selected target with clio-coder targets");
38044
+ }
38045
+ const resolved = resolveRuntimeTarget(providers, {
38046
+ targetId,
38047
+ wireModelId,
38048
+ use: "orchestrator",
38049
+ requestedThinkingLevel: "off",
38050
+ requireTools: false,
38051
+ requireStreaming: true,
38052
+ requireOutputBudget: true
38053
+ });
38054
+ if (!resolved.ok) {
38055
+ throw new Error(
38056
+ "context.compaction.model cannot run as a summarizer; select an available HTTP chat model with an output budget"
38057
+ );
38058
+ }
38059
+ const route = resolved.target;
38421
38060
  let model;
38422
38061
  try {
38423
- const kbHit = providers.knowledgeBase?.lookup(wireModelId) ?? null;
38424
- model = runtime.synthesizeModel(target, wireModelId, kbHit);
38062
+ model = route.runtime.synthesizeModel(
38063
+ route.target,
38064
+ route.wireModelId,
38065
+ providers.knowledgeBase?.lookup(route.wireModelId) ?? null
38066
+ );
38425
38067
  } catch {
38426
- return null;
38068
+ throw new Error("context.compaction.model could not be prepared; check the selected target/model configuration");
38427
38069
  }
38428
- try {
38429
- const status = providers.list().find((entry) => entry.target.id === target.id);
38430
- if (status) {
38431
- const caps = resolveModelCapabilities(status, wireModelId, providers.knowledgeBase, {
38432
- detectedReasoning: providers.getDetectedReasoning(target.id, wireModelId)
38433
- });
38434
- applyModelCapabilityPatch(model, caps);
38070
+ const refined = refineRuntimeTargetWithModelHints(route, model, providers.knowledgeBase);
38071
+ if (refined.capabilityDecisions.maxTokens <= 0) {
38072
+ throw new Error("context.compaction.model has no output budget; select a model with a known positive output limit");
38073
+ }
38074
+ applyModelCapabilityPatch(model, refined.capabilities);
38075
+ let apiKey = LOCAL_API_KEY_FALLBACK2;
38076
+ if (targetRequiresAuth(route.target, route.runtime)) {
38077
+ const auth = await providers.auth.resolveForTarget(route.target, route.runtime);
38078
+ if (!auth.available || !auth.apiKey) {
38079
+ throw new Error(
38080
+ "context.compaction.model authentication is unavailable; authenticate the selected target with clio-coder auth"
38081
+ );
38435
38082
  }
38436
- } catch {
38083
+ apiKey = auth.apiKey;
38437
38084
  }
38438
- return model;
38439
- }
38440
- async function resolveCompactionModel(settings, providers) {
38441
- const targetId = settings.chat?.target ?? null;
38442
- const wireModelId = settings.chat?.model ?? null;
38443
- if (!targetId || !wireModelId) return null;
38444
- const target = resolveTarget(providers, targetId);
38445
- if (!target) return null;
38446
- const model = synthesizeOrchestratorModel(providers, target, wireModelId);
38447
- if (!model) return null;
38448
- const apiKey = await resolveApiKeyForTarget(target, providers);
38449
- const resolution = { model, targetId, endpointKey: canonicalEndpointKey(target) };
38450
- if (apiKey !== void 0) resolution.apiKey = apiKey;
38451
- return resolution;
38085
+ return {
38086
+ model,
38087
+ targetId: route.targetId,
38088
+ wireModelId: route.wireModelId,
38089
+ endpointKey: canonicalEndpointKey(route.target),
38090
+ apiKey,
38091
+ ...route.target.auth?.headers ? { headers: route.target.auth.headers } : {}
38092
+ };
38452
38093
  }
38453
38094
  function readSessionEntriesForCompact(sessionId) {
38454
38095
  const reader = openSession(sessionId);
@@ -38506,34 +38147,72 @@ function appendSkillActivationRegistryEvent(session, activation) {
38506
38147
  } catch {
38507
38148
  }
38508
38149
  }
38509
- async function runCompactionFlow(session, settings, providers, instructions, trigger) {
38150
+ async function runCompactionFlow(session, settings, providers, instructions, trigger, observability) {
38510
38151
  const meta = session.current();
38511
38152
  if (!meta) {
38512
38153
  throw new Error("no current session to compact; start one with /new or /resume first");
38513
38154
  }
38155
+ const stateDir = clioStateDir();
38156
+ const activeLeafTurnId = session.tree(meta.id).leafId ?? void 0;
38157
+ const isOriginCurrent = () => session.current()?.id === meta.id && (session.tree(meta.id).leafId ?? void 0) === activeLeafTurnId;
38158
+ const entries = filterEntriesToActivePath(readSessionEntriesForCompact(meta.id), activeLeafTurnId);
38159
+ if (entries.length === 0) return null;
38160
+ const systemPrompt = await readCompactionSystemPrompt(settings.context.compaction.systemPrompt, meta.cwd);
38514
38161
  const resolved = await resolveCompactionModel(settings, providers);
38515
38162
  if (!resolved) {
38516
38163
  throw new Error("no model configured; set chat.target + chat.model");
38517
38164
  }
38518
- const activeLeafTurnId = session.tree(meta.id).leafId ?? void 0;
38519
- const entries = filterEntriesToActivePath(readSessionEntriesForCompact(meta.id), activeLeafTurnId);
38520
- if (entries.length === 0) return null;
38165
+ if (!isOriginCurrent()) throw new Error("compaction session or branch changed before summarization");
38166
+ const calls = [];
38167
+ const preserveCalls = () => recordFailedCompactionCalls(
38168
+ {
38169
+ stateDir,
38170
+ sessionId: meta.id,
38171
+ repoIdentity: meta.cwdHash || cwdHash(meta.cwd),
38172
+ target: resolved.targetId,
38173
+ model: resolved.wireModelId
38174
+ },
38175
+ calls,
38176
+ isOriginCurrent() ? observability : void 0
38177
+ );
38521
38178
  const releaseEndpointSlot = resolved.endpointKey === null ? () => {
38522
38179
  } : registerForegroundStream(resolved.endpointKey);
38523
38180
  let result;
38524
38181
  try {
38525
38182
  result = await compact({
38526
38183
  entries,
38184
+ onCall: (call) => calls.push(call),
38527
38185
  model: resolved.model,
38186
+ ...systemPrompt !== void 0 ? { systemPrompt } : {},
38187
+ ...resolved.headers !== void 0 ? { headers: resolved.headers } : {},
38528
38188
  ...resolved.apiKey !== void 0 ? { apiKey: resolved.apiKey } : {},
38529
38189
  ...instructions !== void 0 ? { instructions } : {}
38530
38190
  });
38191
+ } catch (error) {
38192
+ try {
38193
+ preserveCalls();
38194
+ } catch (recordingError) {
38195
+ throw new AggregateError([error, recordingError], "compaction failed and its usage could not be fully recorded");
38196
+ }
38197
+ throw error;
38531
38198
  } finally {
38532
38199
  releaseEndpointSlot();
38533
38200
  }
38534
- if (result.messagesSummarized === 0 || result.summary.length === 0) return null;
38201
+ if (!isOriginCurrent()) {
38202
+ preserveCalls();
38203
+ throw new Error("compaction session or branch changed; summary discarded and originating usage retained");
38204
+ }
38205
+ if (result.messagesSummarized === 0 || result.summary.length === 0) {
38206
+ preserveCalls();
38207
+ if (calls.length > 0) throw new Error("compaction returned no summary; reported usage retained without a checkpoint");
38208
+ return null;
38209
+ }
38210
+ if (result.usage) {
38211
+ result.usage = { ...result.usage, targetId: resolved.targetId, modelId: resolved.wireModelId };
38212
+ }
38535
38213
  const entry = {
38536
38214
  kind: "compactionSummary",
38215
+ turnId: randomUUID3(),
38537
38216
  parentTurnId: result.firstKeptTurnId ?? null,
38538
38217
  summary: result.summary,
38539
38218
  tokensBefore: result.tokensBefore,
@@ -38547,11 +38226,38 @@ async function runCompactionFlow(session, settings, providers, instructions, tri
38547
38226
  ...result.usage !== void 0 ? { usage: result.usage } : {}
38548
38227
  };
38549
38228
  if (trigger !== void 0) entry.trigger = trigger;
38550
- session.appendEntry(entry);
38229
+ try {
38230
+ session.appendEntry(entry);
38231
+ } catch (error) {
38232
+ try {
38233
+ if (!compactionCheckpointWasWritten(sessionPaths(meta).current, entry.turnId)) preserveCalls();
38234
+ } catch (recordingError) {
38235
+ throw new AggregateError(
38236
+ [error, recordingError],
38237
+ "compaction checkpoint persistence is unresolved; usage was not duplicated"
38238
+ );
38239
+ }
38240
+ throw error;
38241
+ }
38551
38242
  return result;
38552
38243
  }
38553
- function createProductionAutoCompact(session, getSettings, providers) {
38554
- return (instructions, trigger) => runCompactionFlow(session, getSettings(), providers, instructions, trigger);
38244
+ function compactionCheckpointWasWritten(path2, turnId) {
38245
+ let malformed = false;
38246
+ for (const line of readFileSync9(path2, "utf8").split("\n")) {
38247
+ if (line.trim().length === 0) continue;
38248
+ try {
38249
+ const entry = JSON.parse(line);
38250
+ if (entry && typeof entry === "object" && "turnId" in entry && entry.turnId === turnId && "kind" in entry && entry.kind === "compactionSummary")
38251
+ return true;
38252
+ } catch {
38253
+ malformed = true;
38254
+ }
38255
+ }
38256
+ if (malformed) throw new Error("cannot prove checkpoint absence in a malformed session ledger");
38257
+ return false;
38258
+ }
38259
+ function createProductionAutoCompact(session, getSettings, providers, observability) {
38260
+ return (instructions, trigger) => runCompactionFlow(session, getSettings(), providers, instructions, trigger, observability);
38555
38261
  }
38556
38262
  function estimateTokensFromSummary(summary) {
38557
38263
  return Math.max(1, ceilChars(summary.length));
@@ -38654,7 +38360,7 @@ async function bootOrchestrator(options = {}) {
38654
38360
  let protectedArtifactStateForDispatch = null;
38655
38361
  const muxInteractive = !options.headless && options.acp === void 0 && process.env.CLIO_CODER_INTERACTIVE === "1";
38656
38362
  const muxEnablement = resolvePanesEnablement(options.panes, options.startupSettings?.interface.panes.enabled);
38657
- const withPanes = muxInteractive && muxEnablement !== "off" ? await import("./with-panes-BYOJCLAM.js") : null;
38363
+ const withPanes = muxInteractive && muxEnablement !== "off" ? await import("./with-panes-BDQEWBRT.js") : null;
38658
38364
  const result = await loadDomains(
38659
38365
  [
38660
38366
  options.startupSettings ? createConfigDomainModule(options.startupSettings) : ConfigDomainModule,
@@ -38902,49 +38608,21 @@ async function bootOrchestrator(options = {}) {
38902
38608
  middleware.registerHook(
38903
38609
  createSkillActivationObserver((activation) => appendSkillActivationRegistryEvent(session, activation))
38904
38610
  );
38905
- if (resources) {
38906
- middleware.registerHook(
38907
- createSkillsReminderRegistration({
38908
- countModelVisibleSkills: () => modelVisibleSkills(resources.skills(process.cwd()).items).length,
38909
- // Same lookup context(scope="skills") lists under its Marketplace
38910
- // heading, minus what is already installed, so the count the
38911
- // reminder quotes is the count the listing will show.
38912
- countInstallableSkills: () => {
38913
- const installed2 = new Set(resources.skills(process.cwd()).items.map((skill) => skill.name));
38914
- return discoverMarketplaceSkills({ cwd: process.cwd() }).skills.filter((skill) => !installed2.has(skill.name)).length;
38915
- }
38916
- })
38917
- );
38918
- }
38919
38611
  middleware.registerHook(createTaskBoardReminderRegistration());
38920
38612
  const taskMemoryBank = new TaskMemoryBank();
38921
- let taskMemorySessionId = session?.current()?.id ?? null;
38922
- const ensureTaskMemorySession = () => {
38923
- const currentSessionId = session?.current()?.id ?? null;
38924
- if (currentSessionId === taskMemorySessionId) return;
38925
- taskMemoryBank.clear();
38926
- taskMemorySessionId = currentSessionId;
38927
- };
38928
38613
  const memorySettings = (config?.get() ?? readSettings()).context.memory;
38929
38614
  let deferredMemoryReminderSink = null;
38930
38615
  let deferredWatchdogNoticeSink = null;
38931
38616
  const memoryTracePath = taskMemoryTracePath();
38932
38617
  const memoryTrace = memoryTracePath === null ? null : createTaskMemoryTrace(memoryTracePath);
38933
- let backgroundMemoryRoute = null;
38934
- const recordBackgroundMemoryUsage = (usage) => {
38618
+ const captureBackgroundMemoryUsage = () => {
38935
38619
  const meta = session?.current() ?? null;
38936
- try {
38937
- recordBackgroundMemoryStep({
38938
- usage,
38939
- stateDir: clioStateDir(),
38940
- sessionId: meta?.id ?? null,
38941
- // The identity the session ledger is filed under, so `usage report
38942
- // --repo` selects these rows with the same hash it selects ledgers with.
38943
- repoIdentity: meta ? meta.cwdHash || cwdHash(meta.cwd || process.cwd()) : null,
38944
- ...observability === void 0 ? {} : { observability }
38945
- });
38946
- } catch {
38947
- }
38620
+ return captureTaskMemoryUsage({
38621
+ stateDir: clioStateDir(),
38622
+ sessionId: meta?.id ?? null,
38623
+ repoIdentity: meta ? meta.cwdHash || cwdHash(meta.cwd || process.cwd()) : null,
38624
+ ...observability === void 0 ? {} : { observability }
38625
+ });
38948
38626
  };
38949
38627
  const proposeInjectedMemoryEntries = (entries) => {
38950
38628
  const meta = session?.current() ?? null;
@@ -38973,7 +38651,6 @@ async function bootOrchestrator(options = {}) {
38973
38651
  deliversDeferredReminders: options.headless === void 0,
38974
38652
  onDeferredReminder: (message) => deferredMemoryReminderSink?.(message),
38975
38653
  getSettings: () => {
38976
- ensureTaskMemorySession();
38977
38654
  const memory = effectiveSettingsForDispatch?.().context.memory ?? memorySettings;
38978
38655
  return {
38979
38656
  enabled: memory.enabled,
@@ -38983,32 +38660,21 @@ async function bootOrchestrator(options = {}) {
38983
38660
  timeoutMs: memory.timeoutMs
38984
38661
  };
38985
38662
  },
38986
- getModelClient: () => {
38987
- const settings = effectiveSettingsForDispatch?.();
38988
- backgroundMemoryRoute = settings === void 0 ? null : createBackgroundMemoryModelClient(providers, settings, settings.context.memory.timeoutMs, bus);
38989
- return backgroundMemoryRoute?.client ?? null;
38990
- },
38991
- getModelMaxTokens: (configuredMaxTokens) => backgroundMemoryRoute?.modelMaxTokens(configuredMaxTokens) ?? configuredMaxTokens,
38992
- // A single-slot local server serves one request at a time, so a memory step
38993
- // started while the operator's turn is streaming either waits behind it or
38994
- // makes the server swap the resident model out to answer. The chat loop
38995
- // registers its stream on the endpoint it streams against, so the two are
38996
- // compared by the same canonical key dispatch admission counts slots on.
38997
- backgroundEndpointBusy: () => {
38998
- const endpointKey = backgroundMemoryRoute?.endpointKey ?? null;
38999
- if (endpointKey === null) return false;
39000
- return (foregroundStreamUsage()[endpointKey] ?? 0) > 0;
39001
- },
39002
- onStepUsage: (usage) => recordBackgroundMemoryUsage(usage),
38663
+ ...createBackgroundMemoryRouting(providers, () => effectiveSettingsForDispatch?.(), bus),
38664
+ captureStepUsage: captureBackgroundMemoryUsage,
39003
38665
  onInjectedEntries: (entries) => proposeInjectedMemoryEntries(entries)
39004
38666
  });
39005
38667
  middleware.registerHook(memoryIntervention);
39006
38668
  const unsubscribeMemoryLoop = bus.on(BusChannels.LoopBlocked, () => memoryIntervention.signalLoop());
39007
- termination.onDrain(() => unsubscribeMemoryLoop());
38669
+ const disposeMemoryLifecycle = bindTaskMemoryLifecycle(bus, memoryIntervention);
38670
+ termination.onDrain(() => {
38671
+ unsubscribeMemoryLoop();
38672
+ disposeMemoryLifecycle();
38673
+ });
39008
38674
  if (contextDomain) {
39009
38675
  middleware.registerHook(createFileMutationObserver(({ paths }) => contextDomain.noteFileChanges(paths)));
39010
38676
  }
39011
- const hookReceiptLog = createHookReceiptLog({ persistPath: join12(clioStateDir(), "hook-receipts.json") });
38677
+ const hookReceiptLog = createHookReceiptLog({ persistPath: join11(clioStateDir(), "hook-receipts.json") });
39012
38678
  const extensionReload = createExtensionReloadCoordinator({
39013
38679
  extensions,
39014
38680
  middleware,
@@ -39025,12 +38691,27 @@ async function bootOrchestrator(options = {}) {
39025
38691
  let activeAcpSessionAutonomy = null;
39026
38692
  const resolveBaselineAutonomy = () => effectiveSettingsForDispatch?.().safety.autonomy ?? options.headless?.autonomy ?? (config?.get() ?? readSettings()).safety.autonomy ?? "auto-edit";
39027
38693
  const resolveEffectiveAutonomy = () => activeAcpSessionAutonomy ?? resolveBaselineAutonomy();
38694
+ if (resources) {
38695
+ middleware.registerHook(
38696
+ createSkillsReminderRegistration({
38697
+ countModelVisibleSkills: () => modelVisibleSkills(resources.skills(process.cwd()).items).length,
38698
+ // Same lookup context(scope="skills") lists under its Marketplace
38699
+ // heading, minus what is already installed, so the count the
38700
+ // reminder quotes is the count the listing will show.
38701
+ countInstallableSkills: () => {
38702
+ const installed2 = new Set(resources.skills(process.cwd()).items.map((skill) => skill.name));
38703
+ return discoverMarketplaceSkills({ cwd: process.cwd() }).skills.filter((skill) => !installed2.has(skill.name)).length;
38704
+ },
38705
+ modelMayActivateSkills: () => modelMayActivateSkills(resolveEffectiveAutonomy())
38706
+ })
38707
+ );
38708
+ }
39028
38709
  if (resources) {
39029
38710
  middleware.registerHook(
39030
38711
  createMarketplaceOfferRegistration({
38712
+ interactive,
39031
38713
  listInstalledSkillNames: () => resources.skills(process.cwd()).items.map((skill) => skill.name),
39032
38714
  listMarketplaceEntries: () => discoverMarketplaceSkills({ cwd: process.cwd() }).skills,
39033
- getAutonomy: resolveEffectiveAutonomy,
39034
38715
  installEntry: (entry, scope) => {
39035
38716
  const installed2 = installSkill({ source: entry.sourceUrl, scope, name: entry.name, cwd: process.cwd() });
39036
38717
  return { path: installed2.path, sourceUrl: installed2.sourceUrl, installedHash: installed2.installedHash };
@@ -39092,6 +38773,7 @@ async function bootOrchestrator(options = {}) {
39092
38773
  session.appendEntry(entry);
39093
38774
  }
39094
38775
  });
38776
+ setCommitDecisionRefsProvider(() => activeDecisionRefs(decisionBoard.snapshot()));
39095
38777
  bus.on(BusChannels.SessionTurnSwitched, () => {
39096
38778
  taskBoard.invalidate();
39097
38779
  taskBoard.snapshot();
@@ -39127,6 +38809,8 @@ async function bootOrchestrator(options = {}) {
39127
38809
  onContextRecalled: (payload) => bus.emit(BusChannels.ContextRecalled, payload)
39128
38810
  } : {},
39129
38811
  taskBoard,
38812
+ decisionBoard,
38813
+ getDecisionBoard: () => decisionBoard.snapshot(),
39130
38814
  userTasks,
39131
38815
  dispatch,
39132
38816
  bus,
@@ -39189,7 +38873,6 @@ async function bootOrchestrator(options = {}) {
39189
38873
  return taskMemoryHandoffSeedOffer(process.cwd(), getCurrentSettings().context.memory.enabled);
39190
38874
  };
39191
38875
  const seedCurrentTaskMemoryFromHandoff = () => {
39192
- ensureTaskMemorySession();
39193
38876
  return seedTaskMemoryFromNewestHandoff(taskMemoryBank, process.cwd(), getCurrentSettings().context.memory.enabled);
39194
38877
  };
39195
38878
  if (resumedSessionAtBoot) {
@@ -39350,6 +39033,7 @@ async function bootOrchestrator(options = {}) {
39350
39033
  return meta ? readRecentSessionEntriesForContract(meta.id) : null;
39351
39034
  },
39352
39035
  resolveRigor: () => resolveRigor({ cwd: process.cwd(), override: parseRigorOverride(process.env.CLIO_CODER_RIGOR) }),
39036
+ readActiveAcceptance: (window) => activeUserTaskAcceptance(userTasks.snapshot(), taskBoard.snapshot(), session.current()?.id ?? null, window),
39353
39037
  recordDecision: (record2) => safety.audit.recordCompletionContract?.(record2)
39354
39038
  })
39355
39039
  );
@@ -39362,6 +39046,7 @@ async function bootOrchestrator(options = {}) {
39362
39046
  return key === null ? null : registerForegroundStream(key);
39363
39047
  },
39364
39048
  getSettings: getCurrentSettings,
39049
+ getAutonomy: resolveEffectiveAutonomy,
39365
39050
  providers,
39366
39051
  middleware,
39367
39052
  middlewareToolChoice,
@@ -39390,7 +39075,6 @@ async function bootOrchestrator(options = {}) {
39390
39075
  }
39391
39076
  },
39392
39077
  getTaskMemoryHandoffSource: () => {
39393
- ensureTaskMemorySession();
39394
39078
  const meta = session?.current();
39395
39079
  if (!meta) throw new Error("task memory handoff requires an active session");
39396
39080
  const settings = getCurrentSettings();
@@ -39414,7 +39098,7 @@ async function bootOrchestrator(options = {}) {
39414
39098
  },
39415
39099
  ...session ? {
39416
39100
  readSessionEntries: readCurrentSessionEntries,
39417
- autoCompact: createProductionAutoCompact(session, getCurrentSettings, providers)
39101
+ autoCompact: createProductionAutoCompact(session, getCurrentSettings, providers, observability)
39418
39102
  } : {},
39419
39103
  toolRegistry,
39420
39104
  hasAttachedDispatch: () => dispatchBackground.size() > 0,
@@ -39628,7 +39312,6 @@ async function bootOrchestrator(options = {}) {
39628
39312
  supersedeDecision: (interviewId, key, correction) => decisionBoard.supersede(interviewId, key, correction),
39629
39313
  userTasks,
39630
39314
  getTaskMemoryStatus: () => {
39631
- ensureTaskMemorySession();
39632
39315
  const settings = getCurrentSettings();
39633
39316
  const bank = taskMemoryBank.snapshot();
39634
39317
  return {
@@ -39758,10 +39441,8 @@ async function bootOrchestrator(options = {}) {
39758
39441
  ...session ? {
39759
39442
  onResumeSession: (sessionId) => {
39760
39443
  try {
39761
- const previousSessionId = session.current()?.id ?? null;
39762
39444
  session.resume(sessionId);
39763
39445
  taskBoard.snapshot();
39764
- if (previousSessionId !== sessionId) ensureTaskMemorySession();
39765
39446
  } catch (err) {
39766
39447
  process.stderr.write(
39767
39448
  `[/resume] failed to resume ${sessionId}: ${err instanceof Error ? err.message : String(err)}
@@ -39776,13 +39457,11 @@ async function bootOrchestrator(options = {}) {
39776
39457
  if (settings.chat.model) input.model = settings.chat.model;
39777
39458
  session.create(input);
39778
39459
  taskBoard.snapshot();
39779
- ensureTaskMemorySession();
39780
39460
  },
39781
39461
  onForkSession: (parentTurnId) => {
39782
39462
  try {
39783
39463
  session.fork(parentTurnId);
39784
39464
  taskBoard.snapshot();
39785
- ensureTaskMemorySession();
39786
39465
  } catch (err) {
39787
39466
  process.stderr.write(
39788
39467
  `[/fork] failed at turn ${parentTurnId}: ${err instanceof Error ? err.message : String(err)}
@@ -39803,6 +39482,9 @@ async function bootOrchestrator(options = {}) {
39803
39482
  return { exitCode: 0, bootTimeMs: timer.snapshot().totalMs };
39804
39483
  }
39805
39484
  export {
39806
- bootOrchestrator
39485
+ bootOrchestrator,
39486
+ createBackgroundMemoryModelClient,
39487
+ createBackgroundMemoryRouting,
39488
+ createProductionAutoCompact
39807
39489
  };
39808
- //# sourceMappingURL=orchestrator-DDMPR3PY.js.map
39490
+ //# sourceMappingURL=orchestrator-J4BSH4WQ.js.map