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,230 @@
1
+ /**
2
+ * Memory Lifecycle Hooks
3
+ *
4
+ * Provides event hooks for memory operations:
5
+ * - memoryCreated: When a memory is stored (DB or markdown files)
6
+ * - memoryUpdated: When a memory is updated
7
+ * - memoryDeleted: When a memory is deleted
8
+ * - tierChange: When memory tier changes (hot/warm/cold)
9
+ * - decayApplied: When decay score is updated
10
+ *
11
+ * Each hook can have sync and async handlers.
12
+ * Usage: Register handlers to auto-capture, sync to external systems, etc.
13
+ */
14
+
15
+ import { logger } from '../logger.js';
16
+
17
+ export type HookEvent =
18
+ | 'memoryCreated'
19
+ | 'memoryUpdated'
20
+ | 'memoryDeleted'
21
+ | 'tierChange'
22
+ | 'decayApplied';
23
+
24
+ export interface MemoryHookContext {
25
+ memoryId: string;
26
+ content: string;
27
+ type: string;
28
+ tags: string[];
29
+ project?: string;
30
+ source?: string;
31
+ tier?: string;
32
+ importance?: number;
33
+ oldContent?: string; // For memoryUpdated events
34
+ }
35
+
36
+ export interface TierChangeContext extends MemoryHookContext {
37
+ oldTier: string;
38
+ newTier: string;
39
+ }
40
+
41
+ export interface DecayContext extends MemoryHookContext {
42
+ oldScore: number;
43
+ newScore: number;
44
+ }
45
+
46
+ export type HookHandler<T = MemoryHookContext> = (context: T) => void | Promise<void>;
47
+
48
+ interface HookRegistration {
49
+ event: HookEvent;
50
+ handler: HookHandler;
51
+ priority: number;
52
+ }
53
+
54
+ // Global hook registry
55
+ const hooks: HookRegistration[] = [];
56
+
57
+ /**
58
+ * Register a hook handler for a specific event
59
+ */
60
+ export function registerHook(
61
+ event: HookEvent,
62
+ handler: HookHandler,
63
+ priority: number = 100
64
+ ): void {
65
+ hooks.push({ event, handler, priority });
66
+ hooks.sort((a, b) => b.priority - a.priority);
67
+ logger.info('[Hooks] Registered handler for: ' + event + ' (priority: ' + priority + ')');
68
+ }
69
+
70
+ /**
71
+ * Unregister a hook handler
72
+ */
73
+ export function unregisterHook(event: HookEvent, handler: HookHandler): void {
74
+ const idx = hooks.findIndex(h => h.event === event && h.handler === handler);
75
+ if (idx !== -1) {
76
+ hooks.splice(idx, 1);
77
+ logger.info('[Hooks] Unregistered handler for: ' + event);
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Clear all hooks for an event
83
+ */
84
+ export function clearHooks(event?: HookEvent): void {
85
+ if (event) {
86
+ const before = hooks.length;
87
+ const filtered = hooks.filter(h => h.event !== event);
88
+ hooks.length = 0;
89
+ hooks.push(...filtered);
90
+ logger.info('[Hooks] Cleared ' + (before - filtered.length) + ' hooks for: ' + event);
91
+ } else {
92
+ const count = hooks.length;
93
+ hooks.length = 0;
94
+ logger.info('[Hooks] Cleared all ' + count + ' hooks');
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Get registered hooks for an event
100
+ */
101
+ export function getHooks(event: HookEvent): HookHandler[] {
102
+ return hooks.filter(h => h.event === event).map(h => h.handler);
103
+ }
104
+
105
+ /**
106
+ * List all registered hooks (for debugging)
107
+ */
108
+ export function listHooks(): { event: HookEvent; priority: number }[] {
109
+ return hooks.map(h => ({ event: h.event, priority: h.priority }));
110
+ }
111
+
112
+ // --- Trigger functions ---
113
+
114
+ /**
115
+ * Trigger memoryCreated hooks
116
+ * Called when a memory is stored in DB or markdown files
117
+ */
118
+ export async function triggerMemoryCreated(context: MemoryHookContext): Promise<void> {
119
+ const handlers = getHooks('memoryCreated');
120
+
121
+ for (const handler of handlers) {
122
+ try {
123
+ const result = handler(context);
124
+ if (result instanceof Promise) {
125
+ await result;
126
+ }
127
+ } catch (error) {
128
+ logger.error('[Hooks] Error in memoryCreated handler: ' + error);
129
+ }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Trigger memoryUpdated hooks
135
+ * Called when a memory content/tags/etc changes
136
+ */
137
+ export async function triggerMemoryUpdated(
138
+ context: MemoryHookContext,
139
+ oldContent?: string
140
+ ): Promise<void> {
141
+ const handlers = getHooks('memoryUpdated');
142
+
143
+ for (const handler of handlers) {
144
+ try {
145
+ const result = handler({ ...context, oldContent: oldContent || '' });
146
+ if (result instanceof Promise) {
147
+ await result;
148
+ }
149
+ } catch (error) {
150
+ logger.error('[Hooks] Error in memoryUpdated handler: ' + error);
151
+ }
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Trigger memoryDeleted hooks
157
+ * Called when a memory is deleted
158
+ */
159
+ export async function triggerMemoryDeleted(context: MemoryHookContext): Promise<void> {
160
+ const handlers = getHooks('memoryDeleted');
161
+
162
+ for (const handler of handlers) {
163
+ try {
164
+ const result = handler(context);
165
+ if (result instanceof Promise) {
166
+ await result;
167
+ }
168
+ } catch (error) {
169
+ logger.error('[Hooks] Error in memoryDeleted handler: ' + error);
170
+ }
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Trigger tierChange hooks
176
+ * Called when memory tier changes
177
+ */
178
+ export async function triggerTierChange(context: TierChangeContext): Promise<void> {
179
+ const handlers = getHooks('tierChange');
180
+
181
+ for (const handler of handlers) {
182
+ try {
183
+ const result = handler(context);
184
+ if (result instanceof Promise) {
185
+ await result;
186
+ }
187
+ } catch (error) {
188
+ logger.error('[Hooks] Error in tierChange handler: ' + error);
189
+ }
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Trigger decayApplied hooks
195
+ * Called when memory decay score changes
196
+ */
197
+ export async function triggerDecayApplied(context: DecayContext): Promise<void> {
198
+ const handlers = getHooks('decayApplied');
199
+
200
+ for (const handler of handlers) {
201
+ try {
202
+ const result = handler(context);
203
+ if (result instanceof Promise) {
204
+ await result;
205
+ }
206
+ } catch (error) {
207
+ logger.error('[Hooks] Error in decayApplied handler: ' + error);
208
+ }
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Built-in hook: Auto-save to memory files when storing to DB
214
+ * Use this to have dual storage (DB + markdown files)
215
+ */
216
+ export function createMarkdownAutoSyncHook() {
217
+ return async function markdownAutoSync(context: MemoryHookContext) {
218
+ if (context.tier === 'hot') {
219
+ const { saveToMarkdown } = await import('./markdown/markdown-storage.js');
220
+ await saveToMarkdown({
221
+ content: context.content,
222
+ type: context.type as any,
223
+ tags: context.tags,
224
+ project: context.project,
225
+ source: context.source,
226
+ });
227
+ logger.info('[Hooks] Auto-synced memory to markdown: ' + context.memoryId);
228
+ }
229
+ };
230
+ }
@@ -0,0 +1,65 @@
1
+ import type { MemoryRecord } from '../lib/types.js';
2
+ import { hybridSearch as currentHybridSearch } from './hybrid-search.js';
3
+ import type { SearchInput } from './memories.js';
4
+
5
+ export interface HybridSearchOptions extends SearchInput {
6
+ candidateLimit?: number;
7
+ resultLimit?: number;
8
+ }
9
+
10
+ export interface HybridSearchResult extends MemoryRecord {
11
+ hybridScore: number;
12
+ semanticScore: number;
13
+ recencyScore: number;
14
+ importanceScore: number;
15
+ coactivationScore: number;
16
+ rank: number;
17
+ explanation: string;
18
+ }
19
+
20
+ type ScoredItem = {
21
+ memoryId: string;
22
+ memory: Record<string, unknown>;
23
+ totalScore: number;
24
+ components: Record<string, number>;
25
+ rank: number;
26
+ explanation: string;
27
+ };
28
+
29
+ export function applyEntityBoostAndRerank<T extends ScoredItem>(scored: T[]): T[] {
30
+ return scored
31
+ .map((item) => {
32
+ const rawBoost = item.memory._entityBoost;
33
+ const entityBoost = typeof rawBoost === 'number' ? rawBoost : 0;
34
+ return {
35
+ ...item,
36
+ totalScore: item.totalScore + entityBoost * 20,
37
+ };
38
+ })
39
+ .sort((a, b) => b.totalScore - a.totalScore)
40
+ .map((item, index) => ({
41
+ ...item,
42
+ rank: index + 1,
43
+ }));
44
+ }
45
+
46
+ export async function hybridSearch(options: HybridSearchOptions): Promise<HybridSearchResult[]> {
47
+ const limit = options.resultLimit ?? options.limit ?? 5;
48
+ const results = await currentHybridSearch(options, {
49
+ limit,
50
+ project: options.project,
51
+ type: options.type,
52
+ tags: options.tags,
53
+ });
54
+
55
+ return results.map((result, index) => ({
56
+ ...result,
57
+ hybridScore: result.similarity ?? 0,
58
+ semanticScore: result.similarity ?? 0,
59
+ recencyScore: 0,
60
+ importanceScore: typeof result.importance === 'number' ? result.importance : 0,
61
+ coactivationScore: 0,
62
+ rank: index + 1,
63
+ explanation: 'Compatibility result from current hybrid search',
64
+ }));
65
+ }
@@ -0,0 +1,325 @@
1
+ /** Hybrid Scorer - Multi-factor relevance scoring for memory ranking */
2
+
3
+ import { logger } from '../../core/logger.js';
4
+ import { cosineSimilarity } from '../utils/vector-operations.js';
5
+
6
+ export interface ScoredMemory {
7
+ memoryId: string;
8
+ memory: any;
9
+ totalScore: number;
10
+ components: {
11
+ semantic: number;
12
+ recency: number;
13
+ coactivation: number;
14
+ importance: number;
15
+ confidence: number;
16
+ feedback: number;
17
+ };
18
+ rank: number;
19
+ explanation: string;
20
+ }
21
+
22
+ export interface HybridScorerOptions {
23
+ weights?: {
24
+ semantic?: number;
25
+ recency?: number;
26
+ coactivation?: number;
27
+ importance?: number;
28
+ confidence?: number;
29
+ feedback?: number;
30
+ };
31
+ decayDays?: number;
32
+ minSemanticScore?: number;
33
+ includeExplanation?: boolean;
34
+ }
35
+
36
+ export async function hybridScore(
37
+ queryEmbedding: number[] | null,
38
+ memories: any[],
39
+ options: HybridScorerOptions = {}
40
+ ): Promise<ScoredMemory[]> {
41
+ const weights = {
42
+ semantic: options.weights?.semantic ?? 0.30,
43
+ recency: options.weights?.recency ?? 0.20,
44
+ coactivation: options.weights?.coactivation ?? 0.10,
45
+ importance: options.weights?.importance ?? 0.15,
46
+ confidence: options.weights?.confidence ?? 0.15,
47
+ feedback: options.weights?.feedback ?? 0.10,
48
+ };
49
+
50
+ const decayDays = options.decayDays ?? 30;
51
+ const minSemanticScore = options.minSemanticScore ?? 0.0;
52
+
53
+ const scored: ScoredMemory[] = [];
54
+ const now = new Date();
55
+
56
+ for (const memory of memories) {
57
+ if (queryEmbedding && weights.semantic > 0) {
58
+ const semanticScore = calculateSemanticScore(queryEmbedding, memory);
59
+ if (semanticScore < minSemanticScore) continue;
60
+ }
61
+
62
+ const components = {
63
+ semantic: queryEmbedding ? calculateSemanticScore(queryEmbedding, memory) : 50,
64
+ recency: calculateRecencyScore(memory, now, decayDays),
65
+ coactivation: calculateCoactivationScore(memory),
66
+ importance: calculateImportanceScore(memory),
67
+ confidence: calculateConfidenceScore(memory),
68
+ feedback: calculateFeedbackScore(memory),
69
+ };
70
+
71
+ const totalScore = Math.min(
72
+ 100,
73
+ components.semantic * weights.semantic +
74
+ components.recency * weights.recency +
75
+ components.coactivation * weights.coactivation +
76
+ components.importance * weights.importance +
77
+ components.confidence * weights.confidence +
78
+ components.feedback * weights.feedback
79
+ );
80
+
81
+ scored.push({
82
+ memoryId: memory.id,
83
+ memory,
84
+ totalScore: Math.round(totalScore * 100) / 100,
85
+ components: {
86
+ semantic: Math.round(components.semantic * 100) / 100,
87
+ recency: Math.round(components.recency * 100) / 100,
88
+ coactivation: Math.round(components.coactivation * 100) / 100,
89
+ importance: Math.round(components.importance * 100) / 100,
90
+ confidence: Math.round(components.confidence * 100) / 100,
91
+ feedback: Math.round(components.feedback * 100) / 100,
92
+ },
93
+ rank: 0,
94
+ explanation: options.includeExplanation
95
+ ? generateScoreExplanation(components, weights, memory)
96
+ : '',
97
+ });
98
+ }
99
+
100
+ scored.sort((a, b) => b.totalScore - a.totalScore);
101
+ for (let i = 0; i < scored.length; i++) {
102
+ scored[i].rank = i + 1;
103
+ }
104
+
105
+ return scored;
106
+ }
107
+
108
+ function calculateSemanticScore(queryEmbedding: number[], memory: any): number {
109
+ if (!memory.embedding || queryEmbedding.length === 0) return 50;
110
+
111
+ try {
112
+ let memoryEmbedding: number[] | null = null;
113
+
114
+ if (Array.isArray(memory.embedding)) {
115
+ memoryEmbedding = memory.embedding;
116
+ } else if (typeof memory.embedding === 'string') {
117
+ memoryEmbedding = JSON.parse(memory.embedding);
118
+ }
119
+
120
+ if (!memoryEmbedding || memoryEmbedding.length === 0) return 50;
121
+
122
+ const semanticScore = cosineSimilarity(queryEmbedding, memoryEmbedding);
123
+ return Math.max(0, Math.min(100, (semanticScore + 1) * 50));
124
+ } catch (error) {
125
+ logger.error('Error calculating semantic score', error);
126
+ return 50;
127
+ }
128
+ }
129
+
130
+ function calculateRecencyScore(memory: any, now: Date, decayDays: number): number {
131
+ // Enhanced bi-temporal recency scoring: considers validity period and learning time
132
+ const validFromDate = memory.validFrom ? new Date(memory.validFrom) : null;
133
+ const validToDate = memory.validTo ? new Date(memory.validTo) : null;
134
+ const recordedAtDate = memory.recordedAt ? new Date(memory.recordedAt) : null;
135
+ const createdDate = memory.createdAt ? new Date(memory.createdAt) : null;
136
+
137
+ // Calculate score based on how relevant the memory is right now
138
+ let score = 50; // Default neutral score
139
+
140
+ // If we have a validity period, score based on current time's position within that period
141
+ if (validFromDate && validToDate) {
142
+ const timeInPeriod = now.getTime() - validFromDate.getTime();
143
+ const periodLength = validToDate.getTime() - validFromDate.getTime();
144
+
145
+ if (periodLength > 0) {
146
+ // If now is within the validity period, high score
147
+ if (now >= validFromDate && now <= validToDate) {
148
+ // Full score if right in middle, decreasing toward edges
149
+ const progress = timeInPeriod / periodLength;
150
+ const distanceFromCenter = Math.abs(0.5 - progress) * 2; // 0 at center, 1 at edges
151
+ score = 100 * (1 - distanceFromCenter * 0.8); // 100 at center, 40 at edges
152
+ } else {
153
+ // Outside validity period - score based on how recently it expired or how far in future
154
+ if (now < validFromDate) {
155
+ // Future validity - score based on how soon it becomes valid
156
+ const daysUntilValid = (validFromDate.getTime() - now.getTime()) / (24 * 60 * 60 * 1000);
157
+ score = Math.max(20, 100 - Math.min(80, daysUntilValid / decayDays * 100));
158
+ } else {
159
+ // Past validity - score based on how recently it expired
160
+ const daysSinceExpired = (now.getTime() - validToDate.getTime()) / (24 * 60 * 60 * 1000);
161
+ score = Math.max(10, 60 - Math.min(50, daysSinceExpired / decayDays * 100));
162
+ }
163
+ }
164
+ }
165
+ }
166
+ // If we only have validFrom (open-ended validity)
167
+ else if (validFromDate) {
168
+ const daysSinceValid = (now.getTime() - validFromDate.getTime()) / (24 * 60 * 60 * 1000);
169
+ if (now >= validFromDate) {
170
+ // Still valid - decay from full score over time
171
+ score = Math.max(30, 100 - Math.min(70, daysSinceValid / decayDays * 100));
172
+ } else {
173
+ // Becomes valid in future
174
+ const daysUntilValid = (validFromDate.getTime() - now.getTime()) / (24 * 60 * 60 * 1000);
175
+ score = Math.max(20, 100 - Math.min(80, daysUntilValid / decayDays * 100));
176
+ }
177
+ }
178
+ // Fallback to learned/recorded time
179
+ else {
180
+ const learnedDate = recordedAtDate || createdDate;
181
+ if (learnedDate) {
182
+ const daysSinceLearned = (now.getTime() - learnedDate.getTime()) / (24 * 60 * 60 * 1000);
183
+ score = 100 * Math.pow(0.5, daysSinceLearned / decayDays);
184
+ score = Math.max(0, Math.min(100, score));
185
+ }
186
+ }
187
+
188
+ return Math.round(score * 10) / 10; // Return one decimal place
189
+ }
190
+
191
+ function calculateCoactivationScore(memory: any): number {
192
+ if (!memory.coactivationScore || memory.coactivationScore === 0) return 10;
193
+ return Math.min(100, memory.coactivationScore * 5);
194
+ }
195
+
196
+ function calculateImportanceScore(memory: any): number {
197
+ let score = 50;
198
+
199
+ // Simplified: hot or cold only (warm removed)
200
+ if (memory.tier === 'hot') score += 30;
201
+ // No bonus for cold - it's the fallback
202
+
203
+ if (memory.relevanceScore) score += memory.relevanceScore * 0.2;
204
+ if (memory.isPinned) score += 10;
205
+ if (memory.isProtected) score += 10;
206
+ if (memory.isMergeable || memory.isMerged) score -= 10;
207
+
208
+ return Math.max(0, Math.min(100, score));
209
+ }
210
+
211
+ function calculateConfidenceScore(memory: any): number {
212
+ let score = 50;
213
+
214
+ const signals = memory.metadata?.memorySignals;
215
+
216
+ if (signals) {
217
+ if (signals.priority === 'high') score += 25;
218
+
219
+ if (signals.explicitTriggers && signals.explicitTriggers.length > 0) {
220
+ score += 15 * Math.min(signals.explicitTriggers.length, 2);
221
+ }
222
+
223
+ if (signals.implicit) {
224
+ if (signals.implicit.decision) score += 10;
225
+ if (signals.implicit.correction) score += 15;
226
+ if (signals.implicit.preference) score += 8;
227
+ if (signals.implicit.workflowRule) score += 12;
228
+ if (signals.implicit.lesson) score += 10;
229
+ }
230
+
231
+ if (signals.requiresConflictCheck) score -= 5;
232
+ }
233
+
234
+ switch (memory.type) {
235
+ case 'decision': score += 10; break;
236
+ case 'preference': score += 5; break;
237
+ case 'fact': score += 8; break;
238
+ case 'context': score += 3; break;
239
+ }
240
+
241
+ if (memory.source === 'mcp') score += 5;
242
+
243
+ if (memory.accessCount && memory.accessCount > 5) {
244
+ score += Math.min(10, memory.accessCount / 2);
245
+ }
246
+
247
+ return Math.max(0, Math.min(100, score));
248
+ }
249
+
250
+ function calculateFeedbackScore(memory: any): number {
251
+ const retrievalPriority = memory.retrievalPriority ?? 50;
252
+ return Math.max(0, Math.min(100, retrievalPriority));
253
+ }
254
+
255
+ function generateScoreExplanation(
256
+ components: ScoredMemory['components'],
257
+ weights: ScoredMemory['components'],
258
+ memory: any
259
+ ): string {
260
+ const parts: string[] = [];
261
+
262
+ if (components.semantic > 70) parts.push(`highly relevant (${components.semantic.toFixed(0)})`);
263
+ else if (components.semantic > 50) parts.push(`somewhat relevant (${components.semantic.toFixed(0)})`);
264
+ else parts.push(`low relevance (${components.semantic.toFixed(0)})`);
265
+
266
+ if (components.recency > 70) parts.push('recent');
267
+ else if (components.recency > 30) parts.push('moderately recent');
268
+ else parts.push('older');
269
+
270
+ // Simplified: hot or cold only (warm removed)
271
+ if (memory.tier === 'hot') parts.push('active memory');
272
+ else parts.push('archived memory');
273
+
274
+ if (components.coactivation > 60) parts.push('frequently associated');
275
+
276
+ if (components.confidence > 80) parts.push('high confidence');
277
+ else if (components.confidence > 60) parts.push('moderate confidence');
278
+ else if (components.confidence < 40) parts.push('low confidence');
279
+
280
+ if (components.feedback > 70) parts.push('frequently useful');
281
+ else if (components.feedback < 30) parts.push('rarely used');
282
+
283
+ return parts.join(', ');
284
+ }
285
+
286
+ export async function scoreAndRankMemories(
287
+ queryEmbedding: number[] | null,
288
+ memories: any[],
289
+ topK: number = 10,
290
+ options: HybridScorerOptions = {}
291
+ ): Promise<ScoredMemory[]> {
292
+ const scored = await hybridScore(queryEmbedding, memories, options);
293
+
294
+ logger.debug('Scored and ranked memories', {
295
+ total: scored.length,
296
+ topK,
297
+ topScores: scored.slice(0, topK).map((s) => ({ id: s.memoryId, score: s.totalScore })),
298
+ });
299
+
300
+ return scored.slice(0, topK);
301
+ }
302
+
303
+ export function getScoreDistribution(scored: ScoredMemory[]): {
304
+ min: number;
305
+ max: number;
306
+ avg: number;
307
+ median: number;
308
+ p95: number;
309
+ p99: number;
310
+ } {
311
+ if (scored.length === 0) {
312
+ return { min: 0, max: 0, avg: 0, median: 0, p95: 0, p99: 0 };
313
+ }
314
+
315
+ const scores = scored.map((s) => s.totalScore).sort((a, b) => a - b);
316
+
317
+ return {
318
+ min: scores[0],
319
+ max: scores[scores.length - 1],
320
+ avg: scores.reduce((a, b) => a + b, 0) / scores.length,
321
+ median: scores[Math.floor(scores.length / 2)],
322
+ p95: scores[Math.floor((95 / 100) * scores.length)],
323
+ p99: scores[Math.floor((99 / 100) * scores.length)],
324
+ };
325
+ }