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,449 @@
1
+ /**
2
+ * Context Paging Service - Agent-controlled memory loading
3
+ * Allows agents to load/evict memories from working set
4
+ */
5
+
6
+ import { eq, and, inArray } from 'drizzle-orm';
7
+ import { sql } from 'drizzle-orm';
8
+ import { getMemory } from '../memory/memories.js';
9
+ import { getDbClient } from '../lib/db-client.js';
10
+
11
+ interface LoadedMemory {
12
+ id: string;
13
+ type: string;
14
+ content: string;
15
+ contentPreview: string;
16
+ loadedAt: Date;
17
+ }
18
+
19
+ /**
20
+ * Initialize or get a context session
21
+ * Simplified - just tracks what's loaded, not tokens (Claude manages its own context)
22
+ */
23
+ export async function initializeContextSession(
24
+ sessionId: string,
25
+ projectId: string,
26
+ userId?: string
27
+ ): Promise<void> {
28
+ const { db, schema } = await getDbClient();
29
+ const { contextSessions } = schema;
30
+
31
+ // Check if session exists
32
+ const existing = await db
33
+ .select()
34
+ .from(contextSessions)
35
+ .where(eq(contextSessions.sessionId, sessionId))
36
+ .limit(1);
37
+
38
+ if (existing.length === 0) {
39
+ await db.insert(contextSessions).values({
40
+ sessionId,
41
+ projectId: projectId as any,
42
+ userId: userId || null,
43
+ loadedMemoryIds: JSON.stringify([]) as any,
44
+ tokenBudget: 8000,
45
+ tokensUsed: 0,
46
+ coreMemoryTokens: 0,
47
+ loadedMemoriesTokens: 0,
48
+ metadata: JSON.stringify({}) as any,
49
+ } as any);
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Load a memory into working set
55
+ */
56
+ export async function loadMemoryToContext(
57
+ sessionId: string,
58
+ memoryId: string
59
+ ): Promise<{
60
+ success: boolean;
61
+ message?: string;
62
+ memory?: LoadedMemory;
63
+ }> {
64
+ const { db, schema } = await getDbClient();
65
+ const { contextSessions } = schema;
66
+
67
+ // Get session
68
+ const session = await db
69
+ .select()
70
+ .from(contextSessions)
71
+ .where(eq(contextSessions.sessionId, sessionId))
72
+ .limit(1);
73
+
74
+ if (session.length === 0) {
75
+ return {
76
+ success: false,
77
+ message: `Session "${sessionId}" not found. Initialize session first.`,
78
+ };
79
+ }
80
+
81
+ const currentSession = session[0];
82
+ const loadedIds = (currentSession.loadedMemoryIds as string[]) || [];
83
+
84
+ // Check if already loaded
85
+ if (loadedIds.includes(memoryId)) {
86
+ return {
87
+ success: false,
88
+ message: `Memory "${memoryId}" is already in working set`,
89
+ };
90
+ }
91
+
92
+ // Get memory
93
+ const memory = await getMemory(memoryId);
94
+ if (!memory) {
95
+ return {
96
+ success: false,
97
+ message: `Memory "${memoryId}" not found`,
98
+ };
99
+ }
100
+
101
+ // Update session
102
+ const newLoadedIds = [...loadedIds, memoryId];
103
+ await db
104
+ .update(contextSessions)
105
+ .set({
106
+ loadedMemoryIds: newLoadedIds as any,
107
+ updatedAt: new Date() as any,
108
+ } as any)
109
+ .where(eq(contextSessions.sessionId, sessionId));
110
+
111
+ // Also update memory's contextStatus to 'in-context'
112
+ await db
113
+ .update(schema.memories as any)
114
+ .set({
115
+ contextStatus: 'in-context' as any,
116
+ })
117
+ .where(eq((schema.memories as any).id, memoryId));
118
+
119
+ return {
120
+ success: true,
121
+ memory: {
122
+ id: memory.id,
123
+ type: memory.type,
124
+ content: memory.content,
125
+ contentPreview: memory.content.substring(0, 200) + (memory.content.length > 200 ? '...' : ''),
126
+ loadedAt: new Date(),
127
+ },
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Evict a memory from working set
133
+ */
134
+ export async function evictMemoryFromContext(
135
+ sessionId: string,
136
+ memoryId: string
137
+ ): Promise<{
138
+ success: boolean;
139
+ message?: string;
140
+ }> {
141
+ const { db, schema } = await getDbClient();
142
+ const { contextSessions } = schema;
143
+
144
+ // Get session
145
+ const session = await db
146
+ .select()
147
+ .from(contextSessions)
148
+ .where(eq(contextSessions.sessionId, sessionId))
149
+ .limit(1);
150
+
151
+ if (session.length === 0) {
152
+ return {
153
+ success: false,
154
+ message: `Session "${sessionId}" not found`,
155
+ };
156
+ }
157
+
158
+ const currentSession = session[0];
159
+ const loadedIds = (currentSession.loadedMemoryIds as string[]) || [];
160
+
161
+ // Check if loaded
162
+ if (!loadedIds.includes(memoryId)) {
163
+ return {
164
+ success: false,
165
+ message: `Memory "${memoryId}" is not in working set`,
166
+ };
167
+ }
168
+
169
+ // Update session
170
+ const newLoadedIds = loadedIds.filter((id) => id !== memoryId);
171
+
172
+ await db
173
+ .update(contextSessions)
174
+ .set({
175
+ loadedMemoryIds: newLoadedIds as any,
176
+ updatedAt: new Date() as any,
177
+ } as any)
178
+ .where(eq(contextSessions.sessionId, sessionId));
179
+
180
+ // Also update memory's contextStatus to 'out-of-context'
181
+ await db
182
+ .update(schema.memories as any)
183
+ .set({
184
+ contextStatus: 'out-of-context' as any,
185
+ })
186
+ .where(eq((schema.memories as any).id, memoryId));
187
+
188
+ return {
189
+ success: true,
190
+ message: `Memory "${memoryId}" removed from working set`,
191
+ };
192
+ }
193
+
194
+ /**
195
+ * View all memories in working set
196
+ */
197
+ export async function viewLoadedMemories(
198
+ sessionId: string
199
+ ): Promise<{
200
+ success: boolean;
201
+ memories: LoadedMemory[];
202
+ count: number;
203
+ }> {
204
+ const { db, schema } = await getDbClient();
205
+ const { contextSessions } = schema;
206
+
207
+ // Get session
208
+ const session = await db
209
+ .select()
210
+ .from(contextSessions)
211
+ .where(eq(contextSessions.sessionId, sessionId))
212
+ .limit(1);
213
+
214
+ if (session.length === 0) {
215
+ return {
216
+ success: false,
217
+ memories: [],
218
+ count: 0,
219
+ };
220
+ }
221
+
222
+ const currentSession = session[0];
223
+ const loadedIds = (currentSession.loadedMemoryIds as string[]) || [];
224
+
225
+ if (loadedIds.length === 0) {
226
+ return {
227
+ success: true,
228
+ memories: [],
229
+ count: 0,
230
+ };
231
+ }
232
+
233
+ // Get all loaded memories
234
+ const memories: LoadedMemory[] = [];
235
+ for (const id of loadedIds) {
236
+ const memory = await getMemory(id);
237
+ if (memory) {
238
+ memories.push({
239
+ id: memory.id,
240
+ type: memory.type,
241
+ content: memory.content,
242
+ contentPreview: memory.content.substring(0, 200) + (memory.content.length > 200 ? '...' : ''),
243
+ loadedAt: currentSession.updatedAt,
244
+ });
245
+ }
246
+ }
247
+
248
+ return {
249
+ success: true,
250
+ memories,
251
+ count: memories.length,
252
+ };
253
+ }
254
+
255
+ /**
256
+ * Get context status - what's in your working set and what's available
257
+ */
258
+ export async function getContextStatus(
259
+ sessionId: string,
260
+ projectId: string
261
+ ): Promise<{
262
+ success: boolean;
263
+ coreMemory: {
264
+ sizeBytes: number;
265
+ maxBytes: number;
266
+ usagePercent: number;
267
+ };
268
+ workingSet: {
269
+ loadedCount: number;
270
+ loadedMemories: Array<{
271
+ id: string;
272
+ type: string;
273
+ contentLength: number;
274
+ }>;
275
+ };
276
+ available: {
277
+ totalMemories: number;
278
+ totalObservations: number;
279
+ };
280
+ note: string;
281
+ }> {
282
+ const { db, schema } = await getDbClient();
283
+ const { contextSessions, memories, learnings } = schema;
284
+
285
+ // Get session
286
+ const session = await db
287
+ .select()
288
+ .from(contextSessions)
289
+ .where(eq(contextSessions.sessionId, sessionId))
290
+ .limit(1);
291
+
292
+ if (session.length === 0) {
293
+ return {
294
+ success: false,
295
+ coreMemory: { sizeBytes: 0, maxBytes: 2048, usagePercent: 0 },
296
+ workingSet: { loadedCount: 0, loadedMemories: [] },
297
+ available: { totalMemories: 0, totalObservations: 0 },
298
+ note: "Session not found. Initialize session first.",
299
+ };
300
+ }
301
+
302
+ const currentSession = session[0];
303
+
304
+ // Get core memory stats
305
+ const { getCoreMemoryStats } = await import('../ingestion/core-memory.js');
306
+ const coreStats = await getCoreMemoryStats(projectId);
307
+
308
+ // Get loaded memories
309
+ const loadedIds = (currentSession.loadedMemoryIds as string[]) || [];
310
+ const loadedMemories = [];
311
+ for (const id of loadedIds) {
312
+ const memory = await getMemory(id);
313
+ if (memory) {
314
+ loadedMemories.push({
315
+ id: memory.id,
316
+ type: memory.type,
317
+ contentLength: memory.content.length,
318
+ });
319
+ }
320
+ }
321
+
322
+ // Get external context stats (counts)
323
+ const totalMemories = await db
324
+ .select()
325
+ .from(memories)
326
+ .where(eq(memories.projectId, projectId as any));
327
+
328
+ const totalObservations = await db
329
+ .select()
330
+ .from(learnings)
331
+ .where(eq(learnings.projectId, projectId as any));
332
+
333
+ return {
334
+ success: true,
335
+ coreMemory: {
336
+ sizeBytes: coreStats.totalBytes,
337
+ maxBytes: coreStats.maxBytes,
338
+ usagePercent: coreStats.usagePercent,
339
+ },
340
+ workingSet: {
341
+ loadedCount: loadedMemories.length,
342
+ loadedMemories,
343
+ },
344
+ available: {
345
+ totalMemories: totalMemories.length,
346
+ totalObservations: totalObservations.length,
347
+ },
348
+ note: "Claude manages its own context and token limits. This shows what memories you've loaded into your working set.",
349
+ };
350
+ }
351
+
352
+ /**
353
+ * Clear all loaded memories from working set
354
+ */
355
+ export async function clearLoadedMemories(sessionId: string): Promise<{
356
+ success: boolean;
357
+ message?: string;
358
+ }> {
359
+ const { db, schema } = await getDbClient();
360
+ const { contextSessions } = schema;
361
+
362
+ await db
363
+ .update(contextSessions)
364
+ .set({
365
+ loadedMemoryIds: [] as any,
366
+ updatedAt: new Date() as any,
367
+ } as any)
368
+ .where(eq(contextSessions.sessionId, sessionId));
369
+
370
+ return {
371
+ success: true,
372
+ message: 'All memories cleared from working set',
373
+ };
374
+ }
375
+
376
+ /**
377
+ * Get all memories currently marked as in-context for a session
378
+ */
379
+ export async function getInContextMemories(
380
+ sessionId: string
381
+ ): Promise<LoadedMemory[]> {
382
+ const { db, schema } = await getDbClient();
383
+ const { contextSessions } = schema;
384
+
385
+ // Get session to find project
386
+ const session = await db
387
+ .select()
388
+ .from(contextSessions)
389
+ .where(eq(contextSessions.sessionId, sessionId))
390
+ .limit(1);
391
+
392
+ if (session.length === 0) {
393
+ return [];
394
+ }
395
+
396
+ const { memories } = schema;
397
+ const projectId = session[0].projectId;
398
+
399
+ // Get all in-context memories
400
+ const inContextMemories = await db
401
+ .select()
402
+ .from(memories)
403
+ .where(
404
+ and(
405
+ eq(memories.projectId, projectId as any),
406
+ eq(memories.contextStatus, 'in-context' as any)
407
+ )
408
+ );
409
+
410
+ return inContextMemories.map((mem: any) => ({
411
+ id: mem.id,
412
+ type: mem.type,
413
+ content: mem.content,
414
+ contentPreview: mem.content.substring(0, 200) + (mem.content.length > 200 ? '...' : ''),
415
+ loadedAt: mem.updatedAt,
416
+ }));
417
+ }
418
+
419
+ /**
420
+ * Get out-of-context (archived) memories for a project
421
+ */
422
+ export async function getOutOfContextMemories(
423
+ projectId: string,
424
+ limit: number = 10
425
+ ): Promise<LoadedMemory[]> {
426
+ const { db, schema } = await getDbClient();
427
+ const { memories } = schema;
428
+
429
+ // Get out-of-context memories, ordered by last accessed
430
+ const outOfContextMemories = await db
431
+ .select()
432
+ .from(memories)
433
+ .where(
434
+ and(
435
+ eq(memories.projectId, projectId as any),
436
+ eq(memories.contextStatus, 'out-of-context' as any)
437
+ )
438
+ )
439
+ .orderBy(sql`COALESCE(${memories.lastAccessedAt}, ${memories.createdAt}) DESC`)
440
+ .limit(limit);
441
+
442
+ return outOfContextMemories.map((mem: any) => ({
443
+ id: mem.id,
444
+ type: mem.type,
445
+ content: mem.content,
446
+ contentPreview: mem.content.substring(0, 200) + (mem.content.length > 200 ? '...' : ''),
447
+ loadedAt: mem.lastAccessedAt || mem.createdAt,
448
+ }));
449
+ }
@@ -0,0 +1,234 @@
1
+ import { eq, and, sql } from 'drizzle-orm';
2
+ import { getDb } from '../../db/index.js';
3
+ import { getSchema } from '../../db/schema.js';
4
+ import { createDatabaseClient } from '../storage/database.js';
5
+ import { requireProject } from '../projects.js';
6
+
7
+ export interface ContextWindowConfig {
8
+ maxTokens: number;
9
+ warningThreshold: number;
10
+ criticalThreshold: number;
11
+ }
12
+
13
+ export const DEFAULT_CONTEXT_CONFIG: ContextWindowConfig = {
14
+ maxTokens: 128000,
15
+ warningThreshold: 0.80,
16
+ criticalThreshold: 0.95,
17
+ };
18
+
19
+ export interface TokenUsageStats {
20
+ coreMemoryTokens: number;
21
+ memoriesTokens: number;
22
+ totalTokens: number;
23
+ maxTokens: number;
24
+ usagePercent: number;
25
+ status: 'ok' | 'warning' | 'critical';
26
+ remainingTokens: number;
27
+ }
28
+
29
+ export interface OptimizationSuggestion {
30
+ type: 'drop' | 'summarize' | 'consolidate';
31
+ memoryId: string;
32
+ memoryType: string;
33
+ contentPreview: string;
34
+ tokens: number;
35
+ reason: string;
36
+ priority: number;
37
+ }
38
+
39
+ export function estimateTokens(content: string): number {
40
+ if (!content) return 0;
41
+ return Math.ceil(content.length / 4);
42
+ }
43
+
44
+ export async function getTokenUsage(projectPath: string): Promise<TokenUsageStats> {
45
+ const project = await requireProject(projectPath);
46
+ const projectId = project.id;
47
+ const db = createDatabaseClient(await getDb());
48
+ const schema = await getSchema();
49
+ const memories = schema.memories; const coreMemory = schema.coreMemory;
50
+
51
+ const coreMemoryRows = await db
52
+ .select()
53
+ .from(coreMemory)
54
+ .where(eq(coreMemory.projectId, projectId as any));
55
+
56
+ let coreMemoryTokens = 0;
57
+ for (const row of coreMemoryRows) {
58
+ coreMemoryTokens += (row as any).tokensEstimate || estimateTokens((row as any).content || '');
59
+ }
60
+
61
+ const memoryRows = await db
62
+ .select({
63
+ tokens: (memories as any).tokensEstimate,
64
+ content: memories.content,
65
+ })
66
+ .from(memories)
67
+ .where(eq(memories.projectId, projectId as any));
68
+
69
+ let memoriesTokens = 0;
70
+ for (const row of memoryRows) {
71
+ memoriesTokens += (row as any).tokens || estimateTokens((row as any).content || '');
72
+ }
73
+
74
+ const totalTokens = coreMemoryTokens + memoriesTokens;
75
+ const config = DEFAULT_CONTEXT_CONFIG;
76
+ const usagePercent = (totalTokens / config.maxTokens) * 100;
77
+ const remainingTokens = Math.max(0, config.maxTokens - totalTokens);
78
+
79
+ let status: 'ok' | 'warning' | 'critical' = 'ok';
80
+ if (usagePercent >= config.criticalThreshold * 100) {
81
+ status = 'critical';
82
+ } else if (usagePercent >= config.warningThreshold * 100) {
83
+ status = 'warning';
84
+ }
85
+
86
+ return {
87
+ coreMemoryTokens,
88
+ memoriesTokens,
89
+ totalTokens,
90
+ maxTokens: config.maxTokens,
91
+ usagePercent,
92
+ status,
93
+ remainingTokens,
94
+ };
95
+ }
96
+
97
+ export async function checkContextLimit(
98
+ projectPath: string,
99
+ additionalTokens: number
100
+ ): Promise<{ ok: boolean; warning?: string; stats: TokenUsageStats }> {
101
+ const stats = await getTokenUsage(projectPath);
102
+ const projectedTotal = stats.totalTokens + additionalTokens;
103
+ const projectedPercent = (projectedTotal / stats.maxTokens) * 100;
104
+
105
+ if (projectedPercent >= DEFAULT_CONTEXT_CONFIG.criticalThreshold * 100) {
106
+ return {
107
+ ok: false,
108
+ warning: `CRITICAL: Adding ${additionalTokens} tokens would exceed ${(DEFAULT_CONTEXT_CONFIG.criticalThreshold * 100).toFixed(0)}% of context limit (${projectedPercent.toFixed(1)}% projected). Consider optimizing first.`,
109
+ stats,
110
+ };
111
+ }
112
+
113
+ if (projectedPercent >= DEFAULT_CONTEXT_CONFIG.warningThreshold * 100) {
114
+ return {
115
+ ok: true,
116
+ warning: `WARNING: Adding ${additionalTokens} tokens would reach ${(projectedPercent.toFixed(1))}% of context limit. Consider optimizing soon.`,
117
+ stats,
118
+ };
119
+ }
120
+
121
+ return { ok: true, stats };
122
+ }
123
+
124
+ export async function getOptimizationSuggestions(
125
+ projectPath: string
126
+ ): Promise<OptimizationSuggestion[]> {
127
+ const project = await requireProject(projectPath);
128
+ const projectId = project.id;
129
+ const db = createDatabaseClient(await getDb());
130
+ const schema = await getSchema();
131
+ const memories = schema.memories;
132
+
133
+ const candidates = await db
134
+ .select({
135
+ id: memories.id,
136
+ type: memories.type,
137
+ content: memories.content,
138
+ tokens: (memories as any).tokensEstimate,
139
+ importanceScore: (memories as any).importanceScore,
140
+ accessCount: (memories as any).accessCount,
141
+ createdAt: memories.createdAt,
142
+ isPinned: (memories as any).isPinned,
143
+ isProtected: (memories as any).isProtected,
144
+ })
145
+ .from(memories)
146
+ .where(eq(memories.projectId, projectId as any))
147
+ .orderBy(sql`(importance_score * 0.4 + (100 - COALESCE(access_count, 0)) * 0.3 + (strftime('%s', 'now') - created_at / 1000) / 86400 * 0.3) ASC`)
148
+ .limit(20);
149
+
150
+ const suggestions: OptimizationSuggestion[] = [];
151
+
152
+ for (const mem of candidates) {
153
+ const tokens = (mem as any).tokens || estimateTokens((mem as any).content || '');
154
+ const contentPreview = (mem as any).content?.substring(0, 100) + '...';
155
+ const isPinned = (mem as any).isPinned === 1 || (mem as any).isPinned === true;
156
+ const isProtected = (mem as any).isProtected === 1 || (mem as any).isProtected === true;
157
+ const accessCount = (mem as any).accessCount || 0;
158
+ const importanceScore = (mem as any).importanceScore || 50;
159
+
160
+ if (isPinned || isProtected) {
161
+ continue;
162
+ }
163
+
164
+ if (importanceScore < 30 && accessCount < 3) {
165
+ suggestions.push({
166
+ type: 'drop',
167
+ memoryId: mem.id,
168
+ memoryType: mem.type,
169
+ contentPreview,
170
+ tokens,
171
+ reason: `Low importance (${importanceScore}) and rarely accessed (${accessCount} times)`,
172
+ priority: 1,
173
+ });
174
+ } else if (importanceScore < 50 && tokens > 500) {
175
+ suggestions.push({
176
+ type: 'summarize',
177
+ memoryId: mem.id,
178
+ memoryType: mem.type,
179
+ contentPreview,
180
+ tokens,
181
+ reason: `Large memory (${tokens} tokens) with moderate importance`,
182
+ priority: 2,
183
+ });
184
+ } else if (tokens > 1000) {
185
+ suggestions.push({
186
+ type: 'consolidate',
187
+ memoryId: mem.id,
188
+ memoryType: mem.type,
189
+ contentPreview,
190
+ tokens,
191
+ reason: `Very large memory (${tokens} tokens) - candidate for consolidation`,
192
+ priority: 3,
193
+ });
194
+ }
195
+ }
196
+
197
+ return suggestions.sort((a, b) => a.priority - b.priority).slice(0, 10);
198
+ }
199
+
200
+ export async function getContextWindowStatus(projectPath: string): Promise<{
201
+ config: ContextWindowConfig;
202
+ usage: TokenUsageStats;
203
+ suggestions: OptimizationSuggestion[];
204
+ memoryCount: number;
205
+ coreMemorySections: number;
206
+ }> {
207
+ const project = await requireProject(projectPath);
208
+ const projectId = project.id;
209
+ const db = createDatabaseClient(await getDb());
210
+ const schema = await getSchema();
211
+
212
+ const [usage, suggestions] = await Promise.all([
213
+ getTokenUsage(projectPath),
214
+ getOptimizationSuggestions(projectPath),
215
+ ]);
216
+
217
+ const memoryCount = await db
218
+ .select({ count: sql`COUNT(*)` })
219
+ .from(schema.memories)
220
+ .where(eq(schema.memories.projectId, projectId as any));
221
+
222
+ const coreMemorySections = await db
223
+ .select({ count: sql`COUNT(*)` })
224
+ .from(schema.coreMemory)
225
+ .where(eq(schema.coreMemory.projectId, projectId as any));
226
+
227
+ return {
228
+ config: DEFAULT_CONTEXT_CONFIG,
229
+ usage,
230
+ suggestions,
231
+ memoryCount: (memoryCount[0] as any)?.count || 0,
232
+ coreMemorySections: (coreMemorySections[0] as any)?.count || 0,
233
+ };
234
+ }
@@ -0,0 +1,35 @@
1
+ import { requireProject } from '../projects.js';
2
+ import { getRecent } from '../memory/memories.js';
3
+ import { getObservations } from '../ingestion/learnings.js';
4
+ import { getEntitiesForProject } from '../search/entities.js';
5
+ import { validateLimit } from '../lib/validation.js';
6
+
7
+ export interface ContextInput {
8
+ project: string;
9
+ include?: Array<'memories' | 'observations' | 'entities'>;
10
+ limit?: number;
11
+ }
12
+
13
+ export async function getProjectContext(input: ContextInput): Promise<Record<string, unknown>> {
14
+ const project = await requireProject(input.project);
15
+ const include = input.include ?? ['memories', 'observations'];
16
+ const limit = validateLimit(input.limit, 10, 1, 100);
17
+
18
+ const result: Record<string, unknown> = { project };
19
+
20
+ if (include.includes('memories')) {
21
+ result.memories = await getRecent(project.path, limit);
22
+ }
23
+
24
+ if (include.includes('observations')) {
25
+ result.observations = await getObservations(project.path, limit);
26
+ }
27
+
28
+ if (include.includes('entities')) {
29
+ result.entities = await getEntitiesForProject(project.path, limit);
30
+ }
31
+
32
+ return result;
33
+ }
34
+
35
+