@cleocode/core 2026.6.13 → 2026.6.15

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 (485) hide show
  1. package/dist/admin/ops.d.ts +4 -0
  2. package/dist/admin/ops.d.ts.map +1 -1
  3. package/dist/check/index.d.ts +12 -0
  4. package/dist/check/index.d.ts.map +1 -0
  5. package/dist/check/index.js +12 -0
  6. package/dist/check/index.js.map +1 -0
  7. package/dist/check/pr-gate.d.ts +183 -0
  8. package/dist/check/pr-gate.d.ts.map +1 -0
  9. package/dist/check/pr-gate.js +348 -0
  10. package/dist/check/pr-gate.js.map +1 -0
  11. package/dist/conduit/delivery-router.d.ts +134 -0
  12. package/dist/conduit/delivery-router.d.ts.map +1 -0
  13. package/dist/conduit/delivery-router.js +0 -0
  14. package/dist/conduit/delivery-router.js.map +1 -0
  15. package/dist/conduit/index.d.ts +5 -2
  16. package/dist/conduit/index.d.ts.map +1 -1
  17. package/dist/conduit/index.js +5 -2
  18. package/dist/conduit/index.js.map +1 -1
  19. package/dist/conduit/local-tui-adapter.d.ts +89 -0
  20. package/dist/conduit/local-tui-adapter.d.ts.map +1 -0
  21. package/dist/conduit/local-tui-adapter.js +225 -0
  22. package/dist/conduit/local-tui-adapter.js.map +1 -0
  23. package/dist/config/config-repair.d.ts +70 -0
  24. package/dist/config/config-repair.d.ts.map +1 -0
  25. package/dist/config/config-repair.js +248 -0
  26. package/dist/config/config-repair.js.map +1 -0
  27. package/dist/config/registry.d.ts +54 -0
  28. package/dist/config/registry.d.ts.map +1 -1
  29. package/dist/config/registry.js +92 -0
  30. package/dist/config/registry.js.map +1 -1
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +11 -10
  33. package/dist/config.js.map +1 -1
  34. package/dist/deriver/queue-manager.d.ts +30 -2
  35. package/dist/deriver/queue-manager.d.ts.map +1 -1
  36. package/dist/deriver/queue-manager.js +54 -9
  37. package/dist/deriver/queue-manager.js.map +1 -1
  38. package/dist/dispatch/config-domain-handler.d.ts +125 -0
  39. package/dist/dispatch/config-domain-handler.d.ts.map +1 -0
  40. package/dist/dispatch/config-domain-handler.js +160 -0
  41. package/dist/dispatch/config-domain-handler.js.map +1 -0
  42. package/dist/dispatch/contracts/input-contracts.d.ts.map +1 -1
  43. package/dist/dispatch/contracts/input-contracts.js +19 -1
  44. package/dist/dispatch/contracts/input-contracts.js.map +1 -1
  45. package/dist/docs/export-document.js +3721 -696
  46. package/dist/docs/export-document.js.map +3 -3
  47. package/dist/gateway-client/client.d.ts +123 -0
  48. package/dist/gateway-client/client.d.ts.map +1 -0
  49. package/dist/gateway-client/client.js +93 -0
  50. package/dist/gateway-client/client.js.map +1 -0
  51. package/dist/gateway-client/generated/client/client.gen.d.ts +3 -0
  52. package/dist/gateway-client/generated/client/client.gen.d.ts.map +1 -0
  53. package/dist/gateway-client/generated/client/client.gen.js +217 -0
  54. package/dist/gateway-client/generated/client/client.gen.js.map +1 -0
  55. package/dist/gateway-client/generated/client/index.d.ts +11 -0
  56. package/dist/gateway-client/generated/client/index.d.ts.map +1 -0
  57. package/dist/gateway-client/generated/client/index.js +7 -0
  58. package/dist/gateway-client/generated/client/index.js.map +1 -0
  59. package/dist/gateway-client/generated/client/types.gen.d.ts +121 -0
  60. package/dist/gateway-client/generated/client/types.gen.d.ts.map +1 -0
  61. package/dist/gateway-client/generated/client/types.gen.js +3 -0
  62. package/dist/gateway-client/generated/client/types.gen.js.map +1 -0
  63. package/dist/gateway-client/generated/client/utils.gen.d.ts +38 -0
  64. package/dist/gateway-client/generated/client/utils.gen.d.ts.map +1 -0
  65. package/dist/gateway-client/generated/client/utils.gen.js +229 -0
  66. package/dist/gateway-client/generated/client/utils.gen.js.map +1 -0
  67. package/dist/gateway-client/generated/client.gen.d.ts +13 -0
  68. package/dist/gateway-client/generated/client.gen.d.ts.map +1 -0
  69. package/dist/gateway-client/generated/client.gen.js +4 -0
  70. package/dist/gateway-client/generated/client.gen.js.map +1 -0
  71. package/dist/gateway-client/generated/core/auth.gen.d.ts +26 -0
  72. package/dist/gateway-client/generated/core/auth.gen.d.ts.map +1 -0
  73. package/dist/gateway-client/generated/core/auth.gen.js +15 -0
  74. package/dist/gateway-client/generated/core/auth.gen.js.map +1 -0
  75. package/dist/gateway-client/generated/core/bodySerializer.gen.d.ts +26 -0
  76. package/dist/gateway-client/generated/core/bodySerializer.gen.d.ts.map +1 -0
  77. package/dist/gateway-client/generated/core/bodySerializer.gen.js +58 -0
  78. package/dist/gateway-client/generated/core/bodySerializer.gen.js.map +1 -0
  79. package/dist/gateway-client/generated/core/params.gen.d.ts +44 -0
  80. package/dist/gateway-client/generated/core/params.gen.d.ts.map +1 -0
  81. package/dist/gateway-client/generated/core/params.gen.js +101 -0
  82. package/dist/gateway-client/generated/core/params.gen.js.map +1 -0
  83. package/dist/gateway-client/generated/core/pathSerializer.gen.d.ts +34 -0
  84. package/dist/gateway-client/generated/core/pathSerializer.gen.d.ts.map +1 -0
  85. package/dist/gateway-client/generated/core/pathSerializer.gen.js +107 -0
  86. package/dist/gateway-client/generated/core/pathSerializer.gen.js.map +1 -0
  87. package/dist/gateway-client/generated/core/queryKeySerializer.gen.d.ts +19 -0
  88. package/dist/gateway-client/generated/core/queryKeySerializer.gen.d.ts.map +1 -0
  89. package/dist/gateway-client/generated/core/queryKeySerializer.gen.js +93 -0
  90. package/dist/gateway-client/generated/core/queryKeySerializer.gen.js.map +1 -0
  91. package/dist/gateway-client/generated/core/serverSentEvents.gen.d.ts +72 -0
  92. package/dist/gateway-client/generated/core/serverSentEvents.gen.d.ts.map +1 -0
  93. package/dist/gateway-client/generated/core/serverSentEvents.gen.js +133 -0
  94. package/dist/gateway-client/generated/core/serverSentEvents.gen.js.map +1 -0
  95. package/dist/gateway-client/generated/core/types.gen.d.ts +84 -0
  96. package/dist/gateway-client/generated/core/types.gen.d.ts.map +1 -0
  97. package/dist/gateway-client/generated/core/types.gen.js +3 -0
  98. package/dist/gateway-client/generated/core/types.gen.js.map +1 -0
  99. package/dist/gateway-client/generated/core/utils.gen.d.ts +20 -0
  100. package/dist/gateway-client/generated/core/utils.gen.d.ts.map +1 -0
  101. package/dist/gateway-client/generated/core/utils.gen.js +88 -0
  102. package/dist/gateway-client/generated/core/utils.gen.js.map +1 -0
  103. package/dist/gateway-client/generated/index.d.ts +3 -0
  104. package/dist/gateway-client/generated/index.d.ts.map +1 -0
  105. package/dist/gateway-client/generated/index.js +3 -0
  106. package/dist/gateway-client/generated/index.js.map +1 -0
  107. package/dist/gateway-client/generated/namespaces.gen.d.ts +512 -0
  108. package/dist/gateway-client/generated/namespaces.gen.d.ts.map +1 -0
  109. package/dist/gateway-client/generated/namespaces.gen.js +521 -0
  110. package/dist/gateway-client/generated/namespaces.gen.js.map +1 -0
  111. package/dist/gateway-client/generated/sdk.gen.d.ts +1780 -0
  112. package/dist/gateway-client/generated/sdk.gen.d.ts.map +1 -0
  113. package/dist/gateway-client/generated/sdk.gen.js +3811 -0
  114. package/dist/gateway-client/generated/sdk.gen.js.map +1 -0
  115. package/dist/gateway-client/generated/types.gen.d.ts +14681 -0
  116. package/dist/gateway-client/generated/types.gen.d.ts.map +1 -0
  117. package/dist/gateway-client/generated/types.gen.js +3 -0
  118. package/dist/gateway-client/generated/types.gen.js.map +1 -0
  119. package/dist/gateway-client/index.d.ts +27 -0
  120. package/dist/gateway-client/index.d.ts.map +1 -0
  121. package/dist/gateway-client/index.js +25 -0
  122. package/dist/gateway-client/index.js.map +1 -0
  123. package/dist/gc/cleanup.d.ts +23 -8
  124. package/dist/gc/cleanup.d.ts.map +1 -1
  125. package/dist/gc/cleanup.js +287 -22
  126. package/dist/gc/cleanup.js.map +1 -1
  127. package/dist/index.d.ts +10 -0
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +20 -0
  130. package/dist/index.js.map +1 -1
  131. package/dist/init.d.ts.map +1 -1
  132. package/dist/init.js +28 -0
  133. package/dist/init.js.map +1 -1
  134. package/dist/internal.d.ts +10 -1
  135. package/dist/internal.d.ts.map +1 -1
  136. package/dist/internal.js +18 -1
  137. package/dist/internal.js.map +1 -1
  138. package/dist/llm/catalog-model-resolver.d.ts +19 -0
  139. package/dist/llm/catalog-model-resolver.d.ts.map +1 -1
  140. package/dist/llm/catalog-model-resolver.js +36 -0
  141. package/dist/llm/catalog-model-resolver.js.map +1 -1
  142. package/dist/llm/catalog-resolver.d.ts +112 -0
  143. package/dist/llm/catalog-resolver.d.ts.map +1 -0
  144. package/dist/llm/catalog-resolver.js +207 -0
  145. package/dist/llm/catalog-resolver.js.map +1 -0
  146. package/dist/llm/catalog-seeder.d.ts +96 -0
  147. package/dist/llm/catalog-seeder.d.ts.map +1 -0
  148. package/dist/llm/catalog-seeder.js +189 -0
  149. package/dist/llm/catalog-seeder.js.map +1 -0
  150. package/dist/llm/cli-ops.d.ts +16 -0
  151. package/dist/llm/cli-ops.d.ts.map +1 -1
  152. package/dist/llm/cli-ops.js +37 -10
  153. package/dist/llm/cli-ops.js.map +1 -1
  154. package/dist/llm/complexity-classifier.d.ts +208 -0
  155. package/dist/llm/complexity-classifier.d.ts.map +1 -0
  156. package/dist/llm/complexity-classifier.js +359 -0
  157. package/dist/llm/complexity-classifier.js.map +1 -0
  158. package/dist/llm/credential-pool.d.ts +2 -0
  159. package/dist/llm/credential-pool.d.ts.map +1 -1
  160. package/dist/llm/credential-pool.js +5 -2
  161. package/dist/llm/credential-pool.js.map +1 -1
  162. package/dist/llm/credentials-store.d.ts +10 -14
  163. package/dist/llm/credentials-store.d.ts.map +1 -1
  164. package/dist/llm/credentials-store.js.map +1 -1
  165. package/dist/llm/cross-provider-selector.d.ts +249 -0
  166. package/dist/llm/cross-provider-selector.d.ts.map +1 -0
  167. package/dist/llm/cross-provider-selector.js +572 -0
  168. package/dist/llm/cross-provider-selector.js.map +1 -0
  169. package/dist/llm/entity-ops.d.ts +299 -0
  170. package/dist/llm/entity-ops.d.ts.map +1 -0
  171. package/dist/llm/entity-ops.js +441 -0
  172. package/dist/llm/entity-ops.js.map +1 -0
  173. package/dist/llm/index.d.ts +17 -0
  174. package/dist/llm/index.d.ts.map +1 -1
  175. package/dist/llm/index.js +9 -0
  176. package/dist/llm/index.js.map +1 -1
  177. package/dist/llm/llm-queue-admit.d.ts +118 -0
  178. package/dist/llm/llm-queue-admit.d.ts.map +1 -0
  179. package/dist/llm/llm-queue-admit.js +275 -0
  180. package/dist/llm/llm-queue-admit.js.map +1 -0
  181. package/dist/llm/local-model-fit.d.ts +260 -0
  182. package/dist/llm/local-model-fit.d.ts.map +1 -0
  183. package/dist/llm/local-model-fit.js +563 -0
  184. package/dist/llm/local-model-fit.js.map +1 -0
  185. package/dist/llm/oauth/device-code.d.ts.map +1 -1
  186. package/dist/llm/oauth/device-code.js +2 -8
  187. package/dist/llm/oauth/device-code.js.map +1 -1
  188. package/dist/llm/oauth/google-pkce.d.ts.map +1 -1
  189. package/dist/llm/oauth/google-pkce.js +2 -18
  190. package/dist/llm/oauth/google-pkce.js.map +1 -1
  191. package/dist/llm/oauth/pkce.d.ts +70 -0
  192. package/dist/llm/oauth/pkce.d.ts.map +1 -1
  193. package/dist/llm/oauth/pkce.js +106 -29
  194. package/dist/llm/oauth/pkce.js.map +1 -1
  195. package/dist/llm/onboarding/front-door.d.ts +146 -0
  196. package/dist/llm/onboarding/front-door.d.ts.map +1 -0
  197. package/dist/llm/onboarding/front-door.js +153 -0
  198. package/dist/llm/onboarding/front-door.js.map +1 -0
  199. package/dist/llm/onboarding/login-engine.d.ts +175 -0
  200. package/dist/llm/onboarding/login-engine.d.ts.map +1 -0
  201. package/dist/llm/onboarding/login-engine.js +286 -0
  202. package/dist/llm/onboarding/login-engine.js.map +1 -0
  203. package/dist/llm/pi/pi-gondolin-env.d.ts +23 -0
  204. package/dist/llm/pi/pi-gondolin-env.d.ts.map +1 -1
  205. package/dist/llm/pi/pi-gondolin-env.js +2 -2
  206. package/dist/llm/pi/pi-gondolin-env.js.map +1 -1
  207. package/dist/llm/plugin-facade.js +4612 -1042
  208. package/dist/llm/plugin-facade.js.map +3 -3
  209. package/dist/llm/provider-registry/builtin/anthropic.d.ts.map +1 -1
  210. package/dist/llm/provider-registry/builtin/anthropic.js +23 -10
  211. package/dist/llm/provider-registry/builtin/anthropic.js.map +1 -1
  212. package/dist/llm/provider-registry/builtin/ollama.d.ts +18 -0
  213. package/dist/llm/provider-registry/builtin/ollama.d.ts.map +1 -1
  214. package/dist/llm/provider-registry/builtin/ollama.js +20 -2
  215. package/dist/llm/provider-registry/builtin/ollama.js.map +1 -1
  216. package/dist/llm/provider-registry/provider-alias.d.ts +62 -0
  217. package/dist/llm/provider-registry/provider-alias.d.ts.map +1 -0
  218. package/dist/llm/provider-registry/provider-alias.js +85 -0
  219. package/dist/llm/provider-registry/provider-alias.js.map +1 -0
  220. package/dist/llm/provider-registry/provider-defs.d.ts +45 -0
  221. package/dist/llm/provider-registry/provider-defs.d.ts.map +1 -0
  222. package/dist/llm/provider-registry/provider-defs.js +145 -0
  223. package/dist/llm/provider-registry/provider-defs.js.map +1 -0
  224. package/dist/llm/provider-registry/provider-seed.d.ts +78 -0
  225. package/dist/llm/provider-registry/provider-seed.d.ts.map +1 -0
  226. package/dist/llm/provider-registry/provider-seed.js +113 -0
  227. package/dist/llm/provider-registry/provider-seed.js.map +1 -0
  228. package/dist/llm/role-executor.d.ts.map +1 -1
  229. package/dist/llm/role-executor.js +36 -0
  230. package/dist/llm/role-executor.js.map +1 -1
  231. package/dist/llm/role-resolver.d.ts.map +1 -1
  232. package/dist/llm/role-resolver.js +52 -10
  233. package/dist/llm/role-resolver.js.map +1 -1
  234. package/dist/llm/system-resolver.d.ts.map +1 -1
  235. package/dist/llm/system-resolver.js +73 -22
  236. package/dist/llm/system-resolver.js.map +1 -1
  237. package/dist/llm/transports/codex-responses.d.ts +111 -88
  238. package/dist/llm/transports/codex-responses.d.ts.map +1 -1
  239. package/dist/llm/transports/codex-responses.js +456 -258
  240. package/dist/llm/transports/codex-responses.js.map +1 -1
  241. package/dist/memory/learnings.d.ts +4 -0
  242. package/dist/memory/learnings.d.ts.map +1 -1
  243. package/dist/memory/patterns.d.ts +4 -0
  244. package/dist/memory/patterns.d.ts.map +1 -1
  245. package/dist/metrics/index.d.ts +2 -0
  246. package/dist/metrics/index.d.ts.map +1 -1
  247. package/dist/metrics/index.js +1 -0
  248. package/dist/metrics/index.js.map +1 -1
  249. package/dist/orchestration/spawn.d.ts +89 -0
  250. package/dist/orchestration/spawn.d.ts.map +1 -1
  251. package/dist/orchestration/spawn.js +68 -0
  252. package/dist/orchestration/spawn.js.map +1 -1
  253. package/dist/playbooks/cantbook-profile.d.ts +96 -0
  254. package/dist/playbooks/cantbook-profile.d.ts.map +1 -0
  255. package/dist/playbooks/cantbook-profile.js +97 -0
  256. package/dist/playbooks/cantbook-profile.js.map +1 -0
  257. package/dist/playbooks/guarded-deterministic-runner.d.ts +153 -0
  258. package/dist/playbooks/guarded-deterministic-runner.d.ts.map +1 -0
  259. package/dist/playbooks/guarded-deterministic-runner.js +155 -0
  260. package/dist/playbooks/guarded-deterministic-runner.js.map +1 -0
  261. package/dist/playbooks/index.d.ts +2 -0
  262. package/dist/playbooks/index.d.ts.map +1 -1
  263. package/dist/playbooks/index.js +10 -0
  264. package/dist/playbooks/index.js.map +1 -1
  265. package/dist/playbooks/pi-runner-wiring.d.ts +75 -0
  266. package/dist/playbooks/pi-runner-wiring.d.ts.map +1 -0
  267. package/dist/playbooks/pi-runner-wiring.js +82 -0
  268. package/dist/playbooks/pi-runner-wiring.js.map +1 -0
  269. package/dist/release/index.d.ts +2 -2
  270. package/dist/release/index.d.ts.map +1 -1
  271. package/dist/release/index.js +1 -1
  272. package/dist/release/index.js.map +1 -1
  273. package/dist/release/reconcile.d.ts +97 -0
  274. package/dist/release/reconcile.d.ts.map +1 -1
  275. package/dist/release/reconcile.js +412 -5
  276. package/dist/release/reconcile.js.map +1 -1
  277. package/dist/resources/backend.d.ts +155 -0
  278. package/dist/resources/backend.d.ts.map +1 -0
  279. package/dist/resources/backend.js +23 -0
  280. package/dist/resources/backend.js.map +1 -0
  281. package/dist/resources/linux-backend.d.ts +167 -0
  282. package/dist/resources/linux-backend.d.ts.map +1 -0
  283. package/dist/resources/linux-backend.js +259 -0
  284. package/dist/resources/linux-backend.js.map +1 -0
  285. package/dist/resources/monitor.d.ts +230 -0
  286. package/dist/resources/monitor.d.ts.map +1 -0
  287. package/dist/resources/monitor.js +255 -0
  288. package/dist/resources/monitor.js.map +1 -0
  289. package/dist/resources/spawn-wrapper.d.ts +265 -0
  290. package/dist/resources/spawn-wrapper.d.ts.map +1 -0
  291. package/dist/resources/spawn-wrapper.js +304 -0
  292. package/dist/resources/spawn-wrapper.js.map +1 -0
  293. package/dist/runtime/openapi/generate-openapi.d.ts +211 -0
  294. package/dist/runtime/openapi/generate-openapi.d.ts.map +1 -0
  295. package/dist/runtime/openapi/generate-openapi.js +300 -0
  296. package/dist/runtime/openapi/generate-openapi.js.map +1 -0
  297. package/dist/runtime/openapi/index.d.ts +16 -0
  298. package/dist/runtime/openapi/index.d.ts.map +1 -0
  299. package/dist/runtime/openapi/index.js +16 -0
  300. package/dist/runtime/openapi/index.js.map +1 -0
  301. package/dist/selfimprove/budget.d.ts +11 -2
  302. package/dist/selfimprove/budget.d.ts.map +1 -1
  303. package/dist/selfimprove/budget.js +11 -2
  304. package/dist/selfimprove/budget.js.map +1 -1
  305. package/dist/selfimprove/fix-gen.d.ts +229 -0
  306. package/dist/selfimprove/fix-gen.d.ts.map +1 -0
  307. package/dist/selfimprove/fix-gen.js +266 -0
  308. package/dist/selfimprove/fix-gen.js.map +1 -0
  309. package/dist/selfimprove/run-loop.d.ts +44 -4
  310. package/dist/selfimprove/run-loop.d.ts.map +1 -1
  311. package/dist/selfimprove/run-loop.js +73 -6
  312. package/dist/selfimprove/run-loop.js.map +1 -1
  313. package/dist/selfimprove/scenarios/dhq-replay-find/golden.json +32 -0
  314. package/dist/selfimprove/scenarios/dhq-replay-find/scenario.json +18 -0
  315. package/dist/sentient/cross-project-hygiene.d.ts +11 -2
  316. package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
  317. package/dist/sentient/cross-project-hygiene.js +73 -10
  318. package/dist/sentient/cross-project-hygiene.js.map +1 -1
  319. package/dist/sentient/daemon.d.ts.map +1 -1
  320. package/dist/sentient/daemon.js +7 -2
  321. package/dist/sentient/daemon.js.map +1 -1
  322. package/dist/sentient/worktree-dispatch.d.ts.map +1 -1
  323. package/dist/sentient/worktree-dispatch.js +8 -1
  324. package/dist/sentient/worktree-dispatch.js.map +1 -1
  325. package/dist/setup/config-json-merge.d.ts.map +1 -1
  326. package/dist/setup/config-json-merge.js +14 -0
  327. package/dist/setup/config-json-merge.js.map +1 -1
  328. package/dist/setup/index.d.ts +23 -11
  329. package/dist/setup/index.d.ts.map +1 -1
  330. package/dist/setup/index.js +25 -12
  331. package/dist/setup/index.js.map +1 -1
  332. package/dist/setup/sections/llm.d.ts +28 -1
  333. package/dist/setup/sections/llm.d.ts.map +1 -1
  334. package/dist/setup/sections/llm.js +27 -6
  335. package/dist/setup/sections/llm.js.map +1 -1
  336. package/dist/setup/sections/models-roles.d.ts +40 -0
  337. package/dist/setup/sections/models-roles.d.ts.map +1 -0
  338. package/dist/setup/sections/models-roles.js +219 -0
  339. package/dist/setup/sections/models-roles.js.map +1 -0
  340. package/dist/setup/wizard.d.ts +19 -1
  341. package/dist/setup/wizard.d.ts.map +1 -1
  342. package/dist/setup/wizard.js.map +1 -1
  343. package/dist/spawn/branch-lock.d.ts.map +1 -1
  344. package/dist/spawn/branch-lock.js +7 -1
  345. package/dist/spawn/branch-lock.js.map +1 -1
  346. package/dist/store/attachment-repair.d.ts +110 -0
  347. package/dist/store/attachment-repair.d.ts.map +1 -0
  348. package/dist/store/attachment-repair.js +326 -0
  349. package/dist/store/attachment-repair.js.map +1 -0
  350. package/dist/store/attachment-store.d.ts.map +1 -1
  351. package/dist/store/attachment-store.js +24 -7
  352. package/dist/store/attachment-store.js.map +1 -1
  353. package/dist/store/schedule-schema.d.ts +195 -0
  354. package/dist/store/schedule-schema.d.ts.map +1 -0
  355. package/dist/store/schedule-schema.js +84 -0
  356. package/dist/store/schedule-schema.js.map +1 -0
  357. package/dist/store/schedule-store.d.ts +144 -0
  358. package/dist/store/schedule-store.d.ts.map +1 -0
  359. package/dist/store/schedule-store.js +162 -0
  360. package/dist/store/schedule-store.js.map +1 -0
  361. package/dist/store/schema/attachments.d.ts +1 -1
  362. package/dist/store/schema/cleo-global/index.d.ts +3 -0
  363. package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
  364. package/dist/store/schema/cleo-global/index.js +5 -0
  365. package/dist/store/schema/cleo-global/index.js.map +1 -1
  366. package/dist/store/schema/cleo-global/models-catalog.d.ts +359 -0
  367. package/dist/store/schema/cleo-global/models-catalog.d.ts.map +1 -0
  368. package/dist/store/schema/cleo-global/models-catalog.js +114 -0
  369. package/dist/store/schema/cleo-global/models-catalog.js.map +1 -0
  370. package/dist/store/schema/cleo-global/providers.d.ts +279 -0
  371. package/dist/store/schema/cleo-global/providers.d.ts.map +1 -0
  372. package/dist/store/schema/cleo-global/providers.js +94 -0
  373. package/dist/store/schema/cleo-global/providers.js.map +1 -0
  374. package/dist/store/schema/cleo-global/services.d.ts +493 -0
  375. package/dist/store/schema/cleo-global/services.d.ts.map +1 -0
  376. package/dist/store/schema/cleo-global/services.js +200 -0
  377. package/dist/store/schema/cleo-global/services.js.map +1 -0
  378. package/dist/store/schema/cleo-project/docs.d.ts +1 -1
  379. package/dist/store/schema/cleo-project/provenance-rest.d.ts +1 -1
  380. package/dist/store/schema/cleo-shared/brain.d.ts +2 -2
  381. package/dist/store/schema/memory-schema.d.ts +182 -2
  382. package/dist/store/schema/memory-schema.d.ts.map +1 -1
  383. package/dist/store/schema/memory-schema.js +111 -2
  384. package/dist/store/schema/memory-schema.js.map +1 -1
  385. package/dist/store/schema/provenance/releases.d.ts +1 -1
  386. package/dist/store/service-connections-accessor.d.ts +313 -0
  387. package/dist/store/service-connections-accessor.d.ts.map +1 -0
  388. package/dist/store/service-connections-accessor.js +464 -0
  389. package/dist/store/service-connections-accessor.js.map +1 -0
  390. package/dist/store/service-host-matcher.d.ts +70 -0
  391. package/dist/store/service-host-matcher.d.ts.map +1 -0
  392. package/dist/store/service-host-matcher.js +127 -0
  393. package/dist/store/service-host-matcher.js.map +1 -0
  394. package/dist/store/service-injection.d.ts +152 -0
  395. package/dist/store/service-injection.d.ts.map +1 -0
  396. package/dist/store/service-injection.js +225 -0
  397. package/dist/store/service-injection.js.map +1 -0
  398. package/dist/store/service-oauth.d.ts +287 -0
  399. package/dist/store/service-oauth.d.ts.map +1 -0
  400. package/dist/store/service-oauth.js +524 -0
  401. package/dist/store/service-oauth.js.map +1 -0
  402. package/dist/store/service-trust-gate.d.ts +164 -0
  403. package/dist/store/service-trust-gate.d.ts.map +1 -0
  404. package/dist/store/service-trust-gate.js +122 -0
  405. package/dist/store/service-trust-gate.js.map +1 -0
  406. package/dist/store/validation-schemas.d.ts +4 -4
  407. package/dist/tasks/agent-lifecycle-lane.d.ts +175 -0
  408. package/dist/tasks/agent-lifecycle-lane.d.ts.map +1 -0
  409. package/dist/tasks/agent-lifecycle-lane.js +176 -0
  410. package/dist/tasks/agent-lifecycle-lane.js.map +1 -0
  411. package/dist/tasks/complete.d.ts +17 -0
  412. package/dist/tasks/complete.d.ts.map +1 -1
  413. package/dist/tasks/complete.js +53 -10
  414. package/dist/tasks/complete.js.map +1 -1
  415. package/dist/tasks/depends-waiver-audit.d.ts +52 -0
  416. package/dist/tasks/depends-waiver-audit.d.ts.map +1 -0
  417. package/dist/tasks/depends-waiver-audit.js +36 -0
  418. package/dist/tasks/depends-waiver-audit.js.map +1 -0
  419. package/dist/tasks/engine-wrap.d.ts +36 -2
  420. package/dist/tasks/engine-wrap.d.ts.map +1 -1
  421. package/dist/tasks/engine-wrap.js +44 -2
  422. package/dist/tasks/engine-wrap.js.map +1 -1
  423. package/dist/tasks/evidence.d.ts +34 -2
  424. package/dist/tasks/evidence.d.ts.map +1 -1
  425. package/dist/tasks/evidence.js +293 -35
  426. package/dist/tasks/evidence.js.map +1 -1
  427. package/dist/tasks/index.d.ts +1 -0
  428. package/dist/tasks/index.d.ts.map +1 -1
  429. package/dist/tasks/index.js +1 -0
  430. package/dist/tasks/index.js.map +1 -1
  431. package/dist/tasks/ops.d.ts +3 -0
  432. package/dist/tasks/ops.d.ts.map +1 -1
  433. package/dist/tasks/task-ops.d.ts +1 -1
  434. package/dist/tasks/task-ops.d.ts.map +1 -1
  435. package/dist/tasks/task-ops.js +3 -1
  436. package/dist/tasks/task-ops.js.map +1 -1
  437. package/dist/tasks/task-reparent.d.ts +90 -0
  438. package/dist/tasks/task-reparent.d.ts.map +1 -1
  439. package/dist/tasks/task-reparent.js +171 -0
  440. package/dist/tasks/task-reparent.js.map +1 -1
  441. package/dist/tools/builtin-agent-tools.d.ts.map +1 -1
  442. package/dist/tools/builtin-agent-tools.js +41 -0
  443. package/dist/tools/builtin-agent-tools.js.map +1 -1
  444. package/dist/tools/exec-code-agent-tool.d.ts +179 -0
  445. package/dist/tools/exec-code-agent-tool.d.ts.map +1 -0
  446. package/dist/tools/exec-code-agent-tool.js +239 -0
  447. package/dist/tools/exec-code-agent-tool.js.map +1 -0
  448. package/dist/tools/index.d.ts +6 -0
  449. package/dist/tools/index.d.ts.map +1 -1
  450. package/dist/tools/index.js +15 -0
  451. package/dist/tools/index.js.map +1 -1
  452. package/dist/tools/mcp-agent-tool.d.ts +189 -0
  453. package/dist/tools/mcp-agent-tool.d.ts.map +1 -0
  454. package/dist/tools/mcp-agent-tool.js +243 -0
  455. package/dist/tools/mcp-agent-tool.js.map +1 -0
  456. package/dist/tools/media-agent-tools.d.ts +105 -0
  457. package/dist/tools/media-agent-tools.d.ts.map +1 -0
  458. package/dist/tools/media-agent-tools.js +255 -0
  459. package/dist/tools/media-agent-tools.js.map +1 -0
  460. package/dist/tools/memory-agent-tools.d.ts +99 -0
  461. package/dist/tools/memory-agent-tools.d.ts.map +1 -0
  462. package/dist/tools/memory-agent-tools.js +190 -0
  463. package/dist/tools/memory-agent-tools.js.map +1 -0
  464. package/dist/tools/schedule-agent-tools.d.ts +151 -0
  465. package/dist/tools/schedule-agent-tools.d.ts.map +1 -0
  466. package/dist/tools/schedule-agent-tools.js +238 -0
  467. package/dist/tools/schedule-agent-tools.js.map +1 -0
  468. package/dist/tools/skill-agent-tool.d.ts +108 -0
  469. package/dist/tools/skill-agent-tool.d.ts.map +1 -0
  470. package/dist/tools/skill-agent-tool.js +135 -0
  471. package/dist/tools/skill-agent-tool.js.map +1 -0
  472. package/dist/validation/engine-ops.d.ts.map +1 -1
  473. package/dist/validation/engine-ops.js +17 -1
  474. package/dist/validation/engine-ops.js.map +1 -1
  475. package/dist/verification/verify-tools.d.ts.map +1 -1
  476. package/dist/verification/verify-tools.js +5 -6
  477. package/dist/verification/verify-tools.js.map +1 -1
  478. package/migrations/drizzle-brain/20260610000001_t10405-bitemporal-network-columns/migration.sql +71 -0
  479. package/migrations/drizzle-cleo-global/20260609000000_t11937-service-vault/migration.sql +93 -0
  480. package/migrations/drizzle-cleo-global/20260609010000_t11733-models-catalog/migration.sql +65 -0
  481. package/migrations/drizzle-cleo-global/20260609020000_t11703-providers/migration.sql +52 -0
  482. package/migrations/drizzle-cleo-global/20260610000000_t11962-schedules/migration.sql +48 -0
  483. package/migrations/drizzle-cleo-project/20260610000000_t11962-schedules/migration.sql +48 -0
  484. package/package.json +33 -13
  485. package/templates/workflows/release-prepare.yml.tmpl +48 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-resolver.d.ts","sourceRoot":"","sources":["../../src/llm/catalog-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,2BAA2B,CAAC;AAMnC;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;CAC1C;AAED,kFAAkF;AAClF,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,YAAY,GAAG,cAAc,CAAC;AAE9E,qFAAqF;AACrF,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAKD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAG7E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,IAAI,cAAc,GAAG,IAAI,CAcvD;AA6ED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,mBAAmB,CACvC,kBAAkB,EAAE,MAAM,EAC1B,IAAI,CAAC,EAAE,mBAAmB,GACzB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAqCtC;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Table-first catalog read chokepoint — `resolveCatalogEntry()` (E8 · T11737).
