@iowarp/clio-coder 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (437) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/CONTRIBUTING.md +59 -36
  3. package/README.md +404 -472
  4. package/SECURITY.md +2 -1
  5. package/dist/{acp-ZILU3AUO.js → acp-TMDQZDIG.js} +7 -7
  6. package/dist/{agents-HYWGBGQR.js → agents-5N5NG3XG.js} +28 -28
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-N3QT7CBO.js → auth-Z5CCBXKQ.js} +8 -9
  9. package/dist/{builtins-UJLMOVOV.js → builtins-K6TNDT24.js} +4 -4
  10. package/dist/{chunk-GVQJ5CCZ.js → chunk-2HFQNRV3.js} +7 -7
  11. package/dist/{chunk-QMXC4JB7.js → chunk-2NHR3NAY.js} +163 -1401
  12. package/dist/chunk-2X4RYJTJ.js +39 -0
  13. package/dist/{chunk-Y45G3AXC.js → chunk-2Z2IKEXI.js} +6 -10
  14. package/dist/{chunk-EIMVLWB3.js → chunk-34BHNEE3.js} +7 -3
  15. package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
  16. package/dist/chunk-3EBYEESD.js +314 -0
  17. package/dist/{chunk-CTJ4RNAA.js → chunk-3F7VUY77.js} +2 -2
  18. package/dist/{chunk-AP73CFDC.js → chunk-3KIPBMUA.js} +2 -2
  19. package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
  20. package/dist/{chunk-VEGN6WIQ.js → chunk-462T4EGZ.js} +2 -2
  21. package/dist/{chunk-AFKWHWXF.js → chunk-4JDLP6ZS.js} +33 -16
  22. package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
  23. package/dist/{chunk-AKB4GYDL.js → chunk-54ODD65L.js} +5 -5
  24. package/dist/{chunk-BBTJOK6Y.js → chunk-5KW52TEP.js} +3 -3
  25. package/dist/{chunk-6CCS4G3W.js → chunk-5PFYMY2V.js} +2 -2
  26. package/dist/chunk-77QIVUZB.js +1334 -0
  27. package/dist/{chunk-7OBGU7UB.js → chunk-7BHIY2MW.js} +7 -13
  28. package/dist/{chunk-3QSOM6PA.js → chunk-AZ4WMN4W.js} +2 -2
  29. package/dist/{chunk-6NJQITNH.js → chunk-B74PXLU7.js} +6 -3
  30. package/dist/{chunk-R23Z6K6I.js → chunk-B7HM5Z7T.js} +15 -15
  31. package/dist/{chunk-R32CLGZ6.js → chunk-BO7Y52RY.js} +81 -20
  32. package/dist/{chunk-UEDMSP56.js → chunk-BYMNWQ7O.js} +123 -148
  33. package/dist/{chunk-ZJLUDYFY.js → chunk-CRFOIAX3.js} +4 -4
  34. package/dist/{chunk-2NM363SV.js → chunk-CYZW7JHJ.js} +7 -7
  35. package/dist/{chunk-6HMJX2VU.js → chunk-DYHAXKHD.js} +38 -10
  36. package/dist/{chunk-THYWACCR.js → chunk-DZAW46HP.js} +3 -3
  37. package/dist/{chunk-FYUN5KZ3.js → chunk-DZEK6CJN.js} +17 -17
  38. package/dist/{chunk-3I5NY75V.js → chunk-E7GT7O5N.js} +5 -5
  39. package/dist/{chunk-VKFQTNDV.js → chunk-F2I26BDK.js} +4 -4
  40. package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
  41. package/dist/{chunk-IXJT6DCX.js → chunk-FVDGR2ZL.js} +3 -3
  42. package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
  43. package/dist/{chunk-7EPLI7VL.js → chunk-HIICAHCJ.js} +2 -2
  44. package/dist/{chunk-E67WX76H.js → chunk-HKMD33FO.js} +29 -80
  45. package/dist/chunk-HLAFFSEK.js +360 -0
  46. package/dist/{chunk-UAPGZHYC.js → chunk-I64IFBLB.js} +9 -2
  47. package/dist/{chunk-XKA2ICR3.js → chunk-I66ZTYNP.js} +440 -175
  48. package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
  49. package/dist/{chunk-PVAMAVBB.js → chunk-IDNA72AH.js} +102 -2
  50. package/dist/{chunk-GCSMB2KY.js → chunk-IKOZFYBN.js} +1 -1
  51. package/dist/{chunk-2VG7KLYV.js → chunk-IKSLQ4XV.js} +5460 -3241
  52. package/dist/{chunk-QKIFBZKT.js → chunk-IMXMHHMQ.js} +166 -25
  53. package/dist/{chunk-74YWRRU5.js → chunk-JBCS7CRR.js} +2 -2
  54. package/dist/{chunk-BDPT6GTK.js → chunk-JWJGP5DQ.js} +2 -2
  55. package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
  56. package/dist/chunk-KPXDY6QF.js +47 -0
  57. package/dist/{chunk-ABLSQ6JX.js → chunk-LJID3DYZ.js} +7 -1
  58. package/dist/{chunk-VKRH2TCS.js → chunk-M2DAX4F6.js} +2 -2
  59. package/dist/{chunk-6I5ILFOF.js → chunk-M2WXEHER.js} +2 -2
  60. package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
  61. package/dist/{chunk-N5UK64DP.js → chunk-MCMZMDAC.js} +2 -2
  62. package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
  63. package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
  64. package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
  65. package/dist/{chunk-HUAS7ITX.js → chunk-O3YUNJZ2.js} +13 -21
  66. package/dist/{chunk-MA3H6DM5.js → chunk-P75RZCJW.js} +25 -3
  67. package/dist/{chunk-IG7BCQBA.js → chunk-PGF63K6I.js} +2 -2
  68. package/dist/chunk-PJX3WQUQ.js +42 -0
  69. package/dist/{chunk-6DWBAZ5U.js → chunk-Q4XWMHX6.js} +4 -6
  70. package/dist/{chunk-OJTRZGR3.js → chunk-QQLGQY2A.js} +8 -8
  71. package/dist/{chunk-J4HBWF6Y.js → chunk-RLYRBIYQ.js} +115 -20
  72. package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
  73. package/dist/{chunk-C537JADH.js → chunk-SSEYRH53.js} +6 -7
  74. package/dist/chunk-SZAA6XDG.js +30 -0
  75. package/dist/{chunk-MOPSG2X7.js → chunk-TPEQIQIE.js} +6 -6
  76. package/dist/{chunk-JA5QWE4Z.js → chunk-UBRFI4HS.js} +1879 -1650
  77. package/dist/{chunk-BTGG6BG2.js → chunk-UH347SHR.js} +154 -15
  78. package/dist/{chunk-5YHDIDBP.js → chunk-UH632ZYL.js} +2 -2
  79. package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
  80. package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
  81. package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
  82. package/dist/{chunk-UXN6JT4W.js → chunk-W4YEMFBX.js} +2 -2
  83. package/dist/{chunk-TD3PGPQA.js → chunk-W6NIE6OW.js} +2 -2
  84. package/dist/{chunk-TVH4ONAM.js → chunk-X7IARSHT.js} +3 -3
  85. package/dist/{chunk-PJJ6MY27.js → chunk-XE3PCIXH.js} +3 -3
  86. package/dist/{chunk-FEFIFZTL.js → chunk-XGDPUNND.js} +2 -2
  87. package/dist/{chunk-SCYB3HA4.js → chunk-XOXV5GKE.js} +51 -16
  88. package/dist/{chunk-QTFGO774.js → chunk-XQRY4DTA.js} +24 -11
  89. package/dist/{chunk-BJGUKIG4.js → chunk-YJISEZKC.js} +2 -2
  90. package/dist/{chunk-GPPB3JBE.js → chunk-ZGNYYXQ6.js} +2 -2
  91. package/dist/{chunk-SINK3QR6.js → chunk-ZNT2M6TG.js} +7 -7
  92. package/dist/{chunk-7RY5VZPH.js → chunk-ZW4HH5JJ.js} +6 -6
  93. package/dist/cli/index.js +33 -32
  94. package/dist/{clio-IT3G3VQH.js → clio-7VB377CC.js} +7 -7
  95. package/dist/{code-nav-RK6S7F6E.js → code-nav-YVLCYA7V.js} +85 -17
  96. package/dist/{config-3QZRWZJF.js → config-4HVOS65E.js} +88 -43
  97. package/dist/{configure-FL7Y3KJF.js → configure-PIWO7B24.js} +10 -10
  98. package/dist/{context-5HE7ODYK.js → context-IYEHL3WQ.js} +33 -31
  99. package/dist/{context-XNHL75JV.js → context-KQYIWPWT.js} +47 -34
  100. package/dist/{context-KYQFRVDC.js → context-N6ZE3LGJ.js} +11 -11
  101. package/dist/{context-clear-N545L53A.js → context-clear-G4OGZJDS.js} +33 -31
  102. package/dist/{context-working-set-QHKXSV2F.js → context-working-set-BWLF6LJP.js} +7 -7
  103. package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-2QQAITS3.js} +38 -38
  104. package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
  105. package/dist/{doctor-ZGPEGHIP.js → doctor-LHBD36VU.js} +23 -22
  106. package/dist/{eval-GXLL44RD.js → eval-C45FYRJ6.js} +21 -20
  107. package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-6DEJPLBF.js} +2 -2
  108. package/dist/{evidence-HWLBRH3Q.js → evidence-6SHONYAF.js} +30 -28
  109. package/dist/{evolve-FTZBMNVW.js → evolve-KRKMV72X.js} +30 -28
  110. package/dist/{extensions-VHRBEID7.js → extensions-KPZ2UHBB.js} +5 -3
  111. package/dist/{fleet-CKZHJWZJ.js → fleet-IVTCKDHT.js} +62 -61
  112. package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-EDWL3IT7.js} +5 -5
  113. package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-YP3YEFGK.js} +4 -4
  114. package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-ZFWKHY2M.js} +16 -14
  115. package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-FVUNCBML.js} +31 -29
  116. package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-UN5XED4R.js} +2 -2
  117. package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-XOWC4HSX.js} +17 -15
  118. package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-UN3SODEL.js} +30 -28
  119. package/dist/{fleet-view-WAMJYNDT.js → fleet-view-TWHJKCN6.js} +31 -29
  120. package/dist/{init-5XQRBOFV.js → init-T2QORQ3Y.js} +50 -49
  121. package/dist/{interop-34TVO25M.js → interop-IN5I2A66.js} +5 -5
  122. package/dist/{library-3QY6KF57.js → library-LSCATDLZ.js} +15 -13
  123. package/dist/{memory-L4UTIIIW.js → memory-HYOKAGGJ.js} +31 -29
  124. package/dist/{models-ZVX3QOWE.js → models-2GPMFYCM.js} +22 -21
  125. package/dist/{monitor-CEKVSYTS.js → monitor-E4ASVUJH.js} +34 -32
  126. package/dist/{orchestrator-77BAP6BC.js → orchestrator-DDMPR3PY.js} +984 -583
  127. package/dist/{panes-7STHOAUJ.js → panes-E3RUXOW5.js} +4 -4
  128. package/dist/{panes-SHAUIRXY.js → panes-IXKLOKA2.js} +23 -8
  129. package/dist/{reset-EOLM7GVE.js → reset-OAQP3W4O.js} +4 -4
  130. package/dist/{resources-74GKTLSF.js → resources-OTRSN34L.js} +15 -13
  131. package/dist/{run-HBAUJNNZ.js → run-5DEYH5QK.js} +60 -59
  132. package/dist/{share-G3APVLVP.js → share-IHWTLO3M.js} +19 -15
  133. package/dist/{skills-35HHUKCR.js → skills-IYMXMKW4.js} +17 -15
  134. package/dist/{skills-eval-QN4HSHDC.js → skills-eval-DROHSJAR.js} +36 -36
  135. package/dist/{skills-inventory-J357J34F.js → skills-inventory-D7X4L4ZX.js} +15 -13
  136. package/dist/{slash-commands-JZZCQA32.js → slash-commands-QBM7UZ3B.js} +21 -18
  137. package/dist/{steer-XAVHJM22.js → steer-Z5DO23FJ.js} +2 -2
  138. package/dist/{targets-DSM6CY3M.js → targets-P2FUC4IL.js} +25 -28
  139. package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-YREJ3JX2.js} +5 -5
  140. package/dist/{tools-MKNWVPBH.js → tools-5B7RO6MV.js} +4 -4
  141. package/dist/{trace-ECQ7TIYZ.js → trace-YMGMUM6A.js} +55 -7
  142. package/dist/{upgrade-H7TOM7YL.js → upgrade-PXK3S2YM.js} +11 -9
  143. package/dist/{usage-X52N3IDJ.js → usage-ME5MPXGX.js} +36 -34
  144. package/dist/{verifiers-EJTVVSMA.js → verifiers-BVZ7IWOO.js} +5 -5
  145. package/dist/{verify-YJL6XET2.js → verify-5K7ZKQFC.js} +4 -4
  146. package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
  147. package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-F5W5QTYY.js} +48 -47
  148. package/dist/{with-panes-OBOBFIIR.js → with-panes-BYOJCLAM.js} +51 -255
  149. package/dist/worker/entry.js +45 -30
  150. package/docs/README.md +176 -81
  151. package/docs/{acp.md → architecture/acp.md} +36 -20
  152. package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
  153. package/docs/{architecture.md → architecture/architecture.md} +43 -22
  154. package/docs/{artifact-placement.md → architecture/artifact-placement.md} +26 -23
  155. package/docs/architecture/artifact-versions.md +90 -0
  156. package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
  157. package/docs/{context-engine.md → architecture/context-engine.md} +25 -25
  158. package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
  159. package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
  160. package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
  161. package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
  162. package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
  163. package/docs/{model-catalog.md → architecture/model-catalog.md} +40 -17
  164. package/docs/{observability.md → architecture/observability.md} +26 -13
  165. package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
  166. package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +55 -20
  167. package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +35 -24
  168. package/docs/{safety-model.md → architecture/safety-model.md} +20 -15
  169. package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
  170. package/docs/architecture/time-conventions.md +125 -0
  171. package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
  172. package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
  173. package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
  174. package/docs/{built-in-agents.md → guide/built-in-agents.md} +50 -34
  175. package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +65 -60
  176. package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +227 -289
  177. package/docs/guide/configuration-reference.md +1158 -0
  178. package/docs/{environment-variables.md → guide/environment-variables.md} +31 -28
  179. package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
  180. package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
  181. package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
  182. package/docs/{glossary.md → guide/glossary.md} +14 -11
  183. package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +44 -13
  184. package/docs/guide/panes-and-files.md +290 -0
  185. package/docs/{proactive-memory.md → guide/proactive-memory.md} +79 -66
  186. package/docs/{resource-library.md → guide/resource-library.md} +13 -4
  187. package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +7 -3
  188. package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
  189. package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
  190. package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
  191. package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
  192. package/docs/{development-pipeline.md → process/development-pipeline.md} +24 -26
  193. package/docs/process/documentation-coverage.md +100 -0
  194. package/docs/process/documentation-guide.md +187 -0
  195. package/docs/{eval-runner.md → process/eval-runner.md} +41 -50
  196. package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
  197. package/docs/{evolution.md → process/evolution.md} +2 -2
  198. package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
  199. package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
  200. package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
  201. package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
  202. package/evals/README.md +2 -2
  203. package/package.json +9 -7
  204. package/skills/README.md +46 -37
  205. package/skills/coding/ast-grep/SKILL.md +2 -2
  206. package/skills/coding/coding-standards/SKILL.md +2 -2
  207. package/skills/coding/prototype/SKILL.md +2 -2
  208. package/skills/coding/tdd/SKILL.md +2 -2
  209. package/skills/context/context-handoff/SKILL.md +2 -2
  210. package/skills/context/context-prime/SKILL.md +2 -2
  211. package/skills/git/file-ticket/SKILL.md +2 -2
  212. package/skills/git/fix-issue/SKILL.md +3 -3
  213. package/skills/git/resolve-merge-conflicts/SKILL.md +2 -2
  214. package/skills/git/ship/SKILL.md +2 -2
  215. package/skills/git/worktree-create/SKILL.md +2 -2
  216. package/skills/git/worktree-merge/SKILL.md +2 -2
  217. package/skills/meta/clio-coder-dev/SKILL.md +9 -5
  218. package/skills/meta/clio-coder-dev/evals.md +3 -2
  219. package/skills/meta/clio-coder-test/SKILL.md +102 -95
  220. package/skills/meta/clio-coder-test/evals.md +9 -4
  221. package/skills/meta/clio-coder-test/references/harness.md +100 -124
  222. package/skills/meta/clio-coder-test/references/test-map.md +77 -50
  223. package/skills/meta/credentials/SKILL.md +2 -2
  224. package/skills/meta/find-skills/SKILL.md +2 -2
  225. package/skills/meta/herdr/SKILL.md +2 -2
  226. package/skills/meta/skill-craft/SKILL.md +22 -16
  227. package/skills/planning/architecture/SKILL.md +2 -2
  228. package/skills/planning/backlog/SKILL.md +2 -2
  229. package/skills/planning/prd/SKILL.md +2 -2
  230. package/skills/planning/product-intent/SKILL.md +2 -2
  231. package/skills/planning/tech-spec/SKILL.md +2 -2
  232. package/skills/registry.yaml +62 -62
  233. package/skills/research/arxiv-literature/SKILL.md +2 -2
  234. package/skills/research/experiment-protocol/SKILL.md +2 -2
  235. package/skills/research/scientific-debugging/SKILL.md +2 -2
  236. package/skills/research/scientific-modernization/SKILL.md +2 -2
  237. package/skills/skill-marketplace.json +62 -62
  238. package/skills/workflow/cut-it/SKILL.md +2 -2
  239. package/skills/workflow/design-council/SKILL.md +2 -2
  240. package/skills/workflow/grill-me/SKILL.md +2 -2
  241. package/skills/workflow/workflow-distiller/SKILL.md +2 -2
  242. package/src/cli/args.ts +2 -2
  243. package/src/cli/bootstrap-generate.ts +1 -1
  244. package/src/cli/config-inspect.ts +65 -12
  245. package/src/cli/configure.ts +0 -4
  246. package/src/cli/docs.ts +22 -14
  247. package/src/cli/doctor-naming.ts +5 -5
  248. package/src/cli/doctor-toolchain.ts +3 -3
  249. package/src/cli/eval.ts +1 -2
  250. package/src/cli/extensions.ts +2 -1
  251. package/src/cli/fleet.ts +1 -1
  252. package/src/cli/index.ts +2 -1
  253. package/src/cli/internal-dispatch.ts +3 -4
  254. package/src/cli/panes.ts +19 -5
  255. package/src/cli/run.ts +2 -2
  256. package/src/cli/share.ts +5 -1
  257. package/src/cli/skills-eval.ts +3 -3
  258. package/src/cli/targets.ts +2 -6
  259. package/src/cli/trace.ts +55 -4
  260. package/src/cli/wiki-generate.ts +1 -1
  261. package/src/core/artifact-paths.ts +1 -1
  262. package/src/core/bash-exec.ts +131 -86
  263. package/src/core/bus-events.ts +51 -6
  264. package/src/core/config.ts +5 -1
  265. package/src/core/defaults.ts +7 -4
  266. package/src/core/dispatch-outcome.ts +16 -0
  267. package/src/core/guardrails.ts +10 -49
  268. package/src/core/prompt-hint.ts +9 -0
  269. package/src/domains/agents/builtins/architect.md +2 -3
  270. package/src/domains/agents/builtins/coder.md +3 -2
  271. package/src/domains/agents/builtins/debugger.md +2 -2
  272. package/src/domains/agents/builtins/documenter.md +2 -2
  273. package/src/domains/agents/builtins/git-master.md +1 -1
  274. package/src/domains/agents/builtins/oracle.md +1 -1
  275. package/src/domains/agents/builtins/provenance.md +1 -1
  276. package/src/domains/agents/builtins/researcher.md +1 -1
  277. package/src/domains/agents/builtins/scout.md +1 -1
  278. package/src/domains/agents/builtins/tester.md +2 -2
  279. package/src/domains/agents/builtins/verifier.md +2 -2
  280. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  281. package/src/domains/agents/catalog.ts +12 -14
  282. package/src/domains/agents/contract.ts +2 -0
  283. package/src/domains/agents/extension.ts +23 -1
  284. package/src/domains/config/keybindings.ts +8 -0
  285. package/src/domains/context/extension.ts +0 -3
  286. package/src/domains/context/working-set/path-index.ts +1 -0
  287. package/src/domains/dispatch/capability-match.ts +10 -0
  288. package/src/domains/dispatch/extension.ts +105 -22
  289. package/src/domains/dispatch/host-verification.ts +435 -39
  290. package/src/domains/dispatch/intent-requirements.ts +10 -0
  291. package/src/domains/dispatch/intent.ts +18 -1
  292. package/src/domains/dispatch/path-scope.ts +235 -24
  293. package/src/domains/dispatch/run-event-journal.ts +4 -15
  294. package/src/domains/dispatch/state.ts +2 -3
  295. package/src/domains/dispatch/transport.ts +45 -21
  296. package/src/domains/dispatch/types.ts +55 -3
  297. package/src/domains/eval/artifacts/store.ts +5 -0
  298. package/src/domains/eval/store.ts +8 -1
  299. package/src/domains/evidence/trust-status.ts +10 -1
  300. package/src/domains/extensions/contract.ts +15 -1
  301. package/src/domains/extensions/discovery.ts +238 -41
  302. package/src/domains/extensions/extension.ts +105 -6
  303. package/src/domains/extensions/index.ts +24 -0
  304. package/src/domains/extensions/integrity.ts +189 -0
  305. package/src/domains/extensions/manager.ts +17 -1
  306. package/src/domains/extensions/resource-path.ts +27 -0
  307. package/src/domains/extensions/resources.ts +18 -38
  308. package/src/domains/extensions/snapshot-store.ts +39 -0
  309. package/src/domains/extensions/snapshot.ts +180 -0
  310. package/src/domains/extensions/state.ts +385 -57
  311. package/src/domains/extensions/types.ts +118 -1
  312. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
  313. package/src/domains/lifecycle/migrations/index.ts +2 -0
  314. package/src/domains/lifecycle/naming-resources.ts +19 -4
  315. package/src/domains/lifecycle/naming-yazi.ts +10 -5
  316. package/src/domains/middleware/contract.ts +26 -0
  317. package/src/domains/middleware/extension.ts +24 -24
  318. package/src/domains/middleware/hook-receipts.ts +27 -4
  319. package/src/domains/middleware/hooks-io.ts +65 -32
  320. package/src/domains/middleware/hooks.ts +64 -0
  321. package/src/domains/middleware/index.ts +28 -4
  322. package/src/domains/middleware/registrations.ts +326 -0
  323. package/src/domains/middleware/runtime.ts +28 -0
  324. package/src/domains/middleware/snapshot.ts +20 -7
  325. package/src/domains/mux/contract.ts +38 -0
  326. package/src/domains/mux/detect.ts +6 -13
  327. package/src/domains/mux/index.ts +1 -1
  328. package/src/domains/mux/operations.ts +44 -5
  329. package/src/domains/mux/yazi/assets/yazi.toml +2 -2
  330. package/src/domains/mux/yazi/session.ts +53 -4
  331. package/src/domains/mux/yazi/theme.ts +117 -17
  332. package/src/domains/observability/contract.ts +10 -11
  333. package/src/domains/observability/extension.ts +11 -3
  334. package/src/domains/observability/projection.ts +14 -90
  335. package/src/domains/observability/trace-store.ts +43 -7
  336. package/src/domains/prompts/compiler.ts +73 -53
  337. package/src/domains/prompts/contract.ts +15 -3
  338. package/src/domains/prompts/extension.ts +97 -9
  339. package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
  340. package/src/domains/prompts/fragments/identity/clio.md +6 -12
  341. package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
  342. package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
  343. package/src/domains/prompts/fragments/operating/contract.md +7 -15
  344. package/src/domains/prompts/fragments/operating/delegation.md +32 -34
  345. package/src/domains/prompts/fragments/operating/skills.md +10 -24
  346. package/src/domains/prompts/fragments/operating/worker.md +1 -8
  347. package/src/domains/providers/index.ts +1 -1
  348. package/src/domains/providers/model-runtime-capabilities.ts +85 -21
  349. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +669 -104
  350. package/src/domains/providers/runtime-resolution.ts +31 -0
  351. package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
  352. package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
  353. package/src/domains/providers/types/cost-provenance.ts +19 -0
  354. package/src/domains/providers/types/local-model-quirks.ts +85 -37
  355. package/src/domains/resources/skills/loader.ts +16 -19
  356. package/src/domains/safety/call-target.ts +1 -1
  357. package/src/domains/safety/loop-detector.ts +7 -4
  358. package/src/domains/session/task-board.ts +10 -9
  359. package/src/domains/share/archive.ts +164 -7
  360. package/src/engine/acp/server.ts +62 -9
  361. package/src/engine/apis/llamacpp-residency.ts +3 -4
  362. package/src/engine/apis/lmstudio.ts +3 -3
  363. package/src/engine/apis/ollama-native.ts +6 -6
  364. package/src/engine/apis/openai-completions.ts +28 -25
  365. package/src/engine/apis/output-budget.ts +8 -18
  366. package/src/engine/apis/residency.ts +8 -27
  367. package/src/engine/gemma-channel-filter.ts +19 -0
  368. package/src/engine/loop-guard.ts +92 -12
  369. package/src/engine/worker-runtime.ts +40 -11
  370. package/src/engine/worker-tools.ts +3 -1
  371. package/src/entry/extension-hook-sources.ts +28 -0
  372. package/src/entry/extension-reload.ts +309 -0
  373. package/src/entry/orchestrator.ts +59 -35
  374. package/src/interactive/application-controller.ts +2 -1
  375. package/src/interactive/bus-notices.ts +8 -1
  376. package/src/interactive/chat-loop-messages.ts +3 -13
  377. package/src/interactive/chat-loop.ts +10 -1
  378. package/src/interactive/chat-panel.ts +36 -13
  379. package/src/interactive/chat-renderer.ts +71 -7
  380. package/src/interactive/dispatch-board.ts +6 -11
  381. package/src/interactive/footer/widgets.ts +13 -0
  382. package/src/interactive/interactive-application.ts +39 -4
  383. package/src/interactive/interactive-input-runtime.ts +4 -0
  384. package/src/interactive/interactive-presentation.ts +2 -2
  385. package/src/interactive/interactive-slash-runtime.ts +2 -0
  386. package/src/interactive/overlays/extensions.ts +9 -1
  387. package/src/interactive/overlays/help-reference.ts +13 -0
  388. package/src/interactive/overlays/settings.ts +27 -16
  389. package/src/interactive/panes-runtime.ts +111 -35
  390. package/src/interactive/prompt-cache-identity.ts +88 -0
  391. package/src/interactive/slash-commands.ts +129 -14
  392. package/src/interactive/stream-pacing-policy.ts +0 -23
  393. package/src/interactive/turn-context.ts +30 -15
  394. package/src/interactive/yazi-bridge.ts +60 -6
  395. package/src/tools/agent-tools.ts +30 -1
  396. package/src/tools/artifact.ts +2 -2
  397. package/src/tools/ask-user.ts +3 -3
  398. package/src/tools/bash.ts +1 -1
  399. package/src/tools/bootstrap.ts +4 -0
  400. package/src/tools/builtin-tool-catalog.ts +52 -22
  401. package/src/tools/codewiki/code-nav-surface.ts +6 -0
  402. package/src/tools/codewiki/code-nav.ts +99 -13
  403. package/src/tools/context/docs-engine.ts +20 -7
  404. package/src/tools/context/index.ts +29 -12
  405. package/src/tools/core-bootstrap.ts +28 -6
  406. package/src/tools/credential-present.ts +1 -2
  407. package/src/tools/dispatch-arguments.ts +5 -1
  408. package/src/tools/dispatch-plan.ts +48 -4
  409. package/src/tools/dispatch-run-events.ts +1 -1
  410. package/src/tools/dispatch-schema.ts +338 -0
  411. package/src/tools/dispatch-types.ts +3 -0
  412. package/src/tools/dispatch.ts +9 -254
  413. package/src/tools/ledger.ts +3 -5
  414. package/src/tools/monitor-surface.ts +5 -13
  415. package/src/tools/observation.ts +4 -5
  416. package/src/tools/panes-surface.ts +4 -11
  417. package/src/tools/panes.ts +4 -2
  418. package/src/tools/policy.ts +15 -2
  419. package/src/tools/read.ts +5 -6
  420. package/src/tools/registry.ts +30 -7
  421. package/src/tools/result-shaping.ts +18 -14
  422. package/src/tools/steer-surface.ts +1 -1
  423. package/src/tools/tasks.ts +1 -1
  424. package/src/tools/truncate.ts +6 -5
  425. package/src/tools/verify/surface.ts +6 -12
  426. package/src/tools/web-fetch-surface.ts +1 -3
  427. package/dist/chunk-5QIAJV2D.js +0 -48
  428. package/dist/chunk-JZWT5J3Y.js +0 -814
  429. package/dist/chunk-K7VKOLQQ.js +0 -15
  430. package/dist/chunk-PMZCIOCJ.js +0 -25
  431. package/dist/chunk-SUW5DORT.js +0 -819
  432. package/dist/chunk-UOV2BYIW.js +0 -107
  433. package/dist/chunk-WR6U3OVP.js +0 -45
  434. package/docs/artifact-versions.md +0 -67
  435. package/docs/documentation-coverage.md +0 -46
  436. package/docs/documentation-guide.md +0 -167
  437. package/docs/time-conventions.md +0 -101
