@cleocode/core 2026.4.9 → 2026.4.11

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 (903) hide show
  1. package/dist/adapters/adapter-registry.js +64 -0
  2. package/dist/adapters/adapter-registry.js.map +1 -0
  3. package/dist/adapters/discovery.js +83 -0
  4. package/dist/adapters/discovery.js.map +1 -0
  5. package/dist/adapters/index.js +9 -0
  6. package/dist/adapters/index.js.map +1 -0
  7. package/dist/adapters/manager.js +260 -0
  8. package/dist/adapters/manager.js.map +1 -0
  9. package/dist/admin/export-tasks.js +171 -0
  10. package/dist/admin/export-tasks.js.map +1 -0
  11. package/dist/admin/export.js +103 -0
  12. package/dist/admin/export.js.map +1 -0
  13. package/dist/admin/help.js +106 -0
  14. package/dist/admin/help.js.map +1 -0
  15. package/dist/admin/import-tasks.js +182 -0
  16. package/dist/admin/import-tasks.js.map +1 -0
  17. package/dist/admin/import.js +129 -0
  18. package/dist/admin/import.js.map +1 -0
  19. package/dist/admin/index.js +13 -0
  20. package/dist/admin/index.js.map +1 -0
  21. package/dist/adrs/find.js +134 -0
  22. package/dist/adrs/find.js.map +1 -0
  23. package/dist/adrs/index.js +15 -0
  24. package/dist/adrs/index.js.map +1 -0
  25. package/dist/adrs/link-pipeline.js +160 -0
  26. package/dist/adrs/link-pipeline.js.map +1 -0
  27. package/dist/adrs/list.js +43 -0
  28. package/dist/adrs/list.js.map +1 -0
  29. package/dist/adrs/parse.js +51 -0
  30. package/dist/adrs/parse.js.map +1 -0
  31. package/dist/adrs/show.js +22 -0
  32. package/dist/adrs/show.js.map +1 -0
  33. package/dist/adrs/sync.js +188 -0
  34. package/dist/adrs/sync.js.map +1 -0
  35. package/dist/adrs/types.js +9 -0
  36. package/dist/adrs/types.js.map +1 -0
  37. package/dist/adrs/validate.js +57 -0
  38. package/dist/adrs/validate.js.map +1 -0
  39. package/dist/agents/agent-registry.js +288 -0
  40. package/dist/agents/agent-registry.js.map +1 -0
  41. package/dist/agents/agent-schema.d.ts +2 -2
  42. package/dist/agents/agent-schema.js +82 -0
  43. package/dist/agents/agent-schema.js.map +1 -0
  44. package/dist/agents/capacity.js +116 -0
  45. package/dist/agents/capacity.js.map +1 -0
  46. package/dist/agents/execution-learning.js +474 -0
  47. package/dist/agents/execution-learning.js.map +1 -0
  48. package/dist/agents/health-monitor.js +217 -0
  49. package/dist/agents/health-monitor.js.map +1 -0
  50. package/dist/agents/index.js +29 -0
  51. package/dist/agents/index.js.map +1 -0
  52. package/dist/agents/registry.js +314 -0
  53. package/dist/agents/registry.js.map +1 -0
  54. package/dist/agents/retry.js +215 -0
  55. package/dist/agents/retry.js.map +1 -0
  56. package/dist/audit-prune.js +94 -0
  57. package/dist/audit-prune.js.map +1 -0
  58. package/dist/audit.js +68 -0
  59. package/dist/audit.js.map +1 -0
  60. package/dist/backfill/index.js +229 -0
  61. package/dist/backfill/index.js.map +1 -0
  62. package/dist/bootstrap.js +344 -0
  63. package/dist/bootstrap.js.map +1 -0
  64. package/dist/caamp/adapter.js +259 -0
  65. package/dist/caamp/adapter.js.map +1 -0
  66. package/dist/caamp/capability-check.js +38 -0
  67. package/dist/caamp/capability-check.js.map +1 -0
  68. package/dist/caamp/index.js +21 -0
  69. package/dist/caamp/index.js.map +1 -0
  70. package/dist/caamp-init.js +16 -0
  71. package/dist/caamp-init.js.map +1 -0
  72. package/dist/cleo.js +322 -0
  73. package/dist/cleo.js.map +1 -0
  74. package/dist/code/index.js +10 -0
  75. package/dist/code/index.js.map +1 -0
  76. package/dist/code/outline.js +165 -0
  77. package/dist/code/outline.js.map +1 -0
  78. package/dist/code/parser.js +295 -0
  79. package/dist/code/parser.js.map +1 -0
  80. package/dist/code/search.js +135 -0
  81. package/dist/code/search.js.map +1 -0
  82. package/dist/code/unfold.js +155 -0
  83. package/dist/code/unfold.js.map +1 -0
  84. package/dist/codebase-map/analyzers/architecture.js +130 -0
  85. package/dist/codebase-map/analyzers/architecture.js.map +1 -0
  86. package/dist/codebase-map/analyzers/concerns.js +122 -0
  87. package/dist/codebase-map/analyzers/concerns.js.map +1 -0
  88. package/dist/codebase-map/analyzers/conventions.js +149 -0
  89. package/dist/codebase-map/analyzers/conventions.js.map +1 -0
  90. package/dist/codebase-map/analyzers/integrations.js +108 -0
  91. package/dist/codebase-map/analyzers/integrations.js.map +1 -0
  92. package/dist/codebase-map/analyzers/stack.js +117 -0
  93. package/dist/codebase-map/analyzers/stack.js.map +1 -0
  94. package/dist/codebase-map/analyzers/structure.js +137 -0
  95. package/dist/codebase-map/analyzers/structure.js.map +1 -0
  96. package/dist/codebase-map/analyzers/testing.js +118 -0
  97. package/dist/codebase-map/analyzers/testing.js.map +1 -0
  98. package/dist/codebase-map/index.js +57 -0
  99. package/dist/codebase-map/index.js.map +1 -0
  100. package/dist/codebase-map/store.js +122 -0
  101. package/dist/codebase-map/store.js.map +1 -0
  102. package/dist/codebase-map/summary.js +152 -0
  103. package/dist/codebase-map/summary.js.map +1 -0
  104. package/dist/compliance/index.js +288 -0
  105. package/dist/compliance/index.js.map +1 -0
  106. package/dist/compliance/protocol-enforcement.js +332 -0
  107. package/dist/compliance/protocol-enforcement.js.map +1 -0
  108. package/dist/compliance/protocol-rules.js +786 -0
  109. package/dist/compliance/protocol-rules.js.map +1 -0
  110. package/dist/compliance/protocol-types.js +79 -0
  111. package/dist/compliance/protocol-types.js.map +1 -0
  112. package/dist/compliance/store.js +53 -0
  113. package/dist/compliance/store.js.map +1 -0
  114. package/dist/conduit/conduit-client.js +107 -0
  115. package/dist/conduit/conduit-client.js.map +1 -0
  116. package/dist/conduit/factory.js +52 -0
  117. package/dist/conduit/factory.js.map +1 -0
  118. package/dist/conduit/http-transport.js +155 -0
  119. package/dist/conduit/http-transport.js.map +1 -0
  120. package/dist/conduit/index.js +15 -0
  121. package/dist/conduit/index.js.map +1 -0
  122. package/dist/conduit/local-transport.js +245 -0
  123. package/dist/conduit/local-transport.js.map +1 -0
  124. package/dist/conduit/sse-transport.js +299 -0
  125. package/dist/conduit/sse-transport.js.map +1 -0
  126. package/dist/config/build-config.js +29 -0
  127. package/dist/config/build-config.js.map +1 -0
  128. package/dist/config.js +401 -0
  129. package/dist/config.js.map +1 -0
  130. package/dist/constants.js +18 -0
  131. package/dist/constants.js.map +1 -0
  132. package/dist/context/index.js +137 -0
  133. package/dist/context/index.js.map +1 -0
  134. package/dist/crypto/credentials.js +191 -0
  135. package/dist/crypto/credentials.js.map +1 -0
  136. package/dist/discovery.js +182 -0
  137. package/dist/discovery.js.map +1 -0
  138. package/dist/engine-result.js +12 -0
  139. package/dist/engine-result.js.map +1 -0
  140. package/dist/error-catalog.js +404 -0
  141. package/dist/error-catalog.js.map +1 -0
  142. package/dist/error-registry.js +393 -0
  143. package/dist/error-registry.js.map +1 -0
  144. package/dist/errors.js +167 -0
  145. package/dist/errors.js.map +1 -0
  146. package/dist/hooks/handlers/agent-hooks.js +106 -0
  147. package/dist/hooks/handlers/agent-hooks.js.map +1 -0
  148. package/dist/hooks/handlers/context-hooks.js +111 -0
  149. package/dist/hooks/handlers/context-hooks.js.map +1 -0
  150. package/dist/hooks/handlers/error-hooks.js +52 -0
  151. package/dist/hooks/handlers/error-hooks.js.map +1 -0
  152. package/dist/hooks/handlers/file-hooks.js +104 -0
  153. package/dist/hooks/handlers/file-hooks.js.map +1 -0
  154. package/dist/hooks/handlers/handler-helpers.js +61 -0
  155. package/dist/hooks/handlers/handler-helpers.js.map +1 -0
  156. package/dist/hooks/handlers/index.js +28 -0
  157. package/dist/hooks/handlers/index.js.map +1 -0
  158. package/dist/hooks/handlers/memory-bridge-refresh.js +42 -0
  159. package/dist/hooks/handlers/memory-bridge-refresh.js.map +1 -0
  160. package/dist/hooks/handlers/notification-hooks.js +62 -0
  161. package/dist/hooks/handlers/notification-hooks.js.map +1 -0
  162. package/dist/hooks/handlers/session-hooks.d.ts +21 -0
  163. package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
  164. package/dist/hooks/handlers/session-hooks.js +142 -0
  165. package/dist/hooks/handlers/session-hooks.js.map +1 -0
  166. package/dist/hooks/handlers/task-hooks.js +65 -0
  167. package/dist/hooks/handlers/task-hooks.js.map +1 -0
  168. package/dist/hooks/handlers/work-capture-hooks.js +165 -0
  169. package/dist/hooks/handlers/work-capture-hooks.js.map +1 -0
  170. package/dist/hooks/index.js +13 -0
  171. package/dist/hooks/index.js.map +1 -0
  172. package/dist/hooks/payload-schemas.d.ts +2 -2
  173. package/dist/hooks/payload-schemas.js +220 -0
  174. package/dist/hooks/payload-schemas.js.map +1 -0
  175. package/dist/hooks/provider-hooks.js +66 -0
  176. package/dist/hooks/provider-hooks.js.map +1 -0
  177. package/dist/hooks/registry.js +229 -0
  178. package/dist/hooks/registry.js.map +1 -0
  179. package/dist/hooks/types.js +66 -0
  180. package/dist/hooks/types.js.map +1 -0
  181. package/dist/hooks.js +136 -0
  182. package/dist/hooks.js.map +1 -0
  183. package/dist/index.js +3361 -3095
  184. package/dist/index.js.map +4 -4
  185. package/dist/init.js +852 -0
  186. package/dist/init.js.map +1 -0
  187. package/dist/inject/index.js +82 -0
  188. package/dist/inject/index.js.map +1 -0
  189. package/dist/injection.js +343 -0
  190. package/dist/injection.js.map +1 -0
  191. package/dist/intelligence/adaptive-validation.js +497 -0
  192. package/dist/intelligence/adaptive-validation.js.map +1 -0
  193. package/dist/intelligence/impact.js +675 -0
  194. package/dist/intelligence/impact.js.map +1 -0
  195. package/dist/intelligence/index.js +22 -0
  196. package/dist/intelligence/index.js.map +1 -0
  197. package/dist/intelligence/patterns.js +492 -0
  198. package/dist/intelligence/patterns.js.map +1 -0
  199. package/dist/intelligence/prediction.js +499 -0
  200. package/dist/intelligence/prediction.js.map +1 -0
  201. package/dist/intelligence/types.js +13 -0
  202. package/dist/intelligence/types.js.map +1 -0
  203. package/dist/internal.d.ts +7 -2
  204. package/dist/internal.d.ts.map +1 -1
  205. package/dist/internal.js +299 -0
  206. package/dist/internal.js.map +1 -0
  207. package/dist/issue/create.js +121 -0
  208. package/dist/issue/create.js.map +1 -0
  209. package/dist/issue/diagnostics.js +59 -0
  210. package/dist/issue/diagnostics.js.map +1 -0
  211. package/dist/issue/index.js +10 -0
  212. package/dist/issue/index.js.map +1 -0
  213. package/dist/issue/template-parser.js +267 -0
  214. package/dist/issue/template-parser.js.map +1 -0
  215. package/dist/json-schema-validator.js +76 -0
  216. package/dist/json-schema-validator.js.map +1 -0
  217. package/dist/lib/index.js +11 -0
  218. package/dist/lib/index.js.map +1 -0
  219. package/dist/lib/retry.js +152 -0
  220. package/dist/lib/retry.js.map +1 -0
  221. package/dist/lib/tree-sitter-languages.js +71 -0
  222. package/dist/lib/tree-sitter-languages.js.map +1 -0
  223. package/dist/lifecycle/chain-composition.js +152 -0
  224. package/dist/lifecycle/chain-composition.js.map +1 -0
  225. package/dist/lifecycle/chain-store.js +246 -0
  226. package/dist/lifecycle/chain-store.js.map +1 -0
  227. package/dist/lifecycle/consolidate-rcasd.js +352 -0
  228. package/dist/lifecycle/consolidate-rcasd.js.map +1 -0
  229. package/dist/lifecycle/default-chain.js +176 -0
  230. package/dist/lifecycle/default-chain.js.map +1 -0
  231. package/dist/lifecycle/evidence.js +180 -0
  232. package/dist/lifecycle/evidence.js.map +1 -0
  233. package/dist/lifecycle/frontmatter.js +363 -0
  234. package/dist/lifecycle/frontmatter.js.map +1 -0
  235. package/dist/lifecycle/index.js +756 -0
  236. package/dist/lifecycle/index.js.map +1 -0
  237. package/dist/lifecycle/pipeline.js +656 -0
  238. package/dist/lifecycle/pipeline.js.map +1 -0
  239. package/dist/lifecycle/rcasd-index.js +326 -0
  240. package/dist/lifecycle/rcasd-index.js.map +1 -0
  241. package/dist/lifecycle/rcasd-paths.js +220 -0
  242. package/dist/lifecycle/rcasd-paths.js.map +1 -0
  243. package/dist/lifecycle/resume.js +864 -0
  244. package/dist/lifecycle/resume.js.map +1 -0
  245. package/dist/lifecycle/stage-artifacts.js +94 -0
  246. package/dist/lifecycle/stage-artifacts.js.map +1 -0
  247. package/dist/lifecycle/stage-guidance.js +234 -0
  248. package/dist/lifecycle/stage-guidance.js.map +1 -0
  249. package/dist/lifecycle/stages.js +534 -0
  250. package/dist/lifecycle/stages.js.map +1 -0
  251. package/dist/lifecycle/state-machine.js +516 -0
  252. package/dist/lifecycle/state-machine.js.map +1 -0
  253. package/dist/lifecycle/tessera-engine.js +249 -0
  254. package/dist/lifecycle/tessera-engine.js.map +1 -0
  255. package/dist/logger.js +140 -0
  256. package/dist/logger.js.map +1 -0
  257. package/dist/memory/auto-extract.js +177 -0
  258. package/dist/memory/auto-extract.js.map +1 -0
  259. package/dist/memory/brain-embedding.js +66 -0
  260. package/dist/memory/brain-embedding.js.map +1 -0
  261. package/dist/memory/brain-lifecycle.js +298 -0
  262. package/dist/memory/brain-lifecycle.js.map +1 -0
  263. package/dist/memory/brain-links.js +161 -0
  264. package/dist/memory/brain-links.js.map +1 -0
  265. package/dist/memory/brain-maintenance.js +114 -0
  266. package/dist/memory/brain-maintenance.js.map +1 -0
  267. package/dist/memory/brain-migration.js +149 -0
  268. package/dist/memory/brain-migration.js.map +1 -0
  269. package/dist/memory/brain-reasoning.js +215 -0
  270. package/dist/memory/brain-reasoning.js.map +1 -0
  271. package/dist/memory/brain-retrieval.js +542 -0
  272. package/dist/memory/brain-retrieval.js.map +1 -0
  273. package/dist/memory/brain-row-types.js +10 -0
  274. package/dist/memory/brain-row-types.js.map +1 -0
  275. package/dist/memory/brain-search.js +519 -0
  276. package/dist/memory/brain-search.js.map +1 -0
  277. package/dist/memory/brain-similarity.js +145 -0
  278. package/dist/memory/brain-similarity.js.map +1 -0
  279. package/dist/memory/claude-mem-migration.js +277 -0
  280. package/dist/memory/claude-mem-migration.js.map +1 -0
  281. package/dist/memory/decisions.js +162 -0
  282. package/dist/memory/decisions.js.map +1 -0
  283. package/dist/memory/embedding-local.js +97 -0
  284. package/dist/memory/embedding-local.js.map +1 -0
  285. package/dist/memory/embedding-queue.js +271 -0
  286. package/dist/memory/embedding-queue.js.map +1 -0
  287. package/dist/memory/embedding-worker.js +58 -0
  288. package/dist/memory/embedding-worker.js.map +1 -0
  289. package/dist/memory/engine-compat.js +1397 -0
  290. package/dist/memory/engine-compat.js.map +1 -0
  291. package/dist/memory/index.js +1140 -0
  292. package/dist/memory/index.js.map +1 -0
  293. package/dist/memory/learnings.d.ts +4 -4
  294. package/dist/memory/learnings.js +121 -0
  295. package/dist/memory/learnings.js.map +1 -0
  296. package/dist/memory/memory-bridge.js +370 -0
  297. package/dist/memory/memory-bridge.js.map +1 -0
  298. package/dist/memory/patterns.d.ts +6 -6
  299. package/dist/memory/patterns.js +122 -0
  300. package/dist/memory/patterns.js.map +1 -0
  301. package/dist/memory/pipeline-manifest-sqlite.js +975 -0
  302. package/dist/memory/pipeline-manifest-sqlite.js.map +1 -0
  303. package/dist/memory/session-memory.js +331 -0
  304. package/dist/memory/session-memory.js.map +1 -0
  305. package/dist/metrics/ab-test.js +260 -0
  306. package/dist/metrics/ab-test.js.map +1 -0
  307. package/dist/metrics/aggregation.js +363 -0
  308. package/dist/metrics/aggregation.js.map +1 -0
  309. package/dist/metrics/common.js +64 -0
  310. package/dist/metrics/common.js.map +1 -0
  311. package/dist/metrics/enums.js +78 -0
  312. package/dist/metrics/enums.js.map +1 -0
  313. package/dist/metrics/index.js +19 -0
  314. package/dist/metrics/index.js.map +1 -0
  315. package/dist/metrics/model-provider-registry.js +88 -0
  316. package/dist/metrics/model-provider-registry.js.map +1 -0
  317. package/dist/metrics/otel-integration.js +263 -0
  318. package/dist/metrics/otel-integration.js.map +1 -0
  319. package/dist/metrics/provider-detection.js +103 -0
  320. package/dist/metrics/provider-detection.js.map +1 -0
  321. package/dist/metrics/token-estimation.js +253 -0
  322. package/dist/metrics/token-estimation.js.map +1 -0
  323. package/dist/metrics/token-service.js +450 -0
  324. package/dist/metrics/token-service.js.map +1 -0
  325. package/dist/migration/agent-outputs.js +316 -0
  326. package/dist/migration/agent-outputs.js.map +1 -0
  327. package/dist/migration/checksum.js +92 -0
  328. package/dist/migration/checksum.js.map +1 -0
  329. package/dist/migration/index.js +282 -0
  330. package/dist/migration/index.js.map +1 -0
  331. package/dist/migration/logger.js +360 -0
  332. package/dist/migration/logger.js.map +1 -0
  333. package/dist/migration/preflight.js +9 -0
  334. package/dist/migration/preflight.js.map +1 -0
  335. package/dist/migration/state.js +421 -0
  336. package/dist/migration/state.js.map +1 -0
  337. package/dist/migration/validate.js +241 -0
  338. package/dist/migration/validate.js.map +1 -0
  339. package/dist/mvi-helpers.js +74 -0
  340. package/dist/mvi-helpers.js.map +1 -0
  341. package/dist/nexus/deps.js +375 -0
  342. package/dist/nexus/deps.js.map +1 -0
  343. package/dist/nexus/discover.js +288 -0
  344. package/dist/nexus/discover.js.map +1 -0
  345. package/dist/nexus/hash.js +10 -0
  346. package/dist/nexus/hash.js.map +1 -0
  347. package/dist/nexus/index.js +40 -0
  348. package/dist/nexus/index.js.map +1 -0
  349. package/dist/nexus/migrate-json-to-sqlite.js +115 -0
  350. package/dist/nexus/migrate-json-to-sqlite.js.map +1 -0
  351. package/dist/nexus/permissions.js +105 -0
  352. package/dist/nexus/permissions.js.map +1 -0
  353. package/dist/nexus/query.js +175 -0
  354. package/dist/nexus/query.js.map +1 -0
  355. package/dist/nexus/registry.js +584 -0
  356. package/dist/nexus/registry.js.map +1 -0
  357. package/dist/nexus/sharing/index.js +288 -0
  358. package/dist/nexus/sharing/index.js.map +1 -0
  359. package/dist/nexus/transfer-types.js +8 -0
  360. package/dist/nexus/transfer-types.js.map +1 -0
  361. package/dist/nexus/transfer.js +263 -0
  362. package/dist/nexus/transfer.js.map +1 -0
  363. package/dist/nexus/workspace.js +355 -0
  364. package/dist/nexus/workspace.js.map +1 -0
  365. package/dist/observability/index.js +103 -0
  366. package/dist/observability/index.js.map +1 -0
  367. package/dist/observability/log-filter.js +63 -0
  368. package/dist/observability/log-filter.js.map +1 -0
  369. package/dist/observability/log-parser.js +99 -0
  370. package/dist/observability/log-parser.js.map +1 -0
  371. package/dist/observability/log-reader.js +139 -0
  372. package/dist/observability/log-reader.js.map +1 -0
  373. package/dist/observability/types.js +19 -0
  374. package/dist/observability/types.js.map +1 -0
  375. package/dist/orchestration/analyze.js +107 -0
  376. package/dist/orchestration/analyze.js.map +1 -0
  377. package/dist/orchestration/bootstrap.js +132 -0
  378. package/dist/orchestration/bootstrap.js.map +1 -0
  379. package/dist/orchestration/context.js +56 -0
  380. package/dist/orchestration/context.js.map +1 -0
  381. package/dist/orchestration/critical-path.js +100 -0
  382. package/dist/orchestration/critical-path.js.map +1 -0
  383. package/dist/orchestration/hierarchy.js +183 -0
  384. package/dist/orchestration/hierarchy.js.map +1 -0
  385. package/dist/orchestration/index.js +287 -0
  386. package/dist/orchestration/index.js.map +1 -0
  387. package/dist/orchestration/parallel.js +89 -0
  388. package/dist/orchestration/parallel.js.map +1 -0
  389. package/dist/orchestration/protocol-validators.js +815 -0
  390. package/dist/orchestration/protocol-validators.js.map +1 -0
  391. package/dist/orchestration/skill-ops.js +98 -0
  392. package/dist/orchestration/skill-ops.js.map +1 -0
  393. package/dist/orchestration/status.js +107 -0
  394. package/dist/orchestration/status.js.map +1 -0
  395. package/dist/orchestration/unblock.js +103 -0
  396. package/dist/orchestration/unblock.js.map +1 -0
  397. package/dist/orchestration/validate-spawn.js +67 -0
  398. package/dist/orchestration/validate-spawn.js.map +1 -0
  399. package/dist/orchestration/waves.js +86 -0
  400. package/dist/orchestration/waves.js.map +1 -0
  401. package/dist/otel/index.js +163 -0
  402. package/dist/otel/index.js.map +1 -0
  403. package/dist/output.js +164 -0
  404. package/dist/output.js.map +1 -0
  405. package/dist/pagination.js +64 -0
  406. package/dist/pagination.js.map +1 -0
  407. package/dist/paths.d.ts +39 -9
  408. package/dist/paths.d.ts.map +1 -1
  409. package/dist/paths.js +776 -0
  410. package/dist/paths.js.map +1 -0
  411. package/dist/phases/deps.js +372 -0
  412. package/dist/phases/deps.js.map +1 -0
  413. package/dist/phases/index.js +349 -0
  414. package/dist/phases/index.js.map +1 -0
  415. package/dist/pipeline/index.js +10 -0
  416. package/dist/pipeline/index.js.map +1 -0
  417. package/dist/pipeline/phase.js +45 -0
  418. package/dist/pipeline/phase.js.map +1 -0
  419. package/dist/platform.js +211 -0
  420. package/dist/platform.js.map +1 -0
  421. package/dist/project-info.js +84 -0
  422. package/dist/project-info.js.map +1 -0
  423. package/dist/reconciliation/index.js +10 -0
  424. package/dist/reconciliation/index.js.map +1 -0
  425. package/dist/reconciliation/link-store.js +129 -0
  426. package/dist/reconciliation/link-store.js.map +1 -0
  427. package/dist/reconciliation/reconciliation-engine.js +298 -0
  428. package/dist/reconciliation/reconciliation-engine.js.map +1 -0
  429. package/dist/release/artifacts.js +427 -0
  430. package/dist/release/artifacts.js.map +1 -0
  431. package/dist/release/changelog-writer.js +151 -0
  432. package/dist/release/changelog-writer.js.map +1 -0
  433. package/dist/release/channel.js +144 -0
  434. package/dist/release/channel.js.map +1 -0
  435. package/dist/release/ci.js +166 -0
  436. package/dist/release/ci.js.map +1 -0
  437. package/dist/release/github-pr.js +225 -0
  438. package/dist/release/github-pr.js.map +1 -0
  439. package/dist/release/guards.js +116 -0
  440. package/dist/release/guards.js.map +1 -0
  441. package/dist/release/index.js +22 -0
  442. package/dist/release/index.js.map +1 -0
  443. package/dist/release/release-config.js +158 -0
  444. package/dist/release/release-config.js.map +1 -0
  445. package/dist/release/release-manifest.js +1019 -0
  446. package/dist/release/release-manifest.js.map +1 -0
  447. package/dist/release/version-bump.js +255 -0
  448. package/dist/release/version-bump.js.map +1 -0
  449. package/dist/remote/index.js +257 -0
  450. package/dist/remote/index.js.map +1 -0
  451. package/dist/repair.js +130 -0
  452. package/dist/repair.js.map +1 -0
  453. package/dist/research/index.js +2 -0
  454. package/dist/research/index.js.map +1 -0
  455. package/dist/roadmap/index.js +59 -0
  456. package/dist/roadmap/index.js.map +1 -0
  457. package/dist/routing/capability-matrix.js +1556 -0
  458. package/dist/routing/capability-matrix.js.map +1 -0
  459. package/dist/routing/index.js +9 -0
  460. package/dist/routing/index.js.map +1 -0
  461. package/dist/scaffold.d.ts +15 -2
  462. package/dist/scaffold.d.ts.map +1 -1
  463. package/dist/scaffold.js +1759 -0
  464. package/dist/scaffold.js.map +1 -0
  465. package/dist/schema-management.js +295 -0
  466. package/dist/schema-management.js.map +1 -0
  467. package/dist/security/index.js +9 -0
  468. package/dist/security/index.js.map +1 -0
  469. package/dist/security/input-sanitization.js +321 -0
  470. package/dist/security/input-sanitization.js.map +1 -0
  471. package/dist/sequence/index.js +295 -0
  472. package/dist/sequence/index.js.map +1 -0
  473. package/dist/sessions/assumptions.js +54 -0
  474. package/dist/sessions/assumptions.js.map +1 -0
  475. package/dist/sessions/briefing.js +377 -0
  476. package/dist/sessions/briefing.js.map +1 -0
  477. package/dist/sessions/context-alert.js +222 -0
  478. package/dist/sessions/context-alert.js.map +1 -0
  479. package/dist/sessions/context-inject.js +61 -0
  480. package/dist/sessions/context-inject.js.map +1 -0
  481. package/dist/sessions/context-monitor.js +98 -0
  482. package/dist/sessions/context-monitor.js.map +1 -0
  483. package/dist/sessions/decisions.js +65 -0
  484. package/dist/sessions/decisions.js.map +1 -0
  485. package/dist/sessions/find.js +65 -0
  486. package/dist/sessions/find.js.map +1 -0
  487. package/dist/sessions/handoff.js +328 -0
  488. package/dist/sessions/handoff.js.map +1 -0
  489. package/dist/sessions/hitl-warnings.js +254 -0
  490. package/dist/sessions/hitl-warnings.js.map +1 -0
  491. package/dist/sessions/index.js +327 -0
  492. package/dist/sessions/index.js.map +1 -0
  493. package/dist/sessions/session-archive.js +40 -0
  494. package/dist/sessions/session-archive.js.map +1 -0
  495. package/dist/sessions/session-cleanup.js +59 -0
  496. package/dist/sessions/session-cleanup.js.map +1 -0
  497. package/dist/sessions/session-drift.js +134 -0
  498. package/dist/sessions/session-drift.js.map +1 -0
  499. package/dist/sessions/session-enforcement.js +144 -0
  500. package/dist/sessions/session-enforcement.js.map +1 -0
  501. package/dist/sessions/session-grade.js +253 -0
  502. package/dist/sessions/session-grade.js.map +1 -0
  503. package/dist/sessions/session-history.js +42 -0
  504. package/dist/sessions/session-history.js.map +1 -0
  505. package/dist/sessions/session-id.js +81 -0
  506. package/dist/sessions/session-id.js.map +1 -0
  507. package/dist/sessions/session-memory-bridge.js +52 -0
  508. package/dist/sessions/session-memory-bridge.js.map +1 -0
  509. package/dist/sessions/session-show.js +24 -0
  510. package/dist/sessions/session-show.js.map +1 -0
  511. package/dist/sessions/session-stats.js +69 -0
  512. package/dist/sessions/session-stats.js.map +1 -0
  513. package/dist/sessions/session-suspend.js +39 -0
  514. package/dist/sessions/session-suspend.js.map +1 -0
  515. package/dist/sessions/session-switch.js +51 -0
  516. package/dist/sessions/session-switch.js.map +1 -0
  517. package/dist/sessions/session-view.js +76 -0
  518. package/dist/sessions/session-view.js.map +1 -0
  519. package/dist/sessions/snapshot.js +213 -0
  520. package/dist/sessions/snapshot.js.map +1 -0
  521. package/dist/sessions/statusline-setup.js +85 -0
  522. package/dist/sessions/statusline-setup.js.map +1 -0
  523. package/dist/sessions/types.js +8 -0
  524. package/dist/sessions/types.js.map +1 -0
  525. package/dist/skills/agents/config.js +94 -0
  526. package/dist/skills/agents/config.js.map +1 -0
  527. package/dist/skills/agents/install.js +116 -0
  528. package/dist/skills/agents/install.js.map +1 -0
  529. package/dist/skills/agents/registry.js +161 -0
  530. package/dist/skills/agents/registry.js.map +1 -0
  531. package/dist/skills/discovery.js +333 -0
  532. package/dist/skills/discovery.js.map +1 -0
  533. package/dist/skills/dispatch.js +347 -0
  534. package/dist/skills/dispatch.js.map +1 -0
  535. package/dist/skills/dynamic-skill-generator.js +87 -0
  536. package/dist/skills/dynamic-skill-generator.js.map +1 -0
  537. package/dist/skills/index.js +44 -0
  538. package/dist/skills/index.js.map +1 -0
  539. package/dist/skills/injection/subagent.js +195 -0
  540. package/dist/skills/injection/subagent.js.map +1 -0
  541. package/dist/skills/injection/token.js +260 -0
  542. package/dist/skills/injection/token.js.map +1 -0
  543. package/dist/skills/install.js +40 -0
  544. package/dist/skills/install.js.map +1 -0
  545. package/dist/skills/manifests/contribution.js +175 -0
  546. package/dist/skills/manifests/contribution.js.map +1 -0
  547. package/dist/skills/manifests/research.js +281 -0
  548. package/dist/skills/manifests/research.js.map +1 -0
  549. package/dist/skills/manifests/resolver.js +146 -0
  550. package/dist/skills/manifests/resolver.js.map +1 -0
  551. package/dist/skills/marketplace.js +90 -0
  552. package/dist/skills/marketplace.js.map +1 -0
  553. package/dist/skills/orchestrator/spawn.js +178 -0
  554. package/dist/skills/orchestrator/spawn.js.map +1 -0
  555. package/dist/skills/orchestrator/startup.js +451 -0
  556. package/dist/skills/orchestrator/startup.js.map +1 -0
  557. package/dist/skills/orchestrator/validator.js +301 -0
  558. package/dist/skills/orchestrator/validator.js.map +1 -0
  559. package/dist/skills/precedence-integration.js +73 -0
  560. package/dist/skills/precedence-integration.js.map +1 -0
  561. package/dist/skills/precedence-types.js +16 -0
  562. package/dist/skills/precedence-types.js.map +1 -0
  563. package/dist/skills/routing-table.js +63 -0
  564. package/dist/skills/routing-table.js.map +1 -0
  565. package/dist/skills/skill-paths.js +217 -0
  566. package/dist/skills/skill-paths.js.map +1 -0
  567. package/dist/skills/test-utility.js +55 -0
  568. package/dist/skills/test-utility.js.map +1 -0
  569. package/dist/skills/types.js +118 -0
  570. package/dist/skills/types.js.map +1 -0
  571. package/dist/skills/validation.js +183 -0
  572. package/dist/skills/validation.js.map +1 -0
  573. package/dist/skills/version.js +57 -0
  574. package/dist/skills/version.js.map +1 -0
  575. package/dist/snapshot/index.js +188 -0
  576. package/dist/snapshot/index.js.map +1 -0
  577. package/dist/spawn/adapter-registry.js +246 -0
  578. package/dist/spawn/adapter-registry.js.map +1 -0
  579. package/dist/spawn/index.js +10 -0
  580. package/dist/spawn/index.js.map +1 -0
  581. package/dist/stats/index.js +343 -0
  582. package/dist/stats/index.js.map +1 -0
  583. package/dist/stats/workflow-telemetry.js +400 -0
  584. package/dist/stats/workflow-telemetry.js.map +1 -0
  585. package/dist/sticky/archive.js +47 -0
  586. package/dist/sticky/archive.js.map +1 -0
  587. package/dist/sticky/convert.js +235 -0
  588. package/dist/sticky/convert.js.map +1 -0
  589. package/dist/sticky/create.js +48 -0
  590. package/dist/sticky/create.js.map +1 -0
  591. package/dist/sticky/id.js +35 -0
  592. package/dist/sticky/id.js.map +1 -0
  593. package/dist/sticky/index.js +16 -0
  594. package/dist/sticky/index.js.map +1 -0
  595. package/dist/sticky/list.js +44 -0
  596. package/dist/sticky/list.js.map +1 -0
  597. package/dist/sticky/purge.js +45 -0
  598. package/dist/sticky/purge.js.map +1 -0
  599. package/dist/sticky/show.js +42 -0
  600. package/dist/sticky/show.js.map +1 -0
  601. package/dist/sticky/types.js +10 -0
  602. package/dist/sticky/types.js.map +1 -0
  603. package/dist/store/agent-registry-accessor.js +265 -0
  604. package/dist/store/agent-registry-accessor.js.map +1 -0
  605. package/dist/store/atomic.js +167 -0
  606. package/dist/store/atomic.js.map +1 -0
  607. package/dist/store/backup.js +94 -0
  608. package/dist/store/backup.js.map +1 -0
  609. package/dist/store/brain-accessor.js +397 -0
  610. package/dist/store/brain-accessor.js.map +1 -0
  611. package/dist/store/brain-schema.d.ts +8 -8
  612. package/dist/store/brain-schema.js +215 -0
  613. package/dist/store/brain-schema.js.map +1 -0
  614. package/dist/store/brain-sqlite.js +222 -0
  615. package/dist/store/brain-sqlite.js.map +1 -0
  616. package/dist/store/cache.js +168 -0
  617. package/dist/store/cache.js.map +1 -0
  618. package/dist/store/chain-schema.js +51 -0
  619. package/dist/store/chain-schema.js.map +1 -0
  620. package/dist/store/cleanup-legacy.d.ts +128 -0
  621. package/dist/store/cleanup-legacy.d.ts.map +1 -0
  622. package/dist/store/converters.js +124 -0
  623. package/dist/store/converters.js.map +1 -0
  624. package/dist/store/cross-db-cleanup.js +319 -0
  625. package/dist/store/cross-db-cleanup.js.map +1 -0
  626. package/dist/store/data-accessor.js +26 -0
  627. package/dist/store/data-accessor.js.map +1 -0
  628. package/dist/store/data-safety-central.js +269 -0
  629. package/dist/store/data-safety-central.js.map +1 -0
  630. package/dist/store/data-safety.js +274 -0
  631. package/dist/store/data-safety.js.map +1 -0
  632. package/dist/store/db-helpers.js +224 -0
  633. package/dist/store/db-helpers.js.map +1 -0
  634. package/dist/store/export.js +155 -0
  635. package/dist/store/export.js.map +1 -0
  636. package/dist/store/file-utils.js +270 -0
  637. package/dist/store/file-utils.js.map +1 -0
  638. package/dist/store/git-checkpoint.js +365 -0
  639. package/dist/store/git-checkpoint.js.map +1 -0
  640. package/dist/store/import-logging.js +139 -0
  641. package/dist/store/import-logging.js.map +1 -0
  642. package/dist/store/import-remap.js +145 -0
  643. package/dist/store/import-remap.js.map +1 -0
  644. package/dist/store/import-sort.js +121 -0
  645. package/dist/store/import-sort.js.map +1 -0
  646. package/dist/store/index.d.ts +1 -0
  647. package/dist/store/index.d.ts.map +1 -1
  648. package/dist/store/index.js +29 -0
  649. package/dist/store/index.js.map +1 -0
  650. package/dist/store/json.js +208 -0
  651. package/dist/store/json.js.map +1 -0
  652. package/dist/store/lifecycle-store.js +249 -0
  653. package/dist/store/lifecycle-store.js.map +1 -0
  654. package/dist/store/lock.js +70 -0
  655. package/dist/store/lock.js.map +1 -0
  656. package/dist/store/migration-manager.js +151 -0
  657. package/dist/store/migration-manager.js.map +1 -0
  658. package/dist/store/migration-sqlite.js +676 -0
  659. package/dist/store/migration-sqlite.js.map +1 -0
  660. package/dist/store/nexus-schema.js +62 -0
  661. package/dist/store/nexus-schema.js.map +1 -0
  662. package/dist/store/nexus-sqlite.d.ts +14 -2
  663. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  664. package/dist/store/nexus-sqlite.js +217 -0
  665. package/dist/store/nexus-sqlite.js.map +1 -0
  666. package/dist/store/nexus-validation-schemas.js +40 -0
  667. package/dist/store/nexus-validation-schemas.js.map +1 -0
  668. package/dist/store/parsers.js +37 -0
  669. package/dist/store/parsers.js.map +1 -0
  670. package/dist/store/project-detect.js +457 -0
  671. package/dist/store/project-detect.js.map +1 -0
  672. package/dist/store/provider.js +101 -0
  673. package/dist/store/provider.js.map +1 -0
  674. package/dist/store/safety-data-accessor.js +257 -0
  675. package/dist/store/safety-data-accessor.js.map +1 -0
  676. package/dist/store/schema.js +7 -0
  677. package/dist/store/schema.js.map +1 -0
  678. package/dist/store/session-store.js +219 -0
  679. package/dist/store/session-store.js.map +1 -0
  680. package/dist/store/signaldock-sqlite.js +400 -0
  681. package/dist/store/signaldock-sqlite.js.map +1 -0
  682. package/dist/store/sqlite-backup.d.ts +121 -10
  683. package/dist/store/sqlite-backup.d.ts.map +1 -1
  684. package/dist/store/sqlite-backup.js +241 -0
  685. package/dist/store/sqlite-backup.js.map +1 -0
  686. package/dist/store/sqlite-data-accessor.js +787 -0
  687. package/dist/store/sqlite-data-accessor.js.map +1 -0
  688. package/dist/store/sqlite.d.ts.map +1 -1
  689. package/dist/store/sqlite.js +481 -0
  690. package/dist/store/sqlite.js.map +1 -0
  691. package/dist/store/status-registry.js +8 -0
  692. package/dist/store/status-registry.js.map +1 -0
  693. package/dist/store/task-store.js +358 -0
  694. package/dist/store/task-store.js.map +1 -0
  695. package/dist/store/tasks-schema.d.ts +8 -8
  696. package/dist/store/tasks-schema.js +610 -0
  697. package/dist/store/tasks-schema.js.map +1 -0
  698. package/dist/store/typed-query.js +15 -0
  699. package/dist/store/typed-query.js.map +1 -0
  700. package/dist/store/validation-schemas.d.ts +37 -37
  701. package/dist/store/validation-schemas.js +278 -0
  702. package/dist/store/validation-schemas.js.map +1 -0
  703. package/dist/system/archive-analytics.js +277 -0
  704. package/dist/system/archive-analytics.js.map +1 -0
  705. package/dist/system/archive-stats.js +64 -0
  706. package/dist/system/archive-stats.js.map +1 -0
  707. package/dist/system/audit.js +145 -0
  708. package/dist/system/audit.js.map +1 -0
  709. package/dist/system/backup.d.ts +91 -3
  710. package/dist/system/backup.d.ts.map +1 -1
  711. package/dist/system/backup.js +280 -0
  712. package/dist/system/backup.js.map +1 -0
  713. package/dist/system/cleanup.js +134 -0
  714. package/dist/system/cleanup.js.map +1 -0
  715. package/dist/system/health.js +1100 -0
  716. package/dist/system/health.js.map +1 -0
  717. package/dist/system/index.js +18 -0
  718. package/dist/system/index.js.map +1 -0
  719. package/dist/system/inject-generate.js +122 -0
  720. package/dist/system/inject-generate.js.map +1 -0
  721. package/dist/system/labels.js +38 -0
  722. package/dist/system/labels.js.map +1 -0
  723. package/dist/system/metrics.js +61 -0
  724. package/dist/system/metrics.js.map +1 -0
  725. package/dist/system/migrate.js +43 -0
  726. package/dist/system/migrate.js.map +1 -0
  727. package/dist/system/platform-paths.js +80 -0
  728. package/dist/system/platform-paths.js.map +1 -0
  729. package/dist/system/runtime.js +161 -0
  730. package/dist/system/runtime.js.map +1 -0
  731. package/dist/system/safestop.js +99 -0
  732. package/dist/system/safestop.js.map +1 -0
  733. package/dist/system/storage-preflight.js +123 -0
  734. package/dist/system/storage-preflight.js.map +1 -0
  735. package/dist/task-work/index.js +159 -0
  736. package/dist/task-work/index.js.map +1 -0
  737. package/dist/tasks/add.js +661 -0
  738. package/dist/tasks/add.js.map +1 -0
  739. package/dist/tasks/analyze.js +85 -0
  740. package/dist/tasks/analyze.js.map +1 -0
  741. package/dist/tasks/archive.js +90 -0
  742. package/dist/tasks/archive.js.map +1 -0
  743. package/dist/tasks/atomicity.js +83 -0
  744. package/dist/tasks/atomicity.js.map +1 -0
  745. package/dist/tasks/cancel-ops.js +83 -0
  746. package/dist/tasks/cancel-ops.js.map +1 -0
  747. package/dist/tasks/complete.js +211 -0
  748. package/dist/tasks/complete.js.map +1 -0
  749. package/dist/tasks/crossref-extract.js +73 -0
  750. package/dist/tasks/crossref-extract.js.map +1 -0
  751. package/dist/tasks/delete-preview.js +192 -0
  752. package/dist/tasks/delete-preview.js.map +1 -0
  753. package/dist/tasks/delete.js +120 -0
  754. package/dist/tasks/delete.js.map +1 -0
  755. package/dist/tasks/deletion-strategy.js +200 -0
  756. package/dist/tasks/deletion-strategy.js.map +1 -0
  757. package/dist/tasks/dependency-check.js +278 -0
  758. package/dist/tasks/dependency-check.js.map +1 -0
  759. package/dist/tasks/deps-ready.js +32 -0
  760. package/dist/tasks/deps-ready.js.map +1 -0
  761. package/dist/tasks/enforcement.js +86 -0
  762. package/dist/tasks/enforcement.js.map +1 -0
  763. package/dist/tasks/epic-enforcement.js +294 -0
  764. package/dist/tasks/epic-enforcement.js.map +1 -0
  765. package/dist/tasks/find.js +154 -0
  766. package/dist/tasks/find.js.map +1 -0
  767. package/dist/tasks/graph-cache.js +127 -0
  768. package/dist/tasks/graph-cache.js.map +1 -0
  769. package/dist/tasks/graph-ops.js +171 -0
  770. package/dist/tasks/graph-ops.js.map +1 -0
  771. package/dist/tasks/graph-rag.js +328 -0
  772. package/dist/tasks/graph-rag.js.map +1 -0
  773. package/dist/tasks/hierarchy-policy.js +149 -0
  774. package/dist/tasks/hierarchy-policy.js.map +1 -0
  775. package/dist/tasks/hierarchy.js +185 -0
  776. package/dist/tasks/hierarchy.js.map +1 -0
  777. package/dist/tasks/id-generator.js +65 -0
  778. package/dist/tasks/id-generator.js.map +1 -0
  779. package/dist/tasks/index.js +14 -0
  780. package/dist/tasks/index.js.map +1 -0
  781. package/dist/tasks/labels.js +52 -0
  782. package/dist/tasks/labels.js.map +1 -0
  783. package/dist/tasks/list.js +75 -0
  784. package/dist/tasks/list.js.map +1 -0
  785. package/dist/tasks/phase-tracking.js +133 -0
  786. package/dist/tasks/phase-tracking.js.map +1 -0
  787. package/dist/tasks/pipeline-stage.js +248 -0
  788. package/dist/tasks/pipeline-stage.js.map +1 -0
  789. package/dist/tasks/plan.js +268 -0
  790. package/dist/tasks/plan.js.map +1 -0
  791. package/dist/tasks/relates.js +89 -0
  792. package/dist/tasks/relates.js.map +1 -0
  793. package/dist/tasks/show.js +80 -0
  794. package/dist/tasks/show.js.map +1 -0
  795. package/dist/tasks/size-weighting.js +86 -0
  796. package/dist/tasks/size-weighting.js.map +1 -0
  797. package/dist/tasks/staleness.js +86 -0
  798. package/dist/tasks/staleness.js.map +1 -0
  799. package/dist/tasks/task-ops.js +1741 -0
  800. package/dist/tasks/task-ops.js.map +1 -0
  801. package/dist/tasks/update.js +277 -0
  802. package/dist/tasks/update.js.map +1 -0
  803. package/dist/templates/index.js +10 -0
  804. package/dist/templates/index.js.map +1 -0
  805. package/dist/templates/parser.js +254 -0
  806. package/dist/templates/parser.js.map +1 -0
  807. package/dist/ui/aliases.js +153 -0
  808. package/dist/ui/aliases.js.map +1 -0
  809. package/dist/ui/changelog.js +184 -0
  810. package/dist/ui/changelog.js.map +1 -0
  811. package/dist/ui/command-registry.js +168 -0
  812. package/dist/ui/command-registry.js.map +1 -0
  813. package/dist/ui/flags.js +94 -0
  814. package/dist/ui/flags.js.map +1 -0
  815. package/dist/ui/index.js +24 -0
  816. package/dist/ui/index.js.map +1 -0
  817. package/dist/upgrade.js +1148 -0
  818. package/dist/upgrade.js.map +1 -0
  819. package/dist/validation/chain-validation.js +146 -0
  820. package/dist/validation/chain-validation.js.map +1 -0
  821. package/dist/validation/compliance.js +155 -0
  822. package/dist/validation/compliance.js.map +1 -0
  823. package/dist/validation/docs-sync.js +212 -0
  824. package/dist/validation/docs-sync.js.map +1 -0
  825. package/dist/validation/doctor/checks.js +1069 -0
  826. package/dist/validation/doctor/checks.js.map +1 -0
  827. package/dist/validation/doctor/index.js +9 -0
  828. package/dist/validation/doctor/index.js.map +1 -0
  829. package/dist/validation/doctor/project-cache.js +160 -0
  830. package/dist/validation/doctor/project-cache.js.map +1 -0
  831. package/dist/validation/doctor/utils.js +155 -0
  832. package/dist/validation/doctor/utils.js.map +1 -0
  833. package/dist/validation/engine.js +902 -0
  834. package/dist/validation/engine.js.map +1 -0
  835. package/dist/validation/gap-check.js +175 -0
  836. package/dist/validation/gap-check.js.map +1 -0
  837. package/dist/validation/index.js +40 -0
  838. package/dist/validation/index.js.map +1 -0
  839. package/dist/validation/manifest.js +237 -0
  840. package/dist/validation/manifest.js.map +1 -0
  841. package/dist/validation/operation-gate-validators.js +724 -0
  842. package/dist/validation/operation-gate-validators.js.map +1 -0
  843. package/dist/validation/operation-verification-gates.js +532 -0
  844. package/dist/validation/operation-verification-gates.js.map +1 -0
  845. package/dist/validation/param-utils.js +139 -0
  846. package/dist/validation/param-utils.js.map +1 -0
  847. package/dist/validation/protocol-common.js +300 -0
  848. package/dist/validation/protocol-common.js.map +1 -0
  849. package/dist/validation/protocols/_shared.js +75 -0
  850. package/dist/validation/protocols/_shared.js.map +1 -0
  851. package/dist/validation/protocols/architecture-decision.js +31 -0
  852. package/dist/validation/protocols/architecture-decision.js.map +1 -0
  853. package/dist/validation/protocols/artifact-publish.js +28 -0
  854. package/dist/validation/protocols/artifact-publish.js.map +1 -0
  855. package/dist/validation/protocols/consensus.js +41 -0
  856. package/dist/validation/protocols/consensus.js.map +1 -0
  857. package/dist/validation/protocols/contribution.js +27 -0
  858. package/dist/validation/protocols/contribution.js.map +1 -0
  859. package/dist/validation/protocols/decomposition.js +28 -0
  860. package/dist/validation/protocols/decomposition.js.map +1 -0
  861. package/dist/validation/protocols/implementation.js +24 -0
  862. package/dist/validation/protocols/implementation.js.map +1 -0
  863. package/dist/validation/protocols/provenance.js +29 -0
  864. package/dist/validation/protocols/provenance.js.map +1 -0
  865. package/dist/validation/protocols/release.js +29 -0
  866. package/dist/validation/protocols/release.js.map +1 -0
  867. package/dist/validation/protocols/research.js +24 -0
  868. package/dist/validation/protocols/research.js.map +1 -0
  869. package/dist/validation/protocols/specification.js +27 -0
  870. package/dist/validation/protocols/specification.js.map +1 -0
  871. package/dist/validation/protocols/testing.js +30 -0
  872. package/dist/validation/protocols/testing.js.map +1 -0
  873. package/dist/validation/protocols/validation.js +30 -0
  874. package/dist/validation/protocols/validation.js.map +1 -0
  875. package/dist/validation/schema-integrity.js +170 -0
  876. package/dist/validation/schema-integrity.js.map +1 -0
  877. package/dist/validation/schema-validator.js +176 -0
  878. package/dist/validation/schema-validator.js.map +1 -0
  879. package/dist/validation/validate-ops.js +937 -0
  880. package/dist/validation/validate-ops.js.map +1 -0
  881. package/dist/validation/validation-rules.js +226 -0
  882. package/dist/validation/validation-rules.js.map +1 -0
  883. package/dist/validation/verification.js +321 -0
  884. package/dist/validation/verification.js.map +1 -0
  885. package/package.json +10 -8
  886. package/src/__tests__/paths-walkup.test.ts +305 -0
  887. package/src/__tests__/paths.test.ts +61 -17
  888. package/src/hooks/handlers/session-hooks.ts +42 -0
  889. package/src/internal.ts +19 -2
  890. package/src/paths.ts +91 -14
  891. package/src/scaffold.ts +22 -3
  892. package/src/store/__tests__/cleanup-legacy.test.ts +268 -0
  893. package/src/store/__tests__/database-topology-integration.test.ts +504 -0
  894. package/src/store/__tests__/sqlite-backup-global.test.ts +281 -0
  895. package/src/store/__tests__/sqlite-backup.test.ts +118 -10
  896. package/src/store/cleanup-legacy.ts +208 -0
  897. package/src/store/index.ts +7 -0
  898. package/src/store/nexus-sqlite.ts +32 -3
  899. package/src/store/sqlite-backup.ts +368 -37
  900. package/src/store/sqlite.ts +19 -3
  901. package/src/system/__tests__/backup.test.ts +237 -0
  902. package/src/system/backup.ts +248 -28
  903. package/templates/cleo-gitignore +19 -3
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Tests for global-tier SQLite VACUUM INTO backup (vacuumIntoGlobalBackup,
3
+ * listGlobalSqliteBackups).
4
+ *
5
+ * All tests use a tmp-dir override via `cleoHomeOverride` so they NEVER
6
+ * touch the real user's $XDG_DATA_HOME/cleo/ directory or corrupt actual
7
+ * nexus backups.
8
+ *
9
+ * Coverage:
10
+ * - vacuumIntoGlobalBackup creates a snapshot and increments file count
11
+ * - listGlobalSqliteBackups returns entries sorted newest-first (mtime desc)
12
+ * - Rotation keeps last 10 snapshots, deletes older ones
13
+ * - Snapshot passes PRAGMA integrity_check
14
+ * - Scope filter: listGlobalSqliteBackups with prefix excludes other prefixes
15
+ * - Restore round-trip: snapshot then restore preserves DB content
16
+ * - XDG path: snapshots land under cleoHomeOverride/backups/sqlite/, not hardcoded ~/.cleo/
17
+ *
18
+ * @task T306
19
+ * @epic T299
20
+ */
21
+
22
+ import { existsSync, mkdirSync, readdirSync, utimesSync, writeFileSync } from 'node:fs';
23
+ import { homedir, tmpdir } from 'node:os';
24
+ import { join } from 'node:path';
25
+ import { DatabaseSync } from 'node:sqlite';
26
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
27
+
28
+ describe('sqlite-backup global tier', () => {
29
+ beforeEach(() => {
30
+ vi.resetModules();
31
+ vi.clearAllMocks();
32
+ });
33
+
34
+ /**
35
+ * Create a minimal, valid SQLite database at `dbPath` with a single table
36
+ * and one row so VACUUM INTO and integrity_check have something to verify.
37
+ */
38
+ function seedSqliteDb(dbPath: string): void {
39
+ const db = new DatabaseSync(dbPath);
40
+ db.exec(`
41
+ CREATE TABLE IF NOT EXISTS test_data (id INTEGER PRIMARY KEY, value TEXT);
42
+ INSERT INTO test_data (value) VALUES ('hello');
43
+ `);
44
+ db.close();
45
+ }
46
+
47
+ it('vacuumIntoGlobalBackup creates a snapshot file under cleoHomeOverride/backups/sqlite/', async () => {
48
+ vi.resetModules();
49
+ const cleoHome = join(tmpdir(), `cleo-global-test-create-${Date.now()}`);
50
+ const nexusDbPath = join(cleoHome, 'nexus.db');
51
+ mkdirSync(cleoHome, { recursive: true });
52
+ seedSqliteDb(nexusDbPath);
53
+
54
+ // Mock getNexusNativeDb to return a real DatabaseSync handle
55
+ const nexusDb = new DatabaseSync(nexusDbPath);
56
+ vi.doMock('../nexus-sqlite.js', () => ({ getNexusNativeDb: () => nexusDb }));
57
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => cleoHome }));
58
+
59
+ const { vacuumIntoGlobalBackup } = await import('../sqlite-backup.js');
60
+ const result = await vacuumIntoGlobalBackup('nexus', { cleoHomeOverride: cleoHome });
61
+
62
+ nexusDb.close();
63
+
64
+ expect(result.snapshotPath).toBeTruthy();
65
+ expect(result.snapshotPath).toContain('nexus-');
66
+ expect(result.snapshotPath).toContain(join(cleoHome, 'backups', 'sqlite'));
67
+ expect(existsSync(result.snapshotPath)).toBe(true);
68
+ });
69
+
70
+ it('vacuumIntoGlobalBackup XDG path: uses cleoHomeOverride, not hardcoded ~/.cleo/', async () => {
71
+ vi.resetModules();
72
+ const cleoHome = join(tmpdir(), `cleo-global-xdg-${Date.now()}`);
73
+ const nexusDbPath = join(cleoHome, 'nexus.db');
74
+ mkdirSync(cleoHome, { recursive: true });
75
+ seedSqliteDb(nexusDbPath);
76
+
77
+ const nexusDb = new DatabaseSync(nexusDbPath);
78
+ vi.doMock('../nexus-sqlite.js', () => ({ getNexusNativeDb: () => nexusDb }));
79
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => cleoHome }));
80
+
81
+ const { vacuumIntoGlobalBackup } = await import('../sqlite-backup.js');
82
+ const result = await vacuumIntoGlobalBackup('nexus', { cleoHomeOverride: cleoHome });
83
+
84
+ nexusDb.close();
85
+
86
+ // Must be under the override dir, not the user's actual cleo home
87
+ expect(result.snapshotPath).toContain(cleoHome);
88
+ expect(result.snapshotPath).not.toContain(join(homedir(), '.local'));
89
+ expect(result.snapshotPath).not.toContain('.cleo');
90
+ });
91
+
92
+ it('vacuumIntoGlobalBackup is non-fatal when getNexusNativeDb() returns null', async () => {
93
+ vi.resetModules();
94
+ vi.doMock('../nexus-sqlite.js', () => ({ getNexusNativeDb: () => null }));
95
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => tmpdir() }));
96
+
97
+ const { vacuumIntoGlobalBackup } = await import('../sqlite-backup.js');
98
+ const result = await vacuumIntoGlobalBackup('nexus', {
99
+ cleoHomeOverride: join(tmpdir(), `cleo-null-nexus-${Date.now()}`),
100
+ });
101
+
102
+ expect(result.snapshotPath).toBe('');
103
+ expect(result.rotated).toEqual([]);
104
+ });
105
+
106
+ it('vacuumIntoGlobalBackup snapshot passes PRAGMA integrity_check', async () => {
107
+ vi.resetModules();
108
+ const cleoHome = join(tmpdir(), `cleo-global-integrity-${Date.now()}`);
109
+ const nexusDbPath = join(cleoHome, 'nexus.db');
110
+ mkdirSync(cleoHome, { recursive: true });
111
+ seedSqliteDb(nexusDbPath);
112
+
113
+ const nexusDb = new DatabaseSync(nexusDbPath);
114
+ vi.doMock('../nexus-sqlite.js', () => ({ getNexusNativeDb: () => nexusDb }));
115
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => cleoHome }));
116
+
117
+ const { vacuumIntoGlobalBackup } = await import('../sqlite-backup.js');
118
+ const result = await vacuumIntoGlobalBackup('nexus', { cleoHomeOverride: cleoHome });
119
+
120
+ nexusDb.close();
121
+
122
+ expect(existsSync(result.snapshotPath)).toBe(true);
123
+
124
+ // Open snapshot and verify integrity
125
+ const snapshot = new DatabaseSync(result.snapshotPath, { readonly: true });
126
+ try {
127
+ const row = snapshot.prepare('PRAGMA integrity_check').get() as Record<string, unknown>;
128
+ const ok = row?.['integrity_check'] ?? row?.['integrity check'];
129
+ expect(ok).toBe('ok');
130
+ } finally {
131
+ snapshot.close();
132
+ }
133
+ });
134
+
135
+ it('rotation keeps last 10 snapshots and deletes older ones', async () => {
136
+ vi.resetModules();
137
+ const cleoHome = join(tmpdir(), `cleo-global-rotation-${Date.now()}`);
138
+ const nexusDbPath = join(cleoHome, 'nexus.db');
139
+ const backupDir = join(cleoHome, 'backups', 'sqlite');
140
+ mkdirSync(backupDir, { recursive: true });
141
+ seedSqliteDb(nexusDbPath);
142
+
143
+ // Seed 11 stale snapshots with valid name pattern
144
+ for (let i = 0; i < 11; i++) {
145
+ const day = String(i + 1).padStart(2, '0');
146
+ writeFileSync(join(backupDir, `nexus-202601${day}-120000.db`), 'fake');
147
+ }
148
+
149
+ const nexusDb = new DatabaseSync(nexusDbPath);
150
+ vi.doMock('../nexus-sqlite.js', () => ({ getNexusNativeDb: () => nexusDb }));
151
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => cleoHome }));
152
+
153
+ const { vacuumIntoGlobalBackup } = await import('../sqlite-backup.js');
154
+ const result = await vacuumIntoGlobalBackup('nexus', { cleoHomeOverride: cleoHome });
155
+
156
+ nexusDb.close();
157
+
158
+ const remaining = readdirSync(backupDir).filter(
159
+ (f) => f.startsWith('nexus-') && f.endsWith('.db'),
160
+ );
161
+ // The new snapshot was written, meaning 11 stale + 1 new. After rotation,
162
+ // MAX_SNAPSHOTS (10) must be respected.
163
+ expect(remaining.length).toBeLessThanOrEqual(10);
164
+ // The result snapshot should exist
165
+ expect(existsSync(result.snapshotPath)).toBe(true);
166
+ // At least 2 files were rotated out (11 + 1 new = 12, keep 10, remove 2)
167
+ expect(result.rotated.length).toBeGreaterThanOrEqual(2);
168
+ });
169
+
170
+ it('listGlobalSqliteBackups returns entries sorted newest-first by mtime', async () => {
171
+ vi.resetModules();
172
+ const cleoHome = join(tmpdir(), `cleo-global-list-${Date.now()}`);
173
+ const backupDir = join(cleoHome, 'backups', 'sqlite');
174
+ mkdirSync(backupDir, { recursive: true });
175
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => cleoHome }));
176
+
177
+ const f1 = join(backupDir, 'nexus-20260101-120000.db');
178
+ const f2 = join(backupDir, 'nexus-20260102-120000.db');
179
+ const f3 = join(backupDir, 'nexus-20260103-120000.db');
180
+ writeFileSync(f1, 'fake1');
181
+ writeFileSync(f2, 'fake2');
182
+ writeFileSync(f3, 'fake3');
183
+ // Set deterministic mtimes: f1 oldest, f3 newest
184
+ utimesSync(f1, 1_700_000_100, 1_700_000_100);
185
+ utimesSync(f2, 1_700_000_200, 1_700_000_200);
186
+ utimesSync(f3, 1_700_000_300, 1_700_000_300);
187
+
188
+ const { listGlobalSqliteBackups } = await import('../sqlite-backup.js');
189
+ const entries = listGlobalSqliteBackups(undefined, cleoHome);
190
+
191
+ expect(entries.map((e) => e.name)).toEqual([
192
+ 'nexus-20260103-120000.db',
193
+ 'nexus-20260102-120000.db',
194
+ 'nexus-20260101-120000.db',
195
+ ]);
196
+ // Each entry has required fields
197
+ for (const e of entries) {
198
+ expect(e.path).toBeTruthy();
199
+ expect(typeof e.size).toBe('number');
200
+ expect(e.mtime).toBeInstanceOf(Date);
201
+ }
202
+ });
203
+
204
+ it('listGlobalSqliteBackups prefix filter excludes other prefixes', async () => {
205
+ vi.resetModules();
206
+ const cleoHome = join(tmpdir(), `cleo-global-filter-${Date.now()}`);
207
+ const backupDir = join(cleoHome, 'backups', 'sqlite');
208
+ mkdirSync(backupDir, { recursive: true });
209
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => cleoHome }));
210
+
211
+ // Write files for two different prefixes
212
+ writeFileSync(join(backupDir, 'nexus-20260101-120000.db'), 'nexus-data');
213
+ writeFileSync(join(backupDir, 'nexus-20260102-120000.db'), 'nexus-data-2');
214
+ writeFileSync(join(backupDir, 'signaldock-20260101-120000.db'), 'sd-data');
215
+
216
+ const { listGlobalSqliteBackups } = await import('../sqlite-backup.js');
217
+
218
+ const nexusOnly = listGlobalSqliteBackups('nexus', cleoHome);
219
+ const sdOnly = listGlobalSqliteBackups('signaldock', cleoHome);
220
+ const all = listGlobalSqliteBackups(undefined, cleoHome);
221
+
222
+ expect(nexusOnly.every((e) => e.name.startsWith('nexus-'))).toBe(true);
223
+ expect(nexusOnly.length).toBe(2);
224
+
225
+ expect(sdOnly.every((e) => e.name.startsWith('signaldock-'))).toBe(true);
226
+ expect(sdOnly.length).toBe(1);
227
+
228
+ // Unfiltered returns both
229
+ expect(all.length).toBe(3);
230
+ });
231
+
232
+ it('listGlobalSqliteBackups returns empty array when backup dir does not exist', async () => {
233
+ vi.resetModules();
234
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => tmpdir() }));
235
+
236
+ const { listGlobalSqliteBackups } = await import('../sqlite-backup.js');
237
+ const nonExistentHome = join(tmpdir(), `cleo-no-exist-${Date.now()}`);
238
+ const entries = listGlobalSqliteBackups(undefined, nonExistentHome);
239
+
240
+ expect(entries).toEqual([]);
241
+ });
242
+
243
+ it('restore round-trip: snapshot then restore preserves all rows', async () => {
244
+ vi.resetModules();
245
+ const cleoHome = join(tmpdir(), `cleo-global-roundtrip-${Date.now()}`);
246
+ const nexusDbPath = join(cleoHome, 'nexus.db');
247
+ mkdirSync(cleoHome, { recursive: true });
248
+
249
+ // Seed with known data
250
+ const db = new DatabaseSync(nexusDbPath);
251
+ db.exec(`
252
+ CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT);
253
+ INSERT INTO items (name) VALUES ('alpha');
254
+ INSERT INTO items (name) VALUES ('beta');
255
+ `);
256
+ db.close();
257
+
258
+ const nexusDb = new DatabaseSync(nexusDbPath);
259
+ vi.doMock('../nexus-sqlite.js', () => ({ getNexusNativeDb: () => nexusDb }));
260
+ vi.doMock('../../paths.js', () => ({ getCleoHome: () => cleoHome }));
261
+
262
+ const { vacuumIntoGlobalBackup } = await import('../sqlite-backup.js');
263
+ const { snapshotPath } = await vacuumIntoGlobalBackup('nexus', {
264
+ cleoHomeOverride: cleoHome,
265
+ });
266
+ nexusDb.close();
267
+
268
+ expect(existsSync(snapshotPath)).toBe(true);
269
+
270
+ // Verify the snapshot contains all expected rows
271
+ const snapDb = new DatabaseSync(snapshotPath, { readonly: true });
272
+ try {
273
+ const rows = snapDb.prepare('SELECT name FROM items ORDER BY id').all() as Array<{
274
+ name: string;
275
+ }>;
276
+ expect(rows.map((r) => r.name)).toEqual(['alpha', 'beta']);
277
+ } finally {
278
+ snapDb.close();
279
+ }
280
+ });
281
+ });
@@ -2,16 +2,20 @@
2
2
  * Tests for SQLite VACUUM INTO backup module.
