@soleri/core 2.4.0 → 2.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.
- package/dist/brain/brain.d.ts +7 -0
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +56 -9
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/types.d.ts +2 -2
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/cognee/client.d.ts +3 -0
- package/dist/cognee/client.d.ts.map +1 -1
- package/dist/cognee/client.js +17 -0
- package/dist/cognee/client.js.map +1 -1
- package/dist/cognee/sync-manager.d.ts +94 -0
- package/dist/cognee/sync-manager.d.ts.map +1 -0
- package/dist/cognee/sync-manager.js +293 -0
- package/dist/cognee/sync-manager.js.map +1 -0
- package/dist/curator/curator.d.ts +8 -1
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +64 -1
- package/dist/curator/curator.js.map +1 -1
- package/dist/errors/classify.d.ts +13 -0
- package/dist/errors/classify.d.ts.map +1 -0
- package/dist/errors/classify.js +97 -0
- package/dist/errors/classify.js.map +1 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +4 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/retry.d.ts +40 -0
- package/dist/errors/retry.d.ts.map +1 -0
- package/dist/errors/retry.js +97 -0
- package/dist/errors/retry.js.map +1 -0
- package/dist/errors/types.d.ts +48 -0
- package/dist/errors/types.d.ts.map +1 -0
- package/dist/errors/types.js +59 -0
- package/dist/errors/types.js.map +1 -0
- package/dist/index.d.ts +25 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/intake/content-classifier.d.ts +14 -0
- package/dist/intake/content-classifier.d.ts.map +1 -0
- package/dist/intake/content-classifier.js +125 -0
- package/dist/intake/content-classifier.js.map +1 -0
- package/dist/intake/dedup-gate.d.ts +17 -0
- package/dist/intake/dedup-gate.d.ts.map +1 -0
- package/dist/intake/dedup-gate.js +66 -0
- package/dist/intake/dedup-gate.js.map +1 -0
- package/dist/intake/intake-pipeline.d.ts +63 -0
- package/dist/intake/intake-pipeline.d.ts.map +1 -0
- package/dist/intake/intake-pipeline.js +373 -0
- package/dist/intake/intake-pipeline.js.map +1 -0
- package/dist/intake/types.d.ts +65 -0
- package/dist/intake/types.d.ts.map +1 -0
- package/dist/intake/types.js +3 -0
- package/dist/intake/types.js.map +1 -0
- package/dist/intelligence/loader.js +1 -1
- package/dist/intelligence/loader.js.map +1 -1
- package/dist/intelligence/types.d.ts +3 -1
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/loop/loop-manager.d.ts +58 -7
- package/dist/loop/loop-manager.d.ts.map +1 -1
- package/dist/loop/loop-manager.js +280 -6
- package/dist/loop/loop-manager.js.map +1 -1
- package/dist/loop/types.d.ts +69 -1
- package/dist/loop/types.d.ts.map +1 -1
- package/dist/loop/types.js +4 -1
- package/dist/loop/types.js.map +1 -1
- package/dist/persistence/index.d.ts +3 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +2 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/sqlite-provider.d.ts +25 -0
- package/dist/persistence/sqlite-provider.d.ts.map +1 -0
- package/dist/persistence/sqlite-provider.js +59 -0
- package/dist/persistence/sqlite-provider.js.map +1 -0
- package/dist/persistence/types.d.ts +36 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +8 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/planning/gap-analysis.d.ts +47 -4
- package/dist/planning/gap-analysis.d.ts.map +1 -1
- package/dist/planning/gap-analysis.js +190 -13
- package/dist/planning/gap-analysis.js.map +1 -1
- package/dist/planning/gap-types.d.ts +1 -1
- package/dist/planning/gap-types.d.ts.map +1 -1
- package/dist/planning/gap-types.js.map +1 -1
- package/dist/planning/planner.d.ts +277 -9
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +611 -46
- package/dist/planning/planner.js.map +1 -1
- package/dist/playbooks/generic/brainstorming.d.ts +9 -0
- package/dist/playbooks/generic/brainstorming.d.ts.map +1 -0
- package/dist/playbooks/generic/brainstorming.js +105 -0
- package/dist/playbooks/generic/brainstorming.js.map +1 -0
- package/dist/playbooks/generic/code-review.d.ts +11 -0
- package/dist/playbooks/generic/code-review.d.ts.map +1 -0
- package/dist/playbooks/generic/code-review.js +176 -0
- package/dist/playbooks/generic/code-review.js.map +1 -0
- package/dist/playbooks/generic/subagent-execution.d.ts +9 -0
- package/dist/playbooks/generic/subagent-execution.d.ts.map +1 -0
- package/dist/playbooks/generic/subagent-execution.js +68 -0
- package/dist/playbooks/generic/subagent-execution.js.map +1 -0
- package/dist/playbooks/generic/systematic-debugging.d.ts +9 -0
- package/dist/playbooks/generic/systematic-debugging.d.ts.map +1 -0
- package/dist/playbooks/generic/systematic-debugging.js +87 -0
- package/dist/playbooks/generic/systematic-debugging.js.map +1 -0
- package/dist/playbooks/generic/tdd.d.ts +9 -0
- package/dist/playbooks/generic/tdd.d.ts.map +1 -0
- package/dist/playbooks/generic/tdd.js +70 -0
- package/dist/playbooks/generic/tdd.js.map +1 -0
- package/dist/playbooks/generic/verification.d.ts +9 -0
- package/dist/playbooks/generic/verification.d.ts.map +1 -0
- package/dist/playbooks/generic/verification.js +74 -0
- package/dist/playbooks/generic/verification.js.map +1 -0
- package/dist/playbooks/index.d.ts +4 -0
- package/dist/playbooks/index.d.ts.map +1 -0
- package/dist/playbooks/index.js +5 -0
- package/dist/playbooks/index.js.map +1 -0
- package/dist/playbooks/playbook-registry.d.ts +42 -0
- package/dist/playbooks/playbook-registry.d.ts.map +1 -0
- package/dist/playbooks/playbook-registry.js +227 -0
- package/dist/playbooks/playbook-registry.js.map +1 -0
- package/dist/playbooks/playbook-seeder.d.ts +47 -0
- package/dist/playbooks/playbook-seeder.d.ts.map +1 -0
- package/dist/playbooks/playbook-seeder.js +104 -0
- package/dist/playbooks/playbook-seeder.js.map +1 -0
- package/dist/playbooks/playbook-types.d.ts +132 -0
- package/dist/playbooks/playbook-types.d.ts.map +1 -0
- package/dist/playbooks/playbook-types.js +12 -0
- package/dist/playbooks/playbook-types.js.map +1 -0
- package/dist/project/project-registry.d.ts.map +1 -1
- package/dist/project/project-registry.js +9 -11
- package/dist/project/project-registry.js.map +1 -1
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +3 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/parser.d.ts +17 -0
- package/dist/prompts/parser.d.ts.map +1 -0
- package/dist/prompts/parser.js +47 -0
- package/dist/prompts/parser.js.map +1 -0
- package/dist/prompts/template-manager.d.ts +25 -0
- package/dist/prompts/template-manager.d.ts.map +1 -0
- package/dist/prompts/template-manager.js +71 -0
- package/dist/prompts/template-manager.js.map +1 -0
- package/dist/prompts/types.d.ts +26 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +5 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/runtime/admin-extra-ops.d.ts +5 -3
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
- package/dist/runtime/admin-extra-ops.js +322 -11
- package/dist/runtime/admin-extra-ops.js.map +1 -1
- package/dist/runtime/admin-ops.d.ts.map +1 -1
- package/dist/runtime/admin-ops.js +10 -3
- package/dist/runtime/admin-ops.js.map +1 -1
- package/dist/runtime/capture-ops.d.ts.map +1 -1
- package/dist/runtime/capture-ops.js +20 -2
- package/dist/runtime/capture-ops.js.map +1 -1
- package/dist/runtime/cognee-sync-ops.d.ts +12 -0
- package/dist/runtime/cognee-sync-ops.d.ts.map +1 -0
- package/dist/runtime/cognee-sync-ops.js +55 -0
- package/dist/runtime/cognee-sync-ops.js.map +1 -0
- package/dist/runtime/core-ops.d.ts +8 -6
- package/dist/runtime/core-ops.d.ts.map +1 -1
- package/dist/runtime/core-ops.js +226 -9
- package/dist/runtime/core-ops.js.map +1 -1
- package/dist/runtime/curator-extra-ops.d.ts +2 -2
- package/dist/runtime/curator-extra-ops.d.ts.map +1 -1
- package/dist/runtime/curator-extra-ops.js +15 -3
- package/dist/runtime/curator-extra-ops.js.map +1 -1
- package/dist/runtime/domain-ops.js +2 -2
- package/dist/runtime/domain-ops.js.map +1 -1
- package/dist/runtime/grading-ops.d.ts.map +1 -1
- package/dist/runtime/grading-ops.js.map +1 -1
- package/dist/runtime/intake-ops.d.ts +14 -0
- package/dist/runtime/intake-ops.d.ts.map +1 -0
- package/dist/runtime/intake-ops.js +110 -0
- package/dist/runtime/intake-ops.js.map +1 -0
- package/dist/runtime/loop-ops.d.ts +5 -4
- package/dist/runtime/loop-ops.d.ts.map +1 -1
- package/dist/runtime/loop-ops.js +84 -12
- package/dist/runtime/loop-ops.js.map +1 -1
- package/dist/runtime/memory-cross-project-ops.d.ts.map +1 -1
- package/dist/runtime/memory-cross-project-ops.js.map +1 -1
- package/dist/runtime/memory-extra-ops.js +5 -5
- package/dist/runtime/memory-extra-ops.js.map +1 -1
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
- package/dist/runtime/orchestrate-ops.js +8 -2
- package/dist/runtime/orchestrate-ops.js.map +1 -1
- package/dist/runtime/planning-extra-ops.d.ts +13 -5
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
- package/dist/runtime/planning-extra-ops.js +381 -18
- package/dist/runtime/planning-extra-ops.js.map +1 -1
- package/dist/runtime/playbook-ops.d.ts +14 -0
- package/dist/runtime/playbook-ops.d.ts.map +1 -0
- package/dist/runtime/playbook-ops.js +141 -0
- package/dist/runtime/playbook-ops.js.map +1 -0
- package/dist/runtime/project-ops.d.ts.map +1 -1
- package/dist/runtime/project-ops.js +7 -2
- package/dist/runtime/project-ops.js.map +1 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +27 -8
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +8 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.d.ts +3 -2
- package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.js +345 -4
- package/dist/runtime/vault-extra-ops.js.map +1 -1
- package/dist/vault/playbook.d.ts +34 -0
- package/dist/vault/playbook.d.ts.map +1 -0
- package/dist/vault/playbook.js +60 -0
- package/dist/vault/playbook.js.map +1 -0
- package/dist/vault/vault.d.ts +31 -32
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +201 -181
- package/dist/vault/vault.js.map +1 -1
- package/package.json +7 -3
- package/src/__tests__/admin-extra-ops.test.ts +62 -15
- package/src/__tests__/admin-ops.test.ts +2 -2
- package/src/__tests__/brain.test.ts +3 -3
- package/src/__tests__/cognee-integration.test.ts +80 -0
- package/src/__tests__/cognee-sync-manager.test.ts +103 -0
- package/src/__tests__/core-ops.test.ts +30 -4
- package/src/__tests__/curator-extra-ops.test.ts +24 -2
- package/src/__tests__/errors.test.ts +388 -0
- package/src/__tests__/grading-ops.test.ts +28 -7
- package/src/__tests__/intake-pipeline.test.ts +162 -0
- package/src/__tests__/loop-ops.test.ts +74 -3
- package/src/__tests__/memory-cross-project-ops.test.ts +3 -1
- package/src/__tests__/orchestrate-ops.test.ts +8 -3
- package/src/__tests__/persistence.test.ts +225 -0
- package/src/__tests__/planner.test.ts +99 -21
- package/src/__tests__/planning-extra-ops.test.ts +168 -10
- package/src/__tests__/playbook-registry.test.ts +326 -0
- package/src/__tests__/playbook-seeder.test.ts +163 -0
- package/src/__tests__/playbook.test.ts +389 -0
- package/src/__tests__/project-ops.test.ts +18 -4
- package/src/__tests__/template-manager.test.ts +222 -0
- package/src/__tests__/vault-extra-ops.test.ts +82 -7
- package/src/brain/brain.ts +71 -9
- package/src/brain/types.ts +2 -2
- package/src/cognee/client.ts +18 -0
- package/src/cognee/sync-manager.ts +389 -0
- package/src/curator/curator.ts +88 -7
- package/src/errors/classify.ts +102 -0
- package/src/errors/index.ts +5 -0
- package/src/errors/retry.ts +132 -0
- package/src/errors/types.ts +81 -0
- package/src/index.ts +114 -3
- package/src/intake/content-classifier.ts +146 -0
- package/src/intake/dedup-gate.ts +92 -0
- package/src/intake/intake-pipeline.ts +503 -0
- package/src/intake/types.ts +69 -0
- package/src/intelligence/loader.ts +1 -1
- package/src/intelligence/types.ts +3 -1
- package/src/loop/loop-manager.ts +325 -7
- package/src/loop/types.ts +72 -1
- package/src/persistence/index.ts +7 -0
- package/src/persistence/sqlite-provider.ts +62 -0
- package/src/persistence/types.ts +44 -0
- package/src/planning/gap-analysis.ts +286 -17
- package/src/planning/gap-types.ts +4 -1
- package/src/planning/planner.ts +828 -55
- package/src/playbooks/generic/brainstorming.ts +110 -0
- package/src/playbooks/generic/code-review.ts +181 -0
- package/src/playbooks/generic/subagent-execution.ts +74 -0
- package/src/playbooks/generic/systematic-debugging.ts +92 -0
- package/src/playbooks/generic/tdd.ts +75 -0
- package/src/playbooks/generic/verification.ts +79 -0
- package/src/playbooks/index.ts +27 -0
- package/src/playbooks/playbook-registry.ts +284 -0
- package/src/playbooks/playbook-seeder.ts +119 -0
- package/src/playbooks/playbook-types.ts +162 -0
- package/src/project/project-registry.ts +29 -17
- package/src/prompts/index.ts +3 -0
- package/src/prompts/parser.ts +59 -0
- package/src/prompts/template-manager.ts +77 -0
- package/src/prompts/types.ts +28 -0
- package/src/runtime/admin-extra-ops.ts +358 -13
- package/src/runtime/admin-ops.ts +17 -6
- package/src/runtime/capture-ops.ts +25 -6
- package/src/runtime/cognee-sync-ops.ts +63 -0
- package/src/runtime/core-ops.ts +258 -8
- package/src/runtime/curator-extra-ops.ts +17 -3
- package/src/runtime/domain-ops.ts +2 -2
- package/src/runtime/grading-ops.ts +11 -2
- package/src/runtime/intake-ops.ts +126 -0
- package/src/runtime/loop-ops.ts +96 -13
- package/src/runtime/memory-cross-project-ops.ts +1 -2
- package/src/runtime/memory-extra-ops.ts +5 -5
- package/src/runtime/orchestrate-ops.ts +8 -2
- package/src/runtime/planning-extra-ops.ts +414 -23
- package/src/runtime/playbook-ops.ts +169 -0
- package/src/runtime/project-ops.ts +9 -3
- package/src/runtime/runtime.ts +35 -9
- package/src/runtime/types.ts +8 -0
- package/src/runtime/vault-extra-ops.ts +385 -4
- package/src/vault/playbook.ts +87 -0
- package/src/vault/vault.ts +301 -235
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/vault/vault.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/vault/vault.ts"],"names":[],"mappings":"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"}
|
package/dist/vault/vault.js
CHANGED
|
@@ -1,21 +1,39 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { mkdirSync } from 'node:fs';
|
|
3
|
-
import { dirname } from 'node:path';
|
|
1
|
+
import { SQLitePersistenceProvider } from '../persistence/sqlite-provider.js';
|
|
4
2
|
export class Vault {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
provider;
|
|
4
|
+
sqliteProvider;
|
|
5
|
+
syncManager = null;
|
|
6
|
+
/**
|
|
7
|
+
* Create a Vault with a PersistenceProvider or a SQLite path (backward compat).
|
|
8
|
+
*/
|
|
9
|
+
constructor(providerOrPath = ':memory:') {
|
|
10
|
+
if (typeof providerOrPath === 'string') {
|
|
11
|
+
const sqlite = new SQLitePersistenceProvider(providerOrPath);
|
|
12
|
+
this.provider = sqlite;
|
|
13
|
+
this.sqliteProvider = sqlite;
|
|
14
|
+
// SQLite-specific pragmas
|
|
15
|
+
this.provider.run('PRAGMA journal_mode = WAL');
|
|
16
|
+
this.provider.run('PRAGMA foreign_keys = ON');
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
this.provider = providerOrPath;
|
|
20
|
+
this.sqliteProvider =
|
|
21
|
+
providerOrPath instanceof SQLitePersistenceProvider ? providerOrPath : null;
|
|
22
|
+
}
|
|
12
23
|
this.initialize();
|
|
13
24
|
}
|
|
25
|
+
setSyncManager(mgr) {
|
|
26
|
+
this.syncManager = mgr;
|
|
27
|
+
}
|
|
28
|
+
/** Backward-compatible factory. */
|
|
29
|
+
static createWithSQLite(dbPath = ':memory:') {
|
|
30
|
+
return new Vault(dbPath);
|
|
31
|
+
}
|
|
14
32
|
initialize() {
|
|
15
|
-
this.
|
|
33
|
+
this.provider.execSql(`
|
|
16
34
|
CREATE TABLE IF NOT EXISTS entries (
|
|
17
35
|
id TEXT PRIMARY KEY,
|
|
18
|
-
type TEXT NOT NULL CHECK(type IN ('pattern', 'anti-pattern', 'rule')),
|
|
36
|
+
type TEXT NOT NULL CHECK(type IN ('pattern', 'anti-pattern', 'rule', 'playbook')),
|
|
19
37
|
domain TEXT NOT NULL,
|
|
20
38
|
title TEXT NOT NULL,
|
|
21
39
|
severity TEXT NOT NULL CHECK(severity IN ('critical', 'warning', 'suggestion')),
|
|
@@ -94,21 +112,28 @@ export class Vault {
|
|
|
94
112
|
CREATE INDEX IF NOT EXISTS idx_brain_feedback_query ON brain_feedback(query);
|
|
95
113
|
`);
|
|
96
114
|
this.migrateBrainSchema();
|
|
115
|
+
this.migrateTemporalSchema();
|
|
116
|
+
}
|
|
117
|
+
migrateTemporalSchema() {
|
|
118
|
+
try {
|
|
119
|
+
this.provider.run('ALTER TABLE entries ADD COLUMN valid_from INTEGER');
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Column already exists
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
this.provider.run('ALTER TABLE entries ADD COLUMN valid_until INTEGER');
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Column already exists
|
|
129
|
+
}
|
|
97
130
|
}
|
|
98
|
-
/**
|
|
99
|
-
* Migrate brain_feedback table from old schema (accepted/dismissed only)
|
|
100
|
-
* to new schema with source, confidence, duration, context, reason columns.
|
|
101
|
-
* Also adds extracted_at to brain_sessions if it exists.
|
|
102
|
-
*/
|
|
103
131
|
migrateBrainSchema() {
|
|
104
|
-
|
|
105
|
-
const columns = this.db.prepare('PRAGMA table_info(brain_feedback)').all();
|
|
132
|
+
const columns = this.provider.all('PRAGMA table_info(brain_feedback)');
|
|
106
133
|
const hasSource = columns.some((c) => c.name === 'source');
|
|
107
134
|
if (!hasSource && columns.length > 0) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
this.db
|
|
111
|
-
.prepare(`
|
|
135
|
+
this.provider.transaction(() => {
|
|
136
|
+
this.provider.run(`
|
|
112
137
|
CREATE TABLE brain_feedback_new (
|
|
113
138
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
114
139
|
query TEXT NOT NULL,
|
|
@@ -121,26 +146,20 @@ export class Vault {
|
|
|
121
146
|
reason TEXT,
|
|
122
147
|
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
123
148
|
)
|
|
124
|
-
`)
|
|
125
|
-
|
|
126
|
-
this.db
|
|
127
|
-
.prepare(`
|
|
149
|
+
`);
|
|
150
|
+
this.provider.run(`
|
|
128
151
|
INSERT INTO brain_feedback_new (id, query, entry_id, action, created_at)
|
|
129
152
|
SELECT id, query, entry_id, action, created_at FROM brain_feedback
|
|
130
|
-
`)
|
|
131
|
-
|
|
132
|
-
this.
|
|
133
|
-
this.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
.run();
|
|
137
|
-
})();
|
|
138
|
-
}
|
|
139
|
-
// Add extracted_at to brain_sessions if it exists but lacks the column
|
|
153
|
+
`);
|
|
154
|
+
this.provider.run('DROP TABLE brain_feedback');
|
|
155
|
+
this.provider.run('ALTER TABLE brain_feedback_new RENAME TO brain_feedback');
|
|
156
|
+
this.provider.run('CREATE INDEX IF NOT EXISTS idx_brain_feedback_query ON brain_feedback(query)');
|
|
157
|
+
});
|
|
158
|
+
}
|
|
140
159
|
try {
|
|
141
|
-
const sessionCols = this.
|
|
160
|
+
const sessionCols = this.provider.all('PRAGMA table_info(brain_sessions)');
|
|
142
161
|
if (sessionCols.length > 0 && !sessionCols.some((c) => c.name === 'extracted_at')) {
|
|
143
|
-
this.
|
|
162
|
+
this.provider.run('ALTER TABLE brain_sessions ADD COLUMN extracted_at TEXT');
|
|
144
163
|
}
|
|
145
164
|
}
|
|
146
165
|
catch {
|
|
@@ -148,17 +167,17 @@ export class Vault {
|
|
|
148
167
|
}
|
|
149
168
|
}
|
|
150
169
|
seed(entries) {
|
|
151
|
-
const
|
|
152
|
-
INSERT INTO entries (id,type,domain,title,severity,description,context,example,counter_example,why,tags,applies_to)
|
|
153
|
-
VALUES (@id,@type,@domain,@title,@severity,@description,@context,@example,@counterExample,@why,@tags,@appliesTo)
|
|
170
|
+
const sql = `
|
|
171
|
+
INSERT INTO entries (id,type,domain,title,severity,description,context,example,counter_example,why,tags,applies_to,valid_from,valid_until)
|
|
172
|
+
VALUES (@id,@type,@domain,@title,@severity,@description,@context,@example,@counterExample,@why,@tags,@appliesTo,@validFrom,@validUntil)
|
|
154
173
|
ON CONFLICT(id) DO UPDATE SET type=excluded.type,domain=excluded.domain,title=excluded.title,severity=excluded.severity,
|
|
155
174
|
description=excluded.description,context=excluded.context,example=excluded.example,counter_example=excluded.counter_example,
|
|
156
|
-
why=excluded.why,tags=excluded.tags,applies_to=excluded.applies_to,updated_at=unixepoch()
|
|
157
|
-
|
|
158
|
-
|
|
175
|
+
why=excluded.why,tags=excluded.tags,applies_to=excluded.applies_to,valid_from=excluded.valid_from,valid_until=excluded.valid_until,updated_at=unixepoch()
|
|
176
|
+
`;
|
|
177
|
+
return this.provider.transaction(() => {
|
|
159
178
|
let count = 0;
|
|
160
|
-
for (const entry of
|
|
161
|
-
|
|
179
|
+
for (const entry of entries) {
|
|
180
|
+
this.provider.run(sql, {
|
|
162
181
|
id: entry.id,
|
|
163
182
|
type: entry.type,
|
|
164
183
|
domain: entry.domain,
|
|
@@ -171,12 +190,16 @@ export class Vault {
|
|
|
171
190
|
why: entry.why ?? null,
|
|
172
191
|
tags: JSON.stringify(entry.tags),
|
|
173
192
|
appliesTo: JSON.stringify(entry.appliesTo ?? []),
|
|
193
|
+
validFrom: entry.validFrom ?? null,
|
|
194
|
+
validUntil: entry.validUntil ?? null,
|
|
174
195
|
});
|
|
175
196
|
count++;
|
|
197
|
+
if (this.syncManager) {
|
|
198
|
+
this.syncManager.enqueue('ingest', entry.id, entry);
|
|
199
|
+
}
|
|
176
200
|
}
|
|
177
201
|
return count;
|
|
178
202
|
});
|
|
179
|
-
return tx(entries);
|
|
180
203
|
}
|
|
181
204
|
search(query, options) {
|
|
182
205
|
const limit = options?.limit ?? 10;
|
|
@@ -194,11 +217,15 @@ export class Vault {
|
|
|
194
217
|
filters.push('e.severity = @severity');
|
|
195
218
|
fp.severity = options.severity;
|
|
196
219
|
}
|
|
220
|
+
if (!options?.includeExpired) {
|
|
221
|
+
const now = Math.floor(Date.now() / 1000);
|
|
222
|
+
filters.push('(e.valid_until IS NULL OR e.valid_until > @now)');
|
|
223
|
+
filters.push('(e.valid_from IS NULL OR e.valid_from <= @now)');
|
|
224
|
+
fp.now = now;
|
|
225
|
+
}
|
|
197
226
|
const wc = filters.length > 0 ? `AND ${filters.join(' AND ')}` : '';
|
|
198
227
|
try {
|
|
199
|
-
const rows = this.
|
|
200
|
-
.prepare(`SELECT e.*, -rank as score FROM entries_fts fts JOIN entries e ON e.rowid = fts.rowid WHERE entries_fts MATCH @query ${wc} ORDER BY score DESC LIMIT @limit`)
|
|
201
|
-
.all({ query, limit, ...fp });
|
|
228
|
+
const rows = this.provider.all(`SELECT e.*, -rank as score FROM entries_fts fts JOIN entries e ON e.rowid = fts.rowid WHERE entries_fts MATCH @query ${wc} ORDER BY score DESC LIMIT @limit`, { query, limit, ...fp });
|
|
202
229
|
return rows.map(rowToSearchResult);
|
|
203
230
|
}
|
|
204
231
|
catch {
|
|
@@ -206,7 +233,9 @@ export class Vault {
|
|
|
206
233
|
}
|
|
207
234
|
}
|
|
208
235
|
get(id) {
|
|
209
|
-
const row = this.
|
|
236
|
+
const row = this.provider.get('SELECT * FROM entries WHERE id = ?', [
|
|
237
|
+
id,
|
|
238
|
+
]);
|
|
210
239
|
return row ? rowToEntry(row) : null;
|
|
211
240
|
}
|
|
212
241
|
list(options) {
|
|
@@ -231,31 +260,35 @@ export class Vault {
|
|
|
231
260
|
});
|
|
232
261
|
filters.push(`(${c.join(' OR ')})`);
|
|
233
262
|
}
|
|
263
|
+
if (!options?.includeExpired) {
|
|
264
|
+
const now = Math.floor(Date.now() / 1000);
|
|
265
|
+
filters.push('(valid_until IS NULL OR valid_until > @now)');
|
|
266
|
+
filters.push('(valid_from IS NULL OR valid_from <= @now)');
|
|
267
|
+
params.now = now;
|
|
268
|
+
}
|
|
234
269
|
const wc = filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : '';
|
|
235
|
-
const rows = this.
|
|
236
|
-
.prepare(`SELECT * FROM entries ${wc} ORDER BY severity, domain, title LIMIT @limit OFFSET @offset`)
|
|
237
|
-
.all({ ...params, limit: options?.limit ?? 50, offset: options?.offset ?? 0 });
|
|
270
|
+
const rows = this.provider.all(`SELECT * FROM entries ${wc} ORDER BY severity, domain, title LIMIT @limit OFFSET @offset`, { ...params, limit: options?.limit ?? 50, offset: options?.offset ?? 0 });
|
|
238
271
|
return rows.map(rowToEntry);
|
|
239
272
|
}
|
|
240
273
|
stats() {
|
|
241
|
-
const total = this.
|
|
274
|
+
const total = this.provider.get('SELECT COUNT(*) as count FROM entries').count;
|
|
242
275
|
return {
|
|
243
276
|
totalEntries: total,
|
|
244
|
-
byType: gc(this.
|
|
245
|
-
byDomain: gc(this.
|
|
246
|
-
bySeverity: gc(this.
|
|
277
|
+
byType: gc(this.provider, 'type'),
|
|
278
|
+
byDomain: gc(this.provider, 'domain'),
|
|
279
|
+
bySeverity: gc(this.provider, 'severity'),
|
|
247
280
|
};
|
|
248
281
|
}
|
|
249
282
|
add(entry) {
|
|
250
283
|
this.seed([entry]);
|
|
251
284
|
}
|
|
252
285
|
remove(id) {
|
|
253
|
-
|
|
286
|
+
const deleted = this.provider.run('DELETE FROM entries WHERE id = ?', [id]).changes > 0;
|
|
287
|
+
if (deleted && this.syncManager) {
|
|
288
|
+
this.syncManager.enqueue('delete', id);
|
|
289
|
+
}
|
|
290
|
+
return deleted;
|
|
254
291
|
}
|
|
255
|
-
/**
|
|
256
|
-
* Partial update of an existing entry's mutable fields.
|
|
257
|
-
* Returns the updated entry or null if not found.
|
|
258
|
-
*/
|
|
259
292
|
update(id, fields) {
|
|
260
293
|
const existing = this.get(id);
|
|
261
294
|
if (!existing)
|
|
@@ -264,26 +297,47 @@ export class Vault {
|
|
|
264
297
|
this.seed([merged]);
|
|
265
298
|
return this.get(id);
|
|
266
299
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
300
|
+
setTemporal(id, validFrom, validUntil) {
|
|
301
|
+
const sets = [];
|
|
302
|
+
const params = { id };
|
|
303
|
+
if (validFrom !== undefined) {
|
|
304
|
+
sets.push('valid_from = @validFrom');
|
|
305
|
+
params.validFrom = validFrom;
|
|
306
|
+
}
|
|
307
|
+
if (validUntil !== undefined) {
|
|
308
|
+
sets.push('valid_until = @validUntil');
|
|
309
|
+
params.validUntil = validUntil;
|
|
310
|
+
}
|
|
311
|
+
if (sets.length === 0)
|
|
312
|
+
return false;
|
|
313
|
+
sets.push('updated_at = unixepoch()');
|
|
314
|
+
return (this.provider.run(`UPDATE entries SET ${sets.join(', ')} WHERE id = @id`, params).changes > 0);
|
|
315
|
+
}
|
|
316
|
+
findExpiring(withinDays) {
|
|
317
|
+
const now = Math.floor(Date.now() / 1000);
|
|
318
|
+
const cutoff = now + withinDays * 86400;
|
|
319
|
+
const rows = this.provider.all('SELECT * FROM entries WHERE valid_until IS NOT NULL AND valid_until > @now AND valid_until <= @cutoff ORDER BY valid_until ASC', { now, cutoff });
|
|
320
|
+
return rows.map(rowToEntry);
|
|
321
|
+
}
|
|
322
|
+
findExpired(limit = 50) {
|
|
323
|
+
const now = Math.floor(Date.now() / 1000);
|
|
324
|
+
const rows = this.provider.all('SELECT * FROM entries WHERE valid_until IS NOT NULL AND valid_until <= @now ORDER BY valid_until DESC LIMIT @limit', { now, limit });
|
|
325
|
+
return rows.map(rowToEntry);
|
|
326
|
+
}
|
|
271
327
|
bulkRemove(ids) {
|
|
272
|
-
|
|
273
|
-
const tx = this.db.transaction((idList) => {
|
|
328
|
+
return this.provider.transaction(() => {
|
|
274
329
|
let count = 0;
|
|
275
|
-
for (const id of
|
|
276
|
-
count +=
|
|
330
|
+
for (const id of ids) {
|
|
331
|
+
count += this.provider.run('DELETE FROM entries WHERE id = ?', [id]).changes;
|
|
332
|
+
if (this.syncManager) {
|
|
333
|
+
this.syncManager.enqueue('delete', id);
|
|
334
|
+
}
|
|
277
335
|
}
|
|
278
336
|
return count;
|
|
279
337
|
});
|
|
280
|
-
return tx(ids);
|
|
281
338
|
}
|
|
282
|
-
/**
|
|
283
|
-
* List all unique tags with their occurrence counts.
|
|
284
|
-
*/
|
|
285
339
|
getTags() {
|
|
286
|
-
const rows = this.
|
|
340
|
+
const rows = this.provider.all('SELECT tags FROM entries');
|
|
287
341
|
const counts = new Map();
|
|
288
342
|
for (const row of rows) {
|
|
289
343
|
const tags = JSON.parse(row.tags || '[]');
|
|
@@ -295,41 +349,20 @@ export class Vault {
|
|
|
295
349
|
.map(([tag, count]) => ({ tag, count }))
|
|
296
350
|
.sort((a, b) => b.count - a.count);
|
|
297
351
|
}
|
|
298
|
-
/**
|
|
299
|
-
* List all domains with their entry counts.
|
|
300
|
-
*/
|
|
301
352
|
getDomains() {
|
|
302
|
-
|
|
303
|
-
.prepare('SELECT domain, COUNT(*) as count FROM entries GROUP BY domain ORDER BY count DESC')
|
|
304
|
-
.all();
|
|
305
|
-
return rows;
|
|
353
|
+
return this.provider.all('SELECT domain, COUNT(*) as count FROM entries GROUP BY domain ORDER BY count DESC');
|
|
306
354
|
}
|
|
307
|
-
/**
|
|
308
|
-
* Get recently added or updated entries, ordered by updated_at DESC.
|
|
309
|
-
*/
|
|
310
355
|
getRecent(limit = 20) {
|
|
311
|
-
const rows = this.
|
|
312
|
-
.prepare('SELECT * FROM entries ORDER BY updated_at DESC LIMIT ?')
|
|
313
|
-
.all(limit);
|
|
356
|
+
const rows = this.provider.all('SELECT * FROM entries ORDER BY updated_at DESC LIMIT ?', [limit]);
|
|
314
357
|
return rows.map(rowToEntry);
|
|
315
358
|
}
|
|
316
|
-
/**
|
|
317
|
-
* Export the entire vault as a JSON-serializable bundle.
|
|
318
|
-
*/
|
|
319
359
|
exportAll() {
|
|
320
|
-
const rows = this.
|
|
321
|
-
.prepare('SELECT * FROM entries ORDER BY domain, title')
|
|
322
|
-
.all();
|
|
360
|
+
const rows = this.provider.all('SELECT * FROM entries ORDER BY domain, title');
|
|
323
361
|
const entries = rows.map(rowToEntry);
|
|
324
362
|
return { entries, exportedAt: Math.floor(Date.now() / 1000), count: entries.length };
|
|
325
363
|
}
|
|
326
|
-
/**
|
|
327
|
-
* Get entry age distribution — how old entries are, bucketed.
|
|
328
|
-
*/
|
|
329
364
|
getAgeReport() {
|
|
330
|
-
const rows = this.
|
|
331
|
-
.prepare('SELECT created_at, updated_at FROM entries')
|
|
332
|
-
.all();
|
|
365
|
+
const rows = this.provider.all('SELECT created_at, updated_at FROM entries');
|
|
333
366
|
const now = Math.floor(Date.now() / 1000);
|
|
334
367
|
const bucketDefs = [
|
|
335
368
|
{ label: 'today', minDays: 0, maxDays: 1 },
|
|
@@ -366,16 +399,14 @@ export class Vault {
|
|
|
366
399
|
const projectName = name ?? path.replace(/\/$/, '').split('/').pop() ?? path;
|
|
367
400
|
const existing = this.getProject(path);
|
|
368
401
|
if (existing) {
|
|
369
|
-
this.
|
|
370
|
-
.prepare('UPDATE projects SET last_seen_at = unixepoch(), session_count = session_count + 1 WHERE path = ?')
|
|
371
|
-
.run(path);
|
|
402
|
+
this.provider.run('UPDATE projects SET last_seen_at = unixepoch(), session_count = session_count + 1 WHERE path = ?', [path]);
|
|
372
403
|
return this.getProject(path);
|
|
373
404
|
}
|
|
374
|
-
this.
|
|
405
|
+
this.provider.run('INSERT INTO projects (path, name) VALUES (?, ?)', [path, projectName]);
|
|
375
406
|
return this.getProject(path);
|
|
376
407
|
}
|
|
377
408
|
getProject(path) {
|
|
378
|
-
const row = this.
|
|
409
|
+
const row = this.provider.get('SELECT * FROM projects WHERE path = ?', [path]);
|
|
379
410
|
if (!row)
|
|
380
411
|
return null;
|
|
381
412
|
return {
|
|
@@ -387,9 +418,7 @@ export class Vault {
|
|
|
387
418
|
};
|
|
388
419
|
}
|
|
389
420
|
listProjects() {
|
|
390
|
-
const rows = this.
|
|
391
|
-
.prepare('SELECT * FROM projects ORDER BY last_seen_at DESC')
|
|
392
|
-
.all();
|
|
421
|
+
const rows = this.provider.all('SELECT * FROM projects ORDER BY last_seen_at DESC');
|
|
393
422
|
return rows.map((row) => ({
|
|
394
423
|
path: row.path,
|
|
395
424
|
name: row.name,
|
|
@@ -400,9 +429,7 @@ export class Vault {
|
|
|
400
429
|
}
|
|
401
430
|
captureMemory(memory) {
|
|
402
431
|
const id = `mem-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
403
|
-
this.
|
|
404
|
-
.prepare(`INSERT INTO memories (id, project_path, type, context, summary, topics, files_modified, tools_used) VALUES (@id, @projectPath, @type, @context, @summary, @topics, @filesModified, @toolsUsed)`)
|
|
405
|
-
.run({
|
|
432
|
+
this.provider.run(`INSERT INTO memories (id, project_path, type, context, summary, topics, files_modified, tools_used) VALUES (@id, @projectPath, @type, @context, @summary, @topics, @filesModified, @toolsUsed)`, {
|
|
406
433
|
id,
|
|
407
434
|
projectPath: memory.projectPath,
|
|
408
435
|
type: memory.type,
|
|
@@ -428,9 +455,7 @@ export class Vault {
|
|
|
428
455
|
}
|
|
429
456
|
const wc = filters.length > 0 ? `AND ${filters.join(' AND ')}` : '';
|
|
430
457
|
try {
|
|
431
|
-
const rows = this.
|
|
432
|
-
.prepare(`SELECT m.* FROM memories_fts fts JOIN memories m ON m.rowid = fts.rowid WHERE memories_fts MATCH @query ${wc} ORDER BY rank LIMIT @limit`)
|
|
433
|
-
.all({ query, limit, ...fp });
|
|
458
|
+
const rows = this.provider.all(`SELECT m.* FROM memories_fts fts JOIN memories m ON m.rowid = fts.rowid WHERE memories_fts MATCH @query ${wc} ORDER BY rank LIMIT @limit`, { query, limit, ...fp });
|
|
434
459
|
return rows.map(rowToMemory);
|
|
435
460
|
}
|
|
436
461
|
catch {
|
|
@@ -449,19 +474,13 @@ export class Vault {
|
|
|
449
474
|
params.projectPath = options.projectPath;
|
|
450
475
|
}
|
|
451
476
|
const wc = `WHERE ${filters.join(' AND ')}`;
|
|
452
|
-
const rows = this.
|
|
453
|
-
.prepare(`SELECT * FROM memories ${wc} ORDER BY created_at DESC LIMIT @limit OFFSET @offset`)
|
|
454
|
-
.all({ ...params, limit: options?.limit ?? 50, offset: options?.offset ?? 0 });
|
|
477
|
+
const rows = this.provider.all(`SELECT * FROM memories ${wc} ORDER BY created_at DESC LIMIT @limit OFFSET @offset`, { ...params, limit: options?.limit ?? 50, offset: options?.offset ?? 0 });
|
|
455
478
|
return rows.map(rowToMemory);
|
|
456
479
|
}
|
|
457
480
|
memoryStats() {
|
|
458
|
-
const total = this.
|
|
459
|
-
const byTypeRows = this.
|
|
460
|
-
|
|
461
|
-
.all();
|
|
462
|
-
const byProjectRows = this.db
|
|
463
|
-
.prepare('SELECT project_path as key, COUNT(*) as count FROM memories WHERE archived_at IS NULL GROUP BY project_path')
|
|
464
|
-
.all();
|
|
481
|
+
const total = this.provider.get('SELECT COUNT(*) as count FROM memories WHERE archived_at IS NULL').count;
|
|
482
|
+
const byTypeRows = this.provider.all('SELECT type as key, COUNT(*) as count FROM memories WHERE archived_at IS NULL GROUP BY type');
|
|
483
|
+
const byProjectRows = this.provider.all('SELECT project_path as key, COUNT(*) as count FROM memories WHERE archived_at IS NULL GROUP BY project_path');
|
|
465
484
|
return {
|
|
466
485
|
total,
|
|
467
486
|
byType: Object.fromEntries(byTypeRows.map((r) => [r.key, r.count])),
|
|
@@ -469,11 +488,13 @@ export class Vault {
|
|
|
469
488
|
};
|
|
470
489
|
}
|
|
471
490
|
getMemory(id) {
|
|
472
|
-
const row = this.
|
|
491
|
+
const row = this.provider.get('SELECT * FROM memories WHERE id = ?', [
|
|
492
|
+
id,
|
|
493
|
+
]);
|
|
473
494
|
return row ? rowToMemory(row) : null;
|
|
474
495
|
}
|
|
475
496
|
deleteMemory(id) {
|
|
476
|
-
return this.
|
|
497
|
+
return this.provider.run('DELETE FROM memories WHERE id = ?', [id]).changes > 0;
|
|
477
498
|
}
|
|
478
499
|
memoryStatsDetailed(options) {
|
|
479
500
|
const filters = [];
|
|
@@ -491,21 +512,11 @@ export class Vault {
|
|
|
491
512
|
params.toDate = options.toDate;
|
|
492
513
|
}
|
|
493
514
|
const wc = filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : '';
|
|
494
|
-
const total = this.
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
.get(params).count;
|
|
500
|
-
const byTypeRows = this.db
|
|
501
|
-
.prepare(`SELECT type as key, COUNT(*) as count FROM memories ${wc}${wc ? ' AND' : ' WHERE'} archived_at IS NULL GROUP BY type`)
|
|
502
|
-
.all(params);
|
|
503
|
-
const byProjectRows = this.db
|
|
504
|
-
.prepare(`SELECT project_path as key, COUNT(*) as count FROM memories ${wc}${wc ? ' AND' : ' WHERE'} archived_at IS NULL GROUP BY project_path`)
|
|
505
|
-
.all(params);
|
|
506
|
-
const dateRange = this.db
|
|
507
|
-
.prepare(`SELECT MIN(created_at) as oldest, MAX(created_at) as newest FROM memories ${wc}${wc ? ' AND' : ' WHERE'} archived_at IS NULL`)
|
|
508
|
-
.get(params);
|
|
515
|
+
const total = this.provider.get(`SELECT COUNT(*) as count FROM memories ${wc}${wc ? ' AND' : ' WHERE'} archived_at IS NULL`, params).count;
|
|
516
|
+
const archivedCount = this.provider.get(`SELECT COUNT(*) as count FROM memories ${wc}${wc ? ' AND' : ' WHERE'} archived_at IS NOT NULL`, params).count;
|
|
517
|
+
const byTypeRows = this.provider.all(`SELECT type as key, COUNT(*) as count FROM memories ${wc}${wc ? ' AND' : ' WHERE'} archived_at IS NULL GROUP BY type`, params);
|
|
518
|
+
const byProjectRows = this.provider.all(`SELECT project_path as key, COUNT(*) as count FROM memories ${wc}${wc ? ' AND' : ' WHERE'} archived_at IS NULL GROUP BY project_path`, params);
|
|
519
|
+
const dateRange = this.provider.get(`SELECT MIN(created_at) as oldest, MAX(created_at) as newest FROM memories ${wc}${wc ? ' AND' : ' WHERE'} archived_at IS NULL`, params);
|
|
509
520
|
return {
|
|
510
521
|
total,
|
|
511
522
|
byType: Object.fromEntries(byTypeRows.map((r) => [r.key, r.count])),
|
|
@@ -530,21 +541,19 @@ export class Vault {
|
|
|
530
541
|
params.type = options.type;
|
|
531
542
|
}
|
|
532
543
|
const wc = filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : '';
|
|
533
|
-
const rows = this.
|
|
534
|
-
.prepare(`SELECT * FROM memories ${wc} ORDER BY created_at ASC`)
|
|
535
|
-
.all(params);
|
|
544
|
+
const rows = this.provider.all(`SELECT * FROM memories ${wc} ORDER BY created_at ASC`, Object.keys(params).length > 0 ? params : undefined);
|
|
536
545
|
return rows.map(rowToMemory);
|
|
537
546
|
}
|
|
538
547
|
importMemories(memories) {
|
|
539
|
-
const
|
|
548
|
+
const sql = `
|
|
540
549
|
INSERT OR IGNORE INTO memories (id, project_path, type, context, summary, topics, files_modified, tools_used, created_at, archived_at)
|
|
541
550
|
VALUES (@id, @projectPath, @type, @context, @summary, @topics, @filesModified, @toolsUsed, @createdAt, @archivedAt)
|
|
542
|
-
|
|
551
|
+
`;
|
|
543
552
|
let imported = 0;
|
|
544
553
|
let skipped = 0;
|
|
545
|
-
|
|
546
|
-
for (const m of
|
|
547
|
-
const result =
|
|
554
|
+
this.provider.transaction(() => {
|
|
555
|
+
for (const m of memories) {
|
|
556
|
+
const result = this.provider.run(sql, {
|
|
548
557
|
id: m.id,
|
|
549
558
|
projectPath: m.projectPath,
|
|
550
559
|
type: m.type,
|
|
@@ -562,20 +571,15 @@ export class Vault {
|
|
|
562
571
|
skipped++;
|
|
563
572
|
}
|
|
564
573
|
});
|
|
565
|
-
tx(memories);
|
|
566
574
|
return { imported, skipped };
|
|
567
575
|
}
|
|
568
576
|
pruneMemories(olderThanDays) {
|
|
569
577
|
const cutoff = Math.floor(Date.now() / 1000) - olderThanDays * 86400;
|
|
570
|
-
const result = this.
|
|
571
|
-
.prepare('DELETE FROM memories WHERE created_at < ? AND archived_at IS NULL')
|
|
572
|
-
.run(cutoff);
|
|
578
|
+
const result = this.provider.run('DELETE FROM memories WHERE created_at < ? AND archived_at IS NULL', [cutoff]);
|
|
573
579
|
return { pruned: result.changes };
|
|
574
580
|
}
|
|
575
581
|
deduplicateMemories() {
|
|
576
|
-
|
|
577
|
-
const dupeRows = this.db
|
|
578
|
-
.prepare(`
|
|
582
|
+
const dupeRows = this.provider.all(`
|
|
579
583
|
SELECT m1.id as id1, m2.id as id2
|
|
580
584
|
FROM memories m1
|
|
581
585
|
JOIN memories m2 ON m1.summary = m2.summary
|
|
@@ -584,9 +588,7 @@ export class Vault {
|
|
|
584
588
|
AND m1.id < m2.id
|
|
585
589
|
AND m1.archived_at IS NULL
|
|
586
590
|
AND m2.archived_at IS NULL
|
|
587
|
-
`)
|
|
588
|
-
.all();
|
|
589
|
-
// Group: keep the earliest (id1), remove all later duplicates
|
|
591
|
+
`);
|
|
590
592
|
const groupMap = new Map();
|
|
591
593
|
for (const row of dupeRows) {
|
|
592
594
|
if (!groupMap.has(row.id1))
|
|
@@ -604,19 +606,16 @@ export class Vault {
|
|
|
604
606
|
}
|
|
605
607
|
}
|
|
606
608
|
if (toRemove.size > 0) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
609
|
+
this.provider.transaction(() => {
|
|
610
|
+
for (const id of toRemove) {
|
|
611
|
+
this.provider.run('DELETE FROM memories WHERE id = ?', [id]);
|
|
612
|
+
}
|
|
611
613
|
});
|
|
612
|
-
tx([...toRemove]);
|
|
613
614
|
}
|
|
614
615
|
return { removed: toRemove.size, groups };
|
|
615
616
|
}
|
|
616
617
|
memoryTopics() {
|
|
617
|
-
const rows = this.
|
|
618
|
-
.prepare('SELECT topics FROM memories WHERE archived_at IS NULL')
|
|
619
|
-
.all();
|
|
618
|
+
const rows = this.provider.all('SELECT topics FROM memories WHERE archived_at IS NULL');
|
|
620
619
|
const topicCounts = new Map();
|
|
621
620
|
for (const row of rows) {
|
|
622
621
|
const topics = JSON.parse(row.topics || '[]');
|
|
@@ -629,13 +628,9 @@ export class Vault {
|
|
|
629
628
|
.sort((a, b) => b.count - a.count);
|
|
630
629
|
}
|
|
631
630
|
memoriesByProject() {
|
|
632
|
-
const rows = this.
|
|
633
|
-
.prepare('SELECT project_path as project, COUNT(*) as count FROM memories WHERE archived_at IS NULL GROUP BY project_path ORDER BY count DESC')
|
|
634
|
-
.all();
|
|
631
|
+
const rows = this.provider.all('SELECT project_path as project, COUNT(*) as count FROM memories WHERE archived_at IS NULL GROUP BY project_path ORDER BY count DESC');
|
|
635
632
|
return rows.map((row) => {
|
|
636
|
-
const memories = this.
|
|
637
|
-
.prepare('SELECT * FROM memories WHERE project_path = ? AND archived_at IS NULL ORDER BY created_at DESC')
|
|
638
|
-
.all(row.project);
|
|
633
|
+
const memories = this.provider.all('SELECT * FROM memories WHERE project_path = ? AND archived_at IS NULL ORDER BY created_at DESC', [row.project]);
|
|
639
634
|
return {
|
|
640
635
|
project: row.project,
|
|
641
636
|
count: row.count,
|
|
@@ -643,17 +638,40 @@ export class Vault {
|
|
|
643
638
|
};
|
|
644
639
|
});
|
|
645
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* Rebuild the FTS5 index for the entries table.
|
|
643
|
+
* Useful after bulk operations or if the index gets out of sync.
|
|
644
|
+
*/
|
|
645
|
+
rebuildFtsIndex() {
|
|
646
|
+
try {
|
|
647
|
+
this.provider.run("INSERT INTO entries_fts(entries_fts) VALUES('rebuild')");
|
|
648
|
+
}
|
|
649
|
+
catch {
|
|
650
|
+
// Graceful degradation — FTS rebuild failed (e.g. table doesn't exist yet)
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Get the underlying persistence provider.
|
|
655
|
+
*/
|
|
656
|
+
getProvider() {
|
|
657
|
+
return this.provider;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Get the raw better-sqlite3 Database (backward compat).
|
|
661
|
+
* Throws if the provider is not SQLite.
|
|
662
|
+
*/
|
|
646
663
|
getDb() {
|
|
647
|
-
|
|
664
|
+
if (this.sqliteProvider) {
|
|
665
|
+
return this.sqliteProvider.getDatabase();
|
|
666
|
+
}
|
|
667
|
+
throw new Error('getDb() is only available with SQLite provider');
|
|
648
668
|
}
|
|
649
669
|
close() {
|
|
650
|
-
this.
|
|
670
|
+
this.provider.close();
|
|
651
671
|
}
|
|
652
672
|
}
|
|
653
|
-
function gc(
|
|
654
|
-
const rows =
|
|
655
|
-
.prepare(`SELECT ${col} as key, COUNT(*) as count FROM entries GROUP BY ${col}`)
|
|
656
|
-
.all();
|
|
673
|
+
function gc(provider, col) {
|
|
674
|
+
const rows = provider.all(`SELECT ${col} as key, COUNT(*) as count FROM entries GROUP BY ${col}`);
|
|
657
675
|
return Object.fromEntries(rows.map((r) => [r.key, r.count]));
|
|
658
676
|
}
|
|
659
677
|
function rowToEntry(row) {
|
|
@@ -670,6 +688,8 @@ function rowToEntry(row) {
|
|
|
670
688
|
why: row.why ?? undefined,
|
|
671
689
|
tags: JSON.parse(row.tags || '[]'),
|
|
672
690
|
appliesTo: JSON.parse(row.applies_to || '[]'),
|
|
691
|
+
validFrom: row.valid_from ?? undefined,
|
|
692
|
+
validUntil: row.valid_until ?? undefined,
|
|
673
693
|
};
|
|
674
694
|
}
|
|
675
695
|
function rowToSearchResult(row) {
|