@iowarp/clio-coder 0.3.8 → 0.4.0

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 (552) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/NOTICE +33 -0
  3. package/README.md +12 -3
  4. package/dist/{acp-U67UHUK2.js → acp-G5WJBNCT.js} +13 -12
  5. package/dist/{agents-YU6SGALZ.js → agents-FMV2Q5G4.js} +41 -36
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-5ZPJOIVG.js → auth-3IDSJEIK.js} +18 -18
  8. package/dist/{builtins-C6JMZVV6.js → builtins-XCZWXSC7.js} +5 -5
  9. package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
  10. package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
  11. package/dist/{chunk-XWSF374K.js → chunk-2OQE55CK.js} +3 -3
  12. package/dist/{chunk-5H3GB5BO.js → chunk-32KWKNSF.js} +8 -384
  13. package/dist/{chunk-KTYTFRMB.js → chunk-36EJLSQQ.js} +34 -36
  14. package/dist/{chunk-FHJEP5SW.js → chunk-3BT2XMV4.js} +19 -13
  15. package/dist/chunk-3DPEIQKN.js +113 -0
  16. package/dist/{chunk-GU2UIAFZ.js → chunk-3URVFKWK.js} +7 -7
  17. package/dist/{chunk-WEH5XRJQ.js → chunk-3XML7CDN.js} +3 -3
  18. package/dist/chunk-42FMPA75.js +101 -0
  19. package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
  20. package/dist/{chunk-VCBR6CU7.js → chunk-5PSMVOLM.js} +2 -2
  21. package/dist/{chunk-NMPKI6XL.js → chunk-6DB53AJS.js} +203 -25
  22. package/dist/{chunk-3BINW3FP.js → chunk-76ONBSIA.js} +2 -2
  23. package/dist/{chunk-26LEYJZH.js → chunk-7MCTRUCE.js} +2 -2
  24. package/dist/{chunk-TYPGUK6W.js → chunk-AB44T6BB.js} +111 -5
  25. package/dist/{chunk-K4XHGFR5.js → chunk-B7OBL7PK.js} +317 -721
  26. package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
  27. package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
  28. package/dist/{chunk-ZVJ5BLO2.js → chunk-BKFJHQCA.js} +154 -16
  29. package/dist/chunk-BKFM6EJV.js +462 -0
  30. package/dist/chunk-BMS5RKQY.js +27 -0
  31. package/dist/{chunk-ZNLWCMVZ.js → chunk-BPKCPIL7.js} +2 -2
  32. package/dist/{chunk-TLQJPP24.js → chunk-BUMFYQFY.js} +1394 -1349
  33. package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
  34. package/dist/chunk-C2LTL2W6.js +2447 -0
  35. package/dist/{chunk-ME6CCNFO.js → chunk-CODPRO7Q.js} +8 -8
  36. package/dist/{chunk-E77JEWSD.js → chunk-CTJ4RNAA.js} +7 -37
  37. package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
  38. package/dist/{chunk-7RFXX52T.js → chunk-DQITNCXG.js} +642 -172
  39. package/dist/{chunk-TTHACPOM.js → chunk-DYJP44XW.js} +578 -117
  40. package/dist/{chunk-2HFZQUHL.js → chunk-F4CKPOEQ.js} +18 -8
  41. package/dist/{chunk-DGSYXYMX.js → chunk-FEFIFZTL.js} +3 -3
  42. package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
  43. package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
  44. package/dist/chunk-GKF55TAZ.js +391 -0
  45. package/dist/{chunk-VWZOAB7K.js → chunk-GR5G2PVF.js} +9 -8
  46. package/dist/{chunk-4DGYLA73.js → chunk-GXNLGKAB.js} +80 -9
  47. package/dist/chunk-HHV2GANA.js +88 -0
  48. package/dist/{chunk-IIZWH4XA.js → chunk-HI63TFOG.js} +5 -4
  49. package/dist/{chunk-WLFILSD5.js → chunk-HJJTYUHX.js} +113 -83
  50. package/dist/{chunk-TT36MB5S.js → chunk-HLW2MRKE.js} +3 -1
  51. package/dist/{chunk-PMDBGQSJ.js → chunk-HWHKMHUA.js} +7 -7
  52. package/dist/chunk-HZHHCK24.js +1631 -0
  53. package/dist/{chunk-WSB3FPX7.js → chunk-I5VEOC6I.js} +39 -143
  54. package/dist/chunk-IBEBSCYA.js +564 -0
  55. package/dist/chunk-IQ7KR472.js +362 -0
  56. package/dist/{chunk-A3WNZD3P.js → chunk-J4W7KFM7.js} +949 -972
  57. package/dist/{chunk-TB5666IT.js → chunk-JDG2WCRO.js} +5 -5
  58. package/dist/{chunk-N22QMJKY.js → chunk-K5C3NCBD.js} +4 -4
  59. package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
  60. package/dist/{chunk-5C3AQNDW.js → chunk-KFZI4NIL.js} +216 -38
  61. package/dist/chunk-KMVISBZR.js +132 -0
  62. package/dist/{chunk-WXY7KU3G.js → chunk-LDQ2ZF2M.js} +2 -2
  63. package/dist/{chunk-XN3L4EYL.js → chunk-LQ3DZAMX.js} +3 -3
  64. package/dist/{chunk-U6MBIEMB.js → chunk-LY4S7GJC.js} +173 -144
  65. package/dist/{chunk-4SPRNWDE.js → chunk-MLKNTWH2.js} +19 -19
  66. package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
  67. package/dist/chunk-NEKRRTYW.js +56 -0
  68. package/dist/{chunk-SPULKLCF.js → chunk-NHCZP4K7.js} +3 -3
  69. package/dist/chunk-NHLBIGRH.js +1506 -0
  70. package/dist/chunk-NQQH3YT7.js +302 -0
  71. package/dist/chunk-NYS75XW5.js +15 -0
  72. package/dist/{chunk-GN57SG4G.js → chunk-O4XIVISU.js} +10 -8
  73. package/dist/{chunk-EMYUUSFG.js → chunk-O6TL7WWY.js} +6 -6
  74. package/dist/chunk-OQBA45DZ.js +97 -0
  75. package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
  76. package/dist/chunk-PMZCIOCJ.js +25 -0
  77. package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
  78. package/dist/{chunk-J3YUBZWY.js → chunk-QBJA7R7N.js} +62 -6
  79. package/dist/chunk-QDC3K2U3.js +262 -0
  80. package/dist/{chunk-2HEJ2F35.js → chunk-QLFS5GO2.js} +22 -10
  81. package/dist/{chunk-7RGZWPB6.js → chunk-QLL7ILRG.js} +95 -32
  82. package/dist/{chunk-YS5VLNH5.js → chunk-QREDIESB.js} +6 -6
  83. package/dist/chunk-QSNYB6ZV.js +195 -0
  84. package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
  85. package/dist/chunk-RKKLTLYB.js +45 -0
  86. package/dist/{chunk-P43ETTHK.js → chunk-SJ5ZKQ4S.js} +2 -2
  87. package/dist/{chunk-GPIEI3LY.js → chunk-SP2RXXYO.js} +6 -54
  88. package/dist/chunk-SUCTJL45.js +45 -0
  89. package/dist/{chunk-DYIM5TJT.js → chunk-SUW5DORT.js} +263 -7
  90. package/dist/chunk-T56WDKA5.js +183 -0
  91. package/dist/chunk-TVHHYFHE.js +255 -0
  92. package/dist/{chunk-FJ3H4MN5.js → chunk-TZ3SGWZZ.js} +3 -3
  93. package/dist/{chunk-MXKJU4JB.js → chunk-U77AMWDL.js} +91 -10
  94. package/dist/{chunk-5DHKRSMQ.js → chunk-ULC6OTWO.js} +11 -7
  95. package/dist/{chunk-RWSI4YD7.js → chunk-UM7N4G5A.js} +33 -12
  96. package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
  97. package/dist/{chunk-IGWKHNIQ.js → chunk-UXMFQ54G.js} +44 -37
  98. package/dist/{chunk-HFSBBKSQ.js → chunk-V5DHCITQ.js} +171 -3
  99. package/dist/{chunk-5WIGXA4T.js → chunk-VAZSBTKF.js} +111 -4
  100. package/dist/{chunk-VHN4MY6O.js → chunk-VEO4AP2K.js} +2 -2
  101. package/dist/{chunk-IJ7RPIYJ.js → chunk-VFA6GDY5.js} +65 -4
  102. package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
  103. package/dist/chunk-VO67MWHC.js +75 -0
  104. package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
  105. package/dist/{chunk-TANS5ZJS.js → chunk-VYMXRQI6.js} +36 -22
  106. package/dist/{chunk-WWCZ5F23.js → chunk-W5VSYASO.js} +77 -16
  107. package/dist/{chunk-WNIJTQQK.js → chunk-WZR7K7ZX.js} +72 -116
  108. package/dist/{chunk-5Q2VVUKB.js → chunk-X3YGUTOB.js} +4 -4
  109. package/dist/chunk-X75E3D2N.js +686 -0
  110. package/dist/{chunk-VAWNZU7Z.js → chunk-YDFRH54B.js} +4 -4
  111. package/dist/chunk-YJX4SHTD.js +40 -0
  112. package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
  113. package/dist/chunk-Z2RR6MAK.js +127 -0
  114. package/dist/{chunk-FBVTI2TJ.js → chunk-Z4TXYIEG.js} +12 -131
  115. package/dist/cli/index.js +47 -36
  116. package/dist/{clio-QVTYJ57A.js → clio-2JXHBBY5.js} +7 -7
  117. package/dist/{code-nav-FGGFIE7L.js → code-nav-3YYRMYNF.js} +8 -8
  118. package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
  119. package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
  120. package/dist/{config-LW5IJFQN.js → config-QZPCMYSO.js} +99 -63
  121. package/dist/{configure-7XIZCOU4.js → configure-TEGEBYCA.js} +23 -22
  122. package/dist/{context-Y6Y7QPR6.js → context-AV7OEZ4D.js} +12 -12
  123. package/dist/{context-L3WL3X7K.js → context-E6H5RNMC.js} +56 -47
  124. package/dist/{context-N52ZA626.js → context-GSXUE4CT.js} +29 -27
  125. package/dist/{context-clear-MBQRLSDQ.js → context-clear-SHIBYK6T.js} +55 -46
  126. package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
  127. package/dist/{context-working-set-GS6DSO7F.js → context-working-set-5ZGKPGZQ.js} +13 -13
  128. package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-EFMJT4LD.js} +93 -64
  129. package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
  130. package/dist/doctor-QOA5FNY5.js +313 -0
  131. package/dist/{eval-BEC2WHDA.js → eval-TFBYQH4H.js} +2032 -156
  132. package/dist/eval-inventory-SXH7PDKX.js +316 -0
  133. package/dist/{evidence-REJUMSKM.js → evidence-ERGESKGN.js} +203 -48
  134. package/dist/{evolve-PY5ZBA5K.js → evolve-VDXTSYCJ.js} +52 -43
  135. package/dist/{extensions-HVKU65YU.js → extensions-7BGBHN57.js} +13 -7
  136. package/dist/{fleet-7WZEWRFA.js → fleet-2RRVDF2V.js} +228 -108
  137. package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-VJ726XIA.js} +11 -11
  138. package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
  139. package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-JF5QOATM.js} +18 -15
  140. package/dist/fleet-inspect-VLY4S7QM.js +442 -0
  141. package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-AIZUEJOY.js} +5 -5
  142. package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-AJRPDMDV.js} +22 -19
  143. package/dist/fleet-verify-JFEL2L3H.js +175 -0
  144. package/dist/fleet-view-ZCON35AG.js +102 -0
  145. package/dist/{init-OG3TPGQG.js → init-DN2WWLFE.js} +72 -62
  146. package/dist/install-XGLBQY5E.js +13 -0
  147. package/dist/interop-OZBKXAYL.js +114 -0
  148. package/dist/{library-CNTMPLRF.js → library-YWZG7IMW.js} +21 -18
  149. package/dist/{memory-6IS7F275.js → memory-I4C4HMLW.js} +54 -45
  150. package/dist/{models-ENRJDA5W.js → models-CEYXJBO6.js} +33 -30
  151. package/dist/{monitor-XLDVO7TN.js → monitor-NZ6GCI3P.js} +59 -52
  152. package/dist/{orchestrator-6KSPYRHA.js → orchestrator-GCGQ4N5I.js} +7827 -7328
  153. package/dist/panes-HMABYVO4.js +58 -0
  154. package/dist/panes-KY6W3V2E.js +103 -0
  155. package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
  156. package/dist/{reset-RZ4ER727.js → reset-DQ6FGCSH.js} +13 -11
  157. package/dist/resources-BB3MVJMD.js +111 -0
  158. package/dist/{run-Y2CNK5RU.js → run-H2GQDUER.js} +119 -87
  159. package/dist/{share-A55GYP6Z.js → share-GTJN6A5O.js} +20 -17
  160. package/dist/{skills-ALC5J6AT.js → skills-L55TEW6R.js} +33 -24
  161. package/dist/{skills-eval-JPBEBYQU.js → skills-eval-XVXPH2JI.js} +67 -56
  162. package/dist/skills-inventory-S4MXPJFV.js +126 -0
  163. package/dist/slash-commands-ZSGASKJC.js +77 -0
  164. package/dist/{steer-GGWFUJUD.js → steer-RZGSCY4R.js} +4 -4
  165. package/dist/{support-MIETYA5E.js → support-PKEUNNQL.js} +6 -6
  166. package/dist/{targets-VGNXIR3S.js → targets-NCPZ644J.js} +68 -40
  167. package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-44SV3YCN.js} +6 -4
  168. package/dist/tools-DAF3DI3C.js +27 -0
  169. package/dist/{trace-PNCASAXC.js → trace-FYVW2MQA.js} +207 -10
  170. package/dist/tui-primitives-2AKXQNZK.js +13 -0
  171. package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
  172. package/dist/{upgrade-FUSUAGHR.js → upgrade-3XPP6OQL.js} +27 -24
  173. package/dist/{usage-N4MKVHKD.js → usage-3NLHGTU2.js} +114 -62
  174. package/dist/{verifiers-YAWOJ3H2.js → verifiers-SSQONKRT.js} +172 -13
  175. package/dist/{verify-LTDHYBGY.js → verify-3U6J7FZI.js} +10 -10
  176. package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
  177. package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-CEHYGPGQ.js} +75 -65
  178. package/dist/with-panes-MKB46MPQ.js +782 -0
  179. package/dist/worker/entry.js +106 -75
  180. package/docs/README.md +3 -2
  181. package/docs/acp.md +24 -3
  182. package/docs/alcf-provider.md +1 -1
  183. package/docs/architecture.md +2 -2
  184. package/docs/artifact-versions.md +9 -1
  185. package/docs/built-in-agents.md +1 -1
  186. package/docs/capacity-and-scheduling.md +62 -3
  187. package/docs/commands-and-modes.md +31 -2
  188. package/docs/configuration-and-targets.md +69 -12
  189. package/docs/context-engine.md +63 -4
  190. package/docs/development-pipeline.md +19 -0
  191. package/docs/dispatch-typed-intent.md +385 -0
  192. package/docs/documentation-coverage.md +5 -5
  193. package/docs/documentation-guide.md +1 -1
  194. package/docs/environment-variables.md +3 -0
  195. package/docs/eval-runner.md +262 -11
  196. package/docs/evals-internal.md +72 -2
  197. package/docs/evidence-and-memory.md +12 -11
  198. package/docs/evolution.md +1 -1
  199. package/docs/exit-codes-and-output.md +1 -1
  200. package/docs/extensions-and-sharing.md +27 -1
  201. package/docs/fleet-dispatch.md +25 -4
  202. package/docs/installation-and-lifecycle.md +15 -2
  203. package/docs/middleware-and-components.md +1 -1
  204. package/docs/model-catalog.md +10 -1
  205. package/docs/observability.md +55 -4
  206. package/docs/proactive-memory.md +127 -14
  207. package/docs/prompt-envelope-and-tools.md +19 -1
  208. package/docs/provider-adapter-cookbook.md +1 -1
  209. package/docs/release-cut-checklist.md +19 -3
  210. package/docs/safety-model.md +2 -2
  211. package/docs/scientific-validation.md +3 -3
  212. package/docs/session-lifecycle.md +1 -1
  213. package/docs/skills-marketplace.md +1 -1
  214. package/docs/tool-usage.md +18 -8
  215. package/docs/trace-store.md +1 -1
  216. package/docs/troubleshooting.md +88 -1
  217. package/docs/tui-design.md +1 -1
  218. package/docs/worker-dispatch-mechanics.md +1 -1
  219. package/package.json +5 -2
  220. package/src/cli/acp.ts +6 -2
  221. package/src/cli/agents.ts +1 -1
  222. package/src/cli/argv.ts +25 -0
  223. package/src/cli/config-inspect.ts +33 -6
  224. package/src/cli/config.ts +1 -1
  225. package/src/cli/configure.ts +23 -21
  226. package/src/cli/doctor-panes.ts +124 -0
  227. package/src/cli/doctor-state-size.ts +82 -0
  228. package/src/cli/doctor-toolchain.ts +57 -0
  229. package/src/cli/doctor.ts +22 -1
  230. package/src/cli/eval-inventory.ts +436 -0
  231. package/src/cli/eval.ts +93 -16
  232. package/src/cli/evidence-detail.ts +88 -0
  233. package/src/cli/evidence-inventory.ts +183 -0
  234. package/src/cli/evidence.ts +30 -5
  235. package/src/cli/extensions.ts +5 -1
  236. package/src/cli/fleet-decisions.ts +69 -0
  237. package/src/cli/fleet-inspect.ts +334 -0
  238. package/src/cli/fleet-verify.ts +133 -0
  239. package/src/cli/fleet-view.ts +810 -0
  240. package/src/cli/fleet.ts +179 -39
  241. package/src/cli/index.ts +14 -2
  242. package/src/cli/interop-inspect.ts +128 -0
  243. package/src/cli/interop.ts +34 -0
  244. package/src/cli/panes.ts +35 -0
  245. package/src/cli/reset.ts +5 -2
  246. package/src/cli/run.ts +58 -0
  247. package/src/cli/skills-inventory.ts +185 -0
  248. package/src/cli/skills.ts +16 -13
  249. package/src/cli/targets.ts +44 -13
  250. package/src/cli/tools.ts +321 -0
  251. package/src/cli/trace-inspect.ts +252 -0
  252. package/src/cli/trace.ts +85 -5
  253. package/src/cli/usage.ts +63 -14
  254. package/src/cli/verifiers-inspect.ts +347 -0
  255. package/src/cli/verifiers.ts +9 -0
  256. package/src/core/bus-events.ts +33 -1
  257. package/src/core/cache-telemetry.ts +42 -0
  258. package/src/core/config.ts +67 -0
  259. package/src/core/defaults.ts +124 -8
  260. package/src/core/endpoint-key.ts +27 -0
  261. package/src/core/residency-target-key.ts +25 -0
  262. package/src/core/response-schema.ts +80 -6
  263. package/src/core/theme-token-hex.ts +43 -0
  264. package/src/core/tool-names.ts +2 -1
  265. package/src/core/xdg.ts +1 -1
  266. package/src/domains/agents/fleets/build-review.md +0 -3
  267. package/src/domains/agents/fleets/build-test.md +0 -3
  268. package/src/domains/agents/result-contract-filesystem.ts +32 -0
  269. package/src/domains/agents/result-contract.ts +164 -35
  270. package/src/domains/config/classify.ts +6 -0
  271. package/src/domains/context/codewiki/coordinator.ts +12 -4
  272. package/src/domains/dispatch/admission-error.ts +9 -0
  273. package/src/domains/dispatch/admission.ts +52 -14
  274. package/src/domains/dispatch/capacity-lease.ts +118 -9
  275. package/src/domains/dispatch/contract.ts +11 -0
  276. package/src/domains/dispatch/council-topology.ts +398 -0
  277. package/src/domains/dispatch/execution-plan.ts +44 -4
  278. package/src/domains/dispatch/extension.ts +378 -82
  279. package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
  280. package/src/domains/dispatch/fleet-plan.ts +7 -2
  281. package/src/domains/dispatch/fleet-run.ts +87 -4
  282. package/src/domains/dispatch/gate-decisions.ts +11 -1
  283. package/src/domains/dispatch/gate-role-prompts.ts +9 -0
  284. package/src/domains/dispatch/gate-topology.ts +289 -0
  285. package/src/domains/dispatch/heartbeat.ts +32 -8
  286. package/src/domains/dispatch/index.ts +22 -0
  287. package/src/domains/dispatch/intent-compatibility.ts +330 -0
  288. package/src/domains/dispatch/intent.ts +85 -1
  289. package/src/domains/dispatch/orphan-recovery.ts +5 -0
  290. package/src/domains/dispatch/reservation-store.ts +139 -11
  291. package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
  292. package/src/domains/dispatch/run-event-journal.ts +598 -0
  293. package/src/domains/dispatch/state.ts +49 -1
  294. package/src/domains/dispatch/types.ts +13 -0
  295. package/src/domains/dispatch/validation.ts +33 -8
  296. package/src/domains/dispatch/worker-spawn.ts +25 -11
  297. package/src/domains/dispatch/write-boundary-enforcer.ts +20 -3
  298. package/src/domains/dispatch/write-boundary.ts +62 -1
  299. package/src/domains/eval/artifacts/store.ts +62 -0
  300. package/src/domains/eval/compare/behavioral.ts +224 -0
  301. package/src/domains/eval/compare/compare.ts +342 -2
  302. package/src/domains/eval/compare/envelope.ts +128 -0
  303. package/src/domains/eval/compare/gates.ts +24 -6
  304. package/src/domains/eval/compare/thresholds.ts +30 -3
  305. package/src/domains/eval/execution-provenance.ts +240 -0
  306. package/src/domains/eval/inventory.ts +113 -0
  307. package/src/domains/eval/metrics/aggregate.ts +136 -0
  308. package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
  309. package/src/domains/eval/metrics/tracked.ts +413 -0
  310. package/src/domains/eval/provenance.ts +117 -0
  311. package/src/domains/eval/reports/comparison.ts +128 -0
  312. package/src/domains/eval/reports/junit.ts +17 -3
  313. package/src/domains/eval/reports/markdown.ts +3 -3
  314. package/src/domains/eval/reports/text.ts +14 -0
  315. package/src/domains/eval/run-compare.ts +20 -0
  316. package/src/domains/eval/runners/clio-run.ts +127 -0
  317. package/src/domains/eval/runners/external-command.ts +28 -3
  318. package/src/domains/eval/schema/adapter.ts +111 -0
  319. package/src/domains/eval/schema/artifact.ts +20 -0
  320. package/src/domains/eval/schema/behavioral-metrics.ts +204 -0
  321. package/src/domains/eval/schema/behavioral.ts +520 -0
  322. package/src/domains/eval/schema/execution-envelope.ts +194 -0
  323. package/src/domains/eval/schema/serving.ts +105 -0
  324. package/src/domains/eval/schema/suite.ts +38 -8
  325. package/src/domains/eval/schema/validate.ts +58 -3
  326. package/src/domains/eval/schema/verdict.ts +237 -0
  327. package/src/domains/eval/suites/resolve.ts +2 -0
  328. package/src/domains/eval/suites/run.ts +264 -33
  329. package/src/domains/eval/verifiers/command.ts +2 -1
  330. package/src/domains/eval/workspaces/temp-copy.ts +145 -13
  331. package/src/domains/evidence/build.ts +2 -13
  332. package/src/domains/evidence/eval.ts +2 -12
  333. package/src/domains/evidence/findings-markdown.ts +33 -0
  334. package/src/domains/evidence/run-trust.ts +7 -113
  335. package/src/domains/evidence/store.ts +6 -0
  336. package/src/domains/evidence/trust-projection.ts +2 -2
  337. package/src/domains/extensions/compatibility.ts +285 -0
  338. package/src/domains/extensions/discovery.ts +38 -3
  339. package/src/domains/extensions/resources.ts +1 -1
  340. package/src/domains/extensions/state.ts +12 -3
  341. package/src/domains/extensions/types.ts +2 -0
  342. package/src/domains/lifecycle/doctor.ts +69 -1
  343. package/src/domains/memory/index.ts +14 -1
  344. package/src/domains/memory/task-bank-promotion.ts +64 -0
  345. package/src/domains/memory/task-memory-policy.ts +82 -17
  346. package/src/domains/memory/task-memory-spend.ts +131 -0
  347. package/src/domains/memory/task-memory-status.ts +7 -0
  348. package/src/domains/memory/task-memory-telemetry.ts +3 -0
  349. package/src/domains/middleware/index.ts +1 -0
  350. package/src/domains/middleware/memory-intervention.ts +97 -21
  351. package/src/domains/middleware/memory-step-endpoint.ts +71 -0
  352. package/src/domains/mux/contract.ts +434 -0
  353. package/src/domains/mux/detect.ts +158 -0
  354. package/src/domains/mux/extension.ts +47 -0
  355. package/src/domains/mux/index.ts +96 -0
  356. package/src/domains/mux/manifest.ts +6 -0
  357. package/src/domains/mux/operations.ts +164 -0
  358. package/src/domains/mux/pane-registry.ts +90 -0
  359. package/src/domains/mux/protocol.ts +49 -0
  360. package/src/domains/mux/socket-client.ts +816 -0
  361. package/src/domains/mux/types.ts +222 -0
  362. package/src/domains/mux/viewer-command.ts +59 -0
  363. package/src/domains/mux/yazi/assets/init.lua +2 -0
  364. package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
  365. package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
  366. package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
  367. package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
  368. package/src/domains/mux/yazi/assets/yazi.toml +17 -0
  369. package/src/domains/mux/yazi/event-stream.ts +180 -0
  370. package/src/domains/mux/yazi/profile.ts +299 -0
  371. package/src/domains/mux/yazi/session.ts +228 -0
  372. package/src/domains/mux/yazi/theme.ts +30 -0
  373. package/src/domains/observability/background-memory-usage.ts +140 -0
  374. package/src/domains/observability/cost.ts +22 -1
  375. package/src/domains/observability/index.ts +9 -0
  376. package/src/domains/observability/out-of-turn-usage.ts +51 -2
  377. package/src/domains/observability/trace-store.ts +234 -2
  378. package/src/domains/prompts/compiler.ts +100 -13
  379. package/src/domains/providers/endpoint-capacity.ts +228 -0
  380. package/src/domains/providers/endpoint-slots-store.ts +189 -0
  381. package/src/domains/providers/extension.ts +20 -3
  382. package/src/domains/providers/index.ts +32 -0
  383. package/src/domains/providers/model-runtime-capabilities.ts +32 -0
  384. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +243 -1
  385. package/src/domains/providers/runtime-resolution.ts +8 -1
  386. package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
  387. package/src/domains/providers/runtimes/builtins.ts +2 -0
  388. package/src/domains/providers/runtimes/common/probe-helpers.ts +31 -9
  389. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +1 -1
  390. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
  391. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +1 -1
  392. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +1 -1
  393. package/src/domains/providers/runtimes/local-native/llamacpp.ts +4 -1
  394. package/src/domains/providers/runtimes/local-native/lmstudio.ts +4 -1
  395. package/src/domains/providers/runtimes/local-native/ollama-native.ts +6 -1
  396. package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
  397. package/src/domains/providers/support.ts +1 -0
  398. package/src/domains/providers/target-model-cache.ts +124 -0
  399. package/src/domains/providers/types/capability-flags.ts +2 -0
  400. package/src/domains/providers/types/target-descriptor.ts +2 -0
  401. package/src/domains/resources/index.ts +3 -0
  402. package/src/domains/resources/prompts/loader.ts +95 -33
  403. package/src/domains/resources/skills/loader.ts +33 -0
  404. package/src/domains/safety/action-classifier.ts +6 -0
  405. package/src/domains/safety/call-target.ts +52 -0
  406. package/src/domains/safety/run-effects.ts +35 -4
  407. package/src/domains/session/context-accounting.ts +52 -1
  408. package/src/domains/session/context-ledger.ts +37 -13
  409. package/src/domains/session/index.ts +6 -0
  410. package/src/domains/session/prompt-cache.ts +140 -0
  411. package/src/domains/session/prompt-manifest.ts +42 -0
  412. package/src/domains/toolchain/archive.ts +175 -0
  413. package/src/domains/toolchain/contract.ts +28 -0
  414. package/src/domains/toolchain/extension.ts +47 -0
  415. package/src/domains/toolchain/index.ts +39 -0
  416. package/src/domains/toolchain/install.ts +327 -0
  417. package/src/domains/toolchain/manifest.ts +8 -0
  418. package/src/domains/toolchain/paths.ts +34 -0
  419. package/src/domains/toolchain/registry.ts +265 -0
  420. package/src/domains/toolchain/remove.ts +218 -0
  421. package/src/domains/toolchain/resolve.ts +182 -0
  422. package/src/domains/toolchain/types.ts +113 -0
  423. package/src/domains/toolchain/version.ts +88 -0
  424. package/src/engine/acp/adapter.ts +18 -3
  425. package/src/engine/acp/server.ts +413 -70
  426. package/src/engine/acp/types.ts +19 -1
  427. package/src/engine/ai.ts +35 -0
  428. package/src/engine/apis/llamacpp-residency.ts +55 -3
  429. package/src/engine/apis/lmstudio.ts +25 -5
  430. package/src/engine/apis/ollama-native.ts +2 -1
  431. package/src/engine/apis/openai-completions.ts +80 -17
  432. package/src/engine/apis/residency-lock.ts +3 -1
  433. package/src/engine/apis/residency.ts +34 -1
  434. package/src/engine/claude/sdk-module.ts +98 -0
  435. package/src/engine/claude/sdk-runtime.ts +19 -11
  436. package/src/engine/provider-payload.ts +29 -1
  437. package/src/engine/tui-primitives.ts +21 -0
  438. package/src/engine/tui.ts +1 -0
  439. package/src/engine/worker-runtime.ts +2 -13
  440. package/src/entry/boot-options.ts +2 -0
  441. package/src/entry/orchestrator.ts +279 -35
  442. package/src/entry/panes-activation.ts +31 -0
  443. package/src/entry/with-panes.ts +20 -0
  444. package/src/interactive/chat-loop-messages.ts +26 -7
  445. package/src/interactive/chat-loop.ts +318 -41
  446. package/src/interactive/chat-panel.ts +62 -8
  447. package/src/interactive/clio-editor.ts +45 -8
  448. package/src/interactive/context-activity.ts +5 -1
  449. package/src/interactive/context-meter.ts +1 -1
  450. package/src/interactive/context-overlay.ts +41 -10
  451. package/src/interactive/cost-overlay.ts +66 -6
  452. package/src/interactive/council-grid.ts +1 -3
  453. package/src/interactive/council.ts +11 -0
  454. package/src/interactive/dispatch-board.ts +102 -20
  455. package/src/interactive/fleet-run-preview.ts +41 -15
  456. package/src/interactive/handoff-round.ts +41 -2
  457. package/src/interactive/interactive-application.ts +177 -7
  458. package/src/interactive/interactive-input-runtime.ts +15 -0
  459. package/src/interactive/interactive-presentation.ts +4 -0
  460. package/src/interactive/interactive-shell.ts +20 -17
  461. package/src/interactive/interactive-slash-runtime.ts +63 -10
  462. package/src/interactive/memory-overlay.ts +9 -0
  463. package/src/interactive/modal-marker.ts +170 -0
  464. package/src/interactive/mutation-preview.ts +295 -0
  465. package/src/interactive/mux-bridge.ts +214 -0
  466. package/src/interactive/overlay-frame.ts +58 -2
  467. package/src/interactive/overlay-general-openers.ts +17 -0
  468. package/src/interactive/overlay-key-routing.ts +52 -3
  469. package/src/interactive/overlay-lifecycle.ts +56 -7
  470. package/src/interactive/overlay-model-selectors.ts +40 -3
  471. package/src/interactive/overlay-permission-lifecycle.ts +112 -24
  472. package/src/interactive/overlay-session-lifecycle.ts +73 -9
  473. package/src/interactive/overlay-transitions.ts +18 -4
  474. package/src/interactive/overlays/agents.ts +1 -0
  475. package/src/interactive/overlays/ask-user.ts +227 -49
  476. package/src/interactive/overlays/auth-dialog.ts +1 -0
  477. package/src/interactive/overlays/context-reset.ts +1 -0
  478. package/src/interactive/overlays/cwd-fallback.ts +1 -0
  479. package/src/interactive/overlays/decisions.ts +11 -11
  480. package/src/interactive/overlays/extensions.ts +1 -0
  481. package/src/interactive/overlays/fleet-run-approval.ts +1 -0
  482. package/src/interactive/overlays/handoff-review.ts +1 -0
  483. package/src/interactive/overlays/help-reference.ts +6 -0
  484. package/src/interactive/overlays/interop.ts +1 -0
  485. package/src/interactive/overlays/library-install-confirm.ts +1 -0
  486. package/src/interactive/overlays/library-tabs.ts +28 -0
  487. package/src/interactive/overlays/list-overlay.ts +10 -1
  488. package/src/interactive/overlays/message-picker.ts +1 -0
  489. package/src/interactive/overlays/model-scope.ts +86 -0
  490. package/src/interactive/overlays/model-selector.ts +1 -0
  491. package/src/interactive/overlays/prompts.ts +12 -1
  492. package/src/interactive/overlays/session-selector.ts +1 -0
  493. package/src/interactive/overlays/settings-sections.ts +30 -0
  494. package/src/interactive/overlays/settings.ts +614 -45
  495. package/src/interactive/overlays/side-question.ts +1 -0
  496. package/src/interactive/overlays/skills-hub.ts +3 -11
  497. package/src/interactive/overlays/tree-selector.ts +1 -0
  498. package/src/interactive/pane-policy.ts +46 -0
  499. package/src/interactive/panes-runtime.ts +292 -0
  500. package/src/interactive/permission-hint.ts +34 -2
  501. package/src/interactive/permission-overlay.ts +159 -9
  502. package/src/interactive/prewarm.ts +197 -0
  503. package/src/interactive/render-trace.ts +162 -15
  504. package/src/interactive/renderers/compaction-summary.ts +29 -0
  505. package/src/interactive/renderers/tool-execution.ts +4 -0
  506. package/src/interactive/renderers/worker-entry.ts +122 -14
  507. package/src/interactive/side-question.ts +58 -1
  508. package/src/interactive/slash-commands.ts +251 -15
  509. package/src/interactive/status/controller.ts +11 -0
  510. package/src/interactive/status/state-machine.ts +54 -2
  511. package/src/interactive/status/types.ts +7 -0
  512. package/src/interactive/tasks-overlay.ts +1 -0
  513. package/src/interactive/terminal-lease.ts +2 -0
  514. package/src/interactive/theme/tokens.ts +3 -14
  515. package/src/interactive/turn-context.ts +346 -33
  516. package/src/interactive/turn-persistence.ts +14 -4
  517. package/src/interactive/turn-prewarm.ts +364 -0
  518. package/src/interactive/turn-queues.ts +7 -4
  519. package/src/interactive/turn-runtime.ts +8 -1
  520. package/src/interactive/turn-state.ts +23 -0
  521. package/src/interactive/view/artifacts.ts +109 -1
  522. package/src/interactive/view/view-overlay.ts +29 -3
  523. package/src/interactive/watch-pane.ts +152 -0
  524. package/src/interactive/worker-progress.ts +7 -1
  525. package/src/interactive/worker-receipts.ts +19 -1
  526. package/src/interactive/worker-stream.ts +5 -0
  527. package/src/interactive/yazi-bridge.ts +444 -0
  528. package/src/tools/ask-user.ts +43 -2
  529. package/src/tools/bootstrap.ts +26 -2
  530. package/src/tools/builtin-tool-catalog.ts +15 -0
  531. package/src/tools/compete-worktrees.ts +83 -2
  532. package/src/tools/core-bootstrap.ts +2 -1
  533. package/src/tools/dispatch-admission.ts +14 -3
  534. package/src/tools/dispatch-arguments.ts +20 -20
  535. package/src/tools/dispatch-plan.ts +17 -9
  536. package/src/tools/dispatch-run-events.ts +134 -19
  537. package/src/tools/dispatch-runner.ts +29 -7
  538. package/src/tools/dispatch-scout.ts +1 -1
  539. package/src/tools/dispatch-types.ts +15 -3
  540. package/src/tools/dispatch.ts +1 -1
  541. package/src/tools/executables.ts +17 -14
  542. package/src/tools/observation.ts +54 -4
  543. package/src/tools/panes-surface.ts +38 -0
  544. package/src/tools/panes.ts +112 -0
  545. package/src/tools/policy.ts +10 -1
  546. package/src/tools/presentation.ts +1 -0
  547. package/src/tools/registry.ts +16 -0
  548. package/dist/chunk-AOCYTWAV.js +0 -449
  549. package/dist/chunk-HLE42MG7.js +0 -37
  550. package/dist/chunk-HWUFFB6L.js +0 -83
  551. package/dist/chunk-JOZYP4GM.js +0 -279
  552. package/dist/doctor-M7YEDGAE.js +0 -91
