@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
@@ -273,6 +273,34 @@ function appendThinkingDiagnostics(
273
273
  diagnostics.push(diagnostic(severity, `thinking-${thinking.noticeKind}`, thinking.notice));
274
274
  }
275
275
 
276
+ const CHAT_TEMPLATE_KWARGS_UNDELIVERABLE = "chat-template-kwargs-undeliverable";
277
+
278
+ /**
279
+ * One warning when the family declares chat-template kwargs the runtime
280
+ * cannot carry (#268). LM Studio ignores `chat_template_kwargs` for every
281
+ * family measured, so a Nemotron 3.5 target on that runtime runs without the
282
+ * `force_nonempty_content` its card asks for; the operator sees that once per
283
+ * target and model rather than finding the key silently missing from the wire.
284
+ */
285
+ function appendChatTemplateKwargsDiagnostics(
286
+ diagnostics: RuntimeResolutionDiagnostic[],
287
+ resolved: ResolvedModelRuntimeCapabilities,
288
+ ): void {
289
+ const undeliverable = resolved.request.undeliverableChatTemplateKwargs;
290
+ if (!undeliverable || undeliverable.keys.length === 0) return;
291
+ const keys = undeliverable.keys.join(", ");
292
+ const declared = undeliverable.declaredUnsupported
293
+ ? "its family entry marks them unsupported there"
294
+ : "its family entry does not say so";
295
+ diagnostics.push(
296
+ diagnostic(
297
+ "warning",
298
+ CHAT_TEMPLATE_KWARGS_UNDELIVERABLE,
299
+ `chat-template kwargs ${keys} cannot reach ${resolved.runtimeId}, which ignores chat_template_kwargs; ${resolved.modelId} runs without them and ${declared}`,
300
+ ),
301
+ );
302
+ }
303
+
276
304
  function nonNegativeFiniteNumber(value: unknown): number | undefined {
277
305
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined;
278
306
  }
