squish-memory 1.1.5 → 1.2.1

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 (646) 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 +44 -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/{dist/core/algorithms/index.js → core/algorithms/index.ts} +39 -26
  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/{dist/core/lib/db-client.d.ts → core/lib/db-client.ts} +168 -114
  81. package/core/lib/parse-embedding.ts +59 -0
  82. package/{dist/core/lib/schemas.js → core/lib/schemas.ts} +102 -87
  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/{dist/core/memory/index.js → core/memory/index.ts} +11 -10
  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/{dist/core/places/index.js → core/places/index.ts} +12 -12
  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 +590 -0
  140. package/core/scheduler/heartbeat.ts +91 -0
  141. package/{dist/core/scheduler/index.js → core/scheduler/index.ts} +8 -8
  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/{dist/core/search/index.js → core/search/index.ts} +4 -5
  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/{dist/core/session/index.js → core/session/index.ts} +7 -7
  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/{dist/core/snapshots/cleanup.js → core/snapshots/cleanup.ts} +13 -12
  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/{dist/core/summarization/cleanup.js → core/summarization/cleanup.ts} +13 -12
  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/{dist/core/utils/vector-operations.js → core/utils/vector-operations.ts} +135 -129
  185. package/core/utils/version-management.ts +74 -0
  186. package/core/worker.ts +333 -0
  187. package/db/adapter.ts +215 -0
  188. package/{dist/db/bootstrap.js → db/bootstrap.ts} +388 -418
  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/mcp.json.example +8 -11
  220. package/package.json +140 -159
  221. package/packages/cli/package.json +22 -0
  222. package/packages/cli/src/commands/clean.ts +68 -0
  223. package/packages/cli/src/commands/context.ts +79 -0
  224. package/packages/cli/src/commands/doctor.ts +357 -0
  225. package/packages/cli/src/commands/forget.ts +72 -0
  226. package/packages/cli/src/commands/health.ts +36 -0
  227. package/packages/cli/src/commands/inspect.ts +41 -0
  228. package/packages/cli/src/commands/link.ts +50 -0
  229. package/packages/cli/src/commands/migrate.ts +93 -0
  230. package/packages/cli/src/commands/recall.ts +99 -0
  231. package/packages/cli/src/commands/recent.ts +57 -0
  232. package/packages/cli/src/commands/remember.ts +139 -0
  233. package/packages/cli/src/commands/run.ts +58 -0
  234. package/packages/cli/src/commands/stale.ts +43 -0
  235. package/packages/cli/src/commands/stats.ts +42 -0
  236. package/packages/cli/src/index.ts +57 -0
  237. package/packages/cli/tsconfig.json +24 -0
  238. package/packages/mcp/package.json +26 -0
  239. package/packages/mcp/src/index.ts +940 -0
  240. package/packages/mcp/tsconfig.json +20 -0
  241. package/skills/squish-memory/SKILL.md +38 -35
  242. package/skills/squish-memory/{scripts/install.sh → install.sh} +1 -1
  243. package/skills/squish-memory/references/claude-desktop.json +12 -0
  244. package/skills/squish-memory/references/openclaw.json +13 -0
  245. package/skills/squish-memory/references/opencode.json +14 -0
  246. package/config/hooks/claude-code-hooks.json +0 -39
  247. package/config/hooks/cursor-hooks.json +0 -30
  248. package/config/hooks/opencode-hooks.json +0 -30
  249. package/config/hooks/windsurf-hooks.json +0 -30
  250. package/config/mcp-cli-fallback-policy.json +0 -22
  251. package/config/mcp.json +0 -38
  252. package/config/plugin-manifest.json +0 -101
  253. package/config/plugin-manifest.schema.json +0 -244
  254. package/config/plugin.json +0 -32
  255. package/config/remote-memory-policy.json +0 -32
  256. package/core/commands/context-paging.md +0 -51
  257. package/core/commands/context-status.md +0 -22
  258. package/core/commands/context.md +0 -5
  259. package/core/commands/core-memory.md +0 -56
  260. package/core/commands/health.md +0 -5
  261. package/core/commands/init.md +0 -39
  262. package/core/commands/merge.md +0 -113
  263. package/core/commands/recall.md +0 -5
  264. package/core/commands/remember.md +0 -11
  265. package/core/commands/search.md +0 -10
  266. package/dist/config.d.ts +0 -83
  267. package/dist/config.js +0 -242
  268. package/dist/core/adapters/config/claude-code.d.ts +0 -45
  269. package/dist/core/adapters/config/claude-code.js +0 -113
  270. package/dist/core/adapters/config/cursor.d.ts +0 -26
  271. package/dist/core/adapters/config/cursor.js +0 -74
  272. package/dist/core/adapters/config/opencode.d.ts +0 -23
  273. package/dist/core/adapters/config/opencode.js +0 -73
  274. package/dist/core/adapters/config/windsurf.d.ts +0 -26
  275. package/dist/core/adapters/config/windsurf.js +0 -74
  276. package/dist/core/adapters/index.d.ts +0 -45
  277. package/dist/core/adapters/index.js +0 -84
  278. package/dist/core/adapters/scripts/install-adapter.d.ts +0 -19
  279. package/dist/core/adapters/scripts/install-adapter.js +0 -149
  280. package/dist/core/adapters/timeline.d.ts +0 -23
  281. package/dist/core/adapters/timeline.js +0 -88
  282. package/dist/core/adapters/types.d.ts +0 -157
  283. package/dist/core/adapters/types.js +0 -50
  284. package/dist/core/algorithms/analytics/token-estimator.d.ts +0 -50
  285. package/dist/core/algorithms/analytics/token-estimator.js +0 -154
  286. package/dist/core/algorithms/detection/hash-filters.d.ts +0 -47
  287. package/dist/core/algorithms/detection/hash-filters.js +0 -190
  288. package/dist/core/algorithms/detection/semantic-ranker.d.ts +0 -32
  289. package/dist/core/algorithms/detection/semantic-ranker.js +0 -118
  290. package/dist/core/algorithms/detection/two-stage-detector.d.ts +0 -52
  291. package/dist/core/algorithms/detection/two-stage-detector.js +0 -299
  292. package/dist/core/algorithms/handlers/approve-merge.d.ts +0 -22
  293. package/dist/core/algorithms/handlers/approve-merge.js +0 -179
  294. package/dist/core/algorithms/handlers/detect-duplicates.d.ts +0 -47
  295. package/dist/core/algorithms/handlers/detect-duplicates.js +0 -145
  296. package/dist/core/algorithms/handlers/get-stats.d.ts +0 -39
  297. package/dist/core/algorithms/handlers/get-stats.js +0 -88
  298. package/dist/core/algorithms/handlers/list-proposals.d.ts +0 -45
  299. package/dist/core/algorithms/handlers/list-proposals.js +0 -83
  300. package/dist/core/algorithms/handlers/preview-merge.d.ts +0 -39
  301. package/dist/core/algorithms/handlers/preview-merge.js +0 -93
  302. package/dist/core/algorithms/handlers/reject-merge.d.ts +0 -28
  303. package/dist/core/algorithms/handlers/reject-merge.js +0 -69
  304. package/dist/core/algorithms/handlers/reverse-merge.d.ts +0 -21
  305. package/dist/core/algorithms/handlers/reverse-merge.js +0 -121
  306. package/dist/core/algorithms/index.d.ts +0 -21
  307. package/dist/core/algorithms/operations/cache-maintenance.d.ts +0 -12
  308. package/dist/core/algorithms/operations/cache-maintenance.js +0 -157
  309. package/dist/core/algorithms/safety/safety-checks.d.ts +0 -22
  310. package/dist/core/algorithms/safety/safety-checks.js +0 -179
  311. package/dist/core/algorithms/strategies/merge-strategies.d.ts +0 -50
  312. package/dist/core/algorithms/strategies/merge-strategies.js +0 -288
  313. package/dist/core/algorithms/types.d.ts +0 -133
  314. package/dist/core/algorithms/types.js +0 -5
  315. package/dist/core/algorithms/utils/response-builder.d.ts +0 -28
  316. package/dist/core/algorithms/utils/response-builder.js +0 -37
  317. package/dist/core/associations.d.ts +0 -31
  318. package/dist/core/associations.js +0 -248
  319. package/dist/core/autosave.d.ts +0 -19
  320. package/dist/core/autosave.js +0 -16
  321. package/dist/core/commands/managed-sync.d.ts +0 -10
  322. package/dist/core/commands/managed-sync.js +0 -64
  323. package/dist/core/commands/mcp-server.d.ts +0 -3
  324. package/dist/core/commands/mcp-server.js +0 -739
  325. package/dist/core/consolidation.d.ts +0 -37
  326. package/dist/core/consolidation.js +0 -248
  327. package/dist/core/context/agent-context.d.ts +0 -106
  328. package/dist/core/context/agent-context.js +0 -274
  329. package/dist/core/context/context-paging.d.ts +0 -80
  330. package/dist/core/context/context-paging.js +0 -328
  331. package/dist/core/context/context-window.d.ts +0 -40
  332. package/dist/core/context/context-window.js +0 -177
  333. package/dist/core/context/context.d.ts +0 -7
  334. package/dist/core/context/context.js +0 -22
  335. package/dist/core/embeddings/google-multimodal.d.ts +0 -14
  336. package/dist/core/embeddings/google-multimodal.js +0 -142
  337. package/dist/core/embeddings/qmd-client.d.ts +0 -136
  338. package/dist/core/embeddings/qmd-client.js +0 -403
  339. package/dist/core/embeddings.d.ts +0 -29
  340. package/dist/core/embeddings.js +0 -454
  341. package/dist/core/error-handling.d.ts +0 -63
  342. package/dist/core/error-handling.js +0 -173
  343. package/dist/core/external-folder/index.d.ts +0 -102
  344. package/dist/core/external-folder/index.js +0 -294
  345. package/dist/core/hooks/agent-hooks.d.ts +0 -74
  346. package/dist/core/hooks/agent-hooks.js +0 -244
  347. package/dist/core/hooks/auto-tagger.d.ts +0 -19
  348. package/dist/core/hooks/auto-tagger.js +0 -155
  349. package/dist/core/hooks/capture-filter.d.ts +0 -41
  350. package/dist/core/hooks/capture-filter.js +0 -128
  351. package/dist/core/index.d.ts +0 -10
  352. package/dist/core/index.js +0 -14
  353. package/dist/core/ingestion/agent-memory.d.ts +0 -22
  354. package/dist/core/ingestion/agent-memory.js +0 -109
  355. package/dist/core/ingestion/core-memory.d.ts +0 -78
  356. package/dist/core/ingestion/core-memory.js +0 -226
  357. package/dist/core/ingestion/learnings.d.ts +0 -57
  358. package/dist/core/ingestion/learnings.js +0 -202
  359. package/dist/core/layers/generator.d.ts +0 -25
  360. package/dist/core/layers/generator.js +0 -76
  361. package/dist/core/lib/db-client.js +0 -130
  362. package/dist/core/lib/schemas.d.ts +0 -129
  363. package/dist/core/lib/utils.d.ts +0 -14
  364. package/dist/core/lib/utils.js +0 -90
  365. package/dist/core/lib/validation.d.ts +0 -38
  366. package/dist/core/lib/validation.js +0 -151
  367. package/dist/core/lifecycle.d.ts +0 -26
  368. package/dist/core/lifecycle.js +0 -302
  369. package/dist/core/local-embeddings.d.ts +0 -11
  370. package/dist/core/logger.d.ts +0 -16
  371. package/dist/core/logger.js +0 -40
  372. package/dist/core/mcp/client.d.ts +0 -17
  373. package/dist/core/mcp/client.js +0 -101
  374. package/dist/core/mcp/index.d.ts +0 -6
  375. package/dist/core/mcp/index.js +0 -6
  376. package/dist/core/mcp/server.d.ts +0 -18
  377. package/dist/core/mcp/server.js +0 -157
  378. package/dist/core/mcp/standalone-server.d.ts +0 -13
  379. package/dist/core/mcp/standalone-server.js +0 -46
  380. package/dist/core/mcp/tools.d.ts +0 -9
  381. package/dist/core/mcp/tools.js +0 -365
  382. package/dist/core/mcp/types.d.ts +0 -315
  383. package/dist/core/mcp/types.js +0 -48
  384. package/dist/core/memory/bridge-discovery.d.ts +0 -50
  385. package/dist/core/memory/bridge-discovery.js +0 -291
  386. package/dist/core/memory/categorizer.d.ts +0 -27
  387. package/dist/core/memory/categorizer.js +0 -305
  388. package/dist/core/memory/conflict-detector.d.ts +0 -7
  389. package/dist/core/memory/conflict-detector.js +0 -43
  390. package/dist/core/memory/consolidation.d.ts +0 -42
  391. package/dist/core/memory/consolidation.js +0 -303
  392. package/dist/core/memory/context-collector.d.ts +0 -10
  393. package/dist/core/memory/context-collector.js +0 -56
  394. package/dist/core/memory/contradiction-resolver.d.ts +0 -40
  395. package/dist/core/memory/contradiction-resolver.js +0 -368
  396. package/dist/core/memory/edit-workflow.d.ts +0 -19
  397. package/dist/core/memory/edit-workflow.js +0 -120
  398. package/dist/core/memory/entity-extractor.d.ts +0 -33
  399. package/dist/core/memory/entity-extractor.js +0 -336
  400. package/dist/core/memory/entity-resolver.d.ts +0 -23
  401. package/dist/core/memory/entity-resolver.js +0 -64
  402. package/dist/core/memory/fact-extractor.d.ts +0 -24
  403. package/dist/core/memory/fact-extractor.js +0 -89
  404. package/dist/core/memory/feedback-tracker.d.ts +0 -12
  405. package/dist/core/memory/feedback-tracker.js +0 -155
  406. package/dist/core/memory/hooks.d.ts +0 -88
  407. package/dist/core/memory/hooks.js +0 -174
  408. package/dist/core/memory/hybrid-retrieval.d.ts +0 -29
  409. package/dist/core/memory/hybrid-retrieval.js +0 -139
  410. package/dist/core/memory/hybrid-scorer.d.ts +0 -40
  411. package/dist/core/memory/hybrid-scorer.js +0 -284
  412. package/dist/core/memory/hybrid-search.d.ts +0 -20
  413. package/dist/core/memory/hybrid-search.js +0 -359
  414. package/dist/core/memory/importance.d.ts +0 -63
  415. package/dist/core/memory/importance.js +0 -298
  416. package/dist/core/memory/index.d.ts +0 -8
  417. package/dist/core/memory/loader.d.ts +0 -31
  418. package/dist/core/memory/loader.js +0 -141
  419. package/dist/core/memory/markdown/markdown-storage.d.ts +0 -72
  420. package/dist/core/memory/markdown/markdown-storage.js +0 -243
  421. package/dist/core/memory/memories.d.ts +0 -47
  422. package/dist/core/memory/memories.js +0 -449
  423. package/dist/core/memory/memory-lifecycle.d.ts +0 -8
  424. package/dist/core/memory/memory-lifecycle.js +0 -55
  425. package/dist/core/memory/memory-manager.d.ts +0 -15
  426. package/dist/core/memory/memory-manager.js +0 -46
  427. package/dist/core/memory/migrate.d.ts +0 -21
  428. package/dist/core/memory/migrate.js +0 -134
  429. package/dist/core/memory/normalization.d.ts +0 -22
  430. package/dist/core/memory/normalization.js +0 -26
  431. package/dist/core/memory/progressive-disclosure.d.ts +0 -43
  432. package/dist/core/memory/progressive-disclosure.js +0 -280
  433. package/dist/core/memory/query-processor.d.ts +0 -21
  434. package/dist/core/memory/query-processor.js +0 -72
  435. package/dist/core/memory/query-rewriter.d.ts +0 -13
  436. package/dist/core/memory/query-rewriter.js +0 -118
  437. package/dist/core/memory/response-analyzer.d.ts +0 -9
  438. package/dist/core/memory/response-analyzer.js +0 -61
  439. package/dist/core/memory/serialization.d.ts +0 -10
  440. package/dist/core/memory/serialization.js +0 -84
  441. package/dist/core/memory/stats.d.ts +0 -22
  442. package/dist/core/memory/stats.js +0 -138
  443. package/dist/core/memory/telemetry.d.ts +0 -69
  444. package/dist/core/memory/telemetry.js +0 -313
  445. package/dist/core/memory/temporal-facts.d.ts +0 -41
  446. package/dist/core/memory/temporal-facts.js +0 -283
  447. package/dist/core/memory/temporal-parser.d.ts +0 -32
  448. package/dist/core/memory/temporal-parser.js +0 -385
  449. package/dist/core/memory/trigger-detector.d.ts +0 -14
  450. package/dist/core/memory/trigger-detector.js +0 -42
  451. package/dist/core/memory/write-gate.d.ts +0 -54
  452. package/dist/core/memory/write-gate.js +0 -210
  453. package/dist/core/namespaces/index.d.ts +0 -71
  454. package/dist/core/namespaces/index.js +0 -305
  455. package/dist/core/namespaces/uri-parser.d.ts +0 -31
  456. package/dist/core/namespaces/uri-parser.js +0 -74
  457. package/dist/core/obsidian-vault.d.ts +0 -30
  458. package/dist/core/obsidian-vault.js +0 -94
  459. package/dist/core/places/index.d.ts +0 -14
  460. package/dist/core/places/memory-places.d.ts +0 -68
  461. package/dist/core/places/memory-places.js +0 -261
  462. package/dist/core/places/places.d.ts +0 -88
  463. package/dist/core/places/places.js +0 -314
  464. package/dist/core/places/rules.d.ts +0 -74
  465. package/dist/core/places/rules.js +0 -240
  466. package/dist/core/places/walking.d.ts +0 -56
  467. package/dist/core/places/walking.js +0 -121
  468. package/dist/core/projects.d.ts +0 -17
  469. package/dist/core/projects.js +0 -108
  470. package/dist/core/redis.d.ts +0 -11
  471. package/dist/core/redis.js +0 -69
  472. package/dist/core/responses.d.ts +0 -96
  473. package/dist/core/responses.js +0 -122
  474. package/dist/core/scheduler/cron-scheduler.d.ts +0 -32
  475. package/dist/core/scheduler/cron-scheduler.js +0 -332
  476. package/dist/core/scheduler/heartbeat.d.ts +0 -11
  477. package/dist/core/scheduler/heartbeat.js +0 -73
  478. package/dist/core/scheduler/index.d.ts +0 -8
  479. package/dist/core/scheduler/job-runner.d.ts +0 -11
  480. package/dist/core/scheduler/job-runner.js +0 -164
  481. package/dist/core/search/conversations.d.ts +0 -25
  482. package/dist/core/search/conversations.js +0 -110
  483. package/dist/core/search/entities.d.ts +0 -12
  484. package/dist/core/search/entities.js +0 -31
  485. package/dist/core/search/folder-context.d.ts +0 -25
  486. package/dist/core/search/folder-context.js +0 -119
  487. package/dist/core/search/graph-boost.d.ts +0 -7
  488. package/dist/core/search/graph-boost.js +0 -23
  489. package/dist/core/search/index.d.ts +0 -4
  490. package/dist/core/search/qmd-search.d.ts +0 -61
  491. package/dist/core/search/qmd-search.js +0 -178
  492. package/dist/core/security/encrypt.d.ts +0 -6
  493. package/dist/core/security/encrypt.js +0 -47
  494. package/dist/core/security/governance.d.ts +0 -26
  495. package/dist/core/security/governance.js +0 -79
  496. package/dist/core/security/privacy.d.ts +0 -23
  497. package/dist/core/security/privacy.js +0 -82
  498. package/dist/core/security/secret-detector.d.ts +0 -32
  499. package/dist/core/security/secret-detector.js +0 -88
  500. package/dist/core/session/auto-load.d.ts +0 -6
  501. package/dist/core/session/auto-load.js +0 -119
  502. package/dist/core/session/index.d.ts +0 -7
  503. package/dist/core/session/self-iteration-job.d.ts +0 -20
  504. package/dist/core/session/self-iteration-job.js +0 -282
  505. package/dist/core/session/session-hooks.d.ts +0 -18
  506. package/dist/core/session/session-hooks.js +0 -58
  507. package/dist/core/session/types.d.ts +0 -26
  508. package/dist/core/session/types.js +0 -10
  509. package/dist/core/session-hooks/self-iteration-job.d.ts +0 -20
  510. package/dist/core/session-hooks/self-iteration-job.js +0 -282
  511. package/dist/core/session-hooks/session-hooks.d.ts +0 -18
  512. package/dist/core/session-hooks/session-hooks.js +0 -58
  513. package/dist/core/snapshots/cleanup.d.ts +0 -9
  514. package/dist/core/snapshots/comparison.d.ts +0 -19
  515. package/dist/core/snapshots/comparison.js +0 -43
  516. package/dist/core/snapshots/creation.d.ts +0 -19
  517. package/dist/core/snapshots/creation.js +0 -126
  518. package/dist/core/snapshots/retrieval.d.ts +0 -7
  519. package/dist/core/snapshots/retrieval.js +0 -41
  520. package/dist/core/snapshots/stats.d.ts +0 -11
  521. package/dist/core/snapshots/stats.js +0 -52
  522. package/dist/core/snapshots.d.ts +0 -29
  523. package/dist/core/snapshots.js +0 -220
  524. package/dist/core/storage/cache.d.ts +0 -13
  525. package/dist/core/storage/cache.js +0 -202
  526. package/dist/core/storage/database.d.ts +0 -12
  527. package/dist/core/storage/database.js +0 -12
  528. package/dist/core/summarization/cleanup.d.ts +0 -9
  529. package/dist/core/summarization/queries.d.ts +0 -9
  530. package/dist/core/summarization/queries.js +0 -28
  531. package/dist/core/summarization/stats.d.ts +0 -14
  532. package/dist/core/summarization/stats.js +0 -52
  533. package/dist/core/summarization/strategies.d.ts +0 -24
  534. package/dist/core/summarization/strategies.js +0 -28
  535. package/dist/core/summarization.d.ts +0 -37
  536. package/dist/core/summarization.js +0 -188
  537. package/dist/core/sync/qmd-sync.d.ts +0 -94
  538. package/dist/core/sync/qmd-sync.js +0 -201
  539. package/dist/core/temporal-facts.d.ts +0 -54
  540. package/dist/core/temporal-facts.js +0 -193
  541. package/dist/core/toon.d.ts +0 -43
  542. package/dist/core/toon.js +0 -160
  543. package/dist/core/tracing/collector.d.ts +0 -111
  544. package/dist/core/tracing/collector.js +0 -350
  545. package/dist/core/tracing/visualizer.d.ts +0 -32
  546. package/dist/core/tracing/visualizer.js +0 -165
  547. package/dist/core/utils/cleanup-operations.d.ts +0 -13
  548. package/dist/core/utils/cleanup-operations.js +0 -44
  549. package/dist/core/utils/content-extraction.d.ts +0 -19
  550. package/dist/core/utils/content-extraction.js +0 -75
  551. package/dist/core/utils/filter-builder.d.ts +0 -13
  552. package/dist/core/utils/filter-builder.js +0 -44
  553. package/dist/core/utils/history-traversal.d.ts +0 -13
  554. package/dist/core/utils/history-traversal.js +0 -50
  555. package/dist/core/utils/memory-operations.d.ts +0 -17
  556. package/dist/core/utils/memory-operations.js +0 -43
  557. package/dist/core/utils/query-operations.d.ts +0 -18
  558. package/dist/core/utils/query-operations.js +0 -65
  559. package/dist/core/utils/summarization-helpers.d.ts +0 -21
  560. package/dist/core/utils/summarization-helpers.js +0 -38
  561. package/dist/core/utils/temporal-queries.d.ts +0 -13
  562. package/dist/core/utils/temporal-queries.js +0 -27
  563. package/dist/core/utils/vector-operations.d.ts +0 -71
  564. package/dist/core/utils/version-management.d.ts +0 -9
  565. package/dist/core/utils/version-management.js +0 -61
  566. package/dist/core/worker.d.ts +0 -82
  567. package/dist/core/worker.js +0 -272
  568. package/dist/db/adapter.d.ts +0 -7
  569. package/dist/db/adapter.js +0 -175
  570. package/dist/db/bootstrap.d.ts +0 -9
  571. package/dist/db/drizzle/schema-sqlite.d.ts +0 -4837
  572. package/dist/db/drizzle/schema-sqlite.js +0 -684
  573. package/dist/db/drizzle/schema.d.ts +0 -4082
  574. package/dist/db/drizzle/schema.js +0 -770
  575. package/dist/db/drizzle.config.d.ts +0 -3
  576. package/dist/db/drizzle.config.js +0 -12
  577. package/dist/db/index.d.ts +0 -7
  578. package/dist/db/index.js +0 -89
  579. package/dist/db/neon.d.ts +0 -8
  580. package/dist/db/neon.js +0 -20
  581. package/dist/db/schema/index.d.ts +0 -40
  582. package/dist/db/schema/index.js +0 -105
  583. package/dist/db/schema/tables/context-sessions.d.ts +0 -9
  584. package/dist/db/schema/tables/context-sessions.js +0 -37
  585. package/dist/db/schema/tables/conversations.d.ts +0 -9
  586. package/dist/db/schema/tables/conversations.js +0 -47
  587. package/dist/db/schema/tables/core-memory.d.ts +0 -9
  588. package/dist/db/schema/tables/core-memory.js +0 -41
  589. package/dist/db/schema/tables/entities.d.ts +0 -9
  590. package/dist/db/schema/tables/entities.js +0 -39
  591. package/dist/db/schema/tables/entity-relations.d.ts +0 -9
  592. package/dist/db/schema/tables/entity-relations.js +0 -31
  593. package/dist/db/schema/tables/learnings.d.ts +0 -9
  594. package/dist/db/schema/tables/learnings.js +0 -66
  595. package/dist/db/schema/tables/memories.d.ts +0 -9
  596. package/dist/db/schema/tables/memories.js +0 -161
  597. package/dist/db/schema/tables/memory-associations.d.ts +0 -9
  598. package/dist/db/schema/tables/memory-associations.js +0 -39
  599. package/dist/db/schema/tables/memory-hash-cache.d.ts +0 -9
  600. package/dist/db/schema/tables/memory-hash-cache.js +0 -29
  601. package/dist/db/schema/tables/memory-merge-history.d.ts +0 -9
  602. package/dist/db/schema/tables/memory-merge-history.js +0 -33
  603. package/dist/db/schema/tables/memory-merge-proposals.d.ts +0 -9
  604. package/dist/db/schema/tables/memory-merge-proposals.js +0 -39
  605. package/dist/db/schema/tables/messages.d.ts +0 -9
  606. package/dist/db/schema/tables/messages.js +0 -41
  607. package/dist/db/schema/tables/namespaces.d.ts +0 -9
  608. package/dist/db/schema/tables/namespaces.js +0 -37
  609. package/dist/db/schema/tables/projects.d.ts +0 -9
  610. package/dist/db/schema/tables/projects.js +0 -31
  611. package/dist/db/schema/tables/users.d.ts +0 -9
  612. package/dist/db/schema/tables/users.js +0 -27
  613. package/dist/db/schema.d.ts +0 -3
  614. package/dist/db/schema.js +0 -11
  615. package/dist/db/supabase.d.ts +0 -9
  616. package/dist/db/supabase.js +0 -24
  617. package/dist/index.d.ts +0 -7
  618. package/dist/index.js +0 -1677
  619. package/dist/vendor/sql.js/sql-wasm.wasm +0 -0
  620. package/dist/webui/server.d.ts +0 -5
  621. package/dist/webui/server.js +0 -642
  622. package/generated/mcp/manifest.json +0 -23
  623. package/generated/mcp/mcp-servers.json +0 -25
  624. package/generated/mcp/mcporter.json +0 -34
  625. package/generated/mcp/openclaw-memory-qmd.json +0 -17
  626. package/generated/mcp/runtime.json +0 -12
  627. package/scripts/README.md +0 -60
  628. package/scripts/build-release.sh +0 -36
  629. package/scripts/check-secrets.js +0 -132
  630. package/scripts/copy-runtime-assets.mjs +0 -26
  631. package/scripts/generate-mcp.mjs +0 -264
  632. package/scripts/github-release.sh +0 -77
  633. package/scripts/init-dirs.mjs +0 -13
  634. package/scripts/install-claude-code.sh +0 -85
  635. package/scripts/install-cursor.sh +0 -56
  636. package/scripts/install-hooks.sh +0 -73
  637. package/scripts/install-interactive.mjs +0 -357
  638. package/scripts/install-opencode.sh +0 -75
  639. package/scripts/install-plugin.mjs +0 -415
  640. package/scripts/install-windsurf.sh +0 -67
  641. package/scripts/remote-preflight.mjs +0 -62
  642. package/scripts/squish-fallback.mjs +0 -132
  643. package/scripts/test-interactive.mjs +0 -131
  644. package/scripts/verify-mcp.mjs +0 -214
  645. package/skills/squish-memory/scripts/install.mjs +0 -335
  646. package/skills/squish-memory/write_skill.js +0 -2