3
+ *
4
+ * ## The single read chokepoint
5
+ *
6
+ * The provider+model catalog now has THREE physical surfaces, in strict priority:
7
+ *
8
+ * 1. **`models_catalog` DB table** (cleo-global · T11733) — the SSoT. Seeded
9
+ * from the shipped offline `curated-catalog.json` (T11734).
10
+ * 2. **disk JSON cache** (`llm-catalog/` · T9314 · `catalog-cache.ts`) — the
11
+ * offline/degraded fallback MIRROR (the most-recent models.dev snapshot).
12
+ * 3. **shipped seed** (`curated-catalog.json`) — the last-resort floor that
13
+ * always ships in the package, so a fresh/offline install always resolves.
14
+ *
15
+ * Every catalog reader (the resolver default — T11944; future capability lookups)
16
+ * funnels through {@link resolveCatalogEntry} so the table and the cache can NEVER
17
+ * silently diverge: one chokepoint, table-or-fallback, in that order.
18
+ *
19
+ * ## Offline-first (degrade) — NO network at read time
20
+ *
21
+ * This module NEVER fetches. The network refresh op (`cleo llm refresh-catalog`)
22
+ * is a SEPARATE leaf. `resolveCatalogEntry()` reads the DB table first; when the
23
+ * table is empty/unseeded it falls back to the disk-cache snapshot, then to the
24
+ * shipped seed. A fresh install with no DB rows and no disk cache still resolves
25
+ * from the bundled `curated-catalog.json`.
26
+ *
27
+ * @module llm/catalog-resolver
28
+ * @task T11737
29
+ * @epic T11694 (E8-CATALOG-CURATION)
30
+ */
31
+ import { readFileSync } from 'node:fs';
32
+ import { dirname, join } from 'node:path';
33
+ import { fileURLToPath } from 'node:url';
34
+ import { getLogger } from '../logger.js';
35
+ import { openDualScopeDb, openDualScopeDbAtPath, } from '../store/dual-scope-db.js';
36
+ import { modelsCatalog } from '../store/schema/cleo-global/models-catalog.js';
37
+ import { findLatestCacheFile, getCatalogDir, readCacheFile } from './catalog-cache.js';
38
+ const logger = getLogger('llm-catalog-resolver');
39
+ /** In-memory shipped-seed cache for the process lifetime. */
40
+ let _seed;
41
+ /**
42
+ * Open the global catalog handle at an EXPLICIT path (test seam).
43
+ *
44
+ * Production callers MUST use {@link openDualScopeDb}`('global')`. This path-aware
45
+ * variant exists so tests open a temp-dir `cleo.db` — never `.cleo/*.db`.
46
+ *
47
+ * @param dbPath - Absolute path to the temp `cleo.db`.
48
+ * @task T11737
49
+ */
50
+ export async function openCatalogAtPath(dbPath) {
51
+ const handle = await openDualScopeDbAtPath('global', dbPath);
52
+ return handle.db;
53
+ }
54
+ /**
55
+ * Load the shipped seed (`curated-catalog.json`) from disk — no network.
56
+ *
57
+ * Read once and cached for the process lifetime. Returns `null` only if the
58
+ * bundled file is missing/unparseable (never expected — it ships in the package).
59
+ *
60
+ * @internal
61
+ */
62
+ export function loadShippedSeed() {
63
+ if (_seed !== undefined)
64
+ return _seed;
65
+ try {
66
+ const thisDir = dirname(fileURLToPath(import.meta.url));
67
+ const jsonPath = join(thisDir, 'curated-catalog.json');
68
+ _seed = JSON.parse(readFileSync(jsonPath, 'utf-8'));
69
+ }
70
+ catch (err) {
71
+ logger.warn({ err: err instanceof Error ? err.message : String(err) }, 'catalog-resolver: shipped seed unreadable');
72
+ _seed = null;
73
+ }
74
+ return _seed;
75
+ }
76
+ /** Resolve the global Drizzle handle — injected, else canonical open. */
77
+ async function resolveDb(deps) {
78
+ if (deps?.db !== undefined)
79
+ return deps.db;
80
+ const handle = await openDualScopeDb('global');
81
+ return handle.db;
82
+ }
83
+ /**
84
+ * Read the latest-released entry for a provider from the `models_catalog` table.
85
+ *
86
+ * Returns the single newest row (ordered by `release_date` DESC, `id` DESC as a
87
+ * stable tie-break) for the provider, or `null` when the provider has no rows
88
+ * (table empty/unseeded for that provider). LIMIT 1 — never scans the whole table.
89
+ *
90
+ * @internal
91
+ */
92
+ async function readLatestFromTable(db, providerId) {
93
+ const { desc, eq } = await import('drizzle-orm');
94
+ const rows = await db
95
+ .select({
96
+ id: modelsCatalog.id,
97
+ providerId: modelsCatalog.providerId,
98
+ releaseDate: modelsCatalog.releaseDate,
99
+ contextLimit: modelsCatalog.contextLimit,
100
+ })
101
+ .from(modelsCatalog)
102
+ .where(eq(modelsCatalog.providerId, providerId))
103
+ .orderBy(desc(modelsCatalog.releaseDate), desc(modelsCatalog.id))
104
+ .limit(1);
105
+ const row = rows[0];
106
+ if (!row)
107
+ return null;
108
+ return {
109
+ id: row.id,
110
+ providerId: row.providerId,
111
+ releaseDate: row.releaseDate,
112
+ contextLimit: row.contextLimit ?? null,
113
+ source: 'table',
114
+ };
115
+ }
116
+ /**
117
+ * Resolve the latest-released catalog entry for a provider from a catalog snapshot
118
+ * (disk-cache file or shipped seed), sorted by `release_date` DESC.
119
+ *
120
+ * The two fallback surfaces carry different shapes — the disk cache is the raw
121
+ * models.dev `{ [provider]: { models: { [id]: { release_date, limit } } } }`, the
122
+ * shipped seed is the curated `{ models: { [provider]: { [id]: entry } } }`. This
123
+ * helper accepts the already-extracted per-provider model map.
124
+ *
125
+ * @internal
126
+ */
127
+ function latestFromModelMap(models, providerId, source) {
128
+ let bestId = null;
129
+ let bestDate = '';
130
+ let bestCtx = null;
131
+ for (const [id, entry] of Object.entries(models)) {
132
+ const rd = entry.release_date;
133
+ if (!rd)
134
+ continue;
135
+ if (rd > bestDate || (rd === bestDate && bestId !== null && id > bestId)) {
136
+ bestDate = rd;
137
+ bestId = id;
138
+ bestCtx = entry.limit?.context ?? null;
139
+ }
140
+ }
141
+ if (bestId === null)
142
+ return null;
143
+ return { id: bestId, providerId, releaseDate: bestDate, contextLimit: bestCtx, source };
144
+ }
145
+ /**
146
+ * Resolve the latest-released catalog entry for a provider — the SINGLE table-first
147
+ * read chokepoint (T11737).
148
+ *
149
+ * Resolution order (offline-first, no network):
150
+ * 1. `models_catalog` DB table (SSoT) — newest `release_date` row for the provider.
151
+ * 2. disk JSON cache (`llm-catalog/`) — newest entry when the table has no rows.
152
+ * 3. shipped `curated-catalog.json` seed — last-resort floor (always present).
153
+ *
154
+ * Returns `null` only when NONE of the three surfaces carry a dated entry for the
155
+ * provider — callers then degrade to their own static literal floor (the resolver
156
+ * default keeps `IMPLICIT_FALLBACK_MODEL` for exactly this case — T11944).
157
+ *
158
+ * @param providerCatalogKey - The models.dev provider key (e.g. `anthropic`).
159
+ * @param deps - Optional injected DB handle / cache dir (tests).
160
+ * @returns The newest-released entry for the provider, or `null` when unresolved.
161
+ *
162
+ * @task T11737
163
+ */
164
+ export async function resolveCatalogEntry(providerCatalogKey, deps) {
165
+ const providerId = providerCatalogKey.toLowerCase();
166
+ // 1. Table-first (SSoT).
167
+ try {
168
+ const db = await resolveDb(deps);
169
+ const fromTable = await readLatestFromTable(db, providerId);
170
+ if (fromTable)
171
+ return fromTable;
172
+ }
173
+ catch (err) {
174
+ // A table read failure must NOT break resolution — degrade to the mirrors.
175
+ logger.warn({ err: err instanceof Error ? err.message : String(err), providerId }, 'catalog-resolver: models_catalog read failed; falling back to disk cache');
176
+ }
177
+ // 2. Disk-cache mirror.
178
+ const cacheDir = deps?.cacheDir ?? getCatalogDir();
179
+ const latest = findLatestCacheFile(cacheDir);
180
+ if (latest) {
181
+ const cache = readCacheFile(latest);
182
+ const provider = cache?.[providerId];
183
+ if (provider?.models) {
184
+ const fromCache = latestFromModelMap(provider.models, providerId, 'disk-cache');
185
+ if (fromCache)
186
+ return fromCache;
187
+ }
188
+ }
189
+ // 3. Shipped-seed floor (always present in the package).
190
+ const seed = loadShippedSeed();
191
+ const seedModels = seed?.models?.[providerId];
192
+ if (seedModels) {
193
+ const fromSeed = latestFromModelMap(seedModels, providerId, 'shipped-seed');
194
+ if (fromSeed)
195
+ return fromSeed;
196
+ }
197
+ return null;
198
+ }
199
+ /**
200
+ * Reset the in-memory shipped-seed cache.
201
+ *
202
+ * @internal — for use in unit tests only.
203
+ */
204
+ export function _resetCatalogResolverCache() {
205
+ _seed = undefined;
206
+ }
207
+ //# sourceMappingURL=catalog-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-resolver.js","sourceRoot":"","sources":["../../src/llm/catalog-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Catalog seeder — populates `models_catalog` from the shipped offline seed (T11734).
3
+ *
4
+ * ## What it does
5
+ *
6
+ * {@link seedModelsCatalog} reads the bundled `curated-catalog.json`, validates it
7
+ * against the contract zod schema ({@link curatedCatalogSchema}), flattens every
8
+ * provider→model entry into a `models_catalog` row, and UPSERTS each via
9
+ * {@link openDualScopeDb}`('global')`. Seeding is the offline bootstrap of the
10
+ * catalog SSoT — NO network is touched (the network refresh op is a separate leaf).
11
+ *
12
+ * ## Idempotent (AC2) + version-skip (AC4)
13
+ *
14
+ * The seed carries a semver `version`. The seeder records the seeded version in the
15
+ * global key-value `__catalog_meta` row and SKIPS a re-seed when the persisted
16
+ * version equals the shipped version (logged, not re-written). On a NEWER shipped
17
+ * version it re-seeds (upsert on the `(provider_id, models_dev_id)` natural key, so
18
+ * a re-seed never duplicates rows — running twice yields the same row count).
19
+ *
20
+ * @module llm/catalog-seeder
21
+ * @task T11734
22
+ * @epic T11694 (E8-CATALOG-CURATION)
23
+ */
24
+ import { type CuratedCatalog } from '@cleocode/contracts';
25
+ import { type CleoGlobalDb } from '../store/dual-scope-db.js';
26
+ import { type NewModelsCatalogRow } from '../store/schema/cleo-global/models-catalog.js';
27
+ /** Result of a {@link seedModelsCatalog} run. */
28
+ export interface SeedCatalogResult {
29
+ /** Whether rows were written this run (`false` on a version-skip). */
30
+ readonly seeded: boolean;
31
+ /** The seed version applied (or already persisted on a skip). */
32
+ readonly version: string;
33
+ /** Number of rows upserted (0 on a skip). */
34
+ readonly rowCount: number;
35
+ /** Why the run behaved as it did. */
36
+ readonly reason: 'seeded' | 'version-skip' | 'reseeded-newer';
37
+ }
38
+ /** Injectable seam for {@link seedModelsCatalog} (tests pass a temp-DB handle + fixture). */
39
+ export interface SeedCatalogDeps {
40
+ /**
41
+ * An already-open global Drizzle handle. When omitted the seeder opens via
42
+ * {@link openDualScopeDb}`('global')`. Tests pass a temp-DB handle (opened via
43
+ * {@link openSeederAtPath}) to stay off `.cleo/*.db`.
44
+ */
45
+ readonly db?: CleoGlobalDb;
46
+ /**
47
+ * A catalog object to seed from, bypassing the bundled `curated-catalog.json`
48
+ * (tests pass a fixture). When omitted the shipped seed is read + validated.
49
+ */
50
+ readonly catalog?: CuratedCatalog;
51
+ }
52
+ /**
53
+ * Open the global seeder handle at an EXPLICIT path (test seam).
54
+ *
55
+ * @param dbPath - Absolute path to the temp `cleo.db`.
56
+ * @task T11734
57
+ */
58
+ export declare function openSeederAtPath(dbPath: string): Promise<CleoGlobalDb>;
59
+ /**
60
+ * Read + validate the shipped seed (`curated-catalog.json`) — no network.
61
+ *
62
+ * Throws a descriptive error when the bundled file is missing or fails schema
63
+ * validation, so a malformed seed fails the build/seed loudly rather than silently
64
+ * persisting garbage.
65
+ *
66
+ * @task T11734
67
+ */
68
+ export declare function loadAndValidateSeed(): CuratedCatalog;
69
+ /**
70
+ * Flatten a {@link CuratedCatalog} into `models_catalog` INSERT rows.
71
+ *
72
+ * Each provider→model entry becomes one row; nested `modalities` / `cost` are
73
+ * JSON-serialized into their TEXT columns. `id` and `models_dev_id` both take the
74
+ * entry id (the latter anchors the `(provider_id, models_dev_id)` upsert key).
75
+ *
76
+ * @task T11734
77
+ */
78
+ export declare function flattenCatalogToRows(catalog: CuratedCatalog): NewModelsCatalogRow[];
79
+ /**
80
+ * Seed `models_catalog` from the shipped offline seed — idempotent, offline-first.
81
+ *
82
+ * Behaviour:
83
+ * - First run (no persisted version): upsert every row, persist the version. (AC1)
84
+ * - Re-run with the SAME version: SKIP (logged, not re-written). (AC4)
85
+ * - Re-run with a NEWER shipped version: re-seed (upsert, no duplicates). (AC3)
86
+ *
87
+ * The upsert is on the `(provider_id, models_dev_id)` natural key, so running twice
88
+ * yields the same row count and never duplicates (AC2). NO network is touched.
89
+ *
90
+ * @param deps - Optional injected DB handle / fixture catalog (tests).
91
+ * @returns A {@link SeedCatalogResult} describing what happened.
92
+ *
93
+ * @task T11734
94
+ */
95
+ export declare function seedModelsCatalog(deps?: SeedCatalogDeps): Promise<SeedCatalogResult>;
96
+ //# sourceMappingURL=catalog-seeder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-seeder.d.ts","sourceRoot":"","sources":["../../src/llm/catalog-seeder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,EAAE,KAAK,cAAc,EAAwB,MAAM,qBAAqB,CAAC;AAGhF,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,+CAA+C,CAAC;AAIvD,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,cAAc,GAAG,gBAAgB,CAAC;CAC/D;AAED,6FAA6F;AAC7F,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAG5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAKpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,EAAE,CA0BnF;AAiDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgD1F"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Catalog seeder — populates `models_catalog` from the shipped offline seed (T11734).
3
+ *
4
+ * ## What it does
5
+ *
6
+ * {@link seedModelsCatalog} reads the bundled `curated-catalog.json`, validates it
7
+ * against the contract zod schema ({@link curatedCatalogSchema}), flattens every
8
+ * provider→model entry into a `models_catalog` row, and UPSERTS each via
9
+ * {@link openDualScopeDb}`('global')`. Seeding is the offline bootstrap of the
10
+ * catalog SSoT — NO network is touched (the network refresh op is a separate leaf).
11
+ *
12
+ * ## Idempotent (AC2) + version-skip (AC4)
13
+ *
14
+ * The seed carries a semver `version`. The seeder records the seeded version in the
15
+ * global key-value `__catalog_meta` row and SKIPS a re-seed when the persisted
16
+ * version equals the shipped version (logged, not re-written). On a NEWER shipped
17
+ * version it re-seeds (upsert on the `(provider_id, models_dev_id)` natural key, so
18
+ * a re-seed never duplicates rows — running twice yields the same row count).
19
+ *
20
+ * @module llm/catalog-seeder
21
+ * @task T11734
22
+ * @epic T11694 (E8-CATALOG-CURATION)
23
+ */
24
+ import { readFileSync } from 'node:fs';
25
+ import { dirname, join } from 'node:path';
26
+ import { fileURLToPath } from 'node:url';
27
+ import { curatedCatalogSchema } from '@cleocode/contracts';
28
+ import { sql } from 'drizzle-orm';
29
+ import { getLogger } from '../logger.js';
30
+ import { openDualScopeDb, openDualScopeDbAtPath, } from '../store/dual-scope-db.js';
31
+ import { modelsCatalog, } from '../store/schema/cleo-global/models-catalog.js';
32
+ const logger = getLogger('llm-catalog-seeder');
33
+ /**
34
+ * Open the global seeder handle at an EXPLICIT path (test seam).
35
+ *
36
+ * @param dbPath - Absolute path to the temp `cleo.db`.
37
+ * @task T11734
38
+ */
39
+ export async function openSeederAtPath(dbPath) {
40
+ const handle = await openDualScopeDbAtPath('global', dbPath);
41
+ return handle.db;
42
+ }
43
+ /**
44
+ * Read + validate the shipped seed (`curated-catalog.json`) — no network.
45
+ *
46
+ * Throws a descriptive error when the bundled file is missing or fails schema
47
+ * validation, so a malformed seed fails the build/seed loudly rather than silently
48
+ * persisting garbage.
49
+ *
50
+ * @task T11734
51
+ */
52
+ export function loadAndValidateSeed() {
53
+ const thisDir = dirname(fileURLToPath(import.meta.url));
54
+ const jsonPath = join(thisDir, 'curated-catalog.json');
55
+ const raw = JSON.parse(readFileSync(jsonPath, 'utf-8'));
56
+ return curatedCatalogSchema.parse(raw);
57
+ }
58
+ /**
59
+ * Flatten a {@link CuratedCatalog} into `models_catalog` INSERT rows.
60
+ *
61
+ * Each provider→model entry becomes one row; nested `modalities` / `cost` are
62
+ * JSON-serialized into their TEXT columns. `id` and `models_dev_id` both take the
63
+ * entry id (the latter anchors the `(provider_id, models_dev_id)` upsert key).
64
+ *
65
+ * @task T11734
66
+ */
67
+ export function flattenCatalogToRows(catalog) {
68
+ const rows = [];
69
+ for (const [providerId, models] of Object.entries(catalog.models)) {
70
+ for (const [modelId, entry] of Object.entries(models)) {
71
+ rows.push({
72
+ id: modelId,
73
+ providerId,
74
+ name: entry.name,
75
+ family: entry.family,
76
+ attachment: entry.attachment,
77
+ reasoning: entry.reasoning,
78
+ temperature: entry.temperature,
79
+ interleaved: entry.interleaved,
80
+ toolCall: entry.tool_call,
81
+ modalities: JSON.stringify(entry.modalities),
82
+ cost: JSON.stringify(entry.cost),
83
+ contextLimit: entry.limit.context,
84
+ outputLimit: entry.limit.output,
85
+ status: entry.status,
86
+ releaseDate: entry.release_date,
87
+ modelsDevId: entry.id,
88
+ source: 'seed',
89
+ });
90
+ }
91
+ }
92
+ return rows;
93
+ }
94
+ /** Resolve the global Drizzle handle — injected, else canonical open. */
95
+ async function resolveDb(deps) {
96
+ if (deps?.db !== undefined)
97
+ return deps.db;
98
+ const handle = await openDualScopeDb('global');
99
+ return handle.db;
100
+ }
101
+ /** The KV key under which the seeded catalog version is persisted. */
102
+ const CATALOG_VERSION_KEY = 'catalog.seed.version';
103
+ /**
104
+ * Read the persisted seeded-catalog version from the lightweight `__catalog_meta`
105
+ * KV table (created on demand), or `null` when never seeded.
106
+ *
107
+ * @internal
108
+ */
109
+ async function readPersistedVersion(db) {
110
+ db.run(sql `CREATE TABLE IF NOT EXISTS __catalog_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`);
111
+ const rows = (await db.all(sql `SELECT value FROM __catalog_meta WHERE key = ${CATALOG_VERSION_KEY} LIMIT 1`));
112
+ return rows[0]?.value ?? null;
113
+ }
114
+ /** Persist the seeded-catalog version into `__catalog_meta`. @internal */
115
+ async function writePersistedVersion(db, version) {
116
+ db.run(sql `INSERT INTO __catalog_meta (key, value) VALUES (${CATALOG_VERSION_KEY}, ${version})
117
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value`);
118
+ }
119
+ /** Compare two semver strings — `a > b`? Padded numeric per-segment compare. @internal */
120
+ function semverGreater(a, b) {
121
+ const pa = a.split('.').map((n) => Number.parseInt(n, 10));
122
+ const pb = b.split('.').map((n) => Number.parseInt(n, 10));
123
+ for (let i = 0; i < 3; i++) {
124
+ const da = pa[i] ?? 0;
125
+ const db = pb[i] ?? 0;
126
+ if (da > db)
127
+ return true;
128
+ if (da < db)
129
+ return false;
130
+ }
131
+ return false;
132
+ }
133
+ /**
134
+ * Seed `models_catalog` from the shipped offline seed — idempotent, offline-first.
135
+ *
136
+ * Behaviour:
137
+ * - First run (no persisted version): upsert every row, persist the version. (AC1)
138
+ * - Re-run with the SAME version: SKIP (logged, not re-written). (AC4)
139
+ * - Re-run with a NEWER shipped version: re-seed (upsert, no duplicates). (AC3)
140
+ *
141
+ * The upsert is on the `(provider_id, models_dev_id)` natural key, so running twice
142
+ * yields the same row count and never duplicates (AC2). NO network is touched.
143
+ *
144
+ * @param deps - Optional injected DB handle / fixture catalog (tests).
145
+ * @returns A {@link SeedCatalogResult} describing what happened.
146
+ *
147
+ * @task T11734
148
+ */
149
+ export async function seedModelsCatalog(deps) {
150
+ const catalog = deps?.catalog ?? loadAndValidateSeed();
151
+ const db = await resolveDb(deps);
152
+ const persisted = await readPersistedVersion(db);
153
+ if (persisted !== null && !semverGreater(catalog.version, persisted)) {
154
+ logger.debug({ persisted, shipped: catalog.version }, 'catalog-seeder: persisted version >= shipped; skipping re-seed');
155
+ return { seeded: false, version: persisted, rowCount: 0, reason: 'version-skip' };
156
+ }
157
+ const rows = flattenCatalogToRows(catalog);
158
+ for (const row of rows) {
159
+ await db
160
+ .insert(modelsCatalog)
161
+ .values(row)
162
+ .onConflictDoUpdate({
163
+ target: [modelsCatalog.providerId, modelsCatalog.modelsDevId],
164
+ set: {
165
+ id: row.id,
166
+ name: row.name,
167
+ family: row.family,
168
+ attachment: row.attachment,
169
+ reasoning: row.reasoning,
170
+ temperature: row.temperature,
171
+ interleaved: row.interleaved,
172
+ toolCall: row.toolCall,
173
+ modalities: row.modalities,
174
+ cost: row.cost,
175
+ contextLimit: row.contextLimit,
176
+ outputLimit: row.outputLimit,
177
+ status: row.status,
178
+ releaseDate: row.releaseDate,
179
+ source: row.source,
180
+ seededAt: sql `(datetime('now'))`,
181
+ },
182
+ });
183
+ }
184
+ await writePersistedVersion(db, catalog.version);
185
+ const reason = persisted === null ? 'seeded' : 'reseeded-newer';
186
+ logger.debug({ version: catalog.version, rowCount: rows.length, reason }, 'catalog-seeder: models_catalog seeded');
187
+ return { seeded: true, version: catalog.version, rowCount: rows.length, reason };
188
+ }
189
+ //# sourceMappingURL=catalog-seeder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-seeder.js","sourceRoot":"","sources":["../../src/llm/catalog-seeder.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,22 @@
19
19
  import type { LlmAddParams, LlmAddResult, LlmAuxiliaryStatusParams, LlmAuxiliaryStatusResult, LlmListParams, LlmListResult, LlmProfileParams, LlmProfileResult, LlmRemoveParams, LlmRemoveResult, LlmSystemsOfUseParams, LlmSystemsOfUseResult, LlmTestParams, LlmTestResult, LlmUseParams, LlmUseResult, LlmWhoamiParams, LlmWhoamiResult } from '@cleocode/contracts';