@@ -447,6 +475,7 @@ export function resolveRuntimeTarget(
447
475
  const decisions = capabilityDecisions(runtime, capabilities);
448
476
  appendCapabilityDiagnostics(diagnostics, input, capabilities, decisions, targetId);
449
477
  appendThinkingDiagnostics(diagnostics, modelRuntime, requestedThinkingLevel);
478
+ appendChatTemplateKwargsDiagnostics(diagnostics, modelRuntime);
450
479
 
451
480
  if (hasError(diagnostics)) return { ok: false, diagnostics };
452
481
 
@@ -493,6 +522,7 @@ function withoutStaleRuntimeDiagnostics(
493
522
  ): RuntimeResolutionDiagnostic[] {
494
523
  return diagnostics.filter((entry) => {
495
524
  if (entry.code.startsWith("thinking-")) return false;
525
+ if (entry.code === CHAT_TEMPLATE_KWARGS_UNDELIVERABLE) return false;
496
526
  if (entry.code === "output-budget-unknown" && decisions.maxTokens > 0) return false;
497
527
  if (entry.code === "tools-unsupported" && decisions.tools) return false;
498
528
  return true;
@@ -545,6 +575,7 @@ export function refineRuntimeTargetWithModelHints(
545
575
  const decisions = capabilityDecisions(target.runtime, capabilities);
546
576
  const diagnostics = withoutStaleRuntimeDiagnostics(target.diagnostics, decisions);
547
577
  appendThinkingDiagnostics(diagnostics, modelRuntime, target.requestedThinkingLevel);
578
+ appendChatTemplateKwargsDiagnostics(diagnostics, modelRuntime);
548
579
  return {
549
580
  ...target,
550
581
  capabilities,
@@ -374,6 +374,8 @@ export interface LlamaCppStatusEnrichment {
374
374
  modelId?: string;
375
375
  serverFlags?: LlamaCppServerFlags;
376
376
  notes?: string[];
377
+ /** The router's own load state for the selected model, when it reports one. */
378
+ loadState?: ProbeModelStatus["state"];
377
379
  }
378
380
 
379
381
  function argsFromStatus(status: unknown): string[] {
@@ -490,8 +492,11 @@ export async function probeLlamaCppModelStatus(
490
492
  const entries = await probeOpenAIModelEntries(base, ctx);
491
493
  const selected = selectedModelEntry(entries, target);
492
494
  if (!selected) return {};
495
+ const loadState = modelStateFromOpenAIModelEntry({ id: selected.id, status: selected.status })?.state;
496
+ const withState = (enrichment: LlamaCppStatusEnrichment): LlamaCppStatusEnrichment =>
497
+ loadState === undefined ? enrichment : { ...enrichment, loadState };
493
498
  const args = argsFromStatus(selected.status);
494
- if (args.length === 0) return { notes: statusNotes(selected.id, selected.status) };
499
+ if (args.length === 0) return withState({ notes: statusNotes(selected.id, selected.status) });
495
500
  const flags = parseLlamaCppServerFlags(args);
496
501
  const caps: Partial<CapabilityFlags> = {};
497
502
  const window = llamaCppRequestContextWindow(flags);
@@ -512,7 +517,7 @@ export async function probeLlamaCppModelStatus(
512
517
  );
513
518
  }
514
519
  if (notes.length > 0) enrichment.notes = notes;
515
- return enrichment;
520
+ return withState(enrichment);
516
521
  }
517
522
 
518
523
  /**
@@ -56,7 +56,15 @@ const llamacppRuntime: RuntimeDescriptor = {
56
56
  const health = await (ctx.signal ? probeHttp({ ...healthOpts, signal: ctx.signal }) : probeHttp(healthOpts));
57
57
  if (!health.ok) return health;
58
58
  const status = await probeLlamaCppModelStatus(base, target, ctx);
59
- const props = await probeLlamaCppProps(base, ctx, status.modelId ?? target.defaultModel);
59
+ // A router answers /props?model=<id> by loading that model, and with
60
+ // --models-max 1 that evicts whatever is resident: every probe of a
61
+ // fleet target's default model unloaded the chat model, so the next turn
62
+ // prefilled from zero (11,601 tokens, cache_n 0, on the round-3 resume
63
+ // run on mini). The router's model list already carries the worker's
64
+ // flags (--parallel, --ctx-size) for an unloaded model, so the worker is
65
+ // asked only when it is resident.
66
+ const resident = status.loadState === undefined || status.loadState === "loaded";
67
+ const props = await probeLlamaCppProps(base, ctx, resident ? (status.modelId ?? target.defaultModel) : undefined);
60
68
  const catalog = await probeOpenAIModelCatalog(base, ctx);
61
69
  const result: ProbeResult = { ok: true };
62
70
  if (catalog.models.length > 0) result.models = catalog.models;
@@ -5,3 +5,22 @@ export type CostProvenance = "known" | "known_free" | "estimated" | "unknown";
5
5
  export function normalizeCostProvenance(value: CostProvenance | undefined): CostProvenance {
6
6
  return value ?? "unknown";
7
7
  }
8
+
9
+ const COST_PROVENANCE_VALUES: ReadonlySet<string> = new Set<CostProvenance>([
10
+ "known",
11
+ "known_free",
12
+ "estimated",
13
+ "unknown",
14
+ ]);
15
+
16
+ /**
17
+ * Validate an unvalidated wire value (a dispatch bus payload crossing a
18
+ * worker process boundary, never runtime-checked against this closed set
19
+ * before) against the four real provenance values. An unrecognized value
20
+ * keeps `fallback` rather than being accepted as-is, matching how the
21
+ * observability projection's run summary already treated this field; the
22
+ * interactive dispatch board previously accepted any truthy string here.
23
+ */
24
+ export function resolveCostProvenance(value: unknown, fallback: CostProvenance): CostProvenance {
25
+ return typeof value === "string" && COST_PROVENANCE_VALUES.has(value) ? (value as CostProvenance) : fallback;
26
+ }
@@ -2,7 +2,7 @@
2
2
  * Engine-visible quirks extracted from a knowledge-base entry. The catalog YAML
3
3
  * keeps free-form `quirks` (gpu tiers, runtime preferences, serving notes), so
4
4
  * `KnowledgeBaseEntry.quirks` stays `Record<string, unknown>`. This module
5
- * narrows the slice the engine consumes (KV cache layout, per-mode sampling)
5
+ * narrows the slice the engine consumes (per-mode sampling and thinking)
6
6
  * into a typed shape that flows through `model.clioCoder.quirks` at synth time.
7
7
  *
8
8
  * Field naming follows the Hugging Face / model-card terminology so the YAML
@@ -13,19 +13,7 @@
13
13
  */
14
14
 
15
15
  import type { ThinkingBudgetByLevel, ThinkingEffortByLevel } from "../thinking-control-policy.js";
16
-
17
- export const KV_CACHE_QUANTS = ["f32", "f16", "q8_0", "q4_0", "q4_1", "iq4_nl", "q5_0", "q5_1"] as const;
18
-
19
- export type KvCacheQuant = (typeof KV_CACHE_QUANTS)[number];
20
-
21
- export interface KvCacheQuirks {
22
- /** Quantization type for the key cache. `false` disables quantization (full precision). */
23
- kQuant?: KvCacheQuant | false;
24
- /** Quantization type for the value cache. Requires flash attention to take effect. */
25
- vQuant?: KvCacheQuant | false;
26
- /** Force fp16 KV cache regardless of K/V quant settings. */
27
- useFp16?: boolean;
28
- }
16
+ import { type ThinkingLevel, VALID_THINKING_LEVELS } from "./capability-flags.js";
29
17
 
30
18
  export interface SamplingProfile {
31
19
  temperature?: number;
@@ -36,7 +24,6 @@ export interface SamplingProfile {
36
24
  repeatPenalty?: number;
37
25
  presencePenalty?: number;
38
26
  frequencyPenalty?: number;
39
- maxTokens?: number;
40
27
  }
41
28
 
42
29
  export interface SamplingQuirks {
@@ -59,6 +46,20 @@ export interface SamplingQuirks {
59
46
  */
60
47
  export type ThinkingMechanism = "effort-levels" | "budget-tokens" | "on-off" | "always-on" | "none";
61
48
 
49
+ export type ChatTemplateKwargValue = string | number | boolean;
50
+
51
+ export interface ChatTemplateKwargsByLevel {
52
+ key: string;
53
+ values: Partial<Record<ThinkingLevel, string | number>>;
54
+ lmstudio?: "unsupported" | string;
55
+ }
56
+
57
+ export interface ChatTemplateKwargsQuirks {
58
+ static?: Record<string, ChatTemplateKwargValue>;
59
+ byLevel?: ChatTemplateKwargsByLevel;
60
+ lmstudio?: "unsupported" | string | Record<string, string>;
61
+ }
62
+
62
63
  export interface ThinkingQuirks {
63
64
  mechanism: ThinkingMechanism;
64
65
  /** Token budget for budget-tokens mechanism, keyed by Clio's thinking level. */
@@ -67,24 +68,19 @@ export interface ThinkingQuirks {
67
68
  effortByLevel?: ThinkingEffortByLevel;
68
69
  /** 2-5 line free-text guidance rendered into the Runtime prompt block. */
69
70
  guidance?: string;
71
+ chatTemplateKwargs?: ChatTemplateKwargsQuirks;
70
72
  }
71
73
 
72
74
  export interface LocalModelQuirks {
73
- kvCache?: KvCacheQuirks;
74
75
  sampling?: SamplingQuirks;
75
76
  thinking?: ThinkingQuirks;
77
+ chatTemplateKwargs?: ChatTemplateKwargsQuirks;
76
78
  }
77
79
 
78
80
  function isRecord(value: unknown): value is Record<string, unknown> {
79
81
  return value !== null && typeof value === "object" && !Array.isArray(value);
80
82
  }
81
83
 
82
- function asKvCacheQuant(value: unknown): KvCacheQuant | false | undefined {
83
- if (value === false) return false;
84
- if (typeof value !== "string") return undefined;
85
- return (KV_CACHE_QUANTS as ReadonlyArray<string>).includes(value) ? (value as KvCacheQuant) : undefined;
86
- }
87
-
88
84
  function asPositive(value: unknown): number | undefined {
89
85
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined;
90
86
  }
@@ -98,17 +94,6 @@ function asPenalty(value: unknown): number | undefined {
98
94
  return typeof value === "number" && Number.isFinite(value) ? value : undefined;
99
95
  }
100
96
 
101
- function extractKvCache(raw: unknown): KvCacheQuirks | undefined {
102
- if (!isRecord(raw)) return undefined;
103
- const out: KvCacheQuirks = {};
104
- const k = asKvCacheQuant(raw.kQuant);
105
- if (k !== undefined) out.kQuant = k;
106
- const v = asKvCacheQuant(raw.vQuant);
107
- if (v !== undefined) out.vQuant = v;
108
- if (typeof raw.useFp16 === "boolean") out.useFp16 = raw.useFp16;
109
- return Object.keys(out).length > 0 ? out : undefined;
110
- }
111
-
112
97
  function extractSamplingProfile(raw: unknown): SamplingProfile | undefined {
113
98
  if (!isRecord(raw)) return undefined;
114
99
  const out: SamplingProfile = {};
@@ -129,8 +114,6 @@ function extractSamplingProfile(raw: unknown): SamplingProfile | undefined {
129
114
  if (pp !== undefined) out.presencePenalty = pp;
130
115
  const fp = asPenalty(raw.frequencyPenalty);
131
116
  if (fp !== undefined) out.frequencyPenalty = fp;
132
- const maxTokens = asInteger(raw.maxTokens);
133
- if (maxTokens !== undefined) out.maxTokens = maxTokens;
134
117
  return Object.keys(out).length > 0 ? out : undefined;
135
118
  }
136
119
 
@@ -185,6 +168,66 @@ function extractEffortByLevel(raw: unknown): ThinkingQuirks["effortByLevel"] | u
185
168
  return Object.keys(out).length > 0 ? out : undefined;
186
169
  }
187
170
 
171
+ function extractChatTemplateKwargs(raw: unknown): ChatTemplateKwargsQuirks | undefined {
172
+ if (!isRecord(raw)) return undefined;
173
+ const out: ChatTemplateKwargsQuirks = {};
174
+
175
+ if (isRecord(raw.static)) {
176
+ const staticMap: Record<string, ChatTemplateKwargValue> = {};
177
+ for (const [k, v] of Object.entries(raw.static)) {
178
+ if (typeof v === "boolean") {
179
+ staticMap[k] = v;
180
+ } else if (typeof v === "number" && Number.isFinite(v)) {
181
+ staticMap[k] = v;
182
+ } else if (typeof v === "string" && v.length > 0) {
183
+ staticMap[k] = v;
184
+ }
185
+ }
186
+ if (Object.keys(staticMap).length > 0) out.static = staticMap;
187
+ }
188
+
189
+ if (isRecord(raw.byLevel)) {
190
+ const byLevelRaw = raw.byLevel;
191
+ if (typeof byLevelRaw.key === "string" && byLevelRaw.key.trim().length > 0 && isRecord(byLevelRaw.values)) {
192
+ const values: Partial<Record<ThinkingLevel, string | number>> = {};
193
+ for (const level of VALID_THINKING_LEVELS) {
194
+ const val = byLevelRaw.values[level];
195
+ if (typeof val === "string" && val.length > 0) {
196
+ values[level] = val;
197
+ } else if (typeof val === "number" && Number.isFinite(val)) {
198
+ values[level] = val;
199
+ }
200
+ }
201
+ if (Object.keys(values).length > 0) {
202
+ const byLevel: ChatTemplateKwargsByLevel = {
203
+ key: byLevelRaw.key.trim(),
204
+ values,
205
+ };
206
+ if (typeof byLevelRaw.lmstudio === "string" && byLevelRaw.lmstudio.trim().length > 0) {
207
+ byLevel.lmstudio = byLevelRaw.lmstudio.trim();
208
+ }
209
+ out.byLevel = byLevel;
210
+ }
211
+ }
212
+ }
213
+
214
+ if (typeof raw.lmstudio === "string" && raw.lmstudio.trim().length > 0) {
215
+ out.lmstudio = raw.lmstudio.trim();
216
+ } else if (isRecord(raw.lmstudio)) {
217
+ const lmstudioMap: Record<string, string> = {};
218
+ for (const [k, v] of Object.entries(raw.lmstudio)) {
219
+ if (typeof v === "string" && v.trim().length > 0) {
220
+ lmstudioMap[k] = v.trim();
221
+ }
222
+ }
223
+ if (Object.keys(lmstudioMap).length > 0) {
224
+ out.lmstudio = lmstudioMap;
225
+ }
226
+ }
227
+
228
+ return Object.keys(out).length > 0 ? out : undefined;
229
+ }
230
+
188
231
  function extractThinkingQuirks(raw: unknown): ThinkingQuirks | undefined {
189
232
  if (!isRecord(raw)) return undefined;
190
233
  const mechanism = asThinkingMechanism(raw.mechanism);
@@ -195,6 +238,8 @@ function extractThinkingQuirks(raw: unknown): ThinkingQuirks | undefined {
195
238
  const effortByLevel = extractEffortByLevel(raw.effortByLevel);
196
239
  if (effortByLevel) out.effortByLevel = effortByLevel;
197
240
  if (typeof raw.guidance === "string" && raw.guidance.length > 0) out.guidance = raw.guidance;
241
+ const chatTemplateKwargs = extractChatTemplateKwargs(raw.chatTemplateKwargs);
242
+ if (chatTemplateKwargs) out.chatTemplateKwargs = chatTemplateKwargs;
198
243
  return out;
199
244
  }
200
245
 
@@ -206,11 +251,14 @@ function extractThinkingQuirks(raw: unknown): ThinkingQuirks | undefined {
206
251
  export function extractLocalModelQuirks(raw: unknown): LocalModelQuirks | undefined {
207
252
  if (!isRecord(raw)) return undefined;
208
253
  const out: LocalModelQuirks = {};
209
- const kvCache = extractKvCache(raw.kvCache);
210
- if (kvCache) out.kvCache = kvCache;
211
254
  const sampling = extractSampling(raw.sampling);
212
255
  if (sampling) out.sampling = sampling;
213
256
  const thinking = extractThinkingQuirks(raw.thinking);
214
257
  if (thinking) out.thinking = thinking;
258
+ const chatTemplateKwargs =
259
+ extractChatTemplateKwargs(raw.chatTemplateKwargs) ??
260
+ extractChatTemplateKwargs(isRecord(raw.thinking) ? raw.thinking.chatTemplateKwargs : undefined) ??
261
+ extractChatTemplateKwargs(isRecord(raw.request) ? raw.request.chatTemplateKwargs : undefined);
262
+ if (chatTemplateKwargs) out.chatTemplateKwargs = chatTemplateKwargs;
215
263
  return Object.keys(out).length > 0 ? out : undefined;
216
264
  }
@@ -217,20 +217,8 @@ function defaultPrecedenceForScope(scope: ResourceScope): number {
217
217
  * this gate with skills: both substitute another agent's project file into
218
218
  * Clio's context, so one opt-in covers both.
219
219
  */
220
- let warnedLegacyProjectTrustEnv = false;
221
-
222
220
  export function projectCompatTrusted(explicit?: boolean): boolean {
223
- if (explicit === true) return true;
224
- if (process.env.CLIO_CODER_TRUST_PROJECT_RESOURCES === "1") return true;
225
- if (process.env.CLIO_CODER_TRUST_PROJECT_SKILLS !== "1") return false;
226
- if (!warnedLegacyProjectTrustEnv) {
227
- warnedLegacyProjectTrustEnv = true;
228
- process.emitWarning("CLIO_CODER_TRUST_PROJECT_SKILLS is deprecated; use CLIO_CODER_TRUST_PROJECT_RESOURCES instead", {
229
- code: "CLIO_CODER_DEPRECATED_ENV",
230
- type: "DeprecationWarning",
231
- });
232
- }
233
- return true;
221
+ return explicit === true;
234
222
  }
235
223
 
236
224
  /**
@@ -453,7 +441,16 @@ function validateDescription(description: string | null): string[] {
453
441
  return [];
454
442
  }
455
443
 
456
- function extractMetadata(frontmatter: Record<string, unknown>): Record<string, unknown> {
444
+ /**
445
+ * The deprecation names the file: a bare "clio: skill metadata" warning at
446
+ * boot left the operator hunting across five compatibility roots for the
447
+ * SKILL.md that carried the key, and `doctor` scanned only two of them.
448
+ */
449
+ function warnLegacySkillMetadata(filePath: string): void {
450
+ warnLegacyNaming(`clio: skill metadata in ${filePath}`, "clio-coder: skill metadata");
451
+ }
452
+
453
+ function extractMetadata(frontmatter: Record<string, unknown>, filePath: string): Record<string, unknown> {
457
454
  const metadata: Record<string, unknown> = {};
458
455
  for (const [key, value] of Object.entries(frontmatter)) {
459
456
  if (CORE_FRONTMATTER_KEYS.has(key)) continue;
@@ -462,7 +459,7 @@ function extractMetadata(frontmatter: Record<string, unknown>): Record<string, u
462
459
  continue;
463
460
  }
464
461
  if (key === "clio") {
465
- warnLegacyNaming("clio: skill metadata", "clio-coder: skill metadata");
462
+ warnLegacySkillMetadata(filePath);
466
463
  if (!("clio-coder" in frontmatter)) metadata.clioCoder = value;
467
464
  continue;
468
465
  }
@@ -471,13 +468,13 @@ function extractMetadata(frontmatter: Record<string, unknown>): Record<string, u
471
468
  return metadata;
472
469
  }
473
470
 
474
- function extractProvenance(frontmatter: Record<string, unknown>): SkillProvenance | undefined {
471
+ function extractProvenance(frontmatter: Record<string, unknown>, filePath: string): SkillProvenance | undefined {
475
472
  // Provenance lives nested under the reserved `clio-coder:` block; the flat
476
473
  // top-level keys remain readable for already-installed copies stamped
477
474
  // before the nested form existed.
478
475
  const canonicalRaw = frontmatter["clio-coder"];
479
476
  const legacyRaw = frontmatter.clio;
480
- if (legacyRaw !== undefined) warnLegacyNaming("clio: skill metadata", "clio-coder: skill metadata");
477
+ if (legacyRaw !== undefined) warnLegacySkillMetadata(filePath);
481
478
  const clioCoderRaw = canonicalRaw ?? legacyRaw;
482
479
  const clioCoder =
483
480
  clioCoderRaw !== null && typeof clioCoderRaw === "object" && !Array.isArray(clioCoderRaw)
@@ -671,7 +668,7 @@ function loadSkillFile(
671
668
  scope,
672
669
  ...(root.origin ? { source: root.origin } : {}),
673
670
  };
674
- const provenance = extractProvenance(parsed.frontmatter);
671
+ const provenance = extractProvenance(parsed.frontmatter, filePath);
675
672
  const allowedTools = declaredToolSurface(parsed.frontmatter, "allowed-tools", filePath, diagnostics);
676
673
  const disallowedTools = declaredToolSurface(parsed.frontmatter, "disallowed-tools", filePath, diagnostics);
677
674
  const skill: Skill = {
@@ -691,7 +688,7 @@ function loadSkillFile(
691
688
  pathSubject,
692
689
  trusted: root.trusted ?? true,
693
690
  precedence: root.precedence ?? defaultPrecedenceForScope(scope),
694
- metadata: extractMetadata(parsed.frontmatter),
691
+ metadata: extractMetadata(parsed.frontmatter, filePath),
695
692
  diagnostics,
696
693
  ...(provenance ? { provenance } : {}),
697
694
  };
@@ -168,7 +168,7 @@ const CALL_TARGET_FIELDS: Readonly<Record<string, ReadonlyArray<string>>> = {
168
168
  grep: ["pattern", "path", "mode", "glob", "ignore_case", "literal", "context", "limit", "include_ignored"],
169
169
  find: ["pattern", "path", "order", "limit", "include_ignored"],
170
170
  ls: ["path", "limit"],
171
- code_nav: ["mode", "query", "limit"],
171
+ code_nav: ["source", "mode", "query", "limit"],
172
172
  context: ["scope", "query", "name", "limit", "ref", "include_tree"],
173
173
  credential_present: ["name", "source", "file"],
174
174
  write: ["path"],
@@ -33,10 +33,12 @@ const DEFAULT_WINDOW_MS = 30_000;
33
33
  // stops them before they burn a turn. Callers that need a different cadence
34
34
  // pass `maxRepeats` explicitly.
35
35
  const DEFAULT_MAX_REPEATS = 3;
36
- // Sized so a consecutive or single-interleaved verbatim spiral still counts
37
- // its third repeat at any call latency, while an identical check separated by
38
- // two or more other calls (a fix-verify loop) stays below the threshold.
39
- const DEFAULT_KEEP_LAST_ATTEMPTS = 4;
36
+ // Sized so a batch-shaped spiral still counts its third repeat at any call
37
+ // latency: a model that re-emits the same parallel batch of up to sixteen
38
+ // calls three times has every key inside the retained tail. Fix-verify loops
39
+ // are not this detector's concern any more; the loop guard keys attempts by
40
+ // the turn's write/edit epoch, so a check rerun after a change is a new key.
41
+ const DEFAULT_KEEP_LAST_ATTEMPTS = 48;
40
42
 
41
43
  export function createLoopState(opts?: {
42
44
  windowMs?: number;
@@ -138,6 +140,7 @@ export function observe(state: LoopDetectorState, key: string, now: number): [Lo
138
140
  recent: next,
139
141
  windowMs: state.windowMs,
140
142
  maxRepeats: state.maxRepeats,
143
+ keepLastAttempts: keepLast,
141
144
  };
142
145
  return [newState, { looping, key, count }];
143
146
  }
@@ -421,10 +421,8 @@ function applyMutation(
421
421
  // Completion is the ledger's only load-bearing claim, so it carries two
422
422
  // structural conditions rather than a bare status flip. Evidence is
423
423
  // mandatory: a completed row becomes a passed validation record, and a row
424
- // without evidence would assert a validation that nobody performed. The
425
- // task must also have been started, because work that was never entered
426
- // cannot have produced a result; the honest closes for it are block and
427
- // drop, which record a reason instead.
424
+ // without evidence would assert a validation that nobody performed. Work
425
+ // that did not happen is closed with block or drop, which record a reason.
428
426
  if (mutation.op === "done") {
429
427
  if (mutation.evidence.trim().length === 0) {
430
428
  return {
@@ -432,13 +430,16 @@ function applyMutation(
432
430
  "done requires note as the evidence that the task actually finished (the command you ran, the file:line you verified). If the work did not happen, use block with a reason or drop it.",
433
431
  };
434
432
  }
435
- if (target.status === "pending") {
436
- return {
437
- error: `task ${target.id} was never started, so it cannot be completed. Start it and do the work, or record the truth with block (reason) or drop.`,
438
- };
439
- }
440
433
  }
441
434
  const notes: string[] = [];
435
+ // A model that did the work without announcing it on the board closes
436
+ // several tasks in a row at the end of the turn. Refusing done on a pending
437
+ // task cost a live session six start/done pairs of pure ceremony; the
438
+ // evidence note is the load-bearing claim, so the start is recorded
439
+ // implicitly and named in the notes.
440
+ if (mutation.op === "done" && target.status === "pending") {
441
+ notes.push(`started ${target.id} implicitly: done on a pending task records the start and the completion together`);
442
+ }
442
443
  const tasks = board.tasks.map((task): TaskBoardTask => {
443
444
  if (task.id !== target.id) {
444
445
  // One active task at a time: starting a task parks any other active