@@ -27,6 +27,7 @@ import type { MuxContract, MuxPaneRecord } from "../domains/mux/index.js";
27
27
  import {
28
28
  PANES_PRESETS,
29
29
  type PanesCloseResult,
30
+ type PanesFilesResult,
30
31
  type PanesInventoryEntry,
31
32
  type PanesOpenResult,
32
33
  type PanesOperations,
@@ -36,6 +37,7 @@ import {
36
37
  type PanesYaziController,
37
38
  type PanesYaziStatus,
38
39
  type PanesZoomResult,
40
+ resolvePanesPresetId,
39
41
  } from "../domains/mux/operations.js";
40
42
  import { resolveBinary } from "../tools/executables.js";
41
43
  import { type PaneWatchSource, paneWatchDecision } from "./pane-policy.js";
@@ -54,7 +56,16 @@ export interface PanesRuntimeDeps {
54
56
  newestJournalRunId?: () => string | null;
55
57
  }
56
58
 
57
- const UNAVAILABLE = "the pane layer is not available in this session";
59
+ /**
60
+ * Why there is no pane layer, in the operator's terms. Detection already
61
+ * knows (no `HERDR_ENV`, no socket, a refused rung); repeating that reason
62
+ * beside the refusal is what turns "unavailable" into a next step, and the
63
+ * `--with-panes` hint covers the session that never asked for panes.
64
+ */
65
+ function unavailableReason(mux: MuxContract): string {
66
+ const reason = mux.detection().reason;
67
+ return `the pane layer is not available in this session: ${reason}. Start Clio inside a herdr session with \`clio-coder --with-panes\` to get panes`;
68
+ }
58
69
 
59
70
  /** Fuzzy operator addressing shared by `close` and `zoom`: id, label, purpose; newest first. */
60
71
  function matchOwnedPane(owned: ReadonlyArray<MuxPaneRecord>, target: string): MuxPaneRecord | null {
@@ -78,6 +89,27 @@ function inventory(records: ReadonlyArray<MuxPaneRecord>): ReadonlyArray<PanesIn
78
89
  }));
