squish-memory 1.1.5 → 1.2.0

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 (499) hide show
  1. package/.env.example +32 -16
  2. package/CHANGELOG.md +147 -0
  3. package/README.md +120 -78
  4. package/{scripts → bin}/dependency-manager.mjs +217 -217
  5. package/{scripts → bin}/detect-clients.mjs +78 -78
  6. package/bin/install-interactive.mjs +321 -0
  7. package/bin/squish-mcp.mjs +46 -0
  8. package/bin/squish.mjs +33 -0
  9. package/config/mcp-migration-map.json +1 -6
  10. package/config/mcp-mode-semantics.json +19 -23
  11. package/config/mcp-remote-auth.json +3 -26
  12. package/config/mcp-universal.schema.json +5 -35
  13. package/config/settings.json +107 -52
  14. package/config.js +5 -0
  15. package/config.ts +218 -0
  16. package/core/adapters/config/claude-code.ts +133 -0
  17. package/core/adapters/config/cursor.ts +90 -0
  18. package/core/adapters/config/opencode.ts +89 -0
  19. package/core/adapters/config/windsurf.ts +90 -0
  20. package/core/adapters/index.ts +102 -0
  21. package/core/adapters/timeline.ts +116 -0
  22. package/core/adapters/types.ts +166 -0
  23. package/core/agent-preferences.ts +140 -0
  24. package/core/algorithms/analytics/token-estimator.ts +216 -0
  25. package/core/algorithms/detection/hash-filters.ts +260 -0
  26. package/core/algorithms/detection/semantic-ranker.ts +194 -0
  27. package/core/algorithms/detection/two-stage-detector.ts +421 -0
  28. package/core/algorithms/handlers/approve-merge.ts +215 -0
  29. package/core/algorithms/handlers/detect-duplicates.ts +192 -0
  30. package/core/algorithms/handlers/get-stats.ts +132 -0
  31. package/core/algorithms/handlers/list-proposals.ts +130 -0
  32. package/core/algorithms/handlers/preview-merge.ts +139 -0
  33. package/core/algorithms/handlers/reject-merge.ts +93 -0
  34. package/core/algorithms/handlers/reverse-merge.ts +155 -0
  35. package/core/algorithms/index.ts +39 -0
  36. package/core/algorithms/operations/cache-maintenance.ts +182 -0
  37. package/core/algorithms/safety/safety-checks.ts +256 -0
  38. package/core/algorithms/strategies/merge-strategies.ts +381 -0
  39. package/core/algorithms/types.ts +140 -0
  40. package/core/algorithms/utils/response-builder.ts +61 -0
  41. package/core/associations.ts +363 -0
  42. package/core/beliefs/decay.ts +289 -0
  43. package/core/beliefs/extractor.ts +131 -0
  44. package/core/beliefs/store.ts +557 -0
  45. package/core/beliefs/types.ts +38 -0
  46. package/core/commands/mcp-server.ts +5 -0
  47. package/core/compression.ts +177 -0
  48. package/core/config.js +2 -0
  49. package/core/consolidation.ts +330 -0
  50. package/core/context/agent-context.ts +388 -0
  51. package/core/context/context-paging.ts +449 -0
  52. package/core/context/context-window.ts +234 -0
  53. package/core/context/context.ts +35 -0
  54. package/core/embeddings/embeddings.ts +616 -0
  55. package/core/embeddings/google-multimodal.ts +200 -0
  56. package/{dist/core/local-embeddings.js → core/embeddings/local-embeddings.ts} +12 -11
  57. package/core/embeddings/qmd-client.ts +495 -0
  58. package/core/embeddings/transformers-local.ts +261 -0
  59. package/core/embeddings.js +4 -0
  60. package/core/error-handling.ts +206 -0
  61. package/core/external +219 -0
  62. package/core/graph/entity-deduplicator.ts +232 -0
  63. package/core/graph/graph-builder.ts +257 -0
  64. package/core/graph/graph-traversal.ts +490 -0
  65. package/core/graph/index.ts +24 -0
  66. package/core/graph/llm-entity-extractor.ts +402 -0
  67. package/core/graph/multi-hop-retrieval.ts +317 -0
  68. package/core/graph/relationship-extractor.ts +465 -0
  69. package/core/hooks/agent-hooks.ts +653 -0
  70. package/core/hooks/auto-tagger.ts +149 -0
  71. package/core/hooks/capture-filter.ts +169 -0
  72. package/core/hot-cache.ts +388 -0
  73. package/core/index.ts +10 -0
  74. package/core/ingestion/agent-memory.ts +167 -0
  75. package/core/ingestion/core-memory.ts +326 -0
  76. package/core/ingestion/learnings.ts +260 -0
  77. package/core/ingestion/signal-engine.ts +266 -0
  78. package/core/integrations/obsidian-vault.ts +197 -0
  79. package/core/layers/generator.ts +115 -0
  80. package/core/lib/db-client.ts +168 -0
  81. package/core/lib/parse-embedding.ts +59 -0
  82. package/core/lib/schemas.ts +102 -0
  83. package/core/lib/types.ts +49 -0
  84. package/core/lib/utils.ts +151 -0
  85. package/core/lib/validation.ts +180 -0
  86. package/core/lifecycle.ts +353 -0
  87. package/core/logger.ts +59 -0
  88. package/core/memory/bridge-discovery.ts +395 -0
  89. package/core/memory/categorizer.ts +390 -0
  90. package/core/memory/conflict-detector.ts +62 -0
  91. package/core/memory/consolidation.ts +372 -0
  92. package/core/memory/context-collector.ts +75 -0
  93. package/core/memory/contradiction-resolver.ts +494 -0
  94. package/core/memory/edit-workflow.ts +174 -0
  95. package/core/memory/entity-extractor.ts +426 -0
  96. package/core/memory/entity-resolver.ts +89 -0
  97. package/core/memory/explain.ts +112 -0
  98. package/core/memory/fact-deriver.ts +300 -0
  99. package/core/memory/fact-extractor.ts +120 -0
  100. package/core/memory/feedback-tracker.ts +200 -0
  101. package/core/memory/hooks.ts +230 -0
  102. package/core/memory/hybrid-retrieval.ts +65 -0
  103. package/core/memory/hybrid-scorer.ts +325 -0
  104. package/core/memory/hybrid-search.ts +748 -0
  105. package/core/memory/importance.ts +319 -0
  106. package/core/memory/index.ts +11 -0
  107. package/core/memory/loader.ts +178 -0
  108. package/core/memory/markdown/markdown-storage.ts +318 -0
  109. package/core/memory/memories.ts +565 -0
  110. package/core/memory/memory-lifecycle.ts +51 -0
  111. package/core/memory/memory-manager.ts +53 -0
  112. package/core/memory/migrate.ts +173 -0
  113. package/core/memory/normalization.ts +30 -0
  114. package/core/memory/path-strengthener.ts +211 -0
  115. package/core/memory/progressive-disclosure.ts +392 -0
  116. package/core/memory/query-processor.ts +130 -0
  117. package/core/memory/query-rewriter.ts +153 -0
  118. package/core/memory/response-analyzer.ts +81 -0
  119. package/core/memory/retrieval-feedback.ts +276 -0
  120. package/core/memory/serialization.ts +83 -0
  121. package/core/memory/stale-cleaner.ts +147 -0
  122. package/core/memory/stats.ts +181 -0
  123. package/core/memory/telemetry.ts +392 -0
  124. package/core/memory/temporal-facts.ts +356 -0
  125. package/core/memory/temporal-parser.ts +477 -0
  126. package/core/memory/trigger-detector.ts +104 -0
  127. package/core/memory/write-gate.ts +288 -0
  128. package/core/places/index.ts +14 -0
  129. package/core/places/memory-places.ts +339 -0
  130. package/core/places/places.ts +406 -0
  131. package/core/places/rules.ts +308 -0
  132. package/core/places/walking.ts +192 -0
  133. package/core/projects +89 -0
  134. package/core/projects.ts +131 -0
  135. package/core/redis.ts +82 -0
  136. package/core/responses.ts +187 -0
  137. package/core/runtime/trust-report.ts +195 -0
  138. package/core/runtime/trust-state.ts +360 -0
  139. package/core/scheduler/cron-scheduler.ts +581 -0
  140. package/core/scheduler/heartbeat.ts +91 -0
  141. package/core/scheduler/index.ts +8 -0
  142. package/core/scheduler/job-runner.ts +197 -0
  143. package/core/search/conversations.ts +166 -0
  144. package/core/search/entities.ts +46 -0
  145. package/core/search/folder-context.ts +154 -0
  146. package/core/search/graph-boost.ts +22 -0
  147. package/core/search/index.ts +4 -0
  148. package/core/search/qmd-wrapper.ts +84 -0
  149. package/core/security/encrypt.ts +51 -0
  150. package/core/security/governance.ts +102 -0
  151. package/core/security/privacy.ts +108 -0
  152. package/core/security/secret-detector.ts +122 -0
  153. package/core/session/auto-load.ts +160 -0
  154. package/core/session/entity-tracker.ts +363 -0
  155. package/core/session/index.ts +7 -0
  156. package/core/session/reference-resolver.ts +158 -0
  157. package/core/session/self-iteration-job.ts +478 -0
  158. package/core/session/session-hooks.ts +69 -0
  159. package/core/session/types.ts +36 -0
  160. package/core/session/working-set.ts +275 -0
  161. package/core/snapshots/cleanup.ts +13 -0
  162. package/core/snapshots/comparison.ts +59 -0
  163. package/core/snapshots/creation.ts +139 -0
  164. package/core/snapshots/retrieval.ts +44 -0
  165. package/core/snapshots/stats.ts +63 -0
  166. package/core/storage/cache.ts +241 -0
  167. package/core/storage/database.ts +23 -0
  168. package/core/summarization/cleanup.ts +13 -0
  169. package/core/summarization/queries.ts +32 -0
  170. package/core/summarization/stats.ts +64 -0
  171. package/core/summarization/strategies.ts +52 -0
  172. package/core/summarization.ts +248 -0
  173. package/core/temporal-facts.ts +244 -0
  174. package/core/tracing/collector.ts +470 -0
  175. package/core/tracing/visualizer.ts +195 -0
  176. package/core/utils/cleanup-operations.ts +50 -0
  177. package/core/utils/content-extraction.ts +95 -0
  178. package/core/utils/filter-builder.ts +56 -0
  179. package/core/utils/history-traversal.ts +63 -0
  180. package/core/utils/memory-operations.ts +56 -0
  181. package/core/utils/query-operations.ts +83 -0
  182. package/core/utils/summarization-helpers.ts +45 -0
  183. package/core/utils/temporal-queries.ts +39 -0
  184. package/core/utils/vector-operations.ts +135 -0
  185. package/core/utils/version-management.ts +74 -0
  186. package/core/worker.ts +324 -0
  187. package/db/adapter.ts +215 -0
  188. package/db/bootstrap.ts +1055 -0
  189. package/db/drizzle/migrations/0000_needy_cerebro.sql +402 -0
  190. package/db/drizzle/migrations/meta/0000_snapshot.json +3451 -0
  191. package/db/drizzle/migrations/meta/_journal.json +13 -0
  192. package/db/drizzle/schema-sqlite.ts +1032 -0
  193. package/db/drizzle/schema.ts +1128 -0
  194. package/db/drizzle.config.ts +12 -0
  195. package/db/index.ts +83 -0
  196. package/db/init.sql +5 -0
  197. package/db/migrations/associations.ts +35 -0
  198. package/db/migrations/beliefs.ts +89 -0
  199. package/db/migrations/core-memory.ts +35 -0
  200. package/db/migrations/fts.ts +59 -0
  201. package/db/migrations/index.ts +54 -0
  202. package/db/migrations/indexes.ts +36 -0
  203. package/db/migrations/learnings.ts +34 -0
  204. package/db/migrations/maintenance.ts +68 -0
  205. package/db/migrations/memories.ts +22 -0
  206. package/db/migrations/memory-places.ts +35 -0
  207. package/db/migrations/places.ts +49 -0
  208. package/db/migrations/projects.ts +21 -0
  209. package/db/migrations/tier-conversion.ts +24 -0
  210. package/db/neon.ts +22 -0
  211. package/db/schema/beliefs.ts +50 -0
  212. package/db/schema/generator.ts +159 -0
  213. package/db/schema/index.ts +58 -0
  214. package/db/schema/learnings.ts +32 -0
  215. package/db/schema/memories.ts +83 -0
  216. package/db/schema/projects.ts +33 -0
  217. package/db/schema.ts +13 -0
  218. package/db/supabase.ts +27 -0
  219. package/dist/config.d.ts +40 -17
  220. package/dist/config.js +150 -198
  221. package/dist/core/adapters/types.d.ts +13 -33
  222. package/dist/core/adapters/types.js +1 -1
  223. package/dist/core/agent-preferences.d.ts +16 -0
  224. package/dist/core/agent-preferences.js +124 -0
  225. package/dist/core/algorithms/safety/safety-checks.d.ts +1 -5
  226. package/dist/core/algorithms/types.d.ts +0 -8
  227. package/dist/core/associations.d.ts +3 -1
  228. package/dist/core/associations.js +37 -1
  229. package/dist/core/beliefs/decay.d.ts +27 -0
  230. package/dist/core/beliefs/decay.js +217 -0
  231. package/dist/core/beliefs/extractor.d.ts +9 -0
  232. package/dist/core/beliefs/extractor.js +113 -0
  233. package/dist/core/beliefs/store.d.ts +46 -0
  234. package/dist/core/beliefs/store.js +466 -0
  235. package/dist/core/beliefs/types.d.ts +28 -0
  236. package/dist/core/beliefs/types.js +2 -0
  237. package/dist/core/commands/mcp-server.d.ts +0 -1
  238. package/dist/core/commands/mcp-server.js +4 -737
  239. package/dist/core/commands/remember.d.ts +24 -0
  240. package/dist/core/commands/remember.js +144 -0
  241. package/dist/core/{toon.d.ts → compression.d.ts} +6 -4
  242. package/dist/core/{toon.js → compression.js} +8 -8
  243. package/dist/core/context/agent-context.js +1 -1
  244. package/dist/core/embeddings/embeddings.d.ts +29 -0
  245. package/dist/core/embeddings/embeddings.js +546 -0
  246. package/dist/core/embeddings/google-multimodal.js +6 -2
  247. package/dist/core/{local-embeddings.d.ts → embeddings/local-embeddings.d.ts} +1 -1
  248. package/dist/core/embeddings/local-embeddings.js +11 -0
  249. package/dist/core/embeddings/qmd-client.js +1 -1
  250. package/dist/core/embeddings/transformers-local.d.ts +64 -0
  251. package/dist/core/embeddings/transformers-local.js +213 -0
  252. package/dist/core/embeddings.d.ts +1 -28
  253. package/dist/core/embeddings.js +2 -453
  254. package/dist/core/graph/entity-deduplicator.d.ts +24 -0
  255. package/dist/core/graph/entity-deduplicator.js +183 -0
  256. package/dist/core/graph/graph-builder.d.ts +46 -0
  257. package/dist/core/graph/graph-builder.js +174 -0
  258. package/dist/core/graph/graph-traversal.d.ts +80 -0
  259. package/dist/core/graph/graph-traversal.js +315 -0
  260. package/dist/core/graph/index.d.ts +19 -0
  261. package/dist/core/graph/index.js +13 -0
  262. package/dist/core/graph/llm-entity-extractor.d.ts +49 -0
  263. package/dist/core/graph/llm-entity-extractor.js +313 -0
  264. package/dist/core/graph/multi-hop-retrieval.d.ts +48 -0
  265. package/dist/core/graph/multi-hop-retrieval.js +215 -0
  266. package/dist/core/graph/relationship-extractor.d.ts +48 -0
  267. package/dist/core/graph/relationship-extractor.js +351 -0
  268. package/dist/core/hooks/agent-hooks.d.ts +10 -1
  269. package/dist/core/hooks/agent-hooks.js +301 -24
  270. package/dist/core/hot-cache.d.ts +86 -0
  271. package/dist/core/hot-cache.js +285 -0
  272. package/dist/core/index.d.ts +9 -9
  273. package/dist/core/index.js +9 -12
  274. package/dist/core/ingestion/core-memory.d.ts +2 -2
  275. package/dist/core/ingestion/core-memory.js +3 -3
  276. package/dist/core/ingestion/learnings.js +3 -0
  277. package/dist/core/ingestion/signal-engine.d.ts +41 -0
  278. package/dist/core/ingestion/signal-engine.js +201 -0
  279. package/dist/core/{obsidian-vault.d.ts → integrations/obsidian-vault.d.ts} +2 -1
  280. package/dist/core/{obsidian-vault.js → integrations/obsidian-vault.js} +69 -7
  281. package/dist/core/lib/parse-embedding.d.ts +9 -0
  282. package/dist/core/lib/parse-embedding.js +58 -0
  283. package/dist/core/lib/schemas.d.ts +57 -54
  284. package/dist/core/lib/types.d.ts +45 -0
  285. package/dist/core/lib/types.js +6 -0
  286. package/dist/core/lib/utils.d.ts +4 -0
  287. package/dist/core/lib/utils.js +55 -0
  288. package/dist/core/lifecycle.d.ts +0 -1
  289. package/dist/core/lifecycle.js +13 -23
  290. package/dist/core/logger.d.ts +1 -0
  291. package/dist/core/logger.js +14 -8
  292. package/dist/core/mcp/tools.d.ts +0 -2
  293. package/dist/core/mcp/tools.js +0 -87
  294. package/dist/core/mcp/types.d.ts +25 -253
  295. package/dist/core/mcp/types.js +2 -2
  296. package/dist/core/memory/categorizer.js +1 -0
  297. package/dist/core/memory/consolidation.js +2 -28
  298. package/dist/core/memory/entity-extractor.d.ts +4 -0
  299. package/dist/core/memory/entity-extractor.js +30 -16
  300. package/dist/core/memory/explain.d.ts +18 -0
  301. package/dist/core/memory/explain.js +92 -0
  302. package/dist/core/memory/fact-deriver.d.ts +31 -0
  303. package/dist/core/memory/fact-deriver.js +236 -0
  304. package/dist/core/memory/hybrid-retrieval.d.ts +14 -16
  305. package/dist/core/memory/hybrid-retrieval.js +25 -127
  306. package/dist/core/memory/hybrid-scorer.js +6 -23
  307. package/dist/core/memory/hybrid-search.d.ts +10 -7
  308. package/dist/core/memory/hybrid-search.js +458 -221
  309. package/dist/core/memory/importance.d.ts +0 -17
  310. package/dist/core/memory/importance.js +1 -58
  311. package/dist/core/memory/index.d.ts +1 -0
  312. package/dist/core/memory/index.js +1 -0
  313. package/dist/core/memory/memories.d.ts +13 -17
  314. package/dist/core/memory/memories.js +78 -75
  315. package/dist/core/memory/memory-lifecycle.d.ts +2 -2
  316. package/dist/core/memory/memory-lifecycle.js +10 -18
  317. package/dist/core/memory/normalization.d.ts +1 -16
  318. package/dist/core/memory/path-strengthener.d.ts +39 -0
  319. package/dist/core/memory/path-strengthener.js +150 -0
  320. package/dist/core/memory/query-processor.js +37 -3
  321. package/dist/core/memory/retrieval-feedback.d.ts +70 -0
  322. package/dist/core/memory/retrieval-feedback.js +213 -0
  323. package/dist/core/memory/stale-cleaner.d.ts +26 -0
  324. package/dist/core/memory/stale-cleaner.js +97 -0
  325. package/dist/core/memory/stats.d.ts +10 -0
  326. package/dist/core/memory/stats.js +8 -3
  327. package/dist/core/memory/trigger-detector.d.ts +8 -1
  328. package/dist/core/memory/trigger-detector.js +42 -5
  329. package/dist/core/places/index.d.ts +1 -1
  330. package/dist/core/places/index.js +1 -1
  331. package/dist/core/places/places.d.ts +13 -13
  332. package/dist/core/places/places.js +27 -27
  333. package/dist/core/places/rules.js +23 -23
  334. package/dist/core/places/walking.d.ts +3 -3
  335. package/dist/core/places/walking.js +7 -7
  336. package/dist/core/projects.js +8 -0
  337. package/dist/core/runtime/trust-report.d.ts +102 -0
  338. package/dist/core/runtime/trust-report.js +107 -0
  339. package/dist/core/runtime/trust-state.d.ts +12 -0
  340. package/dist/core/runtime/trust-state.js +309 -0
  341. package/dist/core/scheduler/cron-scheduler.d.ts +1 -1
  342. package/dist/core/scheduler/cron-scheduler.js +164 -3
  343. package/dist/core/scheduler/job-runner.js +1 -1
  344. package/dist/core/search/qmd-wrapper.d.ts +36 -0
  345. package/dist/core/search/qmd-wrapper.js +58 -0
  346. package/dist/core/session/auto-load.js +28 -3
  347. package/dist/core/session/entity-tracker.d.ts +62 -0
  348. package/dist/core/session/entity-tracker.js +287 -0
  349. package/dist/core/session/reference-resolver.d.ts +26 -0
  350. package/dist/core/session/reference-resolver.js +121 -0
  351. package/dist/core/session/self-iteration-job.d.ts +15 -0
  352. package/dist/core/session/self-iteration-job.js +163 -58
  353. package/dist/core/session/working-set.d.ts +50 -0
  354. package/dist/core/session/working-set.js +212 -0
  355. package/dist/core/snapshots/creation.d.ts +2 -8
  356. package/dist/core/snapshots/creation.js +3 -12
  357. package/dist/core/utils/summarization-helpers.d.ts +0 -4
  358. package/dist/core/utils/summarization-helpers.js +1 -6
  359. package/dist/db/bootstrap.d.ts +2 -0
  360. package/dist/db/bootstrap.js +229 -280
  361. package/dist/db/drizzle/schema-sqlite.d.ts +702 -1
  362. package/dist/db/drizzle/schema-sqlite.js +83 -4
  363. package/dist/db/drizzle/schema.d.ts +653 -1
  364. package/dist/db/drizzle/schema.js +93 -4
  365. package/dist/db/migrations/associations.d.ts +6 -0
  366. package/dist/db/migrations/associations.js +29 -0
  367. package/dist/db/migrations/beliefs.d.ts +10 -0
  368. package/dist/db/migrations/beliefs.js +76 -0
  369. package/dist/db/migrations/core-memory.d.ts +6 -0
  370. package/dist/db/migrations/core-memory.js +29 -0
  371. package/dist/db/migrations/fts.d.ts +6 -0
  372. package/dist/db/migrations/fts.js +52 -0
  373. package/dist/db/migrations/index.d.ts +25 -0
  374. package/dist/db/migrations/index.js +51 -0
  375. package/dist/db/migrations/indexes.d.ts +6 -0
  376. package/dist/db/migrations/indexes.js +30 -0
  377. package/dist/db/migrations/learnings.d.ts +7 -0
  378. package/dist/db/migrations/learnings.js +26 -0
  379. package/dist/db/migrations/maintenance.d.ts +6 -0
  380. package/dist/db/migrations/maintenance.js +61 -0
  381. package/dist/db/migrations/memories.d.ts +7 -0
  382. package/dist/db/migrations/memories.js +16 -0
  383. package/dist/db/migrations/memory-places.d.ts +6 -0
  384. package/dist/db/migrations/memory-places.js +29 -0
  385. package/dist/db/migrations/places.d.ts +6 -0
  386. package/dist/db/migrations/places.js +43 -0
  387. package/dist/db/migrations/projects.d.ts +3 -0
  388. package/dist/db/migrations/projects.js +13 -0
  389. package/dist/db/migrations/tier-conversion.d.ts +7 -0
  390. package/dist/db/migrations/tier-conversion.js +20 -0
  391. package/dist/db/schema/beliefs.d.ts +9 -0
  392. package/dist/db/schema/beliefs.js +46 -0
  393. package/dist/db/schema/generator.d.ts +38 -0
  394. package/dist/db/schema/generator.js +108 -0
  395. package/dist/db/schema/index.d.ts +19 -20
  396. package/dist/db/schema/index.js +25 -79
  397. package/dist/db/schema/learnings.d.ts +7 -0
  398. package/dist/db/schema/learnings.js +30 -0
  399. package/dist/db/schema/memories.d.ts +7 -0
  400. package/dist/db/schema/memories.js +81 -0
  401. package/dist/db/schema/projects.d.ts +4 -0
  402. package/dist/db/schema/projects.js +31 -0
  403. package/dist/packages/mcp/src/index.d.ts +3 -0
  404. package/dist/packages/mcp/src/index.js +733 -0
  405. package/mcp.json.example +8 -11
  406. package/package.json +57 -76
  407. package/packages/cli/package.json +22 -0
  408. package/packages/cli/src/commands/clean.ts +68 -0
  409. package/packages/cli/src/commands/context.ts +79 -0
  410. package/packages/cli/src/commands/doctor.ts +357 -0
  411. package/packages/cli/src/commands/forget.ts +72 -0
  412. package/packages/cli/src/commands/health.ts +36 -0
  413. package/packages/cli/src/commands/inspect.ts +41 -0
  414. package/packages/cli/src/commands/link.ts +50 -0
  415. package/packages/cli/src/commands/migrate.ts +93 -0
  416. package/packages/cli/src/commands/recall.ts +99 -0
  417. package/packages/cli/src/commands/recent.ts +57 -0
  418. package/packages/cli/src/commands/remember.ts +139 -0
  419. package/packages/cli/src/commands/run.ts +58 -0
  420. package/packages/cli/src/commands/stale.ts +43 -0
  421. package/packages/cli/src/commands/stats.ts +42 -0
  422. package/packages/cli/src/index.ts +57 -0
  423. package/packages/cli/tsconfig.json +24 -0
  424. package/packages/mcp/package.json +26 -0
  425. package/packages/mcp/src/index.ts +877 -0
  426. package/packages/mcp/tsconfig.json +20 -0
  427. package/skills/squish-memory/SKILL.md +38 -35
  428. package/skills/squish-memory/{scripts/install.sh → install.sh} +1 -1
  429. package/skills/squish-memory/references/claude-desktop.json +12 -0
  430. package/skills/squish-memory/references/openclaw.json +13 -0
  431. package/skills/squish-memory/references/opencode.json +14 -0
  432. package/config/hooks/claude-code-hooks.json +0 -39
  433. package/config/hooks/cursor-hooks.json +0 -30
  434. package/config/hooks/opencode-hooks.json +0 -30
  435. package/config/hooks/windsurf-hooks.json +0 -30
  436. package/config/mcp-cli-fallback-policy.json +0 -22
  437. package/config/mcp.json +0 -38
  438. package/config/plugin-manifest.json +0 -101
  439. package/config/plugin-manifest.schema.json +0 -244
  440. package/config/plugin.json +0 -32
  441. package/config/remote-memory-policy.json +0 -32
  442. package/core/commands/context-paging.md +0 -51
  443. package/core/commands/context-status.md +0 -22
  444. package/core/commands/context.md +0 -5
  445. package/core/commands/core-memory.md +0 -56
  446. package/core/commands/health.md +0 -5
  447. package/core/commands/init.md +0 -39
  448. package/core/commands/merge.md +0 -113
  449. package/core/commands/recall.md +0 -5
  450. package/core/commands/remember.md +0 -11
  451. package/core/commands/search.md +0 -10
  452. package/dist/core/commands/managed-sync.d.ts +0 -10
  453. package/dist/core/commands/managed-sync.js +0 -64
  454. package/dist/core/external-folder/index.d.ts +0 -102
  455. package/dist/core/external-folder/index.js +0 -294
  456. package/dist/core/namespaces/index.d.ts +0 -71
  457. package/dist/core/namespaces/index.js +0 -305
  458. package/dist/core/namespaces/uri-parser.d.ts +0 -31
  459. package/dist/core/namespaces/uri-parser.js +0 -74
  460. package/dist/core/search/qmd-search.d.ts +0 -61
  461. package/dist/core/search/qmd-search.js +0 -178
  462. package/dist/core/session-hooks/self-iteration-job.d.ts +0 -20
  463. package/dist/core/session-hooks/self-iteration-job.js +0 -282
  464. package/dist/core/session-hooks/session-hooks.d.ts +0 -18
  465. package/dist/core/session-hooks/session-hooks.js +0 -58
  466. package/dist/core/snapshots.d.ts +0 -29
  467. package/dist/core/snapshots.js +0 -220
  468. package/dist/core/sync/qmd-sync.d.ts +0 -94
  469. package/dist/core/sync/qmd-sync.js +0 -201
  470. package/dist/index.d.ts +0 -7
  471. package/dist/index.js +0 -1677
  472. package/dist/vendor/sql.js/sql-wasm.wasm +0 -0
  473. package/dist/webui/server.d.ts +0 -5
  474. package/dist/webui/server.js +0 -642
  475. package/generated/mcp/manifest.json +0 -23
  476. package/generated/mcp/mcp-servers.json +0 -25
  477. package/generated/mcp/mcporter.json +0 -34
  478. package/generated/mcp/openclaw-memory-qmd.json +0 -17
  479. package/generated/mcp/runtime.json +0 -12
  480. package/scripts/README.md +0 -60
  481. package/scripts/build-release.sh +0 -36
  482. package/scripts/check-secrets.js +0 -132
  483. package/scripts/copy-runtime-assets.mjs +0 -26
  484. package/scripts/generate-mcp.mjs +0 -264
  485. package/scripts/github-release.sh +0 -77
  486. package/scripts/init-dirs.mjs +0 -13
  487. package/scripts/install-claude-code.sh +0 -85
  488. package/scripts/install-cursor.sh +0 -56
  489. package/scripts/install-hooks.sh +0 -73
  490. package/scripts/install-interactive.mjs +0 -357
  491. package/scripts/install-opencode.sh +0 -75
  492. package/scripts/install-plugin.mjs +0 -415
  493. package/scripts/install-windsurf.sh +0 -67
  494. package/scripts/remote-preflight.mjs +0 -62
  495. package/scripts/squish-fallback.mjs +0 -132
  496. package/scripts/test-interactive.mjs +0 -131
  497. package/scripts/verify-mcp.mjs +0 -214
  498. package/skills/squish-memory/scripts/install.mjs +0 -335
  499. package/skills/squish-memory/write_skill.js +0 -2
