@astragenie/astramemory-local 0.7.2

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 (493) hide show
  1. package/CHANGELOG.md +341 -0
  2. package/README.md +419 -0
  3. package/dist/backup/retention.d.ts +15 -0
  4. package/dist/backup/retention.js +62 -0
  5. package/dist/backup/retention.js.map +1 -0
  6. package/dist/backup/snapshot.d.ts +21 -0
  7. package/dist/backup/snapshot.js +55 -0
  8. package/dist/backup/snapshot.js.map +1 -0
  9. package/dist/backup/verify.d.ts +23 -0
  10. package/dist/backup/verify.js +77 -0
  11. package/dist/backup/verify.js.map +1 -0
  12. package/dist/budget/tracker.d.ts +58 -0
  13. package/dist/budget/tracker.js +102 -0
  14. package/dist/budget/tracker.js.map +1 -0
  15. package/dist/capture/codex.d.ts +63 -0
  16. package/dist/capture/codex.js +0 -0
  17. package/dist/capture/codex.js.map +1 -0
  18. package/dist/cli/backup.d.ts +1 -0
  19. package/dist/cli/backup.js +112 -0
  20. package/dist/cli/backup.js.map +1 -0
  21. package/dist/cli/budget.d.ts +7 -0
  22. package/dist/cli/budget.js +44 -0
  23. package/dist/cli/budget.js.map +1 -0
  24. package/dist/cli/capture.d.ts +10 -0
  25. package/dist/cli/capture.js +113 -0
  26. package/dist/cli/capture.js.map +1 -0
  27. package/dist/cli/consolidate.d.ts +16 -0
  28. package/dist/cli/consolidate.js +146 -0
  29. package/dist/cli/consolidate.js.map +1 -0
  30. package/dist/cli/doctor.d.ts +1 -0
  31. package/dist/cli/doctor.js +54 -0
  32. package/dist/cli/doctor.js.map +1 -0
  33. package/dist/cli/entity-backfill.d.ts +10 -0
  34. package/dist/cli/entity-backfill.js +46 -0
  35. package/dist/cli/entity-backfill.js.map +1 -0
  36. package/dist/cli/hook-install.d.ts +45 -0
  37. package/dist/cli/hook-install.js +77 -0
  38. package/dist/cli/hook-install.js.map +1 -0
  39. package/dist/cli/index.d.ts +2 -0
  40. package/dist/cli/index.js +312 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/cli/init.d.ts +16 -0
  43. package/dist/cli/init.js +431 -0
  44. package/dist/cli/init.js.map +1 -0
  45. package/dist/cli/mcp-stdio.d.ts +18 -0
  46. package/dist/cli/mcp-stdio.js +67 -0
  47. package/dist/cli/mcp-stdio.js.map +1 -0
  48. package/dist/cli/memory.d.ts +15 -0
  49. package/dist/cli/memory.js +52 -0
  50. package/dist/cli/memory.js.map +1 -0
  51. package/dist/cli/open-runtime-db.d.ts +15 -0
  52. package/dist/cli/open-runtime-db.js +37 -0
  53. package/dist/cli/open-runtime-db.js.map +1 -0
  54. package/dist/cli/pair.d.ts +29 -0
  55. package/dist/cli/pair.js +64 -0
  56. package/dist/cli/pair.js.map +1 -0
  57. package/dist/cli/providers.d.ts +10 -0
  58. package/dist/cli/providers.js +97 -0
  59. package/dist/cli/providers.js.map +1 -0
  60. package/dist/cli/queue-purge.d.ts +5 -0
  61. package/dist/cli/queue-purge.js +92 -0
  62. package/dist/cli/queue-purge.js.map +1 -0
  63. package/dist/cli/queue.d.ts +29 -0
  64. package/dist/cli/queue.js +73 -0
  65. package/dist/cli/queue.js.map +1 -0
  66. package/dist/cli/rebuild.d.ts +15 -0
  67. package/dist/cli/rebuild.js +70 -0
  68. package/dist/cli/rebuild.js.map +1 -0
  69. package/dist/cli/reembed-dim.d.ts +21 -0
  70. package/dist/cli/reembed-dim.js +199 -0
  71. package/dist/cli/reembed-dim.js.map +1 -0
  72. package/dist/cli/reinstall.d.ts +1 -0
  73. package/dist/cli/reinstall.js +205 -0
  74. package/dist/cli/reinstall.js.map +1 -0
  75. package/dist/cli/restore.d.ts +1 -0
  76. package/dist/cli/restore.js +167 -0
  77. package/dist/cli/restore.js.map +1 -0
  78. package/dist/cli/retag.d.ts +14 -0
  79. package/dist/cli/retag.js +62 -0
  80. package/dist/cli/retag.js.map +1 -0
  81. package/dist/cli/search.d.ts +66 -0
  82. package/dist/cli/search.js +174 -0
  83. package/dist/cli/search.js.map +1 -0
  84. package/dist/cli/serve.d.ts +9 -0
  85. package/dist/cli/serve.js +364 -0
  86. package/dist/cli/serve.js.map +1 -0
  87. package/dist/cli/service.d.ts +1 -0
  88. package/dist/cli/service.js +121 -0
  89. package/dist/cli/service.js.map +1 -0
  90. package/dist/cli/sync.d.ts +15 -0
  91. package/dist/cli/sync.js +61 -0
  92. package/dist/cli/sync.js.map +1 -0
  93. package/dist/cli/token.d.ts +24 -0
  94. package/dist/cli/token.js +77 -0
  95. package/dist/cli/token.js.map +1 -0
  96. package/dist/cli/wait-health.d.ts +4 -0
  97. package/dist/cli/wait-health.js +23 -0
  98. package/dist/cli/wait-health.js.map +1 -0
  99. package/dist/config/config.d.ts +127 -0
  100. package/dist/config/config.js +38 -0
  101. package/dist/config/config.js.map +1 -0
  102. package/dist/config/datadir.d.ts +30 -0
  103. package/dist/config/datadir.js +65 -0
  104. package/dist/config/datadir.js.map +1 -0
  105. package/dist/config/loader.d.ts +23 -0
  106. package/dist/config/loader.js +102 -0
  107. package/dist/config/loader.js.map +1 -0
  108. package/dist/config/migrate-dirs.d.ts +36 -0
  109. package/dist/config/migrate-dirs.js +132 -0
  110. package/dist/config/migrate-dirs.js.map +1 -0
  111. package/dist/config/persist-envs.d.ts +23 -0
  112. package/dist/config/persist-envs.js +119 -0
  113. package/dist/config/persist-envs.js.map +1 -0
  114. package/dist/config/resolve-runtime.d.ts +19 -0
  115. package/dist/config/resolve-runtime.js +53 -0
  116. package/dist/config/resolve-runtime.js.map +1 -0
  117. package/dist/config/secrets.d.ts +28 -0
  118. package/dist/config/secrets.js +38 -0
  119. package/dist/config/secrets.js.map +1 -0
  120. package/dist/config/sync-settings.d.ts +16 -0
  121. package/dist/config/sync-settings.js +34 -0
  122. package/dist/config/sync-settings.js.map +1 -0
  123. package/dist/config/writer.d.ts +19 -0
  124. package/dist/config/writer.js +121 -0
  125. package/dist/config/writer.js.map +1 -0
  126. package/dist/consolidate/consolidate.d.ts +80 -0
  127. package/dist/consolidate/consolidate.js +0 -0
  128. package/dist/consolidate/consolidate.js.map +1 -0
  129. package/dist/consolidate/proposals.d.ts +35 -0
  130. package/dist/consolidate/proposals.js +66 -0
  131. package/dist/consolidate/proposals.js.map +1 -0
  132. package/dist/contracts/atom-wire.d.ts +48 -0
  133. package/dist/contracts/atom-wire.js +55 -0
  134. package/dist/contracts/atom-wire.js.map +1 -0
  135. package/dist/contracts/embed.d.ts +41 -0
  136. package/dist/contracts/embed.js +20 -0
  137. package/dist/contracts/embed.js.map +1 -0
  138. package/dist/contracts/index.d.ts +5 -0
  139. package/dist/contracts/index.js +6 -0
  140. package/dist/contracts/index.js.map +1 -0
  141. package/dist/contracts/job.d.ts +113 -0
  142. package/dist/contracts/job.js +32 -0
  143. package/dist/contracts/job.js.map +1 -0
  144. package/dist/contracts/llm.d.ts +30 -0
  145. package/dist/contracts/llm.js +2 -0
  146. package/dist/contracts/llm.js.map +1 -0
  147. package/dist/contracts/memory.d.ts +47 -0
  148. package/dist/contracts/memory.js +5 -0
  149. package/dist/contracts/memory.js.map +1 -0
  150. package/dist/contracts/vector.d.ts +29 -0
  151. package/dist/contracts/vector.js +2 -0
  152. package/dist/contracts/vector.js.map +1 -0
  153. package/dist/distill/flatten-turns.d.ts +1 -0
  154. package/dist/distill/flatten-turns.js +50 -0
  155. package/dist/distill/flatten-turns.js.map +1 -0
  156. package/dist/distill/pipeline.d.ts +45 -0
  157. package/dist/distill/pipeline.js +113 -0
  158. package/dist/distill/pipeline.js.map +1 -0
  159. package/dist/distill/prompts/extract.d.ts +122 -0
  160. package/dist/distill/prompts/extract.js +67 -0
  161. package/dist/distill/prompts/extract.js.map +1 -0
  162. package/dist/distill/stages/01-cleanup.d.ts +9 -0
  163. package/dist/distill/stages/01-cleanup.js +67 -0
  164. package/dist/distill/stages/01-cleanup.js.map +1 -0
  165. package/dist/distill/stages/02-normalize.d.ts +9 -0
  166. package/dist/distill/stages/02-normalize.js +76 -0
  167. package/dist/distill/stages/02-normalize.js.map +1 -0
  168. package/dist/distill/stages/03-chunk.d.ts +22 -0
  169. package/dist/distill/stages/03-chunk.js +138 -0
  170. package/dist/distill/stages/03-chunk.js.map +1 -0
  171. package/dist/distill/stages/04-compact.d.ts +28 -0
  172. package/dist/distill/stages/04-compact.js +69 -0
  173. package/dist/distill/stages/04-compact.js.map +1 -0
  174. package/dist/distill/stages/05-extract.d.ts +35 -0
  175. package/dist/distill/stages/05-extract.js +101 -0
  176. package/dist/distill/stages/05-extract.js.map +1 -0
  177. package/dist/distill/stages/06-reduce.d.ts +16 -0
  178. package/dist/distill/stages/06-reduce.js +30 -0
  179. package/dist/distill/stages/06-reduce.js.map +1 -0
  180. package/dist/distill/stages/07-memory-normalize.d.ts +27 -0
  181. package/dist/distill/stages/07-memory-normalize.js +65 -0
  182. package/dist/distill/stages/07-memory-normalize.js.map +1 -0
  183. package/dist/distill/stages/08-embed-index.d.ts +31 -0
  184. package/dist/distill/stages/08-embed-index.js +82 -0
  185. package/dist/distill/stages/08-embed-index.js.map +1 -0
  186. package/dist/doctor/checks.d.ts +77 -0
  187. package/dist/doctor/checks.js +626 -0
  188. package/dist/doctor/checks.js.map +1 -0
  189. package/dist/doctor/hardening-checks.d.ts +9 -0
  190. package/dist/doctor/hardening-checks.js +182 -0
  191. package/dist/doctor/hardening-checks.js.map +1 -0
  192. package/dist/doctor/probes/embed-probe.d.ts +19 -0
  193. package/dist/doctor/probes/embed-probe.js +47 -0
  194. package/dist/doctor/probes/embed-probe.js.map +1 -0
  195. package/dist/doctor/probes/llm-chat-probe.d.ts +11 -0
  196. package/dist/doctor/probes/llm-chat-probe.js +41 -0
  197. package/dist/doctor/probes/llm-chat-probe.js.map +1 -0
  198. package/dist/doctor/probes/plugin-coexistence.d.ts +14 -0
  199. package/dist/doctor/probes/plugin-coexistence.js +60 -0
  200. package/dist/doctor/probes/plugin-coexistence.js.map +1 -0
  201. package/dist/doctor/runner.d.ts +17 -0
  202. package/dist/doctor/runner.js +53 -0
  203. package/dist/doctor/runner.js.map +1 -0
  204. package/dist/doctor/types.d.ts +12 -0
  205. package/dist/doctor/types.js +2 -0
  206. package/dist/doctor/types.js.map +1 -0
  207. package/dist/entity/backfill.d.ts +30 -0
  208. package/dist/entity/backfill.js +55 -0
  209. package/dist/entity/backfill.js.map +1 -0
  210. package/dist/entity/extract-entities.d.ts +27 -0
  211. package/dist/entity/extract-entities.js +86 -0
  212. package/dist/entity/extract-entities.js.map +1 -0
  213. package/dist/entity/normalize.d.ts +17 -0
  214. package/dist/entity/normalize.js +20 -0
  215. package/dist/entity/normalize.js.map +1 -0
  216. package/dist/eval/harness.d.ts +96 -0
  217. package/dist/eval/harness.js +119 -0
  218. package/dist/eval/harness.js.map +1 -0
  219. package/dist/eval/metrics.d.ts +23 -0
  220. package/dist/eval/metrics.js +44 -0
  221. package/dist/eval/metrics.js.map +1 -0
  222. package/dist/log/correlation.d.ts +24 -0
  223. package/dist/log/correlation.js +33 -0
  224. package/dist/log/correlation.js.map +1 -0
  225. package/dist/log/logger.d.ts +38 -0
  226. package/dist/log/logger.js +129 -0
  227. package/dist/log/logger.js.map +1 -0
  228. package/dist/log/scrub.d.ts +33 -0
  229. package/dist/log/scrub.js +91 -0
  230. package/dist/log/scrub.js.map +1 -0
  231. package/dist/mcp/server.d.ts +36 -0
  232. package/dist/mcp/server.js +553 -0
  233. package/dist/mcp/server.js.map +1 -0
  234. package/dist/memory-tool/adapter.d.ts +73 -0
  235. package/dist/memory-tool/adapter.js +269 -0
  236. package/dist/memory-tool/adapter.js.map +1 -0
  237. package/dist/pipeline/errors.d.ts +21 -0
  238. package/dist/pipeline/errors.js +34 -0
  239. package/dist/pipeline/errors.js.map +1 -0
  240. package/dist/pipeline/failure-classifier.d.ts +13 -0
  241. package/dist/pipeline/failure-classifier.js +72 -0
  242. package/dist/pipeline/failure-classifier.js.map +1 -0
  243. package/dist/pipeline/handler-ctx-ext.d.ts +23 -0
  244. package/dist/pipeline/handler-ctx-ext.js +19 -0
  245. package/dist/pipeline/handler-ctx-ext.js.map +1 -0
  246. package/dist/pipeline/handler.d.ts +20 -0
  247. package/dist/pipeline/handler.js +2 -0
  248. package/dist/pipeline/handler.js.map +1 -0
  249. package/dist/pipeline/handlers/cleanup.d.ts +14 -0
  250. package/dist/pipeline/handlers/cleanup.js +47 -0
  251. package/dist/pipeline/handlers/cleanup.js.map +1 -0
  252. package/dist/pipeline/handlers/consolidate.d.ts +8 -0
  253. package/dist/pipeline/handlers/consolidate.js +23 -0
  254. package/dist/pipeline/handlers/consolidate.js.map +1 -0
  255. package/dist/pipeline/handlers/distill-events.d.ts +15 -0
  256. package/dist/pipeline/handlers/distill-events.js +134 -0
  257. package/dist/pipeline/handlers/distill-events.js.map +1 -0
  258. package/dist/pipeline/handlers/distill.d.ts +17 -0
  259. package/dist/pipeline/handlers/distill.js +110 -0
  260. package/dist/pipeline/handlers/distill.js.map +1 -0
  261. package/dist/pipeline/handlers/reembed.d.ts +10 -0
  262. package/dist/pipeline/handlers/reembed.js +34 -0
  263. package/dist/pipeline/handlers/reembed.js.map +1 -0
  264. package/dist/pipeline/job-repo.d.ts +86 -0
  265. package/dist/pipeline/job-repo.js +168 -0
  266. package/dist/pipeline/job-repo.js.map +1 -0
  267. package/dist/pipeline/mock-providers.d.ts +49 -0
  268. package/dist/pipeline/mock-providers.js +175 -0
  269. package/dist/pipeline/mock-providers.js.map +1 -0
  270. package/dist/pipeline/registry.d.ts +15 -0
  271. package/dist/pipeline/registry.js +20 -0
  272. package/dist/pipeline/registry.js.map +1 -0
  273. package/dist/pipeline/worker.d.ts +41 -0
  274. package/dist/pipeline/worker.js +167 -0
  275. package/dist/pipeline/worker.js.map +1 -0
  276. package/dist/providers/embed/azure-openai.d.ts +25 -0
  277. package/dist/providers/embed/azure-openai.js +138 -0
  278. package/dist/providers/embed/azure-openai.js.map +1 -0
  279. package/dist/providers/embed/ollama.d.ts +17 -0
  280. package/dist/providers/embed/ollama.js +106 -0
  281. package/dist/providers/embed/ollama.js.map +1 -0
  282. package/dist/providers/index.d.ts +19 -0
  283. package/dist/providers/index.js +72 -0
  284. package/dist/providers/index.js.map +1 -0
  285. package/dist/providers/llm/azure-openai.d.ts +20 -0
  286. package/dist/providers/llm/azure-openai.js +135 -0
  287. package/dist/providers/llm/azure-openai.js.map +1 -0
  288. package/dist/providers/llm/ollama.d.ts +13 -0
  289. package/dist/providers/llm/ollama.js +113 -0
  290. package/dist/providers/llm/ollama.js.map +1 -0
  291. package/dist/providers/llm/pricing.d.ts +21 -0
  292. package/dist/providers/llm/pricing.js +22 -0
  293. package/dist/providers/llm/pricing.js.map +1 -0
  294. package/dist/recall/pack.d.ts +32 -0
  295. package/dist/recall/pack.js +90 -0
  296. package/dist/recall/pack.js.map +1 -0
  297. package/dist/recall/policy.d.ts +39 -0
  298. package/dist/recall/policy.js +96 -0
  299. package/dist/recall/policy.js.map +1 -0
  300. package/dist/redact/detectors.d.ts +20 -0
  301. package/dist/redact/detectors.js +85 -0
  302. package/dist/redact/detectors.js.map +1 -0
  303. package/dist/redact/entropy.d.ts +24 -0
  304. package/dist/redact/entropy.js +77 -0
  305. package/dist/redact/entropy.js.map +1 -0
  306. package/dist/redact/index.d.ts +47 -0
  307. package/dist/redact/index.js +165 -0
  308. package/dist/redact/index.js.map +1 -0
  309. package/dist/search/fuse.d.ts +108 -0
  310. package/dist/search/fuse.js +135 -0
  311. package/dist/search/fuse.js.map +1 -0
  312. package/dist/search/query.d.ts +28 -0
  313. package/dist/search/query.js +70 -0
  314. package/dist/search/query.js.map +1 -0
  315. package/dist/search/search.d.ts +164 -0
  316. package/dist/search/search.js +310 -0
  317. package/dist/search/search.js.map +1 -0
  318. package/dist/server/app.d.ts +17 -0
  319. package/dist/server/app.js +133 -0
  320. package/dist/server/app.js.map +1 -0
  321. package/dist/server/health-state.d.ts +29 -0
  322. package/dist/server/health-state.js +28 -0
  323. package/dist/server/health-state.js.map +1 -0
  324. package/dist/server/lib/network.d.ts +12 -0
  325. package/dist/server/lib/network.js +16 -0
  326. package/dist/server/lib/network.js.map +1 -0
  327. package/dist/server/lib/score-contract.d.ts +36 -0
  328. package/dist/server/lib/score-contract.js +54 -0
  329. package/dist/server/lib/score-contract.js.map +1 -0
  330. package/dist/server/lib/stable-stringify.d.ts +10 -0
  331. package/dist/server/lib/stable-stringify.js +27 -0
  332. package/dist/server/lib/stable-stringify.js.map +1 -0
  333. package/dist/server/lib/wire-meta.d.ts +7 -0
  334. package/dist/server/lib/wire-meta.js +29 -0
  335. package/dist/server/lib/wire-meta.js.map +1 -0
  336. package/dist/server/queries/dashboard.d.ts +142 -0
  337. package/dist/server/queries/dashboard.js +166 -0
  338. package/dist/server/queries/dashboard.js.map +1 -0
  339. package/dist/server/routes/consolidation.d.ts +14 -0
  340. package/dist/server/routes/consolidation.js +67 -0
  341. package/dist/server/routes/consolidation.js.map +1 -0
  342. package/dist/server/routes/dashboard-api-html.d.ts +15 -0
  343. package/dist/server/routes/dashboard-api-html.js +144 -0
  344. package/dist/server/routes/dashboard-api-html.js.map +1 -0
  345. package/dist/server/routes/dashboard-consolidation-html.d.ts +26 -0
  346. package/dist/server/routes/dashboard-consolidation-html.js +202 -0
  347. package/dist/server/routes/dashboard-consolidation-html.js.map +1 -0
  348. package/dist/server/routes/dashboard-html.d.ts +15 -0
  349. package/dist/server/routes/dashboard-html.js +365 -0
  350. package/dist/server/routes/dashboard-html.js.map +1 -0
  351. package/dist/server/routes/dashboard-jobs-html.d.ts +18 -0
  352. package/dist/server/routes/dashboard-jobs-html.js +186 -0
  353. package/dist/server/routes/dashboard-jobs-html.js.map +1 -0
  354. package/dist/server/routes/dashboard-search-html.d.ts +18 -0
  355. package/dist/server/routes/dashboard-search-html.js +189 -0
  356. package/dist/server/routes/dashboard-search-html.js.map +1 -0
  357. package/dist/server/routes/dashboard.d.ts +19 -0
  358. package/dist/server/routes/dashboard.js +68 -0
  359. package/dist/server/routes/dashboard.js.map +1 -0
  360. package/dist/server/routes/digest.d.ts +9 -0
  361. package/dist/server/routes/digest.js +37 -0
  362. package/dist/server/routes/digest.js.map +1 -0
  363. package/dist/server/routes/entities.d.ts +12 -0
  364. package/dist/server/routes/entities.js +46 -0
  365. package/dist/server/routes/entities.js.map +1 -0
  366. package/dist/server/routes/health.d.ts +14 -0
  367. package/dist/server/routes/health.js +100 -0
  368. package/dist/server/routes/health.js.map +1 -0
  369. package/dist/server/routes/ingest.d.ts +209 -0
  370. package/dist/server/routes/ingest.js +454 -0
  371. package/dist/server/routes/ingest.js.map +1 -0
  372. package/dist/server/routes/lifecycle.d.ts +21 -0
  373. package/dist/server/routes/lifecycle.js +132 -0
  374. package/dist/server/routes/lifecycle.js.map +1 -0
  375. package/dist/server/routes/mcp.d.ts +15 -0
  376. package/dist/server/routes/mcp.js +36 -0
  377. package/dist/server/routes/mcp.js.map +1 -0
  378. package/dist/server/routes/memory-tool.d.ts +14 -0
  379. package/dist/server/routes/memory-tool.js +28 -0
  380. package/dist/server/routes/memory-tool.js.map +1 -0
  381. package/dist/server/routes/memory.d.ts +7 -0
  382. package/dist/server/routes/memory.js +19 -0
  383. package/dist/server/routes/memory.js.map +1 -0
  384. package/dist/server/routes/recall.d.ts +15 -0
  385. package/dist/server/routes/recall.js +74 -0
  386. package/dist/server/routes/recall.js.map +1 -0
  387. package/dist/server/routes/search.d.ts +12 -0
  388. package/dist/server/routes/search.js +203 -0
  389. package/dist/server/routes/search.js.map +1 -0
  390. package/dist/server/routes/version.d.ts +2 -0
  391. package/dist/server/routes/version.js +11 -0
  392. package/dist/server/routes/version.js.map +1 -0
  393. package/dist/server/routes/why.d.ts +9 -0
  394. package/dist/server/routes/why.js +38 -0
  395. package/dist/server/routes/why.js.map +1 -0
  396. package/dist/service/index.d.ts +10 -0
  397. package/dist/service/index.js +25 -0
  398. package/dist/service/index.js.map +1 -0
  399. package/dist/service/install-flow.d.ts +18 -0
  400. package/dist/service/install-flow.js +47 -0
  401. package/dist/service/install-flow.js.map +1 -0
  402. package/dist/service/instance-lock.d.ts +26 -0
  403. package/dist/service/instance-lock.js +150 -0
  404. package/dist/service/instance-lock.js.map +1 -0
  405. package/dist/service/launchd.d.ts +11 -0
  406. package/dist/service/launchd.js +196 -0
  407. package/dist/service/launchd.js.map +1 -0
  408. package/dist/service/schtasks.d.ts +31 -0
  409. package/dist/service/schtasks.js +274 -0
  410. package/dist/service/schtasks.js.map +1 -0
  411. package/dist/service/shim.d.ts +21 -0
  412. package/dist/service/shim.js +80 -0
  413. package/dist/service/shim.js.map +1 -0
  414. package/dist/service/systemd.d.ts +11 -0
  415. package/dist/service/systemd.js +150 -0
  416. package/dist/service/systemd.js.map +1 -0
  417. package/dist/service/task-xml.d.ts +36 -0
  418. package/dist/service/task-xml.js +91 -0
  419. package/dist/service/task-xml.js.map +1 -0
  420. package/dist/service/types.d.ts +47 -0
  421. package/dist/service/types.js +2 -0
  422. package/dist/service/types.js.map +1 -0
  423. package/dist/storage/archival.d.ts +29 -0
  424. package/dist/storage/archival.js +47 -0
  425. package/dist/storage/archival.js.map +1 -0
  426. package/dist/storage/bearer-keystore.d.ts +34 -0
  427. package/dist/storage/bearer-keystore.js +75 -0
  428. package/dist/storage/bearer-keystore.js.map +1 -0
  429. package/dist/storage/db.d.ts +37 -0
  430. package/dist/storage/db.js +92 -0
  431. package/dist/storage/db.js.map +1 -0
  432. package/dist/storage/entities.d.ts +71 -0
  433. package/dist/storage/entities.js +141 -0
  434. package/dist/storage/entities.js.map +1 -0
  435. package/dist/storage/ingest-idempotency.d.ts +26 -0
  436. package/dist/storage/ingest-idempotency.js +29 -0
  437. package/dist/storage/ingest-idempotency.js.map +1 -0
  438. package/dist/storage/keystore.d.ts +64 -0
  439. package/dist/storage/keystore.js +194 -0
  440. package/dist/storage/keystore.js.map +1 -0
  441. package/dist/storage/memories.d.ts +51 -0
  442. package/dist/storage/memories.js +67 -0
  443. package/dist/storage/memories.js.map +1 -0
  444. package/dist/storage/memory-events.d.ts +145 -0
  445. package/dist/storage/memory-events.js +287 -0
  446. package/dist/storage/memory-events.js.map +1 -0
  447. package/dist/storage/migrate-encrypt.d.ts +16 -0
  448. package/dist/storage/migrate-encrypt.js +121 -0
  449. package/dist/storage/migrate-encrypt.js.map +1 -0
  450. package/dist/storage/migrate.d.ts +27 -0
  451. package/dist/storage/migrate.js +105 -0
  452. package/dist/storage/migrate.js.map +1 -0
  453. package/dist/storage/redaction-log.d.ts +18 -0
  454. package/dist/storage/redaction-log.js +27 -0
  455. package/dist/storage/redaction-log.js.map +1 -0
  456. package/dist/storage/usefulness.d.ts +115 -0
  457. package/dist/storage/usefulness.js +203 -0
  458. package/dist/storage/usefulness.js.map +1 -0
  459. package/dist/sync/conflict-resolve.d.ts +26 -0
  460. package/dist/sync/conflict-resolve.js +139 -0
  461. package/dist/sync/conflict-resolve.js.map +1 -0
  462. package/dist/sync/puller.d.ts +115 -0
  463. package/dist/sync/puller.js +173 -0
  464. package/dist/sync/puller.js.map +1 -0
  465. package/dist/sync/shipper.d.ts +112 -0
  466. package/dist/sync/shipper.js +189 -0
  467. package/dist/sync/shipper.js.map +1 -0
  468. package/dist/tag-hygiene/backfill.d.ts +50 -0
  469. package/dist/tag-hygiene/backfill.js +117 -0
  470. package/dist/tag-hygiene/backfill.js.map +1 -0
  471. package/dist/tag-hygiene/derive-repo.d.ts +9 -0
  472. package/dist/tag-hygiene/derive-repo.js +19 -0
  473. package/dist/tag-hygiene/derive-repo.js.map +1 -0
  474. package/dist/tag-hygiene/tier2-infer.d.ts +28 -0
  475. package/dist/tag-hygiene/tier2-infer.js +72 -0
  476. package/dist/tag-hygiene/tier2-infer.js.map +1 -0
  477. package/dist/vector/sqlite-vec.d.ts +16 -0
  478. package/dist/vector/sqlite-vec.js +49 -0
  479. package/dist/vector/sqlite-vec.js.map +1 -0
  480. package/migrations/001-init.sql +117 -0
  481. package/migrations/002-wire-v1.sql +16 -0
  482. package/migrations/003-expand-memory-types.sql +81 -0
  483. package/migrations/004-provenance.sql +4 -0
  484. package/migrations/005-security.sql +12 -0
  485. package/migrations/006-atom-v3.sql +28 -0
  486. package/migrations/007-memory-events.sql +30 -0
  487. package/migrations/008-consolidation.sql +31 -0
  488. package/migrations/009-tag-hygiene.sql +13 -0
  489. package/migrations/010-sync-pull.sql +53 -0
  490. package/migrations/011-embed-dim-migration.sql +28 -0
  491. package/migrations/012-entities.sql +36 -0
  492. package/migrations/013-archival.sql +50 -0
  493. package/package.json +50 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Distill-events handler — ADR-008 `events` capture kind.
