@iowarp/clio-coder 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (595) hide show
  1. package/CHANGELOG.md +90 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +284 -613
  4. package/dist/{acp-FPR54DGL.js → acp-BIYHVZIM.js} +43 -53
  5. package/dist/{agents-OGPIHPJH.js → agents-YT6SSRIT.js} +43 -26
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
  8. package/dist/{chunk-PV4JUBVJ.js → chunk-2EHAIA3X.js} +40 -21
  9. package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
  10. package/dist/chunk-2SFS6XQE.js +122 -0
  11. package/dist/chunk-2VTFPG5O.js +48 -0
  12. package/dist/{chunk-MAR7Y6HW.js → chunk-3ZXDFGR5.js} +23 -16
  13. package/dist/chunk-4BJ5BYCE.js +61 -0
  14. package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
  15. package/dist/chunk-4KLWL3UC.js +18 -0
  16. package/dist/chunk-4VP4KH3K.js +962 -0
  17. package/dist/chunk-4ZG3XFUR.js +77 -0
  18. package/dist/chunk-5B2AEOW5.js +5407 -0
  19. package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
  20. package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
  21. package/dist/chunk-65DEGPJ6.js +52 -0
  22. package/dist/chunk-6EJMN2Y3.js +17 -0
  23. package/dist/chunk-6EJV5X2W.js +16405 -0
  24. package/dist/chunk-6N5PTWMY.js +136 -0
  25. package/dist/chunk-6XLNIQDB.js +27 -0
  26. package/dist/{chunk-TEKV33Q5.js → chunk-77VKQEHF.js} +65 -33
  27. package/dist/chunk-7CR24IG7.js +242 -0
  28. package/dist/{chunk-M5T5VO65.js → chunk-7EYHLWU7.js} +837 -635
  29. package/dist/chunk-7MNJORFF.js +22 -0
  30. package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
  31. package/dist/chunk-AGYYIBLL.js +1069 -0
  32. package/dist/chunk-AO4RKG4M.js +277 -0
  33. package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
  34. package/dist/chunk-ARBGF5F7.js +174 -0
  35. package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
  36. package/dist/chunk-CBCAPZAA.js +229 -0
  37. package/dist/chunk-CMZWFGD2.js +352 -0
  38. package/dist/chunk-ECH6PKUQ.js +39 -0
  39. package/dist/chunk-ED4KHGC3.js +143 -0
  40. package/dist/chunk-EKMEHE4H.js +340 -0
  41. package/dist/{chunk-RPTR2H26.js → chunk-EPVUXGXG.js} +21 -15
  42. package/dist/chunk-FCSXB6T2.js +338 -0
  43. package/dist/chunk-FJ3H4MN5.js +48 -0
  44. package/dist/chunk-FQ4SKYE4.js +29 -0
  45. package/dist/chunk-G2DE3C7R.js +644 -0
  46. package/dist/chunk-G4BMMOKF.js +182 -0
  47. package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
  48. package/dist/chunk-HC4CLZ2Y.js +68 -0
  49. package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
  50. package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
  51. package/dist/chunk-I4HZDVNP.js +73 -0
  52. package/dist/{chunk-4QKXUHSR.js → chunk-IGLFWIYI.js} +70 -20
  53. package/dist/chunk-IKCO5N3L.js +162 -0
  54. package/dist/chunk-IR4CFBFN.js +56 -0
  55. package/dist/{chunk-PFEFKVGL.js → chunk-J5HN4RYU.js} +13 -11
  56. package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
  57. package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
  58. package/dist/chunk-KJ5LWLOE.js +1077 -0
  59. package/dist/chunk-LBMZMYH2.js +285 -0
  60. package/dist/{chunk-G34LV2PF.js → chunk-LBNRH5WM.js} +84 -170
  61. package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
  62. package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
  63. package/dist/chunk-MAW544W2.js +1882 -0
  64. package/dist/chunk-MBS4V7ZP.js +217 -0
  65. package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
  66. package/dist/chunk-MNA4JGU4.js +255 -0
  67. package/dist/chunk-MQSRRFWA.js +3428 -0
  68. package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
  69. package/dist/chunk-OAO4GE4M.js +619 -0
  70. package/dist/chunk-OHHN2SO4.js +5135 -0
  71. package/dist/chunk-OKGUZO2U.js +34 -0
  72. package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
  73. package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
  74. package/dist/chunk-OQE5J4C6.js +73 -0
  75. package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
  76. package/dist/chunk-POHLU5DW.js +1186 -0
  77. package/dist/chunk-QKMUKYO7.js +4961 -0
  78. package/dist/{chunk-ASND7OZK.js → chunk-QTYWRVRA.js} +13 -13
  79. package/dist/{chunk-EYOKLTMF.js → chunk-SRF2PJNW.js} +17 -3
  80. package/dist/chunk-SST6Z5JA.js +80 -0
  81. package/dist/chunk-STBPMHSX.js +2456 -0
  82. package/dist/chunk-T6YILFSB.js +80 -0
  83. package/dist/chunk-TZTZS7QK.js +227 -0
  84. package/dist/chunk-UOV2BYIW.js +107 -0
  85. package/dist/{chunk-Q3RUPKEJ.js → chunk-V4RXGQ5Q.js} +58 -189
  86. package/dist/chunk-VAKQQHWR.js +434 -0
  87. package/dist/chunk-VG7TBQIY.js +128 -0
  88. package/dist/chunk-VJWL6YS5.js +244 -0
  89. package/dist/chunk-WEH5XRJQ.js +32 -0
  90. package/dist/chunk-WMSVI4G2.js +2095 -0
  91. package/dist/chunk-WVO7V2QY.js +797 -0
  92. package/dist/chunk-X4RCMKVQ.js +641 -0
  93. package/dist/chunk-X75S7HFS.js +374 -0
  94. package/dist/chunk-XN3L4EYL.js +46 -0
  95. package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
  96. package/dist/chunk-YHZX5GEU.js +193 -0
  97. package/dist/chunk-YXLYO42X.js +91 -0
  98. package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
  99. package/dist/chunk-ZI647VB5.js +37 -0
  100. package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
  101. package/dist/cli/index.js +62 -54
  102. package/dist/clio-4LY5K2AC.js +25 -0
  103. package/dist/code-nav-7AX6FYE6.js +600 -0
  104. package/dist/codewiki/build-worker.js +66 -0
  105. package/dist/compile-cache-CVJMMODC.js +18 -0
  106. package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
  107. package/dist/{config-IRUQ7SE4.js → config-GTLUW2PR.js} +92 -55
  108. package/dist/configure-R6A64DHX.js +42 -0
  109. package/dist/context-5VKGUVJJ.js +866 -0
  110. package/dist/{context-3KWFLHJG.js → context-JFZEJ7W5.js} +15 -13
  111. package/dist/{context-5RADCKTR.js → context-RW5HC47S.js} +71 -35
  112. package/dist/{context-clear-7TSNPAAI.js → context-clear-6ZHBAZZT.js} +54 -28
  113. package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
  114. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  115. package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
  116. package/dist/{doctor-UC5NAJYQ.js → doctor-KI767GSN.js} +27 -17
  117. package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
  118. package/dist/{evidence-YEGUW4L3.js → evidence-UA6AWDQQ.js} +46 -26
  119. package/dist/{evolve-TXARCTPG.js → evolve-QNTFGV6Z.js} +45 -25
  120. package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
  121. package/dist/{fleet-6G3DHNYE.js → fleet-Q7UOMUSG.js} +163 -54
  122. package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
  123. package/dist/{init-KZ5QTF6M.js → init-WBB65ZHQ.js} +69 -32
  124. package/dist/{memory-73ESV5YC.js → memory-MD3O64RI.js} +48 -27
  125. package/dist/{models-A4PVNWJK.js → models-BZU34YWD.js} +39 -25
  126. package/dist/monitor-MEQA5C3I.js +661 -0
  127. package/dist/{chunk-FCIH3BIZ.js → orchestrator-CGFKEP27.js} +11832 -8687
  128. package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
  129. package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
  130. package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
  131. package/dist/{run-YTPEYQOH.js → run-IV4Q6RLN.js} +101 -61
  132. package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
  133. package/dist/{skills-2V6RA3OQ.js → skills-LQEKRDTN.js} +34 -14
  134. package/dist/{skills-eval-S2TVJO4F.js → skills-eval-3DC4HEWS.js} +70 -34
  135. package/dist/steer-GGWFUJUD.js +77 -0
  136. package/dist/{targets-TYXLPB23.js → targets-C4SSGQOB.js} +43 -27
  137. package/dist/terminal-lease-IT5JW2NR.js +395 -0
  138. package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
  139. package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
  140. package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
  141. package/dist/{upgrade-33G2LMM5.js → upgrade-7TT7SQ3G.js} +45 -25
  142. package/dist/{usage-ZAFSXKKG.js → usage-GV4PKT3M.js} +62 -31
  143. package/dist/verify-G6V4D2G7.js +716 -0
  144. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  145. package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-DQF6Z66B.js} +74 -34
  146. package/dist/worker/entry.js +221 -36
  147. package/dist/workspace-G4ZWUIPR.js +22 -0
  148. package/docs/README.md +22 -17
  149. package/docs/acp.md +168 -16
  150. package/docs/alcf-provider.md +1 -1
  151. package/docs/architecture.md +136 -7
  152. package/docs/artifact-versions.md +1 -1
  153. package/docs/built-in-agents.md +1 -1
  154. package/docs/capacity-and-scheduling.md +1 -1
  155. package/docs/commands-and-modes.md +114 -71
  156. package/docs/config-knobs-audit.md +1 -3
  157. package/docs/configuration-and-targets.md +174 -46
  158. package/docs/context-engine.md +29 -6
  159. package/docs/development-pipeline.md +26 -1
  160. package/docs/dispatch-architecture-rationale.md +1 -1
  161. package/docs/documentation-coverage.md +2 -2
  162. package/docs/documentation-guide.md +1 -1
  163. package/docs/environment-variables.md +13 -5
  164. package/docs/eval-runner.md +1 -1
  165. package/docs/evals-internal.md +1 -1
  166. package/docs/evidence-and-memory.md +6 -2
  167. package/docs/evolution.md +2 -2
  168. package/docs/exit-codes-and-output.md +15 -9
  169. package/docs/extensions-and-sharing.md +9 -9
  170. package/docs/fleet-dispatch.md +7 -5
  171. package/docs/git-commit-provenance.md +120 -0
  172. package/docs/glossary.md +1 -1
  173. package/docs/installation-and-lifecycle.md +34 -27
  174. package/docs/middleware-and-components.md +1 -1
  175. package/docs/model-catalog.md +45 -14
  176. package/docs/observability.md +8 -5
  177. package/docs/performance-methodology.md +491 -0
  178. package/docs/pi-boundary.md +72 -0
  179. package/docs/proactive-memory.md +3 -3
  180. package/docs/prompt-envelope-and-tools.md +24 -3
  181. package/docs/provider-adapter-cookbook.md +57 -4
  182. package/docs/release-cut-checklist.md +129 -115
  183. package/docs/safety-model.md +9 -5
  184. package/docs/scientific-validation.md +3 -3
  185. package/docs/session-lifecycle.md +55 -12
  186. package/docs/skills-marketplace.md +12 -8
  187. package/docs/time-conventions.md +1 -1
  188. package/docs/tool-usage.md +3 -3
  189. package/docs/trace-store.md +1 -1
  190. package/docs/troubleshooting.md +10 -7
  191. package/docs/tui-design.md +47 -10
  192. package/docs/worker-dispatch-mechanics.md +1 -1
  193. package/package.json +19 -22
  194. package/skills/coding/ast-grep/SKILL.md +136 -0
  195. package/skills/coding/ast-grep/evals.md +56 -0
  196. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  197. package/skills/coding/coding-standards/SKILL.md +113 -0
  198. package/skills/coding/coding-standards/evals.md +34 -0
  199. package/skills/coding/prototype/SKILL.md +86 -0
  200. package/skills/coding/prototype/evals.md +42 -0
  201. package/skills/coding/prototype/references/LOGIC.md +67 -0
  202. package/skills/coding/prototype/references/UI.md +112 -0
  203. package/skills/coding/tdd/SKILL.md +101 -0
  204. package/skills/coding/tdd/evals.md +41 -0
  205. package/skills/coding/tdd/references/mocking.md +59 -0
  206. package/skills/coding/tdd/references/tests.md +77 -0
  207. package/skills/context/context-handoff/SKILL.md +126 -0
  208. package/skills/context/context-handoff/evals.md +57 -0
  209. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  210. package/skills/context/context-prime/SKILL.md +95 -0
  211. package/skills/context/context-prime/evals.md +54 -0
  212. package/skills/meta/clio-dev/SKILL.md +91 -0
  213. package/skills/meta/clio-dev/evals.md +45 -0
  214. package/skills/meta/clio-test/SKILL.md +130 -0
  215. package/skills/meta/clio-test/evals.md +43 -0
  216. package/skills/meta/clio-test/references/harness.md +97 -0
  217. package/skills/meta/clio-test/references/test-map.md +59 -0
  218. package/skills/meta/credentials/SKILL.md +125 -0
  219. package/skills/meta/credentials/evals.md +104 -0
  220. package/skills/meta/find-skills/SKILL.md +72 -0
  221. package/skills/meta/find-skills/evals.md +47 -0
  222. package/skills/meta/herdr/SKILL.md +127 -0
  223. package/skills/meta/herdr/evals.md +38 -0
  224. package/skills/meta/skill-craft/SKILL.md +102 -0
  225. package/skills/meta/skill-craft/evals.md +41 -0
  226. package/skills/planning/architecture/SKILL.md +129 -0
  227. package/skills/planning/architecture/evals.md +36 -0
  228. package/skills/planning/backlog/SKILL.md +90 -0
  229. package/skills/planning/backlog/evals.md +43 -0
  230. package/skills/planning/prd/SKILL.md +82 -0
  231. package/skills/planning/prd/evals.md +49 -0
  232. package/skills/planning/product-intent/SKILL.md +112 -0
  233. package/skills/planning/product-intent/evals.md +36 -0
  234. package/skills/planning/tech-spec/SKILL.md +115 -0
  235. package/skills/planning/tech-spec/evals.md +47 -0
  236. package/skills/registry.yaml +136 -0
  237. package/skills/research/arxiv-literature/SKILL.md +104 -0
  238. package/skills/research/arxiv-literature/evals.md +58 -0
  239. package/skills/research/experiment-protocol/SKILL.md +122 -0
  240. package/skills/research/experiment-protocol/evals.md +91 -0
  241. package/skills/research/scientific-debugging/SKILL.md +119 -0
  242. package/skills/research/scientific-debugging/evals.md +138 -0
  243. package/skills/research/scientific-modernization/SKILL.md +138 -0
  244. package/skills/research/scientific-modernization/evals.md +84 -0
  245. package/skills/workflow/design-council/SKILL.md +139 -0
  246. package/skills/workflow/design-council/evals.md +97 -0
  247. package/skills/workflow/grill-me/SKILL.md +186 -0
  248. package/skills/workflow/grill-me/evals.md +78 -0
  249. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  250. package/skills/workflow/workflow-distiller/evals.md +107 -0
  251. package/src/cli/acp.ts +31 -4
  252. package/src/cli/clio.ts +68 -6
  253. package/src/cli/config-inspect.ts +28 -22
  254. package/src/cli/configure.ts +47 -9
  255. package/src/cli/context-clear.ts +2 -2
  256. package/src/cli/context-index.ts +21 -23
  257. package/src/cli/context.ts +13 -8
  258. package/src/cli/default-target.ts +9 -17
  259. package/src/cli/docs.ts +11 -5
  260. package/src/cli/evidence.ts +4 -1
  261. package/src/cli/extensions.ts +10 -1
  262. package/src/cli/fleet.ts +47 -6
  263. package/src/cli/index.ts +55 -26
  264. package/src/cli/memory.ts +3 -1
  265. package/src/cli/models.ts +1 -1
  266. package/src/cli/modes/json-stream.ts +37 -1
  267. package/src/cli/modes/print.ts +24 -9
  268. package/src/cli/run.ts +2 -2
  269. package/src/cli/skills-eval.ts +23 -8
  270. package/src/cli/skills.ts +19 -4
  271. package/src/cli/targets.ts +4 -0
  272. package/src/cli/text-layout.ts +15 -5
  273. package/src/cli/trace.ts +62 -14
  274. package/src/cli/upgrade.ts +18 -2
  275. package/src/cli/usage.ts +10 -3
  276. package/src/cli/wiki-generate.ts +2 -1
  277. package/src/core/agent-environment.ts +7 -0
  278. package/src/core/bash-exec.ts +72 -1
  279. package/src/core/boot-trace.ts +9 -4
  280. package/src/core/bus-events.ts +20 -4
  281. package/src/core/commit-attribution.ts +157 -0
  282. package/src/core/compile-cache.ts +159 -0
  283. package/src/core/config.ts +131 -2
  284. package/src/core/defaults.ts +39 -5
  285. package/src/core/domain-loader.ts +12 -5
  286. package/src/core/git-commit-attribution.ts +362 -0
  287. package/src/core/incomplete-installation.ts +45 -0
  288. package/src/core/response-schema.ts +1 -1
  289. package/src/core/safe-exec.ts +13 -1
  290. package/src/core/settings-layers.ts +155 -21
  291. package/src/core/skill-activation.ts +1 -1
  292. package/src/core/startup-timer.ts +3 -3
  293. package/src/core/state-file-lock.ts +13 -1
  294. package/src/core/termination.ts +78 -5
  295. package/src/domains/config/classify.ts +15 -3
  296. package/src/domains/config/extension.ts +19 -13
  297. package/src/domains/config/index.ts +10 -0
  298. package/src/domains/config/keybindings.ts +42 -6
  299. package/src/domains/context/bootstrap-prompt.ts +1 -1
  300. package/src/domains/context/bootstrap.ts +111 -18
  301. package/src/domains/context/clear.ts +16 -11
  302. package/src/domains/context/clio-md.ts +111 -9
  303. package/src/domains/context/codewiki/artifact.ts +400 -0
  304. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  305. package/src/domains/context/codewiki/build-worker.ts +54 -0
  306. package/src/domains/context/codewiki/coordinator.ts +182 -0
  307. package/src/domains/context/codewiki/indexer.ts +59 -144
  308. package/src/domains/context/codewiki/paths.ts +67 -0
  309. package/src/domains/context/codewiki/schema.ts +80 -0
  310. package/src/domains/context/codewiki/tree-sitter.ts +1 -1
  311. package/src/domains/context/contract.ts +11 -5
  312. package/src/domains/context/extension.ts +94 -143
  313. package/src/domains/context/fingerprint.ts +3 -1
  314. package/src/domains/context/index.ts +12 -22
  315. package/src/domains/context/project-metadata.ts +19 -0
  316. package/src/domains/context/prompt-context.ts +9 -10
  317. package/src/domains/context/refresh.ts +29 -21
  318. package/src/domains/context/runtime.ts +17 -0
  319. package/src/domains/context/wiki/generate.ts +39 -34
  320. package/src/domains/context/wiki/plan.ts +1 -1
  321. package/src/domains/context/wiki/prompts.ts +21 -8
  322. package/src/domains/dispatch/code-step.ts +20 -1
  323. package/src/domains/dispatch/extension.ts +158 -21
  324. package/src/domains/dispatch/failure-classification.ts +6 -0
  325. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  326. package/src/domains/dispatch/orphan-recovery.ts +50 -8
  327. package/src/domains/dispatch/receipt-integrity.ts +5 -0
  328. package/src/domains/dispatch/state.ts +31 -6
  329. package/src/domains/dispatch/transport.ts +2 -1
  330. package/src/domains/dispatch/types.ts +14 -0
  331. package/src/domains/dispatch/worker-spawn.ts +21 -2
  332. package/src/domains/eval/metrics/context.ts +1 -1
  333. package/src/domains/eval/types.ts +0 -1
  334. package/src/domains/evidence/build.ts +41 -1
  335. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  336. package/src/domains/lifecycle/migrations/index.ts +24 -4
  337. package/src/domains/middleware/hooks-io.ts +12 -0
  338. package/src/domains/middleware/skills-reminder.ts +30 -15
  339. package/src/domains/prompts/compiler.ts +142 -84
  340. package/src/domains/prompts/contract.ts +18 -2
  341. package/src/domains/prompts/extension.ts +39 -7
  342. package/src/domains/prompts/fragment-loader.ts +0 -1
  343. package/src/domains/prompts/fragments/identity/clio.md +2 -4
  344. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  345. package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
  346. package/src/domains/prompts/fragments/operating/contract.md +4 -50
  347. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  348. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  349. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  350. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  351. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  352. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  353. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  354. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  355. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  356. package/src/domains/prompts/preload.ts +3 -3
  357. package/src/domains/providers/auth/api-key.ts +1 -1
  358. package/src/domains/providers/auth/backend-file.ts +20 -10
  359. package/src/domains/providers/auth/backend-memory.ts +59 -4
  360. package/src/domains/providers/auth/boot-status.ts +65 -0
  361. package/src/domains/providers/auth/oauth.ts +2 -1
  362. package/src/domains/providers/auth/storage.ts +97 -38
  363. package/src/domains/providers/capabilities.ts +12 -4
  364. package/src/domains/providers/contract.ts +15 -4
  365. package/src/domains/providers/extension.ts +18 -6
  366. package/src/domains/providers/model-runtime-capabilities.ts +15 -4
  367. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
  368. package/src/domains/providers/plugins.ts +5 -3
  369. package/src/domains/providers/probe/fingerprint.ts +25 -5
  370. package/src/domains/providers/registry.ts +31 -10
  371. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  372. package/src/domains/providers/runtimes/builtins.ts +2 -2
  373. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  374. package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
  375. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  376. package/src/domains/providers/support.ts +6 -3
  377. package/src/domains/providers/types/local-model-quirks.ts +7 -9
  378. package/src/domains/providers/types/runtime-descriptor.ts +12 -1
  379. package/src/domains/providers/types/target-descriptor.ts +22 -0
  380. package/src/domains/resources/contract.ts +0 -1
  381. package/src/domains/resources/extension.ts +1 -3
  382. package/src/domains/resources/loader.ts +3 -4
  383. package/src/domains/resources/prompts/loader.ts +16 -2
  384. package/src/domains/resources/prompts/substitute.ts +1 -65
  385. package/src/domains/resources/skills/content-hash.ts +2 -0
  386. package/src/domains/resources/skills/install.ts +17 -0
  387. package/src/domains/resources/skills/loader.ts +17 -10
  388. package/src/domains/resources/skills/marketplace.ts +55 -9
  389. package/src/domains/safety/action-classifier.ts +4 -2
  390. package/src/domains/safety/audit.ts +8 -2
  391. package/src/domains/safety/extension.ts +1 -1
  392. package/src/domains/session/compaction/branch-summary.ts +3 -2
  393. package/src/domains/session/compaction/cut-point.ts +2 -1
  394. package/src/domains/session/compaction/tokens.ts +2 -1
  395. package/src/domains/session/context-ledger.ts +14 -0
  396. package/src/domains/session/contract.ts +15 -0
  397. package/src/domains/session/decision-board.ts +190 -0
  398. package/src/domains/session/entries.ts +66 -3
  399. package/src/domains/session/extension.ts +93 -12
  400. package/src/domains/session/retry.ts +10 -18
  401. package/src/domains/session/session-artifacts.ts +107 -0
  402. package/src/domains/session/task-board.ts +207 -13
  403. package/src/domains/session/tree/active-path.ts +44 -5
  404. package/src/domains/session/tree/fork.ts +26 -27
  405. package/src/domains/session/tree/preview.ts +2 -2
  406. package/src/domains/session/workspace/git-probe.ts +17 -11
  407. package/src/domains/user-tasks/store.ts +297 -0
  408. package/src/engine/acp/errors.ts +96 -0
  409. package/src/engine/acp/server.ts +1728 -146
  410. package/src/engine/acp/transport.ts +135 -14
  411. package/src/engine/acp/types.ts +26 -0
  412. package/src/engine/agent.ts +3 -3
  413. package/src/engine/ai.ts +32 -27
  414. package/src/engine/alcf-oauth.ts +26 -19
  415. package/src/engine/api-registry.ts +223 -0
  416. package/src/engine/apis/index.ts +3 -7
  417. package/src/engine/apis/llamacpp-residency.ts +49 -9
  418. package/src/engine/apis/lmstudio-residency.ts +5 -21
  419. package/src/engine/apis/lmstudio.ts +243 -0
  420. package/src/engine/apis/ollama-native.ts +24 -3
  421. package/src/engine/apis/openai-completions.ts +170 -91
  422. package/src/engine/apis/residency.ts +139 -3
  423. package/src/engine/apis/types.ts +16 -0
  424. package/src/engine/env-api-keys.ts +98 -0
  425. package/src/engine/gemma-channel-filter.ts +223 -0
  426. package/src/engine/instrumented-tui.ts +192 -0
  427. package/src/engine/messages.ts +14 -0
  428. package/src/engine/models.ts +42 -0
  429. package/src/engine/oauth.ts +16 -12
  430. package/src/engine/prompt-templates.ts +1 -0
  431. package/src/engine/provider-payload.ts +16 -59
  432. package/src/engine/strip-tokenizer-sentinels.ts +1 -1
  433. package/src/engine/truncate.ts +9 -0
  434. package/src/engine/tui.ts +17 -9
  435. package/src/engine/types.ts +3 -6
  436. package/src/engine/worker-runtime-capabilities.ts +5 -0
  437. package/src/engine/worker-runtime.ts +1 -1
  438. package/src/engine/worker-tools.ts +9 -4
  439. package/src/entry/boot-options.ts +50 -0
  440. package/src/entry/orchestrator.ts +288 -150
  441. package/src/interactive/application-controller.ts +89 -2
  442. package/src/interactive/chat-loop.ts +266 -41
  443. package/src/interactive/chat-panel.ts +173 -47
  444. package/src/interactive/chat-renderer.ts +262 -72
  445. package/src/interactive/clio-editor.ts +3 -8
  446. package/src/interactive/command-fallbacks.ts +2 -2
  447. package/src/interactive/context-overlay.ts +27 -1
  448. package/src/interactive/editor-submit.ts +228 -24
  449. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  450. package/src/interactive/export-html/index.ts +51 -0
  451. package/src/interactive/export-html/template.ts +45 -0
  452. package/src/interactive/export-html/tool-renderer.ts +54 -0
  453. package/src/interactive/footer/dashboard.ts +4 -0
  454. package/src/interactive/footer/notifications.ts +1 -1
  455. package/src/interactive/footer/widgets.ts +20 -2
  456. package/src/interactive/footer-panel.ts +2 -2
  457. package/src/interactive/format-time.ts +14 -2
  458. package/src/interactive/interactive-application.ts +201 -17
  459. package/src/interactive/interactive-event-projection.ts +6 -1
  460. package/src/interactive/interactive-input-runtime.ts +50 -4
  461. package/src/interactive/interactive-presentation.ts +151 -19
  462. package/src/interactive/interactive-shell.ts +268 -14
  463. package/src/interactive/interactive-slash-runtime.ts +176 -114
  464. package/src/interactive/interactive-tickers.ts +38 -7
  465. package/src/interactive/keybinding-manager.ts +1 -1
  466. package/src/interactive/layout.ts +40 -3
  467. package/src/interactive/overlay-frame.ts +1 -1
  468. package/src/interactive/overlay-general-openers.ts +58 -1
  469. package/src/interactive/overlay-key-routing.ts +3 -0
  470. package/src/interactive/overlay-lifecycle.ts +13 -0
  471. package/src/interactive/overlay-permission-lifecycle.ts +2 -1
  472. package/src/interactive/overlay-session-lifecycle.ts +69 -12
  473. package/src/interactive/overlays/decisions.ts +300 -0
  474. package/src/interactive/overlays/help-reference.ts +15 -10
  475. package/src/interactive/overlays/model-selector.ts +34 -16
  476. package/src/interactive/overlays/session-selector.ts +18 -0
  477. package/src/interactive/overlays/settings.ts +105 -17
  478. package/src/interactive/overlays/skills-hub.ts +4 -4
  479. package/src/interactive/overlays/tree-selector.ts +41 -6
  480. package/src/interactive/render-trace.ts +499 -90
  481. package/src/interactive/renderers/compaction-summary.ts +2 -2
  482. package/src/interactive/renderers/diff.ts +115 -104
  483. package/src/interactive/renderers/mermaid.ts +53 -0
  484. package/src/interactive/renderers/tool-execution.ts +386 -133
  485. package/src/interactive/renderers/worker-entry.ts +20 -4
  486. package/src/interactive/session-switch-settlement.ts +10 -0
  487. package/src/interactive/slash-autocomplete.ts +6 -114
  488. package/src/interactive/slash-commands.ts +135 -47
  489. package/src/interactive/slash-spec.ts +9 -38
  490. package/src/interactive/status/controller.ts +5 -1
  491. package/src/interactive/stdout-backpressure.ts +99 -0
  492. package/src/interactive/stream-pacer.ts +530 -0
  493. package/src/interactive/stream-pacing-policy.ts +66 -0
  494. package/src/interactive/tasks-overlay.ts +368 -14
  495. package/src/interactive/terminal-lease.ts +485 -0
  496. package/src/interactive/theme/tokens.ts +1 -1
  497. package/src/interactive/turn-context.ts +4 -3
  498. package/src/interactive/turn-persistence.ts +30 -13
  499. package/src/interactive/turn-queues.ts +12 -0
  500. package/src/interactive/turn-recovery.ts +25 -8
  501. package/src/interactive/turn-runtime.ts +79 -12
  502. package/src/interactive/turn-state.ts +10 -0
  503. package/src/interactive/view/artifacts.ts +114 -4
  504. package/src/interactive/view/view-overlay.ts +3 -0
  505. package/src/interactive/welcome-dashboard.ts +17 -16
  506. package/src/interactive/worker-receipts.ts +52 -3
  507. package/src/interactive/worker-stream.ts +5 -1
  508. package/src/tools/agent-tools.ts +23 -3
  509. package/src/tools/artifact.ts +2 -2
  510. package/src/tools/ask-user.ts +23 -13
  511. package/src/tools/bash.ts +30 -2
  512. package/src/tools/bootstrap.ts +34 -431
  513. package/src/tools/builtin-tool-catalog.ts +265 -0
  514. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  515. package/src/tools/codewiki/code-nav.ts +8 -22
  516. package/src/tools/codewiki/shared.ts +41 -38
  517. package/src/tools/context/docs-engine.ts +14 -3
  518. package/src/tools/context/index.ts +107 -28
  519. package/src/tools/context/surface.ts +19 -0
  520. package/src/tools/core-bootstrap.ts +168 -0
  521. package/src/tools/credential-present.ts +5 -5
  522. package/src/tools/dispatch-admission.ts +533 -0
  523. package/src/tools/dispatch-background.ts +54 -0
  524. package/src/tools/dispatch-event-text.ts +6 -0
  525. package/src/tools/dispatch-plan.ts +9 -4
  526. package/src/tools/dispatch-run-events.ts +238 -0
  527. package/src/tools/dispatch-runner.ts +2370 -0
  528. package/src/tools/dispatch-scout-admission.ts +295 -0
  529. package/src/tools/dispatch-types.ts +77 -0
  530. package/src/tools/dispatch.ts +67 -3161
  531. package/src/tools/find.ts +4 -2
  532. package/src/tools/grep.ts +2 -2
  533. package/src/tools/lazy-tool.ts +60 -0
  534. package/src/tools/ledger.ts +3 -3
  535. package/src/tools/monitor-surface.ts +36 -0
  536. package/src/tools/monitor.ts +2 -32
  537. package/src/tools/observers.ts +2 -2
  538. package/src/tools/registry.ts +39 -27
  539. package/src/tools/safe-exec.ts +2 -2
  540. package/src/tools/steer-surface.ts +17 -0
  541. package/src/tools/steer.ts +2 -13
  542. package/src/tools/tasks.ts +108 -11
  543. package/src/tools/truncate.ts +25 -184
  544. package/src/tools/verify/frontend.ts +3 -1
  545. package/src/tools/verify/index.ts +3 -38
  546. package/src/tools/verify/surface.ts +46 -0
  547. package/src/tools/web-fetch-surface.ts +23 -0
  548. package/src/tools/web-fetch.ts +2 -20
  549. package/src/tools/write.ts +7 -2
  550. package/src/worker/entry.ts +39 -2
  551. package/src/worker/spec-contract.ts +26 -5
  552. package/dist/chunk-7SS2CTV2.js +0 -61361
  553. package/dist/chunk-DKGKUHFA.js +0 -924
  554. package/dist/chunk-GEP36Y4X.js +0 -12796
  555. package/dist/chunk-XYWBQRDM.js +0 -137
  556. package/dist/clio-BZVGEUFJ.js +0 -58
  557. package/dist/configure-S7S6F6CL.js +0 -32
  558. package/docs/html/agents_blueprint.html +0 -936
  559. package/docs/html/alcf_blueprint.html +0 -324
  560. package/docs/html/architecture_blueprint.html +0 -850
  561. package/docs/html/commands_blueprint.html +0 -939
  562. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  563. package/docs/html/configuration_blueprint.html +0 -1080
  564. package/docs/html/context_blueprint.html +0 -603
  565. package/docs/html/documentation_blueprint.html +0 -832
  566. package/docs/html/environment_blueprint.html +0 -404
  567. package/docs/html/eval_blueprint.html +0 -743
  568. package/docs/html/evals_internal_blueprint.html +0 -190
  569. package/docs/html/evolution_blueprint.html +0 -674
  570. package/docs/html/extensions_blueprint.html +0 -2065
  571. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  572. package/docs/html/index.html +0 -919
  573. package/docs/html/lifecycle_blueprint.html +0 -723
  574. package/docs/html/memory_blueprint.html +0 -699
  575. package/docs/html/middleware_blueprint.html +0 -664
  576. package/docs/html/models_blueprint.html +0 -2366
  577. package/docs/html/observability_blueprint.html +0 -683
  578. package/docs/html/provider_adapter_blueprint.html +0 -245
  579. package/docs/html/safety_blueprint.html +0 -1386
  580. package/docs/html/shared.css +0 -571
  581. package/docs/html/shared.js +0 -143
  582. package/docs/html/skills_blueprint.html +0 -671
  583. package/docs/html/soak_blueprint.html +0 -182
  584. package/docs/html/tool_usage_blueprint.html +0 -350
  585. package/docs/html/tools_blueprint.html +0 -2249
  586. package/docs/html/trace_blueprint.html +0 -235
  587. package/docs/html/tui_design_blueprint.html +0 -374
  588. package/docs/html/validation_blueprint.html +0 -961
  589. package/docs/html/worker_dispatch_blueprint.html +0 -231
  590. package/src/core/release.ts +0 -2
  591. package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
  592. package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
  593. package/src/engine/apis/lmstudio-native.ts +0 -1438
  594. package/src/engine/apis/thinking-replay.ts +0 -11
  595. package/src/tools/string-enum.ts +0 -15