@@ -0,0 +1,81 @@
1
+ /** Response Analyzer - Analyze LLM responses for memory references (Echo/Fizzle tracking) */
2
+
3
+ import { logger } from '../logger.js';
4
+
5
+ export interface AnalysisResult {
6
+ referencedMemoryIds: string[];
7
+ referenceCount: number;
8
+ hasReferences: boolean;
9
+ }
10
+
11
+ const REFERENCE_PATTERNS = [
12
+ /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/gi,
13
+ /as (?:i |we )?(?:mentioned|noted|remembered|recalled|stored|saved)/gi,
14
+ /(?:based|drawing) on (?:my|our|the) (?:memory|previous|earlier)/gi,
15
+ /(?:i |we )?(?:recall|remember|noted) (?:that |earlier )?/gi,
16
+ /from (?:my|our|the) (?:memory|notes|records)/gi,
17
+ ];
18
+
19
+ export function analyzeResponseForMemoryReferences(
20
+ responseText: string,
21
+ injectedMemoryIds: string[],
22
+ injectedMemoryContent: Map<string, string>
23
+ ): AnalysisResult {
24
+ const referencedMemoryIds: string[] = [];
25
+ const responseLower = responseText.toLowerCase();
26
+
27
+ for (const memoryId of injectedMemoryIds) {
28
+ if (responseText.includes(memoryId)) {
29
+ referencedMemoryIds.push(memoryId);
30
+ logger.debug(`[ResponseAnalyzer] Direct reference found: ${memoryId}`);
31
+ }
32
+ }
33
+
34
+ for (const [memoryId, content] of injectedMemoryContent) {
35
+ if (referencedMemoryIds.includes(memoryId)) continue;
36
+
37
+ const contentWords = content.toLowerCase().split(/\s+/).filter(w => w.length > 3);
38
+ if (contentWords.length < 5) continue;
39
+
40
+ let matchCount = 0;
41
+ for (const word of contentWords) {
42
+ if (responseLower.includes(word)) {
43
+ matchCount++;
44
+ }
45
+ }
46
+
47
+ const matchRatio = matchCount / contentWords.length;
48
+ if (matchRatio > 0.5) {
49
+ referencedMemoryIds.push(memoryId);
50
+ logger.debug(`[ResponseAnalyzer] Content match (${(matchRatio * 100).toFixed(0)}%): ${memoryId}`);
51
+ }
52
+ }
53
+
54
+ for (const pattern of REFERENCE_PATTERNS) {
55
+ const matches = responseText.match(pattern);
56
+ if (matches && matches.length > 0) {
57
+ logger.debug(`[ResponseAnalyzer] Reference pattern found: ${matches.length} matches`);
58
+ }
59
+ }
60
+
61
+ const result: AnalysisResult = {
62
+ referencedMemoryIds: [...new Set(referencedMemoryIds)],
63
+ referenceCount: referencedMemoryIds.length,
64
+ hasReferences: referencedMemoryIds.length > 0,
65
+ };
66
+
67
+ if (result.hasReferences) {
68
+ logger.info(`[ResponseAnalyzer] Found ${result.referenceCount} memory references`);
69
+ }
70
+
71
+ return result;
72
+ }
73
+
74
+ export function mightContainMemoryReferences(responseText: string): boolean {
75
+ const responseLower = responseText.toLowerCase();
76
+ const quickPatterns = [
77
+ 'remember', 'recall', 'mentioned', 'noted', 'earlier',
78
+ 'previous', 'as i', 'as we', 'from my', 'from our',
79
+ ];
80
+ return quickPatterns.some(pattern => responseLower.includes(pattern));
81
+ }
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Retrieval Feedback System
3
+ *
4
+ * Tracks whether retrieved memories were useful in responses.
5
+ * Strengthens useful paths, prunes stale nodes, tunes edge weights.
6
+ */
7
+
8
+ import { eq, and, sql } from 'drizzle-orm';
9
+ import { getDb } from '../../db/index.js';
10
+ import { getSchema } from '../../db/schema.js';
11
+ import { logger } from '../logger.js';
12
+
13
+ // ─── Types ──────────────────────────────────────────────────────────────────
14
+
15
+ export interface RetrievalFeedback {
16
+ memoryId: string;
17
+ query: string;
18
+ wasUseful: boolean;
19
+ cited: boolean; // Was the memory cited in the response?
20
+ responseId?: string;
21
+ timestamp: Date;
22
+ }
23
+
24
+ export interface FeedbackStats {
25
+ totalRetrievals: number;
26
+ usefulRetrievals: number;
27
+ citedRetrievals: number;
28
+ usefulnessRate: number;
29
+ citationRate: number;
30
+ }
31
+
32
+ // ─── In-Memory Feedback Buffer ───────────────────────────────────────────────
33
+
34
+ const feedbackBuffer = new Map<string, RetrievalFeedback[]>();
35
+ const MAX_BUFFER_SIZE = 1000;
36
+ const FLUSH_INTERVAL_MS = 60000; // 1 minute
37
+
38
+ let flushTimer: ReturnType<typeof setInterval> | null = null;
39
+
40
+ /**
41
+ * Record that a memory was retrieved for a query.
42
+ * Call this when a memory appears in search results.
43
+ */
44
+ export function recordRetrieval(
45
+ memoryId: string,
46
+ query: string,
47
+ options?: { sessionId?: string }
48
+ ): void {
49
+ const key = options?.sessionId || 'default';
50
+ const buffer = feedbackBuffer.get(key) || [];
51
+
52
+ buffer.push({
53
+ memoryId,
54
+ query,
55
+ wasUseful: false, // Will be updated later
56
+ cited: false,
57
+ timestamp: new Date(),
58
+ });
59
+
60
+ // Trim buffer if too large
61
+ if (buffer.length > MAX_BUFFER_SIZE) {
62
+ buffer.splice(0, buffer.length - MAX_BUFFER_SIZE);
63
+ }
64
+
65
+ feedbackBuffer.set(key, buffer);
66
+ }
67
+
68
+ /**
69
+ * Record that a retrieved memory was actually useful.
70
+ * Call this when a memory is cited or referenced in a response.
71
+ */
72
+ export function recordUsefulRetrieval(
73
+ memoryId: string,
74
+ query: string,
75
+ options?: {
76
+ cited?: boolean;
77
+ responseId?: string;
78
+ sessionId?: string;
79
+ }
80
+ ): void {
81
+ const key = options?.sessionId || 'default';
82
+ const buffer = feedbackBuffer.get(key) || [];
83
+
84
+ // Find the existing retrieval record and update it
85
+ const existing = buffer.find(f => f.memoryId === memoryId && f.query === query && !f.wasUseful);
86
+ if (existing) {
87
+ existing.wasUseful = true;
88
+ existing.cited = options?.cited ?? false;
89
+ existing.responseId = options?.responseId;
90
+ } else {
91
+ // Add a new record
92
+ buffer.push({
93
+ memoryId,
94
+ query,
95
+ wasUseful: true,
96
+ cited: options?.cited ?? false,
97
+ responseId: options?.responseId,
98
+ timestamp: new Date(),
99
+ });
100
+ }
101
+
102
+ feedbackBuffer.set(key, buffer);
103
+ }
104
+
105
+ /**
106
+ * Record that a memory was cited in a response.
107
+ * This is stronger feedback than just "useful" - it means the memory
108
+ * was explicitly referenced.
109
+ */
110
+ export function recordCitation(
111
+ memoryId: string,
112
+ responseId: string,
113
+ options?: { sessionId?: string }
114
+ ): void {
115
+ const key = options?.sessionId || 'default';
116
+ const buffer = feedbackBuffer.get(key) || [];
117
+
118
+ // Mark all retrievals of this memory as useful
119
+ for (const feedback of buffer) {
120
+ if (feedback.memoryId === memoryId) {
121
+ feedback.wasUseful = true;
122
+ feedback.cited = true;
123
+ feedback.responseId = responseId;
124
+ }
125
+ }
126
+
127
+ feedbackBuffer.set(key, buffer);
128
+ }
129
+
130
+ /**
131
+ * Get feedback statistics for a specific memory.
132
+ */
133
+ export function getRetrievalStats(memoryId: string): FeedbackStats {
134
+ let totalRetrievals = 0;
135
+ let usefulRetrievals = 0;
136
+ let citedRetrievals = 0;
137
+
138
+ for (const [, buffer] of feedbackBuffer) {
139
+ for (const feedback of buffer) {
140
+ if (feedback.memoryId === memoryId) {
141
+ totalRetrievals++;
142
+ if (feedback.wasUseful) usefulRetrievals++;
143
+ if (feedback.cited) citedRetrievals++;
144
+ }
145
+ }
146
+ }
147
+
148
+ return {
149
+ totalRetrievals,
150
+ usefulRetrievals,
151
+ citedRetrievals,
152
+ usefulnessRate: totalRetrievals > 0 ? usefulRetrievals / totalRetrievals : 0,
153
+ citationRate: totalRetrievals > 0 ? citedRetrievals / totalRetrievals : 0,
154
+ };
155
+ }
156
+
157
+ /**
158
+ * Get overall feedback statistics.
159
+ */
160
+ export function getOverallFeedbackStats(): FeedbackStats {
161
+ let totalRetrievals = 0;
162
+ let usefulRetrievals = 0;
163
+ let citedRetrievals = 0;
164
+
165
+ for (const [, buffer] of feedbackBuffer) {
166
+ for (const feedback of buffer) {
167
+ totalRetrievals++;
168
+ if (feedback.wasUseful) usefulRetrievals++;
169
+ if (feedback.cited) citedRetrievals++;
170
+ }
171
+ }
172
+
173
+ return {
174
+ totalRetrievals,
175
+ usefulRetrievals,
176
+ citedRetrievals,
177
+ usefulnessRate: totalRetrievals > 0 ? usefulRetrievals / totalRetrievals : 0,
178
+ citationRate: totalRetrievals > 0 ? citedRetrievals / totalRetrievals : 0,
179
+ };
180
+ }
181
+
182
+ /**
183
+ * Flush feedback to the database, updating association weights.
184
+ */
185
+ export async function flushFeedback(): Promise<{
186
+ strengthened: number;
187
+ weakened: number;
188
+ total: number;
189
+ }> {
190
+ const db = await getDb();
191
+ const schema = await getSchema();
192
+
193
+ let strengthened = 0;
194
+ let weakened = 0;
195
+ let total = 0;
196
+
197
+ for (const [, buffer] of feedbackBuffer) {
198
+ for (const feedback of buffer) {
199
+ total++;
200
+
201
+ try {
202
+ // Get associations involving this memory
203
+ const associations = await (db as any)
204
+ .select()
205
+ .from(schema.memoryAssociations)
206
+ .where(
207
+ sql`${schema.memoryAssociations.fromMemoryId} = ${feedback.memoryId} OR ${schema.memoryAssociations.toMemoryId} = ${feedback.memoryId}`
208
+ );
209
+
210
+ for (const assoc of associations) {
211
+ if (feedback.wasUseful) {
212
+ // Strengthen: increase weight and coactivation count
213
+ await (db as any)
214
+ .update(schema.memoryAssociations)
215
+ .set({
216
+ weight: sql`${schema.memoryAssociations.weight} + 1`,
217
+ coactivationCount: sql`${schema.memoryAssociations.coactivationCount} + 1`,
218
+ lastCoactivatedAt: new Date(),
219
+ })
220
+ .where(eq(schema.memoryAssociations.id, assoc.id));
221
+ strengthened++;
222
+ } else {
223
+ // Weaken: decrease weight slightly (but don't go below 1)
224
+ await (db as any)
225
+ .update(schema.memoryAssociations)
226
+ .set({
227
+ weight: sql`GREATEST(${schema.memoryAssociations.weight} - 0.5, 1)`,
228
+ })
229
+ .where(eq(schema.memoryAssociations.id, assoc.id));
230
+ weakened++;
231
+ }
232
+ }
233
+ } catch (error) {
234
+ logger.debug('Error updating association weights', {
235
+ memoryId: feedback.memoryId,
236
+ error: error as Error,
237
+ });
238
+ }
239
+ }
240
+ }
241
+
242
+ // Clear the buffer after flushing
243
+ feedbackBuffer.clear();
244
+
245
+ logger.info('Feedback flushed', { strengthened, weakened, total });
246
+
247
+ return { strengthened, weakened, total };
248
+ }
249
+
250
+ /**
251
+ * Start the periodic feedback flush timer.
252
+ */
253
+ export function startFeedbackFlushTimer(): void {
254
+ if (flushTimer) return;
255
+
256
+ flushTimer = setInterval(async () => {
257
+ try {
258
+ await flushFeedback();
259
+ } catch (error) {
260
+ logger.error('Error flushing feedback', { error: error as Error });
261
+ }
262
+ }, FLUSH_INTERVAL_MS);
263
+
264
+ logger.info('Feedback flush timer started', { intervalMs: FLUSH_INTERVAL_MS });
265
+ }
266
+
267
+ /**
268
+ * Stop the periodic feedback flush timer.
269
+ */
270
+ export function stopFeedbackFlushTimer(): void {
271
+ if (flushTimer) {
272
+ clearInterval(flushTimer);
273
+ flushTimer = null;
274
+ logger.info('Feedback flush timer stopped');
275
+ }
276
+ }
@@ -0,0 +1,83 @@
1
+ import { config } from '../../config.js';
2
+
3
+ export function normalizeTags(tags?: string[]): string[] {
4
+ return (tags || []).map((tag) => tag.trim()).filter((tag) => tag.length > 0);
5
+ }
6
+
7
+ export function toSqliteJson(value: unknown): string | null {
8
+ if (value === undefined || value === null) return null;
9
+ return JSON.stringify(value);
10
+ }
11
+
12
+ export function fromSqliteJson<T>(value: string | null | undefined): T | null {
13
+ if (!value) return null;
14
+ try {
15
+ return JSON.parse(value) as T;
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
20
+
21
+ export function toSqliteTags(tags?: string[]): string | null {
22
+ if (!tags || tags.length === 0) return null;
23
+ return JSON.stringify(tags);
24
+ }
25
+
26
+ export function fromSqliteTags(value: string | null | undefined): string[] {
27
+ if (!value) return [];
28
+ try {
29
+ const parsed = JSON.parse(value);
30
+ return Array.isArray(parsed) ? parsed.map(String) : [];
31
+ } catch {
32
+ return value.split(',').map((tag) => tag.trim()).filter(Boolean);
33
+ }
34
+ }
35
+
36
+ // High-level helpers that abstract away team mode vs local mode
37
+
38
+ export function serializeTags(tags?: string[]): string[] | string | null | undefined {
39
+ if (config.isTeamMode) {
40
+ // PostgreSQL: store as array directly (or null if empty)
41
+ return tags && tags.length > 0 ? tags : null;
42
+ } else {
43
+ // SQLite: store as JSON string (or null)
44
+ return toSqliteTags(tags);
45
+ }
46
+ }
47
+
48
+ export function deserializeTags(value: string[] | string | null | undefined): string[] {
49
+ if (config.isTeamMode) {
50
+ // PostgreSQL: value is already an array or null/undefined
51
+ return Array.isArray(value) ? value : [];
52
+ } else {
53
+ // SQLite: value is a JSON string or null/undefined
54
+ if (typeof value === 'string' || value === null || value === undefined) {
55
+ return fromSqliteTags(value);
56
+ }
57
+ // Unexpected type, return empty array
58
+ return [];
59
+ }
60
+ }
61
+
62
+ export function serializeMetadata(metadata: Record<string, unknown> | null | undefined): Record<string, unknown> | string | null {
63
+ if (config.isTeamMode) {
64
+ // PostgreSQL: store object directly (or null if null/undefined, keep empty object as-is)
65
+ return metadata === undefined || metadata === null ? null : metadata;
66
+ } else {
67
+ // SQLite: store as JSON string (or null)
68
+ return toSqliteJson(metadata);
69
+ }
70
+ }
71
+
72
+ export function deserializeMetadata(value: Record<string, unknown> | string | null | undefined): Record<string, unknown> | null {
73
+ if (config.isTeamMode) {
74
+ // PostgreSQL: value is already an object or null/undefined
75
+ return value == null ? null : (value as Record<string, unknown>);
76
+ } else {
77
+ // SQLite: value is a JSON string or null/undefined
78
+ if (typeof value === 'string' || value === null) {
79
+ return fromSqliteJson<Record<string, unknown>>(value);
80
+ }
81
+ return null;
82
+ }
83
+ }
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Stale Memory Cleaner
3
+ * Deletes memories that are old, low-confidence, and low-importance
4
+ */
5
+
6
+ import { getDb } from '../../db/index.js';
7
+ import { getSchema } from '../../db/schema.js';
8
+ import { lt, or, and, eq, lte } from 'drizzle-orm';
9
+
10
+ export interface StaleMemory {
11
+ id: string;
12
+ content: string;
13
+ type: string;
14
+ createdAt: Date;
15
+ confidenceLevel: string | null;
16
+ importanceScore: number | null;
17
+ isPinned: boolean;
18
+ }
19
+
20
+ export interface StaleMemoryQuery {
21
+ olderThanDays: number;
22
+ confidenceLevels: string[];
23
+ minImportance: number;
24
+ projectId?: string;
25
+ }
26
+
27
+ export async function getStaleMemories(query: StaleMemoryQuery): Promise<StaleMemory[]> {
28
+ const db = await getDb();
29
+ if (!db) return [];
30
+
31
+ const schema = await getSchema();
32
+ const sqliteDb = db as any;
33
+
34
+ const cutoffDate = new Date(Date.now() - query.olderThanDays * 24 * 60 * 60 * 1000);
35
+
36
+ // Build conditions
37
+ const conditions = [
38
+ // Not pinned
39
+ or(
40
+ eq((schema.memories as any).isPinned, false),
41
+ eq((schema.memories as any).isPinned, null)
42
+ ),
43
+ // Older than cutoff
44
+ lt((schema.memories as any).createdAt, cutoffDate),
45
+ ];
46
+
47
+ // Confidence level filter
48
+ if (query.confidenceLevels.length > 0) {
49
+ conditions.push(
50
+ or(
51
+ ...query.confidenceLevels.map(level =>
52
+ eq((schema.memories as any).confidenceLevel, level)
53
+ )
54
+ )
55
+ );
56
+ }
57
+
58
+ // Importance filter (below threshold)
59
+ conditions.push(lte((schema.memories as any).importanceScore, query.minImportance));
60
+
61
+ // Project filter if specified
62
+ if (query.projectId) {
63
+ conditions.push(eq((schema.memories as any).projectId, query.projectId));
64
+ }
65
+
66
+ try {
67
+ const results = await sqliteDb
68
+ .select({
69
+ id: schema.memories.id,
70
+ content: schema.memories.content,
71
+ type: schema.memories.type,
72
+ createdAt: schema.memories.createdAt,
73
+ confidenceLevel: (schema.memories as any).confidenceLevel,
74
+ importanceScore: (schema.memories as any).importanceScore,
75
+ isPinned: (schema.memories as any).isPinned,
76
+ })
77
+ .from(schema.memories)
78
+ .where(and(...conditions.filter(Boolean)));
79
+
80
+ return results.map((r: any) => ({
81
+ ...r,
82
+ isPinned: Boolean(r.isPinned),
83
+ }));
84
+ } catch (error) {
85
+ console.error('[StaleCleaner] Error querying stale memories:', error);
86
+ return [];
87
+ }
88
+ }
89
+
90
+ export async function deleteMemoryPermanently(memoryId: string): Promise<void> {
91
+ const db = await getDb();
92
+ if (!db) return;
93
+
94
+ const schema = await getSchema();
95
+ const sqliteDb = db as any;
96
+
97
+ try {
98
+ // Delete associated records first
99
+ await sqliteDb.delete(schema.memoryAssociations).where(
100
+ or(
101
+ eq((schema.memoryAssociations as any).fromMemoryId, memoryId),
102
+ eq((schema.memoryAssociations as any).toMemoryId, memoryId)
103
+ )
104
+ ).catch(() => {}); // Ignore if table doesn't exist
105
+
106
+ // Delete memory tags
107
+ await sqliteDb.delete((schema as any).memoryTags).where(
108
+ eq((schema as any).memoryTags.memoryId, memoryId)
109
+ ).catch(() => {}); // Ignore if table doesn't exist
110
+
111
+ // Delete the memory itself
112
+ await sqliteDb.delete(schema.memories).where(eq(schema.memories.id, memoryId));
113
+ } catch (error) {
114
+ console.error(`[StaleCleaner] Error deleting memory ${memoryId}:`, error);
115
+ throw error;
116
+ }
117
+ }
118
+
119
+ export async function runAutoClean(options?: Partial<StaleMemoryQuery>): Promise<{
120
+ deleted: number;
121
+ summary: Record<string, unknown>;
122
+ }> {
123
+ const defaultOptions: StaleMemoryQuery = {
124
+ olderThanDays: options?.olderThanDays || 30,
125
+ confidenceLevels: options?.confidenceLevels || ['outdated', 'speculative'],
126
+ minImportance: options?.minImportance || 40,
127
+ };
128
+
129
+ const stale = await getStaleMemories(defaultOptions);
130
+ let deleted = 0;
131
+
132
+ for (const memory of stale) {
133
+ if (!memory.isPinned) {
134
+ await deleteMemoryPermanently(memory.id);
135
+ deleted++;
136
+ }
137
+ }
138
+
139
+ return {
140
+ deleted,
141
+ summary: {
142
+ scanned: stale.length,
143
+ skippedPinned: stale.length - deleted,
144
+ criteria: defaultOptions,
145
+ },
146
+ };
147
+ }