@ijfw/memory-server 1.4.4 → 1.5.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 (232) hide show
  1. package/fixtures/truncation-corpus/_generate-corpus.js +367 -0
  2. package/fixtures/truncation-corpus/fx-01-clean-exit-01/events.jsonl +2 -0
  3. package/fixtures/truncation-corpus/fx-01-clean-exit-01/intent-journal.jsonl +2 -0
  4. package/fixtures/truncation-corpus/fx-01-clean-exit-01/meta.json +18 -0
  5. package/fixtures/truncation-corpus/fx-01-clean-exit-01/target/.ijfw/state/workflow.json +1 -0
  6. package/fixtures/truncation-corpus/fx-01-clean-exit-02/events.jsonl +2 -0
  7. package/fixtures/truncation-corpus/fx-01-clean-exit-02/intent-journal.jsonl +2 -0
  8. package/fixtures/truncation-corpus/fx-01-clean-exit-02/meta.json +18 -0
  9. package/fixtures/truncation-corpus/fx-01-clean-exit-02/target/.ijfw/state/workflow.json +1 -0
  10. package/fixtures/truncation-corpus/fx-01-clean-exit-03/events.jsonl +2 -0
  11. package/fixtures/truncation-corpus/fx-01-clean-exit-03/intent-journal.jsonl +2 -0
  12. package/fixtures/truncation-corpus/fx-01-clean-exit-03/meta.json +18 -0
  13. package/fixtures/truncation-corpus/fx-01-clean-exit-03/target/.ijfw/state/workflow.json +1 -0
  14. package/fixtures/truncation-corpus/fx-01-clean-exit-04/events.jsonl +2 -0
  15. package/fixtures/truncation-corpus/fx-01-clean-exit-04/intent-journal.jsonl +2 -0
  16. package/fixtures/truncation-corpus/fx-01-clean-exit-04/meta.json +18 -0
  17. package/fixtures/truncation-corpus/fx-01-clean-exit-04/target/.ijfw/state/workflow.json +1 -0
  18. package/fixtures/truncation-corpus/fx-01-clean-exit-05/events.jsonl +2 -0
  19. package/fixtures/truncation-corpus/fx-01-clean-exit-05/intent-journal.jsonl +2 -0
  20. package/fixtures/truncation-corpus/fx-01-clean-exit-05/meta.json +18 -0
  21. package/fixtures/truncation-corpus/fx-01-clean-exit-05/target/.ijfw/state/workflow.json +1 -0
  22. package/fixtures/truncation-corpus/fx-02-mid-overwrite-01/events.jsonl +1 -0
  23. package/fixtures/truncation-corpus/fx-02-mid-overwrite-01/intent-journal.jsonl +3 -0
  24. package/fixtures/truncation-corpus/fx-02-mid-overwrite-01/meta.json +18 -0
  25. package/fixtures/truncation-corpus/fx-02-mid-overwrite-01/snapshots/v-midO-1-advance.json +11 -0
  26. package/fixtures/truncation-corpus/fx-02-mid-overwrite-01/target/.ijfw/state/workflow.json +1 -0
  27. package/fixtures/truncation-corpus/fx-02-mid-overwrite-02/events.jsonl +1 -0
  28. package/fixtures/truncation-corpus/fx-02-mid-overwrite-02/intent-journal.jsonl +3 -0
  29. package/fixtures/truncation-corpus/fx-02-mid-overwrite-02/meta.json +18 -0
  30. package/fixtures/truncation-corpus/fx-02-mid-overwrite-02/snapshots/v-midO-2-advance.json +11 -0
  31. package/fixtures/truncation-corpus/fx-02-mid-overwrite-02/target/.ijfw/state/workflow.json +1 -0
  32. package/fixtures/truncation-corpus/fx-02-mid-overwrite-03/events.jsonl +1 -0
  33. package/fixtures/truncation-corpus/fx-02-mid-overwrite-03/intent-journal.jsonl +3 -0
  34. package/fixtures/truncation-corpus/fx-02-mid-overwrite-03/meta.json +18 -0
  35. package/fixtures/truncation-corpus/fx-02-mid-overwrite-03/snapshots/v-midO-3-advance.json +11 -0
  36. package/fixtures/truncation-corpus/fx-02-mid-overwrite-03/target/.ijfw/state/workflow.json +1 -0
  37. package/fixtures/truncation-corpus/fx-02-mid-overwrite-04/events.jsonl +1 -0
  38. package/fixtures/truncation-corpus/fx-02-mid-overwrite-04/intent-journal.jsonl +3 -0
  39. package/fixtures/truncation-corpus/fx-02-mid-overwrite-04/meta.json +18 -0
  40. package/fixtures/truncation-corpus/fx-02-mid-overwrite-04/snapshots/v-midO-4-advance.json +11 -0
  41. package/fixtures/truncation-corpus/fx-02-mid-overwrite-04/target/.ijfw/state/workflow.json +1 -0
  42. package/fixtures/truncation-corpus/fx-02-mid-overwrite-05/events.jsonl +1 -0
  43. package/fixtures/truncation-corpus/fx-02-mid-overwrite-05/intent-journal.jsonl +3 -0
  44. package/fixtures/truncation-corpus/fx-02-mid-overwrite-05/meta.json +18 -0
  45. package/fixtures/truncation-corpus/fx-02-mid-overwrite-05/snapshots/v-midO-5-advance.json +11 -0
  46. package/fixtures/truncation-corpus/fx-02-mid-overwrite-05/target/.ijfw/state/workflow.json +1 -0
  47. package/fixtures/truncation-corpus/fx-03-mid-append-01/events.jsonl +1 -0
  48. package/fixtures/truncation-corpus/fx-03-mid-append-01/intent-journal.jsonl +3 -0
  49. package/fixtures/truncation-corpus/fx-03-mid-append-01/meta.json +18 -0
  50. package/fixtures/truncation-corpus/fx-03-mid-append-01/target/.ijfw/blackboard/decisions.jsonl +1 -0
  51. package/fixtures/truncation-corpus/fx-03-mid-append-02/events.jsonl +1 -0
  52. package/fixtures/truncation-corpus/fx-03-mid-append-02/intent-journal.jsonl +3 -0
  53. package/fixtures/truncation-corpus/fx-03-mid-append-02/meta.json +18 -0
  54. package/fixtures/truncation-corpus/fx-03-mid-append-02/target/.ijfw/blackboard/decisions.jsonl +1 -0
  55. package/fixtures/truncation-corpus/fx-03-mid-append-03/events.jsonl +1 -0
  56. package/fixtures/truncation-corpus/fx-03-mid-append-03/intent-journal.jsonl +3 -0
  57. package/fixtures/truncation-corpus/fx-03-mid-append-03/meta.json +18 -0
  58. package/fixtures/truncation-corpus/fx-03-mid-append-03/target/.ijfw/blackboard/decisions.jsonl +1 -0
  59. package/fixtures/truncation-corpus/fx-03-mid-append-04/events.jsonl +1 -0
  60. package/fixtures/truncation-corpus/fx-03-mid-append-04/intent-journal.jsonl +3 -0
  61. package/fixtures/truncation-corpus/fx-03-mid-append-04/meta.json +18 -0
  62. package/fixtures/truncation-corpus/fx-03-mid-append-04/target/.ijfw/blackboard/decisions.jsonl +1 -0
  63. package/fixtures/truncation-corpus/fx-03-mid-append-05/events.jsonl +1 -0
  64. package/fixtures/truncation-corpus/fx-03-mid-append-05/intent-journal.jsonl +3 -0
  65. package/fixtures/truncation-corpus/fx-03-mid-append-05/meta.json +18 -0
  66. package/fixtures/truncation-corpus/fx-03-mid-append-05/target/.ijfw/blackboard/decisions.jsonl +1 -0
  67. package/fixtures/truncation-corpus/fx-04-no-events-01/events.jsonl +0 -0
  68. package/fixtures/truncation-corpus/fx-04-no-events-01/intent-journal.jsonl +1 -0
  69. package/fixtures/truncation-corpus/fx-04-no-events-01/meta.json +18 -0
  70. package/fixtures/truncation-corpus/fx-04-no-events-01/snapshots/v-noEv-1-set-phase.json +11 -0
  71. package/fixtures/truncation-corpus/fx-04-no-events-01/target/.ijfw/state/workflow.json +1 -0
  72. package/fixtures/truncation-corpus/fx-04-no-events-02/events.jsonl +0 -0
  73. package/fixtures/truncation-corpus/fx-04-no-events-02/intent-journal.jsonl +1 -0
  74. package/fixtures/truncation-corpus/fx-04-no-events-02/meta.json +18 -0
  75. package/fixtures/truncation-corpus/fx-04-no-events-02/snapshots/v-noEv-2-set-phase.json +11 -0
  76. package/fixtures/truncation-corpus/fx-04-no-events-02/target/.ijfw/state/workflow.json +1 -0
  77. package/fixtures/truncation-corpus/fx-04-no-events-03/events.jsonl +0 -0
  78. package/fixtures/truncation-corpus/fx-04-no-events-03/intent-journal.jsonl +1 -0
  79. package/fixtures/truncation-corpus/fx-04-no-events-03/meta.json +18 -0
  80. package/fixtures/truncation-corpus/fx-04-no-events-03/snapshots/v-noEv-3-set-phase.json +11 -0
  81. package/fixtures/truncation-corpus/fx-04-no-events-03/target/.ijfw/state/workflow.json +1 -0
  82. package/fixtures/truncation-corpus/fx-04-no-events-04/events.jsonl +0 -0
  83. package/fixtures/truncation-corpus/fx-04-no-events-04/intent-journal.jsonl +1 -0
  84. package/fixtures/truncation-corpus/fx-04-no-events-04/meta.json +18 -0
  85. package/fixtures/truncation-corpus/fx-04-no-events-04/snapshots/v-noEv-4-set-phase.json +11 -0
  86. package/fixtures/truncation-corpus/fx-04-no-events-04/target/.ijfw/state/workflow.json +1 -0
  87. package/fixtures/truncation-corpus/fx-04-no-events-05/events.jsonl +0 -0
  88. package/fixtures/truncation-corpus/fx-04-no-events-05/intent-journal.jsonl +1 -0
  89. package/fixtures/truncation-corpus/fx-04-no-events-05/meta.json +18 -0
  90. package/fixtures/truncation-corpus/fx-04-no-events-05/snapshots/v-noEv-5-set-phase.json +11 -0
  91. package/fixtures/truncation-corpus/fx-04-no-events-05/target/.ijfw/state/workflow.json +1 -0
  92. package/fixtures/truncation-corpus/fx-05-error-terminated-01/events.jsonl +2 -0
  93. package/fixtures/truncation-corpus/fx-05-error-terminated-01/intent-journal.jsonl +3 -0
  94. package/fixtures/truncation-corpus/fx-05-error-terminated-01/meta.json +18 -0
  95. package/fixtures/truncation-corpus/fx-05-error-terminated-01/snapshots/v-errT-1-partial.json +11 -0
  96. package/fixtures/truncation-corpus/fx-05-error-terminated-01/target/.ijfw/state/workflow.json +1 -0
  97. package/fixtures/truncation-corpus/fx-05-error-terminated-02/events.jsonl +2 -0
  98. package/fixtures/truncation-corpus/fx-05-error-terminated-02/intent-journal.jsonl +3 -0
  99. package/fixtures/truncation-corpus/fx-05-error-terminated-02/meta.json +18 -0
  100. package/fixtures/truncation-corpus/fx-05-error-terminated-02/target/.ijfw/blackboard/decisions.jsonl +1 -0
  101. package/fixtures/truncation-corpus/fx-05-error-terminated-03/events.jsonl +2 -0
  102. package/fixtures/truncation-corpus/fx-05-error-terminated-03/intent-journal.jsonl +3 -0
  103. package/fixtures/truncation-corpus/fx-05-error-terminated-03/meta.json +18 -0
  104. package/fixtures/truncation-corpus/fx-05-error-terminated-03/snapshots/v-errT-3-partial.json +11 -0
  105. package/fixtures/truncation-corpus/fx-05-error-terminated-03/target/.ijfw/state/workflow.json +1 -0
  106. package/fixtures/truncation-corpus/fx-05-error-terminated-04/events.jsonl +2 -0
  107. package/fixtures/truncation-corpus/fx-05-error-terminated-04/intent-journal.jsonl +3 -0
  108. package/fixtures/truncation-corpus/fx-05-error-terminated-04/meta.json +18 -0
  109. package/fixtures/truncation-corpus/fx-05-error-terminated-04/target/.ijfw/blackboard/decisions.jsonl +1 -0
  110. package/fixtures/truncation-corpus/fx-05-error-terminated-05/events.jsonl +2 -0
  111. package/fixtures/truncation-corpus/fx-05-error-terminated-05/intent-journal.jsonl +3 -0
  112. package/fixtures/truncation-corpus/fx-05-error-terminated-05/meta.json +18 -0
  113. package/fixtures/truncation-corpus/fx-05-error-terminated-05/snapshots/v-errT-5-partial.json +11 -0
  114. package/fixtures/truncation-corpus/fx-05-error-terminated-05/target/.ijfw/state/workflow.json +1 -0
  115. package/package.json +1 -1
  116. package/src/active-extension-writer.js +144 -64
  117. package/src/api-client.js +43 -5
  118. package/src/audit-roster.js +80 -5
  119. package/src/blackboard.js +298 -6
  120. package/src/cli-run.js +33 -5
  121. package/src/codex-agents.js +96 -5
  122. package/src/cost/aggregator.js +39 -9
  123. package/src/cost/pricing.js +57 -0
  124. package/src/cost/readers/gemini.js +1 -1
  125. package/src/cross-audit-chunker.js +189 -0
  126. package/src/cross-dispatcher.js +124 -21
  127. package/src/cross-orchestrator-cli.js +550 -14
  128. package/src/cross-orchestrator.js +1016 -17
  129. package/src/cross-project-search.js +195 -9
  130. package/src/dashboard-client-waves.html +304 -0
  131. package/src/dashboard-client.html +5 -1
  132. package/src/dashboard-server.js +73 -0
  133. package/src/deploy-alerts.js +150 -0
  134. package/src/design/iframe-bridge.js +242 -0
  135. package/src/design-companion.js +144 -0
  136. package/src/dispatch/checkpoint-cli.js +97 -0
  137. package/src/dispatch/colon-syntax.js +81 -1
  138. package/src/dispatch/extension.js +26 -2
  139. package/src/dispatch/registry-cli.js +4 -1
  140. package/src/dispatch/wave-cli.js +201 -6
  141. package/src/dispatch/worktree-cli.js +40 -0
  142. package/src/dispatch-planner.js +97 -2
  143. package/src/dream/runner.mjs +47 -11
  144. package/src/dream/stage-runner.js +40 -0
  145. package/src/dream/state-file.js +102 -0
  146. package/src/extension-installer.js +70 -24
  147. package/src/extension-quota-tracker.js +4 -2
  148. package/src/extension-registry.js +289 -35
  149. package/src/feedback-detector.js +26 -0
  150. package/src/fs-lock.js +259 -7
  151. package/src/gate-result.js +95 -1
  152. package/src/hero-line.js +86 -5
  153. package/src/intent-router.js +35 -0
  154. package/src/lib/a11y-contract.js +117 -0
  155. package/src/lib/atomic-io.js +29 -8
  156. package/src/lib/cache-keepalive.js +150 -0
  157. package/src/lib/jsonl-rotation.js +104 -0
  158. package/src/lib/lighthouse-pillar.js +121 -0
  159. package/src/lib/llm-call.js +121 -0
  160. package/src/lib/playwright-baseline.js +205 -0
  161. package/src/lib/rekor-bridge.js +221 -0
  162. package/src/lib/repo-map.js +392 -0
  163. package/src/lib/shasum-verify.js +164 -0
  164. package/src/lib/sketches-gc.js +132 -0
  165. package/src/lib/tmp-suffix.js +62 -0
  166. package/src/lib/ui-review-runner.js +554 -0
  167. package/src/lib/uispec-drift.js +301 -0
  168. package/src/lib/uispec-intake.js +381 -0
  169. package/src/lib/worktree-guards.js +118 -0
  170. package/src/lib/worktree-recovery.js +100 -0
  171. package/src/memory/auto-linker.js +152 -0
  172. package/src/memory/benchmark.js +498 -0
  173. package/src/memory/dedup.js +126 -0
  174. package/src/memory/embedding-cache.js +136 -0
  175. package/src/memory/fact-extractor.js +168 -0
  176. package/src/memory/fts5.js +65 -1
  177. package/src/memory/migrations/004-bitemporal.js +91 -0
  178. package/src/memory/migrations/005-vector-cache.js +61 -0
  179. package/src/memory/migrations/006-obsidian-graph.js +46 -0
  180. package/src/memory/migrations/007-skill-telemetry.js +24 -0
  181. package/src/memory/migrations/008-write-provenance.js +41 -0
  182. package/src/memory/obsidian-parser.js +91 -0
  183. package/src/memory/query-dataview.js +86 -0
  184. package/src/memory/search.js +10 -0
  185. package/src/memory/temporal.js +529 -0
  186. package/src/memory/tokenize.js +10 -0
  187. package/src/memory-facts-handler.js +37 -0
  188. package/src/memory-feedback.js +260 -2
  189. package/src/model-refresh.js +292 -0
  190. package/src/observability/cost-anomaly.js +166 -0
  191. package/src/observability/evaluator-checkpoint-contract.js +117 -0
  192. package/src/observability/trace-id.js +163 -0
  193. package/src/orchestrator/agents-md-blackboard.js +152 -0
  194. package/src/orchestrator/checkpoint-contract.md +140 -0
  195. package/src/orchestrator/debug-trident.js +570 -0
  196. package/src/orchestrator/merge-block-aware.js +350 -0
  197. package/src/orchestrator/plan-checker.js +475 -0
  198. package/src/orchestrator/post-done-runner.js +249 -0
  199. package/src/orchestrator/review.js +38 -3
  200. package/src/orchestrator/runtime-loop.js +430 -0
  201. package/src/orchestrator/skill-telemetry-sink.js +29 -0
  202. package/src/orchestrator/skill-telemetry.js +37 -0
  203. package/src/orchestrator/state-events.js +459 -0
  204. package/src/orchestrator/state-sdk.js +1764 -0
  205. package/src/orchestrator/status-protocol.js +84 -17
  206. package/src/orchestrator/subagent-telemetry.js +452 -0
  207. package/src/orchestrator/termination.js +160 -0
  208. package/src/orchestrator/verification-gate.js +200 -16
  209. package/src/orchestrator/wave-state.js +332 -23
  210. package/src/orchestrator/worktree-provision.js +77 -0
  211. package/src/override-use-registry.js +111 -5
  212. package/src/receipts.js +36 -4
  213. package/src/recovery/checkpoint.js +56 -3
  214. package/src/recovery/code-fixer.js +656 -0
  215. package/src/recovery/truncation.js +317 -0
  216. package/src/redactor.js +75 -6
  217. package/src/runtime-mediator.js +15 -0
  218. package/src/sanitizer.js +10 -0
  219. package/src/search-hybrid.js +139 -0
  220. package/src/server.js +603 -59
  221. package/src/swarm/worktree.js +27 -4
  222. package/src/swarm-config.js +94 -17
  223. package/src/team/domain-templates/book.json +51 -0
  224. package/src/team/domain-templates/business.json +41 -0
  225. package/src/team/domain-templates/content.json +50 -0
  226. package/src/team/domain-templates/design.json +44 -0
  227. package/src/team/domain-templates/research.json +41 -0
  228. package/src/team/domain-templates/software.json +40 -0
  229. package/src/team/generator.js +278 -3
  230. package/src/team/modify.js +203 -0
  231. package/src/team/schemas.js +48 -0
  232. package/src/update-apply.js +19 -3