3
3
  *
4
4
  * Verifies:
5
- * - Non-fatal when getNativeDb() returns null
6
- * - WAL checkpoint runs before VACUUM INTO
7
- * - Snapshot rotation enforces MAX_SNAPSHOTS limit
8
- * - Debounce prevents rapid successive backups
5
+ * - Non-fatal when getNativeDb() / getBrainNativeDb() return null
6
+ * - WAL checkpoint runs before VACUUM INTO for each target
7
+ * - Snapshot rotation enforces MAX_SNAPSHOTS limit per prefix
8
+ * - Debounce prevents rapid successive backups per prefix
9
+ * - vacuumIntoBackupAll snapshots both tasks.db and brain.db
10
+ * - listSqliteBackups / listBrainBackups / listSqliteBackupsAll read back
11
+ * the rotated files sorted newest-first
9
12
  *
10
13
  * @task T4874
14
+ * @task T5158 — extended to cover brain.db + vacuumIntoBackupAll
11
15
  * @epic T4867
12
16
  */
13
17
 
14
- import { mkdirSync, readdirSync, writeFileSync } from 'node:fs';
18
+ import { mkdirSync, readdirSync, utimesSync, writeFileSync } from 'node:fs';
15
19
  import { tmpdir } from 'node:os';
16
20
  import { join } from 'node:path';