20
20
  import { type EngineResult } from '@cleocode/contracts';
21
21
  import { resolveAuxiliaryFallbackChain } from './auxiliary-fallback.js';
22
+ /**
23
+ * Redact every occurrence of a secret in free text (S-11).
24
+ *
25
+ * Used before DEBUG-logging a provider error body: Anthropic 4xx payloads can
26
+ * reflect request headers (including the bearer token) back in human-readable
27
+ * form, so the body must never reach a log stream with the live secret in it.
28
+ * Replaces each occurrence with the standard last-4 preview. Empty/short
29
+ * secrets (< 8 chars) redact nothing — they cannot meaningfully leak and a
30
+ * short needle would shred unrelated text.
31
+ *
32
+ * @param text - Raw text that may contain the secret.
33
+ * @param secret - The live credential to scrub.
34
+ * @returns The text with every occurrence of the secret replaced.
35
+ * @task T11968
36
+ */
37
+ export declare function redactSecret(text: string, secret: string | null): string;
22
38
  /**
23
39
  * `llm.add` — upsert a credential into the multi-credential pool.
24
40
  *
@@ -1 +1 @@
1
- {"version":3,"file":"cli-ops.d.ts","sourceRoot":"","sources":["../../src/llm/cli-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACxB,wBAAwB,EACxB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EAEf,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EAEZ,eAAe,EACf,eAAe,EAGhB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,KAAK,YAAY,EAIlB,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAGL,6BAA6B,EAC9B,MAAM,yBAAyB,CAAC;AAuHjC;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAwBtF;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAWzF;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAc/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CA4BtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAqDzC;AAED;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CA4FzF;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAgC/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAO9C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC,CAoBjD;AAGD,OAAO,EAAE,6BAA6B,EAAE,CAAC"}
1
+ {"version":3,"file":"cli-ops.d.ts","sourceRoot":"","sources":["../../src/llm/cli-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACxB,wBAAwB,EACxB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EAEf,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EAEZ,eAAe,EACf,eAAe,EAGhB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,KAAK,YAAY,EAIlB,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,EAGL,6BAA6B,EAC9B,MAAM,yBAAyB,CAAC;AAuCjC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGxE;AAoFD;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAwBtF;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAWzF;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAc/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CA4BtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAqDzC;AAED;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAoGzF;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAgC/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAO9C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC,CAoBjD;AAGD,OAAO,EAAE,6BAA6B,EAAE,CAAC"}
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import { engineError, engineSuccess, WHOAMI_ROLE_IDS, } from '@cleocode/contracts';
20
20
  import { setConfigValue } from '../config.js';
21
+ import { getLogger } from '../logger.js';
21
22
  // S-13 (CWE-209): wrap any user-facing error string in the project-wide
22
23
  // `redactContent` helper so a stack trace or fetch error that incidentally
23
24
  // contains a credential substring is automatically scrubbed before it
@@ -30,6 +31,7 @@ import { addCredential, getCredentialByLabel, listCredentials, removeCredential,
30
31
  import { IMPLICIT_FALLBACK_MODEL, resolveLLMForRole } from './role-resolver.js';
31
32
  import { tokenPreview } from './sealed-credential.js';
32
33
  import { listSystemsOfUse } from './system-of-use-registry.js';
34
+ const logger = getLogger('llm-cli-ops');
33
35
  // ---------------------------------------------------------------------------
34
36
  // Constants
35
37
  // ---------------------------------------------------------------------------
@@ -50,6 +52,26 @@ const ALL_ROLES = WHOAMI_ROLE_IDS;
50
52
  // ---------------------------------------------------------------------------
51
53
  // Redaction helpers
52
54
  // ---------------------------------------------------------------------------
55
+ /**
56
+ * Redact every occurrence of a secret in free text (S-11).
57
+ *
58
+ * Used before DEBUG-logging a provider error body: Anthropic 4xx payloads can
59
+ * reflect request headers (including the bearer token) back in human-readable
60
+ * form, so the body must never reach a log stream with the live secret in it.
61
+ * Replaces each occurrence with the standard last-4 preview. Empty/short
62
+ * secrets (< 8 chars) redact nothing — they cannot meaningfully leak and a
63
+ * short needle would shred unrelated text.
64
+ *
65
+ * @param text - Raw text that may contain the secret.
66
+ * @param secret - The live credential to scrub.
67
+ * @returns The text with every occurrence of the secret replaced.
68
+ * @task T11968
69
+ */
70
+ export function redactSecret(text, secret) {
71
+ if (!secret || secret.length < 8 || !text)
72
+ return text;
73
+ return text.split(secret).join(`…${secret.slice(-4)}`);
74
+ }
53
75
  /**
54
76
  * Return a redacted preview of a token tagged by auth scheme (S-11).
55
77
  *
@@ -75,10 +97,10 @@ function tokenPreviewOf(token, authType) {
75
97
  /**
76
98
  * Build the redacted view used by every `cleo llm` result envelope.
77
99
  *
78
- * `hasRefreshToken` is hard-coded to `false` in Phase 2 — see
79
- * `StoredCredential` in `credentials-store.ts` for the S-07 rationale.
80
- * The contract field stays on `LlmStoredCredentialView` so Phase 3 can
81
- * resurrect it once a real refresh flow ships.
100
+ * `hasRefreshToken` reflects whether a refresh token is actually stored —
101
+ * the refresh flow consuming it shipped in `credential-pool.ts`
102
+ * (`_refreshViaPkce` / `proactiveRefresh`), superseding the Phase-2 S-07
103
+ * hardcode that reported `false` unconditionally (T11958).
82
104
  */