@@ -0,0 +1,200 @@
1
+ import { logger } from '../logger.js';
2
+ import { config } from '../../config.js';
3
+
4
+ export interface MultimodalInput {
5
+ text?: string;
6
+ image?: Buffer | string;
7
+ video?: string;
8
+ }
9
+
10
+ export interface GoogleMultimodalResponse {
11
+ embedding: number[];
12
+ textEmbedding?: number[];
13
+ imageEmbedding?: number[];
14
+ videoEmbedding?: number[];
15
+ }
16
+
17
+ export async function getGoogleMultimodalEmbedding(
18
+ input: MultimodalInput
19
+ ): Promise<GoogleMultimodalResponse | null> {
20
+ if (!config.googleCloudApiKey && !config.googleCloudProject) {
21
+ logger.debug('Google Cloud credentials not configured');
22
+ return null;
23
+ }
24
+
25
+ if (!config.googleEmbeddingModel) {
26
+ logger.debug('Google embedding model not configured');
27
+ return null;
28
+ }
29
+
30
+ try {
31
+ const endpoint = config.googleCloudLocation === 'global'
32
+ ? `https://aiplatform.googleapis.com/v1/projects/${config.googleCloudProject}/locations/${config.googleCloudLocation}/publishers/google/models/${config.googleEmbeddingModel}:predict`
33
+ : `https://${config.googleCloudLocation}-aiplatform.googleapis.com/v1/projects/${config.googleCloudProject}/locations/${config.googleCloudLocation}/publishers/google/models/${config.googleEmbeddingModel}:predict`;
34
+
35
+ const instances: any[] = [];
36
+
37
+ if (input.text) {
38
+ instances.push({ text: input.text });
39
+ }
40
+
41
+ if (input.image) {
42
+ const imageBytes = typeof input.image === 'string'
43
+ ? input.image
44
+ : input.image.toString('base64');
45
+
46
+ instances.push({
47
+ image: {
48
+ bytesBase64Encoded: imageBytes,
49
+ },
50
+ });
51
+ }
52
+
53
+ if (input.video) {
54
+ instances.push({
55
+ video: {
56
+ gcsUri: input.video,
57
+ },
58
+ });
59
+ }
60
+
61
+ if (instances.length === 0) {
62
+ return null;
63
+ }
64
+
65
+ const response = await fetch(endpoint, {
66
+ method: 'POST',
67
+ headers: {
68
+ 'Content-Type': 'application/json',
69
+ 'Authorization': `Bearer ${await getGoogleAccessToken()}`,
70
+ },
71
+ body: JSON.stringify({
72
+ instances,
73
+ parameters: {
74
+ dimension: 1408,
75
+ },
76
+ }),
77
+ });
78
+
79
+ if (!response.ok) {
80
+ const errorText = await response.text();
81
+ logger.warn(`Google Multimodal embeddings failed: ${response.status} ${errorText}`);
82
+ return null;
83
+ }
84
+
85
+ const data = await response.json() as { predictions?: any[] };
86
+ const predictions = data.predictions || [];
87
+
88
+ const result: GoogleMultimodalResponse = {
89
+ embedding: predictions[0]?.embedding || [],
90
+ };
91
+
92
+ if (input.text && predictions[0]?.textEmbedding) {
93
+ result.textEmbedding = predictions[0].textEmbedding;
94
+ }
95
+
96
+ if (input.image && predictions[0]?.imageEmbedding) {
97
+ result.imageEmbedding = predictions[0].imageEmbedding;
98
+ }
99
+
100
+ if (input.video && predictions[0]?.videoEmbedding) {
101
+ result.videoEmbedding = predictions[0].videoEmbedding;
102
+ }
103
+
104
+ return result.embedding.length > 0 ? result : null;
105
+ } catch (error) {
106
+ logger.error('Google Multimodal embedding error:', error);
107
+ return null;
108
+ }
109
+ }
110
+
111
+ let cachedAccessToken: string | null = null;
112
+ let tokenExpiry: number = 0;
113
+
114
+ async function getGoogleAccessToken(): Promise<string> {
115
+ if (config.googleCloudApiKey) {
116
+ return config.googleCloudApiKey;
117
+ }
118
+
119
+ if (cachedAccessToken && Date.now() < tokenExpiry) {
120
+ return cachedAccessToken;
121
+ }
122
+
123
+ if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
124
+ throw new Error('Google Application Credentials not set');
125
+ }
126
+
127
+ try {
128
+ const credentials = JSON.parse(
129
+ await import('fs').then(fs =>
130
+ fs.promises.readFile(process.env.GOOGLE_APPLICATION_CREDENTIALS!, 'utf-8')
131
+ )
132
+ );
133
+
134
+ const now = Math.floor(Date.now() / 1000);
135
+ const jwt = await createJWT(credentials);
136
+
137
+ const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
138
+ method: 'POST',
139
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
140
+ body: new URLSearchParams({
141
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
142
+ assertion: jwt,
143
+ }),
144
+ });
145
+
146
+ if (!tokenResponse.ok) {
147
+ throw new Error('Failed to get Google access token');
148
+ }
149
+
150
+ const tokenData = await tokenResponse.json() as { access_token: string; expires_in: number };
151
+ cachedAccessToken = tokenData.access_token;
152
+ tokenExpiry = now + tokenData.expires_in - 60;
153
+
154
+ return cachedAccessToken;
155
+ } catch (error) {
156
+ logger.error('Failed to get Google access token:', error);
157
+ throw error;
158
+ }
159
+ }
160
+
161
+ async function createJWT(credentials: any): Promise<string> {
162
+ const now = Math.floor(Date.now() / 1000);
163
+
164
+ const header = {
165
+ alg: 'RS256',
166
+ typ: 'JWT',
167
+ };
168
+
169
+ const payload = {
170
+ iss: credentials.client_email,
171
+ sub: credentials.client_email,
172
+ aud: 'https://oauth2.googleapis.com/token',
173
+ iat: now,
174
+ exp: now + 3600,
175
+ scope: 'https://www.googleapis.com/auth/cloud-platform',
176
+ };
177
+
178
+ const crypto = await import('crypto');
179
+
180
+ const encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64url');
181
+ const encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64url');
182
+
183
+ const signatureInput = `${encodedHeader}.${encodedPayload}`;
184
+
185
+ const sign = crypto.createSign('RSA-SHA256');
186
+ sign.update(signatureInput);
187
+ const signature = sign.sign(credentials.private_key, 'base64url');
188
+
189
+ return `${signatureInput}.${signature}`;
190
+ }
191
+
192
+ export function isMultimodalInput(input: any): input is MultimodalInput {
193
+ return (
194
+ typeof input === 'object' &&
195
+ (typeof input.text === 'string' ||
196
+ Buffer.isBuffer(input.image) ||
197
+ typeof input.image === 'string' ||
198
+ typeof input.video === 'string')
199
+ );
200
+ }
@@ -1,11 +1,12 @@
1
- /**
2
- * Utility functions for local embeddings
3
- * Note: Actual embedding generation is in core/embeddings.ts
4
- */
5
- import { cosineSimilarity as vectorCosineSimilarity } from './utils/vector-operations.js';
6
- /**
7
- * @deprecated Use cosineSimilarity from core/utils/vector-operations.ts directly.
8
- * This re-export is for backward compatibility and will be removed in v1.2.0.
9
- */
10
- export const cosineSimilarity = vectorCosineSimilarity;
11
- //# sourceMappingURL=local-embeddings.js.map
1
+ /**
2
+ * Utility functions for local embeddings
3
+ * Note: Actual embedding generation is in core/embeddings.ts
4
+ */
5
+
6
+ import { cosineSimilarity as vectorCosineSimilarity } from '../utils/vector-operations.js';
7
+
8
+ /**
9
+ * @deprecated Use cosineSimilarity from core/utils/vector-operations.ts directly.
10
+ * This re-export is for backward compatibility and will be removed in v1.2.0.
11
+ */
12
+ export const cosineSimilarity = vectorCosineSimilarity;
@@ -0,0 +1,495 @@
1
+ /**
2
+ * QMD MCP Client
3
+ *
4
+ * Connects to QMD (Quick Markdown Search) MCP server for hybrid search capabilities.
5
+ * QMD provides BM25 full-text search, vector semantic search, and LLM re-ranking.
6
+ *
7
+ * Installation: bun install -g qmd
8
+ * GitHub: https://github.com/tobi/qmd
9
+ *
10
+ * QMD MCP Tools:
11
+ * - qmd_search: Fast BM25 keyword search
12
+ * - qmd_vsearch: Semantic vector search
13
+ * - qmd_query: Hybrid search with re-ranking (best quality)
14
+ * - qmd_get: Retrieve document by path or docid
15
+ * - qmd_multi_get: Retrieve multiple documents
16
+ * - qmd_status: Index health and collection info
17
+ */
18
+
19
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
20
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
21
+ import { spawn } from 'child_process';
22
+ import { logger } from '../logger';
23
+
24
+ export interface QMDSearchOptions {
25
+ query: string;
26
+ collection?: string;
27
+ limit?: number;
28
+ minScore?: number;
29
+ }
30
+
31
+ export interface QMDSearchResult {
32
+ docid: string;
33
+ path: string;
34
+ title: string;
35
+ context: string;
36
+ score: number;
37
+ snippet: string;
38
+ }
39
+
40
+ export interface QMDStatusResult {
41
+ indexHealth: string;
42
+ collections: Array<{
43
+ name: string;
44
+ path: string;
45
+ documentCount: number;
46
+ }>;
47
+ }
48
+
49
+ export interface QMDGetOptions {
50
+ pathOrDocid: string;
51
+ full?: boolean;
52
+ maxBytes?: number;
53
+ }
54
+
55
+ /**
56
+ * QMD MCP Client class
57
+ *
58
+ * Manages connection to QMD MCP server and provides methods for
59
+ * search, document retrieval, and status checking.
60
+ */
61
+ export class QMDClient {
62
+ private client: Client | null = null;
63
+ private transport: StdioClientTransport | null = null;
64
+ private connected = false;
65
+ private connecting = false;
66
+
67
+ /**
68
+ * Check if QMD is installed on the system
69
+ */
70
+ async checkQMDInstalled(): Promise<boolean> {
71
+ return new Promise((resolve) => {
72
+ const process = spawn('qmd', ['--version'], {
73
+ stdio: 'ignore',
74
+ shell: true
75
+ });
76
+
77
+ process.on('close', (code) => {
78
+ resolve(code === 0);
79
+ });
80
+
81
+ process.on('error', () => {
82
+ resolve(false);
83
+ });
84
+
85
+ // Timeout after 5 seconds
86
+ setTimeout(() => {
87
+ process.kill();
88
+ resolve(false);
89
+ }, 5000);
90
+ });
91
+ }
92
+
93
+ /**
94
+ * Connect to QMD MCP server
95
+ * QMD must be installed: bun install -g qmd
96
+ */
97
+ async connect(): Promise<boolean> {
98
+ if (this.connected || this.connecting) {
99
+ return this.connected;
100
+ }
101
+
102
+ this.connecting = true;
103
+
104
+ try {
105
+ // Check if QMD is installed
106
+ const installed = await this.checkQMDInstalled();
107
+ if (!installed) {
108
+ logger.warn('QMD is not installed. Install with: bun install -g qmd');
109
+ this.connecting = false;
110
+ return false;
111
+ }
112
+
113
+ this.transport = new StdioClientTransport({
114
+ command: 'qmd',
115
+ args: ['mcp'],
116
+ stderr: 'inherit'
117
+ });
118
+
119
+ this.client = new Client(
120
+ { name: 'squish-qmd-client', version: '1.0.0' },
121
+ { capabilities: {} }
122
+ );
123
+
124
+ await this.client.connect(this.transport);
125
+ this.connected = true;
126
+ this.connecting = false;
127
+ logger.info('Connected to QMD MCP server');
128
+ return true;
129
+ } catch (error) {
130
+ logger.warn(`QMD MCP connection failed: ${error}`);
131
+ this.connected = false;
132
+ this.connecting = false;
133
+ return false;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Check if QMD is available
139
+ */
140
+ async isAvailable(): Promise<boolean> {
141
+ if (this.connected && this.client) {
142
+ return true;
143
+ }
144
+ return await this.connect();
145
+ }
146
+
147
+ /**
148
+ * Fast BM25 keyword search
149
+ * Uses SQLite FTS5 for fast full-text search
150
+ */
151
+ async search(options: QMDSearchOptions): Promise<QMDSearchResult[]> {
152
+ if (!this.connected || !this.client) {
153
+ throw new Error('QMD client not connected');
154
+ }
155
+
156
+ const result = await this.client.callTool({
157
+ name: 'qmd_search',
158
+ arguments: {
159
+ query: options.query,
160
+ collection: options.collection,
161
+ n: options.limit || 10,
162
+ minScore: options.minScore || 0
163
+ }
164
+ }) as any;
165
+
166
+ return this.parseSearchResults(result);
167
+ }
168
+
169
+ /**
170
+ * Semantic vector search
171
+ * Uses embedding-based similarity search
172
+ */
173
+ async vsearch(options: QMDSearchOptions): Promise<QMDSearchResult[]> {
174
+ if (!this.connected || !this.client) {
175
+ throw new Error('QMD client not connected');
176
+ }
177
+
178
+ const result = await this.client.callTool({
179
+ name: 'qmd_vsearch',
180
+ arguments: {
181
+ query: options.query,
182
+ collection: options.collection,
183
+ n: options.limit || 10,
184
+ minScore: options.minScore || 0
185
+ }
186
+ }) as any;
187
+
188
+ return this.parseSearchResults(result);
189
+ }
190
+
191
+ /**
192
+ * Hybrid search with re-ranking (best quality)
193
+ * Combines BM25 + vector search + LLM re-ranking
194
+ */
195
+ async query(options: QMDSearchOptions): Promise<QMDSearchResult[]> {
196
+ if (!this.connected || !this.client) {
197
+ throw new Error('QMD client not connected');
198
+ }
199
+
200
+ const result = await this.client.callTool({
201
+ name: 'qmd_query',
202
+ arguments: {
203
+ query: options.query,
204
+ collection: options.collection,
205
+ n: options.limit || 10,
206
+ minScore: options.minScore || 0
207
+ }
208
+ }) as any;
209
+
210
+ return this.parseSearchResults(result);
211
+ }
212
+
213
+ /**
214
+ * Get QMD index status and collection info
215
+ */
216
+ async status(): Promise<QMDStatusResult | null> {
217
+ if (!this.connected || !this.client) {
218
+ return null;
219
+ }
220
+
221
+ try {
222
+ const result = await this.client.callTool({
223
+ name: 'qmd_status',
224
+ arguments: {}
225
+ }) as any;
226
+
227
+ return this.parseStatusResult(result);
228
+ } catch (error) {
229
+ logger.debug(`QMD status check failed: ${error}`);
230
+ return null;
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Get document by path or docid
236
+ */
237
+ async get(options: QMDGetOptions): Promise<string> {
238
+ if (!this.connected || !this.client) {
239
+ throw new Error('QMD client not connected');
240
+ }
241
+
242
+ const args: Record<string, any> = {
243
+ path: options.pathOrDocid
244
+ };
245
+
246
+ if (options.full !== undefined) {
247
+ args.full = options.full;
248
+ }
249
+ if (options.maxBytes !== undefined) {
250
+ args['max-bytes'] = options.maxBytes;
251
+ }
252
+
253
+ const result = await this.client.callTool({
254
+ name: 'qmd_get',
255
+ arguments: args
256
+ }) as any;
257
+
258
+ return this.parseGetResult(result);
259
+ }
260
+
261
+ /**
262
+ * Get multiple documents by glob pattern or list
263
+ */
264
+ async multiGet(patternOrList: string | string[], options?: { maxBytes?: number; limit?: number }): Promise<string[]> {
265
+ if (!this.connected || !this.client) {
266
+ throw new Error('QMD client not connected');
267
+ }
268
+
269
+ const args: Record<string, any> = {
270
+ pattern: Array.isArray(patternOrList) ? patternOrList.join(',') : patternOrList
271
+ };
272
+
273
+ if (options?.maxBytes !== undefined) {
274
+ args['max-bytes'] = options.maxBytes;
275
+ }
276
+ if (options?.limit !== undefined) {
277
+ args.l = options.limit;
278
+ }
279
+
280
+ const result = await this.client.callTool({
281
+ name: 'qmd_multi_get',
282
+ arguments: args
283
+ }) as any;
284
+
285
+ return this.parseMultiGetResult(result);
286
+ }
287
+
288
+ /**
289
+ * Disconnect from QMD MCP server
290
+ */
291
+ async disconnect(): Promise<void> {
292
+ if (this.client) {
293
+ try {
294
+ await this.client.close();
295
+ } catch (error) {
296
+ logger.debug(`Error closing QMD client: ${error}`);
297
+ }
298
+ this.connected = false;
299
+ this.client = null;
300
+ this.transport = null;
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Parse search results from QMD response
306
+ */
307
+ private parseSearchResults(result: any): QMDSearchResult[] {
308
+ if (!result || !result.content) {
309
+ return [];
310
+ }
311
+
312
+ const content = result.content;
313
+
314
+ // Handle text output format
315
+ if (typeof content === 'string') {
316
+ return this.parseTextSearchResults(content);
317
+ }
318
+
319
+ // Handle array content format
320
+ if (Array.isArray(content)) {
321
+ const textContent = content
322
+ .filter((item: any) => item.type === 'text')
323
+ .map((item: any) => item.text)
324
+ .join('\n');
325
+ return this.parseTextSearchResults(textContent);
326
+ }
327
+
328
+ return [];
329
+ }
330
+
331
+ /**
332
+ * Parse QMD's text output format into structured results
333
+ */
334
+ private parseTextSearchResults(text: string): QMDSearchResult[] {
335
+ const results: QMDSearchResult[] = [];
336
+ const lines = text.split('\n');
337
+
338
+ let currentResult: Partial<QMDSearchResult> | null = null;
339
+
340
+ for (const line of lines) {
341
+ // Match path line: "docs/guide.md:42 #a1b2c3"
342
+ const pathMatch = line.match(/^([^\s:]+):(\d+)\s+([#a-zA-Z0-9]+)?/);
343
+ if (pathMatch) {
344
+ if (currentResult && currentResult.path) {
345
+ results.push(this.finalizeResult(currentResult));
346
+ }
347
+ currentResult = {
348
+ path: pathMatch[1],
349
+ docid: pathMatch[3] || '',
350
+ score: 0,
351
+ snippet: ''
352
+ };
353
+ continue;
354
+ }
355
+
356
+ // Match score line: "Score: 93%"
357
+ const scoreMatch = line.match(/^Score:\s+(\d+)%/);
358
+ if (scoreMatch && currentResult) {
359
+ currentResult.score = parseInt(scoreMatch[1]) / 100;
360
+ continue;
361
+ }
362
+
363
+ // Match title line: "Title: Some Title"
364
+ const titleMatch = line.match(/^Title:\s+(.+)/);
365
+ if (titleMatch && currentResult) {
366
+ currentResult.title = titleMatch[1];
367
+ continue;
368
+ }
369
+
370
+ // Match context line: "Context: Some context"
371
+ const contextMatch = line.match(/^Context:\s+(.+)/);
372
+ if (contextMatch && currentResult) {
373
+ currentResult.context = contextMatch[1];
374
+ continue;
375
+ }
376
+
377
+ // Collect snippet content
378
+ if (currentResult && line.trim() && !line.startsWith('---')) {
379
+ currentResult.snippet += line + '\n';
380
+ }
381
+ }
382
+
383
+ // Don't forget the last result
384
+ if (currentResult && currentResult.path) {
385
+ results.push(this.finalizeResult(currentResult));
386
+ }
387
+
388
+ return results;
389
+ }
390
+
391
+ /**
392
+ * Finalize a parsed result with defaults
393
+ */
394
+ private finalizeResult(result: Partial<QMDSearchResult>): QMDSearchResult {
395
+ return {
396
+ path: result.path || '',
397
+ docid: result.docid || '',
398
+ title: result.title || result.path?.split('/').pop() || '',
399
+ context: result.context || '',
400
+ score: result.score || 0,
401
+ snippet: (result.snippet || '').trim()
402
+ };
403
+ }
404
+
405
+ /**
406
+ * Parse status result
407
+ */
408
+ private parseStatusResult(result: any): QMDStatusResult | null {
409
+ if (!result || !result.content) {
410
+ return null;
411
+ }
412
+
413
+ const content = result.content;
414
+ if (typeof content === 'string') {
415
+ try {
416
+ return JSON.parse(content);
417
+ } catch {
418
+ return null;
419
+ }
420
+ }
421
+
422
+ if (Array.isArray(content)) {
423
+ const textContent = content
424
+ .filter((item: any) => item.type === 'text')
425
+ .map((item: any) => item.text)
426
+ .join('');
427
+ try {
428
+ return JSON.parse(textContent);
429
+ } catch {
430
+ return null;
431
+ }
432
+ }
433
+
434
+ return null;
435
+ }
436
+
437
+ /**
438
+ * Parse get result
439
+ */
440
+ private parseGetResult(result: any): string {
441
+ if (!result || !result.content) {
442
+ return '';
443
+ }
444
+
445
+ const content = result.content;
446
+ if (typeof content === 'string') {
447
+ return content;
448
+ }
449
+
450
+ if (Array.isArray(content)) {
451
+ return content
452
+ .filter((item: any) => item.type === 'text')
453
+ .map((item: any) => item.text)
454
+ .join('\n');
455
+ }
456
+
457
+ return '';
458
+ }
459
+
460
+ /**
461
+ * Parse multi-get result
462
+ */
463
+ private parseMultiGetResult(result: any): string[] {
464
+ const text = this.parseGetResult(result);
465
+ if (!text) {
466
+ return [];
467
+ }
468
+
469
+ // Split by document separators and return individual documents
470
+ return text.split(/\n---+\n/).filter(doc => doc.trim());
471
+ }
472
+ }
473
+
474
+ // Singleton instance
475
+ let qmdClientInstance: QMDClient | null = null;
476
+
477
+ /**
478
+ * Get the singleton QMD client instance
479
+ */
480
+ export async function getQMDClient(): Promise<QMDClient> {
481
+ if (!qmdClientInstance) {
482
+ qmdClientInstance = new QMDClient();
483
+ }
484
+ return qmdClientInstance;
485
+ }
486
+
487
+ /**
488
+ * Reset the singleton QMD client (useful for testing)
489
+ */
490
+ export function resetQMDClient(): void {
491
+ if (qmdClientInstance) {
492
+ qmdClientInstance.disconnect().catch(() => {});
493
+ qmdClientInstance = null;
494
+ }
495
+ }