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,309 @@
1
+ import { getDbClient } from '../lib/db-client.js';
2
+ import { getRecent } from '../memory/memories.js';
3
+ import { getMemoryStats } from '../memory/stats.js';
4
+ import { explainMemory } from '../memory/explain.js';
5
+ import { getLatestProjectWorkingSetSummary, getProjectSignalStats } from '../session/working-set.js';
6
+ import { getGraphStats } from '../graph/index.js';
7
+ import { getAllProjects, getProjectByPath, ensureProject } from '../projects.js';
8
+ import { getProjectPlaces } from '../places/places.js';
9
+ import { getMemoryPlace } from '../places/memory-places.js';
10
+ import { getPlace } from '../places/places.js';
11
+ import { config } from '../../config.js';
12
+ import { getBeliefsForMemory } from '../beliefs/store.js';
13
+ function isLegacyPlaceholderProject(project, currentWorkspacePath) {
14
+ const normalizedPath = project.path.trim();
15
+ if (normalizedPath === '.')
16
+ return true;
17
+ if (!currentWorkspacePath)
18
+ return false;
19
+ return normalizedPath === currentWorkspacePath && String(project.metadata?.source ?? '') === 'mcp';
20
+ }
21
+ function filterNormalOtherProjects(projects, currentProjectId, currentWorkspacePath) {
22
+ return projects.filter((candidate) => {
23
+ if (candidate.id === currentProjectId)
24
+ return false;
25
+ return !isLegacyPlaceholderProject(candidate, currentWorkspacePath);
26
+ });
27
+ }
28
+ function inferResolution(project, mode) {
29
+ if (mode !== 'inferred')
30
+ return mode;
31
+ const source = String(project.metadata?.source ?? '');
32
+ return source === 'mcp' ? 'auto-created' : 'inferred';
33
+ }
34
+ function toProjectSummary(project, mode) {
35
+ return {
36
+ id: project.id,
37
+ name: project.name,
38
+ path: project.path,
39
+ resolution: inferResolution(project, mode),
40
+ };
41
+ }
42
+ export async function resolveProjectScope(projectPath) {
43
+ const projects = await getAllProjects();
44
+ const explicitPath = projectPath?.trim();
45
+ if (explicitPath) {
46
+ let project = await getProjectByPath(explicitPath);
47
+ let resolution = 'explicit';
48
+ if (!project) {
49
+ project = await ensureProject(explicitPath);
50
+ resolution = 'auto-created';
51
+ }
52
+ if (!project) {
53
+ throw new Error(`Unable to resolve project: ${explicitPath}`);
54
+ }
55
+ return {
56
+ currentProject: toProjectSummary(project, resolution),
57
+ otherProjects: filterNormalOtherProjects(projects, project.id, explicitPath)
58
+ .map((candidate) => toProjectSummary(candidate, 'inferred')),
59
+ nextStep: null,
60
+ };
61
+ }
62
+ const cwd = process.cwd();
63
+ const cwdProject = await getProjectByPath(cwd);
64
+ if (cwdProject) {
65
+ return {
66
+ currentProject: toProjectSummary(cwdProject, 'inferred'),
67
+ otherProjects: filterNormalOtherProjects(projects, cwdProject.id, cwd)
68
+ .map((candidate) => toProjectSummary(candidate, 'inferred')),
69
+ nextStep: null,
70
+ };
71
+ }
72
+ if (projects.length === 1) {
73
+ return {
74
+ currentProject: toProjectSummary(projects[0], 'inferred'),
75
+ otherProjects: [],
76
+ nextStep: null,
77
+ };
78
+ }
79
+ const autoProject = await ensureProject(cwd);
80
+ if (!autoProject) {
81
+ throw new Error(`Unable to create project for current workspace: ${cwd}`);
82
+ }
83
+ const otherProjects = projects
84
+ .filter((candidate) => candidate.id !== autoProject.id)
85
+ .filter((candidate) => !isLegacyPlaceholderProject(candidate, cwd))
86
+ .map((candidate) => toProjectSummary(candidate, 'inferred'));
87
+ return {
88
+ currentProject: toProjectSummary(autoProject, 'auto-created'),
89
+ otherProjects,
90
+ nextStep: otherProjects.length > 0
91
+ ? 'Pass --project with the intended workspace path if this is not the project you meant.'
92
+ : null,
93
+ };
94
+ }
95
+ async function getMemoryPlaceName(memoryId) {
96
+ const placeId = await getMemoryPlace(memoryId);
97
+ if (!placeId)
98
+ return null;
99
+ const place = await getPlace(placeId);
100
+ return place?.name ?? null;
101
+ }
102
+ export async function buildContextState(projectPath, limit = 10) {
103
+ const scope = await resolveProjectScope(projectPath);
104
+ const projectPathResolved = scope.currentProject.path;
105
+ const [sessionSummary, signalSummary, graphStats, memories] = await Promise.all([
106
+ getLatestProjectWorkingSetSummary(projectPathResolved),
107
+ getProjectSignalStats(projectPathResolved),
108
+ getGraphStats(projectPathResolved),
109
+ getRecent(projectPathResolved, limit),
110
+ ]);
111
+ const project = await getProjectByPath(projectPathResolved);
112
+ const places = project ? await getProjectPlaces(project.id) : [];
113
+ const activePlaces = places.filter((place) => place.memoryCount > 0).map((place) => place.name);
114
+ const durableMemories = await Promise.all(memories.map(async (memory) => ({
115
+ id: memory.id,
116
+ type: memory.type,
117
+ content: memory.content,
118
+ place: await getMemoryPlaceName(memory.id),
119
+ })));
120
+ const beliefRows = await Promise.all(memories.map((memory) => getBeliefsForMemory(memory.id)));
121
+ const beliefs = beliefRows.flat().slice(0, 6).map((belief) => ({
122
+ type: belief.type,
123
+ statement: belief.statement,
124
+ status: belief.status,
125
+ }));
126
+ return {
127
+ currentProject: scope.currentProject,
128
+ otherProjects: scope.otherProjects,
129
+ runtime: {
130
+ sessionSummary,
131
+ activePlaces,
132
+ signalSummary: {
133
+ captured: signalSummary.captured,
134
+ suppressed: signalSummary.suppressed,
135
+ sessionOnly: signalSummary.sessionOnly,
136
+ durable: signalSummary.durable,
137
+ durableWithRaw: signalSummary.durableWithRaw,
138
+ },
139
+ graphSummary: graphStats.entityCount > 0 || graphStats.relationCount > 0
140
+ ? `enabled; ${graphStats.entityCount} entities, ${graphStats.relationCount} relations`
141
+ : 'enabled; no graph enrichments yet',
142
+ },
143
+ durableMemories,
144
+ beliefs,
145
+ nextStep: scope.nextStep,
146
+ };
147
+ }
148
+ export async function buildStatsState(projectPath) {
149
+ const scope = await resolveProjectScope(projectPath);
150
+ const projectPathResolved = scope.currentProject.path;
151
+ const [stats, graphStats, sessionSummary] = await Promise.all([
152
+ getMemoryStats(projectPathResolved),
153
+ getGraphStats(projectPathResolved),
154
+ getLatestProjectWorkingSetSummary(projectPathResolved),
155
+ ]);
156
+ const project = await getProjectByPath(projectPathResolved);
157
+ const places = project ? await getProjectPlaces(project.id) : [];
158
+ return {
159
+ currentProject: `${scope.currentProject.name} (${scope.currentProject.path})`,
160
+ totals: {
161
+ memories: stats.totalMemories,
162
+ durable: Math.max(stats.totalMemories, (stats.signal?.durable ?? 0) + (stats.signal?.durableWithRaw ?? 0)),
163
+ sessionLocal: stats.signal?.sessionOnly ?? 0,
164
+ },
165
+ signal: {
166
+ captured: stats.signal?.captured ?? 0,
167
+ suppressed: stats.signal?.suppressed ?? 0,
168
+ sessionOnly: stats.signal?.sessionOnly ?? 0,
169
+ durable: stats.signal?.durable ?? 0,
170
+ durableWithRaw: stats.signal?.durableWithRaw ?? 0,
171
+ tokensSaved: stats.signal?.tokensSaved ?? 0,
172
+ placeRouted: stats.signal?.placeRouted ?? 0,
173
+ graphEnriched: stats.signal?.graphEnriched ?? 0,
174
+ },
175
+ places: {
176
+ active: places.filter((place) => place.memoryCount > 0).length,
177
+ named: places.filter((place) => place.memoryCount > 0).map((place) => place.name),
178
+ },
179
+ graph: {
180
+ status: graphStats.entityCount > 0 || graphStats.relationCount > 0 ? 'enabled' : 'enabled (idle)',
181
+ enrichments: stats.signal?.graphEnriched ?? 0,
182
+ },
183
+ wakeUp: sessionSummary || 'No working set yet',
184
+ signalNote: stats.totalMemories > 0 && (stats.signal?.captured ?? 0) === 0
185
+ ? 'Signal counts cover capture-era writes only. Legacy durable memories may exist without signal telemetry.'
186
+ : 'Signal counts cover capture-era writes only.',
187
+ };
188
+ }
189
+ export async function buildHealthState(projectPath) {
190
+ const scope = await resolveProjectScope(projectPath);
191
+ const checks = [];
192
+ let severity = 'ok';
193
+ let nextStep = scope.nextStep;
194
+ try {
195
+ await getDbClient();
196
+ checks.push({ name: 'database', status: 'ok', detail: 'Database connection succeeded.' });
197
+ }
198
+ catch (error) {
199
+ severity = 'broken';
200
+ nextStep = 'Fix database initialization before relying on memory reads or writes.';
201
+ checks.push({
202
+ name: 'database',
203
+ status: 'broken',
204
+ detail: error?.message ?? 'Database initialization failed.',
205
+ });
206
+ }
207
+ checks.push({
208
+ name: 'project resolution',
209
+ status: 'ok',
210
+ detail: `${scope.currentProject.name} at ${scope.currentProject.path} (${scope.currentProject.resolution})`,
211
+ });
212
+ try {
213
+ await getRecent(scope.currentProject.path, 1);
214
+ checks.push({ name: 'memory write path', status: 'ok', detail: 'Memory store is readable for this project.' });
215
+ }
216
+ catch (error) {
217
+ severity = severity === 'broken' ? 'broken' : 'degraded';
218
+ nextStep = nextStep ?? 'Run `squish doctor` to repair local storage before writing memories.';
219
+ checks.push({
220
+ name: 'memory write path',
221
+ status: 'degraded',
222
+ detail: error?.message ?? 'Memory store could not be read.',
223
+ });
224
+ }
225
+ try {
226
+ const sessionSummary = await getLatestProjectWorkingSetSummary(scope.currentProject.path);
227
+ checks.push({
228
+ name: 'session working set',
229
+ status: sessionSummary ? 'ok' : 'degraded',
230
+ detail: sessionSummary || 'No compact working set has been captured yet.',
231
+ });
232
+ if (!sessionSummary && severity === 'ok') {
233
+ severity = 'degraded';
234
+ nextStep = nextStep ?? 'Run a normal session or memory write so Squish can build a working-set wake-up summary.';
235
+ }
236
+ }
237
+ catch (error) {
238
+ severity = severity === 'broken' ? 'broken' : 'degraded';
239
+ checks.push({
240
+ name: 'session working set',
241
+ status: 'degraded',
242
+ detail: error?.message ?? 'Working-set state could not be loaded.',
243
+ });
244
+ }
245
+ const project = await getProjectByPath(scope.currentProject.path);
246
+ const places = project ? await getProjectPlaces(project.id) : [];
247
+ const activePlaces = places.filter((place) => place.memoryCount > 0);
248
+ checks.push({
249
+ name: 'places',
250
+ status: activePlaces.length > 0 ? 'ok' : 'degraded',
251
+ detail: activePlaces.length > 0
252
+ ? `${activePlaces.length} active places: ${activePlaces.map((place) => place.name).join(', ')}`
253
+ : 'No populated places yet.',
254
+ });
255
+ if (activePlaces.length === 0 && severity === 'ok') {
256
+ severity = 'degraded';
257
+ nextStep = nextStep ?? 'Store or recall project memories to populate place routing.';
258
+ }
259
+ const graphStats = await getGraphStats(scope.currentProject.path);
260
+ checks.push({
261
+ name: 'graph',
262
+ status: graphStats.entityCount > 0 || graphStats.relationCount > 0 ? 'ok' : 'degraded',
263
+ detail: graphStats.entityCount > 0 || graphStats.relationCount > 0
264
+ ? `${graphStats.entityCount} entities and ${graphStats.relationCount} relations available.`
265
+ : 'Graph is enabled but has no extracted entities yet.',
266
+ });
267
+ if (graphStats.entityCount === 0 && graphStats.relationCount === 0 && severity === 'ok') {
268
+ severity = 'degraded';
269
+ nextStep = nextStep ?? 'Write or recall durable memories so graph enrichment has material to process.';
270
+ }
271
+ checks.push({
272
+ name: 'mode',
273
+ status: 'ok',
274
+ detail: `${config.isManagedMode ? 'managed' : 'local'} mode; embeddings ${config.embeddingsProvider}`,
275
+ });
276
+ return {
277
+ severity,
278
+ currentProject: `${scope.currentProject.name} (${scope.currentProject.path})`,
279
+ checks,
280
+ nextStep,
281
+ };
282
+ }
283
+ export async function buildInspectState(id) {
284
+ const inspection = await explainMemory(id);
285
+ if (!inspection)
286
+ return null;
287
+ return {
288
+ id: inspection.id,
289
+ classification: inspection.classification,
290
+ storageReason: inspection.reasons.join('; ') || 'Stored as durable memory.',
291
+ durability: inspection.classification === 'session-only' ? 'session-only' : 'durable',
292
+ place: inspection.place ?? null,
293
+ placeType: inspection.placeType ?? null,
294
+ graphStatus: inspection.graphStatus ?? null,
295
+ rawFallback: inspection.rawFallbackSnapshotId ?? null,
296
+ wakeUpPriority: inspection.nuanceSuppressed ? 'high' : 'normal',
297
+ metadataAvailability: inspection.legacyMetadata
298
+ ? 'Legacy durable record; signal-era metadata is unavailable.'
299
+ : 'Signal metadata available.',
300
+ beliefs: (inspection.beliefs ?? []).map((belief) => ({
301
+ id: belief.id,
302
+ type: belief.type,
303
+ statement: belief.statement,
304
+ status: belief.status,
305
+ confidence: belief.confidence,
306
+ })),
307
+ };
308
+ }
309
+ //# sourceMappingURL=trust-state.js.map
@@ -1,5 +1,5 @@
1
1
  /** Cron Scheduler - Persistent cron-based job scheduling with fallback support */