@@ -5,24 +5,24 @@ import {
5
5
  } from "./chunk-CFGTUFWB.js";
6
6
  import {
7
7
  credentialsPresent
8
- } from "./chunk-LU7P4LHA.js";
8
+ } from "./chunk-P3FOHJT4.js";
9
9
  import {
10
10
  ceilChars,
11
11
  estimateAgentMessageTokens,
12
12
  toolSchemaChars
13
- } from "./chunk-RWSI4YD7.js";
14
- import {
15
- readSettings
16
- } from "./chunk-IJ7RPIYJ.js";
17
- import {
18
- sleep
19
- } from "./chunk-FQ4SKYE4.js";
13
+ } from "./chunk-UM7N4G5A.js";
20
14
  import {
21
15
  getSharedBus
22
16
  } from "./chunk-ZGVHUX3M.js";
23
17
  import {
24
18
  BusChannels
25
- } from "./chunk-TT36MB5S.js";
19
+ } from "./chunk-HLW2MRKE.js";
20
+ import {
21
+ readSettings
22
+ } from "./chunk-VFA6GDY5.js";
23
+ import {
24
+ sleep
25
+ } from "./chunk-FQ4SKYE4.js";
26
26
  import {
27
27
  CLIO_CONTEXT_WINDOW_WARN_BELOW,
28
28
  CLIO_MIN_CONTEXT_WINDOW,
@@ -34,17 +34,17 @@ import {
34
34
  registerBuiltinRuntimes,
35
35
  requestLmStudioJson,
36
36
  resolveLmStudioInstance
37
- } from "./chunk-NMPKI6XL.js";
37
+ } from "./chunk-6DB53AJS.js";
38
38
  import {
39
39
  listKnownModelsForRuntime
40
- } from "./chunk-IIZWH4XA.js";
40
+ } from "./chunk-HI63TFOG.js";
41
41
  import {
42
42
  authNotRequiredStatus,
43
43
  openAuthStorage,
44
44
  registerClioOAuthProviders,
45
45
  resolveAuthTarget,
46
46
  targetRequiresAuth
47
- } from "./chunk-EQ63NRB7.js";
47
+ } from "./chunk-BBVYXMFO.js";
48
48
  import {
49
49
  withStateFileLock
50
50
  } from "./chunk-IKCO5N3L.js";
