@cleocode/core 2026.9.20 → 2026.9.21

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 (855) hide show
  1. package/dist/adapters/discovery.d.ts.map +1 -1
  2. package/dist/adapters/discovery.js +3 -10
  3. package/dist/adapters/discovery.js.map +1 -1
  4. package/dist/adrs/link-pipeline.js +2 -2
  5. package/dist/adrs/link-pipeline.js.map +1 -1
  6. package/dist/adrs/parse.js +3 -3
  7. package/dist/adrs/parse.js.map +1 -1
  8. package/dist/agents/invoke-meta-agent.d.ts.map +1 -1
  9. package/dist/agents/invoke-meta-agent.js +8 -4
  10. package/dist/agents/invoke-meta-agent.js.map +1 -1
  11. package/dist/bootstrap.d.ts +5 -1
  12. package/dist/bootstrap.d.ts.map +1 -1
  13. package/dist/bootstrap.js +41 -21
  14. package/dist/bootstrap.js.map +1 -1
  15. package/dist/cloud/crypto.d.ts +47 -0
  16. package/dist/cloud/crypto.d.ts.map +1 -0
  17. package/dist/cloud/crypto.js +223 -0
  18. package/dist/cloud/crypto.js.map +1 -0
  19. package/dist/cloud/http.d.ts +52 -0
  20. package/dist/cloud/http.d.ts.map +1 -0
  21. package/dist/cloud/http.js +98 -0
  22. package/dist/cloud/http.js.map +1 -0
  23. package/dist/cloud/index.d.ts +19 -0
  24. package/dist/cloud/index.d.ts.map +1 -0
  25. package/dist/cloud/index.js +19 -0
  26. package/dist/cloud/index.js.map +1 -0
  27. package/dist/cloud/journal.d.ts +169 -0
  28. package/dist/cloud/journal.d.ts.map +1 -0
  29. package/dist/cloud/journal.js +428 -0
  30. package/dist/cloud/journal.js.map +1 -0
  31. package/dist/cloud/keys.d.ts +213 -0
  32. package/dist/cloud/keys.d.ts.map +1 -0
  33. package/dist/cloud/keys.js +362 -0
  34. package/dist/cloud/keys.js.map +1 -0
  35. package/dist/cloud/manifest-check.d.ts +36 -0
  36. package/dist/cloud/manifest-check.d.ts.map +1 -0
  37. package/dist/cloud/manifest-check.js +70 -0
  38. package/dist/cloud/manifest-check.js.map +1 -0
  39. package/dist/cloud/projects.d.ts +13 -0
  40. package/dist/cloud/projects.d.ts.map +1 -0
  41. package/dist/cloud/projects.js +11 -0
  42. package/dist/cloud/projects.js.map +1 -0
  43. package/dist/cloud/signing.d.ts +105 -0
  44. package/dist/cloud/signing.d.ts.map +1 -0
  45. package/dist/cloud/signing.js +117 -0
  46. package/dist/cloud/signing.js.map +1 -0
  47. package/dist/cloud/streams.d.ts +6 -0
  48. package/dist/cloud/streams.d.ts.map +1 -0
  49. package/dist/cloud/streams.js +5 -0
  50. package/dist/cloud/streams.js.map +1 -0
  51. package/dist/decide/audit.d.ts +131 -0
  52. package/dist/decide/audit.d.ts.map +1 -0
  53. package/dist/decide/audit.js +98 -0
  54. package/dist/decide/audit.js.map +1 -0
  55. package/dist/decide/budget.d.ts +91 -0
  56. package/dist/decide/budget.d.ts.map +1 -0
  57. package/dist/decide/budget.js +194 -0
  58. package/dist/decide/budget.js.map +1 -0
  59. package/dist/decide/cache.d.ts +49 -0
  60. package/dist/decide/cache.d.ts.map +1 -0
  61. package/dist/decide/cache.js +87 -0
  62. package/dist/decide/cache.js.map +1 -0
  63. package/dist/decide/client.d.ts +103 -0
  64. package/dist/decide/client.d.ts.map +1 -0
  65. package/dist/decide/client.js +262 -0
  66. package/dist/decide/client.js.map +1 -0
  67. package/dist/decide/credentials.d.ts +159 -0
  68. package/dist/decide/credentials.d.ts.map +1 -0
  69. package/dist/decide/credentials.js +383 -0
  70. package/dist/decide/credentials.js.map +1 -0
  71. package/dist/decide/index.d.ts +18 -0
  72. package/dist/decide/index.d.ts.map +1 -0
  73. package/dist/decide/index.js +18 -0
  74. package/dist/decide/index.js.map +1 -0
  75. package/dist/decide/jev-wire.d.ts +155 -0
  76. package/dist/decide/jev-wire.d.ts.map +1 -0
  77. package/dist/decide/jev-wire.js +420 -0
  78. package/dist/decide/jev-wire.js.map +1 -0
  79. package/dist/decide/operations.d.ts +152 -0
  80. package/dist/decide/operations.d.ts.map +1 -0
  81. package/dist/decide/operations.js +199 -0
  82. package/dist/decide/operations.js.map +1 -0
  83. package/dist/decide/provider.d.ts +90 -0
  84. package/dist/decide/provider.d.ts.map +1 -0
  85. package/dist/decide/provider.js +43 -0
  86. package/dist/decide/provider.js.map +1 -0
  87. package/dist/decide/site.d.ts +148 -0
  88. package/dist/decide/site.d.ts.map +1 -0
  89. package/dist/decide/site.js +181 -0
  90. package/dist/decide/site.js.map +1 -0
  91. package/dist/decide/transport.d.ts +67 -0
  92. package/dist/decide/transport.d.ts.map +1 -0
  93. package/dist/decide/transport.js +350 -0
  94. package/dist/decide/transport.js.map +1 -0
  95. package/dist/docs/export-document.js +5908 -2436
  96. package/dist/docs/export-document.js.map +3 -3
  97. package/dist/docs/index.d.ts +2 -2
  98. package/dist/docs/index.d.ts.map +1 -1
  99. package/dist/docs/index.js +1 -1
  100. package/dist/docs/index.js.map +1 -1
  101. package/dist/docs/projection.d.ts.map +1 -1
  102. package/dist/docs/projection.js +2 -3
  103. package/dist/docs/projection.js.map +1 -1
  104. package/dist/docs/publish-pr.d.ts +69 -1
  105. package/dist/docs/publish-pr.d.ts.map +1 -1
  106. package/dist/docs/publish-pr.js +112 -10
  107. package/dist/docs/publish-pr.js.map +1 -1
  108. package/dist/doctor/db-substrate.d.ts +13 -8
  109. package/dist/doctor/db-substrate.d.ts.map +1 -1
  110. package/dist/doctor/db-substrate.js +39 -26
  111. package/dist/doctor/db-substrate.js.map +1 -1
  112. package/dist/doctor/index.d.ts +2 -0
  113. package/dist/doctor/index.d.ts.map +1 -1
  114. package/dist/doctor/index.js +1 -0
  115. package/dist/doctor/index.js.map +1 -1
  116. package/dist/doctor/knowledge.d.ts.map +1 -1
  117. package/dist/doctor/knowledge.js +5 -15
  118. package/dist/doctor/knowledge.js.map +1 -1
  119. package/dist/doctor/nexus-schema-residency.d.ts +1 -1
  120. package/dist/doctor/nexus-schema-residency.d.ts.map +1 -1
  121. package/dist/doctor/nexus-schema-residency.js +3 -0
  122. package/dist/doctor/nexus-schema-residency.js.map +1 -1
  123. package/dist/doctor/project-identity.d.ts +44 -1
  124. package/dist/doctor/project-identity.d.ts.map +1 -1
  125. package/dist/doctor/project-identity.js +237 -10
  126. package/dist/doctor/project-identity.js.map +1 -1
  127. package/dist/doctor/projects.d.ts +170 -0
  128. package/dist/doctor/projects.d.ts.map +1 -0
  129. package/dist/doctor/projects.js +1075 -0
  130. package/dist/doctor/projects.js.map +1 -0
  131. package/dist/doctor/twin-collapse.d.ts +97 -0
  132. package/dist/doctor/twin-collapse.d.ts.map +1 -0
  133. package/dist/doctor/twin-collapse.js +168 -0
  134. package/dist/doctor/twin-collapse.js.map +1 -0
  135. package/dist/doctor/worktree-orphans.d.ts.map +1 -1
  136. package/dist/doctor/worktree-orphans.js +13 -29
  137. package/dist/doctor/worktree-orphans.js.map +1 -1
  138. package/dist/doctor/worktree-stores.d.ts +128 -0
  139. package/dist/doctor/worktree-stores.d.ts.map +1 -0
  140. package/dist/doctor/worktree-stores.js +374 -0
  141. package/dist/doctor/worktree-stores.js.map +1 -0
  142. package/dist/error-catalog.d.ts.map +1 -1
  143. package/dist/error-catalog.js +21 -0
  144. package/dist/error-catalog.js.map +1 -1
  145. package/dist/error-registry.d.ts.map +1 -1
  146. package/dist/error-registry.js +40 -0
  147. package/dist/error-registry.js.map +1 -1
  148. package/dist/gc/cleanup.d.ts.map +1 -1
  149. package/dist/gc/cleanup.js +32 -19
  150. package/dist/gc/cleanup.js.map +1 -1
  151. package/dist/git/bounded-git.d.ts +170 -0
  152. package/dist/git/bounded-git.d.ts.map +1 -0
  153. package/dist/git/bounded-git.js +371 -0
  154. package/dist/git/bounded-git.js.map +1 -0
  155. package/dist/git/work-tree.d.ts +20 -0
  156. package/dist/git/work-tree.d.ts.map +1 -1
  157. package/dist/git/work-tree.js +20 -2
  158. package/dist/git/work-tree.js.map +1 -1
  159. package/dist/hooks/handlers/session-hooks.d.ts +11 -26
  160. package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
  161. package/dist/hooks/handlers/session-hooks.js +18 -47
  162. package/dist/hooks/handlers/session-hooks.js.map +1 -1
  163. package/dist/hooks/payload-schemas.d.ts +2 -2
  164. package/dist/index.d.ts +6 -5
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +5 -3
  167. package/dist/index.js.map +1 -1
  168. package/dist/init/engine-ops.d.ts.map +1 -1
  169. package/dist/init/engine-ops.js +23 -1
  170. package/dist/init/engine-ops.js.map +1 -1
  171. package/dist/init.d.ts +158 -1
  172. package/dist/init.d.ts.map +1 -1
  173. package/dist/init.js +527 -42
  174. package/dist/init.js.map +1 -1
  175. package/dist/injection.d.ts +55 -0
  176. package/dist/injection.d.ts.map +1 -1
  177. package/dist/injection.js +102 -6
  178. package/dist/injection.js.map +1 -1
  179. package/dist/internal.d.ts +9 -5
  180. package/dist/internal.d.ts.map +1 -1
  181. package/dist/internal.js +8 -4
  182. package/dist/internal.js.map +1 -1
  183. package/dist/issue/diagnostics.d.ts.map +1 -1
  184. package/dist/issue/diagnostics.js +2 -1
  185. package/dist/issue/diagnostics.js.map +1 -1
  186. package/dist/lib/concurrency.d.ts +25 -0
  187. package/dist/lib/concurrency.d.ts.map +1 -0
  188. package/dist/lib/concurrency.js +43 -0
  189. package/dist/lib/concurrency.js.map +1 -0
  190. package/dist/lib/index.d.ts +1 -0
  191. package/dist/lib/index.d.ts.map +1 -1
  192. package/dist/lib/index.js +1 -0
  193. package/dist/lib/index.js.map +1 -1
  194. package/dist/lifecycle/engine-ops.d.ts.map +1 -1
  195. package/dist/lifecycle/engine-ops.js +4 -2
  196. package/dist/lifecycle/engine-ops.js.map +1 -1
  197. package/dist/lifecycle/stage-guidance.d.ts +5 -0
  198. package/dist/lifecycle/stage-guidance.d.ts.map +1 -1
  199. package/dist/lifecycle/stage-guidance.js +14 -4
  200. package/dist/lifecycle/stage-guidance.js.map +1 -1
  201. package/dist/llm/catalog-cache.d.ts +3 -2
  202. package/dist/llm/catalog-cache.d.ts.map +1 -1
  203. package/dist/llm/catalog-cache.js +5 -5
  204. package/dist/llm/catalog-cache.js.map +1 -1
  205. package/dist/llm/credentials.d.ts +4 -4
  206. package/dist/llm/credentials.js +6 -6
  207. package/dist/llm/credentials.js.map +1 -1
  208. package/dist/llm/plugin-facade.js +4312 -1798
  209. package/dist/llm/plugin-facade.js.map +3 -3
  210. package/dist/llm/stable-device-id.d.ts.map +1 -1
  211. package/dist/llm/stable-device-id.js +3 -5
  212. package/dist/llm/stable-device-id.js.map +1 -1
  213. package/dist/memory/attention.d.ts.map +1 -1
  214. package/dist/memory/attention.js +30 -30
  215. package/dist/memory/attention.js.map +1 -1
  216. package/dist/memory/decision-contradiction.d.ts +152 -0
  217. package/dist/memory/decision-contradiction.d.ts.map +1 -0
  218. package/dist/memory/decision-contradiction.js +273 -0
  219. package/dist/memory/decision-contradiction.js.map +1 -0
  220. package/dist/memory/decisions.d.ts +42 -11
  221. package/dist/memory/decisions.d.ts.map +1 -1
  222. package/dist/memory/decisions.js +153 -56
  223. package/dist/memory/decisions.js.map +1 -1
  224. package/dist/memory/dialectic-evaluator.d.ts +7 -0
  225. package/dist/memory/dialectic-evaluator.d.ts.map +1 -1
  226. package/dist/memory/dialectic-evaluator.js +23 -8
  227. package/dist/memory/dialectic-evaluator.js.map +1 -1
  228. package/dist/memory/dispatch-trace-format.d.ts +39 -0
  229. package/dist/memory/dispatch-trace-format.d.ts.map +1 -0
  230. package/dist/memory/dispatch-trace-format.js +54 -0
  231. package/dist/memory/dispatch-trace-format.js.map +1 -0
  232. package/dist/memory/dispatch-trace.d.ts.map +1 -1
  233. package/dist/memory/dispatch-trace.js +1 -27
  234. package/dist/memory/dispatch-trace.js.map +1 -1
  235. package/dist/memory/engine-compat.d.ts +2 -0
  236. package/dist/memory/engine-compat.d.ts.map +1 -1
  237. package/dist/memory/engine-compat.js +1 -0
  238. package/dist/memory/engine-compat.js.map +1 -1
  239. package/dist/memory/import-from-provider.js +3 -3
  240. package/dist/memory/import-from-provider.js.map +1 -1
  241. package/dist/memory/learnings.d.ts +2 -2
  242. package/dist/memory/observation-type-decision.d.ts +96 -0
  243. package/dist/memory/observation-type-decision.d.ts.map +1 -0
  244. package/dist/memory/observation-type-decision.js +218 -0
  245. package/dist/memory/observation-type-decision.js.map +1 -0
  246. package/dist/memory/redaction.js +2 -0
  247. package/dist/memory/redaction.js.map +1 -1
  248. package/dist/memory/retrieval/build-retrieval-bundle.d.ts +9 -2
  249. package/dist/memory/retrieval/build-retrieval-bundle.d.ts.map +1 -1
  250. package/dist/memory/retrieval/build-retrieval-bundle.js +42 -11
  251. package/dist/memory/retrieval/build-retrieval-bundle.js.map +1 -1
  252. package/dist/memory/retrieval/get-current-session-id.d.ts +5 -0
  253. package/dist/memory/retrieval/get-current-session-id.d.ts.map +1 -1
  254. package/dist/memory/retrieval/get-current-session-id.js +7 -2
  255. package/dist/memory/retrieval/get-current-session-id.js.map +1 -1
  256. package/dist/memory/retrieval/observe.d.ts.map +1 -1
  257. package/dist/memory/retrieval/observe.js +30 -29
  258. package/dist/memory/retrieval/observe.js.map +1 -1
  259. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  260. package/dist/nexus/analyze-orchestrator.js +42 -29
  261. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  262. package/dist/nexus/assessment-projection.d.ts +76 -0
  263. package/dist/nexus/assessment-projection.d.ts.map +1 -0
  264. package/dist/nexus/assessment-projection.js +143 -0
  265. package/dist/nexus/assessment-projection.js.map +1 -0
  266. package/dist/nexus/assessment-store.d.ts +14 -2
  267. package/dist/nexus/assessment-store.d.ts.map +1 -1
  268. package/dist/nexus/assessment-store.js +21 -3
  269. package/dist/nexus/assessment-store.js.map +1 -1
  270. package/dist/nexus/checkout-nonce.d.ts +48 -0
  271. package/dist/nexus/checkout-nonce.d.ts.map +1 -0
  272. package/dist/nexus/checkout-nonce.js +84 -0
  273. package/dist/nexus/checkout-nonce.js.map +1 -0
  274. package/dist/nexus/devices.d.ts +93 -0
  275. package/dist/nexus/devices.d.ts.map +1 -0
  276. package/dist/nexus/devices.js +141 -0
  277. package/dist/nexus/devices.js.map +1 -0
  278. package/dist/nexus/freshness.d.ts.map +1 -1
  279. package/dist/nexus/freshness.js +25 -6
  280. package/dist/nexus/freshness.js.map +1 -1
  281. package/dist/nexus/git-state.d.ts +225 -0
  282. package/dist/nexus/git-state.d.ts.map +1 -0
  283. package/dist/nexus/git-state.js +677 -0
  284. package/dist/nexus/git-state.js.map +1 -0
  285. package/dist/nexus/graph-manifest.d.ts +20 -4
  286. package/dist/nexus/graph-manifest.d.ts.map +1 -1
  287. package/dist/nexus/graph-manifest.js +40 -5
  288. package/dist/nexus/graph-manifest.js.map +1 -1
  289. package/dist/nexus/identity.d.ts +68 -23
  290. package/dist/nexus/identity.d.ts.map +1 -1
  291. package/dist/nexus/identity.js +99 -22
  292. package/dist/nexus/identity.js.map +1 -1
  293. package/dist/nexus/index.d.ts +5 -2
  294. package/dist/nexus/index.d.ts.map +1 -1
  295. package/dist/nexus/index.js +10 -4
  296. package/dist/nexus/index.js.map +1 -1
  297. package/dist/nexus/knowledge.d.ts +5 -0
  298. package/dist/nexus/knowledge.d.ts.map +1 -1
  299. package/dist/nexus/knowledge.js +26 -2
  300. package/dist/nexus/knowledge.js.map +1 -1
  301. package/dist/nexus/legacy-alias.d.ts +60 -0
  302. package/dist/nexus/legacy-alias.d.ts.map +1 -0
  303. package/dist/nexus/legacy-alias.js +68 -0
  304. package/dist/nexus/legacy-alias.js.map +1 -0
  305. package/dist/nexus/migrate-json-to-sqlite.js +2 -2
  306. package/dist/nexus/migrate-json-to-sqlite.js.map +1 -1
  307. package/dist/nexus/ops.d.ts +1 -0
  308. package/dist/nexus/ops.d.ts.map +1 -1
  309. package/dist/nexus/path-map.d.ts +264 -20
  310. package/dist/nexus/path-map.d.ts.map +1 -1
  311. package/dist/nexus/path-map.js +580 -44
  312. package/dist/nexus/path-map.js.map +1 -1
  313. package/dist/nexus/projects-clean.d.ts +9 -1
  314. package/dist/nexus/projects-clean.d.ts.map +1 -1
  315. package/dist/nexus/projects-clean.js +126 -14
  316. package/dist/nexus/projects-clean.js.map +1 -1
  317. package/dist/nexus/projects-scan.d.ts +56 -1
  318. package/dist/nexus/projects-scan.d.ts.map +1 -1
  319. package/dist/nexus/projects-scan.js +144 -3
  320. package/dist/nexus/projects-scan.js.map +1 -1
  321. package/dist/nexus/registry-hygiene.d.ts +18 -2
  322. package/dist/nexus/registry-hygiene.d.ts.map +1 -1
  323. package/dist/nexus/registry-hygiene.js +37 -11
  324. package/dist/nexus/registry-hygiene.js.map +1 -1
  325. package/dist/nexus/registry-roots.d.ts +47 -0
  326. package/dist/nexus/registry-roots.d.ts.map +1 -0
  327. package/dist/nexus/registry-roots.js +79 -0
  328. package/dist/nexus/registry-roots.js.map +1 -0
  329. package/dist/nexus/registry.d.ts +50 -9
  330. package/dist/nexus/registry.d.ts.map +1 -1
  331. package/dist/nexus/registry.js +311 -156
  332. package/dist/nexus/registry.js.map +1 -1
  333. package/dist/nexus/stored-roots.d.ts +106 -0
  334. package/dist/nexus/stored-roots.d.ts.map +1 -0
  335. package/dist/nexus/stored-roots.js +180 -0
  336. package/dist/nexus/stored-roots.js.map +1 -0
  337. package/dist/nexus/transfer.d.ts.map +1 -1
  338. package/dist/nexus/transfer.js +3 -0
  339. package/dist/nexus/transfer.js.map +1 -1
  340. package/dist/nexus/user-profile-hygiene.d.ts +168 -0
  341. package/dist/nexus/user-profile-hygiene.d.ts.map +1 -0
  342. package/dist/nexus/user-profile-hygiene.js +305 -0
  343. package/dist/nexus/user-profile-hygiene.js.map +1 -0
  344. package/dist/nexus/user-profile.d.ts +53 -2
  345. package/dist/nexus/user-profile.d.ts.map +1 -1
  346. package/dist/nexus/user-profile.js +106 -4
  347. package/dist/nexus/user-profile.js.map +1 -1
  348. package/dist/orchestrate/pivot.d.ts.map +1 -1
  349. package/dist/orchestrate/pivot.js +5 -1
  350. package/dist/orchestrate/pivot.js.map +1 -1
  351. package/dist/orchestrate/spawn-ops.d.ts +12 -0
  352. package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
  353. package/dist/orchestrate/spawn-ops.js +152 -57
  354. package/dist/orchestrate/spawn-ops.js.map +1 -1
  355. package/dist/orchestration/classify-readiness.d.ts +37 -1
  356. package/dist/orchestration/classify-readiness.d.ts.map +1 -1
  357. package/dist/orchestration/classify-readiness.js +48 -19
  358. package/dist/orchestration/classify-readiness.js.map +1 -1
  359. package/dist/orchestration/index.d.ts +3 -2
  360. package/dist/orchestration/index.d.ts.map +1 -1
  361. package/dist/orchestration/index.js +2 -1
  362. package/dist/orchestration/index.js.map +1 -1
  363. package/dist/orchestration/owner-decision-readiness.d.ts +88 -0
  364. package/dist/orchestration/owner-decision-readiness.d.ts.map +1 -0
  365. package/dist/orchestration/owner-decision-readiness.js +152 -0
  366. package/dist/orchestration/owner-decision-readiness.js.map +1 -0
  367. package/dist/orchestration/psyche-memory-budget.d.ts +105 -0
  368. package/dist/orchestration/psyche-memory-budget.d.ts.map +1 -0
  369. package/dist/orchestration/psyche-memory-budget.js +383 -0
  370. package/dist/orchestration/psyche-memory-budget.js.map +1 -0
  371. package/dist/orchestration/spawn-prompt.d.ts +12 -1
  372. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  373. package/dist/orchestration/spawn-prompt.js +141 -179
  374. package/dist/orchestration/spawn-prompt.js.map +1 -1
  375. package/dist/orchestration/spawn.d.ts +7 -0
  376. package/dist/orchestration/spawn.d.ts.map +1 -1
  377. package/dist/orchestration/spawn.js +1 -0
  378. package/dist/orchestration/spawn.js.map +1 -1
  379. package/dist/paths.d.ts +24 -8
  380. package/dist/paths.d.ts.map +1 -1
  381. package/dist/paths.js +135 -71
  382. package/dist/paths.js.map +1 -1
  383. package/dist/platform.d.ts +6 -1
  384. package/dist/platform.d.ts.map +1 -1
  385. package/dist/platform.js +8 -19
  386. package/dist/platform.js.map +1 -1
  387. package/dist/project-info.d.ts +18 -0
  388. package/dist/project-info.d.ts.map +1 -1
  389. package/dist/project-info.js +29 -1
  390. package/dist/project-info.js.map +1 -1
  391. package/dist/project-lifecycle.d.ts +91 -32
  392. package/dist/project-lifecycle.d.ts.map +1 -1
  393. package/dist/project-lifecycle.js +639 -75
  394. package/dist/project-lifecycle.js.map +1 -1
  395. package/dist/project-scope.d.ts +86 -4
  396. package/dist/project-scope.d.ts.map +1 -1
  397. package/dist/project-scope.js +226 -13
  398. package/dist/project-scope.js.map +1 -1
  399. package/dist/project-tombstone.d.ts +111 -0
  400. package/dist/project-tombstone.d.ts.map +1 -0
  401. package/dist/project-tombstone.js +220 -0
  402. package/dist/project-tombstone.js.map +1 -0
  403. package/dist/release/artifacts.d.ts.map +1 -1
  404. package/dist/release/artifacts.js +14 -9
  405. package/dist/release/artifacts.js.map +1 -1
  406. package/dist/release/ci-evidence.d.ts +223 -0
  407. package/dist/release/ci-evidence.d.ts.map +1 -0
  408. package/dist/release/ci-evidence.js +652 -0
  409. package/dist/release/ci-evidence.js.map +1 -0
  410. package/dist/release/engine-ops.d.ts.map +1 -1
  411. package/dist/release/engine-ops.js +3 -3
  412. package/dist/release/engine-ops.js.map +1 -1
  413. package/dist/release/plan.d.ts.map +1 -1
  414. package/dist/release/plan.js +7 -6
  415. package/dist/release/plan.js.map +1 -1
  416. package/dist/release/pr-evidence.d.ts +38 -0
  417. package/dist/release/pr-evidence.d.ts.map +1 -1
  418. package/dist/release/pr-evidence.js +67 -11
  419. package/dist/release/pr-evidence.js.map +1 -1
  420. package/dist/release/reconcile.d.ts.map +1 -1
  421. package/dist/release/reconcile.js +3 -2
  422. package/dist/release/reconcile.js.map +1 -1
  423. package/dist/release/release-manifest.d.ts +2 -1
  424. package/dist/release/release-manifest.d.ts.map +1 -1
  425. package/dist/release/release-manifest.js +6 -5
  426. package/dist/release/release-manifest.js.map +1 -1
  427. package/dist/render/nexus/graph/index.d.ts +4 -0
  428. package/dist/render/nexus/graph/index.d.ts.map +1 -1
  429. package/dist/render/nexus/graph/index.js +57 -0
  430. package/dist/render/nexus/graph/index.js.map +1 -1
  431. package/dist/resources/spawn-wrapper.d.ts +8 -1
  432. package/dist/resources/spawn-wrapper.d.ts.map +1 -1
  433. package/dist/resources/spawn-wrapper.js +42 -5
  434. package/dist/resources/spawn-wrapper.js.map +1 -1
  435. package/dist/routing/build-command-groups.d.ts.map +1 -1
  436. package/dist/routing/build-command-groups.js +1 -0
  437. package/dist/routing/build-command-groups.js.map +1 -1
  438. package/dist/sagas/index.d.ts +1 -1
  439. package/dist/sagas/index.d.ts.map +1 -1
  440. package/dist/sagas/index.js +1 -1
  441. package/dist/sagas/index.js.map +1 -1
  442. package/dist/sagas/reconcile.d.ts +24 -4
  443. package/dist/sagas/reconcile.d.ts.map +1 -1
  444. package/dist/sagas/reconcile.js +226 -100
  445. package/dist/sagas/reconcile.js.map +1 -1
  446. package/dist/scaffold/ensure-config.d.ts.map +1 -1
  447. package/dist/scaffold/ensure-config.js +31 -1
  448. package/dist/scaffold/ensure-config.js.map +1 -1
  449. package/dist/scaffold/project-identity.d.ts +2 -8
  450. package/dist/scaffold/project-identity.d.ts.map +1 -1
  451. package/dist/scaffold/project-identity.js +5 -21
  452. package/dist/scaffold/project-identity.js.map +1 -1
  453. package/dist/security/input-sanitization.d.ts +9 -1
  454. package/dist/security/input-sanitization.d.ts.map +1 -1
  455. package/dist/security/input-sanitization.js +12 -2
  456. package/dist/security/input-sanitization.js.map +1 -1
  457. package/dist/selfimprove/fix-gen.js +4321 -1807
  458. package/dist/selfimprove/fix-gen.js.map +3 -3
  459. package/dist/sentient/propose-tick.d.ts.map +1 -1
  460. package/dist/sentient/propose-tick.js +4 -2
  461. package/dist/sentient/propose-tick.js.map +1 -1
  462. package/dist/sequence/index.d.ts.map +1 -1
  463. package/dist/sequence/index.js +6 -23
  464. package/dist/sequence/index.js.map +1 -1
  465. package/dist/session/engine-ops.d.ts +9 -0
  466. package/dist/session/engine-ops.d.ts.map +1 -1
  467. package/dist/session/engine-ops.js +110 -18
  468. package/dist/session/engine-ops.js.map +1 -1
  469. package/dist/sessions/assumptions.d.ts.map +1 -1
  470. package/dist/sessions/assumptions.js +7 -4
  471. package/dist/sessions/assumptions.js.map +1 -1
  472. package/dist/sessions/briefing.d.ts +6 -0
  473. package/dist/sessions/briefing.d.ts.map +1 -1
  474. package/dist/sessions/briefing.js +12 -1
  475. package/dist/sessions/briefing.js.map +1 -1
  476. package/dist/sessions/decisions.d.ts +38 -3
  477. package/dist/sessions/decisions.d.ts.map +1 -1
  478. package/dist/sessions/decisions.js +235 -21
  479. package/dist/sessions/decisions.js.map +1 -1
  480. package/dist/sessions/drift-watchdog.d.ts.map +1 -1
  481. package/dist/sessions/drift-watchdog.js +4 -2
  482. package/dist/sessions/drift-watchdog.js.map +1 -1
  483. package/dist/sessions/index.d.ts.map +1 -1
  484. package/dist/sessions/index.js +33 -4
  485. package/dist/sessions/index.js.map +1 -1
  486. package/dist/sessions/session-end-snapshot-entry.d.ts +26 -0
  487. package/dist/sessions/session-end-snapshot-entry.d.ts.map +1 -0
  488. package/dist/sessions/session-end-snapshot-entry.js +59 -0
  489. package/dist/sessions/session-end-snapshot-entry.js.map +1 -0
  490. package/dist/sessions/session-end-snapshot.d.ts +114 -0
  491. package/dist/sessions/session-end-snapshot.d.ts.map +1 -0
  492. package/dist/sessions/session-end-snapshot.js +446 -0
  493. package/dist/sessions/session-end-snapshot.js.map +1 -0
  494. package/dist/sessions/session-manifest-mirror.d.ts.map +1 -1
  495. package/dist/sessions/session-manifest-mirror.js +10 -17
  496. package/dist/sessions/session-manifest-mirror.js.map +1 -1
  497. package/dist/sessions/session-switch.d.ts.map +1 -1
  498. package/dist/sessions/session-switch.js +5 -3
  499. package/dist/sessions/session-switch.js.map +1 -1
  500. package/dist/sessions/snapshot.d.ts.map +1 -1
  501. package/dist/sessions/snapshot.js +5 -4
  502. package/dist/sessions/snapshot.js.map +1 -1
  503. package/dist/sessions/terminal-identity.d.ts +169 -0
  504. package/dist/sessions/terminal-identity.d.ts.map +1 -0
  505. package/dist/sessions/terminal-identity.js +273 -0
  506. package/dist/sessions/terminal-identity.js.map +1 -0
  507. package/dist/setup/sections/verification.d.ts +1 -1
  508. package/dist/setup/sections/verification.d.ts.map +1 -1
  509. package/dist/setup/sections/verification.js +11 -15
  510. package/dist/setup/sections/verification.js.map +1 -1
  511. package/dist/skills/discovery.d.ts +8 -2
  512. package/dist/skills/discovery.d.ts.map +1 -1
  513. package/dist/skills/discovery.js +15 -3
  514. package/dist/skills/discovery.js.map +1 -1
  515. package/dist/skills/dispatch.d.ts +5 -2
  516. package/dist/skills/dispatch.d.ts.map +1 -1
  517. package/dist/skills/dispatch.js +5 -2
  518. package/dist/skills/dispatch.js.map +1 -1
  519. package/dist/skills/doctor.d.ts.map +1 -1
  520. package/dist/skills/doctor.js +5 -1
  521. package/dist/skills/doctor.js.map +1 -1
  522. package/dist/skills/federated-search.js +2 -2
  523. package/dist/skills/federated-search.js.map +1 -1
  524. package/dist/skills/index.d.ts +3 -3
  525. package/dist/skills/index.d.ts.map +1 -1
  526. package/dist/skills/index.js +1 -1
  527. package/dist/skills/index.js.map +1 -1
  528. package/dist/skills/migration.d.ts +5 -5
  529. package/dist/skills/migration.d.ts.map +1 -1
  530. package/dist/skills/migration.js +7 -9
  531. package/dist/skills/migration.js.map +1 -1
  532. package/dist/skills/orchestrator/startup.d.ts.map +1 -1
  533. package/dist/skills/orchestrator/startup.js +4 -2
  534. package/dist/skills/orchestrator/startup.js.map +1 -1
  535. package/dist/skills/skill-paths.d.ts +30 -3
  536. package/dist/skills/skill-paths.d.ts.map +1 -1
  537. package/dist/skills/skill-paths.js +28 -9
  538. package/dist/skills/skill-paths.js.map +1 -1
  539. package/dist/skills/skill-root.d.ts +60 -11
  540. package/dist/skills/skill-root.d.ts.map +1 -1
  541. package/dist/skills/skill-root.js +100 -14
  542. package/dist/skills/skill-root.js.map +1 -1
  543. package/dist/skills/skills-guard.js +5 -5
  544. package/dist/skills/skills-guard.js.map +1 -1
  545. package/dist/skills/types.d.ts +23 -0
  546. package/dist/skills/types.d.ts.map +1 -1
  547. package/dist/skills/types.js.map +1 -1
  548. package/dist/spawn/agent-identity.d.ts +51 -2
  549. package/dist/spawn/agent-identity.d.ts.map +1 -1
  550. package/dist/spawn/agent-identity.js +89 -26
  551. package/dist/spawn/agent-identity.js.map +1 -1
  552. package/dist/spawn/branch-lock.d.ts.map +1 -1
  553. package/dist/spawn/branch-lock.js +56 -79
  554. package/dist/spawn/branch-lock.js.map +1 -1
  555. package/dist/spawn/index.d.ts +2 -2
  556. package/dist/spawn/index.d.ts.map +1 -1
  557. package/dist/spawn/index.js +1 -1
  558. package/dist/spawn/index.js.map +1 -1
  559. package/dist/spawn/worktree-lock-holder.d.ts +37 -0
  560. package/dist/spawn/worktree-lock-holder.d.ts.map +1 -0
  561. package/dist/spawn/worktree-lock-holder.js +41 -0
  562. package/dist/spawn/worktree-lock-holder.js.map +1 -0
  563. package/dist/sticky/convert.d.ts.map +1 -1
  564. package/dist/sticky/convert.js +16 -4
  565. package/dist/sticky/convert.js.map +1 -1
  566. package/dist/store/attachment-store.d.ts +14 -0
  567. package/dist/store/attachment-store.d.ts.map +1 -1
  568. package/dist/store/attachment-store.js +11 -1
  569. package/dist/store/attachment-store.js.map +1 -1
  570. package/dist/store/backup-inspect.d.ts +7 -3
  571. package/dist/store/backup-inspect.d.ts.map +1 -1
  572. package/dist/store/backup-inspect.js +18 -7
  573. package/dist/store/backup-inspect.js.map +1 -1
  574. package/dist/store/backup-sidecar.d.ts +60 -0
  575. package/dist/store/backup-sidecar.d.ts.map +1 -0
  576. package/dist/store/backup-sidecar.js +96 -0
  577. package/dist/store/backup-sidecar.js.map +1 -0
  578. package/dist/store/data-accessor.d.ts +1 -1
  579. package/dist/store/data-accessor.d.ts.map +1 -1
  580. package/dist/store/data-accessor.js +6 -6
  581. package/dist/store/data-accessor.js.map +1 -1
  582. package/dist/store/data-safety-central.d.ts +13 -4
  583. package/dist/store/data-safety-central.d.ts.map +1 -1
  584. package/dist/store/data-safety-central.js +31 -4
  585. package/dist/store/data-safety-central.js.map +1 -1
  586. package/dist/store/dual-scope-db.d.ts.map +1 -1
  587. package/dist/store/dual-scope-db.js +10 -0
  588. package/dist/store/dual-scope-db.js.map +1 -1
  589. package/dist/store/exodus/__fixtures__/representative-fixture.d.ts.map +1 -1
  590. package/dist/store/exodus/__fixtures__/representative-fixture.js +4 -0
  591. package/dist/store/exodus/__fixtures__/representative-fixture.js.map +1 -1
  592. package/dist/store/exodus/migrate.js +1 -1
  593. package/dist/store/exodus/migrate.js.map +1 -1
  594. package/dist/store/exodus/reconcile.js +1 -1
  595. package/dist/store/exodus/reconcile.js.map +1 -1
  596. package/dist/store/exodus/runtime-targets.d.ts +4 -3
  597. package/dist/store/exodus/runtime-targets.d.ts.map +1 -1
  598. package/dist/store/exodus/runtime-targets.js +4 -3
  599. package/dist/store/exodus/runtime-targets.js.map +1 -1
  600. package/dist/store/import-logging.d.ts.map +1 -1
  601. package/dist/store/import-logging.js +5 -4
  602. package/dist/store/import-logging.js.map +1 -1
  603. package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
  604. package/dist/store/legacy-tasks-lineage.js +2 -7
  605. package/dist/store/legacy-tasks-lineage.js.map +1 -1
  606. package/dist/store/lock.d.ts +1 -0
  607. package/dist/store/lock.d.ts.map +1 -1
  608. package/dist/store/lock.js +1 -0
  609. package/dist/store/lock.js.map +1 -1
  610. package/dist/store/memory-accessor.d.ts +8 -3
  611. package/dist/store/memory-accessor.d.ts.map +1 -1
  612. package/dist/store/memory-accessor.js +29 -13
  613. package/dist/store/memory-accessor.js.map +1 -1
  614. package/dist/store/memory-sqlite.d.ts.map +1 -1
  615. package/dist/store/memory-sqlite.js +5 -0
  616. package/dist/store/memory-sqlite.js.map +1 -1
  617. package/dist/store/open-cleo-db.d.ts.map +1 -1
  618. package/dist/store/open-cleo-db.js +11 -6
  619. package/dist/store/open-cleo-db.js.map +1 -1
  620. package/dist/store/portable-bundle-relocate.d.ts +13 -8
  621. package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
  622. package/dist/store/portable-bundle-relocate.js +75 -31
  623. package/dist/store/portable-bundle-relocate.js.map +1 -1
  624. package/dist/store/portable-bundle-scan.d.ts.map +1 -1
  625. package/dist/store/portable-bundle-scan.js +2 -1
  626. package/dist/store/portable-bundle-scan.js.map +1 -1
  627. package/dist/store/portable-bundle.d.ts.map +1 -1
  628. package/dist/store/portable-bundle.js +7 -3
  629. package/dist/store/portable-bundle.js.map +1 -1
  630. package/dist/store/pre-repair-snapshot.d.ts +77 -0
  631. package/dist/store/pre-repair-snapshot.d.ts.map +1 -0
  632. package/dist/store/pre-repair-snapshot.js +122 -0
  633. package/dist/store/pre-repair-snapshot.js.map +1 -0
  634. package/dist/store/regenerators.d.ts +2 -1
  635. package/dist/store/regenerators.d.ts.map +1 -1
  636. package/dist/store/regenerators.js +17 -3
  637. package/dist/store/regenerators.js.map +1 -1
  638. package/dist/store/relocated-store-guard.d.ts +71 -0
  639. package/dist/store/relocated-store-guard.d.ts.map +1 -0
  640. package/dist/store/relocated-store-guard.js +138 -0
  641. package/dist/store/relocated-store-guard.js.map +1 -0
  642. package/dist/store/safety-data-accessor.d.ts +2 -2
  643. package/dist/store/safety-data-accessor.d.ts.map +1 -1
  644. package/dist/store/safety-data-accessor.js +2 -2
  645. package/dist/store/safety-data-accessor.js.map +1 -1
  646. package/dist/store/schema/attachments.d.ts +2 -2
  647. package/dist/store/schema/audit.d.ts +5 -5
  648. package/dist/store/schema/background-jobs.d.ts +1 -1
  649. package/dist/store/schema/cleo-global/models-catalog.d.ts +1 -1
  650. package/dist/store/schema/cleo-global/nexus.d.ts +686 -0
  651. package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
  652. package/dist/store/schema/cleo-global/nexus.js +175 -7
  653. package/dist/store/schema/cleo-global/nexus.js.map +1 -1
  654. package/dist/store/schema/cleo-global/skills.d.ts +2 -2
  655. package/dist/store/schema/cleo-project/audit.d.ts +5 -5
  656. package/dist/store/schema/cleo-project/docs.d.ts +3 -3
  657. package/dist/store/schema/cleo-project/lifecycle.d.ts +3 -3
  658. package/dist/store/schema/cleo-project/provenance-commits.d.ts +2 -2
  659. package/dist/store/schema/cleo-project/provenance-rest.d.ts +3 -3
  660. package/dist/store/schema/cleo-project/tasks-core-batch2.d.ts +1 -1
  661. package/dist/store/schema/cleo-project/tasks-core.d.ts +6 -6
  662. package/dist/store/schema/cleo-shared/brain.d.ts +26 -26
  663. package/dist/store/schema/lifecycle.d.ts +3 -3
  664. package/dist/store/schema/manifest.d.ts +1 -1
  665. package/dist/store/schema/memory-schema.d.ts +26 -26
  666. package/dist/store/schema/nexus-schema.d.ts +696 -2
  667. package/dist/store/schema/nexus-schema.d.ts.map +1 -1
  668. package/dist/store/schema/nexus-schema.js +175 -19
  669. package/dist/store/schema/nexus-schema.js.map +1 -1
  670. package/dist/store/schema/provenance/releases.d.ts +1 -1
  671. package/dist/store/schema/skills-schema.d.ts +2 -2
  672. package/dist/store/schema/tasks.d.ts +5 -5
  673. package/dist/store/session-binding-schema.d.ts +132 -0
  674. package/dist/store/session-binding-schema.d.ts.map +1 -0
  675. package/dist/store/session-binding-schema.js +53 -0
  676. package/dist/store/session-binding-schema.js.map +1 -0
  677. package/dist/store/session-store.d.ts +262 -4
  678. package/dist/store/session-store.d.ts.map +1 -1
  679. package/dist/store/session-store.js +486 -26
  680. package/dist/store/session-store.js.map +1 -1
  681. package/dist/store/snapshot-gate.d.ts +239 -0
  682. package/dist/store/snapshot-gate.d.ts.map +1 -0
  683. package/dist/store/snapshot-gate.js +398 -0
  684. package/dist/store/snapshot-gate.js.map +1 -0
  685. package/dist/store/split-brain-import.js +2 -2
  686. package/dist/store/split-brain-import.js.map +1 -1
  687. package/dist/store/sqlite-backup.d.ts +55 -13
  688. package/dist/store/sqlite-backup.d.ts.map +1 -1
  689. package/dist/store/sqlite-backup.js +414 -106
  690. package/dist/store/sqlite-backup.js.map +1 -1
  691. package/dist/store/sqlite-data-accessor.d.ts +15 -0
  692. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  693. package/dist/store/sqlite-data-accessor.js +63 -4
  694. package/dist/store/sqlite-data-accessor.js.map +1 -1
  695. package/dist/store/sqlite.d.ts +1 -1
  696. package/dist/store/sqlite.d.ts.map +1 -1
  697. package/dist/store/sqlite.js +53 -5
  698. package/dist/store/sqlite.js.map +1 -1
  699. package/dist/store/store-write-guard.d.ts +28 -0
  700. package/dist/store/store-write-guard.d.ts.map +1 -0
  701. package/dist/store/store-write-guard.js +50 -0
  702. package/dist/store/store-write-guard.js.map +1 -0
  703. package/dist/store/table-classification.d.ts +143 -0
  704. package/dist/store/table-classification.d.ts.map +1 -0
  705. package/dist/store/table-classification.js +1866 -0
  706. package/dist/store/table-classification.js.map +1 -0
  707. package/dist/store/task-version.d.ts +72 -0
  708. package/dist/store/task-version.d.ts.map +1 -0
  709. package/dist/store/task-version.js +93 -0
  710. package/dist/store/task-version.js.map +1 -0
  711. package/dist/store/tasks-schema.d.ts +1 -0
  712. package/dist/store/tasks-schema.d.ts.map +1 -1
  713. package/dist/store/tasks-schema.js +13 -0
  714. package/dist/store/tasks-schema.js.map +1 -1
  715. package/dist/store/tasks-sqlite.d.ts +10 -3
  716. package/dist/store/tasks-sqlite.d.ts.map +1 -1
  717. package/dist/store/tasks-sqlite.js +12 -3
  718. package/dist/store/tasks-sqlite.js.map +1 -1
  719. package/dist/store/twin-collapse.d.ts +275 -0
  720. package/dist/store/twin-collapse.d.ts.map +1 -0
  721. package/dist/store/twin-collapse.js +805 -0
  722. package/dist/store/twin-collapse.js.map +1 -0
  723. package/dist/store/umbrella-data-accessor.d.ts +2 -2
  724. package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
  725. package/dist/store/umbrella-data-accessor.js +2 -2
  726. package/dist/store/umbrella-data-accessor.js.map +1 -1
  727. package/dist/store/validation-schemas.d.ts +63 -63
  728. package/dist/store/worktree-isolation-guard.d.ts +46 -24
  729. package/dist/store/worktree-isolation-guard.d.ts.map +1 -1
  730. package/dist/store/worktree-isolation-guard.js +69 -50
  731. package/dist/store/worktree-isolation-guard.js.map +1 -1
  732. package/dist/system/backup.d.ts.map +1 -1
  733. package/dist/system/backup.js +3 -67
  734. package/dist/system/backup.js.map +1 -1
  735. package/dist/system/cleo-link.d.ts +163 -0
  736. package/dist/system/cleo-link.d.ts.map +1 -0
  737. package/dist/system/cleo-link.js +246 -0
  738. package/dist/system/cleo-link.js.map +1 -0
  739. package/dist/system/dependencies.d.ts.map +1 -1
  740. package/dist/system/dependencies.js +3 -6
  741. package/dist/system/dependencies.js.map +1 -1
  742. package/dist/system/global-delivery.d.ts +205 -0
  743. package/dist/system/global-delivery.d.ts.map +1 -0
  744. package/dist/system/global-delivery.js +320 -0
  745. package/dist/system/global-delivery.js.map +1 -0
  746. package/dist/system/health.d.ts.map +1 -1
  747. package/dist/system/health.js +29 -6
  748. package/dist/system/health.js.map +1 -1
  749. package/dist/system/project-health.d.ts.map +1 -1
  750. package/dist/system/project-health.js +1 -20
  751. package/dist/system/project-health.js.map +1 -1
  752. package/dist/system/runtime.d.ts.map +1 -1
  753. package/dist/system/runtime.js +2 -12
  754. package/dist/system/runtime.js.map +1 -1
  755. package/dist/system/safestop.d.ts.map +1 -1
  756. package/dist/system/safestop.js +5 -2
  757. package/dist/system/safestop.js.map +1 -1
  758. package/dist/system/skill-fixtures.d.ts +200 -0
  759. package/dist/system/skill-fixtures.d.ts.map +1 -0
  760. package/dist/system/skill-fixtures.js +331 -0
  761. package/dist/system/skill-fixtures.js.map +1 -0
  762. package/dist/tasks/add.d.ts.map +1 -1
  763. package/dist/tasks/add.js +4 -2
  764. package/dist/tasks/add.js.map +1 -1
  765. package/dist/tasks/affected-packages.d.ts +173 -0
  766. package/dist/tasks/affected-packages.d.ts.map +1 -0
  767. package/dist/tasks/affected-packages.js +389 -0
  768. package/dist/tasks/affected-packages.js.map +1 -0
  769. package/dist/tasks/change-set.d.ts +151 -0
  770. package/dist/tasks/change-set.d.ts.map +1 -0
  771. package/dist/tasks/change-set.js +634 -0
  772. package/dist/tasks/change-set.js.map +1 -0
  773. package/dist/tasks/complete.d.ts.map +1 -1
  774. package/dist/tasks/complete.js +10 -5
  775. package/dist/tasks/complete.js.map +1 -1
  776. package/dist/tasks/done-plan.d.ts +103 -0
  777. package/dist/tasks/done-plan.d.ts.map +1 -0
  778. package/dist/tasks/done-plan.js +541 -0
  779. package/dist/tasks/done-plan.js.map +1 -0
  780. package/dist/tasks/done-record.d.ts +127 -0
  781. package/dist/tasks/done-record.d.ts.map +1 -0
  782. package/dist/tasks/done-record.js +373 -0
  783. package/dist/tasks/done-record.js.map +1 -0
  784. package/dist/tasks/duplicate-detector.d.ts +68 -11
  785. package/dist/tasks/duplicate-detector.d.ts.map +1 -1
  786. package/dist/tasks/duplicate-detector.js +314 -58
  787. package/dist/tasks/duplicate-detector.js.map +1 -1
  788. package/dist/tasks/evidence-paths.d.ts +78 -0
  789. package/dist/tasks/evidence-paths.d.ts.map +1 -0
  790. package/dist/tasks/evidence-paths.js +150 -0
  791. package/dist/tasks/evidence-paths.js.map +1 -0
  792. package/dist/tasks/evidence.d.ts +55 -0
  793. package/dist/tasks/evidence.d.ts.map +1 -1
  794. package/dist/tasks/evidence.js +223 -26
  795. package/dist/tasks/evidence.js.map +1 -1
  796. package/dist/tasks/gate-preview.d.ts +5 -0
  797. package/dist/tasks/gate-preview.d.ts.map +1 -1
  798. package/dist/tasks/gate-preview.js +25 -21
  799. package/dist/tasks/gate-preview.js.map +1 -1
  800. package/dist/tasks/gate-result-cache.d.ts +205 -0
  801. package/dist/tasks/gate-result-cache.d.ts.map +1 -0
  802. package/dist/tasks/gate-result-cache.js +285 -0
  803. package/dist/tasks/gate-result-cache.js.map +1 -0
  804. package/dist/tasks/gate-runner.d.ts +126 -3
  805. package/dist/tasks/gate-runner.d.ts.map +1 -1
  806. package/dist/tasks/gate-runner.js +483 -28
  807. package/dist/tasks/gate-runner.js.map +1 -1
  808. package/dist/tasks/session-scope.d.ts +3 -1
  809. package/dist/tasks/session-scope.d.ts.map +1 -1
  810. package/dist/tasks/session-scope.js +18 -3
  811. package/dist/tasks/session-scope.js.map +1 -1
  812. package/dist/tasks/tool-resolver.d.ts +23 -6
  813. package/dist/tasks/tool-resolver.d.ts.map +1 -1
  814. package/dist/tasks/tool-resolver.js +146 -8
  815. package/dist/tasks/tool-resolver.js.map +1 -1
  816. package/dist/tasks/tool-vacuity.d.ts +71 -0
  817. package/dist/tasks/tool-vacuity.d.ts.map +1 -0
  818. package/dist/tasks/tool-vacuity.js +334 -0
  819. package/dist/tasks/tool-vacuity.js.map +1 -0
  820. package/dist/tasks/update.d.ts +8 -0
  821. package/dist/tasks/update.d.ts.map +1 -1
  822. package/dist/tasks/update.js +159 -78
  823. package/dist/tasks/update.js.map +1 -1
  824. package/dist/upgrade.d.ts.map +1 -1
  825. package/dist/upgrade.js +18 -2
  826. package/dist/upgrade.js.map +1 -1
  827. package/dist/validation/doctor/checks.d.ts +20 -2
  828. package/dist/validation/doctor/checks.d.ts.map +1 -1
  829. package/dist/validation/doctor/checks.js +64 -4
  830. package/dist/validation/doctor/checks.js.map +1 -1
  831. package/dist/validation/doctor/index.d.ts +1 -1
  832. package/dist/validation/doctor/index.d.ts.map +1 -1
  833. package/dist/validation/doctor/index.js +1 -1
  834. package/dist/validation/doctor/index.js.map +1 -1
  835. package/dist/validation/doctor/utils.d.ts.map +1 -1
  836. package/dist/validation/doctor/utils.js +7 -2
  837. package/dist/validation/doctor/utils.js.map +1 -1
  838. package/dist/validation/engine-ops.d.ts +15 -0
  839. package/dist/validation/engine-ops.d.ts.map +1 -1
  840. package/dist/validation/engine-ops.js +249 -98
  841. package/dist/validation/engine-ops.js.map +1 -1
  842. package/migrations/drizzle-cleo-global/20260927000000_t12469-project-locations/migration.sql +121 -0
  843. package/migrations/drizzle-cleo-global/20260927010000_t12543-user-profile-project-scope/migration.sql +23 -0
  844. package/migrations/drizzle-cleo-global/20260928010000_t12470-location-candidates/migration.sql +72 -0
  845. package/migrations/drizzle-cleo-global/20260928020000_t12510-nexus-devices/migration.sql +34 -0
  846. package/migrations/drizzle-cleo-global/20260928030000_t12511-project-git-state/migration.sql +62 -0
  847. package/migrations/drizzle-cleo-project/20260927000000_t12499-session-terminal-bindings/migration.sql +34 -0
  848. package/migrations/drizzle-cleo-project/20260928000000_t12500-binding-provider-flag/migration.sql +15 -0
  849. package/package.json +23 -13
  850. package/schemas/config.schema.json +54 -0
  851. package/schemas/project-context.schema.json +51 -3
  852. package/schemas/project-info.schema.json +28 -1
  853. package/templates/CLEO-INJECTION.md +40 -332
  854. package/templates/CLEO-REFERENCE.md +303 -0
  855. package/templates/workflows/README.md +36 -14