83
105
  function viewOf(c) {
84
106
  return {
@@ -86,7 +108,7 @@ function viewOf(c) {
86
108
  label: c.label,
87
109
  authType: c.authType,
88
110
  tokenPreview: tokenPreviewOf(c.accessToken, c.authType),
89
- hasRefreshToken: false,
111
+ hasRefreshToken: typeof c.refreshToken === 'string' && c.refreshToken.length > 0,
90
112
  expiresAt: c.expiresAt ?? null,
91
113
  priority: c.priority,
92
114
  source: c.source,
@@ -351,14 +373,19 @@ export async function llmTest(params) {
351
373
  try {
352
374
  const response = await fetch(url, { method: 'POST', headers, body });
353
375
  if (!response.ok) {
354
- // S-11: NEVER echo the response body in the error envelope. Some
376
+ // S-11: NEVER echo the response body in the error ENVELOPE. Some
355
377
  // provider 4xx responses include reflected request headers (e.g.
356
378
  // Anthropic's error payload can carry `x-api-key` substring matches
357
379
  // back in human-readable form), and a sloppy log pipeline could
358
- // surface that to an audit log. Surface only the HTTP status —
359
- // operators who need the body can re-run with `CLEO_LOG_LEVEL=debug`
360
- // and inspect the underlying fetch trace.
361
- return engineError('E_PROVIDER_PING_FAILED', `${provider} returned HTTP ${response.status} (body suppressed for credential safety; rerun with CLEO_LOG_LEVEL=debug to inspect via raw fetch trace)`);
380
+ // surface that to an audit log. Surface only the HTTP status in the
381
+ // envelope — and emit the body to the DEBUG log with the in-scope
382
+ // credential redacted, so the failure is actually diagnosable
383
+ // (T11958/DHQ-075 repro follow-through: the previous message promised
384
+ // a "raw fetch trace" that did not exist).
385
+ const bodyText = await response.text().catch(() => '');
386
+ logger.debug({ provider, status: response.status, body: redactSecret(bodyText, token).slice(0, 1024) }, 'llm.test provider ping failed');
387
+ return engineError('E_PROVIDER_PING_FAILED', `${provider} returned HTTP ${response.status} (body suppressed for credential safety; ` +
388
+ `rerun with CLEO_LOG_LEVEL=debug to log the redacted response body)`);
362
389
  }
363
390
  const parsed = (await response.json());
364
391
  providerResponseId = typeof parsed.id === 'string' ? parsed.id : null;