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,134 @@
1
+ /**
2
+ * Memory Migration Module
3
+ * Migrate memories between .squish directories/databases
4
+ */
5
+ import { randomUUID } from 'crypto';
6
+ import { existsSync } from 'fs';
7
+ import { join } from 'path';
8
+ import { getDbClient } from '../lib/db-client.js';
9
+ /**
10
+ * Migrate memories from one .squish directory to another
11
+ */
12
+ export async function migrateMemories(sourceDir, targetDir, options = {}) {
13
+ const { dryRun = false, deleteSource = false } = options;
14
+ const sourceDbPath = join(sourceDir, 'squish.db');
15
+ const targetDbPath = join(targetDir, 'squish.db');
16
+ if (!existsSync(sourceDbPath)) {
17
+ throw new Error(`Source database not found: ${sourceDbPath}`);
18
+ }
19
+ if (!existsSync(targetDbPath)) {
20
+ throw new Error(`Target database not found: ${targetDbPath}`);
21
+ }
22
+ // Use bun:sqlite for direct source DB access
23
+ // @ts-ignore - bun:sqlite module not found in types but works at runtime
24
+ const SqliteDatabase = (await import('bun:sqlite')).default;
25
+ const sourceDb = new SqliteDatabase(sourceDbPath, { readonly: true });
26
+ // Get target DB through the app's existing mechanism
27
+ const { db: targetDb, schema } = await getDbClient();
28
+ // Get all projects from source
29
+ const sourceProjects = sourceDb.query('SELECT * FROM projects').all();
30
+ // Map old project IDs to new project IDs
31
+ const projectIdMap = new Map();
32
+ for (const project of sourceProjects) {
33
+ // Check if project with same path exists in target
34
+ const existing = await targetDb.select()
35
+ .from(schema.projects)
36
+ .where((tbl, { eq }) => eq(tbl.path, project.path))
37
+ .limit(1);
38
+ if (existing.length > 0) {
39
+ projectIdMap.set(project.id, existing[0].id);
40
+ }
41
+ else {
42
+ // Create new project in target
43
+ const newId = randomUUID();
44
+ await targetDb.insert(schema.projects).values({
45
+ id: newId,
46
+ path: project.path,
47
+ name: project.name || 'migrated',
48
+ createdAt: new Date(),
49
+ });
50
+ projectIdMap.set(project.id, newId);
51
+ }
52
+ }
53
+ // Migrate memories
54
+ const sourceMemories = sourceDb.query('SELECT * FROM memories').all();
55
+ let memoriesCopied = 0;
56
+ for (const mem of sourceMemories) {
57
+ const oldProjectId = mem.project_id;
58
+ const newProjectId = projectIdMap.get(oldProjectId);
59
+ if (!newProjectId) {
60
+ console.warn(`Skipping memory ${mem.id}: no project mapping found`);
61
+ continue;
62
+ }
63
+ if (!dryRun) {
64
+ // Add 'imported' tag to track migrated memories
65
+ const existingTags = mem.tags ? JSON.parse(mem.tags) : [];
66
+ const newTags = [...existingTags, 'imported'];
67
+ await targetDb.insert(schema.memories).values({
68
+ id: randomUUID(),
69
+ projectId: newProjectId,
70
+ type: mem.type,
71
+ content: mem.content,
72
+ summary: mem.summary,
73
+ source: mem.source || 'migrated',
74
+ confidence: mem.confidence ?? 50,
75
+ confidenceLevel: mem.confidence_level || 'speculative',
76
+ tags: newTags,
77
+ metadata: { ...mem.metadata, migratedAt: new Date().toISOString(), originalId: mem.id },
78
+ isActive: mem.is_active ?? 1,
79
+ createdAt: mem.created_at ? new Date(mem.created_at * 1000) : new Date(),
80
+ updatedAt: new Date(),
81
+ });
82
+ }
83
+ memoriesCopied++;
84
+ }
85
+ // Migrate learnings (renamed from observations)
86
+ const sourceLearnings = sourceDb.query('SELECT * FROM learnings').all();
87
+ let learningsCopied = 0;
88
+ for (const learn of sourceLearnings) {
89
+ const oldProjectId = learn.project_id;
90
+ const newProjectId = projectIdMap.get(oldProjectId);
91
+ if (!newProjectId)
92
+ continue;
93
+ if (!dryRun) {
94
+ // Add is_imported flag to track migrated learnings
95
+ await targetDb.insert(schema.learnings).values({
96
+ id: randomUUID(),
97
+ projectId: newProjectId,
98
+ type: learn.type,
99
+ action: learn.action,
100
+ summary: learn.summary,
101
+ target: learn.target,
102
+ details: learn.details,
103
+ isImported: true,
104
+ createdAt: new Date(),
105
+ });
106
+ }
107
+ learningsCopied++;
108
+ }
109
+ // Migrate memory associations (simplified - skip for now)
110
+ const sourceAssoc = sourceDb.query('SELECT * FROM memory_associations').all();
111
+ let associationsCopied = 0;
112
+ if (!dryRun && sourceAssoc.length > 0) {
113
+ console.warn(`Note: ${sourceAssoc.length} associations not migrated (requires ID mapping)`);
114
+ }
115
+ // Close source DB
116
+ sourceDb.close();
117
+ // Delete source if requested
118
+ let sourceDeleted = false;
119
+ if (!dryRun && deleteSource && memoriesCopied > 0) {
120
+ // Implementation would delete the file
121
+ console.warn('Source deletion not implemented - requires manual removal');
122
+ }
123
+ return {
124
+ memoriesCopied,
125
+ observationsCopied: learningsCopied,
126
+ associationsCopied,
127
+ projectsMapped: projectIdMap.size,
128
+ sourceDeleted,
129
+ message: dryRun
130
+ ? 'Dry run complete - no changes made'
131
+ : `Successfully migrated ${memoriesCopied} memories, ${learningsCopied} learnings`
132
+ };
133
+ }
134
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Memory normalization utilities
3
+ * Shared between memories.ts and loader.ts to avoid circular dependencies
4
+ */
5
+ export interface MemoryRecord {
6
+ id: string;
7
+ projectId?: string | null;
8
+ type: string;
9
+ content: string;
10
+ summary?: string | null;
11
+ tags: string[];
12
+ metadata?: Record<string, unknown> | null;
13
+ createdAt?: string | null;
14
+ validFrom?: string | null;
15
+ validTo?: string | null;
16
+ recordedAt?: string | null;
17
+ similarity?: number;
18
+ importance?: number;
19
+ confidenceLevel?: 'certain' | 'speculative' | 'outdated' | null;
20
+ }
21
+ export declare function normalizeMemory(row: any): MemoryRecord;
22
+ //# sourceMappingURL=normalization.d.ts.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Memory normalization utilities
3
+ * Shared between memories.ts and loader.ts to avoid circular dependencies
4
+ */
5
+ import { deserializeTags, deserializeMetadata } from './serialization.js';
6
+ import { normalizeTimestamp } from '../lib/utils.js';
7
+ export function normalizeMemory(row) {
8
+ const tags = deserializeTags(row.tags ?? null);
9
+ const metadata = deserializeMetadata(row.metadata ?? null);
10
+ const createdAtStr = normalizeTimestamp(row.createdAt ?? row.created_at);
11
+ return {
12
+ id: row.id,
13
+ projectId: row.projectId ?? row.project_id ?? null,
14
+ type: row.type,
15
+ content: row.content,
16
+ summary: row.summary ?? null,
17
+ tags,
18
+ metadata,
19
+ createdAt: createdAtStr,
20
+ validFrom: row.validFrom ?? row.valid_from ?? null,
21
+ validTo: row.validTo ?? row.valid_to ?? null,
22
+ recordedAt: row.recordedAt ?? row.recorded_at ?? null,
23
+ confidenceLevel: row.confidenceLevel ?? row.confidence_level ?? null,
24
+ };
25
+ }
26
+ //# sourceMappingURL=normalization.js.map
@@ -2,7 +2,7 @@ import { randomUUID } from 'crypto';
2
2
  import { eq, desc, 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
  const PREVIEW_TOKENS = 50;
7
7
  const MAX_PRELOAD_CANDIDATES = 20;
8
8
  const TOKEN_ESTIMATE_CHARS = 4;
@@ -2,15 +2,15 @@
2
2
  import { logger } from '../logger.js';
3
3
  import { config } from '../../config.js';
4
4
  import { expandQuery } from './query-processor.js';
5
- const REWRITE_SYSTEM_PROMPT = `You are a search query optimizer. Given a conversation context and a user's latest message, rewrite the message into the single most effective search query to retrieve relevant memories.
6
-
7
- Rules:
8
- 1. Output ONLY the optimized search query - no explanations or extra text
9
- 2. Remove filler words (please, can you, etc.)
10
- 3. Focus on the core information need
11
- 4. Preserve important entities (names, dates, technical terms)
12
- 5. Add synonyms for key terms if helpful
13
- 6. Consider what memories would be most relevant
5
+ const REWRITE_SYSTEM_PROMPT = `You are a search query optimizer. Given a conversation context and a user's latest message, rewrite the message into the single most effective search query to retrieve relevant memories.
6
+
7
+ Rules:
8
+ 1. Output ONLY the optimized search query - no explanations or extra text
9
+ 2. Remove filler words (please, can you, etc.)
10
+ 3. Focus on the core information need
11
+ 4. Preserve important entities (names, dates, technical terms)
12
+ 5. Add synonyms for key terms if helpful
13
+ 6. Consider what memories would be most relevant
14
14
  7. If the message is about recalling something specific, include those details`;
15
15
  export async function rewriteQuery(query, context) {
16
16
  if (!config.queryRewritingEnabled) {
@@ -3,4 +3,8 @@ export declare function toSqliteJson(value: unknown): string | null;
3
3
  export declare function fromSqliteJson<T>(value: string | null | undefined): T | null;
4
4
  export declare function toSqliteTags(tags?: string[]): string | null;
5
5
  export declare function fromSqliteTags(value: string | null | undefined): string[];
6
+ export declare function serializeTags(tags?: string[]): string[] | string | null | undefined;
7
+ export declare function deserializeTags(value: string[] | string | null | undefined): string[];
8
+ export declare function serializeMetadata(metadata: Record<string, unknown> | null | undefined): Record<string, unknown> | string | null;
9
+ export declare function deserializeMetadata(value: Record<string, unknown> | string | null | undefined): Record<string, unknown> | null;
6
10
  //# sourceMappingURL=serialization.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { config } from '../../config.js';
1
2
  export function normalizeTags(tags) {
2
3
  return (tags || []).map((tag) => tag.trim()).filter((tag) => tag.length > 0);
3
4
  }
@@ -32,4 +33,52 @@ export function fromSqliteTags(value) {
32
33
  return value.split(',').map((tag) => tag.trim()).filter(Boolean);
33
34
  }
34
35
  }
36
+ // High-level helpers that abstract away team mode vs local mode
37
+ export function serializeTags(tags) {
38
+ if (config.isTeamMode) {
39
+ // PostgreSQL: store as array directly (or null if empty)
40
+ return tags && tags.length > 0 ? tags : null;
41
+ }
42
+ else {
43
+ // SQLite: store as JSON string (or null)
44
+ return toSqliteTags(tags);
45
+ }
46
+ }
47
+ export function deserializeTags(value) {
48
+ if (config.isTeamMode) {
49
+ // PostgreSQL: value is already an array or null/undefined
50
+ return Array.isArray(value) ? value : [];
51
+ }
52
+ else {
53
+ // SQLite: value is a JSON string or null/undefined
54
+ if (typeof value === 'string' || value === null || value === undefined) {
55
+ return fromSqliteTags(value);
56
+ }
57
+ // Unexpected type, return empty array
58
+ return [];
59
+ }
60
+ }
61
+ export function serializeMetadata(metadata) {
62
+ if (config.isTeamMode) {
63
+ // PostgreSQL: store object directly (or null if null/undefined, keep empty object as-is)
64
+ return metadata === undefined || metadata === null ? null : metadata;
65
+ }
66
+ else {
67
+ // SQLite: store as JSON string (or null)
68
+ return toSqliteJson(metadata);
69
+ }
70
+ }
71
+ export function deserializeMetadata(value) {
72
+ if (config.isTeamMode) {
73
+ // PostgreSQL: value is already an object or null/undefined
74
+ return value == null ? null : value;
75
+ }
76
+ else {
77
+ // SQLite: value is a JSON string or null/undefined
78
+ if (typeof value === 'string' || value === null) {
79
+ return fromSqliteJson(value);
80
+ }
81
+ return null;
82
+ }
83
+ }
35
84
  //# sourceMappingURL=serialization.js.map
@@ -5,6 +5,11 @@
5
5
  export interface MemoryStats {
6
6
  totalMemories: number;
7
7
  byType: Record<string, number>;
8
+ totalNotes: number;
9
+ notesByCategory: Record<string, number>;
10
+ totalLearnings: number;
11
+ learningsByType: Record<string, number>;
12
+ totalLinks: number;
8
13
  oldestMemory?: string;
9
14
  newestMemory?: string;
10
15
  projectPath: string;
@@ -5,8 +5,8 @@
5
5
  import { getDb } from '../../db/index.js';
6
6
  import { getSchema } from '../../db/schema.js';
7
7
  import { config } from '../../config.js';
8
- import { getProjectByPath } from '../../core/projects.js';
9
- import { createDatabaseClient } from '../../core/database.js';
8
+ import { requireProject } from '../../core/projects.js';
9
+ import { createDatabaseClient } from '../storage/database.js';
10
10
  /**
11
11
  * Get memory statistics for a project
12
12
  */
@@ -19,10 +19,15 @@ export async function getMemoryStats(projectPath = process.cwd()) {
19
19
  throw new Error(`Database unavailable: ${error instanceof Error ? error.message : 'Unknown error'}`);
20
20
  }
21
21
  const schema = await getSchema();
22
- const project = await getProjectByPath(projectPath);
22
+ const project = await requireProject(projectPath);
23
23
  const stats = {
24
24
  totalMemories: 0,
25
25
  byType: {},
26
+ totalNotes: 0,
27
+ notesByCategory: {},
28
+ totalLearnings: 0,
29
+ learningsByType: {},
30
+ totalLinks: 0,
26
31
  projectPath,
27
32
  mode: config.isTeamMode ? 'team' : 'local'
28
33
  };
@@ -31,16 +36,16 @@ export async function getMemoryStats(projectPath = process.cwd()) {
31
36
  const countResult = await db
32
37
  .select({ count: schema.memories.id })
33
38
  .from(schema.memories)
34
- .where(project ? eq(schema.memories.projectId, project.id) : undefined);
39
+ .where(eq(schema.memories.projectId, project.id));
35
40
  stats.totalMemories = countResult.length;
36
41
  // Count by type
37
42
  if (config.isTeamMode) {
38
43
  // PostgreSQL - use raw query for GROUP BY
39
- const typeCounts = await db.execute(sql `
40
- SELECT type, COUNT(*) as count
41
- FROM memories
42
- ${project ? sql `WHERE project_id = ${project.id}` : sql ``}
43
- GROUP BY type
44
+ const typeCounts = await db.execute(sql `
45
+ SELECT type, COUNT(*) as count
46
+ FROM memories
47
+ ${sql `WHERE project_id = ${project.id}`}
48
+ GROUP BY type
44
49
  `);
45
50
  for (const row of typeCounts.rows) {
46
51
  stats.byType[row.type] = Number(row.count);
@@ -51,7 +56,7 @@ export async function getMemoryStats(projectPath = process.cwd()) {
51
56
  const allMemories = await db
52
57
  .select({ type: schema.memories.type })
53
58
  .from(schema.memories)
54
- .where(project ? eq(schema.memories.projectId, project.id) : undefined);
59
+ .where(eq(schema.memories.projectId, project.id));
55
60
  for (const mem of allMemories) {
56
61
  const type = mem.type || 'unknown';
57
62
  stats.byType[type] = (stats.byType[type] || 0) + 1;
@@ -61,13 +66,13 @@ export async function getMemoryStats(projectPath = process.cwd()) {
61
66
  const oldest = await db
62
67
  .select({ createdAt: schema.memories.createdAt })
63
68
  .from(schema.memories)
64
- .where(project ? eq(schema.memories.projectId, project.id) : undefined)
69
+ .where(eq(schema.memories.projectId, project.id))
65
70
  .orderBy(asc(schema.memories.createdAt))
66
71
  .limit(1);
67
72
  const newest = await db
68
73
  .select({ createdAt: schema.memories.createdAt })
69
74
  .from(schema.memories)
70
- .where(project ? eq(schema.memories.projectId, project.id) : undefined)
75
+ .where(eq(schema.memories.projectId, project.id))
71
76
  .orderBy(desc(schema.memories.createdAt))
72
77
  .limit(1);
73
78
  if (oldest.length > 0 && oldest[0].createdAt) {
@@ -76,6 +81,52 @@ export async function getMemoryStats(projectPath = process.cwd()) {
76
81
  if (newest.length > 0 && newest[0].createdAt) {
77
82
  stats.newestMemory = newest[0].createdAt;
78
83
  }
84
+ // Learnings
85
+ const allLearnings = await db
86
+ .select({ category: schema.learnings.category, type: schema.learnings.type })
87
+ .from(schema.learnings)
88
+ .where(eq(schema.learnings.projectId, project.id));
89
+ stats.totalNotes = allLearnings.length;
90
+ for (const obs of allLearnings) {
91
+ const cat = obs.category || 'uncategorized';
92
+ stats.notesByCategory[cat] = (stats.notesByCategory[cat] || 0) + 1;
93
+ }
94
+ // Learnings by type
95
+ const learningTypes = ['success', 'failure', 'fix', 'insight'];
96
+ const learningRecords = allLearnings.filter((o) => {
97
+ const type = o.type || '';
98
+ return learningTypes.includes(type.toLowerCase());
99
+ });
100
+ stats.totalLearnings = learningRecords.length;
101
+ // Count by type
102
+ for (const obs of learningRecords) {
103
+ const type = obs.type || 'unknown';
104
+ stats.learningsByType[type] = (stats.learningsByType[type] || 0) + 1;
105
+ }
106
+ // Links
107
+ // Links are scoped via their associated memories
108
+ if (config.isTeamMode) {
109
+ // PostgreSQL - use raw query to join through memories
110
+ const linksCount = await db.execute(sql `
111
+ SELECT COUNT(*) as count FROM memory_associations ma
112
+ JOIN memories m1 ON ma.from_memory_id = m1.id
113
+ JOIN memories m2 ON ma.to_memory_id = m2.id
114
+ ${project ? sql `WHERE m1.project_id = ${project.id} OR m2.project_id = ${project.id}` : sql ``}
115
+ `);
116
+ stats.totalLinks = Number(linksCount.rows[0]?.count || 0);
117
+ }
118
+ else {
119
+ // SQLite - get all and filter in memory
120
+ const allLinks = await db
121
+ .select({
122
+ fromProjectId: schema.memories.projectId,
123
+ toProjectId: schema.memories.projectId
124
+ })
125
+ .from(schema.memoryAssociations)
126
+ .innerJoin(schema.memories, eq(schema.memoryAssociations.fromMemoryId, schema.memories.id))
127
+ .where(project ? eq(schema.memories.projectId, project.id) : undefined);
128
+ stats.totalLinks = allLinks.length;
129
+ }
79
130
  }
80
131
  catch (error) {
81
132
  // Return empty stats on error
@@ -16,6 +16,10 @@ import { parseTemporalFacts } from './temporal-parser.js';
16
16
  export async function checkTemporalValidity(memoryId) {
17
17
  try {
18
18
  const db = await getDb();
19
+ if (!db) {
20
+ // Graceful fallback when database is unavailable
21
+ return { isValid: true, confidence: 0.5 };
22
+ }
19
23
  const schema = await getSchema();
20
24
  const memories = await db
21
25
  .select()
@@ -75,6 +79,10 @@ export async function supersedeOldTemporalFacts(newMemoryId, content, projectId)
75
79
  };
76
80
  try {
77
81
  const db = await getDb();
82
+ if (!db) {
83
+ // Graceful fallback when database is unavailable
84
+ return result;
85
+ }
78
86
  const schema = await getSchema();
79
87
  // Parse temporal facts from new content
80
88
  const temporalFacts = await parseTemporalFacts(content);
@@ -180,6 +188,10 @@ export async function cleanupExpiredTemporalFacts(projectId) {
180
188
  let expiredCount = 0;
181
189
  try {
182
190
  const db = await getDb();
191
+ if (!db) {
192
+ // Graceful fallback when database is unavailable
193
+ return 0;
194
+ }
183
195
  const schema = await getSchema();
184
196
  const now = new Date();
185
197
  const whereClause = projectId
@@ -217,6 +229,15 @@ export async function cleanupExpiredTemporalFacts(projectId) {
217
229
  export async function getTemporalFactsStats(projectId) {
218
230
  try {
219
231
  const db = await getDb();
232
+ if (!db) {
233
+ // Graceful fallback when database is unavailable
234
+ return {
235
+ totalTemporalFacts: 0,
236
+ validFacts: 0,
237
+ expiredFacts: 0,
238
+ supersededFacts: 0,
239
+ };
240
+ }
220
241
  const schema = await getSchema();
221
242
  const now = new Date();
222
243
  const whereClause = projectId
@@ -3,7 +3,7 @@
3
3
  * Validates memories before writing to ensure quality, security, and consistency
4
4
  * Integrates secret detection, trigger detection, and content validation
5
5
  */
6
- import { detectSecrets, redactSecrets } from '../secret-detector.js';
6
+ import { detectSecrets, redactSecrets } from '../security/secret-detector.js';
7
7
  import { detectMemorySignals } from './trigger-detector.js';
8
8
  import { resolveContradictions } from './contradiction-resolver.js';
9
9
  import { logger } from '../logger.js';
@@ -0,0 +1,30 @@
1
+ /** Obsidian Vault Integration
2
+ *
3
+ * Appends hot memories to Obsidian daily notes
4
+ * Format: YYYY-MM-DD.md with memory blocks
5
+ */
6
+ export interface ObsidianMemoryInput {
7
+ content: string;
8
+ id: string;
9
+ type: string;
10
+ tags: string[];
11
+ reasoning?: string;
12
+ memoryContext?: string;
13
+ examples?: string;
14
+ exceptions?: string;
15
+ source?: string;
16
+ }
17
+ /**
18
+ * Append a memory to the daily note in Obsidian vault
19
+ * Creates YYYY-MM-DD.md file if it doesn't exist
20
+ */
21
+ export declare function appendToObsidianVault(memory: ObsidianMemoryInput, vaultPath: string): Promise<void>;
22
+ /**
23
+ * Check if Obsidian vault is connected and accessible
24
+ */
25
+ export declare function isObsidianConnected(vaultPath: string): boolean;
26
+ /**
27
+ * Read existing memories from Obsidian vault (for future import feature)
28
+ */
29
+ export declare function readFromVault(vaultPath: string): Promise<ObsidianMemoryInput[]>;
30
+ //# sourceMappingURL=obsidian-vault.d.ts.map
@@ -0,0 +1,94 @@
1
+ /** Obsidian Vault Integration
2
+ *
3
+ * Appends hot memories to Obsidian daily notes
4
+ * Format: YYYY-MM-DD.md with memory blocks
5
+ */
6
+ import { existsSync, mkdirSync, appendFileSync } from 'fs';
7
+ import { join } from 'path';
8
+ import { logger } from './logger.js';
9
+ /**
10
+ * Append a memory to the daily note in Obsidian vault
11
+ * Creates YYYY-MM-DD.md file if it doesn't exist
12
+ */
13
+ export async function appendToObsidianVault(memory, vaultPath) {
14
+ const today = new Date();
15
+ const year = today.getFullYear();
16
+ const month = String(today.getMonth() + 1).padStart(2, '0');
17
+ const day = String(today.getDate()).padStart(2, '0');
18
+ const dateStr = `${year}-${month}-${day}`;
19
+ const dailyNotePath = join(vaultPath, `${dateStr}.md`);
20
+ // Ensure vault directory exists
21
+ if (!existsSync(vaultPath)) {
22
+ mkdirSync(vaultPath, { recursive: true });
23
+ logger.info(`[Obsidian] Created vault directory: ${vaultPath}`);
24
+ }
25
+ // Build memory block content
26
+ const memoryBlock = formatMemoryAsBlock(memory);
27
+ // Check if daily note exists, if not create with header
28
+ if (!existsSync(dailyNotePath)) {
29
+ const header = `# ${dateStr}\n\n## Squish Memories\n\n`;
30
+ appendFileSync(dailyNotePath, header, 'utf-8');
31
+ logger.info(`[Obsidian] Created daily note: ${dailyNotePath}`);
32
+ }
33
+ // Append memory block
34
+ appendFileSync(dailyNotePath, memoryBlock + '\n\n', 'utf-8');
35
+ logger.info(`[Obsidian] Appended memory to ${dateStr}.md`);
36
+ }
37
+ /**
38
+ * Format memory as Obsidian-compatible block
39
+ */
40
+ function formatMemoryAsBlock(memory) {
41
+ const lines = [];
42
+ // Memory content as checkbox (can be toggled in Obsidian)
43
+ lines.push(`- [ ] "${memory.content}"`);
44
+ // Add ID reference for linking
45
+ lines.push(` - **id:** \`${memory.id}\``);
46
+ // Type and tags
47
+ if (memory.type) {
48
+ lines.push(` - **type:** ${memory.type}`);
49
+ }
50
+ if (memory.tags && memory.tags.length > 0) {
51
+ const tagList = memory.tags.map(t => `#${t.replace(/\s+/g, '-')}`).join(' ');
52
+ lines.push(` - **tags:** ${tagList}`);
53
+ }
54
+ // Rich context fields
55
+ if (memory.source) {
56
+ lines.push(` - **source:** ${memory.source}`);
57
+ }
58
+ if (memory.reasoning) {
59
+ lines.push(` - **reasoning:** ${memory.reasoning}`);
60
+ }
61
+ if (memory.memoryContext) {
62
+ lines.push(` - **context:** ${memory.memoryContext}`);
63
+ }
64
+ if (memory.examples) {
65
+ lines.push(` - **examples:** ${memory.examples}`);
66
+ }
67
+ if (memory.exceptions) {
68
+ lines.push(` - **exceptions:** ${memory.exceptions}`);
69
+ }
70
+ return lines.join('\n');
71
+ }
72
+ /**
73
+ * Check if Obsidian vault is connected and accessible
74
+ */
75
+ export function isObsidianConnected(vaultPath) {
76
+ if (!vaultPath || vaultPath === '') {
77
+ return false;
78
+ }
79
+ // Check if path exists or can be created
80
+ const parentDir = vaultPath.includes('/')
81
+ ? vaultPath.split('/').slice(0, -1).join('/')
82
+ : vaultPath.split('\\').slice(0, -1).join('\\');
83
+ return existsSync(parentDir) || true; // Assume creatable if parent exists
84
+ }
85
+ /**
86
+ * Read existing memories from Obsidian vault (for future import feature)
87
+ */
88
+ export async function readFromVault(vaultPath) {
89
+ // Future: Read .md files and parse memory blocks
90
+ // For MVP, this is placeholder
91
+ logger.info(`[Obsidian] readFromVault called for: ${vaultPath}`);
92
+ return [];
93
+ }
94
+ //# sourceMappingURL=obsidian-vault.js.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Places Module - Spatial memory organization (Method of Loci)
3
+ *
4
+ * Exports:
5
+ * - places.ts: CRUD operations for places
6
+ * - rules.ts: Auto-assignment rules engine
7
+ * - memory-places.ts: Memory-to-place assignments
8
+ * - walking.ts: Sequential walking through places
9
+ */
10
+ export * from './places.js';
11
+ export * from './rules.js';
12
+ export * from './memory-places.js';
13
+ export * from './walking.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Places Module - Spatial memory organization (Method of Loci)
3
+ *
4
+ * Exports:
5
+ * - places.ts: CRUD operations for places
6
+ * - rules.ts: Auto-assignment rules engine
7
+ * - memory-places.ts: Memory-to-place assignments
8
+ * - walking.ts: Sequential walking through places
9
+ */
10
+ export * from './places.js';
11
+ export * from './rules.js';
12
+ export * from './memory-places.js';
13
+ export * from './walking.js';
14
+ //# sourceMappingURL=index.js.map