79
90
  }
80
91
 
92
+ /**
93
+ * The sentence `/quit` prints about the panes it did not close, or null when
94
+ * there are none.
95
+ *
96
+ * Policy (#272): docks close with the session and utility panes stay. A dock
97
+ * is a Clio surface (the files pane, the workers watch pane), so it goes the
98
+ * way a native application's windows go. A pane opened with `/panes open
99
+ * shell|logs|<argv>` is a terminal the operator may be typing in, and killing
100
+ * it on quit is the one thing a pane host must never do behind the operator's
101
+ * back. The next session does not adopt it either, so without this line the
102
+ * pane simply sat there with nothing naming it. Computed before the mux
103
+ * domain stops, because shutdown forgets its registry.
104
+ */
105
+ export function describePanesLeftBehind(mux: Pick<MuxContract, "list" | "docks">): string | null {
106
+ const dockIds = new Set(mux.docks().map((dock) => dock.paneId));
107
+ const left = mux.list().filter((record) => !dockIds.has(record.ref.paneId));
108
+ if (left.length === 0) return null;
109
+ const named = left.map((record) => `${record.label} (${record.ref.paneId})`).join(", ");
110
+ return `Clio left ${left.length} ${left.length === 1 ? "pane" : "panes"} open in herdr: ${named}. Utility panes stay when a session ends; the docks closed with it. Next time run \`/panes close all\` before \`/quit\` to take them with you, or close ${left.length === 1 ? "it" : "them"} now with \`herdr pane close <paneId>\`.`;
111
+ }
112
+
81
113
  export function createPanesRuntime(deps: PanesRuntimeDeps): PanesOperations {
82
114
  const probe = deps.resolveBinaryPath ?? resolveBinary;
83
115
  const journalRoot = deps.journalRoot ?? runEventJournalRoot;
@@ -143,7 +175,7 @@ export function createPanesRuntime(deps: PanesRuntimeDeps): PanesOperations {
143
175
  };
144
176
 
145
177
  const show = async (target: string, source: PaneWatchSource): Promise<PanesShowResult> => {
146
- if (!deps.mux.available()) return { status: "unavailable", reason: UNAVAILABLE };
178
+ if (!deps.mux.available()) return { status: "unavailable", reason: unavailableReason(deps.mux) };
147
179
  const match = matchRun(target);
148
180
  if (match === null) {
149
181
  // The candidate list is what turns a miss into a next step: it names
@@ -164,7 +196,58 @@ export function createPanesRuntime(deps: PanesRuntimeDeps): PanesOperations {
164
196
  return { status: "watching", runId: match.runId, agentId: match.agentId, opened: watched.opened };
165
197
  };
166
198
 
199
+ /**
200
+ * The files pane's open half, shared by `/files`, `/panes open files`, the
201
+ * keybinding, and the model tool. The settings gate and the missing-engine
202
+ * message live here so every door says the same thing.
203
+ */
204
+ const openFiles = async (once: boolean): Promise<Exclude<PanesFilesResult, { status: "closed" }>> => {
205
+ const preset = PANES_PRESETS[0];
206
+ if (!deps.getSettings().interface.panes.files.enabled) {
207
+ return { status: "refused", reason: "the files pane is disabled by interface.panes.files.enabled" };
208
+ }
209
+ if (!yaziController) {
210
+ return { status: "unavailable", reason: "the files pane return path is not ready" };
211
+ }
212
+ const pendingId = beginPendingOpen(preset.id);
213
+ try {
214
+ const result = await yaziController.open(once ? { once: true } : undefined);
215
+ if (result.status === "opened") {
216
+ return { status: "opened", paneId: result.paneId, existing: result.existing };
217
+ }
218
+ if (result.status === "missing-binary") {
219
+ return {
220
+ status: "missing-binary",
221
+ binary: result.binary,
222
+ installHint: preset.installHint,
223
+ // The engine's own resolution sentence, prefixed with the surface it
224
+ // serves: an operator who typed `/files` should not have to know the
225
+ // name of the program to read the answer.
226
+ detail: `the files pane engine is not available: ${result.detail}`,
227
+ };
228
+ }
229
+ return {
230
+ status: result.status === "profile-error" ? "refused" : "unavailable",
231
+ reason: result.reason,
232
+ };
233
+ } finally {
234
+ pendingOpens.delete(pendingId);
235
+ }
236
+ };
237
+
167
238
  return {
239
+ async files(action): Promise<PanesFilesResult> {
240
+ if (action === "close") {
241
+ await yaziController?.close();
242
+ return { status: "closed" };
243
+ }
244
+ if (action === "toggle" && yaziController?.isOpen()) {
245
+ await yaziController.close();
246
+ return { status: "closed" };
247
+ }
248
+ return openFiles(action === "pick");
249
+ },
250
+
168
251
  status(): PanesStatus {
169
252
  const detection = deps.mux.detection();
170
253
  const settings = deps.getSettings();
@@ -201,41 +284,31 @@ export function createPanesRuntime(deps: PanesRuntimeDeps): PanesOperations {
201
284
  async open(request: { preset?: string; argv?: ReadonlyArray<string>; once?: boolean }): Promise<PanesOpenResult> {
202
285
  const cwd = deps.getCwd();
203
286
  if (request.preset !== undefined) {
204
- const preset = PANES_PRESETS.find((entry) => entry.id === request.preset);
287
+ const presetId = resolvePanesPresetId(request.preset);
288
+ const preset = presetId === null ? undefined : PANES_PRESETS.find((entry) => entry.id === presetId);
205
289
  if (!preset) {
206
290
  return { status: "refused", reason: `unknown preset: ${request.preset}` };
207
291
  }
208
- if (preset.id === "yazi") {
209
- if (!deps.getSettings().interface.panes.files.enabled) {
210
- return { status: "refused", reason: "the files pane is disabled by panes.yazi.enabled" };
211
- }
212
- if (!yaziController) {
213
- return { status: "unavailable", reason: "the files-pane return path is not ready" };
292
+ if (preset.id === "files") {
293
+ const result = await openFiles(request.once === true);
294
+ if (result.status === "opened") {
295
+ return { status: "opened", label: preset.id, paneId: result.paneId, existing: result.existing };
214
296
  }
215
- const pendingId = beginPendingOpen(preset.id);
216
- try {
217
- const result = await yaziController.open(request.once ? { once: true } : undefined);
218
- if (result.status === "opened") {
219
- return { status: "opened", label: preset.id, paneId: result.paneId };
220
- }
221
- if (result.status === "missing-binary") {
222
- return {
223
- status: "missing-binary",
224
- preset: preset.id,
225
- binary: result.binary,
226
- installHint: preset.installHint,
227
- detail: result.detail,
228
- };
229
- }
230
- return {
231
- status: result.status === "profile-error" ? "refused" : "unavailable",
232
- reason: result.reason,
233
- };
234
- } finally {
235
- pendingOpens.delete(pendingId);
297
+ if (result.status === "missing-binary") {
298
+ return { ...result, preset: preset.id };
236
299
  }
300
+ return result;
301
+ }
302
+ if (!deps.mux.available()) return { status: "unavailable", reason: unavailableReason(deps.mux) };
303
+ // One pane per preset. A second `/panes open shell` is a request to
304
+ // see the shell that is already there, not to split the screen again;
305
+ // the pane host is asked for focus so the operator lands in it.
306
+ const live = deps.mux.list().find((record) => record.purpose === "utility" && record.label === preset.id);
307
+ if (live) {
308
+ await deps.mux.unzoomSelf();
309
+ await deps.mux.focusPane(live.ref.paneId);
310
+ return { status: "opened", label: preset.id, paneId: live.ref.paneId, existing: true };
237
311
  }
238
- if (!deps.mux.available()) return { status: "unavailable", reason: UNAVAILABLE };
239
312
  const binaryPath = probe(preset.binary);
240
313
  if (binaryPath === null) {
241
314
  return {
@@ -248,7 +321,10 @@ export function createPanesRuntime(deps: PanesRuntimeDeps): PanesOperations {
248
321
  }
249
322
  const argv = presetArgv(preset.id, binaryPath);
250
323
  if (argv === null) {
251
- return { status: "refused", reason: `preset ${preset.id} has nothing to show yet` };
324
+ return {
325
+ status: "refused",
326
+ reason: `no dispatched run has written a journal under ${journalRoot()} yet; the logs pane follows the newest run once one starts`,
327
+ };
252
328
  }
253
329
  const pendingId = beginPendingOpen(preset.id);
254
330
  try {
@@ -259,7 +335,7 @@ export function createPanesRuntime(deps: PanesRuntimeDeps): PanesOperations {
259
335
  pendingOpens.delete(pendingId);
260
336
  }
261
337
  }
262
- if (!deps.mux.available()) return { status: "unavailable", reason: UNAVAILABLE };
338
+ if (!deps.mux.available()) return { status: "unavailable", reason: unavailableReason(deps.mux) };
263
339
  const argv = request.argv ?? [];
264
340
  if (argv.length === 0) return { status: "refused", reason: "nothing to run" };
265
341
  const label = argv[0] ?? "pane";
@@ -274,7 +350,7 @@ export function createPanesRuntime(deps: PanesRuntimeDeps): PanesOperations {
274
350
  },
275
351
 
276
352
  async zoom(target: string): Promise<PanesZoomResult> {
277
- if (!deps.mux.available()) return { status: "unavailable", reason: UNAVAILABLE };
353
+ if (!deps.mux.available()) return { status: "unavailable", reason: unavailableReason(deps.mux) };
278
354
  const match = matchOwnedPane(deps.mux.list(), target.trim().length === 0 ? "watch" : target);
279
355
  if (!match) return { status: "not-found", target: target.trim().length === 0 ? "watch" : target };
280
356
  const changed = await deps.mux.zoomPane(match.ref.paneId, "toggle");
@@ -285,7 +361,7 @@ export function createPanesRuntime(deps: PanesRuntimeDeps): PanesOperations {
285
361
  },
286
362
 
287
363
  async close(target: string): Promise<PanesCloseResult> {
288
- if (!deps.mux.available()) return { status: "unavailable", reason: UNAVAILABLE };
364
+ if (!deps.mux.available()) return { status: "unavailable", reason: unavailableReason(deps.mux) };
289
365
  const owned = deps.mux.list();
290
366
  if (target === "all") {
291
367
  const labels: string[] = [];
@@ -0,0 +1,88 @@
1
+ import type { SessionPromptInputs } from "../domains/prompts/compiler.js";
2
+ import { canonicalJson, sha256 } from "../domains/prompts/hash.js";
3
+ import type { ContextWindowSource } from "../domains/providers/index.js";
4
+ import type { AutonomyLevel } from "../domains/safety/autonomy.js";
5
+
6
+ /** The exact schema bytes pi attaches to a provider request for one tool. */
7
+ export interface AttachedToolSchema {
8
+ name: string;
9
+ description: string;
10
+ parameters: unknown;
11
+ }
12
+
13
+ /**
14
+ * Project the live agent tools onto the schema fields sent to the provider.
15
+ * Array order is preserved because providers serialize the attached tools in
16
+ * that order, so reordering them changes prompt-prefix bytes too.
17
+ */
18
+ export function attachedToolSchemasFromState(tools: ReadonlyArray<unknown>): AttachedToolSchema[] {
19
+ const schemas: AttachedToolSchema[] = [];
20
+ for (const tool of tools) {
21
+ if (!tool || typeof tool !== "object" || Array.isArray(tool)) continue;
22
+ const record = tool as Record<string, unknown>;
23
+ schemas.push({
24
+ name: typeof record.name === "string" ? record.name : "",
25
+ description: typeof record.description === "string" ? record.description : "",
26
+ parameters: record.parameters ?? null,
27
+ });
28
+ }
29
+ return schemas;
30
+ }
31
+
32
+ /**
33
+ * Serialize the exact ordered schema sequence attached to a provider request.
34
+ *
35
+ * `canonicalJson` is deliberately not used here: provider JSON preserves tool
36
+ * array order and nested object insertion order, so canonicalizing parameters
37
+ * can alias two byte-distinct request prefixes. Standard `JSON.stringify`
38
+ * matches the request serialization boundary and throws for unsupported
39
+ * values such as circular references and bigint.
40
+ */
41
+ export function attachedToolSchemaBytes(schemas: ReadonlyArray<AttachedToolSchema>): string {
42
+ try {
43
+ const bytes = JSON.stringify(schemas);
44
+ if (bytes === undefined) throw new Error("JSON.stringify returned undefined");
45
+ return bytes;
46
+ } catch (err) {
47
+ const reason = err instanceof Error ? err.message : String(err);
48
+ throw new Error(`attached tool schemas are not JSON-serializable: ${reason}`, { cause: err });
49
+ }
50
+ }
51
+
52
+ export interface MainPromptCacheIdentityInput {
53
+ targetId: string;
54
+ runtimeId: string;
55
+ wireModelId: string;
56
+ autonomy: AutonomyLevel;
57
+ sessionId: string;
58
+ cwd: string;
59
+ workingContextPaths: ReadonlyArray<string>;
60
+ contextWindowSource: ContextWindowSource | null;
61
+ promptInputEpoch: string;
62
+ sessionInputs: SessionPromptInputs;
63
+ attachedToolSchemas: ReadonlyArray<AttachedToolSchema>;
64
+ }
65
+
66
+ /**
67
+ * Canonical identity for the interactive session-prompt compile cache.
68
+ * Config hot reload explicitly invalidates compiler-owned fragments and
69
+ * rosters; this identity covers every live/caller input resolved per turn.
70
+ */
71
+ export function mainPromptCacheIdentity(input: MainPromptCacheIdentityInput): string {
72
+ return sha256(
73
+ canonicalJson({
74
+ version: 2,
75
+ targetId: input.targetId,
76
+ runtimeId: input.runtimeId,
77
+ wireModelId: input.wireModelId,
78
+ autonomy: input.autonomy,
79
+ sessionId: input.sessionId,
80
+ cwd: input.cwd,
81
+ workingContextPaths: [...input.workingContextPaths].sort((a, b) => a.localeCompare(b)),
82
+ contextWindowSource: input.contextWindowSource,
83
+ promptInputEpoch: input.promptInputEpoch,
84
+ sessionInputs: input.sessionInputs,
85
+ attachedToolSchemaBytes: attachedToolSchemaBytes(input.attachedToolSchemas),
86
+ }),
87
+ );
88
+ }
@@ -13,12 +13,12 @@ import type { ReceiptIntegrityOutcome } from "../domains/evidence/trust-status.j
13
13
  import type { InstalledExtension } from "../domains/extensions/index.js";
14
14
  import type { InteropAgentId, InteropProposal, InteropReport } from "../domains/interop/index.js";
15
15
  import {
16
- isPanesPresetId,
17
16
  PANES_PRESET_IDS,
18
17
  PANES_PRESETS,
19
18
  type PanesOperations,
20
19
  type PanesPresetId,
21
20
  type PanesStatus,
21
+ resolvePanesPresetId,
22
22
  } from "../domains/mux/operations.js";
23
23
  import type { ProvidersContract, ResolvedModelRef } from "../domains/providers/index.js";
24
24
  import { resolveModelReference } from "../domains/providers/index.js";
@@ -31,6 +31,7 @@ import type {
31
31
  import { parseSkillCommand } from "../domains/resources/index.js";
32
32
  import type { ShareImportPlan } from "../domains/share/index.js";
33
33
  import type { UserTask } from "../domains/user-tasks/store.js";
34
+ import type { ExtensionReloadOutcome } from "../entry/extension-reload.js";
34
35
  import { isToolProfileName, TOOL_PROFILE_NAMES, type ToolProfileName } from "../tools/profiles.js";
35
36
  import type { NoticeLevel } from "./command-output.js";
36
37
  import {
@@ -115,7 +116,7 @@ type SlashCommandVariant =
115
116
  /** `ref` is the turnId an `[evicted ...]` marker names. */
116
117
  | { kind: "context-recall"; ref: string }
117
118
  | { kind: "skill-selector" }
118
- | { kind: "resources"; family?: "skills" | "prompts" | "extensions"; tab?: LibraryEntryKind }
119
+ | { kind: "resources"; family?: "skills" | "prompts" | "extensions"; tab?: LibraryEntryKind; action?: "reload" }
119
120
  | { kind: "skill-invocation"; text: string }
120
121
  | ShareCommandVariant
121
122
  | ArchiveCommandVariant
@@ -161,6 +162,9 @@ type SlashCommandVariant =
161
162
  | { kind: "panes-zoom"; target: string }
162
163
  | { kind: "panes-close"; target: string }
163
164
  | { kind: "panes-usage"; reason?: string }
165
+ /** `/files`: toggle the files pane; `pick` borrows it for one selection; `close` closes it. */
166
+ | { kind: "files"; action: "toggle" | "open" | "close" | "pick" }
167
+ | { kind: "files-usage"; reason: string }
164
168
  | { kind: "thinking-set"; level: string }
165
169
  | { kind: "thinking-picker" }
166
170
  | { kind: "output-set"; verbosity: string }
@@ -599,6 +603,13 @@ export interface SlashCommandContext {
599
603
  */
600
604
  expandPromptTemplate?: (text: string) => PromptTemplateExpansion;
601
605
  listExtensions?: () => ReadonlyArray<InstalledExtension>;
606
+ /**
607
+ * `/resources extensions reload`: build, validate, and commit the next
608
+ * extension generation together with its user hooks, or report why it was
609
+ * refused. Absent on a host without the reload coordinator, in which case
610
+ * the command says so instead of pretending.
611
+ */
612
+ reloadExtensions?: () => ExtensionReloadOutcome;
602
613
  /** Detection report, pending proposals, and the two consent actions `/interop` drives. */
603
614
  interop?: {
604
615
  report: () => InteropReport | null;
@@ -937,22 +948,27 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
937
948
  skills: "Browse installed skills",
938
949
  prompts: "Browse prompt templates",
939
950
  library: "Browse resource libraries",
940
- extensions: "Browse installed extensions",
951
+ extensions: "Browse installed extensions; `reload` commits a new extension generation",
941
952
  },
942
953
  args: {
943
954
  subcommands: {
944
955
  skills: {},
945
956
  prompts: {},
946
957
  library: { positionals: [{ name: "kind", required: false }] },
947
- extensions: {},
958
+ extensions: { positionals: [{ name: "action", required: false, values: ["reload"] }] },
948
959
  },
949
960
  },
950
961
  fromArgs(parsed) {
951
962
  if (parsed.error) return { kind: "usage-error", command: "resources", reason: parsed.error };
952
963
  if (parsed.subcommand === undefined || parsed.subcommand === "skills")
953
964
  return { kind: "resources", family: "skills" };
954
- if (parsed.subcommand === "prompts" || parsed.subcommand === "extensions")
955
- return { kind: "resources", family: parsed.subcommand };
965
+ if (parsed.subcommand === "prompts") return { kind: "resources", family: "prompts" };
966
+ if (parsed.subcommand === "extensions") {
967
+ const action = parsed.positionals[0];
968
+ if (action === undefined) return { kind: "resources", family: "extensions" };
969
+ if (action === "reload") return { kind: "resources", family: "extensions", action: "reload" };
970
+ return { kind: "usage-error", command: "resources", reason: `Unknown action: ${action} (one of reload)` };
971
+ }
956
972
  const tab = parsed.positionals[0];
957
973
  if (tab === undefined) return { kind: "resources" };
958
974
  if (!isLibraryTab(tab)) {
@@ -964,8 +980,10 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
964
980
  handle(command, ctx) {
965
981
  if (command.kind !== "resources") return;
966
982
  if (command.family === "prompts") ctx.openPrompts();
967
- else if (command.family === "extensions") ctx.openExtensions();
968
- else ctx.openSkillsHub?.(command.tab);
983
+ else if (command.family === "extensions") {
984
+ if (command.action === "reload") reloadExtensionsCommand(ctx);
985
+ else ctx.openExtensions();
986
+ } else ctx.openSkillsHub?.(command.tab);
969
987
  },
970
988
  },
971
989
  {
@@ -1643,7 +1661,7 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
1643
1661
  },
1644
1662
  subcommandDescriptions: {
1645
1663
  show: "watch a live run or agent in the watch pane",
1646
- open: `open a utility pane (${PANES_PRESET_IDS.join(", ")}, or a command)`,
1664
+ open: `open a utility pane (${PANES_PRESET_IDS.join(", ")}, \`files --once\` for one pick, or a command)`,
1647
1665
  zoom: "toggle zoom on a Clio-owned pane (default: the watch pane)",
1648
1666
  close: "close a Clio-owned pane, or all of them",
1649
1667
  },
@@ -1659,9 +1677,10 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
1659
1677
  const first = argv[0] ?? "";
1660
1678
  // A bare preset name is a preset; anything else is operator argv,
1661
1679
  // which the tool surface deliberately cannot ask for.
1662
- if (argv.length === 1 && isPanesPresetId(first)) return { kind: "panes-open", preset: first };
1663
- if (argv.length === 2 && first === "yazi" && argv[1] === "--once") {
1664
- return { kind: "panes-open", preset: "yazi", once: true };
1680
+ const preset = resolvePanesPresetId(first);
1681
+ if (argv.length === 1 && preset !== null) return { kind: "panes-open", preset };
1682
+ if (argv.length === 2 && preset === "files" && argv[1] === "--once") {
1683
+ return { kind: "panes-open", preset: "files", once: true };
1665
1684
  }
1666
1685
  return { kind: "panes-open", argv };
1667
1686
  }
@@ -1691,7 +1710,7 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
1691
1710
  // every `--with-panes` session, even one where no pane host answered.
1692
1711
  ctx.notice(
1693
1712
  "info",
1694
- "panes are inactive: this session started without them. Restart with `clio-coder --with-panes`, or set panes.enabled=auto",
1713
+ "panes are inactive: this session started without them. Restart with `clio-coder --with-panes`, or set interface.panes.enabled=auto",
1695
1714
  );
1696
1715
  return;
1697
1716
  }
@@ -1728,7 +1747,14 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
1728
1747
  // The in-terminal chooser has already restored the TUI by the
1729
1748
  // time this resolves. A pick emitted its composer notice; an empty
1730
1749
  // chooser was cancellation and deliberately stays silent.
1731
- if (result.paneId !== null) ctx.notice("success", `opened pane ${result.label} (${result.paneId})`);
1750
+ if (result.paneId !== null) {
1751
+ ctx.notice(
1752
+ "success",
1753
+ result.existing
1754
+ ? `focused pane ${result.label} (${result.paneId})`
1755
+ : `opened pane ${result.label} (${result.paneId})`,
1756
+ );
1757
+ }
1732
1758
  } else if (result.status === "missing-binary") {
1733
1759
  // This is a synchronous slash-surface line, not a transient pane-host
1734
1760
  // notification. It remains visible when no pane was ever created and
@@ -1768,6 +1794,62 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
1768
1794
  });
1769
1795
  },
1770
1796
  },
1797
+ {
1798
+ name: "files",
1799
+ description: "Toggle the files pane; picks land in the composer as @ mentions",
1800
+ group: "Inspect",
1801
+ kinds: ["files", "files-usage"],
1802
+ args: { positionals: [{ name: "action", required: false }] },
1803
+ subcommandDescriptions: {
1804
+ open: "open the files pane, or focus it when it is already open",
1805
+ close: "close the files pane",
1806
+ pick: "borrow the files pane for one selection, then close it",
1807
+ },
1808
+ fromArgs(parsed) {
1809
+ if (parsed.error) return { kind: "files-usage", reason: parsed.error };
1810
+ const action = parsed.positionals[0];
1811
+ if (action === undefined) return { kind: "files", action: "toggle" };
1812
+ if (action === "open" || action === "close" || action === "pick" || action === "toggle") {
1813
+ return { kind: "files", action };
1814
+ }
1815
+ return { kind: "files-usage", reason: `Unexpected argument: ${action}` };
1816
+ },
1817
+ handle(command, ctx) {
1818
+ if (command.kind === "files-usage") {
1819
+ ctx.notice("info", `${command.reason}\nusage: /files [open|close|pick]`);
1820
+ return;
1821
+ }
1822
+ if (command.kind !== "files") return;
1823
+ const panes = ctx.panes;
1824
+ if (!panes) {
1825
+ ctx.notice(
1826
+ "info",
1827
+ "the files pane is inactive: this session started without panes. Restart with `clio-coder --with-panes`, or set interface.panes.enabled=auto",
1828
+ );
1829
+ return;
1830
+ }
1831
+ const runLocal = ctx.runLocalOperation ?? ((operation: () => Promise<void>) => void operation());
1832
+ runLocal(async () => {
1833
+ const result = await panes.files(command.action);
1834
+ if (result.status === "opened") {
1835
+ // The in-terminal chooser reports through its own composer notice.
1836
+ if (result.paneId !== null) {
1837
+ ctx.notice(
1838
+ "success",
1839
+ result.existing ? `files pane focused (${result.paneId})` : `files pane opened (${result.paneId})`,
1840
+ );
1841
+ }
1842
+ } else if (result.status === "closed") {
1843
+ ctx.notice("info", "files pane closed");
1844
+ } else if (result.status === "missing-binary") {
1845
+ ctx.io.stdout(`${result.detail}\n`);
1846
+ ctx.render();
1847
+ } else {
1848
+ ctx.notice("warn", result.reason);
1849
+ }
1850
+ });
1851
+ },
1852
+ },
1771
1853
  {
1772
1854
  name: "thinking",
1773
1855
  description: "Set the chat thinking level",
@@ -2069,6 +2151,39 @@ function retiredCommandHint(token: string): string | undefined {
2069
2151
  }
2070
2152
 
2071
2153
  /** Pure slash-command parser: no I/O, no side effects. Walks the registry in order. */
2154
+ /**
2155
+ * One notice line for a reload outcome. Success when the generation committed
2156
+ * cleanly; warn when it committed with dropped hooks or declaration issues;
2157
+ * error when it was refused and the previous generation stays active.
2158
+ */
2159
+ export function formatExtensionReloadNotice(outcome: ExtensionReloadOutcome): [NoticeLevel, string] {
2160
+ if (outcome.status !== "committed") {
2161
+ return ["error", `extensions: reload rejected (${outcome.reason}); generation ${outcome.generation} stays active`];
2162
+ }
2163
+ const delta = outcome.changed
2164
+ ? `changed: +${outcome.added.length} -${outcome.removed.length} ~${outcome.modified.length}`
2165
+ : "unchanged";
2166
+ const issueCount = outcome.hooks.fileIssues + outcome.hooks.issues;
2167
+ const hookParts = [`${outcome.hooks.registered} registered`];
2168
+ if (outcome.hooks.dropped > 0) hookParts.push(`${outcome.hooks.dropped} dropped`);
2169
+ if (issueCount > 0) hookParts.push(`${issueCount} issue${issueCount === 1 ? "" : "s"}`);
2170
+ if (outcome.hooks.overridden > 0) hookParts.push(`${outcome.hooks.overridden} overridden`);
2171
+ const level: NoticeLevel = outcome.hooks.dropped > 0 || issueCount > 0 ? "warn" : "success";
2172
+ return [level, `extensions: generation ${outcome.generation} committed (${delta}); hooks: ${hookParts.join(", ")}`];
2173
+ }
2174
+
2175
+ function reloadExtensionsCommand(ctx: SlashCommandContext): void {
2176
+ if (!ctx.reloadExtensions) {
2177
+ ctx.notice("warn", "extensions: reload is unavailable in this session; restart to pick up installed changes");
2178
+ return;
2179
+ }
2180
+ const outcome = ctx.reloadExtensions();
2181
+ const [level, text] = formatExtensionReloadNotice(outcome);
2182
+ ctx.notice(level, text);
2183
+ for (const line of outcome.lines) ctx.notice("warn", line);
2184
+ if (outcome.status === "committed") ctx.openExtensions();
2185
+ }
2186
+
2072
2187
  export function parseSlashCommand(input: string): SlashCommand {
2073
2188
  const trimmed = input.trim();
2074
2189
  if (trimmed.length === 0) return { kind: "empty" };
@@ -1,28 +1,6 @@
1
- import type { SmoothStreaming } from "../core/defaults.js";
2
-
3
- export const SMOOTH_STREAM_ENV = "CLIO_CODER_SMOOTH_STREAM";
4
-
5
- /**
6
- * One-process override precedence: a valid environment value wins, while an
7
- * invalid value can never accidentally enable animation. `0` is the immediate
8
- * escape hatch; `1` is accepted as the explicit `on` spelling.
9
- */
10
- export function resolveSmoothStreamingMode(
11
- configured: SmoothStreaming,
12
- env: NodeJS.ProcessEnv = process.env,
13
- ): SmoothStreaming {
14
- const raw = env[SMOOTH_STREAM_ENV]?.trim().toLowerCase();
15
- if (!raw) return configured;
16
- if (raw === "0" || raw === "off" || raw === "false") return "off";
17
- if (raw === "auto") return "auto";
18
- if (raw === "1" || raw === "on" || raw === "true") return "on";
19
- return "off";
20
- }
21
-
22
1
  export interface AutoPacingEnvironment {
23
2
  isTTY: boolean;
24
3
  term?: string;
25
- termProgram?: string;
26
4
  sshConnection?: string;
27
5
  sshTty?: string;
28
6
  tmux?: string;
@@ -53,7 +31,6 @@ export function processAutoPacingAllowed(backpressureObserved: boolean, env: Nod
53
31
  return autoPacingAllowed({
54
32
  isTTY: process.stdout.isTTY === true,
55
33
  ...(env.TERM === undefined ? {} : { term: env.TERM }),
56
- ...(env.TERM_PROGRAM === undefined ? {} : { termProgram: env.TERM_PROGRAM }),
57
34
  ...(env.SSH_CONNECTION === undefined ? {} : { sshConnection: env.SSH_CONNECTION }),
58
35
  ...(env.SSH_TTY === undefined ? {} : { sshTty: env.SSH_TTY }),
59
36
  ...(env.TMUX === undefined ? {} : { tmux: env.TMUX }),