17
21
  import { beforeEach, describe, expect, it, vi } from 'vitest';
@@ -24,15 +28,26 @@ describe('sqlite-backup', () => {
24
28
 
25
29
  it('is non-fatal when getNativeDb() returns null', async () => {
26
30
  vi.doMock('../sqlite.js', () => ({ getNativeDb: () => null }));
31
+ vi.doMock('../brain-sqlite.js', () => ({ getBrainNativeDb: () => null }));
27
32
  vi.doMock('../../paths.js', () => ({ getCleoDir: () => tmpdir() }));
28
33
 
29
34
  const { vacuumIntoBackup } = await import('../sqlite-backup.js');
30
35
  await expect(vacuumIntoBackup({ force: true })).resolves.not.toThrow();
31
36
  });
32
37
 
33
- it('calls PRAGMA wal_checkpoint(TRUNCATE) before VACUUM INTO', async () => {
38
+ it('is non-fatal when getBrainNativeDb() returns null', async () => {
39
+ vi.doMock('../sqlite.js', () => ({ getNativeDb: () => null }));
40
+ vi.doMock('../brain-sqlite.js', () => ({ getBrainNativeDb: () => null }));
41
+ vi.doMock('../../paths.js', () => ({ getCleoDir: () => tmpdir() }));
42
+
43
+ const { vacuumIntoBackupAll } = await import('../sqlite-backup.js');
44
+ await expect(vacuumIntoBackupAll({ force: true })).resolves.not.toThrow();
45
+ });
46
+
47
+ it('calls PRAGMA wal_checkpoint(TRUNCATE) before VACUUM INTO for tasks.db', async () => {
34
48
  const execMock = vi.fn();
35
49
  vi.doMock('../sqlite.js', () => ({ getNativeDb: () => ({ exec: execMock }) }));
50
+ vi.doMock('../brain-sqlite.js', () => ({ getBrainNativeDb: () => null }));
36
51
  const tempDir = join(tmpdir(), `cleo-test-wal-${Date.now()}`);
37
52
  vi.doMock('../../paths.js', () => ({ getCleoDir: () => tempDir }));
38
53
 
@@ -46,9 +61,10 @@ describe('sqlite-backup', () => {
46
61
  expect(walIdx).toBeLessThan(vacuumIdx);
47
62
  });
48
63
 
49
- it('enforces maximum 10 snapshots via rotation', async () => {
64
+ it('enforces maximum 10 tasks.db snapshots via rotation', async () => {
50
65
  const execMock = vi.fn();
51
66
  vi.doMock('../sqlite.js', () => ({ getNativeDb: () => ({ exec: execMock }) }));
67
+ vi.doMock('../brain-sqlite.js', () => ({ getBrainNativeDb: () => null }));
52
68
  const tempDir = join(tmpdir(), `cleo-test-rot-${Date.now()}`);
53
69
  const backupDir = join(tempDir, 'backups', 'sqlite');
54
70
  mkdirSync(backupDir, { recursive: true });
@@ -63,13 +79,64 @@ describe('sqlite-backup', () => {
63
79
  const { vacuumIntoBackup } = await import('../sqlite-backup.js');
64
80
  await vacuumIntoBackup({ force: true });
65
81
 
66
- const remaining = readdirSync(backupDir).filter((f) => f.endsWith('.db'));
82
+ const remaining = readdirSync(backupDir).filter(
83
+ (f) => f.startsWith('tasks-') && f.endsWith('.db'),
84
+ );
67
85
  expect(remaining.length).toBeLessThanOrEqual(10);
68
86
  });
69
87
 
70
- it('debounce skips second call within debounce window', async () => {
88
+ it('enforces rotation independently per prefix (tasks + brain)', async () => {
89
+ const tasksExec = vi.fn();
90
+ const brainExec = vi.fn();
91
+ vi.doMock('../sqlite.js', () => ({ getNativeDb: () => ({ exec: tasksExec }) }));
92
+ vi.doMock('../brain-sqlite.js', () => ({ getBrainNativeDb: () => ({ exec: brainExec }) }));
93
+ const tempDir = join(tmpdir(), `cleo-test-rot-prefix-${Date.now()}`);
94
+ const backupDir = join(tempDir, 'backups', 'sqlite');
95
+ mkdirSync(backupDir, { recursive: true });
96
+ vi.doMock('../../paths.js', () => ({ getCleoDir: () => tempDir }));
97
+
98
+ // Seed 11 tasks.db and 11 brain.db stale snapshots.
99
+ for (let i = 0; i < 11; i++) {
100
+ const day = String(i + 1).padStart(2, '0');
101
+ writeFileSync(join(backupDir, `tasks-202601${day}-120000.db`), 'fake');
102
+ writeFileSync(join(backupDir, `brain-202601${day}-120000.db`), 'fake');
103
+ }
104
+
105
+ const { vacuumIntoBackupAll } = await import('../sqlite-backup.js');
106
+ await vacuumIntoBackupAll({ force: true });
107
+
108
+ const files = readdirSync(backupDir);
109
+ const tasksFiles = files.filter((f) => f.startsWith('tasks-') && f.endsWith('.db'));
110
+ const brainFiles = files.filter((f) => f.startsWith('brain-') && f.endsWith('.db'));
111
+ expect(tasksFiles.length).toBeLessThanOrEqual(10);
112
+ expect(brainFiles.length).toBeLessThanOrEqual(10);
113
+ });
114
+
115
+ it('vacuumIntoBackupAll snapshots both tasks.db and brain.db', async () => {
116
+ const tasksExec = vi.fn();
117
+ const brainExec = vi.fn();
118
+ vi.doMock('../sqlite.js', () => ({ getNativeDb: () => ({ exec: tasksExec }) }));
119
+ vi.doMock('../brain-sqlite.js', () => ({ getBrainNativeDb: () => ({ exec: brainExec }) }));
120
+ const tempDir = join(tmpdir(), `cleo-test-both-${Date.now()}`);
121
+ vi.doMock('../../paths.js', () => ({ getCleoDir: () => tempDir }));
122
+
123
+ const { vacuumIntoBackupAll } = await import('../sqlite-backup.js');
124
+ await vacuumIntoBackupAll({ force: true });
125
+
126
+ // Each DB should have received a wal_checkpoint and a VACUUM INTO call.
127
+ const assertExec = (mock: ReturnType<typeof vi.fn>) => {
128
+ const calls = mock.mock.calls.map((c) => c[0] as string);
129
+ expect(calls.some((c) => c.includes('wal_checkpoint'))).toBe(true);
130
+ expect(calls.some((c) => c.includes('VACUUM INTO'))).toBe(true);
131
+ };
132
+ assertExec(tasksExec);
133
+ assertExec(brainExec);
134
+ });
135
+
136
+ it('debounce skips second call within debounce window (tasks prefix)', async () => {
71
137
  const execMock = vi.fn();
72
138
  vi.doMock('../sqlite.js', () => ({ getNativeDb: () => ({ exec: execMock }) }));
139
+ vi.doMock('../brain-sqlite.js', () => ({ getBrainNativeDb: () => null }));
73
140
  const tempDir = join(tmpdir(), `cleo-test-debounce-${Date.now()}`);
74
141
  vi.doMock('../../paths.js', () => ({ getCleoDir: () => tempDir }));
75
142
 
@@ -78,8 +145,49 @@ describe('sqlite-backup', () => {
78
145
  await vacuumIntoBackup({ force: true });
79
146
  const callCountAfterFirst = execMock.mock.calls.length;
80
147
 
81
- // Second call without force -- should be debounced
148
+ // Second call without force should be debounced
82
149
  await vacuumIntoBackup({ force: false });
83
150
  expect(execMock.mock.calls.length).toBe(callCountAfterFirst);
84
151
  });
152
+
153
+ it('listSqliteBackups and listBrainBackups return prefix-specific entries newest-first', async () => {
154
+ vi.doMock('../sqlite.js', () => ({ getNativeDb: () => null }));
155
+ vi.doMock('../brain-sqlite.js', () => ({ getBrainNativeDb: () => null }));
156
+ const tempDir = join(tmpdir(), `cleo-test-list-${Date.now()}`);
157
+ const backupDir = join(tempDir, 'backups', 'sqlite');
158
+ mkdirSync(backupDir, { recursive: true });
159
+ vi.doMock('../../paths.js', () => ({ getCleoDir: () => tempDir }));
160
+
161
+ // Write files then explicitly set mtimes so the listing sort (by mtime
162
+ // descending) is deterministic regardless of filesystem timestamp
163
+ // resolution. Without utimesSync, two files written in the same tight
164
+ // loop can share the same mtime and fall back to insertion order.
165
+ const f1 = join(backupDir, 'tasks-20260101-120000.db');
166
+ const f2 = join(backupDir, 'tasks-20260102-120000.db');
167
+ const f3 = join(backupDir, 'brain-20260103-120000.db');
168
+ writeFileSync(f1, 'fake');
169
+ writeFileSync(f2, 'fake');
170
+ writeFileSync(f3, 'fake');
171
+ // Use distinct epoch seconds, increasing with the date in the filename
172
+ // so that tasks-20260102 is strictly newer than tasks-20260101.
173
+ utimesSync(f1, 1_700_000_100, 1_700_000_100);
174
+ utimesSync(f2, 1_700_000_200, 1_700_000_200);
175
+ utimesSync(f3, 1_700_000_300, 1_700_000_300);
176
+
177
+ const { listSqliteBackups, listBrainBackups, listSqliteBackupsAll } = await import(
178
+ '../sqlite-backup.js'
179
+ );
180
+ const tasksList = listSqliteBackups();
181
+ const brainList = listBrainBackups();
182
+ const all = listSqliteBackupsAll();
183
+
184
+ expect(tasksList.map((e) => e.name)).toEqual([
185
+ 'tasks-20260102-120000.db',
186
+ 'tasks-20260101-120000.db',
187
+ ]);
188
+ expect(brainList.map((e) => e.name)).toEqual(['brain-20260103-120000.db']);
189
+ expect(Object.keys(all).sort()).toEqual(['brain', 'tasks']);
190
+ expect(all['tasks']?.length).toBe(2);
191
+ expect(all['brain']?.length).toBe(1);
192
+ });
85
193
  });
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Idempotent cleanup of legacy and stray CLEO database files.
3
+ *
4
+ * Provides two independent cleanup functions:
5
+ *
6
+ * 1. {@link detectAndRemoveLegacyGlobalFiles} — removes stale files left at
7
+ * the global CLEO home directory (`getCleoHome()`) by pre-v2026.4.11
8
+ * naming migrations. Safe to call on repeat invocations — existence-checks
9
+ * guard every deletion.
10
+ *
11
+ * Files targeted (see ADR-036 §Decision/Global-Tier table):
12
+ * - workspace.db (pre-nexus naming relic)
13
+ * - workspace.db.bak-pre-rename (safety copy from a long-landed rename)
14
+ * - workspace.db-shm (SQLite shared-memory sidecar of workspace.db)
15
+ * - workspace.db-shm-wal (SQLite WAL sidecar of workspace.db)
16
+ * - nexus-pre-cleo.db.bak (pre-CLEO backup of nexus — migration complete)
17
+ *
18
+ * Live files (nexus.db, signaldock.db, machine-key, config.json, etc.) are
19
+ * NEVER touched. The function only acts on the explicit LEGACY_FILES list.
20
+ *
21
+ * 2. {@link detectAndRemoveStrayProjectNexus} — removes a stray
22
+ * `{projectRoot}/.cleo/nexus.db` that violates ADR-036's global-only
23
+ * nexus contract. Some pre-v2026.4.11 code path accidentally created a
24
+ * zero-byte nexus.db at project tier; this cleans it up on first run.
25
+ *
26
+ * @task T304
27
+ * @task T307
28
+ * @epic T299
29
+ * @adr ADR-036
30
+ * @why v2026.4.10 left workspace.db and pre-cleo backups at global tier;
31
+ * ADR-036 mandates their deletion to eliminate diagnostic confusion and
32
+ * false impressions of active legacy databases.
33
+ */
34
+
35
+ import fs from 'node:fs';
36
+ import path from 'node:path';
37
+ import { getLogger } from '../logger.js';
38
+ import { getCleoHome } from '../paths.js';
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Constants
42
+ // ---------------------------------------------------------------------------
43
+
44
+ /**
45
+ * Exhaustive list of legacy filenames that MUST be removed from the global
46
+ * CLEO home directory. No other files are touched.
47
+ *
48
+ * @task T304
49
+ */
50
+ const LEGACY_FILES: readonly string[] = [
51
+ 'workspace.db',
52
+ 'workspace.db.bak-pre-rename',
53
+ 'workspace.db-shm',
54
+ 'workspace.db-shm-wal',
55
+ 'nexus-pre-cleo.db.bak',
56
+ ] as const;
57
+
58
+ // ---------------------------------------------------------------------------
59
+ // Types
60
+ // ---------------------------------------------------------------------------
61
+
62
+ /** Result returned by {@link detectAndRemoveLegacyGlobalFiles}. */
63
+ export interface LegacyCleanupResult {
64
+ /** Filenames (basename only) that were successfully deleted. */
65
+ removed: string[];
66
+ /** Files that could not be deleted, with error messages. */
67
+ errors: Array<{ file: string; error: string }>;
68
+ }
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Implementation
72
+ // ---------------------------------------------------------------------------
73
+
74
+ /**
75
+ * Detect and remove legacy global-tier files from the CLEO home directory.
76
+ *
77
+ * Idempotent: safe to call when some or all files are already absent. Each
78
+ * file is individually existence-checked before attempting deletion. Failures
79
+ * on individual files are captured in `errors` rather than thrown, so the
80
+ * caller receives a complete picture of what was (and was not) cleaned up.
81
+ *
82
+ * Logs each successful deletion at `info` level and each failure at `warn`
83
+ * level via the shared pino logger.
84
+ *
85
+ * @param cleoHomeOverride - Optional directory override for tests. When
86
+ * omitted the canonical `getCleoHome()` path is used. Prefer passing this
87
+ * parameter in test harnesses rather than mutating `CLEO_HOME` environment
88
+ * variables, as it avoids global state contamination between test runs.
89
+ * @returns A {@link LegacyCleanupResult} describing what was removed and any
90
+ * errors encountered.
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * // Production usage (runs against real global home)
95
+ * const result = detectAndRemoveLegacyGlobalFiles();
96
+ * if (result.removed.length > 0) {
97
+ * // Legacy files were cleaned up
98
+ * }
99
+ *
100
+ * // Test usage (runs against tmp directory)
101
+ * const result = detectAndRemoveLegacyGlobalFiles('/tmp/fake-cleo-home');
102
+ * ```
103
+ *
104
+ * @task T304
105
+ * @epic T299
106
+ */
107
+ export function detectAndRemoveLegacyGlobalFiles(cleoHomeOverride?: string): LegacyCleanupResult {
108
+ const log = getLogger('cleanup-legacy');
109
+ const cleoHome = cleoHomeOverride ?? getCleoHome();
110
+ const removed: string[] = [];
111
+ const errors: Array<{ file: string; error: string }> = [];
112
+
113
+ for (const fileName of LEGACY_FILES) {
114
+ const fullPath = path.join(cleoHome, fileName);
115
+ try {
116
+ if (fs.existsSync(fullPath)) {
117
+ fs.unlinkSync(fullPath);
118
+ removed.push(fileName);
119
+ log.info({ file: fullPath }, 'Removed legacy global file');
120
+ }
121
+ } catch (err) {
122
+ const message = err instanceof Error ? err.message : String(err);
123
+ errors.push({ file: fileName, error: message });
124
+ log.warn({ file: fullPath, error: message }, 'Failed to remove legacy global file');
125
+ }
126
+ }
127
+
128
+ return { removed, errors };
129
+ }
130
+
131
+ // ---------------------------------------------------------------------------
132
+ // Project-tier stray nexus.db cleanup (T307)
133
+ // ---------------------------------------------------------------------------
134
+
135
+ /** Result returned by {@link detectAndRemoveStrayProjectNexus}. */
136
+ export interface StrayNexusCleanupResult {
137
+ /** Whether a stray nexus.db was found and deleted. */
138
+ removed: boolean;
139
+ /** Absolute path that was checked (and removed if `removed` is true). */
140
+ path: string;
141
+ }
142
+
143
+ /**
144
+ * Detect and remove a stray project-tier `.cleo/nexus.db` file.
145
+ *
146
+ * ADR-036 declares nexus.db as **global-only** — it lives exclusively under
147
+ * `getCleoHome()` (e.g. `~/.local/share/cleo/nexus.db` on Linux). A
148
+ * zero-byte stray was discovered at `/mnt/projects/cleocode/.cleo/nexus.db`
149
+ * (created 2026-03-31), likely produced by an early `cleo init` / `cleo
150
+ * nexus init` invocation that ran before the canonical path was fully wired
151
+ * through `getNexusDbPath()`.
152
+ *
153
+ * This function is idempotent: calling it when no stray file exists is a
154
+ * no-op. It is designed to be called once per CLI startup (alongside
155
+ * {@link detectAndRemoveLegacyGlobalFiles}) so that users who upgrade to
156
+ * v2026.4.11 have the stray silently cleaned up on the first `cleo` run.
157
+ *
158
+ * @param projectRoot - Absolute path to the project root directory. When
159
+ * omitted the caller is responsible for supplying the current project
160
+ * root from `getProjectRoot()`. An override parameter is accepted here to
161
+ * keep tests hermetic (avoids reading live `process.cwd()` state).
162
+ * @returns A {@link StrayNexusCleanupResult} indicating whether a file was
163
+ * removed and the absolute path that was checked.
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * // Production usage
168
+ * import { getProjectRoot } from '../paths.js';
169
+ * const result = detectAndRemoveStrayProjectNexus(getProjectRoot());
170
+ * if (result.removed) {
171
+ * // Stray project-tier nexus.db has been cleaned up
172
+ * }
173
+ *
174
+ * // Test usage (hermetic)
175
+ * const result = detectAndRemoveStrayProjectNexus('/tmp/fake-project-root');
176
+ * ```
177
+ *
178
+ * @task T307
179
+ * @epic T299
180
+ * @adr ADR-036
181
+ * @why ADR-036 §Decision/Global-Tier: nexus.db is global-only. A stray
182
+ * project-tier copy was created by pre-v2026.4.11 code and must be removed
183
+ * to prevent diagnostic confusion and guard against future regressions.
184
+ */
185
+ export function detectAndRemoveStrayProjectNexus(projectRoot: string): StrayNexusCleanupResult {
186
+ const log = getLogger('cleanup-legacy');
187
+ const strayPath = path.join(projectRoot, '.cleo', 'nexus.db');
188
+
189
+ if (fs.existsSync(strayPath)) {
190
+ try {
191
+ fs.unlinkSync(strayPath);
192
+ log.warn(
193
+ { path: strayPath },
194
+ 'Removed stray project-tier nexus.db (violates ADR-036 global-only contract)',
195
+ );
196
+ return { removed: true, path: strayPath };
197
+ } catch (err) {
198
+ const message = err instanceof Error ? err.message : String(err);
199
+ log.warn(
200
+ { path: strayPath, error: message },
201
+ 'Failed to remove stray project-tier nexus.db — manual deletion may be required',
202
+ );
203
+ return { removed: false, path: strayPath };
204
+ }
205
+ }
206
+
207
+ return { removed: false, path: strayPath };
208
+ }
@@ -61,6 +61,13 @@ export {
61
61
  SafetyDataAccessor,
62
62
  wrapWithSafety,
63
63
  } from './safety-data-accessor.js';
64
+ export {
65
+ listBrainBackups,
66
+ listSqliteBackups,
67
+ listSqliteBackupsAll,
68
+ vacuumIntoBackup,
69
+ vacuumIntoBackupAll,
70
+ } from './sqlite-backup.js';
64
71
 
65
72
  /**
66
73
  * Get a StoreProvider instance for the given working directory.