@cleocode/core 2026.6.12 → 2026.6.13

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 (385) hide show
  1. package/dist/conduit/local-transport.d.ts +12 -0
  2. package/dist/conduit/local-transport.d.ts.map +1 -1
  3. package/dist/conduit/local-transport.js +53 -23
  4. package/dist/conduit/local-transport.js.map +1 -1
  5. package/dist/crypto/credentials.d.ts +37 -0
  6. package/dist/crypto/credentials.d.ts.map +1 -1
  7. package/dist/crypto/credentials.js +110 -0
  8. package/dist/crypto/credentials.js.map +1 -1
  9. package/dist/dispatch/contracts/derive-output-contract.d.ts +86 -0
  10. package/dist/dispatch/contracts/derive-output-contract.d.ts.map +1 -0
  11. package/dist/dispatch/contracts/derive-output-contract.js +347 -0
  12. package/dist/dispatch/contracts/derive-output-contract.js.map +1 -0
  13. package/dist/dispatch/contracts/ensures-schema.d.ts +77 -0
  14. package/dist/dispatch/contracts/ensures-schema.d.ts.map +1 -0
  15. package/dist/dispatch/contracts/ensures-schema.js +91 -0
  16. package/dist/dispatch/contracts/ensures-schema.js.map +1 -0
  17. package/dist/dispatch/contracts/output-contracts.d.ts +27 -5
  18. package/dist/dispatch/contracts/output-contracts.d.ts.map +1 -1
  19. package/dist/dispatch/contracts/output-contracts.js +29 -6
  20. package/dist/dispatch/contracts/output-contracts.js.map +1 -1
  21. package/dist/docs/export-document.js +2294 -1250
  22. package/dist/docs/export-document.js.map +3 -3
  23. package/dist/go/driver.d.ts +132 -7
  24. package/dist/go/driver.d.ts.map +1 -1
  25. package/dist/go/driver.js +135 -10
  26. package/dist/go/driver.js.map +1 -1
  27. package/dist/go/index.d.ts +1 -1
  28. package/dist/go/index.d.ts.map +1 -1
  29. package/dist/go/index.js +1 -1
  30. package/dist/go/index.js.map +1 -1
  31. package/dist/index.d.ts +1 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +5 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal.d.ts +13 -10
  36. package/dist/internal.d.ts.map +1 -1
  37. package/dist/internal.js +11 -11
  38. package/dist/internal.js.map +1 -1
  39. package/dist/lifecycle/engine-ops.d.ts.map +1 -1
  40. package/dist/lifecycle/engine-ops.js +7 -4
  41. package/dist/lifecycle/engine-ops.js.map +1 -1
  42. package/dist/lifecycle/ivtr-loop.d.ts +108 -183
  43. package/dist/lifecycle/ivtr-loop.d.ts.map +1 -1
  44. package/dist/lifecycle/ivtr-loop.js +207 -522
  45. package/dist/lifecycle/ivtr-loop.js.map +1 -1
  46. package/dist/llm/auxiliary-fallback.js +1 -1
  47. package/dist/llm/auxiliary-fallback.js.map +1 -1
  48. package/dist/llm/cli-ops.d.ts +14 -1
  49. package/dist/llm/cli-ops.d.ts.map +1 -1
  50. package/dist/llm/cli-ops.js +41 -12
  51. package/dist/llm/cli-ops.js.map +1 -1
  52. package/dist/llm/concrete-session.d.ts.map +1 -1
  53. package/dist/llm/concrete-session.js +4 -0
  54. package/dist/llm/concrete-session.js.map +1 -1
  55. package/dist/llm/credentials.d.ts +35 -0
  56. package/dist/llm/credentials.d.ts.map +1 -1
  57. package/dist/llm/credentials.js +49 -0
  58. package/dist/llm/credentials.js.map +1 -1
  59. package/dist/llm/index.d.ts +4 -0
  60. package/dist/llm/index.d.ts.map +1 -1
  61. package/dist/llm/index.js +4 -0
  62. package/dist/llm/index.js.map +1 -1
  63. package/dist/llm/pi/gondolin-loader.d.ts +241 -0
  64. package/dist/llm/pi/gondolin-loader.d.ts.map +1 -0
  65. package/dist/llm/pi/gondolin-loader.js +195 -0
  66. package/dist/llm/pi/gondolin-loader.js.map +1 -0
  67. package/dist/llm/pi/index.d.ts +28 -0
  68. package/dist/llm/pi/index.d.ts.map +1 -0
  69. package/dist/llm/pi/index.js +27 -0
  70. package/dist/llm/pi/index.js.map +1 -0
  71. package/dist/llm/pi/pi-agent-adapter.d.ts +135 -0
  72. package/dist/llm/pi/pi-agent-adapter.d.ts.map +1 -0
  73. package/dist/llm/pi/pi-agent-adapter.js +329 -0
  74. package/dist/llm/pi/pi-agent-adapter.js.map +1 -0
  75. package/dist/llm/pi/pi-errors.d.ts +161 -0
  76. package/dist/llm/pi/pi-errors.d.ts.map +1 -0
  77. package/dist/llm/pi/pi-errors.js +296 -0
  78. package/dist/llm/pi/pi-errors.js.map +1 -0
  79. package/dist/llm/pi/pi-execution-env.d.ts +286 -0
  80. package/dist/llm/pi/pi-execution-env.d.ts.map +1 -0
  81. package/dist/llm/pi/pi-execution-env.js +406 -0
  82. package/dist/llm/pi/pi-execution-env.js.map +1 -0
  83. package/dist/llm/pi/pi-gondolin-env.d.ts +227 -0
  84. package/dist/llm/pi/pi-gondolin-env.d.ts.map +1 -0
  85. package/dist/llm/pi/pi-gondolin-env.js +541 -0
  86. package/dist/llm/pi/pi-gondolin-env.js.map +1 -0
  87. package/dist/llm/pi/pi-session-storage.d.ts +154 -0
  88. package/dist/llm/pi/pi-session-storage.d.ts.map +1 -0
  89. package/dist/llm/pi/pi-session-storage.js +314 -0
  90. package/dist/llm/pi/pi-session-storage.js.map +1 -0
  91. package/dist/llm/pi/pi-stream-fn.d.ts +124 -0
  92. package/dist/llm/pi/pi-stream-fn.d.ts.map +1 -0
  93. package/dist/llm/pi/pi-stream-fn.js +504 -0
  94. package/dist/llm/pi/pi-stream-fn.js.map +1 -0
  95. package/dist/llm/pi/pi-tool-bridge.d.ts +99 -0
  96. package/dist/llm/pi/pi-tool-bridge.d.ts.map +1 -0
  97. package/dist/llm/pi/pi-tool-bridge.js +117 -0
  98. package/dist/llm/pi/pi-tool-bridge.js.map +1 -0
  99. package/dist/llm/pi/pi-types.d.ts +56 -0
  100. package/dist/llm/pi/pi-types.d.ts.map +1 -0
  101. package/dist/llm/pi/pi-types.js +16 -0
  102. package/dist/llm/pi/pi-types.js.map +1 -0
  103. package/dist/llm/pi/resolve-execution-env.d.ts +194 -0
  104. package/dist/llm/pi/resolve-execution-env.d.ts.map +1 -0
  105. package/dist/llm/pi/resolve-execution-env.js +132 -0
  106. package/dist/llm/pi/resolve-execution-env.js.map +1 -0
  107. package/dist/llm/plugin-facade.js +2253 -1151
  108. package/dist/llm/plugin-facade.js.map +3 -3
  109. package/dist/llm/role-executor.d.ts.map +1 -1
  110. package/dist/llm/role-executor.js +8 -5
  111. package/dist/llm/role-executor.js.map +1 -1
  112. package/dist/llm/role-resolver.d.ts +46 -14
  113. package/dist/llm/role-resolver.d.ts.map +1 -1
  114. package/dist/llm/role-resolver.js +178 -20
  115. package/dist/llm/role-resolver.js.map +1 -1
  116. package/dist/llm/sealed-credential.d.ts +125 -0
  117. package/dist/llm/sealed-credential.d.ts.map +1 -0
  118. package/dist/llm/sealed-credential.js +133 -0
  119. package/dist/llm/sealed-credential.js.map +1 -0
  120. package/dist/llm/session-factory.d.ts.map +1 -1
  121. package/dist/llm/session-factory.js +6 -2
  122. package/dist/llm/session-factory.js.map +1 -1
  123. package/dist/llm/system-key.d.ts +67 -0
  124. package/dist/llm/system-key.d.ts.map +1 -0
  125. package/dist/llm/system-key.js +87 -0
  126. package/dist/llm/system-key.js.map +1 -0
  127. package/dist/llm/system-of-use-registry.d.ts +119 -0
  128. package/dist/llm/system-of-use-registry.d.ts.map +1 -0
  129. package/dist/llm/system-of-use-registry.js +200 -0
  130. package/dist/llm/system-of-use-registry.js.map +1 -0
  131. package/dist/llm/system-resolver.d.ts +32 -10
  132. package/dist/llm/system-resolver.d.ts.map +1 -1
  133. package/dist/llm/system-resolver.js +70 -18
  134. package/dist/llm/system-resolver.js.map +1 -1
  135. package/dist/memory/brain-writer-thread.d.ts.map +1 -1
  136. package/dist/memory/brain-writer-thread.js +116 -11
  137. package/dist/memory/brain-writer-thread.js.map +1 -1
  138. package/dist/memory/claude-mem-migration.d.ts.map +1 -1
  139. package/dist/memory/claude-mem-migration.js +21 -0
  140. package/dist/memory/claude-mem-migration.js.map +1 -1
  141. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  142. package/dist/memory/graph-memory-bridge.js +32 -25
  143. package/dist/memory/graph-memory-bridge.js.map +1 -1
  144. package/dist/memory/llm-backend-resolver.js +23 -5
  145. package/dist/memory/llm-backend-resolver.js.map +1 -1
  146. package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
  147. package/dist/nexus/migrations/M-split-graph.js +60 -53
  148. package/dist/nexus/migrations/M-split-graph.js.map +1 -1
  149. package/dist/orchestrate/pivot.d.ts.map +1 -1
  150. package/dist/orchestrate/pivot.js +20 -2
  151. package/dist/orchestrate/pivot.js.map +1 -1
  152. package/dist/release/engine-ops.js +2 -2
  153. package/dist/release/engine-ops.js.map +1 -1
  154. package/dist/routing/capability-matrix.d.ts.map +1 -1
  155. package/dist/routing/capability-matrix.js +0 -57
  156. package/dist/routing/capability-matrix.js.map +1 -1
  157. package/dist/selfimprove/budget.d.ts +206 -0
  158. package/dist/selfimprove/budget.d.ts.map +1 -0
  159. package/dist/selfimprove/budget.js +203 -0
  160. package/dist/selfimprove/budget.js.map +1 -0
  161. package/dist/selfimprove/dhq-adapter.d.ts +105 -0
  162. package/dist/selfimprove/dhq-adapter.d.ts.map +1 -0
  163. package/dist/selfimprove/dhq-adapter.js +95 -0
  164. package/dist/selfimprove/dhq-adapter.js.map +1 -0
  165. package/dist/selfimprove/draft-pr.d.ts +129 -0
  166. package/dist/selfimprove/draft-pr.d.ts.map +1 -0
  167. package/dist/selfimprove/draft-pr.js +158 -0
  168. package/dist/selfimprove/draft-pr.js.map +1 -0
  169. package/dist/selfimprove/envelope-diff.d.ts +162 -0
  170. package/dist/selfimprove/envelope-diff.d.ts.map +1 -0
  171. package/dist/selfimprove/envelope-diff.js +321 -0
  172. package/dist/selfimprove/envelope-diff.js.map +1 -0
  173. package/dist/selfimprove/replay.d.ts +121 -0
  174. package/dist/selfimprove/replay.d.ts.map +1 -0
  175. package/dist/selfimprove/replay.js +109 -0
  176. package/dist/selfimprove/replay.js.map +1 -0
  177. package/dist/selfimprove/run-loop.d.ts +148 -0
  178. package/dist/selfimprove/run-loop.d.ts.map +1 -0
  179. package/dist/selfimprove/run-loop.js +240 -0
  180. package/dist/selfimprove/run-loop.js.map +1 -0
  181. package/dist/selfimprove/scenario.d.ts +145 -0
  182. package/dist/selfimprove/scenario.d.ts.map +1 -0
  183. package/dist/selfimprove/scenario.js +243 -0
  184. package/dist/selfimprove/scenario.js.map +1 -0
  185. package/dist/sentient/daemon-entry.js +5 -0
  186. package/dist/sentient/daemon-entry.js.map +1 -1
  187. package/dist/sentient/daemon.d.ts.map +1 -1
  188. package/dist/sentient/daemon.js +19 -0
  189. package/dist/sentient/daemon.js.map +1 -1
  190. package/dist/sentient/hygiene-scan.d.ts.map +1 -1
  191. package/dist/sentient/hygiene-scan.js +14 -6
  192. package/dist/sentient/hygiene-scan.js.map +1 -1
  193. package/dist/sessions/briefing.d.ts.map +1 -1
  194. package/dist/sessions/briefing.js +13 -9
  195. package/dist/sessions/briefing.js.map +1 -1
  196. package/dist/sessions/connection-session-handle.d.ts +161 -0
  197. package/dist/sessions/connection-session-handle.d.ts.map +1 -0
  198. package/dist/sessions/connection-session-handle.js +168 -0
  199. package/dist/sessions/connection-session-handle.js.map +1 -0
  200. package/dist/sessions/handoff.d.ts.map +1 -1
  201. package/dist/sessions/handoff.js +9 -0
  202. package/dist/sessions/handoff.js.map +1 -1
  203. package/dist/sessions/index.d.ts +4 -1
  204. package/dist/sessions/index.d.ts.map +1 -1
  205. package/dist/sessions/index.js +31 -1
  206. package/dist/sessions/index.js.map +1 -1
  207. package/dist/sessions/session-id.d.ts +34 -0
  208. package/dist/sessions/session-id.d.ts.map +1 -1
  209. package/dist/sessions/session-id.js +37 -0
  210. package/dist/sessions/session-id.js.map +1 -1
  211. package/dist/sessions/session-manifest-mirror.d.ts +115 -0
  212. package/dist/sessions/session-manifest-mirror.d.ts.map +1 -0
  213. package/dist/sessions/session-manifest-mirror.js +250 -0
  214. package/dist/sessions/session-manifest-mirror.js.map +1 -0
  215. package/dist/sessions/session-switch.d.ts.map +1 -1
  216. package/dist/sessions/session-switch.js +5 -2
  217. package/dist/sessions/session-switch.js.map +1 -1
  218. package/dist/store/converters.d.ts.map +1 -1
  219. package/dist/store/converters.js +2 -0
  220. package/dist/store/converters.js.map +1 -1
  221. package/dist/store/db-helpers.d.ts.map +1 -1
  222. package/dist/store/db-helpers.js +2 -0
  223. package/dist/store/db-helpers.js.map +1 -1
  224. package/dist/store/dual-scope-db.d.ts.map +1 -1
  225. package/dist/store/dual-scope-db.js +87 -47
  226. package/dist/store/dual-scope-db.js.map +1 -1
  227. package/dist/store/pi-session-store.d.ts +151 -0
  228. package/dist/store/pi-session-store.d.ts.map +1 -0
  229. package/dist/store/pi-session-store.js +166 -0
  230. package/dist/store/pi-session-store.js.map +1 -0
  231. package/dist/store/safety-data-accessor.d.ts +1 -0
  232. package/dist/store/safety-data-accessor.d.ts.map +1 -1
  233. package/dist/store/safety-data-accessor.js +5 -0
  234. package/dist/store/safety-data-accessor.js.map +1 -1
  235. package/dist/store/schema/cleo-global/accounts.d.ts +357 -0
  236. package/dist/store/schema/cleo-global/accounts.d.ts.map +1 -0
  237. package/dist/store/schema/cleo-global/accounts.js +136 -0
  238. package/dist/store/schema/cleo-global/accounts.js.map +1 -0
  239. package/dist/store/schema/cleo-global/index.d.ts +2 -0
  240. package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
  241. package/dist/store/schema/cleo-global/index.js +2 -0
  242. package/dist/store/schema/cleo-global/index.js.map +1 -1
  243. package/dist/store/schema/cleo-global/session-manifest.d.ts +217 -0
  244. package/dist/store/schema/cleo-global/session-manifest.d.ts.map +1 -0
  245. package/dist/store/schema/cleo-global/session-manifest.js +99 -0
  246. package/dist/store/schema/cleo-global/session-manifest.js.map +1 -0
  247. package/dist/store/schema/cleo-project/tasks-core.d.ts +16 -0
  248. package/dist/store/schema/cleo-project/tasks-core.d.ts.map +1 -1
  249. package/dist/store/schema/cleo-project/tasks-core.js +14 -0
  250. package/dist/store/schema/cleo-project/tasks-core.js.map +1 -1
  251. package/dist/store/schema/tasks.d.ts +16 -0
  252. package/dist/store/schema/tasks.d.ts.map +1 -1
  253. package/dist/store/schema/tasks.js +10 -0
  254. package/dist/store/schema/tasks.js.map +1 -1
  255. package/dist/store/selfimprove-dhq-schema.d.ts +284 -0
  256. package/dist/store/selfimprove-dhq-schema.d.ts.map +1 -0
  257. package/dist/store/selfimprove-dhq-schema.js +128 -0
  258. package/dist/store/selfimprove-dhq-schema.js.map +1 -0
  259. package/dist/store/selfimprove-dhq-store.d.ts +175 -0
  260. package/dist/store/selfimprove-dhq-store.d.ts.map +1 -0
  261. package/dist/store/selfimprove-dhq-store.js +182 -0
  262. package/dist/store/selfimprove-dhq-store.js.map +1 -0
  263. package/dist/store/session-store.d.ts +52 -13
  264. package/dist/store/session-store.d.ts.map +1 -1
  265. package/dist/store/session-store.js +71 -13
  266. package/dist/store/session-store.js.map +1 -1
  267. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  268. package/dist/store/sqlite-data-accessor.js +7 -0
  269. package/dist/store/sqlite-data-accessor.js.map +1 -1
  270. package/dist/store/umbrella-data-accessor.d.ts +1 -0
  271. package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
  272. package/dist/store/umbrella-data-accessor.js +5 -0
  273. package/dist/store/umbrella-data-accessor.js.map +1 -1
  274. package/dist/store/validation-schemas.d.ts +32 -0
  275. package/dist/store/validation-schemas.d.ts.map +1 -1
  276. package/dist/store/writer-lease-schema.d.ts +392 -0
  277. package/dist/store/writer-lease-schema.d.ts.map +1 -0
  278. package/dist/store/writer-lease-schema.js +142 -0
  279. package/dist/store/writer-lease-schema.js.map +1 -0
  280. package/dist/store/writer-lease.d.ts +368 -0
  281. package/dist/store/writer-lease.d.ts.map +1 -0
  282. package/dist/store/writer-lease.js +1002 -0
  283. package/dist/store/writer-lease.js.map +1 -0
  284. package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
  285. package/dist/tasks/backfill-child-projections.js +14 -9
  286. package/dist/tasks/backfill-child-projections.js.map +1 -1
  287. package/dist/tasks/complete.d.ts.map +1 -1
  288. package/dist/tasks/complete.js +7 -10
  289. package/dist/tasks/complete.js.map +1 -1
  290. package/dist/tasks/duplicate-detector.d.ts.map +1 -1
  291. package/dist/tasks/duplicate-detector.js +14 -7
  292. package/dist/tasks/duplicate-detector.js.map +1 -1
  293. package/dist/telemetry/index.d.ts.map +1 -1
  294. package/dist/telemetry/index.js +10 -4
  295. package/dist/telemetry/index.js.map +1 -1
  296. package/dist/tools/agent-registry.d.ts +250 -0
  297. package/dist/tools/agent-registry.d.ts.map +1 -0
  298. package/dist/tools/agent-registry.js +292 -0
  299. package/dist/tools/agent-registry.js.map +1 -0
  300. package/dist/tools/agent-tool-families.d.ts +107 -0
  301. package/dist/tools/agent-tool-families.d.ts.map +1 -0
  302. package/dist/tools/agent-tool-families.js +527 -0
  303. package/dist/tools/agent-tool-families.js.map +1 -0
  304. package/dist/tools/browser-driver.d.ts +183 -0
  305. package/dist/tools/browser-driver.d.ts.map +1 -0
  306. package/dist/tools/browser-driver.js +242 -0
  307. package/dist/tools/browser-driver.js.map +1 -0
  308. package/dist/tools/builtin-agent-tools.d.ts +36 -0
  309. package/dist/tools/builtin-agent-tools.d.ts.map +1 -0
  310. package/dist/tools/builtin-agent-tools.js +150 -0
  311. package/dist/tools/builtin-agent-tools.js.map +1 -0
  312. package/dist/tools/dispatch.d.ts +370 -0
  313. package/dist/tools/dispatch.d.ts.map +1 -0
  314. package/dist/tools/dispatch.js +505 -0
  315. package/dist/tools/dispatch.js.map +1 -0
  316. package/dist/tools/env-scrub.d.ts +93 -0
  317. package/dist/tools/env-scrub.d.ts.map +1 -0
  318. package/dist/tools/env-scrub.js +176 -0
  319. package/dist/tools/env-scrub.js.map +1 -0
  320. package/dist/tools/fs.d.ts +30 -0
  321. package/dist/tools/fs.d.ts.map +1 -1
  322. package/dist/tools/fs.js +55 -2
  323. package/dist/tools/fs.js.map +1 -1
  324. package/dist/tools/guard.d.ts +15 -0
  325. package/dist/tools/guard.d.ts.map +1 -1
  326. package/dist/tools/guard.js +49 -12
  327. package/dist/tools/guard.js.map +1 -1
  328. package/dist/tools/index.d.ts +10 -0
  329. package/dist/tools/index.d.ts.map +1 -1
  330. package/dist/tools/index.js +37 -0
  331. package/dist/tools/index.js.map +1 -1
  332. package/dist/tools/pty.d.ts +45 -0
  333. package/dist/tools/pty.d.ts.map +1 -0
  334. package/dist/tools/pty.js +166 -0
  335. package/dist/tools/pty.js.map +1 -0
  336. package/dist/tools/schema-gen.d.ts +57 -0
  337. package/dist/tools/schema-gen.d.ts.map +1 -0
  338. package/dist/tools/schema-gen.js +52 -0
  339. package/dist/tools/schema-gen.js.map +1 -0
  340. package/dist/tools/shell.d.ts +12 -0
  341. package/dist/tools/shell.d.ts.map +1 -1
  342. package/dist/tools/shell.js +14 -1
  343. package/dist/tools/shell.js.map +1 -1
  344. package/dist/tools/web-agent-tools.d.ts +72 -0
  345. package/dist/tools/web-agent-tools.d.ts.map +1 -0
  346. package/dist/tools/web-agent-tools.js +393 -0
  347. package/dist/tools/web-agent-tools.js.map +1 -0
  348. package/dist/tools/web-search-backends.d.ts +156 -0
  349. package/dist/tools/web-search-backends.d.ts.map +1 -0
  350. package/dist/tools/web-search-backends.js +290 -0
  351. package/dist/tools/web-search-backends.js.map +1 -0
  352. package/dist/validation/ops.d.ts +1 -15
  353. package/dist/validation/ops.d.ts.map +1 -1
  354. package/dist/validation/ops.js +0 -20
  355. package/dist/validation/ops.js.map +1 -1
  356. package/migrations/drizzle-cleo-global/20260607000000_t11891-writer-leases/migration.sql +55 -0
  357. package/migrations/drizzle-cleo-global/20260607010000_t11639-session-manifest/migration.sql +43 -0
  358. package/migrations/drizzle-cleo-global/20260608000000_t11899-pi-session-tree/migration.sql +52 -0
  359. package/migrations/drizzle-cleo-global/20260608010000_t11709-accounts-credential-pool/migration.sql +72 -0
  360. package/migrations/drizzle-cleo-global/20260608020000_t11889-selfimprove-dhq/migration.sql +64 -0
  361. package/migrations/drizzle-cleo-project/20260607000000_t11891-writer-leases/migration.sql +55 -0
  362. package/migrations/drizzle-cleo-project/20260607010000_t11639-session-parent/migration.sql +22 -0
  363. package/migrations/drizzle-cleo-project/20260608000000_t11899-pi-session-tree/migration.sql +52 -0
  364. package/migrations/drizzle-cleo-project/20260608020000_t11889-selfimprove-dhq/migration.sql +64 -0
  365. package/package.json +15 -13
  366. package/dist/lifecycle/chain-composition.d.ts +0 -30
  367. package/dist/lifecycle/chain-composition.d.ts.map +0 -1
  368. package/dist/lifecycle/chain-composition.js +0 -152
  369. package/dist/lifecycle/chain-composition.js.map +0 -1
  370. package/dist/lifecycle/chain-store.d.ts +0 -70
  371. package/dist/lifecycle/chain-store.d.ts.map +0 -1
  372. package/dist/lifecycle/chain-store.js +0 -246
  373. package/dist/lifecycle/chain-store.js.map +0 -1
  374. package/dist/lifecycle/default-chain.d.ts +0 -39
  375. package/dist/lifecycle/default-chain.d.ts.map +0 -1
  376. package/dist/lifecycle/default-chain.js +0 -176
  377. package/dist/lifecycle/default-chain.js.map +0 -1
  378. package/dist/lifecycle/tessera-engine.d.ts +0 -48
  379. package/dist/lifecycle/tessera-engine.d.ts.map +0 -1
  380. package/dist/lifecycle/tessera-engine.js +0 -249
  381. package/dist/lifecycle/tessera-engine.js.map +0 -1
  382. package/dist/validation/chain-validation.d.ts +0 -43
  383. package/dist/validation/chain-validation.d.ts.map +0 -1
  384. package/dist/validation/chain-validation.js +0 -146
  385. package/dist/validation/chain-validation.js.map +0 -1
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Sealed credential handle — runtime implementation (E10 · T11753).
3
+ *
4
+ * The {@link SealedCredential} **type** lives in `@cleocode/contracts`
5
+ * (`llm/sealed-credential.ts`, types-only for Gate 10 purity). Its `fetch()` is
6
+ * a function-TYPED interface field; the concrete body — the on-demand
7
+ * materialization of the plaintext token — lives HERE in `@cleocode/core`.
8
+ *
9
+ * ## Why this module exists
10
+ *
11
+ * Before E10, {@link import('./role-resolver.js').resolveLLMForRole} returned
12
+ * the resolved credential's plaintext `apiKey` **inline** on its envelope. That
13
+ * bare secret string travelled up the entire resolution call stack
14
+ * (`resolveLLMForRole` → `resolveLLMForSystem` → consumers) where any layer that
15
+ * merely *routed* it to the wire could accidentally log it, serialize it into a
16
+ * LAFS envelope, or copy it into a diagnostic.
17
+ *
18
+ * {@link makeSealedCredential} inverts that. The resolver builds an opaque
19
+ * {@link SealedCredential} handle whose `fetch()` closure captures a
20
+ * `resolveToken` thunk. The plaintext is materialized **only** when a wire
21
+ * boundary (`transportForProvider` / `session-factory.ts`) or daemon
22
+ * worker-injection invokes `fetch()`. Between the resolver and those boundaries,
23
+ * NO layer holds a plaintext secret — it holds a handle.
24
+ *
25
+ * ## The brand chokepoint
26
+ *
27
+ * {@link brandDecryptedToken} is the SOLE place a {@link DecryptedToken} is
28
+ * minted from a raw string. Because `DecryptedToken` is a phantom-branded type
29
+ * (contracts), a plain `string` cannot be widened into one anywhere else — so an
30
+ * audit of "who mints a token" reduces to "who calls `brandDecryptedToken`",
31
+ * and that is exclusively this module (invoked inside `fetch()`).
32
+ *
33
+ * @module llm/sealed-credential
34
+ * @task T11753
35
+ * @epic T11746
36
+ * @see ADR-072 §Type lock-in
37
+ */
38
+ /**
39
+ * Build the non-secret, redacted preview of a credential string.
40
+ *
41
+ * SECURITY: this is the SOLE token→preview redaction chokepoint for the sealed
42
+ * handle. It reveals at most the last 4 characters of the token plus an
43
+ * auth-scheme marker (`oat-…` for OAuth, `…` otherwise) — never enough to
44
+ * reconstruct the secret. It is computed ONCE at seal time and stored on the
45
+ * handle's {@link SealedCredential.tokenPreview}; the full plaintext is NOT
46
+ * retained for it.
47
+ *
48
+ * The preview is the ONLY credential-derived string that may cross a
49
+ * logging/diagnostic/envelope boundary (E10 · T11754 · AC3); everything else
50
+ * goes through {@link SealedCredential.fetch} at the wire and is discarded.
51
+ *
52
+ * @param token - The plaintext secret (read transiently; not retained).
53
+ * @param authType - Auth scheme, used only to pick the cosmetic prefix.
54
+ * @returns A redacted preview safe to log and serialize.
55
+ * @task T11754
56
+ */
57
+ export function tokenPreview(token, authType) {
58
+ const prefix = authType === 'oauth' ? 'oat-…' : '…';
59
+ if (!token)
60
+ return prefix;
61
+ if (token.length <= 4)
62
+ return `${prefix}${token}`;
63
+ return `${prefix}${token.slice(-4)}`;
64
+ }
65
+ /**
66
+ * Mint a {@link DecryptedToken} from a raw plaintext secret.
67
+ *
68
+ * SECURITY: this is the ONE chokepoint that produces a branded
69
+ * {@link DecryptedToken}. It MUST be called only from inside a
70
+ * {@link SealedCredential.fetch} closure (see {@link makeSealedCredential}) —
71
+ * i.e. at the wire / daemon worker-injection boundary — never to surface a
72
+ * plaintext up the resolver stack.
73
+ *
74
+ * The brand is phantom (compile-time only); at runtime this returns a frozen
75
+ * object `{ value }`. The `__decryptedToken` marker is never materialized at
76
+ * runtime — the cast below is the deliberate, single, audited point where a
77
+ * `string` becomes a `DecryptedToken`.
78
+ *
79
+ * @param value - The materialized plaintext secret (API key / OAuth bearer).
80
+ * @returns The branded token, valid only for immediate wire/daemon use.
81
+ * @internal
82
+ */
83
+ function brandDecryptedToken(value) {
84
+ // The single, audited string→DecryptedToken mint. `Object.freeze` prevents a
85
+ // consumer from mutating `value` in place after fetch().
86
+ return Object.freeze({ value });
87
+ }
88
+ /**
89
+ * Build a {@link SealedCredential} handle from a provider/account and an
90
+ * on-demand token resolver.
91
+ *
92
+ * The returned handle carries ONLY the non-secret `provider` + `account`
93
+ * inline. Its `fetch()` closure captures {@link MakeSealedCredentialParams.resolveToken}
94
+ * and brands the result — the plaintext exists transiently inside `fetch()` and
95
+ * is NEVER attached to the handle object, so the handle can be logged or
96
+ * serialized without leaking the secret.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * // In the resolver — capture the already-resolved token in the closure but do
101
+ * // NOT place it on the returned envelope:
102
+ * const sealed = makeSealedCredential({
103
+ * provider: 'anthropic',
104
+ * account: usedLabel ?? 'default',
105
+ * tokenPreview: tokenPreview(token, authType), // non-secret; safe to log
106
+ * resolveToken: () => token, // captured, not surfaced
107
+ * });
108
+ * // At the wire — the ONLY place fetch() runs (via authHeadersFromSealed):
109
+ * const headers = await authHeadersFromSealed(sealed, authType);
110
+ * // the plaintext never escapes authHeadersFromSealed; only headers come out.
111
+ * ```
112
+ *
113
+ * @param params - Provider, account label, and the on-demand token resolver.
114
+ * @returns An opaque sealed-credential handle.
115
+ * @task T11753
116
+ */
117
+ export function makeSealedCredential(params) {
118
+ const { provider, account, tokenPreview: preview, resolveToken } = params;
119
+ return {
120
+ provider,
121
+ account,
122
+ tokenPreview: preview,
123
+ fetch: async () => {
124
+ // The SOLE decrypt/materialize point. `resolveToken` re-obtains (or, in
125
+ // T11754, decrypts) the plaintext on demand; we brand it and hand it to
126
+ // the wire. The plaintext never escapes this closure except as the
127
+ // branded return value the caller is contractually bound to discard.
128
+ const plaintext = await resolveToken();
129
+ return brandDecryptedToken(plaintext);
130
+ },
131
+ };
132
+ }
133
+ //# sourceMappingURL=sealed-credential.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sealed-credential.js","sourceRoot":"","sources":["../../src/llm/sealed-credential.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAIH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAA6B;IACvE,MAAM,MAAM,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC;IAClD,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,mBAAmB,CAAC,KAAa;IACxC,6EAA6E;IAC7E,yDAAyD;IACzD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAmB,CAAC;AACpD,CAAC;AAuCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAkC;IACrE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAC1E,OAAO;QACL,QAAQ;QACR,OAAO;QACP,YAAY,EAAE,OAAO;QACrB,KAAK,EAAE,KAAK,IAA6B,EAAE;YACzC,wEAAwE;YACxE,wEAAwE;YACxE,mEAAmE;YACnE,qEAAqE;YACrE,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAC;YACvC,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"session-factory.d.ts","sourceRoot":"","sources":["../../src/llm/session-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,qBAAqB,EACtB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAIzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMxD;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,oBAAoB,CAC3B,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,kBAAkB,EAC9B,OAAO,CAAC,EAAE,OAAO,GAChB,YAAY,CAEd;AAuCD;;;;;;;;;;;;;GAaG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;IAChE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0B;IAE9D;;;OAGG;gBACS,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE;IAIhD;;;;;;;;;OASG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAItD;;;;;;;;;;OAUG;IACG,MAAM,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC;CA0C/D;AAMD;;;;;;GAMG;AACH,OAAO,EAAE,oBAAoB,IAAI,+BAA+B,EAAE,CAAC"}
1
+ {"version":3,"file":"session-factory.d.ts","sourceRoot":"","sources":["../../src/llm/session-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,qBAAqB,EACtB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAIzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMxD;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,oBAAoB,CAC3B,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,kBAAkB,EAC9B,OAAO,CAAC,EAAE,OAAO,GAChB,YAAY,CAEd;AAuCD;;;;;;;;;;;;;GAaG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;IAChE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0B;IAE9D;;;OAGG;gBACS,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE;IAIhD;;;;;;;;;OASG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAItD;;;;;;;;;;OAUG;IACG,MAAM,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC;CA8C/D;AAMD;;;;;;GAMG;AACH,OAAO,EAAE,oBAAoB,IAAI,+BAA+B,EAAE,CAAC"}
@@ -118,12 +118,16 @@ export class DefaultLlmSessionFactory {
118
118
  }
119
119
  if (opts.role) {
120
120
  const resolved = await resolveLLMForRole(opts.role);
121
- if (!resolved.credential?.apiKey) {
121
+ if (!resolved.sealedCredential || !resolved.credential) {
122
122
  throw new Error(`No credential available for role '${opts.role}' / provider '${resolved.provider}'`);
123
123
  }
124
+ // E10 (T11753): materialize the plaintext from the sealed handle ONLY here,
125
+ // at the wire — `transportForProvider` is one of the two sanctioned decrypt
126
+ // boundaries. The token is wired into the transport and never surfaced.
127
+ const token = (await resolved.sealedCredential.fetch()).value;
124
128
  const resolvedCredential = credentialResultToResolved({
125
129
  provider: resolved.provider,
126
- apiKey: resolved.credential.apiKey,
130
+ apiKey: token,
127
131
  authType: resolved.credential.authType,
128
132
  label: resolved.credentialLabel,
129
133
  });
@@ -1 +1 @@
1
- {"version":3,"file":"session-factory.js","sourceRoot":"","sources":["../../src/llm/session-factory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-factory.js","sourceRoot":"","sources":["../../src/llm/session-factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Runtime encode/decode for {@link SystemOfUse} string keys (E9 · T11751).
3
+ *
4
+ * The structured `{ kind, id }` {@link SystemOfUse} descriptor must cross
5
+ * string-only boundaries (config keys under `llm.systems[...]`, CLI args, audit
6
+ * logs, the runtime registry in `system-of-use-registry.ts`). This module is the
7
+ * single canonical codec between the descriptor and its flat string form.
8
+ *
9
+ * Encoding rules (driven entirely by the {@link OPEN_SYSTEM_KEY_PREFIXES} DATA
10
+ * declared in `@cleocode/contracts`, so the prefix set never drifts):
11
+ *
12
+ * - OPEN axes (`tool` / `skill` / `cantbook-node` / `spawn-unit`) →
13
+ * `<prefix><id>` (e.g. `{ kind: 'tool', id: 'web-search' }` ↔ `'tool:web-search'`).
14
+ * - CLOSED axes (`role` / `orchestration` / `aux`) → the bare `id`
15
+ * (e.g. `{ kind: 'aux', id: 'sentient' }` ↔ `'sentient'`). The flat label
16
+ * vocabulary the resolver already accepts (`SystemOfUseLabel`) IS the closed
17
+ * `aux`/`role` id, so closed keys round-trip without a prefix.
18
+ *
19
+ * Contracts-purity (Gate 10): this runtime codec lives in `@cleocode/core`, NOT
20
+ * in the type-only contracts package — it only READS the
21
+ * {@link OPEN_SYSTEM_KEY_PREFIXES} data map.
22
+ *
23
+ * @module llm/system-key
24
+ * @task T11751
25
+ * @epic T11745
26
+ */
27
+ import { type SystemOfUse, type SystemOfUseKind } from '@cleocode/contracts';
28
+ /**
29
+ * Encode a structured {@link SystemOfUse} descriptor into its canonical string
30
+ * key (the form stored in `llm.systems[...]` and the runtime registry).
31
+ *
32
+ * Open-axis descriptors gain their {@link OPEN_SYSTEM_KEY_PREFIXES} prefix;
33
+ * closed-axis descriptors (`role` / `orchestration` / `aux`) encode to the bare
34
+ * `id` so they round-trip with the flat resolver label vocabulary.
35
+ *
36
+ * @param system - The descriptor to encode.
37
+ * @returns The canonical string key.
38
+ * @task T11751
39
+ */
40
+ export declare function formatSystemKey(system: SystemOfUse): string;
41
+ /**
42
+ * Decode an open-axis string key back into its {@link SystemOfUse} descriptor.
43
+ *
44
+ * Returns `undefined` for a bare key with NO recognised open prefix — such keys
45
+ * are closed-axis ids (`role` / `orchestration` / `aux`) whose `kind` cannot be
46
+ * inferred from the string alone (the same `'sentient'` is an `aux` id and a
47
+ * resolver label). Callers that need the closed-axis descriptor must consult the
48
+ * value SSoTs (`AUX_SYSTEM_IDS` / `ROLE_SYSTEM_IDS` / `ORCHESTRATION_TIER_IDS`).
49
+ *
50
+ * @param key - The string key to decode.
51
+ * @returns The open-axis descriptor, or `undefined` for an un-prefixed key.
52
+ * @task T11751
53
+ */
54
+ export declare function parseSystemKey(key: string): SystemOfUse | undefined;
55
+ /**
56
+ * The {@link SystemOfUseKind} a string key encodes, inferred from its prefix.
57
+ *
58
+ * Open-prefixed keys return their open kind; un-prefixed keys are reported as
59
+ * `'aux'` (the closed lane the flat resolver labels live in). Pure inspection —
60
+ * does not assert the id is registered.
61
+ *
62
+ * @param key - The string key to inspect.
63
+ * @returns The inferred kind.
64
+ * @task T11751
65
+ */
66
+ export declare function systemKeyKind(key: string): SystemOfUseKind;
67
+ //# sourceMappingURL=system-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-key.d.ts","sourceRoot":"","sources":["../../src/llm/system-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAM3D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAUnE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAG1D"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Runtime encode/decode for {@link SystemOfUse} string keys (E9 · T11751).
3
+ *
4
+ * The structured `{ kind, id }` {@link SystemOfUse} descriptor must cross
5
+ * string-only boundaries (config keys under `llm.systems[...]`, CLI args, audit
6
+ * logs, the runtime registry in `system-of-use-registry.ts`). This module is the
7
+ * single canonical codec between the descriptor and its flat string form.
8
+ *
9
+ * Encoding rules (driven entirely by the {@link OPEN_SYSTEM_KEY_PREFIXES} DATA
10
+ * declared in `@cleocode/contracts`, so the prefix set never drifts):
11
+ *
12
+ * - OPEN axes (`tool` / `skill` / `cantbook-node` / `spawn-unit`) →
13
+ * `<prefix><id>` (e.g. `{ kind: 'tool', id: 'web-search' }` ↔ `'tool:web-search'`).
14
+ * - CLOSED axes (`role` / `orchestration` / `aux`) → the bare `id`
15
+ * (e.g. `{ kind: 'aux', id: 'sentient' }` ↔ `'sentient'`). The flat label
16
+ * vocabulary the resolver already accepts (`SystemOfUseLabel`) IS the closed
17
+ * `aux`/`role` id, so closed keys round-trip without a prefix.
18
+ *
19
+ * Contracts-purity (Gate 10): this runtime codec lives in `@cleocode/core`, NOT
20
+ * in the type-only contracts package — it only READS the
21
+ * {@link OPEN_SYSTEM_KEY_PREFIXES} data map.
22
+ *
23
+ * @module llm/system-key
24
+ * @task T11751
25
+ * @epic T11745
26
+ */
27
+ import { isOpenSystemKind, OPEN_SYSTEM_KEY_PREFIXES, } from '@cleocode/contracts';
28
+ /**
29
+ * Encode a structured {@link SystemOfUse} descriptor into its canonical string
30
+ * key (the form stored in `llm.systems[...]` and the runtime registry).
31
+ *
32
+ * Open-axis descriptors gain their {@link OPEN_SYSTEM_KEY_PREFIXES} prefix;
33
+ * closed-axis descriptors (`role` / `orchestration` / `aux`) encode to the bare
34
+ * `id` so they round-trip with the flat resolver label vocabulary.
35
+ *
36
+ * @param system - The descriptor to encode.
37
+ * @returns The canonical string key.
38
+ * @task T11751
39
+ */
40
+ export function formatSystemKey(system) {
41
+ if (isOpenSystemKind(system.kind)) {
42
+ return `${OPEN_SYSTEM_KEY_PREFIXES[system.kind]}${system.id}`;
43
+ }
44
+ // Closed axes (role / orchestration / aux) encode to the bare id.
45
+ return system.id;
46
+ }
47
+ /**
48
+ * Decode an open-axis string key back into its {@link SystemOfUse} descriptor.
49
+ *
50
+ * Returns `undefined` for a bare key with NO recognised open prefix — such keys
51
+ * are closed-axis ids (`role` / `orchestration` / `aux`) whose `kind` cannot be
52
+ * inferred from the string alone (the same `'sentient'` is an `aux` id and a
53
+ * resolver label). Callers that need the closed-axis descriptor must consult the
54
+ * value SSoTs (`AUX_SYSTEM_IDS` / `ROLE_SYSTEM_IDS` / `ORCHESTRATION_TIER_IDS`).
55
+ *
56
+ * @param key - The string key to decode.
57
+ * @returns The open-axis descriptor, or `undefined` for an un-prefixed key.
58
+ * @task T11751
59
+ */
60
+ export function parseSystemKey(key) {
61
+ for (const kind of Object.keys(OPEN_SYSTEM_KEY_PREFIXES)) {
62
+ const prefix = OPEN_SYSTEM_KEY_PREFIXES[kind];
63
+ if (key.startsWith(prefix)) {
64
+ const id = key.slice(prefix.length);
65
+ if (!id)
66
+ return undefined;
67
+ return { kind, id };
68
+ }
69
+ }
70
+ return undefined;
71
+ }
72
+ /**
73
+ * The {@link SystemOfUseKind} a string key encodes, inferred from its prefix.
74
+ *
75
+ * Open-prefixed keys return their open kind; un-prefixed keys are reported as
76
+ * `'aux'` (the closed lane the flat resolver labels live in). Pure inspection —
77
+ * does not assert the id is registered.
78
+ *
79
+ * @param key - The string key to inspect.
80
+ * @returns The inferred kind.
81
+ * @task T11751
82
+ */
83
+ export function systemKeyKind(key) {
84
+ const parsed = parseSystemKey(key);
85
+ return parsed ? parsed.kind : 'aux';
86
+ }
87
+ //# sourceMappingURL=system-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-key.js","sourceRoot":"","sources":["../../src/llm/system-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EACL,gBAAgB,EAChB,wBAAwB,GAIzB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,MAAmB;IACjD,IAAI,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,GAAG,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,EAAE,EAAE,CAAC;IAChE,CAAC;IACD,kEAAkE;IAClE,OAAO,MAAM,CAAC,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAqB,EAAE,CAAC;QAC7E,MAAM,MAAM,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,EAAE;gBAAE,OAAO,SAAS,CAAC;YAC1B,OAAO,EAAE,IAAI,EAAE,EAAE,EAAiB,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AACtC,CAAC"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * `registerSystemOfUse` — runtime extension point for the E9 system-of-use
3
+ * taxonomy (T11751 · AC1).
4
+ *
5
+ * ## Why a runtime registry
6
+ *
7
+ * {@link BUILTIN_SYSTEMS_OF_USE} is the static, closed-axis registry of the
8
+ * well-known systems (orchestration tiers + roles + aux subsystems). Plugins,
9
+ * extensions, and downstream packages need to declare NEW systems-of-use (e.g.
10
+ * a `tool:my-search` or a bespoke `aux`-like subsystem) and give each a default
11
+ * provider/model binding — WITHOUT editing the contracts SSoT.
12
+ *
13
+ * `registerSystemOfUse(key, displayName, defaults)` adds such a system to a
14
+ * process-level registry. The registered default binding is consulted by the
15
+ * single E9 resolution chokepoint (`resolveLLMForSystem` → `resolveLLMForRole`)
16
+ * **strictly BELOW user config** — after `llm.systems[key]`, `llm.default`, and
17
+ * `llm.defaultProfile` — so the user ALWAYS wins (AC1). A registered default
18
+ * only supplies a binding when the user has configured nothing for that key.
19
+ *
20
+ * ## Import-time purity
21
+ *
22
+ * This module performs NO registration at import time — the registry starts
23
+ * empty and is populated only by explicit `registerSystemOfUse(...)` calls. It
24
+ * holds no I/O, no config reads, and no side effects on load (so importing it
25
+ * is always safe). It is the runtime half intentionally split out of the
26
+ * type-only `@cleocode/contracts` (Gate 10).
27
+ *
28
+ * @module llm/system-of-use-registry
29
+ * @task T11751
30
+ * @epic T11745
31
+ */
32
+ import { type RegisteredSystemOfUse, type SystemOfUseDefaults, type SystemOfUseKind, type SystemOfUsePickerEntry } from '@cleocode/contracts';
33
+ import { formatSystemKey } from './system-key.js';
34
+ /**
35
+ * A registered system-of-use whose `defaults` carry neither a `profile` nor a
36
+ * complete `provider`+`model` tuple is structurally incomplete: it can declare
37
+ * presence in the picker but cannot supply a resolution binding. Such a default
38
+ * is skipped at resolution time (the chain falls through) — never an error.
39
+ *
40
+ * @param defaults - The candidate default binding.
41
+ * @returns `true` when the default can actually bind a provider/model.
42
+ * @task T11751
43
+ */
44
+ export declare function isResolvableSystemDefault(defaults: SystemOfUseDefaults): boolean;
45
+ /**
46
+ * Register a new system-of-use with a default provider/model binding (AC1).
47
+ *
48
+ * The registration is merged UNDER user config: the resolver consults
49
+ * `defaults` only when the user has configured nothing more specific for `key`
50
+ * (no `llm.systems[key]`, no `llm.default`, no `llm.defaultProfile`). Re-calling
51
+ * with the same `key` REPLACES the prior registration (last-write-wins) so a
52
+ * package can update its own default idempotently.
53
+ *
54
+ * `key` MAY be a flat label (e.g. `'sentient'`) or an open-axis encoded key
55
+ * (`'tool:web-search'`). Passing a structured `SystemOfUse` descriptor is also
56
+ * supported via {@link registerSystemOfUseDescriptor}.
57
+ *
58
+ * @param key - Encoded system-of-use key (non-empty).
59
+ * @param displayName - Human-readable name for the picker surface (non-empty).
60
+ * @param defaults - Default binding consulted strictly below user config.
61
+ * @returns The stored {@link RegisteredSystemOfUse} record.
62
+ * @throws {RangeError} When `key` or `displayName` is empty.
63
+ * @task T11751
64
+ * @epic T11745
65
+ */
66
+ export declare function registerSystemOfUse(key: string, displayName: string, defaults: SystemOfUseDefaults): RegisteredSystemOfUse;
67
+ /**
68
+ * Register a system-of-use from a structured {@link SystemOfUse} descriptor,
69
+ * encoding it to its canonical string key via {@link formatSystemKey}.
70
+ *
71
+ * Convenience wrapper over {@link registerSystemOfUse} for callers that already
72
+ * hold a `{ kind, id }` descriptor (e.g. plugin-declared tools/skills).
73
+ *
74
+ * @param system - The structured descriptor to register.
75
+ * @param displayName - Human-readable name for the picker surface.
76
+ * @param defaults - Default binding consulted strictly below user config.
77
+ * @returns The stored {@link RegisteredSystemOfUse} record.
78
+ * @task T11751
79
+ */
80
+ export declare function registerSystemOfUseDescriptor(system: Parameters<typeof formatSystemKey>[0], displayName: string, defaults: SystemOfUseDefaults): RegisteredSystemOfUse;
81
+ /**
82
+ * Look up the runtime-registered default binding for an encoded system key.
83
+ *
84
+ * Returns `undefined` when no system is registered under `key` OR when its
85
+ * default is structurally incomplete (so the resolver falls through). This is
86
+ * the read surface the E9 resolver calls AFTER exhausting all user-config tiers.
87
+ *
88
+ * @param key - Encoded system-of-use key (may be undefined — returns undefined).
89
+ * @returns The resolvable {@link SystemOfUseDefaults}, or `undefined`.
90
+ * @task T11751
91
+ */
92
+ export declare function getRegisteredSystemDefault(key: string | undefined): SystemOfUseDefaults | undefined;
93
+ /**
94
+ * Enumerate every system-of-use for the TUI / Studio profile picker (AC2):
95
+ * the static {@link BUILTIN_SYSTEMS_OF_USE} table followed by every
96
+ * runtime-registered system, de-duplicated by key (a registration for a builtin
97
+ * key overrides the builtin entry — "user/runtime wins" for the picker label).
98
+ *
99
+ * Each entry carries its encoded `key`, a `displayName`, the discriminant
100
+ * `kind`, and its `source` (`'builtin'` | `'registered'`) so the picker can
101
+ * render and group them. Registered entries also surface their `defaults`.
102
+ *
103
+ * @param kind - Optional kind filter — when set, only that axis is returned.
104
+ * @returns The merged, ordered picker entries.
105
+ * @task T11751
106
+ * @epic T11745
107
+ */
108
+ export declare function listSystemsOfUse(kind?: SystemOfUseKind): SystemOfUsePickerEntry[];
109
+ /**
110
+ * Clear all runtime registrations.
111
+ *
112
+ * Intended for test isolation — production code never needs to un-register a
113
+ * system. Builtins are unaffected (they live in the contracts SSoT, not here).
114
+ *
115
+ * @internal
116
+ * @task T11751
117
+ */
118
+ export declare function clearRegisteredSystemsOfUse(): void;
119
+ //# sourceMappingURL=system-of-use-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-of-use-registry.d.ts","sourceRoot":"","sources":["../../src/llm/system-of-use-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAiB,MAAM,iBAAiB,CAAC;AAajE;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAGhF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,mBAAmB,GAC5B,qBAAqB,CAyBvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,EAC7C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,mBAAmB,GAC5B,qBAAqB,CAEvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,mBAAmB,GAAG,SAAS,CAMjC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,CAAC,EAAE,eAAe,GAAG,sBAAsB,EAAE,CA2BjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * `registerSystemOfUse` — runtime extension point for the E9 system-of-use
3
+ * taxonomy (T11751 · AC1).
4
+ *
5
+ * ## Why a runtime registry
6
+ *
7
+ * {@link BUILTIN_SYSTEMS_OF_USE} is the static, closed-axis registry of the
8
+ * well-known systems (orchestration tiers + roles + aux subsystems). Plugins,
9
+ * extensions, and downstream packages need to declare NEW systems-of-use (e.g.
10
+ * a `tool:my-search` or a bespoke `aux`-like subsystem) and give each a default
11
+ * provider/model binding — WITHOUT editing the contracts SSoT.
12
+ *
13
+ * `registerSystemOfUse(key, displayName, defaults)` adds such a system to a
14
+ * process-level registry. The registered default binding is consulted by the
15
+ * single E9 resolution chokepoint (`resolveLLMForSystem` → `resolveLLMForRole`)
16
+ * **strictly BELOW user config** — after `llm.systems[key]`, `llm.default`, and
17
+ * `llm.defaultProfile` — so the user ALWAYS wins (AC1). A registered default
18
+ * only supplies a binding when the user has configured nothing for that key.
19
+ *
20
+ * ## Import-time purity
21
+ *
22
+ * This module performs NO registration at import time — the registry starts
23
+ * empty and is populated only by explicit `registerSystemOfUse(...)` calls. It
24
+ * holds no I/O, no config reads, and no side effects on load (so importing it
25
+ * is always safe). It is the runtime half intentionally split out of the
26
+ * type-only `@cleocode/contracts` (Gate 10).
27
+ *
28
+ * @module llm/system-of-use-registry
29
+ * @task T11751
30
+ * @epic T11745
31
+ */
32
+ import { BUILTIN_SYSTEMS_OF_USE, } from '@cleocode/contracts';
33
+ import { getLogger } from '../logger.js';
34
+ import { formatSystemKey, systemKeyKind } from './system-key.js';
35
+ const logger = getLogger('llm-system-of-use-registry');
36
+ /**
37
+ * Process-level registry of runtime-registered systems-of-use, keyed by encoded
38
+ * system key. Starts EMPTY — populated only by {@link registerSystemOfUse}.
39
+ *
40
+ * Module-private: callers reach it through the exported functions so the
41
+ * "user wins" / "register vs read" contract is enforced in one place.
42
+ */
43
+ const REGISTRY = new Map();
44
+ /**
45
+ * A registered system-of-use whose `defaults` carry neither a `profile` nor a
46
+ * complete `provider`+`model` tuple is structurally incomplete: it can declare
47
+ * presence in the picker but cannot supply a resolution binding. Such a default
48
+ * is skipped at resolution time (the chain falls through) — never an error.
49
+ *
50
+ * @param defaults - The candidate default binding.
51
+ * @returns `true` when the default can actually bind a provider/model.
52
+ * @task T11751
53
+ */
54
+ export function isResolvableSystemDefault(defaults) {
55
+ if (defaults.profile)
56
+ return true;
57
+ return Boolean(defaults.provider && defaults.model);
58
+ }
59
+ /**
60
+ * Register a new system-of-use with a default provider/model binding (AC1).
61
+ *
62
+ * The registration is merged UNDER user config: the resolver consults
63
+ * `defaults` only when the user has configured nothing more specific for `key`
64
+ * (no `llm.systems[key]`, no `llm.default`, no `llm.defaultProfile`). Re-calling
65
+ * with the same `key` REPLACES the prior registration (last-write-wins) so a
66
+ * package can update its own default idempotently.
67
+ *
68
+ * `key` MAY be a flat label (e.g. `'sentient'`) or an open-axis encoded key
69
+ * (`'tool:web-search'`). Passing a structured `SystemOfUse` descriptor is also
70
+ * supported via {@link registerSystemOfUseDescriptor}.
71
+ *
72
+ * @param key - Encoded system-of-use key (non-empty).
73
+ * @param displayName - Human-readable name for the picker surface (non-empty).
74
+ * @param defaults - Default binding consulted strictly below user config.
75
+ * @returns The stored {@link RegisteredSystemOfUse} record.
76
+ * @throws {RangeError} When `key` or `displayName` is empty.
77
+ * @task T11751
78
+ * @epic T11745
79
+ */
80
+ export function registerSystemOfUse(key, displayName, defaults) {
81
+ if (!key.trim()) {
82
+ throw new RangeError('registerSystemOfUse: `key` must be a non-empty string');
83
+ }
84
+ if (!displayName.trim()) {
85
+ throw new RangeError('registerSystemOfUse: `displayName` must be a non-empty string');
86
+ }
87
+ const record = {
88
+ key,
89
+ displayName,
90
+ // Defensive copy — the registry owns its records and never aliases the
91
+ // caller's object (so a later caller mutation cannot rewrite a binding).
92
+ defaults: { ...defaults },
93
+ };
94
+ REGISTRY.set(key, record);
95
+ if (!isResolvableSystemDefault(defaults)) {
96
+ logger.debug({ key }, 'registerSystemOfUse: registered with a non-binding default (picker-only) ' +
97
+ '— resolution will fall through past this entry');
98
+ }
99
+ return record;
100
+ }
101
+ /**
102
+ * Register a system-of-use from a structured {@link SystemOfUse} descriptor,
103
+ * encoding it to its canonical string key via {@link formatSystemKey}.
104
+ *
105
+ * Convenience wrapper over {@link registerSystemOfUse} for callers that already
106
+ * hold a `{ kind, id }` descriptor (e.g. plugin-declared tools/skills).
107
+ *
108
+ * @param system - The structured descriptor to register.
109
+ * @param displayName - Human-readable name for the picker surface.
110
+ * @param defaults - Default binding consulted strictly below user config.
111
+ * @returns The stored {@link RegisteredSystemOfUse} record.
112
+ * @task T11751
113
+ */
114
+ export function registerSystemOfUseDescriptor(system, displayName, defaults) {
115
+ return registerSystemOfUse(formatSystemKey(system), displayName, defaults);
116
+ }
117
+ /**
118
+ * Look up the runtime-registered default binding for an encoded system key.
119
+ *
120
+ * Returns `undefined` when no system is registered under `key` OR when its
121
+ * default is structurally incomplete (so the resolver falls through). This is
122
+ * the read surface the E9 resolver calls AFTER exhausting all user-config tiers.
123
+ *
124
+ * @param key - Encoded system-of-use key (may be undefined — returns undefined).
125
+ * @returns The resolvable {@link SystemOfUseDefaults}, or `undefined`.
126
+ * @task T11751
127
+ */
128
+ export function getRegisteredSystemDefault(key) {
129
+ if (!key)
130
+ return undefined;
131
+ const record = REGISTRY.get(key);
132
+ if (!record)
133
+ return undefined;
134
+ if (!isResolvableSystemDefault(record.defaults))
135
+ return undefined;
136
+ return record.defaults;
137
+ }
138
+ /**
139
+ * Enumerate every system-of-use for the TUI / Studio profile picker (AC2):
140
+ * the static {@link BUILTIN_SYSTEMS_OF_USE} table followed by every
141
+ * runtime-registered system, de-duplicated by key (a registration for a builtin
142
+ * key overrides the builtin entry — "user/runtime wins" for the picker label).
143
+ *
144
+ * Each entry carries its encoded `key`, a `displayName`, the discriminant
145
+ * `kind`, and its `source` (`'builtin'` | `'registered'`) so the picker can
146
+ * render and group them. Registered entries also surface their `defaults`.
147
+ *
148
+ * @param kind - Optional kind filter — when set, only that axis is returned.
149
+ * @returns The merged, ordered picker entries.
150
+ * @task T11751
151
+ * @epic T11745
152
+ */
153
+ export function listSystemsOfUse(kind) {
154
+ const byKey = new Map();
155
+ // 1. Builtins first (stable order from the contracts SSoT).
156
+ for (const sys of BUILTIN_SYSTEMS_OF_USE) {
157
+ const key = formatSystemKey(sys);
158
+ byKey.set(key, {
159
+ key,
160
+ displayName: defaultDisplayName(sys.kind, sys.id),
161
+ kind: sys.kind,
162
+ source: 'builtin',
163
+ });
164
+ }
165
+ // 2. Runtime registrations override/extend (registered wins on key collision).
166
+ for (const record of REGISTRY.values()) {
167
+ byKey.set(record.key, {
168
+ key: record.key,
169
+ displayName: record.displayName,
170
+ kind: systemKeyKind(record.key),
171
+ source: 'registered',
172
+ defaults: record.defaults,
173
+ });
174
+ }
175
+ const entries = [...byKey.values()];
176
+ return kind ? entries.filter((e) => e.kind === kind) : entries;
177
+ }
178
+ /**
179
+ * Clear all runtime registrations.
180
+ *
181
+ * Intended for test isolation — production code never needs to un-register a
182
+ * system. Builtins are unaffected (they live in the contracts SSoT, not here).
183
+ *
184
+ * @internal
185
+ * @task T11751
186
+ */
187
+ export function clearRegisteredSystemsOfUse() {
188
+ REGISTRY.clear();
189
+ }
190
+ // ---------------------------------------------------------------------------
191
+ // Internal helpers
192
+ // ---------------------------------------------------------------------------
193
+ /**
194
+ * Derive a human-readable default display name for a builtin system. Plain
195
+ * id-with-kind-prefix; the picker may localise/override on top of this.
196
+ */
197
+ function defaultDisplayName(kind, id) {
198
+ return `${kind}: ${id}`;
199
+ }
200
+ //# sourceMappingURL=system-of-use-registry.js.map