squish-memory 1.0.2 → 1.1.5

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 (341) hide show
  1. package/.env.example +130 -0
  2. package/CHANGELOG.md +55 -0
  3. package/README.md +150 -287
  4. package/config/hooks/claude-code-hooks.json +39 -0
  5. package/config/hooks/cursor-hooks.json +30 -0
  6. package/config/hooks/opencode-hooks.json +30 -0
  7. package/config/hooks/windsurf-hooks.json +30 -0
  8. package/config/mcp-mode-semantics.json +23 -21
  9. package/config/plugin-manifest.json +101 -152
  10. package/{plugin.json → config/plugin.json} +2 -2
  11. package/config/settings.json +52 -51
  12. package/{commands → core/commands}/init.md +39 -39
  13. package/dist/config.d.ts +28 -4
  14. package/dist/config.js +97 -29
  15. package/dist/core/adapters/config/claude-code.d.ts +45 -0
  16. package/dist/core/adapters/config/claude-code.js +113 -0
  17. package/dist/core/adapters/config/cursor.d.ts +26 -0
  18. package/dist/core/adapters/config/cursor.js +74 -0
  19. package/dist/core/adapters/config/opencode.d.ts +23 -0
  20. package/dist/core/adapters/config/opencode.js +73 -0
  21. package/dist/core/adapters/config/windsurf.d.ts +26 -0
  22. package/dist/core/adapters/config/windsurf.js +74 -0
  23. package/dist/core/adapters/index.d.ts +45 -0
  24. package/dist/core/adapters/index.js +84 -0
  25. package/dist/core/adapters/scripts/install-adapter.d.ts +19 -0
  26. package/dist/core/adapters/scripts/install-adapter.js +149 -0
  27. package/dist/core/adapters/timeline.d.ts +23 -0
  28. package/dist/core/adapters/timeline.js +88 -0
  29. package/dist/core/adapters/types.d.ts +157 -0
  30. package/dist/core/adapters/types.js +50 -0
  31. package/dist/{algorithms → core/algorithms}/analytics/token-estimator.d.ts +1 -1
  32. package/dist/{algorithms → core/algorithms}/analytics/token-estimator.js +3 -3
  33. package/dist/{algorithms → core/algorithms}/detection/semantic-ranker.d.ts +1 -1
  34. package/dist/{algorithms → core/algorithms}/detection/semantic-ranker.js +1 -1
  35. package/dist/{algorithms → core/algorithms}/detection/two-stage-detector.d.ts +1 -1
  36. package/dist/{algorithms → core/algorithms}/detection/two-stage-detector.js +7 -10
  37. package/dist/{algorithms → core/algorithms}/handlers/approve-merge.js +4 -4
  38. package/dist/{algorithms → core/algorithms}/handlers/detect-duplicates.js +3 -3
  39. package/dist/{algorithms → core/algorithms}/handlers/get-stats.js +3 -3
  40. package/dist/{algorithms → core/algorithms}/handlers/list-proposals.js +3 -3
  41. package/dist/{algorithms → core/algorithms}/handlers/preview-merge.js +3 -3
  42. package/dist/{algorithms → core/algorithms}/handlers/reject-merge.js +3 -3
  43. package/dist/{algorithms → core/algorithms}/handlers/reverse-merge.js +3 -3
  44. package/dist/core/algorithms/index.d.ts +21 -0
  45. package/dist/core/algorithms/index.js +26 -0
  46. package/dist/core/algorithms/operations/cache-maintenance.d.ts +12 -0
  47. package/dist/core/algorithms/operations/cache-maintenance.js +157 -0
  48. package/dist/{algorithms → core/algorithms}/safety/safety-checks.d.ts +1 -1
  49. package/dist/{algorithms → core/algorithms}/strategies/merge-strategies.d.ts +19 -1
  50. package/dist/{algorithms → core/algorithms}/strategies/merge-strategies.js +74 -123
  51. package/dist/core/algorithms/types.d.ts +133 -0
  52. package/dist/core/algorithms/types.js +5 -0
  53. package/dist/core/associations.d.ts +1 -2
  54. package/dist/core/associations.js +1 -2
  55. package/dist/core/autosave.d.ts +19 -0
  56. package/dist/core/autosave.js +16 -0
  57. package/dist/{commands → core/commands}/managed-sync.js +5 -5
  58. package/dist/core/commands/mcp-server.js +739 -0
  59. package/dist/core/context/agent-context.d.ts +106 -0
  60. package/dist/core/context/agent-context.js +274 -0
  61. package/dist/core/{context-paging.d.ts → context/context-paging.d.ts} +2 -12
  62. package/dist/core/{context-paging.js → context/context-paging.js} +19 -39
  63. package/dist/core/context/context-window.d.ts +40 -0
  64. package/dist/core/context/context-window.js +177 -0
  65. package/dist/core/context/context.js +22 -0
  66. package/dist/core/embeddings.d.ts +1 -1
  67. package/dist/core/embeddings.js +54 -2
  68. package/dist/core/error-handling.d.ts +63 -0
  69. package/dist/core/error-handling.js +173 -0
  70. package/dist/core/external-folder/index.d.ts +102 -0
  71. package/dist/core/external-folder/index.js +294 -0
  72. package/dist/core/hooks/agent-hooks.d.ts +74 -0
  73. package/dist/core/hooks/agent-hooks.js +244 -0
  74. package/dist/core/hooks/auto-tagger.d.ts +19 -0
  75. package/dist/core/hooks/auto-tagger.js +155 -0
  76. package/dist/core/hooks/capture-filter.d.ts +41 -0
  77. package/dist/core/hooks/capture-filter.js +128 -0
  78. package/dist/core/index.d.ts +6 -6
  79. package/dist/core/index.js +6 -6
  80. package/dist/core/{agent-memory.js → ingestion/agent-memory.js} +5 -7
  81. package/dist/core/{core-memory.js → ingestion/core-memory.js} +4 -4
  82. package/dist/core/ingestion/learnings.d.ts +57 -0
  83. package/dist/core/ingestion/learnings.js +202 -0
  84. package/dist/core/lib/db-client.d.ts +114 -0
  85. package/dist/core/lib/db-client.js +130 -0
  86. package/dist/core/lib/schemas.d.ts +129 -0
  87. package/dist/core/lib/schemas.js +87 -0
  88. package/dist/core/{utils.d.ts → lib/utils.d.ts} +1 -0
  89. package/dist/core/{utils.js → lib/utils.js} +31 -15
  90. package/dist/core/lib/validation.d.ts +38 -0
  91. package/dist/core/lib/validation.js +151 -0
  92. package/dist/core/lifecycle.d.ts +7 -0
  93. package/dist/core/lifecycle.js +140 -20
  94. package/dist/core/local-embeddings.d.ts +6 -1
  95. package/dist/core/local-embeddings.js +6 -15
  96. package/dist/core/logger.js +7 -1
  97. package/dist/core/mcp/tools.js +35 -3
  98. package/dist/core/memory/categorizer.js +1 -0
  99. package/dist/core/memory/conflict-detector.js +1 -1
  100. package/dist/core/memory/consolidation.d.ts +1 -10
  101. package/dist/core/memory/consolidation.js +2 -11
  102. package/dist/core/memory/context-collector.js +1 -1
  103. package/dist/core/memory/edit-workflow.js +1 -1
  104. package/dist/core/memory/entity-resolver.js +7 -7
  105. package/dist/core/memory/fact-extractor.js +12 -12
  106. package/dist/core/memory/feedback-tracker.js +1 -1
  107. package/dist/core/memory/hooks.d.ts +88 -0
  108. package/dist/core/memory/hooks.js +174 -0
  109. package/dist/core/memory/hybrid-retrieval.js +2 -2
  110. package/dist/core/memory/hybrid-search.d.ts +1 -6
  111. package/dist/core/memory/hybrid-search.js +70 -84
  112. package/dist/core/memory/importance.d.ts +8 -13
  113. package/dist/core/memory/importance.js +47 -74
  114. package/dist/core/memory/loader.d.ts +31 -0
  115. package/dist/core/memory/loader.js +141 -0
  116. package/dist/core/memory/markdown/markdown-storage.d.ts +72 -0
  117. package/dist/core/memory/markdown/markdown-storage.js +243 -0
  118. package/dist/core/memory/memories.d.ts +12 -4
  119. package/dist/core/memory/memories.js +192 -180
  120. package/dist/core/memory/memory-lifecycle.d.ts +8 -0
  121. package/dist/core/memory/memory-lifecycle.js +55 -0
  122. package/dist/core/memory/migrate.d.ts +21 -0
  123. package/dist/core/memory/migrate.js +134 -0
  124. package/dist/core/memory/normalization.d.ts +22 -0
  125. package/dist/core/memory/normalization.js +26 -0
  126. package/dist/core/memory/progressive-disclosure.js +1 -1
  127. package/dist/core/memory/query-rewriter.js +9 -9
  128. package/dist/core/memory/serialization.d.ts +4 -0
  129. package/dist/core/memory/serialization.js +49 -0
  130. package/dist/core/memory/stats.d.ts +5 -0
  131. package/dist/core/memory/stats.js +63 -12
  132. package/dist/core/memory/temporal-facts.js +21 -0
  133. package/dist/core/memory/write-gate.js +1 -1
  134. package/dist/core/obsidian-vault.d.ts +30 -0
  135. package/dist/core/obsidian-vault.js +94 -0
  136. package/dist/core/places/index.d.ts +14 -0
  137. package/dist/core/places/index.js +14 -0
  138. package/dist/core/places/memory-places.d.ts +68 -0
  139. package/dist/core/places/memory-places.js +261 -0
  140. package/dist/core/places/places.d.ts +88 -0
  141. package/dist/core/places/places.js +314 -0
  142. package/dist/core/places/rules.d.ts +74 -0
  143. package/dist/core/places/rules.js +240 -0
  144. package/dist/core/places/walking.d.ts +56 -0
  145. package/dist/core/places/walking.js +121 -0
  146. package/dist/core/projects.d.ts +5 -0
  147. package/dist/core/projects.js +39 -18
  148. package/dist/core/responses.d.ts +96 -0
  149. package/dist/core/responses.js +122 -0
  150. package/dist/core/scheduler/cron-scheduler.js +29 -7
  151. package/dist/core/scheduler/index.d.ts +1 -1
  152. package/dist/core/scheduler/index.js +1 -1
  153. package/dist/core/scheduler/job-runner.js +1 -1
  154. package/dist/core/search/conversations.js +40 -42
  155. package/dist/core/search/entities.js +6 -9
  156. package/dist/core/search/graph-boost.d.ts +7 -0
  157. package/dist/core/search/graph-boost.js +23 -0
  158. package/dist/core/search/qmd-search.js +4 -4
  159. package/dist/core/security/encrypt.d.ts +6 -0
  160. package/dist/core/security/encrypt.js +47 -0
  161. package/dist/core/{governance.d.ts → security/governance.d.ts} +6 -1
  162. package/dist/core/security/governance.js +79 -0
  163. package/dist/core/session/auto-load.js +6 -6
  164. package/dist/core/session/index.d.ts +1 -1
  165. package/dist/core/session/index.js +1 -1
  166. package/dist/core/session/self-iteration-job.d.ts +20 -0
  167. package/dist/core/session/self-iteration-job.js +282 -0
  168. package/dist/core/session/session-hooks.d.ts +18 -0
  169. package/dist/core/session/session-hooks.js +58 -0
  170. package/dist/core/session-hooks/self-iteration-job.js +35 -35
  171. package/dist/core/{cache.js → storage/cache.js} +2 -2
  172. package/dist/core/sync/qmd-sync.d.ts +1 -13
  173. package/dist/core/sync/qmd-sync.js +1 -13
  174. package/dist/core/toon.d.ts +43 -0
  175. package/dist/core/toon.js +160 -0
  176. package/dist/core/utils/memory-operations.js +1 -1
  177. package/dist/core/utils/vector-operations.d.ts +71 -0
  178. package/dist/core/utils/vector-operations.js +129 -0
  179. package/dist/db/adapter.d.ts +3 -3
  180. package/dist/db/adapter.js +99 -88
  181. package/dist/db/bootstrap.js +820 -522
  182. package/dist/{drizzle → db/drizzle}/schema-sqlite.d.ts +74 -25
  183. package/dist/{drizzle → db/drizzle}/schema-sqlite.js +91 -24
  184. package/dist/{drizzle → db/drizzle}/schema.d.ts +79 -32
  185. package/dist/{drizzle → db/drizzle}/schema.js +106 -35
  186. package/dist/db/drizzle.config.d.ts +3 -0
  187. package/dist/db/drizzle.config.js +12 -0
  188. package/dist/db/index.d.ts +1 -5
  189. package/dist/db/index.js +51 -8
  190. package/dist/db/neon.d.ts +8 -0
  191. package/dist/db/neon.js +20 -0
  192. package/dist/db/schema/index.d.ts +40 -0
  193. package/dist/db/schema/index.js +105 -0
  194. package/dist/db/schema/tables/context-sessions.d.ts +9 -0
  195. package/dist/db/schema/tables/context-sessions.js +37 -0
  196. package/dist/db/schema/tables/conversations.d.ts +9 -0
  197. package/dist/db/schema/tables/conversations.js +47 -0
  198. package/dist/db/schema/tables/core-memory.d.ts +9 -0
  199. package/dist/db/schema/tables/core-memory.js +41 -0
  200. package/dist/db/schema/tables/entities.d.ts +9 -0
  201. package/dist/db/schema/tables/entities.js +39 -0
  202. package/dist/db/schema/tables/entity-relations.d.ts +9 -0
  203. package/dist/db/schema/tables/entity-relations.js +31 -0
  204. package/dist/db/schema/tables/learnings.d.ts +9 -0
  205. package/dist/db/schema/tables/learnings.js +66 -0
  206. package/dist/db/schema/tables/memories.d.ts +9 -0
  207. package/dist/db/schema/tables/memories.js +161 -0
  208. package/dist/db/schema/tables/memory-associations.d.ts +9 -0
  209. package/dist/db/schema/tables/memory-associations.js +39 -0
  210. package/dist/db/schema/tables/memory-hash-cache.d.ts +9 -0
  211. package/dist/db/schema/tables/memory-hash-cache.js +29 -0
  212. package/dist/db/schema/tables/memory-merge-history.d.ts +9 -0
  213. package/dist/db/schema/tables/memory-merge-history.js +33 -0
  214. package/dist/db/schema/tables/memory-merge-proposals.d.ts +9 -0
  215. package/dist/db/schema/tables/memory-merge-proposals.js +39 -0
  216. package/dist/db/schema/tables/messages.d.ts +9 -0
  217. package/dist/db/schema/tables/messages.js +41 -0
  218. package/dist/db/schema/tables/namespaces.d.ts +9 -0
  219. package/dist/db/schema/tables/namespaces.js +37 -0
  220. package/dist/db/schema/tables/projects.d.ts +9 -0
  221. package/dist/db/schema/tables/projects.js +31 -0
  222. package/dist/db/schema/tables/users.d.ts +9 -0
  223. package/dist/db/schema/tables/users.js +27 -0
  224. package/dist/db/schema.d.ts +1 -1
  225. package/dist/db/schema.js +2 -2
  226. package/dist/db/supabase.d.ts +9 -0
  227. package/dist/db/supabase.js +24 -0
  228. package/dist/index.d.ts +2 -14
  229. package/dist/index.js +1320 -640
  230. package/dist/vendor/sql.js/sql-wasm.wasm +0 -0
  231. package/dist/webui/server.d.ts +5 -0
  232. package/dist/{api/web/web.js → webui/server.js} +511 -508
  233. package/generated/mcp/manifest.json +1 -1
  234. package/{.mcp.json → mcp.json.example} +1 -1
  235. package/package.json +159 -181
  236. package/scripts/README.md +60 -0
  237. package/scripts/copy-runtime-assets.mjs +26 -0
  238. package/scripts/generate-mcp.mjs +264 -264
  239. package/scripts/github-release.sh +4 -4
  240. package/scripts/install-claude-code.sh +85 -0
  241. package/scripts/install-cursor.sh +56 -0
  242. package/scripts/install-hooks.sh +73 -0
  243. package/scripts/install-interactive.mjs +357 -677
  244. package/scripts/install-opencode.sh +75 -0
  245. package/scripts/install-windsurf.sh +67 -0
  246. package/skills/squish-memory/SKILL.md +104 -114
  247. package/skills/squish-memory/{install.mjs → scripts/install.mjs} +2 -2
  248. package/skills/squish-memory/{install.sh → scripts/install.sh} +2 -2
  249. package/skills/squish-memory/write_skill.js +2 -0
  250. package/.claude-plugin/marketplace.json +0 -20
  251. package/.claude-plugin/plugin.json +0 -32
  252. package/.env.mcp.example +0 -60
  253. package/QUICK-START.md +0 -71
  254. package/bin/squish-add.mjs +0 -32
  255. package/bin/squish-rm.mjs +0 -21
  256. package/commands/observe.md +0 -5
  257. package/dist/api/web/index.d.ts +0 -3
  258. package/dist/api/web/index.js +0 -4
  259. package/dist/api/web/web-server.d.ts +0 -3
  260. package/dist/api/web/web-server.js +0 -6
  261. package/dist/api/web/web.d.ts +0 -4
  262. package/dist/commands/mcp-server.js +0 -393
  263. package/dist/core/context.js +0 -24
  264. package/dist/core/governance.js +0 -64
  265. package/dist/core/observations.d.ts +0 -26
  266. package/dist/core/observations.js +0 -110
  267. package/dist/core/requirements.d.ts +0 -20
  268. package/dist/core/requirements.js +0 -35
  269. package/hooks/hooks.json +0 -52
  270. package/hooks/post-tool-use.js +0 -26
  271. package/hooks/session-end.js +0 -28
  272. package/hooks/session-start.js +0 -33
  273. package/hooks/user-prompt-submit.js +0 -26
  274. package/hooks/utils.js +0 -153
  275. package/npx-installer.js +0 -208
  276. package/packages/plugin-claude-code/README.md +0 -73
  277. package/packages/plugin-claude-code/dist/plugin-wrapper.d.ts +0 -35
  278. package/packages/plugin-claude-code/dist/plugin-wrapper.js +0 -191
  279. package/packages/plugin-claude-code/package.json +0 -31
  280. package/packages/plugin-openclaw/README.md +0 -70
  281. package/packages/plugin-openclaw/dist/index.d.ts +0 -49
  282. package/packages/plugin-openclaw/dist/index.js +0 -262
  283. package/packages/plugin-openclaw/openclaw.plugin.json +0 -94
  284. package/packages/plugin-openclaw/package.json +0 -31
  285. package/packages/plugin-opencode/install.mjs +0 -217
  286. package/packages/plugin-opencode/package.json +0 -21
  287. package/scripts/db/check-db.mjs +0 -88
  288. package/scripts/db/fix-all-columns.mjs +0 -52
  289. package/scripts/db/fix-schema-all.mjs +0 -55
  290. package/scripts/db/fix-schema-full.mjs +0 -46
  291. package/scripts/db/fix-schema.mjs +0 -38
  292. package/scripts/db/init-db.mjs +0 -13
  293. package/scripts/db/recreate-db.mjs +0 -14
  294. package/scripts/install-mcp.mjs +0 -116
  295. package/scripts/install-web.sh +0 -120
  296. package/scripts/install.mjs +0 -340
  297. package/scripts/openclaw-bootstrap.mjs +0 -127
  298. package/scripts/package-release.sh +0 -71
  299. package/scripts/test/test-all-systems.mjs +0 -139
  300. package/scripts/test/test-memory-system.mjs +0 -139
  301. package/scripts/test/test-v0.5.0.mjs +0 -210
  302. package/skills/memory-guide/SKILL.md +0 -332
  303. package/skills/squish-cli/SKILL.md +0 -240
  304. package/skills/squish-mcp/SKILL.md +0 -355
  305. package/skills/squish-memory/claude-desktop.json +0 -12
  306. package/skills/squish-memory/openclaw.json +0 -13
  307. package/skills/squish-memory/opencode.json +0 -14
  308. package/skills/squish-memory/skill.json +0 -32
  309. /package/{commands → core/commands}/context-paging.md +0 -0
  310. /package/{commands → core/commands}/context-status.md +0 -0
  311. /package/{commands → core/commands}/context.md +0 -0
  312. /package/{commands → core/commands}/core-memory.md +0 -0
  313. /package/{commands → core/commands}/health.md +0 -0
  314. /package/{commands → core/commands}/merge.md +0 -0
  315. /package/{commands → core/commands}/recall.md +0 -0
  316. /package/{commands → core/commands}/remember.md +0 -0
  317. /package/{commands → core/commands}/search.md +0 -0
  318. /package/dist/{algorithms → core/algorithms}/detection/hash-filters.d.ts +0 -0
  319. /package/dist/{algorithms → core/algorithms}/detection/hash-filters.js +0 -0
  320. /package/dist/{algorithms → core/algorithms}/handlers/approve-merge.d.ts +0 -0
  321. /package/dist/{algorithms → core/algorithms}/handlers/detect-duplicates.d.ts +0 -0
  322. /package/dist/{algorithms → core/algorithms}/handlers/get-stats.d.ts +0 -0
  323. /package/dist/{algorithms → core/algorithms}/handlers/list-proposals.d.ts +0 -0
  324. /package/dist/{algorithms → core/algorithms}/handlers/preview-merge.d.ts +0 -0
  325. /package/dist/{algorithms → core/algorithms}/handlers/reject-merge.d.ts +0 -0
  326. /package/dist/{algorithms → core/algorithms}/handlers/reverse-merge.d.ts +0 -0
  327. /package/dist/{algorithms → core/algorithms}/safety/safety-checks.js +0 -0
  328. /package/dist/{algorithms → core/algorithms}/utils/response-builder.d.ts +0 -0
  329. /package/dist/{algorithms → core/algorithms}/utils/response-builder.js +0 -0
  330. /package/dist/{commands → core/commands}/managed-sync.d.ts +0 -0
  331. /package/dist/{commands → core/commands}/mcp-server.d.ts +0 -0
  332. /package/dist/core/{context.d.ts → context/context.d.ts} +0 -0
  333. /package/dist/core/{agent-memory.d.ts → ingestion/agent-memory.d.ts} +0 -0
  334. /package/dist/core/{core-memory.d.ts → ingestion/core-memory.d.ts} +0 -0
  335. /package/dist/core/{privacy.d.ts → security/privacy.d.ts} +0 -0
  336. /package/dist/core/{privacy.js → security/privacy.js} +0 -0
  337. /package/dist/core/{secret-detector.d.ts → security/secret-detector.d.ts} +0 -0
  338. /package/dist/core/{secret-detector.js → security/secret-detector.js} +0 -0
  339. /package/dist/core/{cache.d.ts → storage/cache.d.ts} +0 -0
  340. /package/dist/core/{database.d.ts → storage/database.d.ts} +0 -0
  341. /package/dist/core/{database.js → storage/database.js} +0 -0
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Input validation utilities for Squish
3
+ * Consolidates scattered validation patterns into a unified module
4
+ */
5
+ import { normalizeTags } from '../memory/serialization.js';
6
+ /**
7
+ * Validate and normalize a limit value with bounds checking
8
+ */
9
+ export function validateLimit(value, defaultValue = 20, min = 1, max = 100) {
10
+ // Handle undefined, null, empty string
11
+ if (value === undefined || value === null || value === '') {
12
+ return defaultValue;
13
+ }
14
+ // Convert string to number, truncate decimals
15
+ let num;
16
+ if (typeof value === 'string') {
17
+ const parsed = parseInt(value, 10);
18
+ if (isNaN(parsed)) {
19
+ return NaN;
20
+ }
21
+ num = parsed;
22
+ }
23
+ else {
24
+ // Truncate decimals for numbers
25
+ num = Math.trunc(value);
26
+ }
27
+ // Handle NaN
28
+ if (isNaN(num)) {
29
+ return NaN;
30
+ }
31
+ // Clamp to bounds
32
+ return Math.min(Math.max(num, min), max);
33
+ }
34
+ /**
35
+ * Parse an integer with bounds checking
36
+ */
37
+ export function parseIntBounded(value, defaultValue, min, max) {
38
+ return validateLimit(value, defaultValue, min, max);
39
+ }
40
+ /**
41
+ * Validate a project path
42
+ */
43
+ export async function validateProjectPath(path, options) {
44
+ const { createIfMissing = false, require: requireProject = false } = options || {};
45
+ // If path is undefined, throw if required or return current directory
46
+ if (path === undefined || path === '') {
47
+ if (requireProject) {
48
+ throw new Error('Project path is required');
49
+ }
50
+ return process.cwd();
51
+ }
52
+ // Resolve to absolute path
53
+ const absolutePath = path.startsWith('/') || /^[a-zA-Z]:\\/.test(path)
54
+ ? path
55
+ : path.startsWith('~')
56
+ ? path.replace(/^~/, process.env.HOME || process.env.USERPROFILE || '')
57
+ : path.startsWith('.')
58
+ ? path
59
+ : path;
60
+ // Check if project exists in database
61
+ const { getProjectByPath } = await import('../projects.js');
62
+ const existingProject = await getProjectByPath(absolutePath);
63
+ if (existingProject) {
64
+ return absolutePath;
65
+ }
66
+ // Project doesn't exist
67
+ if (requireProject) {
68
+ throw new Error(`Project not found: ${absolutePath}`);
69
+ }
70
+ if (createIfMissing) {
71
+ const { ensureProject } = await import('../projects.js');
72
+ await ensureProject(absolutePath);
73
+ return absolutePath;
74
+ }
75
+ // Return the path even if it doesn't exist in database (for non-db validation)
76
+ return absolutePath;
77
+ }
78
+ /**
79
+ * Validate a UUID
80
+ */
81
+ export function validateUuid(id) {
82
+ if (typeof id !== 'string' || !id) {
83
+ return false;
84
+ }
85
+ // UUID v4/v5 regex pattern (8-4-4-4-12 hex digits)
86
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
87
+ return uuidRegex.test(id);
88
+ }
89
+ /**
90
+ * Require a valid UUID, throws if invalid
91
+ */
92
+ export function requireUuid(id) {
93
+ if (!validateUuid(id)) {
94
+ throw new Error('Invalid UUID');
95
+ }
96
+ return id;
97
+ }
98
+ /**
99
+ * Validate a date value
100
+ *
101
+ * @param value - The date to validate (string, Date, number, or undefined)
102
+ * @returns Date object if valid, null otherwise
103
+ */
104
+ export function validateDate(value) {
105
+ if (!value) {
106
+ return null;
107
+ }
108
+ try {
109
+ let date;
110
+ if (value instanceof Date) {
111
+ date = value;
112
+ }
113
+ else if (typeof value === 'number') {
114
+ // Handle both milliseconds and seconds timestamps
115
+ if (value > 100000000000000) {
116
+ // Microseconds, convert to milliseconds
117
+ date = new Date(value / 1000);
118
+ }
119
+ else if (value > 1000000000000) {
120
+ // Milliseconds
121
+ date = new Date(value);
122
+ }
123
+ else if (value >= 0) {
124
+ // Seconds
125
+ date = new Date(value * 1000);
126
+ }
127
+ else {
128
+ return null;
129
+ }
130
+ }
131
+ else if (typeof value === 'string') {
132
+ date = new Date(value);
133
+ }
134
+ else {
135
+ return null;
136
+ }
137
+ // Check if date is valid
138
+ if (isNaN(date.getTime())) {
139
+ return null;
140
+ }
141
+ return date;
142
+ }
143
+ catch {
144
+ return null;
145
+ }
146
+ }
147
+ // Re-export normalizeTags for tag validation
148
+ export { normalizeTags };
149
+ // Re-export clampLimit for backward compatibility
150
+ export { clampLimit } from './utils.js';
151
+ //# sourceMappingURL=validation.js.map
@@ -1,6 +1,12 @@
1
1
  /**
2
2
  * Memory Lifecycle Management
3
3
  * Implements sector-based decay, tier classification, and eviction policies
4
+ *
5
+ * Decay Formula: newScore = importanceScore * (1 - decayRate/100)^days
6
+ * - decayRate: per-memory integer (e.g., 30 = 30% decay per decay cycle)
7
+ * - days: days since lastDecayAt
8
+ * - Tier demotion occurs when score drops below decayThreshold
9
+ * - Cold memories below threshold get status = 'expired'
4
10
  */
