@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,199 @@
1
+ /**
2
+ * `astramem-local reembed-dim --dim <N> [--yes] [--batch-size N] [--json]`
3
+ *
4
+ * FEAT-409 AC-4 — resumable procedure for changing the embedding dimension
5
+ * on an EXISTING database with live data. See docs/embed-dim-migration.md
6
+ * for the full runbook (backup-first, stop-daemon, run, restart sequence).
7
+ *
8
+ * WHY this can't be a plain schema migration: sqlite-vec's `memories_vec`
9
+ * vec0 virtual table bakes its dim into `CREATE VIRTUAL TABLE ... FLOAT[N]`
10
+ * DDL — there is no ALTER for it. Changing dim therefore means:
11
+ * 1. Recreating `memories_vec` at the new dim (DESTRUCTIVE — drops every
12
+ * existing vector). This is why a pre-change backup is the rollback
13
+ * (AC-4): there is no in-place undo once this step runs.
14
+ * 2. Re-embedding every memory's text with the newly-configured provider
15
+ * and upserting into the recreated table.
16
+ *
17
+ * RESUMABILITY: migration 011 added `dim_migration_progress`, a checkpoint
18
+ * table keyed by (memory_id, target_dim). Step 2 commits a checkpoint row
19
+ * right after each memory's vec upsert, so an interrupted run (Ctrl+C,
20
+ * crash, a transient Ollama/Azure failure) resumes on the next invocation
21
+ * by skipping memory ids already checkpointed for this target dim — no
22
+ * re-work, no memory permanently stuck without a vector. Step 1 (the
23
+ * destructive recreate) only runs once per target dim: it is skipped
24
+ * whenever a checkpoint row for that target dim already exists, which is
25
+ * exactly the signal that step 1 already ran for this target.
26
+ *
27
+ * `runReembedDim` is the testable core (no process.exit, no config.yaml
28
+ * I/O, injectable embed provider). `reembedDimCommand` is the CLI wrapper:
29
+ * arg parsing, confirmation prompt, config.yaml persistence, exit codes.
30
+ */
31
+ import { join } from 'node:path';
32
+ import { resolveRuntimeConfig } from '../config/resolve-runtime.js';
33
+ import { defaultConfigDir } from '../config/datadir.js';
34
+ import { writeConfig } from '../config/writer.js';
35
+ import { getOrCreateKey } from '../storage/keystore.js';
36
+ import { openDb } from '../storage/db.js';
37
+ import { getProviders } from '../providers/index.js';
38
+ import { makeMockProviders } from '../pipeline/mock-providers.js';
39
+ import { SqliteVecStore } from '../vector/sqlite-vec.js';
40
+ function parseArg(args, flag) {
41
+ const i = args.indexOf(flag);
42
+ return i >= 0 ? args[i + 1] : undefined;
43
+ }
44
+ /** Recreate memories_vec at the new dim — destructive, resumability guard
45
+ * is: only do this when NO checkpoint rows exist yet for target_dim (i.e.
46
+ * this is the first invocation for this target, not a resume). */
47
+ function maybeRecreateVecSchema(db, targetDim) {
48
+ const existing = db
49
+ .prepare('SELECT COUNT(*) AS n FROM dim_migration_progress WHERE target_dim = ?')
50
+ .get(targetDim);
51
+ if (existing.n > 0)
52
+ return false; // resume — schema already recreated
53
+ db.exec('DROP TABLE IF EXISTS memories_vec');
54
+ db.exec(`CREATE VIRTUAL TABLE memories_vec USING vec0(embedding FLOAT[${targetDim}])`);
55
+ return true;
56
+ }
57
+ /**
58
+ * Testable core: no process.exit, no config.yaml writes, no provider
59
+ * resolution — the caller supplies `embed` (already verified to produce
60
+ * `targetDim`-shaped vectors). Safe to call repeatedly against the same DB
61
+ * for the same targetDim (resumable — see module doc).
62
+ */
63
+ export async function runReembedDim(db, targetDim, embed, batchSize = 20) {
64
+ // Same guard migrate() applies (src/storage/migrate.ts) — this is the
65
+ // exported core function, callable directly by anything that imports it
66
+ // (not just the CLI wrapper below, which already validates --dim), so it
67
+ // must be self-guarding rather than trusting the caller to have checked.
68
+ // Fails fast, before maybeRecreateVecSchema ever interpolates targetDim
69
+ // into DROP/CREATE VIRTUAL TABLE DDL.
70
+ if (!Number.isInteger(targetDim) || targetDim <= 0) {
71
+ throw new Error(`invalid embedding dim: ${targetDim} (must be a positive integer)`);
72
+ }
73
+ const schemaRecreated = maybeRecreateVecSchema(db, targetDim);
74
+ const vecStore = new SqliteVecStore(db, targetDim);
75
+ const candidates = db
76
+ .prepare(`
77
+ SELECT id, text FROM memories
78
+ WHERE id NOT IN (SELECT memory_id FROM dim_migration_progress WHERE target_dim = ?)
79
+ ORDER BY created_at ASC
80
+ `)
81
+ .all(targetDim);
82
+ const alreadyDoneBefore = db.prepare('SELECT COUNT(*) AS n FROM dim_migration_progress WHERE target_dim = ?').get(targetDim).n;
83
+ const failed = [];
84
+ let reembedded = 0;
85
+ for (let i = 0; i < candidates.length; i += batchSize) {
86
+ const batch = candidates.slice(i, i + batchSize);
87
+ for (const mem of batch) {
88
+ try {
89
+ const [vec] = await embed.embed([mem.text]);
90
+ if (!vec)
91
+ throw new Error('embed provider returned no vector');
92
+ if (vec.length !== targetDim) {
93
+ throw new Error(`provider returned dim=${vec.length}, expected ${targetDim}`);
94
+ }
95
+ // upsert(), the memories row update, then the checkpoint INSERT —
96
+ // each is individually atomic (single-statement better-sqlite3
97
+ // writes). If the process dies between them, resume just re-embeds
98
+ // this one memory again on the next run: embed+upsert+update is
99
+ // idempotent, so at-least-once is safe.
100
+ await vecStore.upsert(mem.id, vec);
101
+ // Mirror pipeline/handlers/reembed.ts: memories.embedding_* must
102
+ // track what's actually in memories_vec, or API/MCP callers get a
103
+ // silent lie about which provider/model/dim produced the vector.
104
+ db.prepare('UPDATE memories SET embedding_provider = ?, embedding_model = ?, embedding_dim = ?, updated_at = ? WHERE id = ?').run(embed.name, embed.model, targetDim, Date.now(), mem.id);
105
+ db.prepare('INSERT INTO dim_migration_progress (memory_id, target_dim, completed_at) VALUES (?, ?, ?)').run(mem.id, targetDim, Date.now());
106
+ reembedded++;
107
+ }
108
+ catch (err) {
109
+ failed.push({ memoryId: mem.id, error: err instanceof Error ? err.message : String(err) });
110
+ }
111
+ }
112
+ }
113
+ return {
114
+ targetDim,
115
+ totalCandidates: candidates.length,
116
+ alreadyDone: alreadyDoneBefore,
117
+ reembedded,
118
+ failed,
119
+ schemaRecreated,
120
+ };
121
+ }
122
+ export async function reembedDimCommand(args) {
123
+ const jsonMode = args.includes('--json');
124
+ const yes = args.includes('--yes');
125
+ const dimArg = parseArg(args, '--dim');
126
+ const batchArg = parseArg(args, '--batch-size');
127
+ const batchSize = batchArg ? Math.max(1, Number(batchArg)) : 20;
128
+ const targetDim = dimArg !== undefined ? Number(dimArg) : NaN;
129
+ if (!Number.isInteger(targetDim) || targetDim <= 0) {
130
+ console.error('reembed-dim: --dim <positive integer> is required');
131
+ process.exit(1);
132
+ }
133
+ const { cfg, dataDir } = resolveRuntimeConfig();
134
+ const dbPath = dataDir === ':memory:' ? ':memory:' : join(dataDir, 'memory.sqlite');
135
+ if (!yes && !jsonMode) {
136
+ console.log('');
137
+ console.log(' AstraMemory Reembed-Dim');
138
+ console.log(' ──────────────────────────────');
139
+ console.log(` Target dim : ${targetDim} (current config: ${cfg.embedding.dim})`);
140
+ console.log(` Data dir : ${dataDir}`);
141
+ console.log(' This DROPS and recreates memories_vec — all existing vectors are');
142
+ console.log(' discarded, then every memory is re-embedded with the configured provider.');
143
+ console.log(' A pre-change backup (`astramem-local backup`) is your rollback — there is');
144
+ console.log(' no undo once the schema recreate step runs.');
145
+ console.log(' Re-run with --yes to proceed (safe to Ctrl+C and resume — see docs/embed-dim-migration.md).');
146
+ console.log('');
147
+ process.exit(1);
148
+ }
149
+ const key = cfg.security.encryption.enabled ? getOrCreateKey(defaultConfigDir()).key : undefined;
150
+ const db = openDb(dbPath, key ? { key } : {});
151
+ // New config with the target dim — used both to persist config.yaml AND
152
+ // to build the embed provider that will actually produce target-dim
153
+ // vectors below (provider.dim flows from config.embedding.dim, FEAT-409).
154
+ const newCfg = { ...cfg, embedding: { ...cfg.embedding, dim: targetDim } };
155
+ const useMock = process.env.ASTRA_MEMORY_MOCK_PROVIDERS === '1';
156
+ const embed = useMock ? makeMockProviders(targetDim).embed : getProviders(newCfg).embed;
157
+ if (embed.dim !== targetDim) {
158
+ console.error(`reembed-dim: configured provider (${embed.name}/${embed.model}) produces dim=${embed.dim}, ` +
159
+ `not the requested --dim ${targetDim}. Update config.embedding.model to a model that ` +
160
+ `natively produces ${targetDim} dims (or one that supports it via a dimensions param) before retrying.`);
161
+ db.close();
162
+ process.exit(1);
163
+ }
164
+ const result = await runReembedDim(db, targetDim, embed, batchSize);
165
+ // Persist the new dim (+ provider/model already matched above) so the
166
+ // next daemon boot's preflight (AC-3) sees a config that matches the
167
+ // schema we just recreated. Skipped for :memory: (no real config to
168
+ // update — dev/test throwaway state, same guard the sync shipper uses).
169
+ let configPath;
170
+ if (dataDir !== ':memory:') {
171
+ configPath = join(defaultConfigDir(), 'config.yaml');
172
+ writeConfig(newCfg, configPath);
173
+ }
174
+ db.close();
175
+ if (jsonMode) {
176
+ console.log(JSON.stringify(result, null, 2));
177
+ }
178
+ else {
179
+ console.log('');
180
+ console.log(' AstraMemory Reembed-Dim — complete');
181
+ console.log(' ──────────────────────────────');
182
+ console.log(` Target dim : ${targetDim}`);
183
+ console.log(` Schema recreated : ${result.schemaRecreated ? 'yes (fresh run)' : 'no (resumed run)'}`);
184
+ console.log(` Already done : ${result.alreadyDone}`);
185
+ console.log(` Reembedded now : ${result.reembedded}`);
186
+ console.log(` Failed : ${result.failed.length}`);
187
+ if (result.failed.length > 0) {
188
+ console.log(' Re-run this command to retry failed memories (resumable).');
189
+ }
190
+ if (configPath) {
191
+ console.log(` config.yaml updated: embedding.dim=${targetDim} at ${configPath}`);
192
+ console.log(' Restart the daemon (`astramem-local reinstall` or `service restart`) to pick this up.');
193
+ }
194
+ console.log('');
195
+ }
196
+ if (result.failed.length > 0)
197
+ process.exit(1);
198
+ }
199
+ //# sourceMappingURL=reembed-dim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reembed-dim.js","sourceRoot":"","sources":["../../src/cli/reembed-dim.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function reinstallCommand(args: string[]): Promise<void>;
@@ -0,0 +1,205 @@
1
+ /**
2
+ * reinstall.ts — `astramem-local reinstall` (D4).
3
+ *
4
+ * The one command that always works: fully non-interactive, idempotent, every
5
+ * failure surfaced verbatim. Run it after every upgrade (git pull + build) or
6
+ * whenever the service is in a weird state.
7
+ *
8
+ * Sequence:
9
+ * 1. resolve current build (refuse if dist/ missing)
10
+ * 2. resolve runtime config + print provenance of each value
11
+ * 3. stop any running daemon (via daemon.lock PID)
12
+ * 4. write shim + register scheduler task (single shared install path)
13
+ * 5. start the service
14
+ * 6. wait for /health, assert served version === this build's version
15
+ * (catches a stale global install shadowing the repo build)
16
+ * 7. config sanity warnings (legacy dirs, plaintext backups, dataDir drift)
17
+ *
18
+ * Exit codes: 0 = healthy end-state; 1 = any step failed.
19
+ */
20
+ import { existsSync } from 'node:fs';
21
+ import { join } from 'node:path';
22
+ import { resolveRuntimeConfig } from '../config/resolve-runtime.js';
23
+ import { legacyDataDir, legacyConfigDir } from '../config/datadir.js';
24
+ import { installServiceFlow } from '../service/install-flow.js';
25
+ import { readLockInfo } from '../service/instance-lock.js';
26
+ import { waitForHealth } from './wait-health.js';
27
+ import { PKG_VERSION } from '../server/lib/wire-meta.js';
28
+ function hasFlag(args, flag) {
29
+ return args.includes(flag);
30
+ }
31
+ async function stopRunningDaemon(dataDir, port) {
32
+ const holder = readLockInfo(dataDir);
33
+ if (!holder)
34
+ return { step: 'stop-daemon', ok: true, detail: 'no daemon.lock — nothing to stop' };
35
+ let alive = true;
36
+ try {
37
+ process.kill(holder.pid, 0);
38
+ }
39
+ catch {
40
+ alive = false;
41
+ }
42
+ if (!alive)
43
+ return { step: 'stop-daemon', ok: true, detail: `stale lock (pid ${holder.pid} dead)` };
44
+ try {
45
+ // SIGTERM runs the daemon's graceful shutdown; on Windows Node this
46
+ // terminates the process (no handler runs), which is still acceptable —
47
+ // boot job-recovery handles interrupted work.
48
+ process.kill(holder.pid, 'SIGTERM');
49
+ }
50
+ catch (err) {
51
+ return { step: 'stop-daemon', ok: false, detail: `kill pid ${holder.pid} failed: ${err.message}` };
52
+ }
53
+ // Wait up to 5s for the port to go quiet.
54
+ const deadline = Date.now() + 5000;
55
+ while (Date.now() < deadline) {
56
+ try {
57
+ await fetch(`http://127.0.0.1:${holder.port ?? port}/health`, { signal: AbortSignal.timeout(500) });
58
+ await new Promise(r => setTimeout(r, 250));
59
+ }
60
+ catch {
61
+ return { step: 'stop-daemon', ok: true, detail: `stopped pid ${holder.pid}` };
62
+ }
63
+ }
64
+ return { step: 'stop-daemon', ok: false, detail: `pid ${holder.pid} still serving after 5s` };
65
+ }
66
+ export async function reinstallCommand(args) {
67
+ const jsonMode = hasFlag(args, '--json');
68
+ const steps = [];
69
+ const log = (s) => { if (!jsonMode)
70
+ console.log(s); };
71
+ log(`\nAstraMemory reinstall — v${PKG_VERSION}\n`);
72
+ // 1+2. Resolve config with provenance.
73
+ const { port, dataDir, configDir, sources } = resolveRuntimeConfig();
74
+ log(` config dir : ${configDir}`);
75
+ log(` data dir : ${dataDir} (from ${sources.dataDir})`);
76
+ log(` port : ${port} (from ${sources.port})`);
77
+ steps.push({ step: 'resolve-config', ok: true, detail: `dataDir=${dataDir} port=${port}` });
78
+ // 3. Stop any running daemon.
79
+ const stopResult = await stopRunningDaemon(dataDir, port);
80
+ steps.push(stopResult);
81
+ log(` · stop daemon: ${stopResult.detail}`);
82
+ if (!stopResult.ok) {
83
+ finish(steps, jsonMode);
84
+ return;
85
+ }
86
+ // 4. Install (shared flow: shim + scheduler registration).
87
+ let startFn = null;
88
+ try {
89
+ const { result, adapter, build } = await installServiceFlow(port);
90
+ if (result.kind === 'task') {
91
+ steps.push({ step: 'install-service', ok: true, detail: 'registered (task)' });
92
+ log(' · service registered (task)');
93
+ startFn = () => adapter.start();
94
+ // W2.4: nightly verified backup by default — a memory daemon without
95
+ // backups is one disk hiccup away from losing everything.
96
+ if (!hasFlag(args, '--no-backup-timer')) {
97
+ try {
98
+ await adapter.installBackupTimer(build.rawExecPath, 7);
99
+ steps.push({ step: 'install-backup-timer', ok: true, detail: 'nightly 03:00, keep 7, verified' });
100
+ log(' · backup timer registered (nightly 03:00, keep 7)');
101
+ }
102
+ catch (err) {
103
+ // Soft-fail: daemon service matters more than the timer.
104
+ steps.push({ step: 'install-backup-timer', ok: false, detail: err.message });
105
+ log(` ⚠ backup timer failed: ${err.message}`);
106
+ }
107
+ }
108
+ }
109
+ else {
110
+ // Startup-shortcut fallback: works at next logon but no start/stop
111
+ // control. Count it as a soft failure so the exit code says "not fully
112
+ // healthy" — the verbatim tier errors were already printed by install.
113
+ steps.push({
114
+ step: 'install-service',
115
+ ok: false,
116
+ detail: `fell back to Startup shortcut (${result.path}) — 'service start/stop' unavailable; fix the schtasks errors above`,
117
+ });
118
+ }
119
+ }
120
+ catch (err) {
121
+ steps.push({ step: 'install-service', ok: false, detail: err.message });
122
+ log(` ✗ install failed: ${err.message}`);
123
+ finish(steps, jsonMode);
124
+ return;
125
+ }
126
+ // 5. Start.
127
+ if (startFn) {
128
+ try {
129
+ await startFn();
130
+ steps.push({ step: 'start-service', ok: true });
131
+ log(' · service started');
132
+ }
133
+ catch (err) {
134
+ steps.push({ step: 'start-service', ok: false, detail: err.message });
135
+ log(` ✗ start failed: ${err.message}`);
136
+ }
137
+ }
138
+ // 6. Health + version assertion.
139
+ const healthy = await waitForHealth(port, 30_000);
140
+ if (!healthy) {
141
+ steps.push({ step: 'verify-health', ok: false, detail: `/health not responding on port ${port} within 30s` });
142
+ }
143
+ else {
144
+ try {
145
+ const res = await fetch(`http://127.0.0.1:${port}/version`, { signal: AbortSignal.timeout(3000) });
146
+ const body = (await res.json());
147
+ if (body.version === PKG_VERSION) {
148
+ steps.push({ step: 'verify-version', ok: true, detail: `daemon serving v${body.version}` });
149
+ log(` ✓ daemon healthy, serving v${body.version}`);
150
+ }
151
+ else {
152
+ steps.push({
153
+ step: 'verify-version',
154
+ ok: false,
155
+ detail: `daemon reports v${body.version} but this build is v${PKG_VERSION} — a DIFFERENT install is serving. ` +
156
+ `Most common cause: a stale global install (e.g. 'bun install -g' shadowing the repo build). ` +
157
+ `Stop the other daemon and re-run reinstall from the build you want.`,
158
+ });
159
+ }
160
+ }
161
+ catch (err) {
162
+ steps.push({ step: 'verify-version', ok: false, detail: err.message });
163
+ }
164
+ }
165
+ // 7. Sanity warnings (never fail the run — informational).
166
+ const warnings = [];
167
+ const legacyData = legacyDataDir();
168
+ if (legacyData !== dataDir && existsSync(join(legacyData, 'memory.sqlite'))) {
169
+ warnings.push(`legacy data dir still holds a database: ${legacyData} — verify it is not the one with your real data`);
170
+ }
171
+ const legacyCfg = legacyConfigDir();
172
+ if (legacyCfg !== configDir && existsSync(legacyCfg)) {
173
+ warnings.push(`legacy config dir still present: ${legacyCfg}`);
174
+ }
175
+ if (existsSync(join(dataDir, 'memory.sqlite.pre-encryption.bak'))) {
176
+ warnings.push(`plaintext pre-encryption backup present: ${join(dataDir, 'memory.sqlite.pre-encryption.bak')} — delete once the encrypted DB is verified`);
177
+ }
178
+ if (sources.dataDir === 'config.yaml') {
179
+ warnings.push(`dataDir comes from config.yaml and differs from the platform default — intentional? (${dataDir})`);
180
+ }
181
+ for (const w of warnings)
182
+ log(` ⚠ ${w}`);
183
+ finish(steps, jsonMode, warnings);
184
+ }
185
+ function finish(steps, jsonMode, warnings = []) {
186
+ const failed = steps.filter(s => !s.ok);
187
+ if (jsonMode) {
188
+ console.log(JSON.stringify({ ok: failed.length === 0, version: PKG_VERSION, steps, warnings }, null, 2));
189
+ }
190
+ else {
191
+ console.log('');
192
+ if (failed.length === 0) {
193
+ console.log('✓ reinstall complete — service registered, daemon healthy.');
194
+ }
195
+ else {
196
+ console.log(`✗ reinstall finished with ${failed.length} failed step(s):`);
197
+ for (const f of failed)
198
+ console.log(` ${f.step}: ${f.detail ?? 'failed'}`);
199
+ }
200
+ console.log('');
201
+ }
202
+ if (failed.length > 0)
203
+ process.exit(1);
204
+ }
205
+ //# sourceMappingURL=reinstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reinstall.js","sourceRoot":"","sources":["../../src/cli/reinstall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function restoreCommand(args: string[]): Promise<void>;
@@ -0,0 +1,167 @@
1
+ /**
2
+ * restore.ts — `astramem-local restore <snapshot>` (W2.2).
3
+ *
4
+ * Until now restore was an undocumented manual file copy. This command makes
5
+ * it safe:
6
+ * 1. verify the snapshot BEFORE touching anything (integrity_check + key)
7
+ * 2. stop a running daemon (via daemon.lock, same as reinstall)
8
+ * 3. set the current DB aside as memory.sqlite.pre-restore.bak (never lost)
9
+ * 4. swap the snapshot in via copy-to-tmp + atomic rename
10
+ * 5. run schema migrations (an old snapshot may predate current schema)
11
+ * 6. restart the service if one is registered, verify /health
12
+ *
13
+ * Exit codes: 0 = restored + healthy (or restored, daemon left stopped);
14
+ * 1 = any failure — the original DB is never deleted.
15
+ */
16
+ import { existsSync, copyFileSync, renameSync, rmSync } from 'node:fs';
17
+ import { join } from 'node:path';
18
+ import Database from 'better-sqlite3-multiple-ciphers';
19
+ import { resolveRuntimeConfig } from '../config/resolve-runtime.js';
20
+ import { defaultConfigDir } from '../config/datadir.js';
21
+ import { getOrCreateKey } from '../storage/keystore.js';
22
+ import { readLockInfo } from '../service/instance-lock.js';
23
+ import { getServiceAdapter } from '../service/index.js';
24
+ import { openDb } from '../storage/db.js';
25
+ import { migrate } from '../storage/migrate.js';
26
+ import { waitForHealth } from './wait-health.js';
27
+ function hasFlag(args, flag) {
28
+ return args.includes(flag);
29
+ }
30
+ async function stopDaemon(dataDir, port) {
31
+ const holder = readLockInfo(dataDir);
32
+ if (!holder)
33
+ return 'no daemon running';
34
+ let alive = true;
35
+ try {
36
+ process.kill(holder.pid, 0);
37
+ }
38
+ catch {
39
+ alive = false;
40
+ }
41
+ if (!alive)
42
+ return `stale lock (pid ${holder.pid} dead)`;
43
+ process.kill(holder.pid, 'SIGTERM');
44
+ const deadline = Date.now() + 5000;
45
+ while (Date.now() < deadline) {
46
+ try {
47
+ await fetch(`http://127.0.0.1:${holder.port ?? port}/health`, { signal: AbortSignal.timeout(500) });
48
+ await new Promise(r => setTimeout(r, 250));
49
+ }
50
+ catch {
51
+ return `stopped pid ${holder.pid}`;
52
+ }
53
+ }
54
+ throw new Error(`daemon pid ${holder.pid} still serving after 5s — stop it manually and retry`);
55
+ }
56
+ /** Standalone integrity probe of a snapshot file (key-aware). */
57
+ function probeSnapshot(path, key) {
58
+ let db = null;
59
+ try {
60
+ db = new Database(path, { readonly: true });
61
+ if (key)
62
+ db.pragma(`key='${key.replace(/'/g, "''")}'`);
63
+ const rows = db.pragma('integrity_check');
64
+ const verdict = rows.map(r => r.integrity_check).join('; ');
65
+ return verdict === 'ok' ? { ok: true } : { ok: false, error: `integrity_check: ${verdict}` };
66
+ }
67
+ catch (err) {
68
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
69
+ }
70
+ finally {
71
+ try {
72
+ db?.close();
73
+ }
74
+ catch { /* ignore */ }
75
+ }
76
+ }
77
+ export async function restoreCommand(args) {
78
+ const snapshotPath = args.find(a => !a.startsWith('-'));
79
+ const noRestart = hasFlag(args, '--no-restart');
80
+ if (!snapshotPath) {
81
+ console.error('restore: snapshot path required\nUsage: astramem-local restore <snapshot.sqlite> [--no-restart]');
82
+ process.exit(1);
83
+ }
84
+ if (!existsSync(snapshotPath)) {
85
+ console.error(`restore: snapshot not found: ${snapshotPath}`);
86
+ process.exit(1);
87
+ }
88
+ const { cfg, port, dataDir } = resolveRuntimeConfig();
89
+ if (dataDir === ':memory:') {
90
+ console.error('restore: refusing to restore into :memory:');
91
+ process.exit(1);
92
+ }
93
+ const dbPath = join(dataDir, 'memory.sqlite');
94
+ const key = cfg.security.encryption.enabled ? getOrCreateKey(defaultConfigDir()).key : undefined;
95
+ console.log(`\nAstraMemory restore\n snapshot: ${snapshotPath}\n target : ${dbPath}\n`);
96
+ // 1. Verify the snapshot before touching anything.
97
+ const probe = probeSnapshot(snapshotPath, key);
98
+ if (!probe.ok) {
99
+ console.error(`✗ snapshot failed verification: ${probe.error}`);
100
+ console.error(' Nothing was changed.');
101
+ process.exit(1);
102
+ }
103
+ console.log(' · snapshot integrity: ok');
104
+ // 2. Stop the daemon.
105
+ try {
106
+ console.log(` · stop daemon: ${await stopDaemon(dataDir, port)}`);
107
+ }
108
+ catch (err) {
109
+ console.error(`✗ ${err.message}`);
110
+ process.exit(1);
111
+ }
112
+ // 3+4. Set current DB aside, swap snapshot in atomically.
113
+ const asidePath = `${dbPath}.pre-restore.bak`;
114
+ const tmpPath = `${dbPath}.restoring-tmp`;
115
+ try {
116
+ copyFileSync(snapshotPath, tmpPath);
117
+ if (existsSync(dbPath)) {
118
+ rmSync(asidePath, { force: true });
119
+ renameSync(dbPath, asidePath);
120
+ console.log(` · current DB set aside: ${asidePath}`);
121
+ // Stale WAL/SHM belong to the old DB — remove so SQLite doesn't pair
122
+ // them with the restored file (mismatched WAL corrupts).
123
+ rmSync(`${dbPath}-wal`, { force: true });
124
+ rmSync(`${dbPath}-shm`, { force: true });
125
+ }
126
+ renameSync(tmpPath, dbPath);
127
+ console.log(' · snapshot swapped in');
128
+ }
129
+ catch (err) {
130
+ rmSync(tmpPath, { force: true });
131
+ console.error(`✗ swap failed: ${err.message}`);
132
+ console.error(` Original DB ${existsSync(asidePath) ? `is at ${asidePath} — rename it back` : 'was not moved'}.`);
133
+ process.exit(1);
134
+ }
135
+ // 5. Migrations — an older snapshot may predate the current schema.
136
+ try {
137
+ const db = openDb(dbPath, key ? { key } : {});
138
+ migrate(db, cfg.embedding.dim);
139
+ db.close();
140
+ console.log(' · schema migrations applied');
141
+ }
142
+ catch (err) {
143
+ console.error(`✗ migration on restored DB failed: ${err.message}`);
144
+ console.error(` Roll back: delete ${dbPath} and rename ${asidePath} back.`);
145
+ process.exit(1);
146
+ }
147
+ // 6. Restart service when one is registered.
148
+ if (!noRestart) {
149
+ try {
150
+ const adapter = getServiceAdapter();
151
+ const status = await adapter.status();
152
+ if (status.installed) {
153
+ await adapter.start();
154
+ const healthy = await waitForHealth(port, 30_000);
155
+ console.log(healthy ? ` ✓ daemon healthy on :${port}` : ` ⚠ daemon did not report healthy within 30s — check 'astramem-local doctor'`);
156
+ }
157
+ else {
158
+ console.log(' · no service registered — start manually (serve / service start)');
159
+ }
160
+ }
161
+ catch (err) {
162
+ console.log(` ⚠ restart failed: ${err.message} — start manually`);
163
+ }
164
+ }
165
+ console.log(`\n✓ restore complete. Previous DB kept at ${asidePath} — delete it once verified.\n`);
166
+ }
167
+ //# sourceMappingURL=restore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restore.js","sourceRoot":"","sources":["../../src/cli/restore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,QAAQ,MAAM,iCAAiC,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,SAAS,OAAO,CAAC,IAAc,EAAE,IAAY;IAC3C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,IAAY;IACrD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM;QAAE,OAAO,mBAAmB,CAAC;IACxC,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,IAAI,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,KAAK,GAAG,KAAK,CAAC;IAAC,CAAC;IAC7D,IAAI,CAAC,KAAK;QAAE,OAAO,mBAAmB,MAAM,CAAC,GAAG,QAAQ,CAAC;IACzD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,IAAI,IAAI,SAAS,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpG,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,eAAe,MAAM,CAAC,GAAG,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,cAAc,MAAM,CAAC,GAAG,sDAAsD,CAAC,CAAC;AAClG,CAAC;AAED,iEAAiE;AACjE,SAAS,aAAa,CAAC,IAAY,EAAE,GAAY;IAC/C,IAAI,EAAE,GAAc,IAAI,CAAC;IACzB,IAAI,CAAC;QACH,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAO,CAAC;QAClD,IAAI,GAAG;YAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAuC,CAAC;QAChF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,OAAO,EAAE,EAAE,CAAC;IAC/F,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAChF,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,EAAE,EAAE,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAc;IACjD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAChD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,iGAAiG,CAAC,CAAC;QACjH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,oBAAoB,EAAE,CAAC;IACtD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,gBAAgB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjG,OAAO,CAAC,GAAG,CAAC,sCAAsC,YAAY,iBAAiB,MAAM,IAAI,CAAC,CAAC;IAE3F,mDAAmD;IACnD,MAAM,KAAK,GAAG,aAAa,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,mCAAmC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAE1C,sBAAsB;IACtB,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,0DAA0D;IAC1D,MAAM,SAAS,GAAG,GAAG,MAAM,kBAAkB,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,MAAM,gBAAgB,CAAC;IAC1C,IAAI,CAAC;QACH,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACnC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,6BAA6B,SAAS,EAAE,CAAC,CAAC;YACtD,qEAAqE;YACrE,yDAAyD;YACzD,MAAM,CAAC,GAAG,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,MAAM,CAAC,GAAG,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;QACD,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,kBAAmB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,KAAK,CAAC,iBAAiB,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,mBAAmB,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC;QACnH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oEAAoE;IACpE,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,sCAAuC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9E,OAAO,CAAC,KAAK,CAAC,uBAAuB,MAAM,eAAe,SAAS,QAAQ,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,6CAA6C;IAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;YACtC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC,CAAC,8EAA8E,CAAC,CAAC;YAC3I,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,uBAAwB,GAAa,CAAC,OAAO,mBAAmB,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,6CAA6C,SAAS,+BAA+B,CAAC,CAAC;AACrG,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `astramem-local retag [--dry-run] [--limit N] [--tier2] [--no-tier2]
3
+ * [--confidence N] [--json]`
4
+ *
5
+ * FEAT-403 (W4.3) — one-shot repo/project tag-hygiene backfill. Scans
6
+ * memories with null/empty repo or project, derives tags tier-1 (session
7
+ * cwd/project_id) then optionally tier-2 (LLM-assisted, confidence-gated).
8
+ * See src/tag-hygiene/backfill.ts for the core (DB-only, testable) logic.
9
+ *
10
+ * tier-2 defaults to OFF (config.tagHygiene.tier2Enabled=false) — a
11
+ * data-mutating heuristic pass over legacy rows carries real mis-tag risk,
12
+ * so it is opt-in via --tier2 or config, never silently on.
13
+ */
14
+ export declare function retagCommand(args: string[]): Promise<void>;