@@ -52,10 +52,16 @@ import {
52
52
  require_dist
53
53
  } from "./chunk-APJ265NV.js";
54
54
  import {
55
+ clioCacheDir,
55
56
  clioConfigDir,
57
+ clioStateDir,
56
58
  clioStatePath,
57
- resolveClioDirs
58
- } from "./chunk-BNAZZHFG.js";
59
+ resolveClioDirs,
60
+ stateRootRemoved
61
+ } from "./chunk-BYP5D4HI.js";
62
+ import {
63
+ safeResourceWrite
64
+ } from "./chunk-WEPFGWHJ.js";
59
65
  import {
60
66
  getRuntimeRegistry
61
67
  } from "./chunk-NUGM5KR6.js";
@@ -65,27 +71,241 @@ import {
65
71
  getCatalogModelForRuntime,
66
72
  mergeCapabilities,
67
73
  resolveCostProvenance
68
- } from "./chunk-PT7HYKEM.js";
74
+ } from "./chunk-VO2LKSTM.js";
69
75
  import {
70
76
  activateExternalPluginApiBridge,
71
77
  calculateEngineCost,
72
78
  ensurePiAiRegistered,
73
79
  registerEngineApiProvider
74
- } from "./chunk-FCSXB6T2.js";
80
+ } from "./chunk-UOSL25KY.js";
75
81
  import {
76
82
  __toESM,
77
83
  init_esm_shims
78
84
  } from "./chunk-3R73A4XB.js";