5
11
  export interface LifecycleStats {
6
12
  decayed: number;
@@ -11,6 +17,7 @@ export interface LifecycleStats {
11
17
  warm: number;
12
18
  cold: number;
13
19
  };
20
+ expired: number;
14
21
  }
15
22
  /**
16
23
  * Run full lifecycle maintenance on all memories
@@ -1,19 +1,43 @@
1
1
  /**
2
2
  * Memory Lifecycle Management
3
3
  * Implements sector-based decay, tier classification, and eviction policies
4
+ *
5
+ * Decay Formula: newScore = importanceScore * (1 - decayRate/100)^days
6
+ * - decayRate: per-memory integer (e.g., 30 = 30% decay per decay cycle)
7
+ * - days: days since lastDecayAt
8
+ * - Tier demotion occurs when score drops below decayThreshold
9
+ * - Cold memories below threshold get status = 'expired'
4
10
  */
5
11
  import { and, eq, lt, inArray } from 'drizzle-orm';
6
12
  import { getDb } from '../db/index.js';
7
13
  import { getSchema } from '../db/schema.js';
8
14
  import { config } from '../config.js';
9
15
  import { logger } from './logger.js';
10
- const SECTOR_DECAY_RATES = {
16
+ import { triggerTierChange, triggerDecayApplied } from './memory/hooks.js';
17
+ /**
18
+ * Default decay intervals by sector (days until decay check)
19
+ * These determine how often memories in each sector are evaluated for decay
20
+ */
21
+ const SECTOR_DECAY_INTERVAL_DAYS = {
11
22
  episodic: 30,
12
23
  semantic: 90,
13
24
  procedural: 180,
14
25
  autobiographical: 365,
15
26
  working: 7,
16
27
  };
28
+ /**
29
+ * Default decay rates by memory type (percentage per decay cycle)
30
+ * Used as fallback when memory.decayRate is not set
31
+ */
32
+ const DEFAULT_DECAY_RATES = {
33
+ observation: 5,
34
+ fact: 3,
35
+ decision: 2,
36
+ context: 4,
37
+ preference: 3,
38
+ note: 5,
39
+ reflection: 2,
40
+ };
17
41
  const TIER_THRESHOLDS = {
18
42
  hot: { recency: 7, coactivation: 10, salience: 70 },
19
43
  warm: { recency: 30, coactivation: 5, salience: 50 },
@@ -24,13 +48,14 @@ const TIER_THRESHOLDS = {
24
48
  */
25
49
  export async function runLifecycleMaintenance(projectId) {
26
50
  if (!config.lifecycleEnabled) {
27
- return { decayed: 0, evicted: 0, promoted: 0, tierChanges: { hot: 0, warm: 0, cold: 0 } };
51
+ return { decayed: 0, evicted: 0, promoted: 0, tierChanges: { hot: 0, warm: 0, cold: 0 }, expired: 0 };
28
52
  }
29
53
  const stats = {
30
54
  decayed: 0,
31
55
  evicted: 0,
32
56
  promoted: 0,
33
57
  tierChanges: { hot: 0, warm: 0, cold: 0 },
58
+ expired: 0,
34
59
  };
35
60
  try {
36
61
  await applyDecay(projectId, stats);
@@ -43,34 +68,105 @@ export async function runLifecycleMaintenance(projectId) {
43
68
  return stats;
44
69
  }
45
70
  /**
46
- * Apply decay to memories based on sector
71
+ * Apply decay to memories using per-memory decay rate formula
72
+ *
73
+ * Formula: newScore = importanceScore * (1 - decayRate/100)^days
74
+ * - Uses per-memory decayRate (stored as integer percentage, e.g., 30 = 30%)
75
+ * - Calculates days since lastDecayAt
76
+ * - Demotes tier when score drops below decayThreshold
77
+ * - Sets status = 'expired' for cold memories below threshold
47
78
  */
48
79
  async function applyDecay(projectId, stats) {
49
80
  try {
50
81
  const db = await getDb();
51
82
  const schema = await getSchema();
52
83
  const now = new Date();
53
- // For each sector, apply decay
54
- for (const [sector, decayDays] of Object.entries(SECTOR_DECAY_RATES)) {
55
- const decayThreshold = new Date(now.getTime() - decayDays * 24 * 60 * 60 * 1000);
56
- // Build where clause
57
- let where;
58
- if (projectId) {
59
- where = and(eq(schema.memories.sector, sector), eq(schema.memories.projectId, projectId), lt(schema.memories.lastDecayAt, decayThreshold), eq(schema.memories.isProtected, false));
84
+ const decayThreshold = config.decayThreshold || 0.1;
85
+ // Fetch memories that need decay processing (not protected, not expired)
86
+ let whereClause;
87
+ const conditions = [
88
+ eq(schema.memories.isProtected, false),
89
+ eq(schema.memories.status, 'active'),
90
+ ];
91
+ if (projectId) {
92
+ conditions.push(eq(schema.memories.projectId, projectId));
93
+ }
94
+ whereClause = and(...conditions);
95
+ const memories = await db
96
+ .select()
97
+ .from(schema.memories)
98
+ .where(whereClause)
99
+ .limit(10000);
100
+ let decayed = 0;
101
+ let expired = 0;
102
+ const expiredIds = [];
103
+ for (const memory of memories) {
104
+ // Get decay rate for this memory (fallback to type-based default)
105
+ const decayRate = memory.decayRate || DEFAULT_DECAY_RATES[memory.type] || 5;
106
+ // Calculate days since last decay
107
+ const lastDecayAt = memory.lastDecayAt ? new Date(memory.lastDecayAt) : new Date(memory.createdAt);
108
+ const daysSinceDecay = Math.max(0, (now.getTime() - lastDecayAt.getTime()) / (24 * 60 * 60 * 1000));
109
+ // Skip if not enough time has passed for this sector
110
+ const sectorInterval = SECTOR_DECAY_INTERVAL_DAYS[memory.sector] || 30;
111
+ if (daysSinceDecay < sectorInterval) {
112
+ continue;
60
113
  }
61
- else {
62
- where = and(eq(schema.memories.sector, sector), lt(schema.memories.lastDecayAt, decayThreshold), eq(schema.memories.isProtected, false));
114
+ // Apply decay formula: newScore = oldScore * (1 - decayRate/100)^days
115
+ const currentScore = memory.importanceScore || memory.relevanceScore || 50;
116
+ const decayMultiplier = Math.pow(1 - decayRate / 100, daysSinceDecay / sectorInterval);
117
+ const newScore = Math.max(0, Math.round(currentScore * decayMultiplier));
118
+ // Check if memory should expire (cold tier + below threshold)
119
+ const shouldExpire = memory.tier === 'cold' && newScore < (decayThreshold * 100);
120
+ if (shouldExpire) {
121
+ expiredIds.push(memory.id);
122
+ expired++;
123
+ logger.debug('Memory expiring', { id: memory.id, score: newScore, tier: memory.tier });
63
124
  }
64
- // Decay: reduce relevance score by 10%
65
- const result = await db.update(schema.memories)
125
+ else if (newScore !== currentScore) {
126
+ // Only update if score changed
127
+ await db
128
+ .update(schema.memories)
129
+ .set({
130
+ importanceScore: newScore,
131
+ relevanceScore: newScore,
132
+ lastDecayAt: now,
133
+ updatedAt: now,
134
+ })
135
+ .where(eq(schema.memories.id, memory.id));
136
+ decayed++;
137
+ // Trigger decay applied hook
138
+ try {
139
+ await triggerDecayApplied({
140
+ memoryId: memory.id,
141
+ content: memory.content,
142
+ type: memory.type,
143
+ tags: typeof memory.tags === 'string' ? memory.tags.split(',') : [],
144
+ project: memory.projectId || undefined,
145
+ source: memory.source || undefined,
146
+ tier: memory.tier,
147
+ importance: newScore,
148
+ oldScore: currentScore,
149
+ newScore: newScore,
150
+ });
151
+ }
152
+ catch (hookError) {
153
+ logger.error('Error triggering decayApplied hook', hookError);
154
+ }
155
+ }
156
+ }
157
+ // Batch expire memories
158
+ if (expiredIds.length > 0) {
159
+ await db
160
+ .update(schema.memories)
66
161
  .set({
67
- relevanceScore: Math.max(0, schema.memories.relevanceScore * 0.9),
68
- lastDecayAt: now,
162
+ status: 'expired',
163
+ updatedAt: now,
69
164
  })
70
- .where(where);
71
- const rowCount = result?.rowCount || 0;
72
- stats.decayed += rowCount;
165
+ .where(inArray(schema.memories.id, expiredIds));
73
166
  }
167
+ stats.decayed += decayed;
168
+ stats.expired += expired;
169
+ logger.info('Decay applied', { decayed, expired, total: memories.length });
74
170
  }
75
171
  catch (error) {
76
172
  logger.error('Error applying decay', error);
@@ -78,7 +174,6 @@ async function applyDecay(projectId, stats) {
78
174
  }
79
175
  /**
80
176
  * Update memory tiers based on recency, coactivation, and salience
81
- * OPTIMIZED: Uses batched updates instead of individual UPDATE queries
82
177
  */
83
178
  async function updateTiers(projectId, stats) {
84
179
  try {
@@ -146,6 +241,31 @@ async function updateTiers(projectId, stats) {
146
241
  .set({ tier: 'cold', updatedAt: now })
147
242
  .where(inArray(schema.memories.id, coldIds));
148
243
  }
244
+ // Trigger tier change hooks for each memory that changed tier
245
+ if (tierAssignments.size > 0) {
246
+ for (const memory of memories) {
247
+ const newTier = tierAssignments.get(memory.id);
248
+ if (newTier && newTier !== memory.tier) {
249
+ try {
250
+ await triggerTierChange({
251
+ memoryId: memory.id,
252
+ content: memory.content,
253
+ type: memory.type,
254
+ tags: typeof memory.tags === 'string' ? memory.tags.split(',') : [],
255
+ project: memory.projectId || undefined,
256
+ source: memory.source || undefined,
257
+ tier: newTier,
258
+ importance: memory.importanceScore || memory.relevanceScore || 50,
259
+ oldTier: memory.tier,
260
+ newTier: newTier,
261
+ });
262
+ }
263
+ catch (hookError) {
264
+ logger.error('Error triggering tierChange hook', hookError);
265
+ }
266
+ }
267
+ }
268
+ }
149
269
  // Update stats
150
270
  stats.tierChanges.hot = tierCounts.hot;
151
271
  stats.tierChanges.warm = tierCounts.warm;
@@ -2,5 +2,10 @@
2
2
  * Utility functions for local embeddings
3
3
  * Note: Actual embedding generation is in core/embeddings.ts
4
4
  */
5
- export declare function cosineSimilarity(a: number[], b: number[]): number;
5
+ import { cosineSimilarity as vectorCosineSimilarity } from './utils/vector-operations.js';
6
+ /**
7
+ * @deprecated Use cosineSimilarity from core/utils/vector-operations.ts directly.
8
+ * This re-export is for backward compatibility and will be removed in v1.2.0.
9
+ */
10
+ export declare const cosineSimilarity: typeof vectorCosineSimilarity;
6
11
  //# sourceMappingURL=local-embeddings.d.ts.map
@@ -2,19 +2,10 @@
2
2
  * Utility functions for local embeddings
3
3
  * Note: Actual embedding generation is in core/embeddings.ts
4
4
  */
5
- export function cosineSimilarity(a, b) {
6
- if (a.length !== b.length) {
7
- throw new Error('Embeddings must have same dimensions');
8
- }
9
- let dotProduct = 0;
10
- let normA = 0;
11
- let normB = 0;
12
- for (let i = 0; i < a.length; i++) {
13
- dotProduct += a[i] * b[i];
14
- normA += a[i] * a[i];
15
- normB += b[i] * b[i];
16
- }
17
- const denominator = Math.sqrt(normA) * Math.sqrt(normB);
18
- return denominator === 0 ? 0 : dotProduct / denominator;
19
- }
5
+ import { cosineSimilarity as vectorCosineSimilarity } from './utils/vector-operations.js';
6
+ /**
7
+ * @deprecated Use cosineSimilarity from core/utils/vector-operations.ts directly.
8
+ * This re-export is for backward compatibility and will be removed in v1.2.0.
9
+ */
10
+ export const cosineSimilarity = vectorCosineSimilarity;
20
11
  //# sourceMappingURL=local-embeddings.js.map
@@ -1,3 +1,8 @@
1
+ function isQuietMode() {
2
+ return process.env.SQUISH_QUIET !== 'false' &&
3
+ process.env.DEBUG !== 'true' &&
4
+ process.env.DEBUG !== '1';
5
+ }
1
6
  class Logger {
2
7
  prefix;
3
8
  debugEnabled;
@@ -11,7 +16,8 @@ class Logger {
11
16
  return `[${this.prefix}:${level}] ${message}${ctx}`;
12
17
  }
13
18
  info(message, context) {
14
- console.error(this.format('info', message, context));
19
+ if (!isQuietMode())
20
+ console.error(this.format('info', message, context));
15
21
  }
16
22
  warn(message, context) {
17
23
  console.error(this.format('warn', message, context));
@@ -1,5 +1,5 @@
1
1
  import { hybridSearch } from '../memory/hybrid-retrieval.js';
2
- import { rememberMemory, getMemoryById } from '../memory/memories.js';
2
+ import { rememberMemory, getMemory } from '../memory/memories.js';
3
3
  import { getEmbedding } from '../embeddings.js';
4
4
  import { getQMDClient } from '../embeddings/qmd-client.js';
5
5
  import { logger } from '../logger.js';
@@ -83,13 +83,39 @@ export const squishRememberTool = {
83
83
  type: 'string',
84
84
  description: 'Project path',
85
85
  },
86
+ // Rich context fields (Agent 4 feedback)
87
+ source: {
88
+ type: 'string',
89
+ description: 'Source of this memory (e.g., "voice", "chat", "document")',
90
+ },
91
+ reasoning: {
92
+ type: 'string',
93
+ description: 'Why this memory is important',
94
+ },
95
+ context: {
96
+ type: 'string',
97
+ description: 'What triggered this memory',
98
+ },
99
+ examples: {
100
+ type: 'string',
101
+ description: 'When to apply this knowledge',
102
+ },
103
+ exceptions: {
104
+ type: 'string',
105
+ description: 'When NOT to apply this',
106
+ },
107
+ tier: {
108
+ type: 'string',
109
+ description: 'Memory tier: hot (active) or cold (archived)',
110
+ enum: ['hot', 'cold'],
111
+ },
86
112
  },
87
113
  required: ['content'],
88
114
  },
89
115
  },
90
116
  handler: async (args) => {
91
117
  try {
92
- const { content, type = 'observation', tags = [], project } = args;
118
+ const { content, type = 'observation', tags = [], project, source, reasoning, context, examples, exceptions, tier = 'hot' } = args;
93
119
  if (!content) {
94
120
  return errorResult('Content is required');
95
121
  }
@@ -98,6 +124,12 @@ export const squishRememberTool = {
98
124
  type,
99
125
  tags,
100
126
  project,
127
+ source,
128
+ reasoning,
129
+ memoryContext: context,
130
+ examples,
131
+ exceptions,
132
+ tier,
101
133
  });
102
134
  return textResult(`Memory stored: ${memory.id}`);
103
135
  }
@@ -128,7 +160,7 @@ export const squishRecallTool = {
128
160
  if (!memoryId) {
129
161
  return errorResult('Memory ID is required');
130
162
  }
131
- const memory = await getMemoryById(memoryId);
163
+ const memory = await getMemory(memoryId);
132
164
  if (!memory) {
133
165
  return errorResult('Memory not found');
134
166
  }
@@ -80,6 +80,7 @@ export async function categorizeMemory(content, existingTags = []) {
80
80
  decision: 0,
81
81
  context: 0,
82
82
  preference: 0,
83
+ note: 0,
83
84
  };
84
85
  for (const { type, patterns, weight } of MEMORY_TYPE_PATTERNS) {
85
86
  for (const pattern of patterns) {
@@ -1,7 +1,7 @@
1
1
  import { eq, and, sql } from 'drizzle-orm';
2
2
  import { getDb } from '../../db/index.js';
3
3
  import { getSchema } from '../../db/schema.js';
4
- import { createDatabaseClient } from '../../core/database.js';
4
+ import { createDatabaseClient } from '../storage/database.js';
5
5
  export async function detectConflicts(memoryId, proposedContent) {
6
6
  const db = createDatabaseClient(await getDb());
7
7
  const schema = await getSchema();
@@ -1,15 +1,6 @@
1
1
  /**
2
2
  * Memory Consolidation System
3
- *
4
- * Implements experience replay and memory consolidation for Squish.
5
- * Based on research from ReMe (Memory Replay) and LIGHT framework.
6
- *
7
- * Consolidation process:
8
- * 1. Find clusters of old, low-importance memories
9
- * 2. Group related memories by similarity
10
- * 3. Summarize each cluster using extractive summarization
11
- * 4. Create consolidated memory with summary
12
- * 5. Mark originals as consolidated (not deleted - reversible)
3
+ * Implements experience replay and memory consolidation
13
4
  */
14
5
  export interface ConsolidationOptions {
15
6
  projectId: string;
@@ -1,18 +1,9 @@
1
1
  /**
2
2
  * Memory Consolidation System
3
- *
4
- * Implements experience replay and memory consolidation for Squish.
5
- * Based on research from ReMe (Memory Replay) and LIGHT framework.
6
- *
7
- * Consolidation process:
8
- * 1. Find clusters of old, low-importance memories
9
- * 2. Group related memories by similarity
10
- * 3. Summarize each cluster using extractive summarization
11
- * 4. Create consolidated memory with summary
12
- * 5. Mark originals as consolidated (not deleted - reversible)
3
+ * Implements experience replay and memory consolidation
13
4
  */
14
5
  import { eq, inArray } from 'drizzle-orm';
15
- import { createDatabaseClient } from '../database.js';
6
+ import { createDatabaseClient } from '../storage/database.js';
16
7
  import { getDb } from '../../db/index.js';
17
8
  import { getSchema } from '../../db/schema.js';
18
9
  import { cosineSimilarity } from './importance.js';
@@ -1,7 +1,7 @@
1
1
  /** Context Collector - Collect recent conversation context for query rewriting */
2
2
  import { logger } from '../logger.js';
3
3
  import { getDb } from '../../db/index.js';
4
- import { messages, conversations } from '../../drizzle/schema-sqlite.js';
4
+ import { messages, conversations } from '../../db/drizzle/schema-sqlite.js';
5
5
  import { eq, desc } from 'drizzle-orm';
6
6
  export async function collectRecentContext(sessionId, count = 5) {
7
7
  const db = await getDb();
@@ -2,7 +2,7 @@ import { randomUUID } from 'crypto';
2
2
  import { eq, and, sql } from 'drizzle-orm';
3
3
  import { getDb } from '../../db/index.js';
4
4
  import { getSchema } from '../../db/schema.js';
5
- import { createDatabaseClient } from '../../core/database.js';
5
+ import { createDatabaseClient } from '../storage/database.js';
6
6
  export async function createEditProposal(memoryId, currentContent, proposedContent, reason, userId) {
7
7
  const db = createDatabaseClient(await getDb());
8
8
  const schema = await getSchema();
@@ -3,13 +3,13 @@
3
3
  * NO FALLBACKS - real extraction or throw
4
4
  */
5
5
  export async function extractQueryEntities(query, callClaudeFn) {
6
- const prompt = `Extract entities from this question. Return ONLY JSON:
7
- {
8
- "primary": ["Alice", "project name"],
9
- "secondary": ["team", "budget"],
10
- "queryType": "factual"
11
- }
12
-
6
+ const prompt = `Extract entities from this question. Return ONLY JSON:
7
+ {
8
+ "primary": ["Alice", "project name"],
9
+ "secondary": ["team", "budget"],
10
+ "queryType": "factual"
11
+ }
12
+
13
13
  Question: ${query}`;
14
14
  const response = await callClaudeFn(prompt, 500);
15
15
  const jsonMatch = response.match(/\{[\s\S]*\}/);
@@ -13,18 +13,18 @@ export async function extractFacts(text, callClaude) {
13
13
  entities: []
14
14
  };
15
15
  }
16
- const prompt = `Extract atomic facts from this conversation.
17
-
18
- Requirements:
19
- - Extract specific, verifiable facts (names, dates, numbers, relationships)
20
- - Each fact should be a standalone statement
21
- - Identify entities (people, organizations, projects, locations)
22
- - Note temporal information and relationships
23
-
24
- Return ONLY valid JSON in this exact format:
25
- {"facts":[{"content":"fact statement","confidence":0.95,"entities":["Name"],"relation":"optional"}],"summary":"brief summary","entities":["all","entities"]}
26
-
27
- Text to analyze:
16
+ const prompt = `Extract atomic facts from this conversation.
17
+
18
+ Requirements:
19
+ - Extract specific, verifiable facts (names, dates, numbers, relationships)
20
+ - Each fact should be a standalone statement
21
+ - Identify entities (people, organizations, projects, locations)
22
+ - Note temporal information and relationships
23
+
24
+ Return ONLY valid JSON in this exact format:
25
+ {"facts":[{"content":"fact statement","confidence":0.95,"entities":["Name"],"relation":"optional"}],"summary":"brief summary","entities":["all","entities"]}
26
+
27
+ Text to analyze:
28
28
  ${text.substring(0, 4000)}`;
29
29
  const response = await callClaude(prompt, 2000);
30
30
  // Extract JSON - look for the first { and last }
@@ -2,7 +2,7 @@
2
2
  import { logger } from '../logger.js';
3
3
  import { config } from '../../config.js';
4
4
  import { getDb } from '../../db/index.js';
5
- import { memoryFeedback, memories } from '../../drizzle/schema-sqlite.js';
5
+ import { memoryFeedback, memories } from '../../db/drizzle/schema-sqlite.js';
6
6
  import { eq, and } from 'drizzle-orm';
7
7
  import { analyzeResponseForMemoryReferences, mightContainMemoryReferences } from './response-analyzer.js';
8
8
  const injectionTracker = new Map();