@@ -0,0 +1,241 @@
1
+ import { CLIO_MIN_CONTEXT_WINDOW, CLIO_MIN_MAX_OUTPUT_TOKENS } from "../../../../core/context-floor.js";
2
+ import type { Api, Model } from "../../../../engine/types.js";
3
+ import type { CapabilityFlags, ThinkingLevel } from "../../types/capability-flags.js";
4
+ import type { KnowledgeBaseHit } from "../../types/knowledge-base.js";
5
+ import type { ProbeContext, ProbeModelStatus, ProbeResult, RuntimeDescriptor } from "../../types/runtime-descriptor.js";
6
+ import type { TargetDescriptor } from "../../types/target-descriptor.js";
7
+ import {
8
+ foldLmStudioModels,
9
+ greetLmStudio,
10
+ type LmStudioCatalog,
11
+ type LmStudioLoadedInstance,
12
+ type LmStudioModelInfo,
13
+ listLmStudioModels,
14
+ lmStudioReasoningLevels,
15
+ loadedContextLength,
16
+ parseLmStudioV1Models,
17
+ resolveLmStudioInstance,
18
+ } from "../common/lmstudio-http.js";
19
+ import { synthLocalModel, withV1 } from "../common/local-synth.js";
20
+
21
+ const defaultCapabilities: CapabilityFlags = {
22
+ chat: true,
23
+ tools: true,
24
+ toolCallFormat: "openai",
25
+ structuredOutputs: "json-schema",
26
+ reasoning: true,
27
+ vision: true,
28
+ audio: false,
29
+ embeddings: false,
30
+ rerank: false,
31
+ fim: false,
32
+ contextWindow: CLIO_MIN_CONTEXT_WINDOW,
33
+ maxTokens: CLIO_MIN_MAX_OUTPUT_TOKENS,
34
+ };
35
+
36
+ const reasoningOptionsByTargetModel = new Map<string, ReadonlyArray<string>>();
37
+
38
+ function reasoningOptionsKey(target: TargetDescriptor, modelId: string): string {
39
+ const url = (target.url ?? "").replace(/^ws:/u, "http:").replace(/^wss:/u, "https:").replace(/\/$/u, "");
40
+ return `${target.id}|${url}|${modelId}`;
41
+ }
42
+
43
+ function rememberReasoningOptions(target: TargetDescriptor, models: ReadonlyArray<LmStudioModelInfo>): void {
44
+ const prefix = reasoningOptionsKey(target, "");
45
+ for (const key of reasoningOptionsByTargetModel.keys()) {
46
+ if (key.startsWith(prefix)) reasoningOptionsByTargetModel.delete(key);
47
+ }
48
+ for (const model of models) {
49
+ if (!model.reasoningOptions) continue;
50
+ reasoningOptionsByTargetModel.set(reasoningOptionsKey(target, model.key), model.reasoningOptions);
51
+ for (const instance of model.loadedInstances) {
52
+ reasoningOptionsByTargetModel.set(reasoningOptionsKey(target, instance.id), model.reasoningOptions);
53
+ }
54
+ }
55
+ }
56
+
57
+ function configuredModel(target: TargetDescriptor): string | undefined {
58
+ const id = target.defaultModel?.trim();
59
+ return id && id.length > 0 ? id : undefined;
60
+ }
61
+
62
+ function resolveModel(
63
+ models: ReadonlyArray<LmStudioModelInfo>,
64
+ id: string | undefined,
65
+ ): { model: LmStudioModelInfo; instance?: LmStudioLoadedInstance } | null {
66
+ if (id) {
67
+ for (const model of models) {
68
+ if (model.key === id) return { model, ...(model.loadedInstances[0] ? { instance: model.loadedInstances[0] } : {}) };
69
+ const instance = model.loadedInstances.find((entry) => entry.id === id);
70
+ if (instance) return { model, instance };
71
+ }
72
+ return null;
73
+ }
74
+ const model = models.find((entry) => entry.loadedInstances.length > 0) ?? models[0];
75
+ return model ? { model, ...(model.loadedInstances[0] ? { instance: model.loadedInstances[0] } : {}) } : null;
76
+ }
77
+
78
+ function capabilities(model: LmStudioModelInfo, instance?: LmStudioLoadedInstance): Partial<CapabilityFlags> {
79
+ const out: Partial<CapabilityFlags> = {};
80
+ if (model.vision !== undefined) out.vision = model.vision;
81
+ if (model.tools !== undefined) out.tools = model.tools;
82
+ if (model.reasoning !== undefined) out.reasoning = model.reasoning;
83
+ else if (model.reasoningOptions !== undefined)
84
+ out.reasoning = model.reasoningOptions.some((option) => option !== "off");
85
+ const contextWindow = loadedContextLength(instance) ?? model.maxContextLength;
86
+ if (contextWindow !== undefined) out.contextWindow = contextWindow;
87
+ return out;
88
+ }
89
+
90
+ function statusFor(
91
+ model: LmStudioModelInfo,
92
+ instance: LmStudioLoadedInstance | undefined,
93
+ reasoningLevels: ReadonlyArray<ThinkingLevel>,
94
+ ): ProbeModelStatus {
95
+ const status: ProbeModelStatus = {
96
+ state: instance ? "loaded" : "unloaded",
97
+ key: model.key,
98
+ reasoningLevels,
99
+ };
100
+ if (instance) {
101
+ status.instanceId = instance.id;
102
+ status.loadConfig = instance.config;
103
+ const contextLength = loadedContextLength(instance);
104
+ if (contextLength !== undefined) status.contextLength = contextLength;
105
+ }
106
+ return status;
107
+ }
108
+
109
+ function probeFromCatalog(catalog: LmStudioCatalog, target: TargetDescriptor): ProbeResult {
110
+ if (!catalog.ok) {
111
+ return {
112
+ ok: false,
113
+ ...(catalog.latencyMs !== undefined ? { latencyMs: catalog.latencyMs } : {}),
114
+ error: catalog.error ?? "LM Studio model listing failed",
115
+ };
116
+ }
117
+ const models = foldLmStudioModels(catalog.models);
118
+ rememberReasoningOptions(target, models);
119
+ const ids: string[] = [];
120
+ const modelCapabilities: Record<string, Partial<CapabilityFlags>> = {};
121
+ const modelStates: Record<string, ProbeModelStatus> = {};
122
+ for (const model of models) {
123
+ const levels = lmStudioReasoningLevels(model.reasoningOptions);
124
+ const keyInstance = model.loadedInstances[0];
125
+ modelCapabilities[model.key] = capabilities(model, keyInstance);
126
+ modelStates[model.key] = statusFor(model, keyInstance, levels);
127
+ for (const instance of model.loadedInstances) {
128
+ if (!ids.includes(instance.id)) ids.push(instance.id);
129
+ modelCapabilities[instance.id] = capabilities(model, instance);
130
+ const instanceStatus = statusFor(model, instance, levels);
131
+ modelStates[instance.id] = instanceStatus;
132
+ const resolution = resolveLmStudioInstance(target, models, instance.id, configuredModel(target));
133
+ instanceStatus.detail =
134
+ resolution.peerTargets.length > 0
135
+ ? `loaded on ${target.id}; also loaded on ${resolution.peerTargets.join(", ")}`
136
+ : `loaded on ${target.id}`;
137
+ }
138
+ if (model.loadedInstances.length === 0) {
139
+ ids.push(model.key);
140
+ const keyStatus = modelStates[model.key];
141
+ if (keyStatus) keyStatus.detail = "not loaded (LM Studio will load it on first use)";
142
+ }
143
+ }
144
+ const selected = resolveModel(models, configuredModel(target));
145
+ const result: ProbeResult = {
146
+ ok: true,
147
+ models: ids,
148
+ modelCapabilities,
149
+ modelStates,
150
+ serverVersion:
151
+ catalog.tier === "0.4+"
152
+ ? "LM Studio API 0.4+"
153
+ : catalog.tier === "0.3.x"
154
+ ? "LM Studio API 0.3.x"
155
+ : "LM Studio OpenAI-compatible API",
156
+ surfaces: {
157
+ openaiChat: "/v1/chat/completions",
158
+ ...(catalog.tier === "0.4+" ? { nativeV1: "/api/v1/models" } : {}),
159
+ ...(catalog.tier === "0.3.x" ? { nativeV0: "/api/v0/models" } : {}),
160
+ },
161
+ };
162
+ if (catalog.latencyMs !== undefined) result.latencyMs = catalog.latencyMs;
163
+ if (selected) {
164
+ result.discoveredCapabilities = capabilities(selected.model, selected.instance);
165
+ result.capabilityModelId = configuredModel(target) ?? selected.model.key;
166
+ }
167
+ const loaded = models.flatMap((model) =>
168
+ model.loadedInstances.map((instance) => {
169
+ const context = loadedContextLength(instance);
170
+ return `${model.key} as ${instance.id}${context ? ` at ${context} tokens` : ""}`;
171
+ }),
172
+ );
173
+ result.notes = [
174
+ `LM Studio surface tier ${catalog.tier ?? "unknown"}`,
175
+ `Surfaces: ${Object.values(result.surfaces ?? {}).join(", ")}`,
176
+ ...(loaded.length > 0 ? [`Loaded instances: ${loaded.join(", ")}`] : []),
177
+ ];
178
+ return result;
179
+ }
180
+
181
+ export function probeResultFromV1Models(data: unknown, target: TargetDescriptor, latencyMs?: number): ProbeResult {
182
+ const models = parseLmStudioV1Models(data);
183
+ if (!models) return { ok: false, error: "LM Studio /api/v1/models response has no models array" };
184
+ return probeFromCatalog({ ok: true, models, tier: "0.4+", ...(latencyMs !== undefined ? { latencyMs } : {}) }, target);
185
+ }
186
+
187
+ const lmstudioRuntime: RuntimeDescriptor = {
188
+ id: "lmstudio",
189
+ aliases: ["lmstudio-native"],
190
+ displayName: "LM Studio",
191
+ kind: "http",
192
+ tier: "local-native",
193
+ apiFamily: "openai-completions",
194
+ auth: "api-key",
195
+ defaultCapabilities,
196
+ async probe(target, ctx): Promise<ProbeResult> {
197
+ const [greeting, catalog] = await Promise.all([greetLmStudio(target, ctx), listLmStudioModels(target, ctx)]);
198
+ if (!greeting.ok && catalog.tier !== "0.3.x") {
199
+ return {
200
+ ok: false,
201
+ ...(greeting.latencyMs !== undefined ? { latencyMs: greeting.latencyMs } : {}),
202
+ error: `URL did not identify itself as LM Studio: ${greeting.error ?? "greeting missing"}`,
203
+ };
204
+ }
205
+ return probeFromCatalog(catalog, target);
206
+ },
207
+ async probeModels(target: TargetDescriptor, ctx: ProbeContext): Promise<string[]> {
208
+ const catalog = await listLmStudioModels(target, ctx);
209
+ return probeFromCatalog(catalog, target).models ?? [];
210
+ },
211
+ synthesizeModel(target: TargetDescriptor, wireModelId: string, kb: KnowledgeBaseHit | null): Model<Api> {
212
+ const canonicalTarget = target.runtime === "lmstudio" ? target : { ...target, runtime: "lmstudio" };
213
+ const model = synthLocalModel({
214
+ target: canonicalTarget,
215
+ wireModelId,
216
+ kb,
217
+ defaultCapabilities,
218
+ apiFamily: "openai-completions",
219
+ provider: "lmstudio",
220
+ baseUrlForTarget: (url) => withV1(url.replace(/^ws:/u, "http:").replace(/^wss:/u, "https:")),
221
+ });
222
+ const metadata = (
223
+ model as Model<Api> & {
224
+ clio?: {
225
+ chatTemplateKwargsUnsupported?: boolean;
226
+ lmstudioReasoningOptions?: ReadonlyArray<string>;
227
+ lmstudioDefaultModel?: string;
228
+ };
229
+ }
230
+ ).clio;
231
+ if (metadata) {
232
+ metadata.chatTemplateKwargsUnsupported = true;
233
+ if (target.defaultModel) metadata.lmstudioDefaultModel = target.defaultModel;
234
+ const options = reasoningOptionsByTargetModel.get(reasoningOptionsKey(canonicalTarget, wireModelId));
235
+ if (options) metadata.lmstudioReasoningOptions = options;
236
+ }
237
+ return model;
238
+ },
239
+ };
240
+
241
+ export default lmstudioRuntime;
@@ -55,7 +55,7 @@ const SUMMARY_BY_RUNTIME_ID: Readonly<Record<string, string>> = {
55
55
  "openai-codex": "ChatGPT Plus/Pro via Codex OAuth",
56
56
  openrouter: "OpenRouter API",
57
57
  "ollama-native": "Ollama native API",
58
- "lmstudio-native": "LM Studio SDK + native model management",
58
+ lmstudio: "LM Studio chat over OpenAI-compatible REST with native REST model management",
59
59
  llamacpp: "llama.cpp server (auto-detect surface)",
60
60
  "anthropic-compat": "Generic Anthropic-compatible REST",
61
61
  "openai-compat": "Generic OpenAI-compatible REST",
@@ -151,7 +151,7 @@ export function defaultModelForRuntime(runtimeId: string): string | undefined {
151
151
  * about which ids matter.
152
152
  */
153
153
  export function describeRuntimeModels(entry: ProviderSupportEntry, sample: number): string {
154
- if (entry.modelSource === "catalog") return `${entry.modelHints.length} in pi-ai catalog`;
154
+ if (entry.modelSource === "catalog") return `${entry.modelHints.length} in catalog`;
155
155
  if (entry.modelHints.length === 0) return "-";
156
156
  return entry.modelHints.slice(0, sample).join(", ");
157
157
  }
@@ -206,7 +206,10 @@ export function configuredTargetsForRuntime(
206
206
  settings: Readonly<ClioSettings>,
207
207
  runtimeId: string,
208
208
  ): ReadonlyArray<TargetDescriptor> {
209
- return settings.targets.filter((target) => target.runtime === runtimeId);
209
+ const canonical = getRuntimeIfRegistered(runtimeId)?.id ?? runtimeId;
210
+ return settings.targets.filter(
211
+ (target) => (getRuntimeIfRegistered(target.runtime)?.id ?? target.runtime) === canonical,
212
+ );
210
213
  }
211
214
 
212
215
  export function resolveProviderReference(
@@ -6,11 +6,9 @@
6
6
  * into a typed shape that flows through `model.clio.quirks` at synth time.
7
7
  *
8
8
  * Field naming follows the Hugging Face / model-card terminology so the YAML
9
- * can be authored against the source-of-truth card. Engine adapters translate
10
- * these into the SDK-specific names at consumption sites:
11
- * - LM Studio SDK uses `topPSampling`, `topKSampling`, `minPSampling`,
12
- * `repeatPenalty`, `llamaKCacheQuantizationType`.
13
- * - LM Studio's OpenAI-compat surface accepts `top_p`, `top_k`, `min_p`,
9
+ * can be authored against the source-of-truth card. The OpenAI adapter
10
+ * translates these into pi-ai sampling parameters at consumption:
11
+ * - OpenAI-compatible surfaces accept `top_p`, `top_k`, `min_p`,
14
12
  * `repeat_penalty`.
15
13
  */
16
14
 
@@ -81,7 +79,7 @@ function isRecord(value: unknown): value is Record<string, unknown> {
81
79
  return value !== null && typeof value === "object" && !Array.isArray(value);
82
80
  }
83
81
 
84
- export function asKvCacheQuant(value: unknown): KvCacheQuant | false | undefined {
82
+ function asKvCacheQuant(value: unknown): KvCacheQuant | false | undefined {
85
83
  if (value === false) return false;
86
84
  if (typeof value !== "string") return undefined;
87
85
  return (KV_CACHE_QUANTS as ReadonlyArray<string>).includes(value) ? (value as KvCacheQuant) : undefined;
@@ -122,9 +120,9 @@ function extractSamplingProfile(raw: unknown): SamplingProfile | undefined {
122
120
  if (topK !== undefined) out.topK = topK;
123
121
  const minP = asPositive(raw.minP);
124
122
  if (minP !== undefined) out.minP = minP;
125
- // Catalog YAML may use either `repeatPenalty` (LM Studio SDK term) or
126
- // `repetitionPenalty` (HF model-card term); accept both, prefer the SDK
127
- // spelling when both are present.
123
+ // Catalog YAML may use either `repeatPenalty` (engine field name) or
124
+ // `repetitionPenalty` (HF model-card term); accept both, preferring the
125
+ // engine spelling when both are present.
128
126
  const rp = asPenalty(raw.repeatPenalty) ?? asPenalty(raw.repetitionPenalty);
129
127
  if (rp !== undefined) out.repeatPenalty = rp;
130
128
  const pp = asPenalty(raw.presencePenalty);
@@ -17,7 +17,6 @@ export type RuntimeApiFamily =
17
17
  | "bedrock-converse-stream"
18
18
  | "google-generative-ai"
19
19
  | "google-vertex"
20
- | "lmstudio-native"
21
20
  | "mistral-conversations"
22
21
  | "ollama-native"
23
22
  | "rerank-http"
@@ -53,6 +52,8 @@ export interface ProbeSurfaceMap {
53
52
  rerank?: string;
54
53
  completion?: string;
55
54
  infill?: string;
55
+ nativeV1?: string;
56
+ nativeV0?: string;
56
57
  }
57
58
 
58
59
  export type ProbeModelLoadState = "loaded" | "loading" | "unloaded" | "failed" | "unknown";
@@ -76,6 +77,14 @@ export interface ProbeModelStatus {
76
77
  */
77
78
  sizeVramBytes?: number;
78
79
  sizeBytes?: number;
80
+ /** Downloaded model key that owns this configured id or loaded instance. */
81
+ key?: string;
82
+ /** Loaded instance id selected for this model, when one exists. */
83
+ instanceId?: string;
84
+ /** Load configuration echoed by LM Studio for the selected instance. */
85
+ loadConfig?: Readonly<Record<string, unknown>>;
86
+ /** Reasoning levels accepted by this model after LM Studio option clamping. */
87
+ reasoningLevels?: ReadonlyArray<"off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
79
88
  }
80
89
 
81
90
  export interface ProbeResult {
@@ -115,6 +124,8 @@ export interface ReasoningProbeResult {
115
124
 
116
125
  export interface RuntimeDescriptor {
117
126
  id: string;
127
+ /** Deprecated or compatibility ids that resolve to this descriptor object. */
128
+ aliases?: ReadonlyArray<string>;
118
129
  displayName: string;
119
130
  kind: RuntimeKind;
120
131
  tier?: RuntimeTier;
@@ -18,6 +18,27 @@ export interface TargetPricing {
18
18
  // unrenamed by rebrand decision so existing `lifecycle:` lines keep working.
19
19
  export type TargetLifecycle = "user-managed" | "clio-managed";
20
20
 
21
+ export interface LmStudioLoadSettings {
22
+ contextLength?: number;
23
+ flashAttention?: boolean;
24
+ evalBatchSize?: number;
25
+ numExperts?: number;
26
+ offloadKvCacheToGpu?: boolean;
27
+ }
28
+
29
+ export type LmStudioReasoningSetting = "auto" | "off" | "on" | "low" | "medium" | "high";
30
+
31
+ export interface LmStudioRequestSettings {
32
+ ttlSeconds?: number;
33
+ draftModel?: string;
34
+ reasoning?: LmStudioReasoningSetting;
35
+ }
36
+
37
+ export interface LmStudioTargetSettings {
38
+ load?: LmStudioLoadSettings;
39
+ request?: LmStudioRequestSettings;
40
+ }
41
+
21
42
  /**
22
43
  * Persisted target specification from settings.yaml (`targets:`). It binds a
23
44
  * user-facing target id to a RuntimeDescriptor id, target URL/auth metadata,
@@ -35,4 +56,5 @@ export interface TargetDescriptor {
35
56
  lifecycle?: TargetLifecycle;
36
57
  gateway?: boolean;
37
58
  pricing?: TargetPricing;
59
+ lmstudio?: LmStudioTargetSettings;
38
60
  }
@@ -19,7 +19,6 @@ export interface ResourcesContract extends DomainContract {
19
19
  ): { text: string; pendingSkillRequests: PendingSkillRequest[] };
20
20
  prompts(cwd?: string): ResourceList<PromptTemplate>;
21
21
  expandPromptTemplate(text: string, cwd?: string): PromptTemplateExpansion;
22
- themes(): ResourceList<never>;
23
22
  resolvePath(value: string, cwd?: string): string;
24
23
  reload(): Promise<void>;
25
24
  }
@@ -10,6 +10,7 @@ export function createResourcesBundle(
10
10
  const config = (): ConfigContract | undefined => context.getContract<ConfigContract>("config");
11
11
  const loader = createResourcesLoader({
12
12
  ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
13
+ ...(options.reservedPromptNames !== undefined ? { reservedPromptNames: options.reservedPromptNames } : {}),
13
14
  skills: () => ({
14
15
  ...skillOptions(config()?.get().skills.trustProjectCompatRoots === true, options),
15
16
  }),
@@ -35,9 +36,6 @@ export function createResourcesBundle(
35
36
  expandPromptTemplate(text, cwd) {
36
37
  return loader.expandPromptTemplate(text, cwd);
37
38
  },
38
- themes() {
39
- return loader.themes();
40
- },
41
39
  resolvePath(value, cwd) {
42
40
  return loader.resolvePath(value, cwd);
43
41
  },
@@ -25,6 +25,8 @@ export interface ResourceList<T> {
25
25
 
26
26
  export interface ResourceLoaderOptions {
27
27
  cwd?: string;
28
+ /** Slash-command names prompt templates may not claim. */
29
+ reservedPromptNames?: ReadonlySet<string>;
28
30
  skills?: () => Pick<LoadSkillsInput, "trustProjectCompatRoots" | "disableDiscovery" | "explicitSkillPaths">;
29
31
  }
30
32
 
@@ -38,7 +40,6 @@ export interface ResourcesLoader {
38
40
  ): { text: string; pendingSkillRequests: PendingSkillRequest[] };
39
41
  prompts(cwd?: string): ResourceList<PromptTemplate>;
40
42
  expandPromptTemplate(text: string, cwd?: string): PromptTemplateExpansion;
41
- themes(): ResourceList<never>;
42
43
  resolvePath(value: string, cwd?: string): string;
43
44
  reload(): Promise<void>;
44
45
  }
@@ -53,6 +54,7 @@ export function createResourcesLoader(options: ResourceLoaderOptions = {}): Reso
53
54
  // trust decision whichever kind is read out of it.
54
55
  const promptOptions = (cwd: string): LoadPromptTemplatesInput => ({
55
56
  cwd,
57
+ ...(options.reservedPromptNames !== undefined ? { reservedNames: options.reservedPromptNames } : {}),
56
58
  ...(skillOptions().trustProjectCompatRoots !== undefined
57
59
  ? { trustProjectCompatRoots: skillOptions().trustProjectCompatRoots === true }
58
60
  : {}),
@@ -73,9 +75,6 @@ export function createResourcesLoader(options: ResourceLoaderOptions = {}): Reso
73
75
  expandPromptTemplate(text, cwd = defaultCwd) {
74
76
  return expandPromptTemplateInput(text, loadPromptTemplates(promptOptions(cwd)));
75
77
  },
76
- themes() {
77
- return { items: [], diagnostics: [] };
78
- },
79
78
  resolvePath(value, cwd = defaultCwd) {
80
79
  return expandConfigPath(value, { cwd });
81
80
  },
@@ -1,6 +1,7 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import path from "node:path";
4
+ import { parseCommandArgs, substituteArgs } from "../../../engine/prompt-templates.js";
4
5
  import { INTEROP_AGENT_KINDS } from "../../interop/registry.js";
5
6
  import {
6
7
  type ResourceCandidate,
@@ -18,7 +19,6 @@ import {
18
19
  stringField,
19
20
  } from "../common-loader.js";
20
21
  import { projectCompatTrusted } from "../skills/loader.js";
21
- import { parseCommandArgs, substituteArgs } from "./substitute.js";
22
22
 
23
23
  export interface PromptTemplate {
24
24
  name: string;
@@ -51,6 +51,8 @@ export interface LoadPromptTemplatesInput {
51
51
  home?: string;
52
52
  /** Opt in to model-visible project compatibility roots (.claude/commands, .codex/prompts). */
53
53
  trustProjectCompatRoots?: boolean;
54
+ /** Names owned by another command registry and unavailable to templates. */
55
+ reservedNames?: ReadonlySet<string>;
54
56
  }
55
57
 
56
58
  export type PromptTemplateExpansion =
@@ -189,8 +191,20 @@ export function loadPromptTemplates(input: LoadPromptTemplatesInput = {}): Promp
189
191
  const diagnostics: ResourceDiagnostic[] = [];
190
192
  const candidates = roots.flatMap((root) => loadPromptRoot(root, diagnostics));
191
193
  const resolved = resolveResourceCollisions(candidates);
194
+ const items: PromptTemplate[] = [];
195
+ for (const template of resolved.winners) {
196
+ if (input.reservedNames?.has(template.name) === true) {
197
+ diagnostics.push({
198
+ type: "collision",
199
+ message: `prompt template /${template.name} conflicts with the built-in slash command /${template.name} and was ignored`,
200
+ path: template.filePath,
201
+ });
202
+ continue;
203
+ }
204
+ items.push(template);
205
+ }
192
206
  return {
193
- items: [...resolved.winners].sort((a, b) => a.name.localeCompare(b.name)),
207
+ items: items.sort((a, b) => a.name.localeCompare(b.name)),
194
208
  diagnostics: [...diagnostics, ...resolved.diagnostics],
195
209
  };
196
210
  }
@@ -1,65 +1 @@
1
- export function parseCommandArgs(input: string): string[] {
2
- const args: string[] = [];
3
- let current = "";
4
- let hasToken = false;
5
- let quote: "'" | '"' | null = null;
6
-
7
- const push = (): void => {
8
- if (!hasToken) return;
9
- args.push(current);
10
- current = "";
11
- hasToken = false;
12
- };
13
-
14
- for (let i = 0; i < input.length; i += 1) {
15
- const ch = input[i];
16
- if (!ch) continue;
17
- if (quote) {
18
- if (ch === quote) {
19
- quote = null;
20
- } else {
21
- current += ch;
22
- }
23
- continue;
24
- }
25
- if (ch === "'" || ch === `"`) {
26
- quote = ch;
27
- hasToken = true;
28
- continue;
29
- }
30
- if (/\s/.test(ch)) {
31
- push();
32
- continue;
33
- }
34
- current += ch;
35
- hasToken = true;
36
- }
37
- push();
38
-
39
- return args;
40
- }
41
-
42
- function sliceArgs(args: ReadonlyArray<string>, startText: string, lengthText: string | undefined): string {
43
- const start = Number.parseInt(startText, 10);
44
- if (!Number.isFinite(start) || start <= 0) return "";
45
- const zeroBased = start - 1;
46
- if (lengthText === undefined) return args.slice(zeroBased).join(" ");
47
- const length = Number.parseInt(lengthText, 10);
48
- if (!Number.isFinite(length) || length <= 0) return "";
49
- return args.slice(zeroBased, zeroBased + length).join(" ");
50
- }
51
-
52
- export function substituteArgs(content: string, args: ReadonlyArray<string>): string {
53
- const allArgs = args.join(" ");
54
- return content
55
- .replace(/\$\{@:(\d+)(?::(\d+))?\}/g, (_match, start: string, length: string | undefined) =>
56
- sliceArgs(args, start, length),
57
- )
58
- .replace(/\$ARGUMENTS/g, allArgs)
59
- .replace(/\$@/g, allArgs)
60
- .replace(/\$(\d+)/g, (_match, indexText: string) => {
61
- const index = Number.parseInt(indexText, 10);
62
- if (!Number.isFinite(index) || index <= 0) return "";
63
- return args[index - 1] ?? "";
64
- });
65
- }
1
+ export { parseCommandArgs, substituteArgs } from "../../../engine/prompt-templates.js";
@@ -20,6 +20,8 @@ export const PROVENANCE_KEYS = new Set([
20
20
  "installed-hash",
21
21
  "installedHash",
22
22
  "audit",
23
+ "installed-by",
24
+ "installedBy",
23
25
  ]);
24
26
 
25
27
  export interface FrontmatterRegion {
@@ -117,6 +117,16 @@ export function parseSkillSourceSpec(source: string): SkillSourceSpec | null {
117
117
  return { kind: "local", path: path.resolve(expanded), original: trimmed };
118
118
  }
119
119
 
120
+ /**
121
+ * Whether this process is running inside a dispatched worker rather than the
122
+ * operator's own interactive session. `worker/entry.ts` sets this on itself at
123
+ * launch, so it rides the environment into every bash-tool child a worker
124
+ * spawns, including a `clio-coder skills install` a worker runs directly.
125
+ */
126
+ function installingAsWorker(): boolean {
127
+ return process.env.CLIO_CODER_WORKER_RUN === "1";
128
+ }
129
+
120
130
  function yamlQuote(value: string): string {
121
131
  return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
122
132
  }
@@ -126,6 +136,8 @@ interface ProvenanceFields {
126
136
  installedAt: string;
127
137
  updatedAt?: string;
128
138
  installedHash: string;
139
+ /** Who ran the install: a dispatched worker, or (unmarked) the operator. */
140
+ installedBy?: "worker";
129
141
  }
130
142
 
131
143
  /**
@@ -152,6 +164,7 @@ function injectProvenanceFrontmatter(rawText: string, fields: ProvenanceFields):
152
164
  `installed-hash: ${yamlQuote(fields.installedHash)}`,
153
165
  // Audit is a human decision; installs always land unreviewed.
154
166
  "audit: unknown",
167
+ ...(fields.installedBy ? [`installed-by: ${yamlQuote(fields.installedBy)}`] : []),
155
168
  ];
156
169
  const clioIndex = kept.findIndex((line) => /^clio:/.test(line));
157
170
  if (clioIndex >= 0 && !/^clio:\s*$/.test(kept[clioIndex] as string)) {
@@ -317,6 +330,7 @@ export function installSkillFromSource(input: InstallSkillInput): InstallSkillRe
317
330
  sourceUrl: spec.original,
318
331
  installedAt: new Date().toISOString(),
319
332
  installedHash,
333
+ ...(installingAsWorker() ? { installedBy: "worker" as const } : {}),
320
334
  }),
321
335
  "utf8",
322
336
  );
@@ -384,6 +398,9 @@ function updateOne(skill: Skill, force: boolean): SkillUpdateReport {
384
398
  installedAt: skill.provenance?.installedAt ?? new Date().toISOString(),
385
399
  updatedAt: new Date().toISOString(),
386
400
  installedHash: remoteHash,
401
+ // Who installed a skill is set once; an update, worker- or
402
+ // operator-run, does not change who put it there originally.
403
+ ...(skill.provenance?.installedBy ? { installedBy: skill.provenance.installedBy } : {}),
387
404
  }),
388
405
  "utf8",
389
406
  );
@@ -67,6 +67,8 @@ export interface SkillProvenance {
67
67
  /** Content hash of the upstream SKILL.md at install time, provenance-stripped. */
68
68
  installedHash?: string;
69
69
  audit?: "pass" | "warn" | "fail" | "unknown";
70
+ /** Who ran the install: a dispatched worker, or (unmarked) the operator. */
71
+ installedBy?: "worker";
70
72
  }
71
73
 
72
74
  export interface Skill {
@@ -479,7 +481,18 @@ function extractProvenance(frontmatter: Record<string, unknown>): SkillProvenanc
479
481
  const auditRaw = field("audit");
480
482
  const audit =
481
483
  auditRaw === "pass" || auditRaw === "warn" || auditRaw === "fail" || auditRaw === "unknown" ? auditRaw : undefined;
482
- if (!installUrl && !registryId && !registryUrl && !installedAt && !updatedAt && !installedHash && !audit)
484
+ const installedByRaw = field("installed-by", "installedBy");
485
+ const installedBy = installedByRaw === "worker" ? installedByRaw : undefined;
486
+ if (
487
+ !installUrl &&
488
+ !registryId &&
489
+ !registryUrl &&
490
+ !installedAt &&
491
+ !updatedAt &&
492
+ !installedHash &&
493
+ !audit &&
494
+ !installedBy
495
+ )
483
496
  return undefined;
484
497
  return {
485
498
  ...(installUrl ? { installUrl } : {}),
@@ -489,6 +502,7 @@ function extractProvenance(frontmatter: Record<string, unknown>): SkillProvenanc
489
502
  ...(updatedAt ? { updatedAt } : {}),
490
503
  ...(installedHash ? { installedHash } : {}),
491
504
  ...(audit ? { audit } : {}),
505
+ ...(installedBy ? { installedBy } : {}),
492
506
  };
493
507
  }
494
508
 
@@ -881,15 +895,8 @@ export function modelVisibleSkills(skills: ReadonlyArray<Skill>): Skill[] {
881
895
 
882
896
  export function parseSkillCommand(input: string): { name: string; args: string } | null {
883
897
  const trimmed = input.trim();
884
- const prefix = trimmed.startsWith("/skill:")
885
- ? "/skill:"
886
- : trimmed.startsWith("/skills:")
887
- ? "/skills:"
888
- : trimmed.startsWith("/skill ")
889
- ? "/skill "
890
- : null;
891
- if (!prefix) return null;
892
- const rest = trimmed.slice(prefix.length).trim();
898
+ if (!trimmed.startsWith("/skill ")) return null;
899
+ const rest = trimmed.slice("/skill ".length).trim();
893
900
  const separator = rest.search(/\s/);
894
901
  const name = separator === -1 ? rest : rest.slice(0, separator);
895
902
  if (name.length === 0) return null;