79
85
 
86
+ // src/domains/providers/endpoint-capacity.ts
87
+ init_esm_shims();
88
+
89
+ // src/core/endpoint-key.ts
90
+ init_esm_shims();
91
+ function canonicalEndpointUrl(raw) {
92
+ if (!raw?.trim()) return null;
93
+ try {
94
+ const url = new URL(raw.trim().replace(/^ws:/u, "http:").replace(/^wss:/u, "https:"));
95
+ url.protocol = url.protocol.toLowerCase();
96
+ if (url.protocol !== "http:" && url.protocol !== "https:") return null;
97
+ url.hostname = url.hostname.toLowerCase();
98
+ url.username = "";
99
+ url.password = "";
100
+ url.hash = "";
101
+ url.search = "";
102
+ let path = url.pathname.replace(/\/{2,}/gu, "/").replace(/\/$/u, "");
103
+ if (path.endsWith("/v1")) path = path.slice(0, -3);
104
+ url.pathname = path || "/";
105
+ return url.toString().replace(/\/$/u, "");
106
+ } catch {
107
+ return null;
108
+ }
109
+ }
110
+
111
+ // src/domains/providers/endpoint-slots-store.ts
112
+ init_esm_shims();
113
+ import { existsSync, readFileSync } from "node:fs";
114
+ import { join } from "node:path";
115
+ var DEFAULT_ENDPOINT_SLOTS_TTL_MS = 24 * 60 * 60 * 1e3;
116
+ var ENDPOINT_SLOTS_TTL_ENV_VAR = "CLIO_CODER_ENDPOINT_SLOTS_TTL_MS";
117
+ var MAX_ENDPOINT_SLOT_RECORDS = 64;
118
+ function endpointSlotsPath() {
119
+ return join(clioStateDir(), "endpoint-slots.json");
120
+ }
121
+ function endpointSlotsTtlMs(env = process.env) {
122
+ const raw = env[ENDPOINT_SLOTS_TTL_ENV_VAR]?.trim();
123
+ if (raw !== void 0 && /^[1-9]\d*$/.test(raw)) {
124
+ const parsed = Number(raw);
125
+ if (Number.isSafeInteger(parsed)) return parsed;
126
+ }
127
+ return DEFAULT_ENDPOINT_SLOTS_TTL_MS;
128
+ }
129
+ function validRecord(key, value) {
130
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
131
+ const record = value;
132
+ return record.endpointKey === key && typeof record.runtimeId === "string" && record.runtimeId.length > 0 && typeof record.slots === "number" && Number.isInteger(record.slots) && record.slots > 0 && typeof record.observedAt === "string" && Number.isFinite(Date.parse(record.observedAt));
133
+ }
134
+ function readRecords() {
135
+ const path = endpointSlotsPath();
136
+ if (!existsSync(path)) return [];
137
+ try {
138
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
139
+ if (parsed?.version !== 1 || typeof parsed.endpoints !== "object" || parsed.endpoints === null) return [];
140
+ return Object.entries(parsed.endpoints).filter(([key, value]) => validRecord(key, value)).map(([, value]) => ({ ...value }));
141
+ } catch {
142
+ return [];
143
+ }
144
+ }
145
+ function fresh(record, nowMs, ttlMs) {
146
+ const observedMs = Date.parse(record.observedAt);
147
+ return observedMs <= nowMs && nowMs - observedMs < ttlMs;
148
+ }
149
+ function readDiscoveredEndpointSlots(options) {
150
+ const nowMs = options?.nowMs ?? Date.now();
151
+ const ttlMs = options?.ttlMs ?? endpointSlotsTtlMs();
152
+ const out = {};
153
+ for (const record of readRecords()) {
154
+ if (!fresh(record, nowMs, ttlMs)) continue;
155
+ out[record.endpointKey] = record;
156
+ }
157
+ return Object.freeze(out);
158
+ }
159
+ function writeRecords(records) {
160
+ const kept = [...records].sort((a, b) => Date.parse(b.observedAt) - Date.parse(a.observedAt)).slice(0, MAX_ENDPOINT_SLOT_RECORDS);
161
+ const file = {
162
+ version: 1,
163
+ endpoints: Object.fromEntries(kept.map((record) => [record.endpointKey, { ...record }]))
164
+ };
165
+ safeResourceWrite(endpointSlotsPath(), `${JSON.stringify(file, null, 2)}
166
+ `, { encoding: "utf8" });
167
+ }
168
+ async function recordDiscoveredEndpointSlots(entry, options) {
169
+ if (!Number.isInteger(entry.slots) || entry.slots <= 0) return;
170
+ if (entry.endpointKey.length === 0 || entry.runtimeId.length === 0) return;
171
+ if (stateRootRemoved()) return;
172
+ const nowMs = options?.nowMs ?? Date.now();
173
+ const ttlMs = options?.ttlMs ?? endpointSlotsTtlMs();
174
+ try {
175
+ await withStateFileLock(endpointSlotsPath(), () => {
176
+ if (stateRootRemoved()) return;
177
+ const kept = readRecords().filter(
178
+ (record) => record.endpointKey !== entry.endpointKey && fresh(record, nowMs, ttlMs)
179
+ );
180
+ kept.push({
181
+ endpointKey: entry.endpointKey,
182
+ runtimeId: entry.runtimeId,
183
+ slots: entry.slots,
184
+ observedAt: new Date(nowMs).toISOString()
185
+ });
186
+ writeRecords(kept);
187
+ });
188
+ } catch (error) {
189
+ options?.onError?.(error);
190
+ }
191
+ }
192
+
193
+ // src/domains/providers/endpoint-capacity.ts
194
+ var UNBOUNDED_LOCAL_NATIVE_RUNTIMES = /* @__PURE__ */ new Set(["vllm", "sglang"]);
195
+ function canonicalEndpointKey(value) {
196
+ return canonicalEndpointUrl(typeof value === "string" ? value : value.url);
197
+ }
198
+ function endpointLabel(endpointKey) {
199
+ try {
200
+ const url = new URL(endpointKey);
201
+ return `${url.host}${url.pathname === "/" ? "" : url.pathname}`;
202
+ } catch {
203
+ return endpointKey;
204
+ }
205
+ }
206
+ function positiveInteger(value) {
207
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : void 0;
208
+ }
209
+ function endpointCapacityFor(input, priors = readDiscoveredEndpointSlots()) {
210
+ const key = canonicalEndpointKey(input.target);
211
+ if (key === null) return null;
212
+ const label = endpointLabel(key);
213
+ const override = positiveInteger(input.target.maxConcurrentRequests);
214
+ if (override !== void 0) return { key, label, limit: override, source: "override" };
215
+ const discovered = positiveInteger(input.discoveredSlots);
216
+ if (discovered !== void 0) return { key, label, limit: discovered, source: "discovered" };
217
+ const prior = priors[key];
218
+ if (prior !== void 0 && prior.runtimeId === (input.runtime?.id ?? input.target.runtime)) {
219
+ return { key, label, limit: prior.slots, source: "discovered-prior" };
220
+ }
221
+ if (input.runtime?.tier !== "local-native" || UNBOUNDED_LOCAL_NATIVE_RUNTIMES.has(input.runtime.id)) return null;
222
+ return { key, label, limit: 1, source: "local-native-default" };
223
+ }
224
+ function endpointCapacityForStatus(status, priors = readDiscoveredEndpointSlots()) {
225
+ return endpointCapacityFor(
226
+ {
227
+ target: status.target,
228
+ runtime: status.runtime ?? null,
229
+ discoveredSlots: status.probeCapabilities?.parallelSlots
230
+ },
231
+ priors
232
+ );
233
+ }
234
+ function sourceRank(source) {
235
+ switch (source) {
236
+ case "override":
237
+ return 3;
238
+ case "discovered":
239
+ return 2;
240
+ case "discovered-prior":
241
+ return 1;
242
+ default:
243
+ return 0;
244
+ }
245
+ }
246
+ function foldCapacity(capacities, candidate) {
247
+ if (candidate === null) return;
248
+ const current = capacities[candidate.key];
249
+ if (current === void 0 || sourceRank(candidate.source) > sourceRank(current.source) || sourceRank(candidate.source) === sourceRank(current.source) && candidate.limit < current.limit) {
250
+ capacities[candidate.key] = candidate;
251
+ }
252
+ }
253
+ function endpointCapacitiesForStatuses(statuses) {
254
+ const priors = readDiscoveredEndpointSlots();
255
+ const capacities = {};
256
+ for (const status of statuses) foldCapacity(capacities, endpointCapacityForStatus(status, priors));
257
+ return capacities;
258
+ }
259
+ function resolveEndpointCapacities(input) {
260
+ const priors = readDiscoveredEndpointSlots();
261
+ const capacities = {};
262
+ const covered = /* @__PURE__ */ new Set();
263
+ for (const status of input.statuses) {
264
+ covered.add(status.target.id);
265
+ foldCapacity(capacities, endpointCapacityForStatus(status, priors));
266
+ }
267
+ for (const target of input.targets ?? []) {
268
+ if (covered.has(target.id)) continue;
269
+ foldCapacity(
270
+ capacities,
271
+ endpointCapacityFor({ target, runtime: input.runtimeFor?.(target.runtime) ?? null }, priors)
272
+ );
273
+ }
274
+ return capacities;
275
+ }
276
+ function recordEndpointSlotsFromStatus(status, options) {
277
+ const key = canonicalEndpointKey(status.target);
278
+ const slots = positiveInteger(status.probeCapabilities?.parallelSlots);
279
+ const runtimeId = status.runtime?.id ?? status.target.runtime;
280
+ if (key === null || slots === void 0 || runtimeId === void 0) return Promise.resolve();
281
+ return recordDiscoveredEndpointSlots({ endpointKey: key, runtimeId, slots }, options);
282
+ }
283
+ var foregroundStreams = /* @__PURE__ */ new Map();
284
+ function registerForegroundStream(endpointKey) {
285
+ foregroundStreams.set(endpointKey, (foregroundStreams.get(endpointKey) ?? 0) + 1);
286
+ let held = true;
287
+ return () => {
288
+ if (!held) return;
289
+ held = false;
290
+ const next = (foregroundStreams.get(endpointKey) ?? 1) - 1;
291
+ if (next <= 0) foregroundStreams.delete(endpointKey);
292
+ else foregroundStreams.set(endpointKey, next);
293
+ };
294
+ }
295
+ function foregroundStreamUsage() {
296
+ return Object.fromEntries(foregroundStreams);
297
+ }
298
+
80
299
  // src/engine/apis/residency.ts
