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,149 @@
1
+ /**
2
+ * Auto-Tagger - Infer tags from context
3
+ *
4
+ * Analyzes tool input/output to automatically infer relevant tags.
5
+ * Uses pattern matching to classify actions.
6
+ */
7
+
8
+ import type { ToolCategory } from './capture-filter.js';
9
+
10
+ /**
11
+ * Infer tags based on tool, input, and content
12
+ */
13
+ export function inferTags(
14
+ toolName: string,
15
+ toolInput: Record<string, unknown>,
16
+ content: string
17
+ ): string[] {
18
+ const tags: string[] = ['hook', 'autocapture']; // Always add these
19
+
20
+ const tool = toolName.toLowerCase();
21
+ const inputStr = JSON.stringify(toolInput).toLowerCase();
22
+ const contentLower = content.toLowerCase();
23
+
24
+ // File type tags
25
+ if (tool === 'write' || tool === 'edit') {
26
+ const filePath = String(toolInput.filePath || toolInput.path || '');
27
+
28
+ if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
29
+ tags.push('typescript');
30
+ } else if (filePath.endsWith('.js') || filePath.endsWith('.jsx')) {
31
+ tags.push('javascript');
32
+ } else if (filePath.endsWith('.json')) {
33
+ tags.push('config');
34
+ } else if (filePath.endsWith('.md')) {
35
+ tags.push('documentation');
36
+ } else if (filePath.endsWith('.test.ts') || filePath.endsWith('.spec.ts')) {
37
+ tags.push('test');
38
+ }
39
+
40
+ // Feature/fix detection
41
+ if (contentLower.includes('fix') || contentLower.includes('bug')) {
42
+ tags.push('bugfix');
43
+ } else if (contentLower.includes('refactor')) {
44
+ tags.push('refactor');
45
+ } else if (contentLower.includes('feature') || contentLower.includes('add')) {
46
+ tags.push('feature');
47
+ } else if (contentLower.includes('test')) {
48
+ tags.push('testing');
49
+ }
50
+ }
51
+
52
+ // Bash command tags
53
+ if (tool === 'bash') {
54
+ const cmd = String(toolInput.command || toolInput.cmd || '');
55
+
56
+ if (cmd.includes('git commit')) {
57
+ tags.push('commit', 'version-control');
58
+ } else if (cmd.includes('test') || cmd.includes('jest') || cmd.includes('vitest')) {
59
+ tags.push('testing', 'test');
60
+ } else if (cmd.includes('build') || cmd.includes('compile')) {
61
+ tags.push('build');
62
+ } else if (cmd.includes('install')) {
63
+ tags.push('dependencies');
64
+ } else if (cmd.includes('lint') || cmd.includes('format')) {
65
+ tags.push('linting');
66
+ }
67
+ }
68
+
69
+ // Task tags
70
+ if (tool === 'task' || tool === 'todowrite') {
71
+ tags.push('task', 'planning');
72
+
73
+ if (contentLower.includes('fix') || contentLower.includes('bug')) {
74
+ tags.push('bugfix');
75
+ } else if (contentLower.includes('feature')) {
76
+ tags.push('feature');
77
+ } else if (contentLower.includes('refactor')) {
78
+ tags.push('refactor');
79
+ }
80
+ }
81
+
82
+ // Deduplicate
83
+ return [...new Set(tags)];
84
+ }
85
+
86
+ /**
87
+ * Extract tags from commit message
88
+ */
89
+ export function extractCommitTags(commitMessage: string): string[] {
90
+ const tags: string[] = ['commit'];
91
+ const msg = commitMessage.toLowerCase();
92
+
93
+ // Conventional commits
94
+ if (msg.startsWith('feat:') || msg.includes('feature')) {
95
+ tags.push('feature', 'conventional-commit');
96
+ } else if (msg.startsWith('fix:') || msg.includes('bugfix')) {
97
+ tags.push('bugfix', 'conventional-commit');
98
+ } else if (msg.startsWith('refactor:')) {
99
+ tags.push('refactor', 'conventional-commit');
100
+ } else if (msg.startsWith('docs:')) {
101
+ tags.push('documentation', 'conventional-commit');
102
+ } else if (msg.startsWith('test:')) {
103
+ tags.push('testing', 'conventional-commit');
104
+ } else if (msg.startsWith('chore:')) {
105
+ tags.push('chore', 'conventional-commit');
106
+ }
107
+
108
+ return tags;
109
+ }
110
+
111
+ /**
112
+ * Extract tags from file path
113
+ */
114
+ export function extractFileTags(filePath: string): string[] {
115
+ const tags: string[] = [];
116
+ const path = filePath.toLowerCase();
117
+
118
+ // By extension
119
+ if (path.endsWith('.ts') || path.endsWith('.tsx')) {
120
+ tags.push('typescript');
121
+ } else if (path.endsWith('.js') || path.endsWith('.jsx')) {
122
+ tags.push('javascript');
123
+ } else if (path.endsWith('.py')) {
124
+ tags.push('python');
125
+ } else if (path.endsWith('.go')) {
126
+ tags.push('golang');
127
+ } else if (path.endsWith('.rs')) {
128
+ tags.push('rust');
129
+ } else if (path.endsWith('.java')) {
130
+ tags.push('java');
131
+ } else if (path.endsWith('.json')) {
132
+ tags.push('config');
133
+ } else if (path.endsWith('.md')) {
134
+ tags.push('documentation');
135
+ }
136
+
137
+ // By directory pattern
138
+ if (path.includes('/test') || path.includes('/tests') || path.includes('__tests__')) {
139
+ tags.push('test');
140
+ } else if (path.includes('/src/')) {
141
+ tags.push('source');
142
+ } else if (path.includes('/lib/') || path.includes('/utils/')) {
143
+ tags.push('library');
144
+ } else if (path.includes('/config/') || path.includes('/scripts/')) {
145
+ tags.push('config');
146
+ }
147
+
148
+ return tags;
149
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Capture Filter - Smart filtering of tool usage
3
+ *
4
+ * Don't capture everything - filter out noise.
5
+ * Only capture meaningful actions that warrant memory.
6
+ */
7
+
8
+ import { logger } from '../logger.js';
9
+
10
+ /** Tool categories for capture */
11
+ export type ToolCategory =
12
+ | 'reading'
13
+ | 'modification'
14
+ | 'command'
15
+ | 'commit'
16
+ | 'testing'
17
+ | 'search'
18
+ | 'planning'
19
+ | 'other';
20
+
21
+ /** Capture decision */
22
+ export interface CaptureDecision {
23
+ shouldCapture: boolean;
24
+ reason?: string;
25
+ priority: 'high' | 'medium' | 'low';
26
+ }
27
+
28
+ /**
29
+ * Check if a tool should be captured
30
+ *
31
+ * Rules:
32
+ * - Write, Edit, MultiEdit → capture (modification)
33
+ * - Bash with commit → capture (commit)
34
+ * - Bash with test → capture (testing)
35
+ * - Task → capture (planning)
36
+ * - Read, Glob, grep → skip (reading - too noisy)
37
+ */
38
+ export function shouldCaptureTool(toolName: string): boolean {
39
+ const decision = getCaptureDecision(toolName);
40
+ return decision.shouldCapture;
41
+ }
42
+
43
+ /**
44
+ * Get detailed capture decision
45
+ */
46
+ export function getCaptureDecision(toolName: string): CaptureDecision {
47
+ const tool = toolName.toLowerCase();
48
+
49
+ // High priority - always capture
50
+ if (['write', 'edit', 'multiedit'].includes(tool)) {
51
+ return {
52
+ shouldCapture: true,
53
+ reason: 'File modification',
54
+ priority: 'high',
55
+ };
56
+ }
57
+
58
+ // Command with specific patterns
59
+ if (tool === 'bash') {
60
+ // Let the caller check the command for commit/test patterns
61
+ return {
62
+ shouldCapture: true, // Will be filtered by content check
63
+ reason: 'Command execution',
64
+ priority: 'medium',
65
+ };
66
+ }
67
+
68
+ // Task operations
69
+ if (['task', 'todowrite'].includes(tool)) {
70
+ return {
71
+ shouldCapture: true,
72
+ reason: 'Task/planning activity',
73
+ priority: 'high',
74
+ };
75
+ }
76
+
77
+ // Skip noisy tools
78
+ if (['read', 'glob', 'grep', 'websearch', 'webfetch', 'codesearch'].includes(tool)) {
79
+ return {
80
+ shouldCapture: false,
81
+ reason: 'Reading/search tool - too noisy',
82
+ priority: 'low',
83
+ };
84
+ }
85
+
86
+ // Skip other common noise
87
+ if (['bash'].includes(tool)) {
88
+ return {
89
+ shouldCapture: false, // Too noisy without filtering
90
+ reason: 'General command - filtered',
91
+ priority: 'low',
92
+ };
93
+ }
94
+
95
+ // Default: don't capture unknown tools
96
+ return {
97
+ shouldCapture: false,
98
+ reason: 'Unknown tool',
99
+ priority: 'low',
100
+ };
101
+ }
102
+
103
+ /**
104
+ * Check if Bash command should be captured based on content
105
+ */
106
+ export function shouldCaptureBashCommand(command: string): { capture: boolean; reason: string } {
107
+ const cmd = command.toLowerCase();
108
+
109
+ // Git commits - HIGH priority
110
+ if (cmd.includes('git commit') || cmd.includes('git add') && cmd.includes('git commit')) {
111
+ return { capture: true, reason: 'Git commit' };
112
+ }
113
+
114
+ // Tests - HIGH priority
115
+ if (cmd.includes('test') || cmd.includes('jest') || cmd.includes('vitest') ||
116
+ cmd.includes('pytest') || cmd.includes('bun test')) {
117
+ return { capture: true, reason: 'Test execution' };
118
+ }
119
+
120
+ // Build/compile - MEDIUM priority
121
+ if (cmd.includes('build') || cmd.includes('compile') || cmd.includes('tsc') ||
122
+ cmd.includes('bun build') || cmd.includes('npm run build')) {
123
+ return { capture: true, reason: 'Build/compile' };
124
+ }
125
+
126
+ // Installation - LOW priority
127
+ if (cmd.includes('npm install') || cmd.includes('bun install') ||
128
+ cmd.includes('pip install') || cmd.includes('yarn add')) {
129
+ return { capture: false, reason: 'Package installation - too noisy' };
130
+ }
131
+
132
+ // Git operations (non-commit) - LOW priority
133
+ if (cmd.includes('git') && !cmd.includes('commit')) {
134
+ return { capture: false, reason: 'Git operations - not commits' };
135
+ }
136
+
137
+ // File operations - MEDIUM priority
138
+ if (cmd.includes('mkdir') || cmd.includes('touch') || cmd.includes('rm ')) {
139
+ return { capture: true, reason: 'File operation' };
140
+ }
141
+
142
+ // Default - don't capture
143
+ return { capture: false, reason: 'General command' };
144
+ }
145
+
146
+ /**
147
+ * Categorize tool for tagging
148
+ */
149
+ export function categorizeTool(toolName: string): ToolCategory {
150
+ const tool = toolName.toLowerCase();
151
+
152
+ if (['write', 'edit', 'multiedit'].includes(tool)) {
153
+ return 'modification';
154
+ }
155
+
156
+ if (tool === 'bash') {
157
+ return 'command';
158
+ }
159
+
160
+ if (['read', 'glob', 'grep', 'websearch', 'webfetch'].includes(tool)) {
161
+ return 'reading';
162
+ }
163
+
164
+ if (['task', 'todowrite', 'todo-read'].includes(tool)) {
165
+ return 'planning';
166
+ }
167
+
168
+ return 'other';
169
+ }
@@ -0,0 +1,388 @@
1
+ /**
2
+ * Hot Cache - Persistent session context (Karpathy-style)
3
+ *
4
+ * Implements the "hot.md" layer from LLM Wiki pattern:
5
+ * - ~500 words persistent session context
6
+ * - Survives restart (unlike session working set)
7
+ * - Auto-updates on session events
8
+ * - Deduplication and stale detection
9
+ */
10
+
11
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync } from 'fs';
12
+ import { join, dirname } from 'path';
13
+ import { createHash } from 'crypto';
14
+ import { logger } from '../logger.js';
15
+ import { getProjectPath } from '../projects.js';
16
+
17
+ export interface HotCacheEntry {
18
+ id: string;
19
+ content: string;
20
+ hash: string;
21
+ createdAt: number;
22
+ lastReferencedAt: number;
23
+ referenceCount: number;
24
+ tags?: string[];
25
+ }
26
+
27
+ export interface HotCache {
28
+ version: string;
29
+ projectPath: string;
30
+ entries: HotCacheEntry[];
31
+ lastUpdated: number;
32
+ staleEntries: string[]; // IDs flagged as stale
33
+ }
34
+
35
+ const HOT_CACHE_VERSION = '1.0.0';
36
+ const MAX_HOT_CACHE_SIZE = 500; // ~500 words max
37
+ const STALE_THRESHOLD_DAYS = 7; // Flag as stale after 7 days
38
+ const STALE_REFERENCE_COUNT = 3; // Minimum refs before considering stale
39
+
40
+ let hotCacheInstance: HotCache | null = null;
41
+
42
+ /**
43
+ * Get the hot cache file path for a project
44
+ */
45
+ function getHotCachePath(projectPath: string): string {
46
+ return join(projectPath, '.squish', 'hot-cache.json');
47
+ }
48
+
49
+ /**
50
+ * Ensure .squish directory exists
51
+ */
52
+ async function ensureSquishDir(projectPath: string): Promise<string> {
53
+ const squishDir = join(projectPath, '.squish');
54
+ if (!existsSync(squishDir)) {
55
+ mkdirSync(squishDir, { recursive: true });
56
+ }
57
+ return squishDir;
58
+ }
59
+
60
+ /**
61
+ * Create content hash for deduplication
62
+ */
63
+ function hashContent(content: string): string {
64
+ return createHash('sha256').update(content.trim()).digest('hex').slice(0, 12);
65
+ }
66
+
67
+ /**
68
+ * Load hot cache from disk (or create new)
69
+ */
70
+ export async function loadHotCache(projectPath?: string): Promise<HotCache> {
71
+ const path = projectPath || await getProjectPath();
72
+ if (!path) {
73
+ return createEmptyHotCache('');
74
+ }
75
+
76
+ const cachePath = getHotCachePath(path);
77
+
78
+ try {
79
+ if (existsSync(cachePath)) {
80
+ const content = readFileSync(cachePath, 'utf-8');
81
+ const cache = JSON.parse(content) as HotCache;
82
+
83
+ // Clean stale entries on load
84
+ cache.staleEntries = identifyStaleEntries(cache.entries);
85
+
86
+ // Remove very stale entries (>14 days)
87
+ cache.entries = cache.entries.filter(entry => {
88
+ const ageDays = (Date.now() - entry.lastReferencedAt) / (24 * 60 * 60 * 1000);
89
+ return ageDays < 14;
90
+ });
91
+
92
+ logger.info('[HotCache] Loaded', { entries: cache.entries.length, path });
93
+ return cache;
94
+ }
95
+ } catch (error) {
96
+ logger.warn('[HotCache] Load failed, creating new', { error });
97
+ }
98
+
99
+ return createEmptyHotCache(path);
100
+ }
101
+
102
+ /**
103
+ * Create empty hot cache
104
+ */
105
+ function createEmptyHotCache(projectPath: string): HotCache {
106
+ return {
107
+ version: HOT_CACHE_VERSION,
108
+ projectPath,
109
+ entries: [],
110
+ lastUpdated: Date.now(),
111
+ staleEntries: [],
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Identify stale entries (>7 days without enough references)
117
+ */
118
+ function identifyStaleEntries(entries: HotCacheEntry[]): string[] {
119
+ const stale: string[] = [];
120
+ const now = Date.now();
121
+
122
+ for (const entry of entries) {
123
+ const daysSinceRef = (now - entry.lastReferencedAt) / (24 * 60 * 60 * 1000);
124
+ if (daysSinceRef > STALE_THRESHOLD_DAYS && entry.referenceCount < STALE_REFERENCE_COUNT) {
125
+ stale.push(entry.id);
126
+ }
127
+ }
128
+
129
+ return stale;
130
+ }
131
+
132
+ /**
133
+ * Save hot cache to disk
134
+ */
135
+ export async function saveHotCache(cache: HotCache): Promise<void> {
136
+ const cachePath = getHotCachePath(cache.projectPath);
137
+
138
+ try {
139
+ await ensureSquishDir(cache.projectPath);
140
+ writeFileSync(cachePath, JSON.stringify(cache, null, 2), 'utf-8');
141
+ cache.lastUpdated = Date.now();
142
+ } catch (error) {
143
+ logger.error('[HotCache] Save failed', { error });
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Add an entry to hot cache (with deduplication)
149
+ */
150
+ export async function addToHotCache(
151
+ content: string,
152
+ options?: {
153
+ projectPath?: string;
154
+ tags?: string[];
155
+ reference?: boolean;
156
+ }
157
+ ): Promise<HotCache> {
158
+ const path = options?.projectPath || await getProjectPath();
159
+ if (!path) {
160
+ return createEmptyHotCache('');
161
+ }
162
+
163
+ const cache = await loadHotCache(path);
164
+
165
+ const contentHash = hashContent(content);
166
+
167
+ // Check for duplicate by hash
168
+ const existingIndex = cache.entries.findIndex(e => e.hash === contentHash);
169
+ if (existingIndex >= 0) {
170
+ // Update reference info for duplicate
171
+ cache.entries[existingIndex].lastReferencedAt = Date.now();
172
+ cache.entries[existingIndex].referenceCount++;
173
+ await saveHotCache(cache);
174
+ logger.debug('[HotCache] Updated existing entry reference', { hash: contentHash });
175
+ return cache;
176
+ }
177
+
178
+ // Add new entry
179
+ const newEntry: HotCacheEntry = {
180
+ id: `hot-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
181
+ content: content.slice(0, 500), // Limit individual entry size
182
+ hash: contentHash,
183
+ createdAt: Date.now(),
184
+ lastReferencedAt: Date.now(),
185
+ referenceCount: 1,
186
+ tags: options?.tags,
187
+ };
188
+
189
+ cache.entries.push(newEntry);
190
+
191
+ // Trim if over max size (remove oldest entries)
192
+ if (cache.entries.length > MAX_HOT_CACHE_SIZE) {
193
+ cache.entries = cache.entries
194
+ .sort((a, b) => b.lastReferencedAt - a.lastReferencedAt)
195
+ .slice(0, MAX_HOT_CACHE_SIZE);
196
+ }
197
+
198
+ await saveHotCache(cache);
199
+ logger.info('[HotCache] Added new entry', { entries: cache.entries.length });
200
+
201
+ return cache;
202
+ }
203
+
204
+ /**
205
+ * Get hot cache summary for context
206
+ * Returns markdown-formatted summary of recent entries
207
+ */
208
+ export async function getHotCacheSummary(
209
+ options?: {
210
+ projectPath?: string;
211
+ maxEntries?: number;
212
+ }
213
+ ): Promise<string> {
214
+ const path = options?.projectPath || await getProjectPath();
215
+ if (!path) return '';
216
+
217
+ const cache = await loadHotCache(path);
218
+
219
+ if (cache.entries.length === 0) {
220
+ return '## Hot Cache\n\nNo active hot memories yet.\n';
221
+ }
222
+
223
+ const maxEntries = options?.maxEntries || 10;
224
+ const recentEntries = cache.entries
225
+ .sort((a, b) => b.lastReferencedAt - a.lastReferencedAt)
226
+ .slice(0, maxEntries);
227
+
228
+ const lines = ['## Hot Cache\n'];
229
+
230
+ for (const entry of recentEntries) {
231
+ const date = new Date(entry.lastReferencedAt).toISOString().split('T')[0];
232
+ const stale = cache.staleEntries.includes(entry.id) ? ' [STALE]' : '';
233
+ lines.push(`- ${entry.content.slice(0, 100)}${entry.content.length > 100 ? '...' : ''}${stale} (${date})`);
234
+ }
235
+
236
+ if (cache.staleEntries.length > 0) {
237
+ lines.push(`\n* ${cache.staleEntries.length} entries flagged as stale (consider cleaning)*`);
238
+ }
239
+
240
+ return lines.join('\n');
241
+ }
242
+
243
+ /**
244
+ * Reference an existing hot cache entry (prevents staleness)
245
+ */
246
+ export async function referenceHotCacheEntry(
247
+ entryId: string,
248
+ projectPath?: string
249
+ ): Promise<boolean> {
250
+ const path = projectPath || await getProjectPath();
251
+ if (!path) return false;
252
+
253
+ const cache = await loadHotCache(path);
254
+ const entry = cache.entries.find(e => e.id === entryId);
255
+
256
+ if (entry) {
257
+ entry.lastReferencedAt = Date.now();
258
+ entry.referenceCount++;
259
+ await saveHotCache(cache);
260
+ return true;
261
+ }
262
+
263
+ return false;
264
+ }
265
+
266
+ /**
267
+ * Remove stale entries from hot cache
268
+ */
269
+ export async function cleanStaleEntries(projectPath?: string): Promise<number> {
270
+ const path = projectPath || await getProjectPath();
271
+ if (!path) return 0;
272
+
273
+ const cache = await loadHotCache(path);
274
+ const staleIdSet = new Set(cache.staleEntries);
275
+
276
+ const originalCount = cache.entries.length;
277
+ cache.entries = cache.entries.filter(e => !staleIdSet.has(e.id));
278
+ cache.staleEntries = [];
279
+
280
+ await saveHotCache(cache);
281
+
282
+ const removed = originalCount - cache.entries.length;
283
+ logger.info('[HotCache] Cleaned stale entries', { removed });
284
+
285
+ return removed;
286
+ }
287
+
288
+ /**
289
+ * Add session context to hot cache
290
+ * Called from session hooks with key session information
291
+ */
292
+ export async function addSessionContextToHotCache(
293
+ sessionInfo: {
294
+ activeFiles?: string[];
295
+ commands?: string[];
296
+ failures?: string[];
297
+ decisions?: string[];
298
+ hypotheses?: string[];
299
+ },
300
+ projectPath?: string
301
+ ): Promise<HotCache> {
302
+ const path = projectPath || await getProjectPath();
303
+ if (!path) return createEmptyHotCache('');
304
+
305
+ // Build context entries from session info
306
+ const entries: string[] = [];
307
+
308
+ if (sessionInfo.activeFiles?.length) {
309
+ entries.push(`Active files: ${sessionInfo.activeFiles.join(', ')}`);
310
+ }
311
+
312
+ if (sessionInfo.commands?.length) {
313
+ entries.push(`Recent commands: ${sessionInfo.commands.slice(-3).join('; ')}`);
314
+ }
315
+
316
+ if (sessionInfo.failures?.length) {
317
+ entries.push(`Recent failures: ${sessionInfo.failures.slice(-2).join('; ')}`);
318
+ }
319
+
320
+ if (sessionInfo.decisions?.length) {
321
+ entries.push(`Decisions: ${sessionInfo.decisions.join('; ')}`);
322
+ }
323
+
324
+ if (sessionInfo.hypotheses?.length) {
325
+ entries.push(`Hypotheses: ${sessionInfo.hypotheses.slice(-2).join('; ')}`);
326
+ }
327
+
328
+ // Add each entry to hot cache
329
+ let cache = await loadHotCache(path);
330
+ for (const entry of entries) {
331
+ cache = await addToHotCache(entry, { projectPath: path });
332
+ }
333
+
334
+ return cache;
335
+ }
336
+
337
+ /**
338
+ * Get all hot cache entries (for advanced use)
339
+ */
340
+ export async function getHotCacheEntries(
341
+ projectPath?: string
342
+ ): Promise<HotCacheEntry[]> {
343
+ const path = projectPath || await getProjectPath();
344
+ if (!path) return [];
345
+
346
+ const cache = await loadHotCache(path);
347
+ return cache.entries;
348
+ }
349
+
350
+ /**
351
+ * Clear hot cache (dangerous - use with caution)
352
+ */
353
+ export async function clearHotCache(projectPath?: string): Promise<void> {
354
+ const path = projectPath || await getProjectPath();
355
+ if (!path) return;
356
+
357
+ const cache = createEmptyHotCache(path);
358
+ await saveHotCache(cache);
359
+ logger.info('[HotCache] Cleared');
360
+ }
361
+
362
+ /**
363
+ * Get hot cache statistics
364
+ */
365
+ export async function getHotCacheStats(projectPath?: string): Promise<{
366
+ entries: number;
367
+ staleEntries: number;
368
+ oldestEntry: number | null;
369
+ newestEntry: number | null;
370
+ }> {
371
+ const path = projectPath || await getProjectPath();
372
+ if (!path) return { entries: 0, staleEntries: 0, oldestEntry: null, newestEntry: null };
373
+
374
+ const cache = await loadHotCache(path);
375
+
376
+ if (cache.entries.length === 0) {
377
+ return { entries: 0, staleEntries: 0, oldestEntry: null, newestEntry: null };
378
+ }
379
+
380
+ const timestamps = cache.entries.map(e => e.createdAt);
381
+
382
+ return {
383
+ entries: cache.entries.length,
384
+ staleEntries: cache.staleEntries.length,
385
+ oldestEntry: Math.min(...timestamps),
386
+ newestEntry: Math.max(...timestamps),
387
+ };
388
+ }
package/core/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ // Shared services - Core utilities and services
2
+ export * from './storage/cache';
3
+ export * from './context/context';
4
+ export * from './storage/database';
5
+ export * from './embeddings';
6
+ export * from './ingestion/learnings';
7
+ export * from './security/privacy';
8
+ export * from './projects';
9
+ export * from './security/secret-detector';
10
+ export * from './worker';