3
+ *
4
+ * Pre-typed atom candidates (runner-plugin grades/lessons/review verdicts)
5
+ * are already atom-shaped when they hit the wire, so this handler skips
6
+ * pipeline stages 1-5 (cleanup/normalize/chunk/compact/extract — the raw-text
7
+ * and LLM stages) and enters directly at stage 6 (reduce), chaining straight
8
+ * through stage 7 (memory-normalize) and stage 8 (embed+index), mirroring
9
+ * the same three-stage tail src/distill/pipeline.ts runs for the transcript
10
+ * path. No LLMProvider is used here (no compaction/extraction call), so the
11
+ * BudgetExceeded semantics distillHandler has for stages 4/5 do not apply —
12
+ * only the embed provider is exercised (stage 8).
13
+ */
14
+ import { createHash } from 'node:crypto';
15
+ import { z } from 'zod';
16
+ import { isExtendedCtx } from '../handler-ctx-ext.js';
17
+ import { reduce } from '../../distill/stages/06-reduce.js';
18
+ import { memoryNormalize } from '../../distill/stages/07-memory-normalize.js';
19
+ import { embedAndIndex } from '../../distill/stages/08-embed-index.js';
20
+ import { backfillSummaryMemoryId } from '../../storage/ingest-idempotency.js';
21
+ import { childLogger } from '../../log/logger.js';
22
+ /**
23
+ * Flexible payload schema — ingest route writes {transcript_id, session_id}
24
+ * without the `kind` discriminator. Accept both forms (mirrors distill.ts).
25
+ */
26
+ const DistillEventsPayloadFlexSchema = z.object({
27
+ transcript_id: z.string().min(1),
28
+ session_id: z.string().min(1),
29
+ kind: z.string().optional(),
30
+ });
31
+ /**
32
+ * Shape of one event as stored in `transcripts.content` (redacted, JSON
33
+ * array) — mirrors CanonicalEventItemSchema in server/routes/ingest.ts and
34
+ * the 7-type registry in distill/prompts/extract.ts (AtomSchema).
35
+ */
36
+ const StoredEventSchema = z.object({
37
+ type: z.enum(['decision', 'fact', 'lesson', 'command', 'todo', 'note', 'event']),
38
+ text: z.string().min(1),
39
+ importance: z.number().min(0).max(1).optional(),
40
+ confidence: z.number().min(0).max(1).optional(),
41
+ evidence: z.string().optional(),
42
+ occurred_at: z.number().optional(),
43
+ });
44
+ const StoredEventsSchema = z.array(StoredEventSchema).min(1);
45
+ /** Applied when the source event omits importance/confidence (ADR-008). */
46
+ const DEFAULT_IMPORTANCE = 0.7;
47
+ const DEFAULT_CONFIDENCE = 0.9;
48
+ export const distillEventsHandler = {
49
+ kind: 'distill-events',
50
+ async handle(payload, ctx) {
51
+ const parsed = DistillEventsPayloadFlexSchema.safeParse(payload);
52
+ if (!parsed.success) {
53
+ throw new Error(`Invalid distill-events payload: ${parsed.error.message}`);
54
+ }
55
+ const { transcript_id, session_id } = parsed.data;
56
+ // Fetch the transcript row the ingest route wrote (content = JSON of
57
+ // redacted events, source = `<tool>-events` or 'events').
58
+ const transcript = ctx.db
59
+ .prepare('SELECT id, session_id, content, source FROM transcripts WHERE id = ?')
60
+ .get(transcript_id);
61
+ if (!transcript) {
62
+ throw new Error(`Transcript not found: ${transcript_id}`);
63
+ }
64
+ // Fetch session metadata for memory context
65
+ const session = ctx.db
66
+ .prepare('SELECT id, repo, project, branch, agent FROM sessions WHERE id = ?')
67
+ .get(session_id);
68
+ let rawEvents;
69
+ try {
70
+ rawEvents = JSON.parse(transcript.content);
71
+ }
72
+ catch (e) {
73
+ // Deterministic — retrying will never fix a JSON parse failure.
74
+ throw new Error(`distill-events transcript content is not valid JSON: ${String(e)}`);
75
+ }
76
+ const eventsResult = StoredEventsSchema.safeParse(rawEvents);
77
+ if (!eventsResult.success) {
78
+ throw new Error(`distill-events transcript content does not match the events shape: ${eventsResult.error.message}`);
79
+ }
80
+ const events = eventsResult.data;
81
+ // Map pre-typed events straight to Atoms — the stage-1-5 skip (ADR-008):
82
+ // no cleanup/normalize/chunk/compact/extract, just the atom shape stages
83
+ // 6-8 already expect.
84
+ const atoms = events.map(ev => ({
85
+ type: ev.type,
86
+ text: ev.text,
87
+ importance: ev.importance ?? DEFAULT_IMPORTANCE,
88
+ confidence: ev.confidence ?? DEFAULT_CONFIDENCE,
89
+ evidence: ev.evidence,
90
+ }));
91
+ if (!isExtendedCtx(ctx)) {
92
+ // Fallback: no providers available (e.g. in unit tests without providers)
93
+ console.warn(`[distill-events] no providers in ctx — transcript ${transcript_id} logged but not distilled. ` +
94
+ 'Ensure ExtendedHandlerCtx is passed when providers are configured.');
95
+ return;
96
+ }
97
+ const pipeLog = childLogger({ session_id });
98
+ // Stage 6: Reduce (merge by content hash)
99
+ pipeLog.info({ stage: 'reduce', atoms_in: atoms.length }, 'stage start');
100
+ const reducedAtoms = reduce(atoms);
101
+ pipeLog.info({ stage: 'reduce', atoms_out: reducedAtoms.length }, 'stage complete');
102
+ // Stage 7: Memory-normalize
103
+ pipeLog.info({ stage: 'memory-normalize' }, 'stage start');
104
+ const normalizedMemories = memoryNormalize(reducedAtoms);
105
+ pipeLog.info({ stage: 'memory-normalize', memories: normalizedMemories.length }, 'stage complete');
106
+ // Stage 8: Embed + index — session/repo/branch/agent come from the
107
+ // session row; embedAndIndex appends a 'create' memory_event per new
108
+ // memory (2b), same as the transcript path.
109
+ const sourceHash = createHash('sha256').update(transcript.content, 'utf8').digest('hex');
110
+ pipeLog.info({ stage: 'embed-index', memories: normalizedMemories.length }, 'stage start');
111
+ const indexResults = await embedAndIndex(normalizedMemories, {
112
+ db: ctx.db,
113
+ embed: ctx.providers.embed,
114
+ sessionId: session_id,
115
+ repo: session?.repo ?? null,
116
+ project: session?.project ?? null,
117
+ branch: session?.branch ?? null,
118
+ agent: session?.agent ?? null,
119
+ sourceHash,
120
+ });
121
+ const created = indexResults.filter(r => r.created).length;
122
+ const deduped = indexResults.filter(r => !r.created).length;
123
+ pipeLog.info({ stage: 'embed-index', memories_created: created, memories_deduped: deduped }, 'stage complete');
124
+ console.log(`[distill-events] transcript=${transcript_id} events=${events.length} atoms=${atoms.length} ` +
125
+ `created=${created} deduped=${deduped}`);
126
+ // D-DEF2 parity: backfill ingest_idempotency.summary_memory_id from the
127
+ // transcript-id placeholder to the real created memory id, same as the
128
+ // transcript path.
129
+ if (indexResults.length > 0) {
130
+ backfillSummaryMemoryId(ctx.db, transcript_id, indexResults[0].memoryId);
131
+ }
132
+ },
133
+ };
134
+ //# sourceMappingURL=distill-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distill-events.js","sourceRoot":"","sources":["../../../src/pipeline/handlers/distill-events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Distill handler — Wave 3 implementation.
3
+ *
4
+ * Validates the payload, fetches transcript from DB,
5
+ * runs the 8-stage pipeline, and handles BudgetExceeded by
6
+ * moving the job to paused (not failed).
7
+ */
8
+ import type { JobHandler } from '../handler.js';
9
+ export declare const distillHandler: JobHandler;
10
+ /**
11
+ * Sentinel error thrown by the distill handler when the budget cap is hit.
12
+ * The worker loop must catch this and call JobRepo.pause() instead of fail().
13
+ */
14
+ export declare class DistillBudgetPausedError extends Error {
15
+ constructor(budgetMessage: string);
16
+ static is(err: unknown): err is DistillBudgetPausedError;
17
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Distill handler — Wave 3 implementation.
3
+ *
4
+ * Validates the payload, fetches transcript from DB,
5
+ * runs the 8-stage pipeline, and handles BudgetExceeded by
6
+ * moving the job to paused (not failed).
7
+ */
8
+ import { z } from 'zod';
9
+ import { isExtendedCtx } from '../handler-ctx-ext.js';
10
+ import { runPipeline, BudgetExceeded } from '../../distill/pipeline.js';
11
+ import { flattenTranscriptContent } from '../../distill/flatten-turns.js';
12
+ import { backfillSummaryMemoryId } from '../../storage/ingest-idempotency.js';
13
+ /**
14
+ * Flexible payload schema — ingest route writes {transcript_id, session_id}
15
+ * without the `kind` discriminator. Accept both forms.
16
+ */
17
+ const DistillPayloadFlexSchema = z.object({
18
+ transcript_id: z.string().min(1),
19
+ session_id: z.string().min(1),
20
+ // kind is optional here — ingest route may or may not include it
21
+ kind: z.string().optional(),
22
+ });
23
+ export const distillHandler = {
24
+ kind: 'distill',
25
+ async handle(payload, ctx) {
26
+ const parsed = DistillPayloadFlexSchema.safeParse(payload);
27
+ if (!parsed.success) {
28
+ throw new Error(`Invalid distill payload: ${parsed.error.message}`);
29
+ }
30
+ const { transcript_id, session_id } = parsed.data;
31
+ // Fetch transcript content
32
+ const transcript = ctx.db
33
+ .prepare('SELECT id, session_id, content, source FROM transcripts WHERE id = ?')
34
+ .get(transcript_id);
35
+ if (!transcript) {
36
+ throw new Error(`Transcript not found: ${transcript_id}`);
37
+ }
38
+ // Fetch session metadata for memory context
39
+ const session = ctx.db
40
+ .prepare('SELECT id, repo, project, branch, agent FROM sessions WHERE id = ?')
41
+ .get(session_id);
42
+ // D-DEF1: canonical transcripts store JSON.stringify(turns) in `content`
43
+ // (structured [{role, text, ts}]). Flatten to "role: text" lines — the
44
+ // format stages 1-3 (cleanup/normalize/chunk) actually parse — before it
45
+ // enters the pipeline. Legacy plain-text content passes through as-is.
46
+ const transcriptText = flattenTranscriptContent(transcript.content);
47
+ // Derive source hash for idempotency
48
+ const { createHash } = await import('node:crypto');
49
+ const sourceHash = createHash('sha256')
50
+ .update(transcript.content, 'utf8')
51
+ .digest('hex');
52
+ // Check if we have extended context with providers
53
+ if (!isExtendedCtx(ctx)) {
54
+ // Fallback: no providers available (e.g. in unit tests without providers)
55
+ // Log and complete — no memories will be created
56
+ console.warn(`[distill] no providers in ctx — transcript ${transcript_id} logged but not distilled. ` +
57
+ 'Ensure ExtendedHandlerCtx is passed when providers are configured.');
58
+ return;
59
+ }
60
+ const pipelineCtx = {
61
+ db: ctx.db,
62
+ llmCompaction: ctx.providers.llm.compaction,
63
+ llmExtraction: ctx.providers.llm.extraction,
64
+ embed: ctx.providers.embed,
65
+ capUsd: ctx.config.budget.daily_usd,
66
+ sessionId: session_id,
67
+ repo: session?.repo ?? null,
68
+ project: session?.project ?? null,
69
+ branch: session?.branch ?? null,
70
+ agent: session?.agent ?? null,
71
+ sourceHash,
72
+ };
73
+ try {
74
+ const result = await runPipeline(transcriptText, pipelineCtx);
75
+ console.log(`[distill] transcript=${transcript_id} chunks=${result.chunksProcessed} atoms=${result.atomsExtracted} ` +
76
+ `created=${result.memoriesCreated} deduped=${result.memoriesDeduped}`);
77
+ // D-DEF2: backfill ingest_idempotency.summary_memory_id (currently the
78
+ // transcript-id placeholder written at ingest time) with the real
79
+ // memory id this run produced, so idempotent replays return it.
80
+ if (result.memoryIds.length > 0) {
81
+ backfillSummaryMemoryId(ctx.db, transcript_id, result.memoryIds[0]);
82
+ }
83
+ }
84
+ catch (err) {
85
+ if (err instanceof BudgetExceeded) {
86
+ // Budget exceeded — move job to paused. The worker will not retry.
87
+ // We need access to the job id — the worker passes it via the job object.
88
+ // Since JobHandler.handle does not receive the job id directly,
89
+ // we throw a special marker error that the worker catches.
90
+ // Alternative: use a sentinel to signal paused state.
91
+ throw new DistillBudgetPausedError(err.message);
92
+ }
93
+ throw err;
94
+ }
95
+ },
96
+ };
97
+ /**
98
+ * Sentinel error thrown by the distill handler when the budget cap is hit.
99
+ * The worker loop must catch this and call JobRepo.pause() instead of fail().
100
+ */
101
+ export class DistillBudgetPausedError extends Error {
102
+ constructor(budgetMessage) {
103
+ super(`BUDGET_PAUSED:${budgetMessage}`);
104
+ this.name = 'DistillBudgetPausedError';
105
+ }
106
+ static is(err) {
107
+ return err instanceof DistillBudgetPausedError;
108
+ }
109
+ }
110
+ //# sourceMappingURL=distill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distill.js","sourceRoot":"","sources":["../../../src/pipeline/handlers/distill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { JobHandler } from '../handler.js';
2
+ /**
3
+ * Reembed handler — recompute + upsert the embedding for one memory
4
+ * (`rebuild` CLI enqueues one job per memory; model swaps re-index this way).
5
+ *
6
+ * A missing memory is a success, not a failure: the memory may have been
7
+ * erased (ADR-006) or superseded-and-cleaned between enqueue and execution,
8
+ * and retrying would never make it reappear.
9
+ */
10
+ export declare const reembedHandler: JobHandler;
@@ -0,0 +1,34 @@
1
+ import { ReembedPayloadSchema } from '../../contracts/index.js';
2
+ import { isExtendedCtx } from '../handler-ctx-ext.js';
3
+ /**
4
+ * Reembed handler — recompute + upsert the embedding for one memory
5
+ * (`rebuild` CLI enqueues one job per memory; model swaps re-index this way).
6
+ *
7
+ * A missing memory is a success, not a failure: the memory may have been
8
+ * erased (ADR-006) or superseded-and-cleaned between enqueue and execution,
9
+ * and retrying would never make it reappear.
10
+ */
11
+ export const reembedHandler = {
12
+ kind: 'reembed',
13
+ async handle(payload, ctx) {
14
+ const parsed = ReembedPayloadSchema.safeParse(payload);
15
+ if (!parsed.success) {
16
+ throw new Error(`Invalid reembed payload: ${parsed.error.message}`);
17
+ }
18
+ if (!isExtendedCtx(ctx)) {
19
+ throw new Error('reembed requires the extended handler context (providers + vecStore)');
20
+ }
21
+ const { memory_id } = parsed.data;
22
+ const memory = ctx.memoryRepo.get(memory_id);
23
+ if (!memory) {
24
+ console.log(`[reembed] memory ${memory_id} no longer exists — skipping`);
25
+ return;
26
+ }
27
+ const [vec] = await ctx.providers.embed.embed([memory.text]);
28
+ if (!vec)
29
+ throw new Error(`embed provider returned no vector for memory ${memory_id}`);
30
+ await ctx.vecStore.upsert(memory_id, vec);
31
+ ctx.db.prepare('UPDATE memories SET embedding_provider = ?, embedding_model = ?, embedding_dim = ?, updated_at = ? WHERE id = ?').run(ctx.providers.embed.name, ctx.providers.embed.model, ctx.providers.embed.dim, Date.now(), memory_id);
32
+ }
33
+ };
34
+ //# sourceMappingURL=reembed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reembed.js","sourceRoot":"","sources":["../../../src/pipeline/handlers/reembed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,IAAI,EAAE,SAAS;IAEf,KAAK,CAAC,MAAM,CAAC,OAAgB,EAAE,GAAe;QAC5C,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC1F,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;QAClC,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,oBAAoB,SAAS,8BAA8B,CAAC,CAAC;YACzE,OAAO;QACT,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,SAAS,EAAE,CAAC,CAAC;QACvF,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAE1C,GAAG,CAAC,EAAE,CAAC,OAAO,CACZ,iHAAiH,CAClH,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IAC7G,CAAC;CACF,CAAC"}
@@ -0,0 +1,86 @@
1
+ import type { DB } from '../storage/db.js';
2
+ import type { Job, JobKind } from '../contracts/index.js';
3
+ /**
4
+ * Data-access object for the jobs table.
5
+ * All methods are synchronous (better-sqlite3 is sync).
6
+ */
7
+ export declare class JobRepo {
8
+ private readonly db;
9
+ constructor(db: DB);
10
+ /** Insert a new job in pending state, return its generated id. */
11
+ enqueue(kind: JobKind, payload: unknown): string;
12
+ /**
13
+ * Atomically claim the oldest pending job: pending → running.
14
+ * Returns the updated Job row, or null if the queue is empty.
15
+ * Uses a CTE-based UPDATE so only one concurrent caller wins the row.
16
+ */
17
+ claimPending(): Job | null;
18
+ /** Transition a running job to completed. */
19
+ complete(id: string): void;
20
+ /**
21
+ * Record a handler failure: increment attempts and record the error.
22
+ * The new state is 'failed'. The worker checks attempts after this call
23
+ * and either re-enqueues (back to 'pending') or calls markPoison.
24
+ */
25
+ fail(id: string, error: string): void;
26
+ /**
27
+ * Move a failed job back to pending so the worker will retry it.
28
+ * Only call this when attempts < MAX_ATTEMPTS.
29
+ */
30
+ requeueForRetry(id: string): void;
31
+ /** Transition a job to the poison state (permanently failed). */
32
+ markPoison(id: string): void;
33
+ /** Transition a job to paused (e.g. budget exceeded). */
34
+ pause(id: string): void;
35
+ /**
36
+ * Record a non-failure note on the job (e.g. budget pause reason) without
37
+ * touching `attempts`. Use for state transitions that are not handler errors.
38
+ */
39
+ setLastError(id: string, note: string): void;
40
+ /** Read a single job by id. Returns null if not found. */
41
+ get(id: string): Job | null;
42
+ /**
43
+ * Boot-time crash recovery. Call once at daemon start, before the worker.
44
+ *
45
+ * - 'running' jobs are orphans: the previous process died mid-handle (on
46
+ * Windows, schtasks /end and Task Manager kills bypass the SIGTERM
47
+ * handler entirely). Requeue them.
48
+ * - 'failed' jobs with attempts < maxAttempts were waiting on an IN-MEMORY
49
+ * retry timer (worker.ts setTimeout) that died with the process — without
50
+ * this they are stranded in 'failed' forever. Requeue them too.
51
+ *
52
+ * `attempts` is preserved in both cases so poison thresholds still apply.
53
+ * Handlers must tolerate re-execution of partially-applied work (distill/
54
+ * reembed write via idempotent upserts; a rare duplicate memory from a
55
+ * mid-write crash is deduped downstream by consolidation).
56
+ */
57
+ recoverOrphans(maxAttempts?: number): {
58
+ requeuedRunning: number;
59
+ requeuedFailed: number;
60
+ };
61
+ /**
62
+ * Retention purge: completed jobs are transient bookkeeping (7d), poison
63
+ * jobs are kept longer (30d) for `queue` command forensics. Other states
64
+ * are never touched.
65
+ */
66
+ purgeOld(opts?: {
67
+ completedDays?: number;
68
+ poisonDays?: number;
69
+ }): {
70
+ completed: number;
71
+ poison: number;
72
+ };
73
+ /** List all jobs currently in the 'poison' state, oldest first (FEAT-405 manual purge). */
74
+ listPoison(): Job[];
75
+ /**
76
+ * Delete specific poison jobs by id (FEAT-405 `queue purge --poison`).
77
+ * Guarded to state = 'poison' so a job that transitions out of poison
78
+ * between the caller's read (for the forensics dump) and this delete is
79
+ * never silently swept up. Callers must capture ids via listPoison() first
80
+ * and write the forensics dump BEFORE calling this.
81
+ */
82
+ purgePoisonByIds(ids: string[]): number;
83
+ /** State → count map for /health queue reporting. */
84
+ stateCounts(): Record<string, number>;
85
+ private _transition;
86
+ }
@@ -0,0 +1,168 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ /**
3
+ * Data-access object for the jobs table.
4
+ * All methods are synchronous (better-sqlite3 is sync).
5
+ */
6
+ export class JobRepo {
7
+ db;
8
+ constructor(db) {
9
+ this.db = db;
10
+ }
11
+ /** Insert a new job in pending state, return its generated id. */
12
+ enqueue(kind, payload) {
13
+ const id = randomUUID();
14
+ const now = Date.now();
15
+ this.db.prepare(`
16
+ INSERT INTO jobs (id, kind, payload_json, state, attempts, last_error, created_at, updated_at)
17
+ VALUES (?, ?, ?, 'pending', 0, NULL, ?, ?)
18
+ `).run(id, kind, JSON.stringify(payload), now, now);
19
+ return id;
20
+ }
21
+ /**
22
+ * Atomically claim the oldest pending job: pending → running.
23
+ * Returns the updated Job row, or null if the queue is empty.
24
+ * Uses a CTE-based UPDATE so only one concurrent caller wins the row.
25
+ */
26
+ claimPending() {
27
+ // SQLite does not support UPDATE ... RETURNING with a subquery on some versions,
28
+ // so we use a transaction: SELECT the candidate, then UPDATE if still pending.
29
+ const claim = this.db.transaction(() => {
30
+ const candidate = this.db.prepare(`
31
+ SELECT * FROM jobs
32
+ WHERE state = 'pending'
33
+ ORDER BY created_at ASC
34
+ LIMIT 1
35
+ `).get();
36
+ if (!candidate)
37
+ return null;
38
+ const now = Date.now();
39
+ const changes = this.db.prepare(`
40
+ UPDATE jobs
41
+ SET state = 'running', updated_at = ?
42
+ WHERE id = ? AND state = 'pending'
43
+ `).run(now, candidate.id).changes;
44
+ if (changes === 0)
45
+ return null; // race: another worker grabbed it
46
+ return { ...candidate, state: 'running', updated_at: now };
47
+ });
48
+ return claim();
49
+ }
50
+ /** Transition a running job to completed. */
51
+ complete(id) {
52
+ this._transition(id, 'completed');
53
+ }
54
+ /**
55
+ * Record a handler failure: increment attempts and record the error.
56
+ * The new state is 'failed'. The worker checks attempts after this call
57
+ * and either re-enqueues (back to 'pending') or calls markPoison.
58
+ */
59
+ fail(id, error) {
60
+ const now = Date.now();
61
+ this.db.prepare(`
62
+ UPDATE jobs
63
+ SET state = 'failed', last_error = ?, attempts = attempts + 1, updated_at = ?
64
+ WHERE id = ?
65
+ `).run(error, now, id);
66
+ }
67
+ /**
68
+ * Move a failed job back to pending so the worker will retry it.
69
+ * Only call this when attempts < MAX_ATTEMPTS.
70
+ */
71
+ requeueForRetry(id) {
72
+ this._transition(id, 'pending');
73
+ }
74
+ /** Transition a job to the poison state (permanently failed). */
75
+ markPoison(id) {
76
+ this._transition(id, 'poison');
77
+ }
78
+ /** Transition a job to paused (e.g. budget exceeded). */
79
+ pause(id) {
80
+ this._transition(id, 'paused');
81
+ }
82
+ /**
83
+ * Record a non-failure note on the job (e.g. budget pause reason) without
84
+ * touching `attempts`. Use for state transitions that are not handler errors.
85
+ */
86
+ setLastError(id, note) {
87
+ const now = Date.now();
88
+ this.db.prepare('UPDATE jobs SET last_error = ?, updated_at = ? WHERE id = ?').run(note, now, id);
89
+ }
90
+ /** Read a single job by id. Returns null if not found. */
91
+ get(id) {
92
+ const row = this.db.prepare('SELECT * FROM jobs WHERE id = ?').get(id);
93
+ return row ?? null;
94
+ }
95
+ /**
96
+ * Boot-time crash recovery. Call once at daemon start, before the worker.
97
+ *
98
+ * - 'running' jobs are orphans: the previous process died mid-handle (on
99
+ * Windows, schtasks /end and Task Manager kills bypass the SIGTERM
100
+ * handler entirely). Requeue them.
101
+ * - 'failed' jobs with attempts < maxAttempts were waiting on an IN-MEMORY
102
+ * retry timer (worker.ts setTimeout) that died with the process — without
103
+ * this they are stranded in 'failed' forever. Requeue them too.
104
+ *
105
+ * `attempts` is preserved in both cases so poison thresholds still apply.
106
+ * Handlers must tolerate re-execution of partially-applied work (distill/
107
+ * reembed write via idempotent upserts; a rare duplicate memory from a
108
+ * mid-write crash is deduped downstream by consolidation).
109
+ */
110
+ recoverOrphans(maxAttempts = 3) {
111
+ const now = Date.now();
112
+ const requeuedRunning = this.db.prepare(`
113
+ UPDATE jobs SET state = 'pending', updated_at = ?
114
+ WHERE state = 'running'
115
+ `).run(now).changes;
116
+ const requeuedFailed = this.db.prepare(`
117
+ UPDATE jobs SET state = 'pending', updated_at = ?
118
+ WHERE state = 'failed' AND attempts < ?
119
+ `).run(now, maxAttempts).changes;
120
+ return { requeuedRunning, requeuedFailed };
121
+ }
122
+ /**
123
+ * Retention purge: completed jobs are transient bookkeeping (7d), poison
124
+ * jobs are kept longer (30d) for `queue` command forensics. Other states
125
+ * are never touched.
126
+ */
127
+ purgeOld(opts = {}) {
128
+ const now = Date.now();
129
+ const dayMs = 24 * 60 * 60 * 1000;
130
+ const completedCutoff = now - (opts.completedDays ?? 7) * dayMs;
131
+ const poisonCutoff = now - (opts.poisonDays ?? 30) * dayMs;
132
+ const completed = this.db.prepare(`DELETE FROM jobs WHERE state = 'completed' AND updated_at < ?`).run(completedCutoff).changes;
133
+ const poison = this.db.prepare(`DELETE FROM jobs WHERE state = 'poison' AND updated_at < ?`).run(poisonCutoff).changes;
134
+ return { completed, poison };
135
+ }
136
+ /** List all jobs currently in the 'poison' state, oldest first (FEAT-405 manual purge). */
137
+ listPoison() {
138
+ return this.db.prepare(`
139
+ SELECT * FROM jobs WHERE state = 'poison' ORDER BY updated_at ASC
140
+ `).all();
141
+ }
142
+ /**
143
+ * Delete specific poison jobs by id (FEAT-405 `queue purge --poison`).
144
+ * Guarded to state = 'poison' so a job that transitions out of poison
145
+ * between the caller's read (for the forensics dump) and this delete is
146
+ * never silently swept up. Callers must capture ids via listPoison() first
147
+ * and write the forensics dump BEFORE calling this.
148
+ */
149
+ purgePoisonByIds(ids) {
150
+ if (ids.length === 0)
151
+ return 0;
152
+ const placeholders = ids.map(() => '?').join(',');
153
+ return this.db.prepare(`DELETE FROM jobs WHERE state = 'poison' AND id IN (${placeholders})`).run(...ids).changes;
154
+ }
155
+ /** State → count map for /health queue reporting. */
156
+ stateCounts() {
157
+ const rows = this.db.prepare(`SELECT state, COUNT(*) AS n FROM jobs GROUP BY state`).all();
158
+ const out = {};
159
+ for (const r of rows)
160
+ out[r.state] = r.n;
161
+ return out;
162
+ }
163
+ _transition(id, state) {
164
+ const now = Date.now();
165
+ this.db.prepare('UPDATE jobs SET state = ?, updated_at = ? WHERE id = ?').run(state, now, id);
166
+ }
167
+ }
168
+ //# sourceMappingURL=job-repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-repo.js","sourceRoot":"","sources":["../../src/pipeline/job-repo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Mock providers for CI / integration testing.
3
+ *
4
+ * Used when ASTRA_MEMORY_MOCK_PROVIDERS=1 is set (or injected directly in tests).
5
+ *
6
+ * - MockLLMProvider: compaction returns the input text unchanged;
7
+ * extraction checks a small deterministic keyword table (see below) and
8
+ * returns one atom per matched keyword, or an empty atoms list if none match.
9
+ * - MockEmbedProvider: deterministic vector (dim defaults to
10
+ * DEFAULT_EMBED_DIM = 1024, configurable) seeded from text hash. No
11
+ * network, no Ollama required.
12
+ *
13
+ * These mocks satisfy the LLMProvider / EmbedProvider contracts and make
14
+ * the full 8-stage distillation pipeline runnable in CI.
15
+ *
16
+ * TEST-ONLY deterministic extraction vocabulary (SLICE-SMOKE-1 orchestrator
17
+ * decision, 2026-07-04: extending this file additively was approved as a
18
+ * relaxation of "no product-code changes" for test-double code specifically
19
+ * — see the smoke-suite run brief. Exclusively consumed by
20
+ * tests/smoke/_fixtures/session-canonical.json; fixture and this table must
21
+ * stay in lockstep, and this file is never reachable outside
22
+ * ASTRA_MEMORY_MOCK_PROVIDERS=1 (CI/test only — real serving never sets it).
23
+ * Each row is an independent case-insensitive substring match against the
24
+ * full extraction input; matching keywords each append one fixed atom (no
25
+ * parsing, no branching beyond the match itself):
26
+ *
27
+ * trigger keyword -> atom type -> entity emitted
28
+ * ---------------------------------------------------------------------
29
+ * "sqlite-vec" / "sqlite_vec" -> decision -> none (ORIGINAL, unchanged
30
+ * byte-for-byte since before
31
+ * SLICE-SMOKE-1)
32
+ * "priya nair" -> fact -> person: "Priya Nair"
33
+ * "astramemory-local" -> fact -> repo: "astramemory-local"
34
+ * "typescript" -> fact -> tech: "TypeScript"
35
+ * "todo:" -> todo -> none
36
+ * "prefers markdown summaries" -> note -> none (closest valid
37
+ * MemoryType — the schema
38
+ * has no 'preference' type)
39
+ */
40
+ import type { ProviderSet } from '../providers/index.js';
41
+ export type MockProviderSet = ProviderSet;
42
+ /**
43
+ * Returns a ProviderSet backed entirely by mock providers.
44
+ * Safe to call multiple times — each call returns fresh instances.
45
+ * `dim` defaults to DEFAULT_EMBED_DIM (1024); pass e.g. cfg.embedding.dim
46
+ * to exercise a non-default dim under ASTRA_MEMORY_MOCK_PROVIDERS=1
47
+ * (FEAT-409 AC-2).
48
+ */
49
+ export declare function makeMockProviders(dim?: number): MockProviderSet;