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,192 @@
1
+ /**
2
+ * Walking Interface - Sequential memory retrieval through places
3
+ *
4
+ * Implements place walking through memory places:
5
+ * - Walk single place to get memories in order
6
+ * - Walk all places for full tour
7
+ * - Token budget handling with TOON compression
8
+ */
9
+
10
+ import { getDb } from '../../db/index.js';
11
+ import { getSchema } from '../../db/schema.js';
12
+ import { getProjectPlaces, type Place } from './places.js';
13
+ import { getPlaceMemories } from './memory-places.js';
14
+ import { getMemory } from '../memory/memories.js';
15
+ import { compressForContext, isCompressed } from '../compression.js';
16
+ import { logger } from '../logger.js';
17
+
18
+ export interface WalkOptions {
19
+ tokenBudget?: number; // Max tokens (default: 170)
20
+ maxMemoriesPerPlace?: number;
21
+ includePurpose?: boolean;
22
+ compressWithCompression?: boolean;
23
+ }
24
+
25
+ export interface WalkResult {
26
+ place: Place;
27
+ memories: MemorySummary[];
28
+ totalTokens: number;
29
+ truncated: boolean;
30
+ }
31
+
32
+ export interface MemorySummary {
33
+ id: string;
34
+ content: string;
35
+ type: string;
36
+ tags: string[];
37
+ createdAt: string;
38
+ }
39
+
40
+ /**
41
+ * Walk through a single place
42
+ */
43
+ export async function walkPlace(
44
+ projectId: string,
45
+ placeType: string,
46
+ options: WalkOptions = {}
47
+ ): Promise<WalkResult | null> {
48
+ const { tokenBudget = 170, maxMemoriesPerPlace = 10, includePurpose = true, compressWithCompression = false } = options;
49
+
50
+ // Get the place
51
+ const places = await getProjectPlaces(projectId);
52
+ const place = places.find(p => p.placeType === placeType);
53
+
54
+ if (!place) {
55
+ logger.warn(`[Walking] Place not found: ${placeType}`);
56
+ return null;
57
+ }
58
+
59
+ // Get memory IDs for this place
60
+ const memoryIds = await getPlaceMemories(place.id, maxMemoriesPerPlace);
61
+
62
+ // Get full memories
63
+ const memories: MemorySummary[] = [];
64
+ let totalTokens = 0;
65
+
66
+ for (const memoryId of memoryIds) {
67
+ const memory = await getMemory(memoryId);
68
+ if (!memory) continue;
69
+
70
+ let content = memory.content || '';
71
+
72
+ // Compress with TOON if requested
73
+ if (compressWithCompression && content) {
74
+ content = compressForContext(content);
75
+ }
76
+
77
+ const tokenEstimate = Math.ceil(content.length / 4); // rough token estimate
78
+
79
+ if (totalTokens + tokenEstimate > tokenBudget) {
80
+ // Would exceed budget - stop adding
81
+ break;
82
+ }
83
+
84
+ memories.push({
85
+ id: memory.id,
86
+ content,
87
+ type: memory.type,
88
+ tags: memory.tags || [],
89
+ createdAt: memory.createdAt || '',
90
+ });
91
+
92
+ totalTokens += tokenEstimate;
93
+ }
94
+
95
+ return {
96
+ place,
97
+ memories,
98
+ totalTokens,
99
+ truncated: memories.length < memoryIds.length,
100
+ };
101
+ }
102
+
103
+ /**
104
+ * Walk through all places in sort order
105
+ */
106
+ export async function walkAllPlaces(
107
+ projectId: string,
108
+ options: WalkOptions = {}
109
+ ): Promise<WalkResult[]> {
110
+ const places = await getProjectPlaces(projectId);
111
+ const results: WalkResult[] = [];
112
+
113
+ for (const place of places) {
114
+ const walkResult = await walkPlace(projectId, place.placeType, options);
115
+ if (walkResult && walkResult.memories.length > 0) {
116
+ results.push(walkResult);
117
+ }
118
+ }
119
+
120
+ logger.info(`[Walking] Walked ${results.length} places for project ${projectId}`);
121
+ return results;
122
+ }
123
+
124
+ /**
125
+ * Quick tour - just place names and purposes (minimal tokens)
126
+ */
127
+ export async function quickTour(projectId: string): Promise<{
128
+ places: { name: string; purpose: string; memoryCount: number }[];
129
+ totalMemories: number;
130
+ }> {
131
+ const places = await getProjectPlaces(projectId);
132
+
133
+ return {
134
+ places: places.map(p => ({
135
+ name: p.name,
136
+ purpose: p.purpose || '',
137
+ memoryCount: p.memoryCount,
138
+ })),
139
+ totalMemories: places.reduce((sum, p) => sum + p.memoryCount, 0),
140
+ };
141
+ }
142
+
143
+ /**
144
+ * Get context summary for a place (for injection)
145
+ */
146
+ export async function getPlaceContext(
147
+ projectId: string,
148
+ placeType: string,
149
+ maxTokens: number = 50
150
+ ): Promise<string> {
151
+ const walkResult = await walkPlace(projectId, placeType, {
152
+ tokenBudget: maxTokens,
153
+ compressWithCompression: true,
154
+ });
155
+
156
+ if (!walkResult || walkResult.memories.length === 0) {
157
+ return '';
158
+ }
159
+
160
+ const lines = walkResult.memories.map((m, i) =>
161
+ `${i + 1}. [${m.type}] ${m.content.substring(0, 100)}`
162
+ );
163
+
164
+ return `## ${walkResult.place.name}\n${lines.join('\n')}`;
165
+ }
166
+
167
+ /**
168
+ * Full context for session start (all places)
169
+ */
170
+ export async function getFullWalkingContext(
171
+ projectId: string,
172
+ maxTokens: number = 170
173
+ ): Promise<string> {
174
+ const results = await walkAllPlaces(projectId, {
175
+ tokenBudget: Math.floor(maxTokens / 7), // Distribute across 7 places
176
+ compressWithCompression: true,
177
+ });
178
+
179
+ if (results.length === 0) {
180
+ return 'No memories yet. Start building your spatial memory!';
181
+ }
182
+
183
+ const sections = results.map(r => {
184
+ const lines = r.memories.slice(0, 3).map((m, i) =>
185
+ ` ${i + 1}. ${m.content.substring(0, 60)}...`
186
+ ).join('\n');
187
+
188
+ return `## ${r.place.name}\n${lines}`;
189
+ });
190
+
191
+ return sections.join('\n\n');
192
+ }
package/core/projects ADDED
@@ -0,0 +1,89 @@
1
+ // Deterministic Memory Requirements
2
+ import { eq } from 'drizzle-orm';
3
+ import { getSchema } from '../db/schema.js';
4
+ import { buildMemoryFilters, buildMemoryFiltersPartial } from './utils/filter-builder.js';
5
+ import { executeMemoryQuery, executeMemoryAssertion, MemoryRequirementError } from './utils/query-operations.js';
6
+
7
+ export interface MemoryCriteria {
8
+ tag?: string;
9
+ type?: string;
10
+ types?: string[];
11
+ sector?: string;
12
+ minAge?: number;
13
+ maxAge?: number;
14
+ minConfidence?: number;
15
+ minRelevance?: number;
16
+ projectId?: string;
17
+ agentId?: string;
18
+ visibilityScope?: string;
19
+ }
20
+
21
+ export async function requireMemory(criteria: MemoryCriteria): Promise<any> {
22
+ const schema = await getSchema();
23
+ const filters = buildMemoryFilters(criteria, schema);
24
+
25
+ const memories = await executeMemoryAssertion(
26
+ criteria,
27
+ filters,
28
+ 1,
29
+ 'memory requirement',
30
+ 'Required memory not found'
31
+ );
32
+
33
+ return memories[0];
34
+ }
35
+
36
+ export async function assertMemoryPresent(memoryId: string): Promise<void> {
37
+ const criteria = { memoryId };
38
+ const schema = await getSchema();
39
+ const filters = [eq(schema.memories.id, memoryId)];
40
+
41
+ await executeMemoryAssertion(
42
+ criteria,
43
+ filters,
44
+ 1,
45
+ 'asserting memory presence',
46
+ 'Required memory is not present: ' + memoryId
47
+ );
48
+ }
49
+
50
+ export async function assertMemoryNotPresent(criteria: MemoryCriteria): Promise<void> {
51
+ const schema = await getSchema();
52
+ const filters = buildMemoryFiltersPartial(criteria, schema);
53
+
54
+ await executeMemoryAssertion(
55
+ criteria,
56
+ filters,
57
+ 0,
58
+ 'checking memory non-presence',
59
+ 'Memory should not exist but was found'
60
+ );
61
+ }
62
+
63
+ export async function requireMemories(criteria: MemoryCriteria, minCount: number = 1): Promise<any[]> {
64
+ const schema = await getSchema();
65
+ const filters = buildMemoryFilters(criteria, schema);
66
+
67
+ return executeMemoryAssertion(
68
+ criteria,
69
+ filters,
70
+ minCount,
71
+ 'checking memory requirements',
72
+ `Required ${minCount} memories but found fewer`
73
+ );
74
+ }
75
+
76
+ export async function requireHighConfidenceMemory(
77
+ criteria: MemoryCriteria,
78
+ minConfidence: number = 80
79
+ ): Promise<any> {
80
+ return requireMemory({ ...criteria, minConfidence });
81
+ }
82
+
83
+ export async function requireRecentMemory(
84
+ criteria: MemoryCriteria,
85
+ maxAgeDays: number = 7
86
+ ): Promise<any> {
87
+ const maxAge = maxAgeDays * 24 * 60 * 60 * 1000;
88
+ return requireMemory({ ...criteria, maxAge });
89
+ }
@@ -0,0 +1,131 @@
1
+ import { basename } from 'path';
2
+ import { randomUUID } from 'crypto';
3
+ import { eq } from 'drizzle-orm';
4
+ import { getDb } from '../db/index.js';
5
+ import { getSchema } from '../db/schema.js';
6
+ import { serializeMetadata, deserializeMetadata } from './memory/serialization.js';
7
+ import { config } from '../config.js';
8
+ import { createDatabaseClient } from './storage/database.js';
9
+
10
+ export interface ProjectRecord {
11
+ id: string;
12
+ name: string;
13
+ path: string;
14
+ description?: string | null;
15
+ metadata?: Record<string, unknown> | null;
16
+ }
17
+
18
+ export async function getProjectByPath(path: string): Promise<ProjectRecord | null> {
19
+ try {
20
+ const db = createDatabaseClient(await getDb());
21
+ const schema = await getSchema();
22
+ const rows = await db.select().from(schema.projects).where(eq(schema.projects.path, path)).limit(1);
23
+ const row = rows[0];
24
+ if (!row) return null;
25
+ return normalizeProject(row);
26
+ } catch (error: any) {
27
+ throw error;
28
+ }
29
+ }
30
+
31
+ export async function ensureProject(path?: string): Promise<ProjectRecord | null> {
32
+ if (!path) return null;
33
+ const existing = await getProjectByPath(path);
34
+ if (existing) return existing;
35
+
36
+ const db = createDatabaseClient(await getDb());
37
+ const schema = await getSchema();
38
+ const id = randomUUID();
39
+ const name = basename(path) || path;
40
+ const metadata = { source: 'mcp' };
41
+
42
+ await db.insert(schema.projects).values({
43
+ id,
44
+ name,
45
+ path,
46
+ metadata: serializeMetadata(metadata),
47
+ });
48
+
49
+ return { id, name, path, metadata };
50
+ }
51
+
52
+ export class ProjectNotFoundError extends Error {
53
+ constructor(path: string) {
54
+ super(`Project not found: ${path}`);
55
+ this.name = 'ProjectNotFoundError';
56
+ }
57
+ }
58
+
59
+ export async function requireProject(path: string): Promise<ProjectRecord> {
60
+ const project = await getProjectByPath(path);
61
+ if (!project) {
62
+ throw new ProjectNotFoundError(path);
63
+ }
64
+ return project;
65
+ }
66
+
67
+ export async function getOrCreateProject(path?: string): Promise<ProjectRecord | null> {
68
+ if (!path) return null;
69
+ const existing = await getProjectByPath(path);
70
+ if (existing) return existing;
71
+
72
+ const db = createDatabaseClient(await getDb());
73
+ const schema = await getSchema();
74
+ const id = randomUUID();
75
+ const name = basename(path) || path;
76
+ const metadata = { source: 'mcp' };
77
+
78
+ await db.insert(schema.projects).values({
79
+ id,
80
+ name,
81
+ path,
82
+ metadata: serializeMetadata(metadata),
83
+ });
84
+
85
+ return { id, name, path, metadata };
86
+ }
87
+
88
+ function normalizeProject(row: any): ProjectRecord {
89
+ const metadata = deserializeMetadata(row.metadata ?? null);
90
+ return {
91
+ id: row.id,
92
+ name: row.name,
93
+ path: row.path,
94
+ description: row.description ?? null,
95
+ metadata,
96
+ };
97
+ }
98
+
99
+ export async function getAllProjects(): Promise<ProjectRecord[]> {
100
+ try {
101
+ const db = createDatabaseClient(await getDb());
102
+ const schema = await getSchema();
103
+ const rows = await db.select().from(schema.projects);
104
+
105
+ // Auto-create default project if none exist
106
+ if (rows.length === 0) {
107
+ const cwd = process.cwd();
108
+ const defaultProject = await getOrCreateProject(cwd);
109
+ if (defaultProject) {
110
+ return [defaultProject];
111
+ }
112
+ }
113
+
114
+ return rows.map(normalizeProject);
115
+ } catch (error: any) {
116
+ throw error;
117
+ }
118
+ }
119
+
120
+ export async function getProjectById(id: string): Promise<ProjectRecord | null> {
121
+ try {
122
+ const db = createDatabaseClient(await getDb());
123
+ const schema = await getSchema();
124
+ const rows = await db.select().from(schema.projects).where(eq(schema.projects.id, id)).limit(1);
125
+ const row = rows[0];
126
+ if (!row) return null;
127
+ return normalizeProject(row);
128
+ } catch (error: any) {
129
+ throw error;
130
+ }
131
+ }
package/core/redis.ts ADDED
@@ -0,0 +1,82 @@
1
+ import { createClient, RedisClientType } from 'redis';
2
+ import { performRedisPublish } from './utils/memory-operations.js';
3
+ import { logger } from './logger.js';
4
+
5
+ const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
6
+
7
+ let client: RedisClientType | null = null;
8
+
9
+ export async function getRedisClient(): Promise<RedisClientType> {
10
+ if (client && client.isOpen) {
11
+ return client;
12
+ }
13
+
14
+ client = createClient({ url: REDIS_URL });
15
+
16
+ client.on('error', (err) => {
17
+ logger.error('Redis client error', err);
18
+ });
19
+
20
+ client.on('connect', () => {
21
+ logger.info('Redis connected');
22
+ });
23
+
24
+ await client.connect();
25
+ return client;
26
+ }
27
+
28
+ export async function closeRedisConnection(): Promise<void> {
29
+ if (client && client.isOpen) {
30
+ await client.quit();
31
+ client = null;
32
+ }
33
+ }
34
+
35
+ // Cache helpers with TTL
36
+ export async function cacheGet<T>(key: string): Promise<T | null> {
37
+ const redis = await getRedisClient();
38
+ const value = await redis.get(key);
39
+ return value ? JSON.parse(value) : null;
40
+ }
41
+
42
+ export async function cacheSet<T>(key: string, value: T, ttlSeconds: number = 300): Promise<void> {
43
+ const redis = await getRedisClient();
44
+ await redis.setEx(key, ttlSeconds, JSON.stringify(value));
45
+ }
46
+
47
+ export async function cacheDelete(key: string): Promise<void> {
48
+ const redis = await getRedisClient();
49
+ await redis.del(key);
50
+ }
51
+
52
+ export async function cacheClear(pattern: string): Promise<void> {
53
+ const redis = await getRedisClient();
54
+ const keys = await redis.keys(pattern);
55
+ if (keys.length > 0) {
56
+ await redis.del(keys);
57
+ }
58
+ }
59
+
60
+ // Pub/Sub for real-time sync
61
+ export async function publish(channel: string, message: unknown): Promise<void> {
62
+ await performRedisPublish(getRedisClient, channel, message);
63
+ }
64
+
65
+ export async function subscribe(channel: string, callback: (message: unknown) => void): Promise<void> {
66
+ const subscriber = (await getRedisClient()).duplicate();
67
+ await subscriber.connect();
68
+ await subscriber.subscribe(channel, (message) => {
69
+ callback(JSON.parse(message));
70
+ });
71
+ }
72
+
73
+ // Check Redis health
74
+ export async function checkRedisHealth(): Promise<boolean> {
75
+ try {
76
+ const redis = await getRedisClient();
77
+ const pong = await redis.ping();
78
+ return pong === 'PONG';
79
+ } catch {
80
+ return false;
81
+ }
82
+ }
@@ -0,0 +1,187 @@
1
+ /**
2
+ * ResponseFormatter - Unified response formatting for all Squish output contexts
3
+ * @module core/responses
4
+ */
5
+
6
+ export type ResponseStatus = 'ok' | 'error';
7
+
8
+ export interface BaseResponse<T = unknown> {
9
+ status: ResponseStatus;
10
+ message?: string;
11
+ data?: T;
12
+ error?: string;
13
+ timestamp?: string;
14
+ }
15
+
16
+ export interface PaginatedResponse<T> extends BaseResponse<T[]> {
17
+ count: number;
18
+ total?: number;
19
+ page?: number;
20
+ limit?: number;
21
+ }
22
+
23
+ /**
24
+ * Format options for web responses
25
+ */
26
+ export interface WebFormatOptions {
27
+ statusCode?: number;
28
+ pagination?: { total: number; page: number; limit: number };
29
+ }
30
+
31
+ /**
32
+ * Unified response formatter for all Squish output contexts
33
+ */
34
+ export class ResponseFormatter {
35
+ /**
36
+ * Generate ISO timestamp
37
+ */
38
+ private static getTimestamp(): string {
39
+ return new Date().toISOString();
40
+ }
41
+
42
+ /**
43
+ * Build base response with timestamp
44
+ */
45
+ private static buildBase<T>(status: ResponseStatus, message?: string, data?: T, error?: string): BaseResponse<T> {
46
+ return {
47
+ status,
48
+ message,
49
+ data,
50
+ error,
51
+ timestamp: this.getTimestamp(),
52
+ };
53
+ }
54
+
55
+ // CLI Formatters
56
+
57
+ /**
58
+ * Format response for CLI output (pretty-printed JSON)
59
+ */
60
+ static cli<T>(data: T, message?: string): string {
61
+ const response = this.buildBase<T>(data instanceof Error ? 'error' : 'ok', message, data);
62
+ return JSON.stringify(response, null, 2);
63
+ }
64
+
65
+ /**
66
+ * Format error for CLI and exit process
67
+ */
68
+ static cliError(error: Error): never {
69
+ const response = this.buildBase<void>('error', error.message, undefined, error.message);
70
+ console.error(JSON.stringify(response, null, 2));
71
+ process.exit(1);
72
+ }
73
+
74
+ // Web API Formatters
75
+
76
+ /**
77
+ * Format successful response for Web API
78
+ */
79
+ static web<T>(
80
+ data: T,
81
+ message?: string,
82
+ options?: WebFormatOptions
83
+ ): { status: number; body: BaseResponse<T> } {
84
+ const body = this.buildBase<T>('ok', message, data);
85
+
86
+ // Add pagination metadata if provided
87
+ if (options?.pagination) {
88
+ (body as any).count = options.pagination.total;
89
+ (body as any).total = options.pagination.total;
90
+ (body as any).page = options.pagination.page;
91
+ (body as any).limit = options.pagination.limit;
92
+ }
93
+
94
+ return {
95
+ status: options?.statusCode ?? 200,
96
+ body,
97
+ };
98
+ }
99
+
100
+ /**
101
+ * Format error response for Web API
102
+ */
103
+ static webError(
104
+ error: Error,
105
+ options?: { statusCode?: number; log?: boolean }
106
+ ): { status: number; body: BaseResponse } {
107
+ const statusCode = options?.statusCode ?? 500;
108
+ const body = this.buildBase<void>('error', error.message, undefined, error.message);
109
+
110
+ if (options?.log !== false) {
111
+ console.error(`[Web API Error ${statusCode}]:`, error.message);
112
+ }
113
+
114
+ return { status: statusCode, body };
115
+ }
116
+
117
+ // MCP Formatters
118
+
119
+ /**
120
+ * Format response for MCP tools
121
+ */
122
+ static mcp<T>(
123
+ data: T,
124
+ message?: string
125
+ ): { content: Array<{ type: string; text: string }> } {
126
+ const response = this.buildBase<T>('ok', message, data);
127
+ return {
128
+ content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],
129
+ };
130
+ }
131
+
132
+ /**
133
+ * Format error for MCP tools (throws McpError)
134
+ */
135
+ static mcpError(
136
+ error: Error,
137
+ context?: string
138
+ ): never {
139
+ const message = context ? `${context}: ${error.message}` : error.message;
140
+ const response = this.buildBase<void>('error', message, undefined, message);
141
+
142
+ // Import McpError dynamically to avoid requiring @modelcontextprotocol/sdk in non-MCP contexts
143
+ try {
144
+ const { McpError, ErrorCode } = require('@modelcontextprotocol/sdk/types.js');
145
+ throw new McpError(ErrorCode.InternalError, JSON.stringify(response));
146
+ } catch (e) {
147
+ // If McpError is not available, throw a standard error with MCP-formatted message
148
+ const mcpError = new Error(JSON.stringify(response));
149
+ mcpError.name = 'McpError';
150
+ throw mcpError;
151
+ }
152
+ }
153
+
154
+ // Algorithm Handler Formatters
155
+
156
+ /**
157
+ * Format response for algorithm handlers
158
+ */
159
+ static algorithm<T>(
160
+ data: T,
161
+ message: string,
162
+ options?: { ok?: boolean; error?: string }
163
+ ): BaseResponse<T> {
164
+ const isOk = options?.ok !== false;
165
+ return this.buildBase<T>(
166
+ isOk ? 'ok' : 'error',
167
+ message,
168
+ isOk ? data : undefined,
169
+ options?.error
170
+ );
171
+ }
172
+
173
+ /**
174
+ * Convenience method for success responses
175
+ */
176
+ static success<T>(data: T, message?: string): BaseResponse<T> {
177
+ return this.buildBase<T>('ok', message, data);
178
+ }
179
+
180
+ /**
181
+ * Convenience method for failure responses
182
+ */
183
+ static failure(message: string, error?: Error | string): BaseResponse {
184
+ const errorMessage = error instanceof Error ? error.message : error;
185
+ return this.buildBase<void>('error', message, undefined, errorMessage);
186
+ }
187
+ }