@@ -0,0 +1,805 @@
1
+ /**
2
+ * Twin collapses (T12535): keep a prefixed twin in step with its BARE legacy
3
+ * table, which stays authoritative while an older CLEO build still writes it.
4
+ *
5
+ * ## Why
6
+ *
7
+ * The project `cleo.db` carries legacy bare tables beside their prefixed (E6)
8
+ * twins. For `schema_meta` and `sticky_tags` the runtime wrote the bare table
9
+ * while the twin held a frozen exodus copy. This build reads and writes only
10
+ * the twin. The release before it (2026.9.20) is still installed on machines
11
+ * that share project stores and keeps writing the bare tables, so the collapse
12
+ * runs at every open:
13
+ *
14
+ * - **Initial collapse** (no marker yet): check the free space, snapshot the
15
+ * store, then fold the bare table into the twin, bare-authoritative.
16
+ * - **Incremental re-merge** (marker present): carry over only the bare keys
17
+ * (sticky ids) whose hash changed since the last merge. No snapshot. An
18
+ * unchanged bare table costs one read of it and no write.
19
+ *
20
+ * A later release removes the incremental re-merge once no supported build
21
+ * writes the bare tables; slice 3 then drops them after a backup.
22
+ *
23
+ * ## State and provenance
24
+ *
25
+ * The marker row `twin_collapse:<bare table>` in the twin's key/value table
26
+ * holds, per key (`schema_meta`) or per sticky id (`sticky_tags`), a sha256
27
+ * of the BARE value and of the TWIN value as of the last merge. A bare hash
28
+ * that moved means the older build wrote it; a twin hash that moved means this
29
+ * build wrote it.
30
+ *
31
+ * ## Rules
32
+ *
33
+ * The bare row is authoritative for every key. A monotonic counter FIELD is
34
+ * merged on its own: the result is the bare value with that field set to
35
+ * max(bare, twin). A whole twin value never replaces a bare one
36
+ * ({@link mergeSchemaMetaValue}).
37
+ *
38
+ * | `schema_meta` key | Counter field |
39
+ * |---|---|
40
+ * | `task_id_sequence` (`{counter,lastId,checksum}` from `sequence/index.ts`, or a plain number) | `counter` (a plain number takes the max of the two numbers) |
41
+ * | `sqlite_snapshot_gate` (`{generation,prefixes}`, `snapshot-gate.ts`) | `generation` |
42
+ * | `file_meta` (`FileMeta`; `session/engine-ops.ts` bumps `generation` on session start/end/resume) | `generation` |
43
+ * | `backfill:*` (the two `t877` guard keys) | not carried: the lineage re-inserts them into every bare table and nothing reads them |
44
+ * | `twin_collapse*` | not carried: collapse state and failures live only in the twin |
45
+ * | every other key (`schemaVersion`, `version`, `focus_state`, `focus_state:<session>`, `project_meta`, `project`, `parallel_state`, `activeSession`, `reconcile.<task>.release`, any unknown key) | none: the bare value |
46
+ *
47
+ * - **Initial collapse**, when the bare table holds at least one carried key:
48
+ * every bare key is carried under the rules, and a key only the twin holds
49
+ * is a frozen copy and is DROPPED (listed in the receipt, marker and log).
50
+ * The exceptions are `task_id_sequence` and `sqlite_snapshot_gate` (a
51
+ * counter must not move back) and the collapse keys. `file_meta` is dropped
52
+ * only when the bare table lacks it; when both have it the field rule
53
+ * applies. When the bare table holds no carried key (a fresh lineage, e.g.
54
+ * after exodus landed legacy rows in the twin), nothing is dropped.
55
+ * - **Incremental re-merge**, per bare key whose hash changed since the last
56
+ * merge:
57
+ * - twin unchanged since the last merge → the bare value (counter fields
58
+ * maxed);
59
+ * - twin ALSO changed (this build wrote it too) → CONFLICT: the TWIN value
60
+ * wins, recorded in the marker and reported by `cleo doctor` as a warning.
61
+ * A counter key is never a conflict: the twin value is kept with its
62
+ * counter field maxed against the bare one.
63
+ * A key the older build deleted is deleted from the twin unless the twin
64
+ * changed it too (conflict) or it is `task_id_sequence` /
65
+ * `sqlite_snapshot_gate`. A key the bare table never changed is never
66
+ * touched.
67
+ *
68
+ * `sticky_tags` → `brain_sticky_tags` (rows are `(sticky_id, tag)`, both the
69
+ * key, so a collision is two identical rows and one is kept):
70
+ *
71
+ * - Initial collapse, when the bare table has rows: the twin is made equal to
72
+ * the bare set; frozen twin-only rows are dropped and listed. A bare tag whose
73
+ * note no longer exists is not carried (`skipped`; it stays in the bare table).
74
+ * - Incremental re-merge, per sticky id whose bare tag-set hash changed: if
75
+ * the twin's set for that id is unchanged since the last merge, the twin
76
+ * set is made equal to the bare set (additions AND removals propagate);
77
+ * if the twin set changed too, the twin wins and a conflict is recorded.
78
+ *
79
+ * ## Contract
80
+ *
81
+ * 1. **Snapshot first** (initial collapse only, only when the merge changes
82
+ * the twin). The free space is checked before the `VACUUM INTO`. One
83
+ * snapshot covers every pair collapsing in this open, registered as a
84
+ * `migration` backup (`cleo backup list`, rotation).
85
+ * 2. **Atomic.** Each pair merges, verifies and writes its marker in one
86
+ * `BEGIN IMMEDIATE` transaction, the marker re-read under the write lock.
87
+ * Any failure rolls back: both tables byte-identical.
88
+ * 3. **Verified.** Every row the merge decided is re-read and compared before
89
+ * the marker is written; a mismatch rolls back.
90
+ * 4. **The bare table is never written.**
91
+ * 5. **Never locked out** (inside a domain bind, `onFailure: 'degrade'`). A
92
+ * failed or impossible collapse does not fail the bind. The failure is
93
+ * recorded (`twin_collapse_failed:<table>`), and the connection is put in a
94
+ * READ-ONLY-FOR-USERS mode: the merged view the collapse would have
95
+ * committed is computed in memory and served from TEMP shadow tables of the
96
+ * same names (unqualified SQL resolves `temp` before `main`), so reads see
97
+ * bare-authoritative data while `main` stays untouched. Mutating operations
98
+ * are refused with `E_TWIN_COLLAPSE_FAILED` by the dispatch write guard
99
+ * ({@link twinCollapseFailureOf}), and the shadows carry TEMP triggers that
100
+ * abort any write into them ({@link SHADOW_WRITE_REFUSED}), so a direct SDK
101
+ * write fails instead of being lost. `cleo doctor twin-collapse --retry`
102
+ * runs the collapse with `onFailure: 'throw'`; on success the shadows and
103
+ * their triggers are dropped.
104
+ *
105
+ * ## Gate 28
106
+ *
107
+ * This module is a sanctioned writer (`scripts/lint-no-raw-table-writes.mjs`
108
+ * SANCTIONED): it runs on the chokepoint handle inside the domain bind, and the
109
+ * accessors import the modules that call it.
110
+ *
111
+ * @module
112
+ * @task T12535
113
+ */
114
+ import { createHash } from 'node:crypto';
115
+ import { ExitCode } from '@cleocode/contracts';
116
+ import { CleoError } from '../errors.js';
117
+ import { getLogger } from '../logger.js';
118
+ import { planMigrationSnapshot, writeMigrationSnapshot } from './pre-repair-snapshot.js';
119
+ import { SNAPSHOT_GATE_META_KEY } from './snapshot-gate.js';
120
+ const log = getLogger('twin-collapse');
121
+ /** Prefix of the marker key holding a pair's collapse state. */
122
+ export const TWIN_COLLAPSE_MARKER_PREFIX = 'twin_collapse:';
123
+ /** Prefix of the key recording a pair's last failed collapse. */
124
+ export const TWIN_COLLAPSE_FAILURE_PREFIX = 'twin_collapse_failed:';
125
+ /** `schema_meta` keys whose named field is a monotonic counter (merged as max). */
126
+ export const SCHEMA_META_COUNTER_FIELDS = {
127
+ task_id_sequence: 'counter',
128
+ [SNAPSHOT_GATE_META_KEY]: 'generation',
129
+ file_meta: 'generation',
130
+ };
131
+ /** `schema_meta` keys never deleted from the twin (a counter never moves back). */
132
+ export const SCHEMA_META_NEVER_DELETED = new Set([
133
+ 'task_id_sequence',
134
+ SNAPSHOT_GATE_META_KEY,
135
+ ]);
136
+ /** Most conflicts kept in the marker (the doctor warning lists them). */
137
+ const MAX_CONFLICTS = 50;
138
+ const sha = (value) => createHash('sha256').update(value).digest('hex');
139
+ /** Hash of an absent value (distinct from any real value's hash). */
140
+ const ABSENT = sha('\u0000absent');
141
+ function hasMainTable(db, name) {
142
+ return (db.prepare("SELECT 1 FROM main.sqlite_master WHERE type = 'table' AND name = ?").get(name) !==
143
+ undefined);
144
+ }
145
+ function readKv(db, kvTable, key) {
146
+ return db.prepare(`SELECT value FROM main.${kvTable} WHERE key = ?`).get(key)?.value;
147
+ }
148
+ function writeKv(db, kvTable, key, value) {
149
+ db.prepare(`INSERT INTO main.${kvTable} (key, value) VALUES (?, ?) ` +
150
+ 'ON CONFLICT(key) DO UPDATE SET value = excluded.value').run(key, value);
151
+ }
152
+ function sameHashes(a, b) {
153
+ const ka = Object.keys(a);
154
+ return ka.length === Object.keys(b).length && ka.every((k) => a[k] === b[k]);
155
+ }
156
+ /** Parse a marker row; a pre-release marker (no hashes) yields `hashes: null`. */
157
+ function readState(db, pair) {
158
+ const raw = readKv(db, pair.kvTable, `${TWIN_COLLAPSE_MARKER_PREFIX}${pair.table}`);
159
+ if (raw === undefined)
160
+ return undefined;
161
+ let parsed = {};
162
+ try {
163
+ parsed = JSON.parse(raw);
164
+ }
165
+ catch {
166
+ parsed = {};
167
+ }
168
+ const str = (v) => (typeof v === 'string' ? v : '');
169
+ return {
170
+ version: 3,
171
+ task: 'T12535',
172
+ collapsedAt: str(parsed.collapsedAt),
173
+ lastMergedAt: str(parsed.lastMergedAt),
174
+ snapshot: typeof parsed.snapshot === 'string' ? parsed.snapshot : null,
175
+ hashes: parsed.version === 3 && parsed.hashes ? parsed.hashes : null,
176
+ dropped: Array.isArray(parsed.dropped) ? parsed.dropped : [],
177
+ conflicts: Array.isArray(parsed.conflicts) ? parsed.conflicts : [],
178
+ conflictsAt: typeof parsed.conflictsAt === 'string' ? parsed.conflictsAt : null,
179
+ };
180
+ }
181
+ /** Whether the bare side moved since the stored hashes (or no usable state exists). */
182
+ function bareChanged(db, pair, state) {
183
+ return !state?.hashes || !sameHashes(state.hashes.bare, pair.bareHashes(db));
184
+ }
185
+ /** Hashes of the last merge; a pre-release marker treats the current twin as unchanged. */
186
+ function lastHashes(db, pair, state) {
187
+ return state.hashes ?? { bare: {}, twin: pair.twinHashes(db) };
188
+ }
189
+ // ── schema_meta ──────────────────────────────────────────────────────────────
190
+ function parseJson(value) {
191
+ try {
192
+ return JSON.parse(value);
193
+ }
194
+ catch {
195
+ return undefined;
196
+ }
197
+ }
198
+ /** A counter field's value, whether the whole value is a number or an object holding it. */
199
+ function counterOf(value, field) {
200
+ const parsed = parseJson(value);
201
+ if (typeof parsed === 'number' && Number.isFinite(parsed))
202
+ return parsed;
203
+ if (parsed === null || typeof parsed !== 'object')
204
+ return undefined;
205
+ const n = parsed[field];
206
+ return typeof n === 'number' && Number.isFinite(n) ? n : undefined;
207
+ }
208
+ /**
209
+ * `base` with its counter field raised to the other value's counter when that
210
+ * is larger. `base` is returned verbatim otherwise, and when it has no
211
+ * counter to raise (not a number, not an object holding the field).
212
+ */
213
+ function withMaxCounter(base, other, field) {
214
+ if (other === undefined)
215
+ return base;
216
+ const b = counterOf(base, field);
217
+ const o = counterOf(other, field);
218
+ if (b === undefined || o === undefined || o <= b)
219
+ return base;
220
+ const parsed = parseJson(base);
221
+ if (typeof parsed === 'number')
222
+ return String(o);
223
+ return JSON.stringify({ ...parsed, [field]: o });
224
+ }
225
+ /** Whether a `schema_meta` key is carried at all. */
226
+ function carried(key) {
227
+ return !key.startsWith('backfill:') && !key.startsWith('twin_collapse');
228
+ }
229
+ /**
230
+ * The value a `schema_meta` key gets when the bare side is authoritative (the
231
+ * rule table is in the module comment).
232
+ *
233
+ * @param key - The key.
234
+ * @param bare - Its value in the bare table.
235
+ * @param twin - Its value in the twin, or `undefined` when absent.
236
+ * @returns The value to keep, or `null` when the key is not carried.
237
+ * @task T12535
238
+ */
239
+ export function mergeSchemaMetaValue(key, bare, twin) {
240
+ if (!carried(key))
241
+ return null;
242
+ const field = SCHEMA_META_COUNTER_FIELDS[key];
243
+ return field === undefined ? bare : withMaxCounter(bare, twin, field);
244
+ }
245
+ function kvRows(db, table, schema = 'main') {
246
+ const rows = db.prepare(`SELECT key, value FROM ${schema}.${table}`).all();
247
+ return new Map(rows.map((r) => [r.key, r.value]));
248
+ }
249
+ /** Carried rows of a `schema_meta` table. */
250
+ function carriedRows(db, table) {
251
+ const all = kvRows(db, table);
252
+ for (const key of [...all.keys()])
253
+ if (!carried(key))
254
+ all.delete(key);
255
+ return all;
256
+ }
257
+ const hashMap = (m) => Object.fromEntries([...m].map(([k, v]) => [k, sha(v)]));
258
+ const emptyPlan = () => ({ set: new Map(), del: [], dropped: [], conflicts: [], skipped: 0 });
259
+ function planSchemaMeta(db, state) {
260
+ const plan = emptyPlan();
261
+ const bare = carriedRows(db, 'schema_meta');
262
+ const twin = carriedRows(db, 'tasks_schema_meta');
263
+ const want = (key, value) => {
264
+ if (value !== null && value !== twin.get(key))
265
+ plan.set.set(key, value);
266
+ };
267
+ if (state === undefined) {
268
+ if (bare.size === 0)
269
+ return plan;
270
+ for (const [key, value] of bare)
271
+ want(key, mergeSchemaMetaValue(key, value, twin.get(key)));
272
+ for (const key of [...twin.keys()].sort()) {
273
+ if (!bare.has(key) && !SCHEMA_META_NEVER_DELETED.has(key)) {
274
+ plan.del.push(key);
275
+ plan.dropped.push(key);
276
+ }
277
+ }
278
+ return plan;
279
+ }
280
+ const last = lastHashes(db, SCHEMA_META, state);
281
+ const twinMoved = (key) => {
282
+ const now = twin.has(key) ? sha(twin.get(key)) : ABSENT;
283
+ return now !== (last.twin[key] ?? ABSENT);
284
+ };
285
+ for (const key of [...bare.keys()].sort()) {
286
+ const value = bare.get(key);
287
+ if (last.bare[key] === sha(value))
288
+ continue;
289
+ const field = SCHEMA_META_COUNTER_FIELDS[key];
290
+ const current = twin.get(key);
291
+ if (field !== undefined) {
292
+ // A counter is never a conflict: keep whichever side is authoritative
293
+ // for the rest of the value, and max the counter field against the other.
294
+ const base = twinMoved(key) && current !== undefined ? current : value;
295
+ want(key, withMaxCounter(base, base === value ? current : value, field));
296
+ }
297
+ else if (twinMoved(key)) {
298
+ plan.conflicts.push(key);
299
+ }
300
+ else {
301
+ want(key, value);
302
+ }
303
+ }
304
+ for (const key of Object.keys(last.bare).sort()) {
305
+ if (bare.has(key) || SCHEMA_META_NEVER_DELETED.has(key) || !twin.has(key))
306
+ continue;
307
+ if (twinMoved(key))
308
+ plan.conflicts.push(key);
309
+ else
310
+ plan.del.push(key);
311
+ }
312
+ return plan;
313
+ }
314
+ function applyKv(db, schema, table, plan) {
315
+ const before = kvRows(db, table, schema);
316
+ const upsert = db.prepare(`INSERT INTO ${schema}.${table} (key, value) VALUES (?, ?) ` +
317
+ 'ON CONFLICT(key) DO UPDATE SET value = excluded.value');
318
+ const del = db.prepare(`DELETE FROM ${schema}.${table} WHERE key = ?`);
319
+ let inserted = 0;
320
+ let replaced = 0;
321
+ let deleted = 0;
322
+ for (const [key, value] of plan.set) {
323
+ upsert.run(key, value);
324
+ if (before.has(key))
325
+ replaced++;
326
+ else
327
+ inserted++;
328
+ }
329
+ for (const key of plan.del)
330
+ deleted += Number(del.run(key).changes);
331
+ return { inserted, replaced, deleted };
332
+ }
333
+ const SCHEMA_META = {
334
+ table: 'schema_meta',
335
+ twin: 'tasks_schema_meta',
336
+ kvTable: 'tasks_schema_meta',
337
+ tables: ['schema_meta', 'tasks_schema_meta'],
338
+ bareHashes: (db) => hashMap(carriedRows(db, 'schema_meta')),
339
+ twinHashes: (db) => hashMap(carriedRows(db, 'tasks_schema_meta')),
340
+ plan: planSchemaMeta,
341
+ apply(db, plan) {
342
+ const counts = applyKv(db, 'main', 'tasks_schema_meta', plan);
343
+ for (const [key, value] of plan.set) {
344
+ if (readKv(db, 'tasks_schema_meta', key) !== value)
345
+ throw new Error(`schema_meta collapse did not verify for key ${JSON.stringify(key)}`);
346
+ }
347
+ for (const key of plan.del) {
348
+ if (readKv(db, 'tasks_schema_meta', key) !== undefined)
349
+ throw new Error(`schema_meta collapse did not verify the removal of ${JSON.stringify(key)}`);
350
+ }
351
+ return counts;
352
+ },
353
+ shadow(db, plan) {
354
+ db.exec('CREATE TEMP TABLE IF NOT EXISTS tasks_schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)');
355
+ db.exec('DELETE FROM temp.tasks_schema_meta');
356
+ db.exec('INSERT INTO temp.tasks_schema_meta (key, value) SELECT key, value FROM main.tasks_schema_meta');
357
+ applyKv(db, 'temp', 'tasks_schema_meta', plan);
358
+ },
359
+ };
360
+ // ── sticky_tags ──────────────────────────────────────────────────────────────
361
+ /** Tag sets by sticky id (tags sorted). */
362
+ function stickySets(db, table) {
363
+ const rows = db
364
+ .prepare(`SELECT sticky_id, tag FROM main.${table} ORDER BY sticky_id, tag`)
365
+ .all();
366
+ const out = new Map();
367
+ for (const r of rows) {
368
+ const tags = out.get(r.sticky_id) ?? [];
369
+ tags.push(r.tag);
370
+ out.set(r.sticky_id, tags);
371
+ }
372
+ return out;
373
+ }
374
+ const hashSets = (m) => Object.fromEntries([...m].map(([k, tags]) => [k, sha(JSON.stringify(tags))]));
375
+ const EMPTY_SET = sha(JSON.stringify([]));
376
+ function planSticky(db, state) {
377
+ const plan = emptyPlan();
378
+ const bare = stickySets(db, 'sticky_tags');
379
+ const twin = stickySets(db, 'brain_sticky_tags');
380
+ const noteExists = db.prepare('SELECT 1 FROM main.brain_sticky_notes WHERE id = ?');
381
+ /** Make the twin's set for `id` equal the bare set. */
382
+ const mirror = (id, dropping) => {
383
+ const b = new Set(bare.get(id) ?? []);
384
+ const t = new Set(twin.get(id) ?? []);
385
+ const alive = b.size === 0 || noteExists.get(id) !== undefined;
386
+ for (const tag of b) {
387
+ if (!alive)
388
+ plan.skipped++;
389
+ else if (!t.has(tag))
390
+ plan.set.set(`${id}\t${tag}`, '');
391
+ }
392
+ for (const tag of t) {
393
+ if (b.has(tag))
394
+ continue;
395
+ plan.del.push(`${id}\t${tag}`);
396
+ if (dropping)
397
+ plan.dropped.push(`${id}\t${tag}`);
398
+ }
399
+ };
400
+ if (state === undefined) {
401
+ if (bare.size === 0)
402
+ return plan;
403
+ for (const id of [...new Set([...bare.keys(), ...twin.keys()])].sort())
404
+ mirror(id, true);
405
+ return plan;
406
+ }
407
+ const last = lastHashes(db, STICKY_TAGS, state);
408
+ const ids = new Set([...bare.keys(), ...Object.keys(last.bare)]);
409
+ for (const id of [...ids].sort()) {
410
+ const bareNow = bare.has(id) ? sha(JSON.stringify(bare.get(id))) : EMPTY_SET;
411
+ if (bareNow === (last.bare[id] ?? EMPTY_SET))
412
+ continue;
413
+ const twinNow = twin.has(id) ? sha(JSON.stringify(twin.get(id))) : EMPTY_SET;
414
+ if (twinNow !== (last.twin[id] ?? EMPTY_SET))
415
+ plan.conflicts.push(id);
416
+ else
417
+ mirror(id, false);
418
+ }
419
+ return plan;
420
+ }
421
+ function applyStickyRows(db, schema, plan) {
422
+ const insert = db.prepare(`INSERT OR IGNORE INTO ${schema}.brain_sticky_tags (sticky_id, tag) VALUES (?, ?)`);
423
+ const del = db.prepare(`DELETE FROM ${schema}.brain_sticky_tags WHERE sticky_id = ? AND tag = ?`);
424
+ let inserted = 0;
425
+ let deleted = 0;
426
+ for (const row of plan.set.keys()) {
427
+ const [id, tag] = row.split('\t');
428
+ inserted += Number(insert.run(id, tag).changes);
429
+ }
430
+ for (const row of plan.del) {
431
+ const [id, tag] = row.split('\t');
432
+ deleted += Number(del.run(id, tag).changes);
433
+ }
434
+ return { inserted, replaced: 0, deleted };
435
+ }
436
+ const STICKY_TAGS = {
437
+ table: 'sticky_tags',
438
+ twin: 'brain_sticky_tags',
439
+ kvTable: 'brain_schema_meta',
440
+ tables: ['sticky_tags', 'brain_sticky_tags', 'brain_sticky_notes', 'brain_schema_meta'],
441
+ bareHashes: (db) => hashSets(stickySets(db, 'sticky_tags')),
442
+ twinHashes: (db) => hashSets(stickySets(db, 'brain_sticky_tags')),
443
+ plan: planSticky,
444
+ apply(db, plan) {
445
+ const counts = applyStickyRows(db, 'main', plan);
446
+ const present = db.prepare('SELECT 1 FROM main.brain_sticky_tags WHERE sticky_id = ? AND tag = ?');
447
+ const has = (row) => {
448
+ const [id, tag] = row.split('\t');
449
+ return present.get(id, tag) !== undefined;
450
+ };
451
+ const missing = [...plan.set.keys()].filter((r) => !has(r)).length;
452
+ const lingering = plan.del.filter(has).length;
453
+ if (missing > 0 || lingering > 0)
454
+ throw new Error(`sticky_tags collapse did not verify: ${missing} missing, ${lingering} not removed`);
455
+ return counts;
456
+ },
457
+ shadow(db, plan) {
458
+ db.exec('CREATE TEMP TABLE IF NOT EXISTS brain_sticky_tags (sticky_id TEXT NOT NULL, tag TEXT NOT NULL, PRIMARY KEY (sticky_id, tag))');
459
+ db.exec('DELETE FROM temp.brain_sticky_tags');
460
+ db.exec('INSERT INTO temp.brain_sticky_tags (sticky_id, tag) SELECT sticky_id, tag FROM main.brain_sticky_tags');
461
+ applyStickyRows(db, 'temp', plan);
462
+ },
463
+ };
464
+ /** The pairs this build collapses, in order. */
465
+ const PAIRS = [SCHEMA_META, STICKY_TAGS];
466
+ /** Connections serving TEMP shadows because their collapse failed. */
467
+ const degraded = new WeakMap();
468
+ /**
469
+ * The failure a connection is degraded by, if any: reads on it are served from
470
+ * TEMP shadows and writes must be refused (the dispatch write guard does).
471
+ *
472
+ * @param db - A project `cleo.db` connection.
473
+ * @returns The failure, or `undefined` when the store is fully collapsed.
474
+ * @task T12535
475
+ */
476
+ export function twinCollapseFailureOf(db) {
477
+ return degraded.get(db);
478
+ }
479
+ /**
480
+ * Refuse a write before its first statement when the store is degraded by a
481
+ * failed twin collapse. The write accessors of the collapsed tables
482
+ * (`tasks_schema_meta`, and sticky notes and tags) call it at entry, so a
483
+ * degraded store never takes a partial write (e.g. a sticky's `tags_json`
484
+ * without its tag rows). The shadows' TEMP triggers stay as the backstop.
485
+ *
486
+ * @param handle - The connection the write would use (a `DatabaseSync`, or a
487
+ * drizzle instance's `$client`); anything else is not checked.
488
+ * @throws {CleoError} `E_TWIN_COLLAPSE_FAILED` when the connection is degraded.
489
+ * @task T12535
490
+ */
491
+ export function assertTwinCollapseWritable(handle) {
492
+ if (typeof handle !== 'object' || handle === null)
493
+ return;
494
+ const failure = degraded.get(handle);
495
+ if (failure)
496
+ throw twinCollapseError(failure);
497
+ }
498
+ /**
499
+ * Build the `E_TWIN_COLLAPSE_FAILED` error for a failure.
500
+ *
501
+ * @param failure - The failure.
502
+ * @param cause - The underlying error, when there is one.
503
+ * @returns The error.
504
+ * @task T12535
505
+ */
506
+ export function twinCollapseError(failure, cause) {
507
+ const where = !failure.snapshotPath
508
+ ? ''
509
+ : failure.snapshotWritten
510
+ ? ` Snapshot: ${failure.snapshotPath}.`
511
+ : ` Snapshot would be written to ${failure.snapshotPath}.`;
512
+ const space = failure.requiredBytes > 0
513
+ ? ` The snapshot needs ${failure.requiredBytes} bytes free` +
514
+ (failure.availableBytes === null ? '.' : ` (${failure.availableBytes} free).`)
515
+ : '';
516
+ return new CleoError(ExitCode.TWIN_COLLAPSE_FAILED, `Twin collapse of ${failure.tables.join(', ')} failed (both tables unchanged; reads still ` +
517
+ `work, writes are refused): ${failure.cause}.${where}${space} Run 'cleo doctor twin-collapse'.`, {
518
+ fix: "Run 'cleo doctor twin-collapse' for details, clear the cause (free the space, make " +
519
+ ".cleo/backups/sqlite writable), then 'cleo doctor twin-collapse --retry'.",
520
+ details: { field: 'twinCollapse', ...failure },
521
+ cause,
522
+ });
523
+ }
524
+ /** Record a failure outside the rolled-back transaction; best effort. */
525
+ function recordFailure(db, pairs, failure) {
526
+ for (const pair of pairs) {
527
+ try {
528
+ writeKv(db, pair.kvTable, `${TWIN_COLLAPSE_FAILURE_PREFIX}${pair.table}`, JSON.stringify(failure));
529
+ }
530
+ catch {
531
+ // The store itself may be the problem (disk full, read-only); the
532
+ // failure is still carried by the degraded state and the error.
533
+ }
534
+ }
535
+ }
536
+ /** Message a write into a sealed shadow aborts with. */
537
+ export const SHADOW_WRITE_REFUSED = 'E_TWIN_COLLAPSE_FAILED: store is read-only until the twin collapse succeeds; run cleo doctor twin-collapse';
538
+ const SHADOW_WRITE_OPS = ['INSERT', 'UPDATE', 'DELETE'];
539
+ /** Remove a shadow's write-refusing triggers (before it is rebuilt). */
540
+ function unsealShadow(db, twin) {
541
+ for (const op of SHADOW_WRITE_OPS) {
542
+ db.exec(`DROP TRIGGER IF EXISTS temp.${twin}_refuse_${op.toLowerCase()}`);
543
+ }
544
+ }
545
+ /**
546
+ * Make a shadow refuse writes. A write through the store accessors that
547
+ * bypasses the dispatch write guard (a direct SDK call) then fails with
548
+ * {@link SHADOW_WRITE_REFUSED} instead of landing in the shadow and being lost
549
+ * when the connection closes. The collapse itself writes `main.<twin>`
550
+ * (schema-qualified), which these TEMP triggers do not cover.
551
+ */
552
+ function sealShadow(db, twin) {
553
+ for (const op of SHADOW_WRITE_OPS) {
554
+ db.exec(`CREATE TEMP TRIGGER IF NOT EXISTS ${twin}_refuse_${op.toLowerCase()} BEFORE ${op} ON temp.${twin} ` +
555
+ `BEGIN SELECT RAISE(ABORT, '${SHADOW_WRITE_REFUSED}'); END`);
556
+ }
557
+ }
558
+ /** Drop the TEMP shadows (and their triggers) of a connection that is no longer degraded. */
559
+ function clearShadows(db) {
560
+ for (const pair of PAIRS)
561
+ db.exec(`DROP TABLE IF EXISTS temp.${pair.twin}`);
562
+ degraded.delete(db);
563
+ }
564
+ function receipt(pair, status, snapshotPath) {
565
+ return {
566
+ table: pair.table,
567
+ twin: pair.twin,
568
+ status,
569
+ snapshotPath,
570
+ inserted: 0,
571
+ replaced: 0,
572
+ deleted: 0,
573
+ skipped: 0,
574
+ dropped: [],
575
+ conflicts: [],
576
+ };
577
+ }
578
+ /** Run one pair's merge in its own transaction. */
579
+ function collapsePair(db, pair, snapshotPath) {
580
+ db.exec('BEGIN IMMEDIATE');
581
+ try {
582
+ // Re-read under the write lock: another process may have merged since.
583
+ const state = readState(db, pair);
584
+ if (!bareChanged(db, pair, state)) {
585
+ db.exec('ROLLBACK');
586
+ return receipt(pair, 'unchanged', state?.snapshot ?? null);
587
+ }
588
+ const plan = pair.plan(db, state);
589
+ if (state === undefined && snapshotPath === null && (plan.set.size > 0 || plan.del.length > 0))
590
+ throw new Error(`bare ${pair.table} changed after the snapshot decision; retry the open`);
591
+ const counts = pair.apply(db, plan);
592
+ const now = new Date().toISOString();
593
+ const next = {
594
+ version: 3,
595
+ task: 'T12535',
596
+ collapsedAt: state?.collapsedAt || now,
597
+ lastMergedAt: now,
598
+ snapshot: state?.snapshot ?? snapshotPath,
599
+ hashes: { bare: pair.bareHashes(db), twin: pair.twinHashes(db) },
600
+ dropped: state === undefined ? plan.dropped : state.dropped,
601
+ conflicts: plan.conflicts.slice(0, MAX_CONFLICTS),
602
+ conflictsAt: plan.conflicts.length > 0 ? now : null,
603
+ };
604
+ writeKv(db, pair.kvTable, `${TWIN_COLLAPSE_MARKER_PREFIX}${pair.table}`, JSON.stringify(next));
605
+ db.prepare(`DELETE FROM main.${pair.kvTable} WHERE key = ?`).run(`${TWIN_COLLAPSE_FAILURE_PREFIX}${pair.table}`);
606
+ db.exec('COMMIT');
607
+ const done = {
608
+ ...receipt(pair, state === undefined ? 'initial' : 'incremental', next.snapshot),
609
+ ...counts,
610
+ skipped: plan.skipped,
611
+ dropped: plan.dropped,
612
+ conflicts: plan.conflicts,
613
+ };
614
+ if (counts.inserted + counts.replaced + counts.deleted > 0 || plan.conflicts.length > 0)
615
+ log.warn(done, `carried bare ${pair.table} into ${pair.twin} (${done.status}, T12535)`);
616
+ return done;
617
+ }
618
+ catch (error) {
619
+ if (db.isTransaction)
620
+ db.exec('ROLLBACK');
621
+ throw error;
622
+ }
623
+ }
624
+ /**
625
+ * Collapse every bare/twin pair present in the store: the initial collapse
626
+ * (snapshot first) where no marker exists yet, an incremental re-merge of
627
+ * changed bare keys where one does.
628
+ *
629
+ * @param nativeDb - The project `cleo.db` connection, outside any transaction.
630
+ * @param dbPath - Its file path (locates `.cleo/backups/sqlite/`).
631
+ * @param options - Failure handling.
632
+ * @returns One receipt per pair.
633
+ * @throws {CleoError} `E_TWIN_COLLAPSE_FAILED` with `onFailure: 'throw'`.
634
+ * @task T12535
635
+ */
636
+ export function collapseTwinTables(nativeDb, dbPath, options = {}) {
637
+ const onFailure = options.onFailure ?? 'throw';
638
+ // A bind on a connection already degraded in this process does not retry:
639
+ // the cause is outside CLEO; `cleo doctor twin-collapse --retry` retries.
640
+ if (onFailure === 'degrade' && degraded.has(nativeDb))
641
+ return PAIRS.map((p) => receipt(p, 'degraded', null));
642
+ const byTable = new Map();
643
+ const inOrder = () => PAIRS.map((p) => byTable.get(p.table)).filter((r) => r !== undefined);
644
+ const pending = [];
645
+ for (const pair of PAIRS) {
646
+ if (!pair.tables.every((t) => hasMainTable(nativeDb, t))) {
647
+ byTable.set(pair.table, receipt(pair, 'no-bare-table', null));
648
+ continue;
649
+ }
650
+ const state = readState(nativeDb, pair);
651
+ if (bareChanged(nativeDb, pair, state))
652
+ pending.push(pair);
653
+ else
654
+ byTable.set(pair.table, receipt(pair, 'unchanged', state?.snapshot ?? null));
655
+ }
656
+ if (pending.length === 0) {
657
+ if (degraded.has(nativeDb))
658
+ clearShadows(nativeDb);
659
+ return inOrder();
660
+ }
661
+ if (nativeDb.isTransaction)
662
+ throw new Error('twin collapse needs a connection outside a transaction');
663
+ const fail = (pairs, failure, cause) => {
664
+ recordFailure(nativeDb, pairs, failure);
665
+ log.error(failure, `twin collapse of ${failure.tables.join(', ')} failed (T12535)`);
666
+ if (onFailure === 'throw')
667
+ throw twinCollapseError(failure, cause);
668
+ // Read-only-for-users mode: serve the merged view from TEMP shadows. If
669
+ // even that cannot be built, reads cannot be served correctly either.
670
+ try {
671
+ for (const pair of pairs) {
672
+ unsealShadow(nativeDb, pair.twin);
673
+ pair.shadow(nativeDb, pair.plan(nativeDb, readState(nativeDb, pair)));
674
+ sealShadow(nativeDb, pair.twin);
675
+ }
676
+ }
677
+ catch (shadowError) {
678
+ throw twinCollapseError(failure, shadowError);
679
+ }
680
+ degraded.set(nativeDb, failure);
681
+ for (const pair of pairs)
682
+ byTable.set(pair.table, receipt(pair, 'degraded', failure.snapshotPath));
683
+ };
684
+ // One snapshot covers every pair whose INITIAL collapse changes its twin.
685
+ const needSnapshot = pending.filter((p) => {
686
+ if (readState(nativeDb, p) !== undefined)
687
+ return false;
688
+ const plan = p.plan(nativeDb, undefined);
689
+ return plan.set.size > 0 || plan.del.length > 0;
690
+ });
691
+ let snapshotPath = null;
692
+ if (needSnapshot.length > 0) {
693
+ const plan = planMigrationSnapshot(nativeDb, dbPath);
694
+ try {
695
+ snapshotPath = writeMigrationSnapshot(nativeDb, plan, `T12535 twin collapse of ${needSnapshot.map((p) => p.table).join(', ')} (store before the merge)`);
696
+ }
697
+ catch (error) {
698
+ fail(needSnapshot, {
699
+ tables: needSnapshot.map((p) => p.table),
700
+ cause: `snapshot not written: ${error instanceof Error ? error.message : String(error)}`,
701
+ snapshotPath: plan.snapshotPath,
702
+ snapshotWritten: false,
703
+ requiredBytes: plan.requiredBytes,
704
+ availableBytes: plan.availableBytes,
705
+ failedAt: new Date().toISOString(),
706
+ }, error);
707
+ // Pairs that need no snapshot (incremental, or an initial no-op) still run.
708
+ const rest = pending.filter((p) => !needSnapshot.includes(p));
709
+ pending.length = 0;
710
+ pending.push(...rest);
711
+ }
712
+ }
713
+ const failed = [];
714
+ let firstError;
715
+ for (const pair of pending) {
716
+ try {
717
+ byTable.set(pair.table, collapsePair(nativeDb, pair, snapshotPath));
718
+ }
719
+ catch (error) {
720
+ failed.push(pair);
721
+ firstError ??= error;
722
+ }
723
+ }
724
+ if (failed.length > 0) {
725
+ fail(failed, {
726
+ tables: failed.map((p) => p.table),
727
+ cause: firstError instanceof Error ? firstError.message : String(firstError),
728
+ snapshotPath,
729
+ snapshotWritten: snapshotPath !== null,
730
+ requiredBytes: 0,
731
+ availableBytes: null,
732
+ failedAt: new Date().toISOString(),
733
+ }, firstError);
734
+ }
735
+ else if (degraded.has(nativeDb) && byTable.size === PAIRS.length) {
736
+ if ([...byTable.values()].every((r) => r.status !== 'degraded'))
737
+ clearShadows(nativeDb);
738
+ }
739
+ return inOrder();
740
+ }
741
+ /**
742
+ * Report every pair's collapse state without writing (for `cleo doctor`).
743
+ *
744
+ * @param db - A connection on the project `cleo.db`; read-only is enough.
745
+ * @returns One status per pair.
746
+ * @task T12535
747
+ */
748
+ export function inspectTwinCollapse(db) {
749
+ return PAIRS.map((pair) => {
750
+ const empty = {
751
+ table: pair.table,
752
+ twin: pair.twin,
753
+ wouldChangeTwin: false,
754
+ snapshotPath: null,
755
+ collapsedAt: null,
756
+ lastMergedAt: null,
757
+ changedSinceMerge: 0,
758
+ conflicts: [],
759
+ conflictsAt: null,
760
+ failure: null,
761
+ };
762
+ if (!pair.tables.every((t) => hasMainTable(db, t)))
763
+ return { ...empty, state: 'no-bare-table' };
764
+ let failure = null;
765
+ try {
766
+ const raw = readKv(db, pair.kvTable, `${TWIN_COLLAPSE_FAILURE_PREFIX}${pair.table}`);
767
+ failure = raw === undefined ? null : JSON.parse(raw);
768
+ }
769
+ catch {
770
+ failure = null;
771
+ }
772
+ const state = readState(db, pair);
773
+ const now = pair.bareHashes(db);
774
+ const prev = state?.hashes?.bare ?? {};
775
+ let changed = 0;
776
+ for (const k of new Set([...Object.keys(now), ...Object.keys(prev)])) {
777
+ if (now[k] !== prev[k])
778
+ changed++;
779
+ }
780
+ let wouldChangeTwin = false;
781
+ if (state === undefined) {
782
+ const plan = pair.plan(db, undefined);
783
+ wouldChangeTwin = plan.set.size > 0 || plan.del.length > 0;
784
+ }
785
+ return {
786
+ ...empty,
787
+ state: failure !== null
788
+ ? 'failed'
789
+ : state === undefined
790
+ ? 'pending'
791
+ : changed > 0 || state.hashes === null
792
+ ? 'bare-changed'
793
+ : 'collapsed',
794
+ wouldChangeTwin,
795
+ snapshotPath: state?.snapshot ?? failure?.snapshotPath ?? null,
796
+ collapsedAt: state?.collapsedAt || null,
797
+ lastMergedAt: state?.lastMergedAt || null,
798
+ changedSinceMerge: state === undefined ? 0 : changed,
799
+ conflicts: state?.conflicts ?? [],
800
+ conflictsAt: state?.conflictsAt ?? null,
801
+ failure,
802
+ };
803
+ });
804
+ }
805
+ //# sourceMappingURL=twin-collapse.js.map