81
300
  init_esm_shims();
82
301
 
83
302
  // src/engine/apis/residency-lock.ts
84
303
  init_esm_shims();
85
- import { join } from "node:path";
304
+ import { join as join2 } from "node:path";
86
305
  var LOCK_WAIT_MS = 12e4;
87
306
  function lockTargetFor(targetKey) {
88
- return join(clioStatePath(), "residency-locks", targetKey.replace(/[^a-zA-Z0-9._-]+/g, "_"));
307
+ const key = canonicalEndpointKey(targetKey) ?? targetKey;
308
+ return join2(clioStatePath(), "residency-locks", key.replace(/[^a-zA-Z0-9._-]+/g, "_"));
89
309
  }
90
310
  async function withResidencyLock(targetKey, fn) {
91
311
  return withStateFileLock(lockTargetFor(targetKey), fn, {
@@ -114,6 +334,9 @@ function emitResidencyNotice(notice) {
114
334
  } catch {
115
335
  }
116
336
  }
337
+ function emitResidencyMutation(mutation) {
338
+ getSharedBus().emit(BusChannels.ResidencyMutation, { ...mutation, at: Date.now() });
339
+ }
117
340
  var protectedModelsProvider = null;
118
341
  function setProtectedModelsProvider(provider) {
119
342
  protectedModelsProvider = provider;
@@ -344,6 +567,13 @@ async function restoreEvictedModels(adapter, evicted, loadError) {
344
567
  try {
345
568
  await adapter.reloadEvicted(entry.modelId);
346
569
  restored.push(entry.modelId);
570
+ emitResidencyMutation({
571
+ targetKey: adapter.targetKey,
572
+ targetId: adapter.targetId,
573
+ runtimeId: adapter.runtimeId,
574
+ model: entry.modelId,
575
+ operation: "load"
576
+ });
347
577
  } catch {
348
578
  failed.push(entry.modelId);
349
579
  }
@@ -460,12 +690,28 @@ async function reconcileResidency(adapter) {
460
690
  await adapter.unload(entry.modelId);
461
691
  forgetClioLoaded(adapter.targetKey, entry.modelId);
462
692
  evicted.push(entry);
693
+ emitResidencyMutation({
694
+ targetKey: adapter.targetKey,
695
+ targetId: adapter.targetId,
696
+ runtimeId: adapter.runtimeId,
697
+ model: entry.modelId,
698
+ operation: "evict"
699
+ });
463
700
  } catch {
464
701
  }
465
702
  }
466
703
  if (!adapter.load) return;
467
704
  try {
468
705
  await adapter.load(adapter.keepModelId);
706
+ if (!plan.keepResident) {
707
+ emitResidencyMutation({
708
+ targetKey: adapter.targetKey,
709
+ targetId: adapter.targetId,
710
+ runtimeId: adapter.runtimeId,
711
+ model: adapter.keepModelId,
712
+ operation: "load"
713
+ });
714
+ }
469
715
  } catch (error) {
470
716
  await restoreEvictedModels(adapter, evicted, error);
471
717
  throw error;
@@ -796,6 +1042,13 @@ function harmonyReasoningEffort(level) {
796
1042
  if (level === "medium") return "medium";
797
1043
  return "low";
798
1044
  }
1045
+ var MEMORY_ALWAYS_ON_MODEL_MIN_OUTPUT_TOKENS = 4e3;
1046
+ function memoryInterventionModelMaxTokens(input) {
1047
+ const configured = Number.isSafeInteger(input.configuredMaxTokens) && input.configuredMaxTokens > 0 ? input.configuredMaxTokens : 1;
1048
+ const requested = input.thinkingMechanism === "always-on" ? Math.max(configured * 2, MEMORY_ALWAYS_ON_MODEL_MIN_OUTPUT_TOKENS) : configured;
1049
+ const modelCap = input.modelMaxTokens;
1050
+ return typeof modelCap === "number" && Number.isSafeInteger(modelCap) && modelCap > 0 ? Math.min(requested, modelCap) : requested;
1051
+ }
799
1052
  function reasoningClassForMechanism(mechanism) {
800
1053
  if (mechanism === "none") return "never";
801
1054
  if (mechanism === "always-on") return "always";
@@ -1186,6 +1439,91 @@ function resolveTargetRuntimeCapabilities(target, runtime, wireModelId, capabili
1186
1439
  });
1187
1440
  }
1188
1441
 
1442
+ // src/domains/providers/target-model-cache.ts
1443
+ init_esm_shims();
1444
+ import { createHash } from "node:crypto";
1445
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
1446
+ import { join as join3 } from "node:path";
1447
+ var TARGET_MODEL_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
1448
+ var TARGET_MODEL_CACHE_VERSION = 1;
1449
+ var TARGET_MODEL_CACHE_MAX_MODELS = 4096;
1450
+ var TARGET_MODEL_CACHE_MAX_MODEL_ID_CHARS = 1024;
1451
+ function targetCacheKey(targetId) {
1452
+ return createHash("sha256").update(targetId).digest("hex").slice(0, 24);
1453
+ }
1454
+ function targetModelSnapshotPath(targetId, cacheDir = clioCacheDir()) {
1455
+ return join3(cacheDir, "provider-target-models", `${targetCacheKey(targetId)}.json`);
1456
+ }
1457
+ function normalizedModels(models) {
1458
+ const seen = /* @__PURE__ */ new Set();
1459
+ const out = [];
1460
+ for (const raw of models) {
1461
+ const model = raw.trim();
1462
+ if (model.length === 0 || model.length > TARGET_MODEL_CACHE_MAX_MODEL_ID_CHARS || seen.has(model)) continue;
1463
+ seen.add(model);
1464
+ out.push(model);
1465
+ if (out.length >= TARGET_MODEL_CACHE_MAX_MODELS) break;
1466
+ }
1467
+ return out;
1468
+ }
1469
+ function parseSnapshot(value) {
1470
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
1471
+ const row = value;
1472
+ if (row.version !== TARGET_MODEL_CACHE_VERSION) return null;
1473
+ if (typeof row.targetId !== "string" || row.targetId.length === 0) return null;
1474
+ if (typeof row.runtimeId !== "string" || row.runtimeId.length === 0) return null;
1475
+ if (row.url !== null && typeof row.url !== "string") return null;
1476
+ if (!Array.isArray(row.models) || row.models.some((model) => typeof model !== "string")) return null;
1477
+ if (typeof row.observedAt !== "string" || !Number.isFinite(Date.parse(row.observedAt))) return null;
1478
+ const models = normalizedModels(row.models);
1479
+ if (models.length !== row.models.length) return null;
1480
+ return {
1481
+ version: TARGET_MODEL_CACHE_VERSION,
1482
+ targetId: row.targetId,
1483
+ runtimeId: row.runtimeId,
1484
+ url: row.url,
1485
+ models,
1486
+ observedAt: row.observedAt
1487
+ };
1488
+ }
1489
+ function readTargetModelSnapshot(target, options = {}) {
1490
+ const path = targetModelSnapshotPath(target.id, options.cacheDir);
1491
+ if (!existsSync2(path)) return null;
1492
+ try {
1493
+ const snapshot = parseSnapshot(JSON.parse(readFileSync2(path, "utf8")));
1494
+ if (snapshot === null) return null;
1495
+ if (snapshot.targetId !== target.id || snapshot.runtimeId !== target.runtime) return null;
1496
+ if (snapshot.url !== (target.url ?? null)) return null;
1497
+ const observedMs = Date.parse(snapshot.observedAt);
1498
+ const nowMs = options.nowMs ?? Date.now();
1499
+ const ttlMs = options.ttlMs ?? TARGET_MODEL_CACHE_TTL_MS;
1500
+ if (observedMs > nowMs || nowMs - observedMs >= ttlMs) return null;
1501
+ return snapshot;
1502
+ } catch {
1503
+ return null;
1504
+ }
1505
+ }
1506
+ function recordTargetModelSnapshot(target, models, options = {}) {
1507
+ if (target.id.length === 0 || target.runtime.length === 0) return false;
1508
+ const snapshot = {
1509
+ version: TARGET_MODEL_CACHE_VERSION,
1510
+ targetId: target.id,
1511
+ runtimeId: target.runtime,
1512
+ url: target.url ?? null,
1513
+ models: normalizedModels(models),
1514
+ observedAt: new Date(options.nowMs ?? Date.now()).toISOString()
1515
+ };
1516
+ try {
1517
+ safeResourceWrite(targetModelSnapshotPath(target.id, options.cacheDir), `${JSON.stringify(snapshot, null, 2)}
1518
+ `, {
1519
+ encoding: "utf8"
1520
+ });
1521
+ return true;
1522
+ } catch {
1523
+ return false;
1524
+ }
1525
+ }
1526
+
1189
1527
  // src/domains/providers/eligibility.ts
1190
1528
  init_esm_shims();
1191
1529
  function isTargetEligibleRuntime(runtime) {
@@ -1291,6 +1629,105 @@ function canonicalizeWireModelId(status, requested) {
1291
1629
  return matches.length === 1 ? matches[0] ?? requested : requested;
1292
1630
  }
1293
1631
 
1632
+ // src/domains/providers/resolver.ts
1633
+ init_esm_shims();
1634
+ var GLOB_CHARS = /[*?[]/;
1635
+ function isThinkingLevel(token) {
1636
+ return VALID_THINKING_LEVELS.includes(token);
1637
+ }
1638
+ function splitThinkingSuffix(pattern) {
1639
+ const idx = pattern.lastIndexOf(":");
1640
+ if (idx === -1) return { base: pattern };
1641
+ const suffix = pattern.slice(idx + 1).trim();
1642
+ if (!isThinkingLevel(suffix)) return { base: pattern };
1643
+ const base = pattern.slice(0, idx).trim();
1644
+ return base ? { base, thinkingLevel: suffix } : { base: pattern };
1645
+ }
1646
+ function globToRegExp(glob) {
1647
+ let body = "^";
1648
+ for (let i = 0; i < glob.length; i++) {
1649
+ const ch = glob[i] ?? "";
1650
+ if (ch === "*") {
1651
+ body += ".*";
1652
+ } else if (ch === "?") {
1653
+ body += ".";
1654
+ } else if (ch === "[") {
1655
+ const close = glob.indexOf("]", i + 1);
1656
+ if (close === -1) {
1657
+ body += "\\[";
1658
+ continue;
1659
+ }
1660
+ body += `[${glob.slice(i + 1, close)}]`;
1661
+ i = close;
1662
+ } else if (/[.+^${}()|\\]/.test(ch)) {
1663
+ body += `\\${ch}`;
1664
+ } else {
1665
+ body += ch;
1666
+ }
1667
+ }
1668
+ body += "$";
1669
+ return new RegExp(body, "i");
1670
+ }
1671
+ function collectCandidates(providers) {
1672
+ const out = [];
1673
+ const seen = /* @__PURE__ */ new Set();
1674
+ for (const status of providers.list()) {
1675
+ for (const model of modelIdsForStatus(status)) {
1676
+ const key = `${status.target.id}/${model}`;
1677
+ if (seen.has(key)) continue;
1678
+ seen.add(key);
1679
+ out.push({ target: status.target.id, model, full: key });
1680
+ }
1681
+ }
1682
+ return out;
1683
+ }
1684
+ function pickFirst(candidates) {
1685
+ if (candidates.length === 0) return null;
1686
+ const head = candidates[0];
1687
+ if (!head) return null;
1688
+ return { ref: head, ambiguous: candidates.length > 1 };
1689
+ }
1690
+ function buildResult(pattern, pick, thinkingLevel) {
1691
+ if (!pick) {
1692
+ return { ref: null, error: `no models match pattern "${pattern}"` };
1693
+ }
1694
+ const ref = { target: pick.ref.target, model: pick.ref.model };
1695
+ if (thinkingLevel) ref.thinkingLevel = thinkingLevel;
1696
+ const result = { ref };
1697
+ if (pick.ambiguous) {
1698
+ result.warning = `pattern "${pattern}" matched multiple models; using ${pick.ref.full}`;
1699
+ }
1700
+ return result;
1701
+ }
1702
+ function resolveModelReference(rawPattern, providers) {
1703
+ const trimmed = rawPattern.trim();
1704
+ if (!trimmed) return { ref: null, error: "empty pattern" };
1705
+ const { base, thinkingLevel } = splitThinkingSuffix(trimmed);
1706
+ const candidates = collectCandidates(providers);
1707
+ if (candidates.length === 0) {
1708
+ return { ref: null, error: "no targets configured; add one with `clio-coder configure` or `clio-coder targets add`" };
1709
+ }
1710
+ const lower = base.toLowerCase();
1711
+ const exactFull = candidates.filter((c) => c.full.toLowerCase() === lower);
1712
+ if (exactFull.length > 0) return buildResult(base, pickFirst(exactFull), thinkingLevel);
1713
+ if (GLOB_CHARS.test(base)) {
1714
+ const re = globToRegExp(base);
1715
+ const globMatches = candidates.filter((c) => re.test(c.full) || re.test(c.model));
1716
+ return buildResult(base, pickFirst(globMatches), thinkingLevel);
1717
+ }
1718
+ const slashIdx = base.indexOf("/");
1719
+ if (slashIdx !== -1) {
1720
+ const ep = base.slice(0, slashIdx).toLowerCase();
1721
+ const mdl = base.slice(slashIdx + 1).toLowerCase();
1722
+ const epModel = candidates.filter((c) => c.target.toLowerCase() === ep && c.model.toLowerCase() === mdl);
1723
+ if (epModel.length > 0) return buildResult(base, pickFirst(epModel), thinkingLevel);
1724
+ }
1725
+ const exactModel = candidates.filter((c) => c.model.toLowerCase() === lower);
1726
+ if (exactModel.length > 0) return buildResult(base, pickFirst(exactModel), thinkingLevel);
1727
+ const partial = candidates.filter((c) => c.model.toLowerCase().includes(lower));
1728
+ return buildResult(base, pickFirst(partial), thinkingLevel);
1729
+ }
1730
+
1294
1731
  // src/domains/providers/runtime-resolution.ts
1295
1732
  init_esm_shims();
1296
1733
  function diagnostic(severity, code, message) {
@@ -1477,7 +1914,7 @@ function resolveRuntimeTarget(providers, input) {
1477
1914
  const capabilityResolution = modelCapabilitiesFor(providers, status, wireModelId);
1478
1915
  const capabilities = { ...capabilityResolution.capabilities };
1479
1916
  const probedContextWindow = probeCapabilitiesForModel(status, wireModelId)?.contextWindow ?? null;
1480
- const loadedContextWindow = loadedContextWindowForModel(status, wireModelId);
1917
+ const loadedContextWindow = loadedContextWindowForModel(status, wireModelId) ?? input.knownLoadedContextWindow ?? null;
1481
1918
  const contextWindowDetails = resolveContextWindowDetails(
1482
1919
  target,
1483
1920
  runtime,
@@ -1705,6 +2142,12 @@ function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase
1705
2142
  };
1706
2143
  }
1707
2144
 
2145
+ // src/domains/providers/types/cost-provenance.ts
2146
+ init_esm_shims();
2147
+ function normalizeCostProvenance(value) {
2148
+ return value ?? "unknown";
2149
+ }
2150
+
1708
2151
  // src/domains/providers/index.ts
1709
2152
  init_esm_shims();
1710
2153
 
@@ -1722,6 +2165,18 @@ import {
1722
2165
  Ollama
1723
2166
  } from "ollama";
1724
2167
 
2168
+ // src/core/residency-target-key.ts
2169
+ init_esm_shims();
2170
+ var RESIDENCY_RUNTIME_IDS = /* @__PURE__ */ new Set([
2171
+ "llamacpp",
2172
+ "lmstudio",
2173
+ "ollama-native"
2174
+ ]);
2175
+ function residencyTargetKey(runtimeId, baseUrl) {
2176
+ if (!RESIDENCY_RUNTIME_IDS.has(runtimeId) || typeof baseUrl !== "string") return null;
2177
+ return canonicalEndpointUrl(baseUrl) ?? baseUrl;
2178
+ }
2179
+
1725
2180
  // src/engine/gemma-channel-filter.ts
1726
2181
  init_esm_shims();
1727
2182
  import { createAssistantMessageEventStream } from "@earendil-works/pi-ai";
@@ -1991,7 +2446,7 @@ async function reconcileOllamaResidency(model, headers) {
1991
2446
  if (!baseUrl) return;
1992
2447
  const metadata2 = model.clio;
1993
2448
  const adapter = {
1994
- targetKey: `ollama-native|${baseUrl}`,
2449
+ targetKey: residencyTargetKey("ollama-native", baseUrl),
1995
2450
  targetId: ollamaTargetId(model),
1996
2451
  runtimeId: "ollama-native",
1997
2452
  keepModelId: model.id,
@@ -2559,6 +3014,26 @@ async function fetchRouterModels(input, fetchImpl) {
2559
3014
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
2560
3015
  return parseRouterModels(await response.json());
2561
3016
  }
3017
+ var RouterModelPostError = class extends Error {
3018
+ constructor(url, status, responseBody) {
3019
+ super(`llama.cpp router rejected ${url}: HTTP ${status}; response: ${responseBody}`);
3020
+ this.url = url;
3021
+ this.status = status;
3022
+ this.responseBody = responseBody;
3023
+ this.name = "RouterModelPostError";
3024
+ }
3025
+ url;
3026
+ status;
3027
+ responseBody;
3028
+ };
3029
+ async function routerErrorBody(response) {
3030
+ try {
3031
+ const body = (await response.text()).trim();
3032
+ return body.length > 0 ? body : "<empty body>";
3033
+ } catch (error) {
3034
+ return `<unreadable body: ${error instanceof Error ? error.message : String(error)}>`;
3035
+ }
3036
+ }
2562
3037
  async function postRouterModel(fetchImpl, url, modelId) {
2563
3038
  const response = await fetchImpl(url, {
2564
3039
  method: "POST",
@@ -2567,7 +3042,27 @@ async function postRouterModel(fetchImpl, url, modelId) {
2567
3042
  signal: AbortSignal.timeout(LOAD_TIMEOUT_MS)
2568
3043
  });
2569
3044
  if (response.ok) return;
2570
- throw new Error(`llama.cpp router rejected ${url}: HTTP ${response.status}`);
3045
+ throw new RouterModelPostError(url, response.status, await routerErrorBody(response));
3046
+ }
3047
+ function alreadyRunningResponse(body) {
3048
+ return body.toLowerCase().includes("already running");
3049
+ }
3050
+ async function postRouterLoad(input, fetchImpl, modelId) {
3051
+ try {
3052
+ await postRouterModel(fetchImpl, loadUrl(input.baseUrl), modelId);
3053
+ } catch (error) {
3054
+ if (!(error instanceof RouterModelPostError)) throw error;
3055
+ let model;
3056
+ try {
3057
+ model = (await fetchRouterModels(input, fetchImpl)).find((entry) => entry.id === modelId);
3058
+ } catch {
3059
+ if (alreadyRunningResponse(error.responseBody)) return;
3060
+ throw error;
3061
+ }
3062
+ if (alreadyRunningResponse(error.responseBody)) return;
3063
+ if (model !== void 0 && model.state !== "unloaded" && model.state !== "failed") return;
3064
+ throw error;
3065
+ }
2571
3066
  }
2572
3067
  async function waitForLoaded(input, fetchImpl, modelId) {
2573
3068
  const started = performance.now();
@@ -2582,7 +3077,7 @@ async function waitForLoaded(input, fetchImpl, modelId) {
2582
3077
  }
2583
3078
  async function ensureModelLoaded(input, fetchImpl, modelId, knownState) {
2584
3079
  if (knownState === "loaded" || knownState === "sleeping") return;
2585
- if (knownState !== "loading") await postRouterModel(fetchImpl, loadUrl(input.baseUrl), modelId);
3080
+ if (knownState !== "loading") await postRouterLoad(input, fetchImpl, modelId);
2586
3081
  await waitForLoaded(input, fetchImpl, modelId);
2587
3082
  }
2588
3083
  async function restoreDisplacedPinned(input, fetchImpl, before) {
@@ -2609,7 +3104,7 @@ async function ensureLlamaCppResidency(input) {
2609
3104
  const fetchImpl = input.fetchImpl ?? fetch;
2610
3105
  let snapshot = [];
2611
3106
  const adapter = {
2612
- targetKey: `llamacpp|${input.baseUrl}`,
3107
+ targetKey: residencyTargetKey("llamacpp", input.baseUrl),
2613
3108
  targetId: input.targetId,
2614
3109
  runtimeId: input.runtimeId,
2615
3110
  keepModelId: input.keepModelId,
@@ -2809,7 +3304,7 @@ async function ensureLmStudioResidency(model, options = {}) {
2809
3304
  (entry) => entry.loadedInstances.map((instance) => ({ modelKey: entry.key, identifier: instance.id, instance }))
2810
3305
  );
2811
3306
  const managed = residencyManagedFor(info.lifecycle);
2812
- const targetKey = `lmstudio|${lmStudioRootUrl(target.url ?? model.baseUrl)}`;
3307
+ const targetKey = residencyTargetKey("lmstudio", target.url ?? model.baseUrl);
2813
3308
  const contextLength = target.lmstudio?.load?.contextLength;
2814
3309
  const plan = await reconcileResidency({
2815
3310
  targetKey,
@@ -2852,17 +3347,36 @@ async function ensureLmStudioResidency(model, options = {}) {
2852
3347
  });
2853
3348
  }
2854
3349
  }
3350
+ const loadAndReport = async () => {
3351
+ const instanceId = await loadOwnedInstance(target, targetKey, body, options.apiKey, options.signal);
3352
+ emitResidencyMutation({
3353
+ targetKey,
3354
+ targetId: info.targetId,
3355
+ runtimeId: "lmstudio",
3356
+ model: modelKey,
3357
+ operation: "load"
3358
+ });
3359
+ return instanceId ?? model.id;
3360
+ };
2855
3361
  try {
2856
- return await loadOwnedInstance(target, targetKey, body, options.apiKey, options.signal) ?? model.id;
3362
+ return await loadAndReport();
2857
3363
  } catch (error) {
2858
3364
  if (plan.decision === "observe" || plan.fallbackEvict.length === 0) throw error;
2859
3365
  return withResidencyLock(targetKey, async () => {
2860
3366
  for (const candidate of plan.fallbackEvict) {
2861
3367
  for (const entry of instances.filter((resident) => resident.modelKey === candidate.modelId)) {
2862
- await unloadOwnedInstance(target, targetKey, entry.identifier, options.apiKey, options.signal);
3368
+ if (await unloadOwnedInstance(target, targetKey, entry.identifier, options.apiKey, options.signal)) {
3369
+ emitResidencyMutation({
3370
+ targetKey,
3371
+ targetId: info.targetId,
3372
+ runtimeId: "lmstudio",
3373
+ model: candidate.modelId,
3374
+ operation: "evict"
3375
+ });
3376
+ }
2863
3377
  }
2864
3378
  }
2865
- return await loadOwnedInstance(target, targetKey, body, options.apiKey, options.signal) ?? model.id;
3379
+ return loadAndReport();
2866
3380
  });
2867
3381
  }
2868
3382
  }
@@ -2884,8 +3398,36 @@ function pickSamplingProfile2(quirks, thinkingActive) {
2884
3398
  function isPlainRecord(value) {
2885
3399
  return value !== null && typeof value === "object" && !Array.isArray(value);
2886
3400
  }
2887
- function observeResponseModelIdLine(line, capture) {
2888
- if (capture.done) return;
3401
+ function nonnegativeFiniteNumber(value) {
3402
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
3403
+ }
3404
+ function backendCompletionTimings(value, source) {
3405
+ if (!isPlainRecord(value)) return null;
3406
+ const promptN = nonnegativeFiniteNumber(value.prompt_n);
3407
+ const predictedN = nonnegativeFiniteNumber(value.predicted_n);
3408
+ const promptMs = nonnegativeFiniteNumber(value.prompt_ms);
3409
+ const predictedMs = nonnegativeFiniteNumber(value.predicted_ms);
3410
+ if (promptN === null || predictedN === null || promptMs === null || predictedMs === null) return null;
3411
+ const cacheN = nonnegativeFiniteNumber(value.cache_n);
3412
+ return {
3413
+ promptTokens: promptN + (cacheN ?? 0),
3414
+ cachedTokens: cacheN,
3415
+ predictedTokens: predictedN,
3416
+ promptMs,
3417
+ predictedMs,
3418
+ source
3419
+ };
3420
+ }
3421
+ function backendTimingsSourceForModel(model) {
3422
+ const metadata2 = model.clio;
3423
+ if (model.provider === "llamacpp" && metadata2?.runtimeId === "llamacpp") return "llamacpp-timings";
3424
+ if (model.provider === "lmstudio" && metadata2?.runtimeId === "lmstudio") return "lmstudio-timings";
3425
+ return null;
3426
+ }
3427
+ function captureCanStopEarly(capture) {
3428
+ return capture.modelIdDone && capture.backendTimingsSource === null;
3429
+ }
3430
+ function observeResponseMetadataLine(line, capture) {
2889
3431
  const normalized = line.endsWith("\r") ? line.slice(0, -1) : line;
2890
3432
  if (!normalized.startsWith("data:")) return;
2891
3433
  const data = normalized.slice("data:".length).trimStart();
@@ -2893,23 +3435,29 @@ function observeResponseModelIdLine(line, capture) {
2893
3435
  try {
2894
3436
  const payload = JSON.parse(data);
2895
3437
  if (!isPlainRecord(payload)) return;
2896
- const model = payload.model;
2897
- if (typeof model === "string" && model.trim().length > 0) {
2898
- capture.reportedModelId = model.trim();
2899
- capture.done = true;
3438
+ if (!capture.modelIdDone) {
3439
+ const model = payload.model;
3440
+ if (typeof model === "string" && model.trim().length > 0) {
3441
+ capture.reportedModelId = model.trim();
3442
+ capture.modelIdDone = true;
3443
+ }
3444
+ }
3445
+ if (capture.backendTimingsSource !== null) {
3446
+ const timings = backendCompletionTimings(payload.timings, capture.backendTimingsSource);
3447
+ if (timings !== null) capture.backendTimings = timings;
2900
3448
  }
2901
3449
  } catch {
2902
3450
  }
2903
3451
  }
2904
3452
  function observeResponseModelIdBytes(chunk, capture, flush = false) {
2905
- if (capture.done || !capture.decoder) return;
3453
+ if (!capture.decoder) return;
2906
3454
  capture.buffer += chunk ? capture.decoder.decode(chunk, { stream: !flush }) : capture.decoder.decode();
2907
3455
  let newline = capture.buffer.indexOf("\n");
2908
3456
  while (newline >= 0) {
2909
3457
  const line = capture.buffer.slice(0, newline);
2910
3458
  capture.buffer = capture.buffer.slice(newline + 1);
2911
- observeResponseModelIdLine(line, capture);
2912
- if (capture.done) {
3459
+ observeResponseMetadataLine(line, capture);
3460
+ if (captureCanStopEarly(capture)) {
2913
3461
  capture.buffer = "";
2914
3462
  capture.decoder = null;
2915
3463
  return;
@@ -2917,10 +3465,10 @@ function observeResponseModelIdBytes(chunk, capture, flush = false) {
2917
3465
  newline = capture.buffer.indexOf("\n");
2918
3466
  }
2919
3467
  if (flush && capture.buffer.length > 0) {
2920
- observeResponseModelIdLine(capture.buffer, capture);
3468
+ observeResponseMetadataLine(capture.buffer, capture);
2921
3469
  capture.buffer = "";
2922
3470
  }
2923
- if (capture.done || flush) capture.decoder = null;
3471
+ if (captureCanStopEarly(capture) || flush) capture.decoder = null;
2924
3472
  }
2925
3473
  function captureResponseModelId(response, capture) {
2926
3474
  if (!response.body || !response.headers.get("content-type")?.toLowerCase().includes("text/event-stream")) {
@@ -2930,12 +3478,12 @@ function captureResponseModelId(response, capture) {
2930
3478
  new TransformStream({
2931
3479
  transform(chunk, controller) {
2932
3480
  capture.observed = true;
2933
- if (!capture.done) observeResponseModelIdBytes(chunk, capture);
3481
+ observeResponseModelIdBytes(chunk, capture);
2934
3482
  controller.enqueue(chunk);
2935
3483
  },
2936
3484
  flush() {
2937
3485
  capture.observed = true;
2938
- if (!capture.done) observeResponseModelIdBytes(void 0, capture, true);
3486
+ observeResponseModelIdBytes(void 0, capture, true);
2939
3487
  }
2940
3488
  })
2941
3489
  );
@@ -2945,11 +3493,13 @@ function captureResponseModelId(response, capture) {
2945
3493
  headers: response.headers
2946
3494
  });
2947
3495
  }
2948
- function withResponseModelIdCapture(options, sourceFactory) {
3496
+ function withResponseModelIdCapture(model, options, sourceFactory) {
2949
3497
  const capture = {
2950
3498
  reportedModelId: null,
2951
3499
  observed: false,
2952
- done: false,
3500
+ modelIdDone: false,
3501
+ backendTimings: null,
3502
+ backendTimingsSource: backendTimingsSourceForModel(model),
2953
3503
  buffer: "",
2954
3504
  decoder: new TextDecoder()
2955
3505
  };
@@ -2964,8 +3514,13 @@ function withResponseModelIdCapture(options, sourceFactory) {
2964
3514
  try {
2965
3515
  for await (const event of source) {
2966
3516
  const observation = capture.observed ? capture.reportedModelId === null ? { state: "not-reported" } : { state: "reported", reportedModelId: capture.reportedModelId } : { state: "not-observed" };
2967
- if (event.type === "done") event.message.responseModelIdObservation = observation;
2968
- else if (event.type === "error") event.error.responseModelIdObservation = observation;
3517
+ if (event.type === "done") {
3518
+ event.message.responseModelIdObservation = observation;
3519
+ if (capture.backendTimings !== null) event.message.backendTimings = capture.backendTimings;
3520
+ } else if (event.type === "error") {
3521
+ event.error.responseModelIdObservation = observation;
3522
+ if (capture.backendTimings !== null) event.error.backendTimings = capture.backendTimings;
3523
+ }
2969
3524
  annotated.push(event);
2970
3525
  }
2971
3526
  annotated.end();
@@ -3460,6 +4015,7 @@ var openAICompletionsApiProvider = {
3460
4015
  stripNeverReasoningFromStream(
3461
4016
  filterGemmaChannelStream(
3462
4017
  withResponseModelIdCapture(
4018
+ model,
3463
4019
  withRemainingContextBudget(model, effectiveContext, withSamplers),
3464
4020
  (capturedOptions) => withLocalResidency(
3465
4021
  model,
@@ -3491,6 +4047,7 @@ var openAICompletionsApiProvider = {
3491
4047
  stripNeverReasoningFromStream(
3492
4048
  filterGemmaChannelStream(
3493
4049
  withResponseModelIdCapture(
4050
+ model,
3494
4051
  withRemainingContextBudget(model, effectiveContext, withSamplers),
3495
4052
  (capturedOptions) => withLocalResidency(
3496
4053
  model,
@@ -3525,8 +4082,8 @@ function registerClioApiProviders() {
3525
4082
 
3526
4083
  // src/domains/providers/knowledge-base-path.ts
3527
4084
  init_esm_shims();
3528
- import { existsSync, statSync } from "node:fs";
3529
- import { delimiter, dirname, join as join2 } from "node:path";
4085
+ import { existsSync as existsSync3, statSync } from "node:fs";
4086
+ import { delimiter, dirname, join as join4 } from "node:path";
3530
4087
  import { fileURLToPath } from "node:url";
3531
4088
  var MODEL_CATALOG_OVERLAY_DIR = "model-catalog.d";
3532
4089
  var MODEL_CATALOG_DIRS_ENV = "CLIO_CODER_MODEL_CATALOG_DIRS";
@@ -3540,19 +4097,19 @@ function isDirectory(path) {
3540
4097
  function resolveProvidersModelsDir(importMetaUrl) {
3541
4098
  const start = dirname(fileURLToPath(importMetaUrl));
3542
4099
  const directCandidates = [
3543
- join2(start, "models"),
3544
- join2(start, "..", "domains", "providers", "models"),
3545
- join2(start, "..", "providers-models")
4100
+ join4(start, "models"),
4101
+ join4(start, "..", "domains", "providers", "models"),
4102
+ join4(start, "..", "providers-models")
3546
4103
  ];
3547
4104
  for (const candidate of directCandidates) {
3548
4105
  if (isDirectory(candidate)) return candidate;
3549
4106
  }
3550
4107
  let cursor = start;
3551
4108
  for (let i = 0; i < 8; i++) {
3552
- const packageJson = join2(cursor, "package.json");
3553
- const sourceModels = join2(cursor, "src", "domains", "providers", "models");
3554
- const distModels = join2(cursor, "dist", "providers-models");
3555
- if (existsSync(packageJson)) {
4109
+ const packageJson = join4(cursor, "package.json");
4110
+ const sourceModels = join4(cursor, "src", "domains", "providers", "models");
4111
+ const distModels = join4(cursor, "dist", "providers-models");
4112
+ if (existsSync3(packageJson)) {
3556
4113
  if (isDirectory(sourceModels)) return sourceModels;
3557
4114
  if (isDirectory(distModels)) return distModels;
3558
4115
  }
@@ -3582,8 +4139,8 @@ function resolveProviderModelCatalogDirs(importMetaUrl, options = {}) {
3582
4139
  const bundled = resolveProvidersModelsDir(importMetaUrl);
3583
4140
  const cwd = options.cwd ?? process.cwd();
3584
4141
  const overlays = uniqueExistingDirs([
3585
- join2(resolveClioDirs().config, MODEL_CATALOG_OVERLAY_DIR),
3586
- join2(cwd, ".clio-coder", MODEL_CATALOG_OVERLAY_DIR),
4142
+ join4(resolveClioDirs().config, MODEL_CATALOG_OVERLAY_DIR),
4143
+ join4(cwd, ".clio-coder", MODEL_CATALOG_OVERLAY_DIR),
3587
4144
  ...envOverlayDirs()
3588
4145
  ]);
3589
4146
  return {
@@ -3602,7 +4159,7 @@ function resolveProviderKnowledgeBaseRoots(importMetaUrl, options = {}) {
3602
4159
 
3603
4160
  // src/domains/providers/plugins.ts
3604
4161
  init_esm_shims();
3605
- import { join as join3 } from "node:path";
4162
+ import { join as join5 } from "node:path";
3606
4163
  function extractPluginPackages(settings) {
3607
4164
  if (!settings || typeof settings !== "object") return [];
3608
4165
  const raw = settings.runtimePlugins;
@@ -3611,7 +4168,7 @@ function extractPluginPackages(settings) {
3611
4168
  }
3612
4169
  async function loadPluginRuntimes(registry, settings) {
3613
4170
  const loaded = [];
3614
- const pluginDir = join3(clioConfigDir(), "runtimes");
4171
+ const pluginDir = join5(clioConfigDir(), "runtimes");
3615
4172
  const packages = extractPluginPackages(settings);
3616
4173
  try {
3617
4174
  const ids = await registry.loadFromDir(pluginDir, activateExternalPluginApiBridge);
@@ -3639,8 +4196,8 @@ async function loadPluginRuntimes(registry, settings) {
3639
4196
  // src/domains/providers/types/knowledge-base.ts
3640
4197
  init_esm_shims();
3641
4198
  var import_yaml = __toESM(require_dist(), 1);
3642
- import { readdirSync, readFileSync, statSync as statSync2 } from "node:fs";
3643
- import { join as join4 } from "node:path";
4199
+ import { readdirSync, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
4200
+ import { join as join6 } from "node:path";
3644
4201
  var FileKnowledgeBase = class {
3645
4202
  roots;
3646
4203
  loaded = [];
@@ -3654,7 +4211,7 @@ var FileKnowledgeBase = class {
3654
4211
  const files = collectYamlFiles(root.dir);
3655
4212
  for (const file of files) {
3656
4213
  const name = root.label ? `${root.label}:${file.name}` : file.name;
3657
- const raw = readFileSync(file.path, "utf8");
4214
+ const raw = readFileSync3(file.path, "utf8");
3658
4215
  const parsed = (0, import_yaml.parse)(raw);
3659
4216
  if (!Array.isArray(parsed)) {
3660
4217
  throw new Error(`knowledge base file ${name} must be a YAML list of KnowledgeBaseEntry`);
@@ -3712,7 +4269,7 @@ function collectYamlFiles(dir, prefix = "") {
3712
4269
  const out = [];
3713
4270
  const entries = readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
3714
4271
  for (const entry of entries) {
3715
- const path = join4(dir, entry.name);
4272
+ const path = join6(dir, entry.name);
3716
4273
  const name = prefix ? `${prefix}/${entry.name}` : entry.name;
3717
4274
  if (entry.isDirectory()) {
3718
4275
  out.push(...collectYamlFiles(path, name));
@@ -3818,16 +4375,17 @@ function uniqueModels2(ids) {
3818
4375
  }
3819
4376
  return out;
3820
4377
  }
3821
- function discoveredModelsSource(probe, preservePreviousProbe, previous, desc) {
4378
+ function discoveredModelsSource(probe, preservePreviousProbe, previous, cachedModels, desc) {
3822
4379
  if (probe?.models !== void 0) return "probe";
3823
4380
  if (preservePreviousProbe && previous?.discoveredModels && previous.discoveredModels.length > 0) return "cache";
4381
+ if (cachedModels.length > 0) return "cache";
3824
4382
  if (desc.knownModels && desc.knownModels.length > 0) return "runtime";
3825
4383
  return "none";
3826
4384
  }
3827
4385
  function sameProbeIdentity(previous, next) {
3828
4386
  return previous.id === next.id && previous.runtime === next.runtime && (previous.url ?? "") === (next.url ?? "") && (previous.defaultModel ?? "") === (next.defaultModel ?? "");
3829
4387
  }
3830
- function mergeProbeResult(desc, target, probe, previous) {
4388
+ function mergeProbeResult(desc, target, probe, previous, cachedModels = []) {
3831
4389
  const probeSucceeded = probe?.ok ?? false;
3832
4390
  const preservePrevious = !probeSucceeded && previous !== void 0 && sameProbeIdentity(previous.target, target);
3833
4391
  const probeCapabilities = probe?.discoveredCapabilities ?? (preservePrevious ? previous.probeCapabilities : null) ?? null;
@@ -3836,12 +4394,12 @@ function mergeProbeResult(desc, target, probe, previous) {
3836
4394
  const probeNotes = probe?.notes && probe.notes.length > 0 ? probe.notes : preservePrevious ? previous.probeNotes : void 0;
3837
4395
  const probeSurfaces = probe?.surfaces ?? (preservePrevious ? previous.probeSurfaces : void 0);
3838
4396
  const discoveredModels = uniqueModels2(
3839
- probe?.models ?? (preservePrevious ? previous.discoveredModels : void 0) ?? desc.knownModels ?? []
4397
+ probe?.models ?? (preservePrevious ? previous.discoveredModels : void 0) ?? (cachedModels.length > 0 ? cachedModels : void 0) ?? desc.knownModels ?? []
3840
4398
  );
3841
4399
  const discoveredModelStates = probe?.modelStates ?? (preservePrevious ? previous.discoveredModelStates : null) ?? null;
3842
4400
  const merge = {
3843
4401
  discoveredModels,
3844
- discoveredModelsSource: discoveredModelsSource(probe, preservePrevious, previous, desc),
4402
+ discoveredModelsSource: discoveredModelsSource(probe, preservePrevious, previous, cachedModels, desc),
3845
4403
  discoveredModelStates,
3846
4404
  probeCapabilities,
3847
4405
  probeModelCapabilities,
@@ -3934,7 +4492,8 @@ function createProvidersBundle(context) {
3934
4492
  return out2;
3935
4493
  }
3936
4494
  const availability = availabilityFor(desc, target, authStatusFor);
3937
- const merge = mergeProbeResult(desc, target, probe, previous);
4495
+ const cachedModels = readTargetModelSnapshot(target)?.models ?? [];
4496
+ const merge = mergeProbeResult(desc, target, probe, previous, cachedModels);
3938
4497
  const { capabilities, contextWindowProvenance } = capabilitiesFor(desc, target, merge, kb);
3939
4498
  const healthy = probe !== null ? probe.ok : null;
3940
4499
  const unservedDefault = probe?.ok ? unservedDefaultModelReason(desc, target, merge) : null;
@@ -4022,6 +4581,10 @@ function createProvidersBundle(context) {
4022
4581
  }
4023
4582
  const status = buildStatus(target, desc, probeResult, previous);
4024
4583
  statuses.set(target.id, status);
4584
+ if (probeResult.ok && probeResult.models !== void 0) {
4585
+ recordTargetModelSnapshot(target, probeResult.models);
4586
+ }
4587
+ void recordEndpointSlotsFromStatus(status);
4025
4588
  context.bus.emit(BusChannels.ProviderHealth, { id: target.id, status });
4026
4589
  return status;
4027
4590
  }
@@ -4184,111 +4747,6 @@ var ProvidersManifest = {
4184
4747
  dependsOn: ["config"]
4185
4748
  };
4186
4749
 
4187
- // src/domains/providers/resolver.ts
4188
- init_esm_shims();
4189
- var GLOB_CHARS = /[*?[]/;
4190
- function isThinkingLevel(token) {
4191
- return VALID_THINKING_LEVELS.includes(token);
4192
- }
4193
- function splitThinkingSuffix(pattern) {
4194
- const idx = pattern.lastIndexOf(":");
4195
- if (idx === -1) return { base: pattern };
4196
- const suffix = pattern.slice(idx + 1).trim();
4197
- if (!isThinkingLevel(suffix)) return { base: pattern };
4198
- const base = pattern.slice(0, idx).trim();
4199
- return base ? { base, thinkingLevel: suffix } : { base: pattern };
4200
- }
4201
- function globToRegExp(glob) {
4202
- let body = "^";
4203
- for (let i = 0; i < glob.length; i++) {
4204
- const ch = glob[i] ?? "";
4205
- if (ch === "*") {
4206
- body += ".*";
4207
- } else if (ch === "?") {
4208
- body += ".";
4209
- } else if (ch === "[") {
4210
- const close = glob.indexOf("]", i + 1);
4211
- if (close === -1) {
4212
- body += "\\[";
4213
- continue;
4214
- }
4215
- body += `[${glob.slice(i + 1, close)}]`;
4216
- i = close;
4217
- } else if (/[.+^${}()|\\]/.test(ch)) {
4218
- body += `\\${ch}`;
4219
- } else {
4220
- body += ch;
4221
- }
4222
- }
4223
- body += "$";
4224
- return new RegExp(body, "i");
4225
- }
4226
- function collectCandidates(providers) {
4227
- const out = [];
4228
- const seen = /* @__PURE__ */ new Set();
4229
- for (const status of providers.list()) {
4230
- for (const model of modelIdsForStatus(status)) {
4231
- const key = `${status.target.id}/${model}`;
4232
- if (seen.has(key)) continue;
4233
- seen.add(key);
4234
- out.push({ target: status.target.id, model, full: key });
4235
- }
4236
- }
4237
- return out;
4238
- }
4239
- function pickFirst(candidates) {
4240
- if (candidates.length === 0) return null;
4241
- const head = candidates[0];
4242
- if (!head) return null;
4243
- return { ref: head, ambiguous: candidates.length > 1 };
4244
- }
4245
- function buildResult(pattern, pick, thinkingLevel) {
4246
- if (!pick) {
4247
- return { ref: null, error: `no models match pattern "${pattern}"` };
4248
- }
4249
- const ref = { target: pick.ref.target, model: pick.ref.model };
4250
- if (thinkingLevel) ref.thinkingLevel = thinkingLevel;
4251
- const result = { ref };
4252
- if (pick.ambiguous) {
4253
- result.warning = `pattern "${pattern}" matched multiple models; using ${pick.ref.full}`;
4254
- }
4255
- return result;
4256
- }
4257
- function resolveModelReference(rawPattern, providers) {
4258
- const trimmed = rawPattern.trim();
4259
- if (!trimmed) return { ref: null, error: "empty pattern" };
4260
- const { base, thinkingLevel } = splitThinkingSuffix(trimmed);
4261
- const candidates = collectCandidates(providers);
4262
- if (candidates.length === 0) {
4263
- return { ref: null, error: "no targets configured; add one with `clio-coder configure` or `clio-coder targets add`" };
4264
- }
4265
- const lower = base.toLowerCase();
4266
- const exactFull = candidates.filter((c) => c.full.toLowerCase() === lower);
4267
- if (exactFull.length > 0) return buildResult(base, pickFirst(exactFull), thinkingLevel);
4268
- if (GLOB_CHARS.test(base)) {
4269
- const re = globToRegExp(base);
4270
- const globMatches = candidates.filter((c) => re.test(c.full) || re.test(c.model));
4271
- return buildResult(base, pickFirst(globMatches), thinkingLevel);
4272
- }
4273
- const slashIdx = base.indexOf("/");
4274
- if (slashIdx !== -1) {
4275
- const ep = base.slice(0, slashIdx).toLowerCase();
4276
- const mdl = base.slice(slashIdx + 1).toLowerCase();
4277
- const epModel = candidates.filter((c) => c.target.toLowerCase() === ep && c.model.toLowerCase() === mdl);
4278
- if (epModel.length > 0) return buildResult(base, pickFirst(epModel), thinkingLevel);
4279
- }
4280
- const exactModel = candidates.filter((c) => c.model.toLowerCase() === lower);
4281
- if (exactModel.length > 0) return buildResult(base, pickFirst(exactModel), thinkingLevel);
4282
- const partial = candidates.filter((c) => c.model.toLowerCase().includes(lower));
4283
- return buildResult(base, pickFirst(partial), thinkingLevel);
4284
- }
4285
-
4286
- // src/domains/providers/types/cost-provenance.ts
4287
- init_esm_shims();
4288
- function normalizeCostProvenance(value) {
4289
- return value ?? "unknown";
4290
- }
4291
-
4292
4750
  // src/domains/providers/index.ts
4293
4751
  var ProvidersDomainModule = {
4294
4752
  manifest: ProvidersManifest,
@@ -4296,8 +4754,17 @@ var ProvidersDomainModule = {
4296
4754
  };
4297
4755
 
4298
4756
  export {
4757
+ residencyTargetKey,
4299
4758
  setGlobalDefaultMaxOutputTokens,
4300
4759
  resolveReservedOutputTokens,
4760
+ canonicalEndpointKey,
4761
+ endpointLabel,
4762
+ endpointCapacityFor,
4763
+ endpointCapacityForStatus,
4764
+ endpointCapacitiesForStatuses,
4765
+ resolveEndpointCapacities,
4766
+ registerForegroundStream,
4767
+ foregroundStreamUsage,
4301
4768
  setResidencyNoticeSink,
4302
4769
  setProtectedModelsProvider,
4303
4770
  withRunOverrides,
@@ -4306,6 +4773,7 @@ export {
4306
4773
  applyModelCapabilityPatch,
4307
4774
  probeCapabilitiesForModel,
4308
4775
  resolveModelCapabilities,
4776
+ memoryInterventionModelMaxTokens,
4309
4777
  thinkingLevelChoiceLabel,
4310
4778
  thinkingLevelFromChoiceLabel,
4311
4779
  resolveModelRuntimeCapabilitiesForProviders,
@@ -4313,6 +4781,8 @@ export {
4313
4781
  registerClioApiProviders,
4314
4782
  resolveProviderKnowledgeBaseRoots,
4315
4783
  loadPluginRuntimes,
4784
+ readTargetModelSnapshot,
4785
+ recordTargetModelSnapshot,
4316
4786
  FileKnowledgeBase,
4317
4787
  isOrchestratorEligibleRuntime,
4318
4788
  isDispatchEligibleRuntime,
@@ -4330,4 +4800,4 @@ export {
4330
4800
  normalizeCostProvenance,
4331
4801
  ProvidersDomainModule
4332
4802
  };
4333
- //# sourceMappingURL=chunk-7RFXX52T.js.map
4803
+ //# sourceMappingURL=chunk-DQITNCXG.js.map