@@ -0,0 +1,91 @@
1
+ // IJFW v1.5.0 -- Obsidian-grade markdown extractor.
2
+ //
3
+ // Pulls three structured signals out of memory body text:
4
+ // 1. [[wikilinks]] -> links: [{ target, line }]
5
+ // 2. #nested/tags -> tags: [{ path, depth }]
6
+ // 3. [key:: value] (Dataview) -> meta: [{ key, value }]
7
+ //
8
+ // Code fences and inline-code spans are masked before extraction so that
9
+ // example syntax never produces fake edges. DB writes happen in
10
+ // indexObsidianRelations (idempotent re-index: clears prior rows for the
11
+ // memory id before re-inserting).
12
+
13
+ const FENCE_RE = /```[\s\S]*?```/g;
14
+ const INLINE_CODE_RE = /`[^`\n]+`/g;
15
+ // eslint-disable-next-line security/detect-unsafe-regex -- parses developer-authored markdown notes on local disk; negated [^\]\n] classes bound match to one line per token
16
+ const WIKILINK_RE = /\[\[([^\]\n|]+)(?:\|[^\]\n]+)?\]\]/g;
17
+ const TAG_RE = /(?:^|[^\w&])#([\w/-]+)/g;
18
+ const META_RE = /\[([A-Za-z_][\w-]*)::\s*([^\]\n]+?)\]/g;
19
+
20
+ function maskCode(text) {
21
+ return text
22
+ .replace(FENCE_RE, (m) => ' '.repeat(m.length))
23
+ .replace(INLINE_CODE_RE, (m) => ' '.repeat(m.length));
24
+ }
25
+
26
+ function lineOf(masked, idx) {
27
+ let line = 1;
28
+ for (let i = 0; i < idx; i++) if (masked.charCodeAt(i) === 10) line++;
29
+ return line;
30
+ }
31
+
32
+ function normaliseLinkTarget(raw) {
33
+ return raw
34
+ .trim()
35
+ .toLowerCase()
36
+ .replace(/\s+/g, '-')
37
+ .replace(/[^a-z0-9/_-]/g, '');
38
+ }
39
+
40
+ export function parseObsidian(text) {
41
+ if (typeof text !== 'string' || text.length === 0) {
42
+ return { links: [], tags: [], meta: [] };
43
+ }
44
+ const masked = maskCode(text);
45
+
46
+ const links = [];
47
+ for (const m of masked.matchAll(WIKILINK_RE)) {
48
+ const target = normaliseLinkTarget(m[1]);
49
+ if (target) links.push({ target, line: lineOf(masked, m.index) });
50
+ }
51
+
52
+ const tagSet = new Map();
53
+ for (const m of masked.matchAll(TAG_RE)) {
54
+ const path = m[1].toLowerCase().replace(/^\/+|\/+$/g, '');
55
+ if (!path) continue;
56
+ const depth = path.split('/').length;
57
+ if (!tagSet.has(path)) tagSet.set(path, { path, depth });
58
+ }
59
+
60
+ const meta = [];
61
+ for (const m of masked.matchAll(META_RE)) {
62
+ meta.push({ key: m[1].toLowerCase(), value: m[2].trim() });
63
+ }
64
+
65
+ return { links, tags: [...tagSet.values()], meta };
66
+ }
67
+
68
+ export function indexObsidianRelations(db, memoryId, text) {
69
+ const parsed = parseObsidian(text);
70
+ const insLink = db.prepare(
71
+ 'INSERT OR IGNORE INTO memory_links (from_id, to_target, line) VALUES (?, ?, ?)',
72
+ );
73
+ const insTag = db.prepare(
74
+ 'INSERT OR IGNORE INTO memory_tags (memory_id, tag_path, depth) VALUES (?, ?, ?)',
75
+ );
76
+ const insMeta = db.prepare(
77
+ 'INSERT OR IGNORE INTO memory_meta (memory_id, key, value) VALUES (?, ?, ?)',
78
+ );
79
+ const tx = db.transaction(() => {
80
+ db.prepare('DELETE FROM memory_links WHERE from_id=?').run(memoryId);
81
+ db.prepare('DELETE FROM memory_tags WHERE memory_id=?').run(memoryId);
82
+ db.prepare('DELETE FROM memory_meta WHERE memory_id=?').run(memoryId);
83
+ for (const l of parsed.links) insLink.run(memoryId, l.target, l.line);
84
+ for (const t of parsed.tags) insTag.run(memoryId, t.path, t.depth);
85
+ for (const m of parsed.meta) insMeta.run(memoryId, m.key, m.value);
86
+ });
87
+ tx();
88
+ return parsed;
89
+ }
90
+
91
+ export default { parseObsidian, indexObsidianRelations };
@@ -0,0 +1,86 @@
1
+ // IJFW v1.5.0 -- Dataview-grade declarative query for memory_entries.
2
+ //
3
+ // Supported grammar (v1 — intentionally minimal; expand in v1.6+):
4
+ // tag = #path[/sub]* prefix-matches memory_tags.tag_path
5
+ // linked_to = "target" matches memory_links.to_target
6
+ // created_after = <unix-secs> memory_entries.created_at > N
7
+ // created_before = <unix-secs> memory_entries.created_at < N
8
+ //
9
+ // Multiple filters AND together via case-insensitive " and ".
10
+ // Whitespace-tolerant. Unrecognised clauses are silently skipped
11
+ // (caller can inspect parsed.filters for __unrecognised entries).
12
+
13
+ const CLAUSE_AND = /\s+and\s+/i;
14
+ const TAG_RE = /^\s*tag\s*=\s*#?([\w/_-]+)\s*$/i;
15
+ const LINKED_RE = /^\s*linked_to\s*=\s*"([^"\n]+)"\s*$/i;
16
+ const CREATED_AFTER_RE = /^\s*created_after\s*=\s*(\d+)\s*$/i;
17
+ const CREATED_BEFORE_RE = /^\s*created_before\s*=\s*(\d+)\s*$/i;
18
+
19
+ export function parseDataviewQuery(input) {
20
+ const clauses = String(input || '').split(CLAUSE_AND);
21
+ const out = { filters: [] };
22
+ for (const raw of clauses) {
23
+ const c = raw.trim();
24
+ if (!c) continue;
25
+ let m;
26
+ if ((m = c.match(TAG_RE))) {
27
+ out.tag = m[1].toLowerCase().replace(/^\/+|\/+$/g, '');
28
+ continue;
29
+ }
30
+ if ((m = c.match(LINKED_RE))) {
31
+ out.filters.push({ field: 'linked_to', op: '=', value: m[1] });
32
+ continue;
33
+ }
34
+ if ((m = c.match(CREATED_AFTER_RE))) {
35
+ out.filters.push({ field: 'created_after', op: '=', value: Number(m[1]) });
36
+ continue;
37
+ }
38
+ if ((m = c.match(CREATED_BEFORE_RE))) {
39
+ out.filters.push({ field: 'created_before', op: '=', value: Number(m[1]) });
40
+ continue;
41
+ }
42
+ out.filters.push({ field: '__unrecognised', op: '=', value: c });
43
+ }
44
+ return out;
45
+ }
46
+
47
+ export function runDataviewQuery(db, parsed) {
48
+ const where = [];
49
+ const params = [];
50
+ let join = '';
51
+ if (parsed.tag) {
52
+ join += ' JOIN memory_tags t ON t.memory_id = e.id ';
53
+ where.push('(t.tag_path = ? OR t.tag_path LIKE ?)');
54
+ params.push(parsed.tag, `${parsed.tag}/%`);
55
+ }
56
+ for (const f of parsed.filters) {
57
+ switch (f.field) {
58
+ case 'linked_to':
59
+ join += ' JOIN memory_links l ON l.from_id = e.id ';
60
+ where.push('l.to_target = ?');
61
+ params.push(f.value);
62
+ break;
63
+ case 'created_after':
64
+ where.push('e.created_at > ?');
65
+ params.push(f.value);
66
+ break;
67
+ case 'created_before':
68
+ where.push('e.created_at < ?');
69
+ params.push(f.value);
70
+ break;
71
+ default: /* __unrecognised silently skipped */
72
+ }
73
+ }
74
+ // Note: memory_entries (migration 001 schema) has columns:
75
+ // id (INTEGER PK), body, source, session_id, created_at. No title column.
76
+ // memory_links/_tags/_meta store TEXT memory_id — SQLite coerces across
77
+ // the type boundary at JOIN time (SQLite is permissive without strict FKs).
78
+ const sql = `SELECT DISTINCT e.id, e.body, e.source, e.created_at
79
+ FROM memory_entries e ${join}
80
+ ${where.length ? 'WHERE ' + where.join(' AND ') : ''}
81
+ ORDER BY e.created_at DESC`;
82
+ const rows = db.prepare(sql).all(...params);
83
+ return { rows, rowCount: rows.length, parsed, sql };
84
+ }
85
+
86
+ export default { parseDataviewQuery, runDataviewQuery };
@@ -58,10 +58,20 @@ async function loadMemoryMigrationsSync() {
58
58
  const v1 = await import('./migrations/001-fts5-init.js');
59
59
  const v2 = await import('./migrations/002-tier-semantic.js');
60
60
  const v3 = await import('./migrations/003-stale-candidate.js');
61
+ const v4 = await import('./migrations/004-bitemporal.js');
62
+ const v5 = await import('./migrations/005-vector-cache.js');
63
+ const v6 = await import('./migrations/006-obsidian-graph.js');
64
+ const v7 = await import('./migrations/007-skill-telemetry.js');
65
+ const v8 = await import('./migrations/008-write-provenance.js');
61
66
  return [
62
67
  { version: v1.VERSION, description: v1.DESCRIPTION, up: v1.up },
63
68
  { version: v2.VERSION, description: v2.DESCRIPTION, up: v2.up },
64
69
  { version: v3.VERSION, description: v3.DESCRIPTION, up: v3.up },
70
+ { version: v4.VERSION, description: v4.DESCRIPTION, up: v4.up },
71
+ { version: v5.VERSION, description: v5.DESCRIPTION, up: v5.up },
72
+ { version: v6.VERSION, description: v6.DESCRIPTION, up: v6.up },
73
+ { version: v7.VERSION, description: v7.DESCRIPTION, up: v7.up },
74
+ { version: v8.VERSION, description: v8.DESCRIPTION, up: v8.up },
65
75
  ].sort((a, b) => a.version - b.version);
66
76
  }
67
77