2
- export type JobType = 'nightly' | 'weekly' | 'hourly';
2
+ export type JobType = 'nightly' | 'weekly' | 'hourly' | 'daily';
3
3
  export type JobStatus = 'success' | 'failed' | 'skipped';
4
4
  export interface ScheduledJob {
5
5
  id: string;
@@ -1,6 +1,6 @@
1
1
  /** Cron Scheduler - Persistent cron-based job scheduling with fallback support */
2
2
  import cron from 'node-cron';
3
- import { selfIterationHandler } from '../session-hooks/self-iteration-job.js';
3
+ import { selfIterationHandler } from '../session/self-iteration-job.js';
4
4
  import { runLifecycleMaintenance } from '../lifecycle.js';
5
5
  import { logger } from '../logger.js';
6
6
  import { config } from '../../config.js';
@@ -8,7 +8,14 @@ import { getDb } from '../../db/index.js';
8
8
  import { maintenanceJobs, maintenanceJobHistory } from '../../db/drizzle/schema-sqlite.js';
9
9
  import { eq } from 'drizzle-orm';
10
10
  const jobHandlers = new Map();
11
- const activeTasks = new Map();
11
+ const activeTasks = new Map(); // node-cron ScheduledTask type
12
+ // Job interval by type (in ms) - used for catch-up detection
13
+ const JOB_INTERVALS = {
14
+ hourly: 60 * 60 * 1000, // 1 hour
15
+ daily: 24 * 60 * 60 * 1000, // 24 hours
16
+ nightly: 24 * 60 * 60 * 1000, // 24 hours (same as daily)
17
+ weekly: 7 * 24 * 60 * 60 * 1000, // 7 days
18
+ };
12
19
  export function registerJobHandler(jobName, handler) {
13
20
  jobHandlers.set(jobName, handler);
14
21
  logger.info(`[Scheduler] Registered handler for job: ${jobName}`);
@@ -29,6 +36,67 @@ const decayHandler = async (context) => {
29
36
  };
30
37
  };
31
38
  registerJobHandler('decay_maintenance', decayHandler);
39
+ // Belief decay handler - applies confidence decay to beliefs
40
+ const beliefDecayHandler = async (context) => {
41
+ const { applyBeliefDecay } = await import('../beliefs/decay.js');
42
+ const stats = await applyBeliefDecay();
43
+ return {
44
+ recordsProcessed: stats.decayed + stats.sourceCountUpdated,
45
+ summary: {
46
+ beliefDecayed: stats.decayed,
47
+ sourceCountUpdated: stats.sourceCountUpdated,
48
+ errors: stats.errors,
49
+ },
50
+ };
51
+ };
52
+ registerJobHandler('belief_decay', beliefDecayHandler);
53
+ // Auto-clean handler - deletes stale memories automatically
54
+ const autoCleanHandler = async (context) => {
55
+ const { getStaleMemories, deleteMemoryPermanently } = await import('../memory/stale-cleaner.js');
56
+ const { getAllProjects } = await import('../projects.js');
57
+ const jobConfig = context.config;
58
+ if (jobConfig.enabled === false) {
59
+ return { recordsProcessed: 0, summary: { skipped: true, reason: 'auto-clean disabled' } };
60
+ }
61
+ const olderThanDays = jobConfig.olderThanDays || 30;
62
+ const confidenceLevels = jobConfig.confidenceLevel || ['outdated', 'speculative'];
63
+ const minImportance = jobConfig.minImportance || 40;
64
+ const dryRun = jobConfig.dryRun !== undefined ? jobConfig.dryRun : false; // Default to actual delete for safety
65
+ const projects = await getAllProjects();
66
+ let totalStale = 0;
67
+ let totalDeleted = 0;
68
+ for (const project of projects) {
69
+ const stale = await getStaleMemories({
70
+ olderThanDays,
71
+ confidenceLevels,
72
+ minImportance,
73
+ projectId: project.id,
74
+ });
75
+ totalStale += stale.length;
76
+ if (dryRun) {
77
+ logger.info(`[AutoClean] Would delete ${stale.length} stale memories in ${project.path}`);
78
+ }
79
+ else {
80
+ for (const memory of stale) {
81
+ if (!memory.isPinned) {
82
+ await deleteMemoryPermanently(memory.id);
83
+ totalDeleted++;
84
+ }
85
+ }
86
+ logger.info(`[AutoClean] Deleted ${stale.length} stale memories in ${project.path}`);
87
+ }
88
+ }
89
+ return {
90
+ recordsProcessed: dryRun ? totalStale : totalDeleted,
91
+ summary: {
92
+ mode: dryRun ? 'dry-run' : 'deleted',
93
+ projectsScanned: projects.length,
94
+ memoriesAffected: dryRun ? totalStale : totalDeleted,
95
+ criteria: { olderThanDays, confidenceLevels, minImportance },
96
+ },
97
+ };
98
+ };
99
+ registerJobHandler('auto_clean', autoCleanHandler);
32
100
  export async function initializeScheduler() {
33
101
  if (!config.cronEnabled) {
34
102
  logger.info('[Scheduler] Cron scheduling disabled, using heartbeat fallback');
@@ -41,6 +109,8 @@ export async function initializeScheduler() {
41
109
  }
42
110
  try {
43
111
  await ensureDefaultJobs(db);
112
+ // Check for missed jobs (catch-up after machine wake from sleep)
113
+ await checkMissedJobs();
44
114
  const sqliteDb = db;
45
115
  const jobs = await sqliteDb
46
116
  .select()
@@ -55,6 +125,78 @@ export async function initializeScheduler() {
55
125
  logger.error('[Scheduler] Failed to initialize:', error);
56
126
  }
57
127
  }
128
+ /**
129
+ * Check for missed jobs and execute catch-up if needed
130
+ * Called on scheduler initialization (including after machine wake from sleep)
131
+ */
132
+ async function checkMissedJobs() {
133
+ try {
134
+ const db = await getDb();
135
+ if (!db)
136
+ return;
137
+ const sqliteDb = db;
138
+ const jobs = await sqliteDb
139
+ .select()
140
+ .from(maintenanceJobs)
141
+ .where(eq(maintenanceJobs.enabled, true));
142
+ const now = Date.now();
143
+ for (const job of jobs) {
144
+ const intervalMs = JOB_INTERVALS[job.jobType];
145
+ if (!intervalMs)
146
+ continue;
147
+ const lastRun = job.lastRunAt ? new Date(job.lastRunAt).getTime() : 0;
148
+ const elapsed = lastRun > 0 ? now - lastRun : intervalMs * 2; // If never run, treat as overdue
149
+ const gracePeriod = intervalMs * 1.5; // 1.5x interval grace
150
+ if (elapsed > gracePeriod) {
151
+ logger.info(`[Scheduler] Catch-up needed for ${job.jobName}, elapsed ${Math.round(elapsed / (60 * 60 * 1000))}h (grace: ${Math.round(gracePeriod / (60 * 60 * 1000))}h)`);
152
+ // Execute catch-up
153
+ const handler = jobHandlers.get(job.jobName);
154
+ if (handler) {
155
+ try {
156
+ const startedAt = new Date();
157
+ const context = {
158
+ jobId: job.id,
159
+ jobName: job.jobName,
160
+ jobType: job.jobType,
161
+ config: typeof job.jobConfig === 'string'
162
+ ? JSON.parse(job.jobConfig)
163
+ : job.jobConfig ?? {},
164
+ startedAt,
165
+ };
166
+ await handler(context);
167
+ // Record successful catch-up run
168
+ const completedAt = new Date();
169
+ await sqliteDb
170
+ .update(maintenanceJobs)
171
+ .set({
172
+ lastRunAt: completedAt,
173
+ lastRunStatus: 'success',
174
+ lastRunDuration: completedAt.getTime() - startedAt.getTime(),
175
+ })
176
+ .where(eq(maintenanceJobs.id, job.id));
177
+ logger.info(`[Scheduler] Catch-up completed for ${job.jobName}`);
178
+ }
179
+ catch (catchError) {
180
+ const msg = catchError instanceof Error ? catchError.message : String(catchError);
181
+ logger.error(`[Scheduler] Catch-up failed for ${job.jobName}:`, msg);
182
+ await sqliteDb
183
+ .update(maintenanceJobs)
184
+ .set({
185
+ lastRunAt: new Date(),
186
+ lastRunStatus: 'failed',
187
+ lastRunError: msg,
188
+ })
189
+ .where(eq(maintenanceJobs.id, job.id));
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
195
+ catch (error) {
196
+ const msg = error instanceof Error ? error.message : String(error);
197
+ logger.error('[Scheduler] Error checking missed jobs:', msg);
198
+ }
199
+ }
58
200
  async function ensureDefaultJobs(db) {
59
201
  const defaultJobs = [
60
202
  {
@@ -64,6 +206,13 @@ async function ensureDefaultJobs(db) {
64
206
  enabled: true,
65
207
  jobConfig: { applyDecay: true, updateTiers: true, evictOld: true },
66
208
  },
209
+ {
210
+ jobName: 'belief_decay',
211
+ jobType: 'daily',
212
+ cronExpression: '0 4 * * *', // Run daily at 4 AM
213
+ enabled: true,
214
+ jobConfig: { applyBeliefDecay: true },
215
+ },
67
216
  {
68
217
  jobName: 'nightly_maintenance',
69
218
  jobType: 'nightly',
@@ -85,6 +234,19 @@ async function ensureDefaultJobs(db) {
85
234
  enabled: true,
86
235
  jobConfig: { minMessageCount: 5, maxMessagesToProcess: 50 },
87
236
  },
237
+ {
238
+ jobName: 'auto_clean',
239
+ jobType: 'daily',
240
+ cronExpression: '0 3 * * *', // Run daily at 3 AM
241
+ enabled: true,
242
+ jobConfig: {
243
+ enabled: true,
244
+ olderThanDays: 30,
245
+ confidenceLevel: ['outdated', 'speculative'],
246
+ minImportance: 40,
247
+ dryRun: true, // Start with dry-run for safety
248
+ },
249
+ },
88
250
  ];
89
251
  for (const job of defaultJobs) {
90
252
  let existing;
@@ -167,7 +329,6 @@ export async function scheduleJob(job) {
167
329
  const task = cron.schedule(job.cronExpression, async () => {
168
330
  await executeJob(job);
169
331
  }, {
170
- scheduled: true,
171
332
  timezone: 'UTC',
172
333
  });
173
334
  activeTasks.set(job.jobName, task);
@@ -15,8 +15,8 @@ export async function runNightlyJob(context) {
15
15
  try {
16
16
  const lifecycleResult = await runLifecycleMaintenance();
17
17
  summary.decayApplied = lifecycleResult?.decayed || 0;
18
+ // Simplified: hot/cold only (warm removed)
18
19
  summary.tiersUpdated = (lifecycleResult?.tierChanges?.hot || 0) +
19
- (lifecycleResult?.tierChanges?.warm || 0) +
20
20
  (lifecycleResult?.tierChanges?.cold || 0);
21
21
  recordsProcessed += summary.decayApplied;
22
22
  recordsProcessed += summary.tiersUpdated;
@@ -0,0 +1,36 @@
1
+ import { type QMDSearchResult } from '../embeddings/qmd-client.js';
2
+ export type { QMDSearchResult };
3
+ export interface QMDStatus {
4
+ indexHealth: string;
5
+ documentCount: number;
6
+ collections?: Array<{
7
+ name: string;
8
+ path: string;
9
+ documentCount: number;
10
+ }>;
11
+ }
12
+ export declare function isAvailable(): Promise<boolean>;
13
+ export declare function search(query: string, options?: {
14
+ collection?: string;
15
+ limit?: number;
16
+ minScore?: number;
17
+ }): Promise<QMDSearchResult[]>;
18
+ export declare function vsearch(query: string, options?: {
19
+ collection?: string;
20
+ limit?: number;
21
+ minScore?: number;
22
+ }): Promise<QMDSearchResult[]>;
23
+ export declare function query(queryText: string, options?: {
24
+ collection?: string;
25
+ limit?: number;
26
+ minScore?: number;
27
+ }): Promise<QMDSearchResult[]>;
28
+ export declare function get(pathOrDocid: string, options?: {
29
+ full?: boolean;
30
+ maxBytes?: number;
31
+ }): Promise<string>;
32
+ export declare function status(): Promise<QMDStatus | null>;
33
+ export declare function embed(): Promise<number[] | null>;
34
+ export declare function ensureWikiDir(projectPath: string): Promise<string>;
35
+ export declare function close(): Promise<void>;
36
+ //# sourceMappingURL=qmd-wrapper.d.ts.map
@@ -0,0 +1,58 @@
1
+ import { getQMDClient } from '../embeddings/qmd-client.js';
2
+ export async function isAvailable() {
3
+ const client = await getQMDClient();
4
+ return client.isAvailable();
5
+ }
6
+ export async function search(query, options = {}) {
7
+ const client = await getQMDClient();
8
+ if (!(await client.isAvailable()))
9
+ return [];
10
+ return client.search({ query, ...options });
11
+ }
12
+ export async function vsearch(query, options = {}) {
13
+ const client = await getQMDClient();
14
+ if (!(await client.isAvailable()))
15
+ return [];
16
+ return client.vsearch({ query, ...options });
17
+ }
18
+ export async function query(queryText, options = {}) {
19
+ const client = await getQMDClient();
20
+ if (!(await client.isAvailable()))
21
+ return [];
22
+ return client.query({ query: queryText, ...options });
23
+ }
24
+ export async function get(pathOrDocid, options = {}) {
25
+ const client = await getQMDClient();
26
+ if (!(await client.isAvailable()))
27
+ return '';
28
+ return client.get({ pathOrDocid, ...options });
29
+ }
30
+ export async function status() {
31
+ const client = await getQMDClient();
32
+ if (!(await client.isAvailable()))
33
+ return null;
34
+ const result = await client.status();
35
+ if (!result)
36
+ return null;
37
+ return {
38
+ indexHealth: result.indexHealth,
39
+ documentCount: result.collections.reduce((sum, collection) => sum + collection.documentCount, 0),
40
+ collections: result.collections,
41
+ };
42
+ }
43
+ export async function embed() {
44
+ return null;
45
+ }
46
+ export async function ensureWikiDir(projectPath) {
47
+ const { join } = await import('path');
48
+ const { mkdirSync, existsSync } = await import('fs');
49
+ const wikiDir = join(projectPath, '.squish', 'wiki');
50
+ if (!existsSync(wikiDir))
51
+ mkdirSync(wikiDir, { recursive: true });
52
+ return wikiDir;
53
+ }
54
+ export async function close() {
55
+ const client = await getQMDClient();
56
+ await client.disconnect();
57
+ }
58
+ //# sourceMappingURL=qmd-wrapper.js.map
@@ -6,9 +6,9 @@ import { search } from '../memory/memories.js';
6
6
  import { getProjectContext } from '../context/context.js';
7
7
  import { getOrCreateProject } from '../projects.js';
8
8
  import { DEFAULT_AUTO_LOAD_CONFIG } from './types.js';
9
- function estimateTokens(text) {
10
- return Math.ceil(text.length / 4);
11
- }
9
+ import { estimateTokens } from '../context/context-window.js';
10
+ import { getLatestProjectWorkingSetSummary } from './working-set.js';
11
+ import { getHotCacheSummary } from '../hot-cache.js';
12
12
  export async function performAutoLoad(projectPath, customConfig) {
13
13
  const startTime = Date.now();
14
14
  const cfg = { ...DEFAULT_AUTO_LOAD_CONFIG, ...customConfig };
@@ -33,6 +33,31 @@ export async function performAutoLoad(projectPath, customConfig) {
33
33
  return result;
34
34
  }
35
35
  const projectId = project.id;
36
+ try {
37
+ const workingSetSummary = await getLatestProjectWorkingSetSummary(projectPath);
38
+ if (workingSetSummary) {
39
+ result.tokensUsed += estimateTokens(workingSetSummary);
40
+ }
41
+ }
42
+ catch (error) {
43
+ const msg = error instanceof Error ? error.message : String(error);
44
+ result.warnings.push(`Failed to load session working set: ${msg}`);
45
+ }
46
+ // NEW: Load persistent hot cache (Karpathy-style, survives restart)
47
+ if (cfg.includeCoreMemory) {
48
+ try {
49
+ const hotCacheSummary = await getHotCacheSummary({ projectPath, maxEntries: 5 });
50
+ if (hotCacheSummary) {
51
+ result.tokensUsed += estimateTokens(hotCacheSummary);
52
+ logger.info('[AutoLoad] Hot cache loaded from persistent storage');
53
+ }
54
+ }
55
+ catch (error) {
56
+ const msg = error instanceof Error ? error.message : String(error);
57
+ result.warnings.push(`Failed to load hot cache: ${msg}`);
58
+ logger.warn(`[AutoLoad] Failed to load hot cache: ${msg}`);
59
+ }
60
+ }
36
61
  if (cfg.includeCoreMemory) {
37
62
  try {
38
63
  await initializeCoreMemory(projectId);