@soleri/core 2.4.0 → 2.6.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/intelligence.d.ts +1 -0
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +164 -148
- package/dist/brain/intelligence.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/control/identity-manager.d.ts +3 -1
- package/dist/control/identity-manager.d.ts.map +1 -1
- package/dist/control/identity-manager.js +49 -51
- package/dist/control/identity-manager.js.map +1 -1
- package/dist/control/intent-router.d.ts +1 -0
- package/dist/control/intent-router.d.ts.map +1 -1
- package/dist/control/intent-router.js +32 -32
- package/dist/control/intent-router.js.map +1 -1
- package/dist/curator/curator.d.ts +9 -1
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +104 -92
- 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/governance/governance.d.ts +1 -0
- package/dist/governance/governance.d.ts.map +1 -1
- package/dist/governance/governance.js +51 -68
- package/dist/governance/governance.js.map +1 -1
- package/dist/index.d.ts +26 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -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 +4 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +3 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/postgres-provider.d.ts +46 -0
- package/dist/persistence/postgres-provider.d.ts.map +1 -0
- package/dist/persistence/postgres-provider.js +115 -0
- package/dist/persistence/postgres-provider.js.map +1 -0
- package/dist/persistence/sqlite-provider.d.ts +28 -0
- package/dist/persistence/sqlite-provider.d.ts.map +1 -0
- package/dist/persistence/sqlite-provider.js +97 -0
- package/dist/persistence/sqlite-provider.js.map +1 -0
- package/dist/persistence/types.d.ts +58 -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 +4 -4
- package/dist/project/project-registry.d.ts.map +1 -1
- package/dist/project/project-registry.js +30 -57
- 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 +348 -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 +28 -9
- 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 +4 -2
- package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
- package/dist/runtime/vault-extra-ops.js +383 -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 +52 -32
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +300 -181
- package/dist/vault/vault.js.map +1 -1
- package/package.json +9 -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 +36 -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 +291 -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__/postgres-provider.test.ts +58 -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/__tests__/vault.test.ts +184 -0
- package/src/brain/brain.ts +71 -9
- package/src/brain/intelligence.ts +258 -307
- package/src/brain/types.ts +2 -2
- package/src/cognee/client.ts +18 -0
- package/src/cognee/sync-manager.ts +389 -0
- package/src/control/identity-manager.ts +77 -75
- package/src/control/intent-router.ts +55 -57
- package/src/curator/curator.ts +199 -139
- 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/governance/governance.ts +90 -107
- package/src/index.ts +116 -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 +9 -0
- package/src/persistence/postgres-provider.ts +157 -0
- package/src/persistence/sqlite-provider.ts +115 -0
- package/src/persistence/types.ts +74 -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 +81 -74
- 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 +391 -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 +36 -10
- package/src/runtime/types.ts +8 -0
- package/src/runtime/vault-extra-ops.ts +425 -4
- package/src/vault/playbook.ts +87 -0
- package/src/vault/vault.ts +419 -235
|
@@ -83,16 +83,17 @@ const DEFAULT_MODES = [
|
|
|
83
83
|
// ─── Class ──────────────────────────────────────────────────────────
|
|
84
84
|
export class IntentRouter {
|
|
85
85
|
vault;
|
|
86
|
+
provider;
|
|
86
87
|
currentMode = 'GENERAL-MODE';
|
|
87
88
|
constructor(vault) {
|
|
88
89
|
this.vault = vault;
|
|
90
|
+
this.provider = vault.getProvider();
|
|
89
91
|
this.initializeTables();
|
|
90
92
|
this.seedDefaultModes();
|
|
91
93
|
}
|
|
92
94
|
// ─── Table Initialization ───────────────────────────────────────────
|
|
93
95
|
initializeTables() {
|
|
94
|
-
|
|
95
|
-
db.exec(`
|
|
96
|
+
this.provider.execSql(`
|
|
96
97
|
CREATE TABLE IF NOT EXISTS agent_modes (
|
|
97
98
|
mode TEXT PRIMARY KEY,
|
|
98
99
|
intent TEXT NOT NULL,
|
|
@@ -113,12 +114,12 @@ export class IntentRouter {
|
|
|
113
114
|
`);
|
|
114
115
|
}
|
|
115
116
|
seedDefaultModes() {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
117
|
+
this.provider.transaction(() => {
|
|
118
|
+
for (const m of DEFAULT_MODES) {
|
|
119
|
+
this.provider.run(`INSERT OR IGNORE INTO agent_modes (mode, intent, description, behavior_rules, keywords)
|
|
120
|
+
VALUES (?, ?, ?, ?, ?)`, [m.mode, m.intent, m.description, JSON.stringify(m.behaviorRules), JSON.stringify(m.keywords)]);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
122
123
|
}
|
|
123
124
|
// ─── Intent Classification ──────────────────────────────────────────
|
|
124
125
|
routeIntent(prompt) {
|
|
@@ -162,14 +163,18 @@ export class IntentRouter {
|
|
|
162
163
|
return classification;
|
|
163
164
|
}
|
|
164
165
|
logRouting(prompt, classification) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
this.provider.run(`INSERT INTO agent_routing_log (prompt, intent, mode, confidence, matched_keywords)
|
|
167
|
+
VALUES (?, ?, ?, ?, ?)`, [
|
|
168
|
+
prompt,
|
|
169
|
+
classification.intent,
|
|
170
|
+
classification.mode,
|
|
171
|
+
classification.confidence,
|
|
172
|
+
JSON.stringify(classification.matchedKeywords),
|
|
173
|
+
]);
|
|
168
174
|
}
|
|
169
175
|
// ─── Mode Management ───────────────────────────────────────────────
|
|
170
176
|
morph(mode) {
|
|
171
|
-
const
|
|
172
|
-
const row = db.prepare('SELECT * FROM agent_modes WHERE mode = ?').get(mode);
|
|
177
|
+
const row = this.provider.get('SELECT * FROM agent_modes WHERE mode = ?', [mode]);
|
|
173
178
|
if (!row) {
|
|
174
179
|
throw new Error(`Unknown mode: ${mode}`);
|
|
175
180
|
}
|
|
@@ -182,46 +187,41 @@ export class IntentRouter {
|
|
|
182
187
|
return this.currentMode;
|
|
183
188
|
}
|
|
184
189
|
getBehaviorRules(mode) {
|
|
185
|
-
const db = this.vault.getDb();
|
|
186
190
|
const target = mode ?? this.currentMode;
|
|
187
|
-
const row =
|
|
191
|
+
const row = this.provider.get('SELECT behavior_rules FROM agent_modes WHERE mode = ?', [target]);
|
|
188
192
|
if (!row)
|
|
189
193
|
return [];
|
|
190
194
|
return JSON.parse(row.behavior_rules);
|
|
191
195
|
}
|
|
192
196
|
getModes() {
|
|
193
|
-
const
|
|
194
|
-
const rows = db.prepare('SELECT * FROM agent_modes ORDER BY mode').all();
|
|
197
|
+
const rows = this.provider.all('SELECT * FROM agent_modes ORDER BY mode');
|
|
195
198
|
return rows.map(rowToModeConfig);
|
|
196
199
|
}
|
|
197
200
|
registerMode(config) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
+
this.provider.run(`INSERT OR REPLACE INTO agent_modes (mode, intent, description, behavior_rules, keywords)
|
|
202
|
+
VALUES (?, ?, ?, ?, ?)`, [
|
|
203
|
+
config.mode,
|
|
204
|
+
config.intent,
|
|
205
|
+
config.description,
|
|
206
|
+
JSON.stringify(config.behaviorRules),
|
|
207
|
+
JSON.stringify(config.keywords),
|
|
208
|
+
]);
|
|
201
209
|
}
|
|
202
210
|
updateModeRules(mode, rules) {
|
|
203
|
-
const
|
|
204
|
-
const result = db
|
|
205
|
-
.prepare('UPDATE agent_modes SET behavior_rules = ? WHERE mode = ?')
|
|
206
|
-
.run(JSON.stringify(rules), mode);
|
|
211
|
+
const result = this.provider.run('UPDATE agent_modes SET behavior_rules = ? WHERE mode = ?', [JSON.stringify(rules), mode]);
|
|
207
212
|
if (result.changes === 0) {
|
|
208
213
|
throw new Error(`Unknown mode: ${mode}`);
|
|
209
214
|
}
|
|
210
215
|
}
|
|
211
216
|
// ─── Analytics ──────────────────────────────────────────────────────
|
|
212
217
|
getRoutingStats() {
|
|
213
|
-
const
|
|
214
|
-
const
|
|
215
|
-
const intentRows = db
|
|
216
|
-
.prepare('SELECT intent, COUNT(*) as count FROM agent_routing_log GROUP BY intent')
|
|
217
|
-
.all();
|
|
218
|
+
const total = (this.provider.get('SELECT COUNT(*) as count FROM agent_routing_log')).count;
|
|
219
|
+
const intentRows = this.provider.all('SELECT intent, COUNT(*) as count FROM agent_routing_log GROUP BY intent');
|
|
218
220
|
const byIntent = {};
|
|
219
221
|
for (const row of intentRows) {
|
|
220
222
|
byIntent[row.intent] = row.count;
|
|
221
223
|
}
|
|
222
|
-
const modeRows =
|
|
223
|
-
.prepare('SELECT mode, COUNT(*) as count FROM agent_routing_log GROUP BY mode')
|
|
224
|
-
.all();
|
|
224
|
+
const modeRows = this.provider.all('SELECT mode, COUNT(*) as count FROM agent_routing_log GROUP BY mode');
|
|
225
225
|
const byMode = {};
|
|
226
226
|
for (const row of modeRows) {
|
|
227
227
|
byMode[row.mode] = row.count;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-router.js","sourceRoot":"","sources":["../../src/control/intent-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"intent-router.js","sourceRoot":"","sources":["../../src/control/intent-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { Vault } from '../vault/vault.js';
|
|
2
2
|
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
3
|
+
import type { CogneeClient } from '../cognee/client.js';
|
|
3
4
|
import type { CuratorStatus, TagNormalizationResult, CanonicalTag, DuplicateDetectionResult, Contradiction, ContradictionStatus, GroomResult, GroomAllResult, ConsolidationOptions, ConsolidationResult, ChangelogEntry, HealthAuditResult } from './types.js';
|
|
4
5
|
export declare class Curator {
|
|
5
6
|
private vault;
|
|
6
|
-
|
|
7
|
+
private cognee;
|
|
8
|
+
private provider;
|
|
9
|
+
constructor(vault: Vault, cognee?: CogneeClient);
|
|
7
10
|
private initializeTables;
|
|
8
11
|
private seedDefaultAliases;
|
|
9
12
|
getStatus(): CuratorStatus;
|
|
@@ -16,6 +19,11 @@ export declare class Curator {
|
|
|
16
19
|
detectContradictions(threshold?: number): Contradiction[];
|
|
17
20
|
getContradictions(status?: ContradictionStatus): Contradiction[];
|
|
18
21
|
resolveContradiction(id: number, resolution: 'resolved' | 'dismissed'): Contradiction | null;
|
|
22
|
+
detectContradictionsHybrid(threshold?: number): Promise<{
|
|
23
|
+
contradictions: Contradiction[];
|
|
24
|
+
cogneeAvailable: boolean;
|
|
25
|
+
method: 'hybrid' | 'tfidf-only';
|
|
26
|
+
}>;
|
|
19
27
|
groomEntry(entryId: string): GroomResult | null;
|
|
20
28
|
groomAll(): GroomAllResult;
|
|
21
29
|
consolidate(options?: ConsolidationOptions): ConsolidationResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"curator.d.ts","sourceRoot":"","sources":["../../src/curator/curator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"curator.d.ts","sourceRoot":"","sources":["../../src/curator/curator.ts"],"names":[],"mappings":"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"}
|
package/dist/curator/curator.js
CHANGED
|
@@ -22,15 +22,18 @@ const DEFAULT_TAG_ALIASES = [
|
|
|
22
22
|
// ─── Curator Class ──────────────────────────────────────────────────
|
|
23
23
|
export class Curator {
|
|
24
24
|
vault;
|
|
25
|
-
|
|
25
|
+
cognee;
|
|
26
|
+
provider;
|
|
27
|
+
constructor(vault, cognee) {
|
|
26
28
|
this.vault = vault;
|
|
29
|
+
this.cognee = cognee;
|
|
30
|
+
this.provider = vault.getProvider();
|
|
27
31
|
this.initializeTables();
|
|
28
32
|
this.seedDefaultAliases();
|
|
29
33
|
}
|
|
30
34
|
// ─── Schema ─────────────────────────────────────────────────────
|
|
31
35
|
initializeTables() {
|
|
32
|
-
|
|
33
|
-
db.exec(`
|
|
36
|
+
this.provider.execSql(`
|
|
34
37
|
CREATE TABLE IF NOT EXISTS curator_entry_state (
|
|
35
38
|
entry_id TEXT PRIMARY KEY,
|
|
36
39
|
status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'stale', 'archived')),
|
|
@@ -82,30 +85,25 @@ export class Curator {
|
|
|
82
85
|
resolved_at INTEGER,
|
|
83
86
|
UNIQUE(pattern_id, antipattern_id)
|
|
84
87
|
);
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_curator_state_status ON curator_entry_state(status);
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_curator_changelog_entry ON curator_changelog(entry_id);
|
|
85
90
|
`);
|
|
86
91
|
}
|
|
87
92
|
seedDefaultAliases() {
|
|
88
|
-
|
|
89
|
-
const insertCanonical = db.prepare('INSERT OR IGNORE INTO curator_tag_canonical (tag) VALUES (?)');
|
|
90
|
-
const insertAlias = db.prepare('INSERT OR IGNORE INTO curator_tag_alias (alias, canonical) VALUES (?, ?)');
|
|
91
|
-
const tx = db.transaction(() => {
|
|
93
|
+
this.provider.transaction(() => {
|
|
92
94
|
const canonicals = new Set(DEFAULT_TAG_ALIASES.map(([, c]) => c));
|
|
93
95
|
for (const tag of canonicals) {
|
|
94
|
-
|
|
96
|
+
this.provider.run('INSERT OR IGNORE INTO curator_tag_canonical (tag) VALUES (?)', [tag]);
|
|
95
97
|
}
|
|
96
98
|
for (const [alias, canonical] of DEFAULT_TAG_ALIASES) {
|
|
97
|
-
|
|
99
|
+
this.provider.run('INSERT OR IGNORE INTO curator_tag_alias (alias, canonical) VALUES (?, ?)', [alias, canonical]);
|
|
98
100
|
}
|
|
99
101
|
});
|
|
100
|
-
tx();
|
|
101
102
|
}
|
|
102
103
|
// ─── Status ─────────────────────────────────────────────────────
|
|
103
104
|
getStatus() {
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const lastGroomed = db
|
|
107
|
-
.prepare('SELECT MAX(last_groomed_at) as ts FROM curator_entry_state WHERE last_groomed_at IS NOT NULL')
|
|
108
|
-
.get();
|
|
105
|
+
const tableCount = (table) => (this.provider.get(`SELECT COUNT(*) as count FROM ${table}`) ?? { count: 0 }).count;
|
|
106
|
+
const lastGroomed = this.provider.get('SELECT MAX(last_groomed_at) as ts FROM curator_entry_state WHERE last_groomed_at IS NOT NULL') ?? { ts: null };
|
|
109
107
|
return {
|
|
110
108
|
initialized: true,
|
|
111
109
|
tables: {
|
|
@@ -120,9 +118,8 @@ export class Curator {
|
|
|
120
118
|
}
|
|
121
119
|
// ─── Tag Normalization ──────────────────────────────────────────
|
|
122
120
|
normalizeTag(tag) {
|
|
123
|
-
const db = this.vault.getDb();
|
|
124
121
|
const lower = tag.toLowerCase().trim();
|
|
125
|
-
const row =
|
|
122
|
+
const row = this.provider.get('SELECT canonical FROM curator_tag_alias WHERE alias = ?', [lower]);
|
|
126
123
|
if (row) {
|
|
127
124
|
return { original: tag, normalized: row.canonical, wasAliased: true };
|
|
128
125
|
}
|
|
@@ -144,27 +141,22 @@ export class Curator {
|
|
|
144
141
|
}
|
|
145
142
|
if (changed) {
|
|
146
143
|
const dedupedTags = [...new Set(normalizedTags)];
|
|
147
|
-
|
|
148
|
-
db.prepare('UPDATE entries SET tags = ?, updated_at = unixepoch() WHERE id = ?').run(JSON.stringify(dedupedTags), entryId);
|
|
144
|
+
this.provider.run('UPDATE entries SET tags = ?, updated_at = unixepoch() WHERE id = ?', [JSON.stringify(dedupedTags), entryId]);
|
|
149
145
|
this.logChange('normalize_tags', entryId, JSON.stringify(entry.tags), JSON.stringify(dedupedTags), 'Tag normalization');
|
|
150
146
|
}
|
|
151
147
|
return results;
|
|
152
148
|
}
|
|
153
149
|
addTagAlias(alias, canonical) {
|
|
154
|
-
const db = this.vault.getDb();
|
|
155
150
|
const lower = alias.toLowerCase().trim();
|
|
156
151
|
const canonicalLower = canonical.toLowerCase().trim();
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
this.provider.run('INSERT OR IGNORE INTO curator_tag_canonical (tag) VALUES (?)', [canonicalLower]);
|
|
153
|
+
this.provider.run('INSERT OR REPLACE INTO curator_tag_alias (alias, canonical) VALUES (?, ?)', [lower, canonicalLower]);
|
|
159
154
|
}
|
|
160
155
|
getCanonicalTags() {
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
FROM curator_tag_canonical c
|
|
166
|
-
ORDER BY c.tag`)
|
|
167
|
-
.all();
|
|
156
|
+
const rows = this.provider.all(`SELECT c.tag, c.description,
|
|
157
|
+
(SELECT COUNT(*) FROM curator_tag_alias a WHERE a.canonical = c.tag) as alias_count
|
|
158
|
+
FROM curator_tag_canonical c
|
|
159
|
+
ORDER BY c.tag`);
|
|
168
160
|
return rows.map((row) => ({
|
|
169
161
|
tag: row.tag,
|
|
170
162
|
description: row.description,
|
|
@@ -173,11 +165,8 @@ export class Curator {
|
|
|
173
165
|
}));
|
|
174
166
|
}
|
|
175
167
|
countTagUsage(tag) {
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
.prepare('SELECT COUNT(*) as count FROM entries WHERE tags LIKE ?')
|
|
179
|
-
.get(`%"${tag}"%`);
|
|
180
|
-
return row.count;
|
|
168
|
+
const row = this.provider.get('SELECT COUNT(*) as count FROM entries WHERE tags LIKE ?', [`%"${tag}"%`]);
|
|
169
|
+
return row?.count ?? 0;
|
|
181
170
|
}
|
|
182
171
|
// ─── Duplicate Detection ────────────────────────────────────────
|
|
183
172
|
detectDuplicates(entryId, threshold) {
|
|
@@ -232,10 +221,7 @@ export class Curator {
|
|
|
232
221
|
if (antipatterns.length === 0 || patterns.length === 0)
|
|
233
222
|
return [];
|
|
234
223
|
const vocabulary = this.buildVocabulary(entries);
|
|
235
|
-
const db = this.vault.getDb();
|
|
236
224
|
const detected = [];
|
|
237
|
-
const insertStmt = db.prepare(`INSERT OR IGNORE INTO curator_contradictions (pattern_id, antipattern_id, similarity)
|
|
238
|
-
VALUES (?, ?, ?)`);
|
|
239
225
|
for (const ap of antipatterns) {
|
|
240
226
|
// Stage 1: FTS5 candidate retrieval (fall back to all patterns if FTS returns empty)
|
|
241
227
|
let candidates;
|
|
@@ -254,12 +240,11 @@ export class Curator {
|
|
|
254
240
|
const pVec = calculateTfIdf(tokenize(pText), vocabulary);
|
|
255
241
|
const similarity = cosineSimilarity(apVec, pVec);
|
|
256
242
|
if (similarity >= effectiveThreshold) {
|
|
257
|
-
const result =
|
|
243
|
+
const result = this.provider.run('INSERT OR IGNORE INTO curator_contradictions (pattern_id, antipattern_id, similarity) VALUES (?, ?, ?)', [pattern.id, ap.id, similarity]);
|
|
258
244
|
if (result.changes > 0) {
|
|
259
|
-
const row =
|
|
260
|
-
|
|
261
|
-
.
|
|
262
|
-
detected.push(this.rowToContradiction(row));
|
|
245
|
+
const row = this.provider.get('SELECT * FROM curator_contradictions WHERE pattern_id = ? AND antipattern_id = ?', [pattern.id, ap.id]);
|
|
246
|
+
if (row)
|
|
247
|
+
detected.push(this.rowToContradiction(row));
|
|
263
248
|
}
|
|
264
249
|
}
|
|
265
250
|
}
|
|
@@ -267,19 +252,74 @@ export class Curator {
|
|
|
267
252
|
return detected;
|
|
268
253
|
}
|
|
269
254
|
getContradictions(status) {
|
|
270
|
-
const db = this.vault.getDb();
|
|
271
255
|
const query = status
|
|
272
256
|
? 'SELECT * FROM curator_contradictions WHERE status = ? ORDER BY similarity DESC'
|
|
273
257
|
: 'SELECT * FROM curator_contradictions ORDER BY similarity DESC';
|
|
274
|
-
const rows = (status ?
|
|
258
|
+
const rows = this.provider.all(query, status ? [status] : undefined);
|
|
275
259
|
return rows.map((r) => this.rowToContradiction(r));
|
|
276
260
|
}
|
|
277
261
|
resolveContradiction(id, resolution) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const row = db.prepare('SELECT * FROM curator_contradictions WHERE id = ?').get(id);
|
|
262
|
+
this.provider.run('UPDATE curator_contradictions SET status = ?, resolved_at = unixepoch() WHERE id = ?', [resolution, id]);
|
|
263
|
+
const row = this.provider.get('SELECT * FROM curator_contradictions WHERE id = ?', [id]);
|
|
281
264
|
return row ? this.rowToContradiction(row) : null;
|
|
282
265
|
}
|
|
266
|
+
async detectContradictionsHybrid(threshold) {
|
|
267
|
+
const effectiveThreshold = threshold ?? DEFAULT_CONTRADICTION_THRESHOLD;
|
|
268
|
+
const entries = this.vault.list({ limit: 100000 });
|
|
269
|
+
const antipatterns = entries.filter((e) => e.type === 'anti-pattern');
|
|
270
|
+
const patterns = entries.filter((e) => e.type === 'pattern');
|
|
271
|
+
if (antipatterns.length === 0 || patterns.length === 0) {
|
|
272
|
+
return { contradictions: [], cogneeAvailable: false, method: 'tfidf-only' };
|
|
273
|
+
}
|
|
274
|
+
const vocabulary = this.buildVocabulary(entries);
|
|
275
|
+
const detected = [];
|
|
276
|
+
const cogneeAvailable = this.cognee?.isAvailable ?? false;
|
|
277
|
+
for (const ap of antipatterns) {
|
|
278
|
+
let candidates;
|
|
279
|
+
try {
|
|
280
|
+
const searchResults = this.vault.search(ap.title, { type: 'pattern', limit: 20 });
|
|
281
|
+
candidates = searchResults.length > 0 ? searchResults.map((r) => r.entry) : patterns;
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
candidates = patterns;
|
|
285
|
+
}
|
|
286
|
+
const apText = [ap.title, ap.description, ap.context ?? ''].join(' ');
|
|
287
|
+
const apVec = calculateTfIdf(tokenize(apText), vocabulary);
|
|
288
|
+
for (const pattern of candidates) {
|
|
289
|
+
const pText = [pattern.title, pattern.description, pattern.context ?? ''].join(' ');
|
|
290
|
+
const pVec = calculateTfIdf(tokenize(pText), vocabulary);
|
|
291
|
+
const tfidfScore = cosineSimilarity(apVec, pVec);
|
|
292
|
+
let finalScore = tfidfScore;
|
|
293
|
+
if (cogneeAvailable && this.cognee) {
|
|
294
|
+
try {
|
|
295
|
+
const cogneeResults = await this.cognee.search(`${ap.title} ${pattern.title}`, {
|
|
296
|
+
limit: 5,
|
|
297
|
+
});
|
|
298
|
+
const cogneeScore = cogneeResults.length > 0
|
|
299
|
+
? cogneeResults.reduce((sum, r) => sum + r.score, 0) / cogneeResults.length
|
|
300
|
+
: 0;
|
|
301
|
+
finalScore = 0.6 * tfidfScore + 0.4 * cogneeScore;
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
finalScore = tfidfScore;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (finalScore >= effectiveThreshold) {
|
|
308
|
+
const result = this.provider.run('INSERT OR IGNORE INTO curator_contradictions (pattern_id, antipattern_id, similarity) VALUES (?, ?, ?)', [pattern.id, ap.id, finalScore]);
|
|
309
|
+
if (result.changes > 0) {
|
|
310
|
+
const row = this.provider.get('SELECT * FROM curator_contradictions WHERE pattern_id = ? AND antipattern_id = ?', [pattern.id, ap.id]);
|
|
311
|
+
if (row)
|
|
312
|
+
detected.push(this.rowToContradiction(row));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
contradictions: detected,
|
|
319
|
+
cogneeAvailable,
|
|
320
|
+
method: cogneeAvailable ? 'hybrid' : 'tfidf-only',
|
|
321
|
+
};
|
|
322
|
+
}
|
|
283
323
|
// ─── Grooming ───────────────────────────────────────────────────
|
|
284
324
|
groomEntry(entryId) {
|
|
285
325
|
const entry = this.vault.get(entryId);
|
|
@@ -287,15 +327,14 @@ export class Curator {
|
|
|
287
327
|
return null;
|
|
288
328
|
const tagsNormalized = this.normalizeTags(entryId);
|
|
289
329
|
// Check staleness based on entry's updated_at timestamp
|
|
290
|
-
const
|
|
291
|
-
const row = db.prepare('SELECT updated_at FROM entries WHERE id = ?').get(entryId);
|
|
330
|
+
const row = this.provider.get('SELECT updated_at FROM entries WHERE id = ?', [entryId]);
|
|
292
331
|
const now = Math.floor(Date.now() / 1000);
|
|
293
332
|
const stale = row ? now - row.updated_at > DEFAULT_STALE_DAYS * 86400 : false;
|
|
294
333
|
const status = stale ? 'stale' : 'active';
|
|
295
334
|
// Upsert entry state
|
|
296
|
-
|
|
335
|
+
this.provider.run(`INSERT INTO curator_entry_state (entry_id, status, last_groomed_at)
|
|
297
336
|
VALUES (?, ?, unixepoch())
|
|
298
|
-
ON CONFLICT(entry_id) DO UPDATE SET status = excluded.status, last_groomed_at = unixepoch()
|
|
337
|
+
ON CONFLICT(entry_id) DO UPDATE SET status = excluded.status, last_groomed_at = unixepoch()`, [entryId, status]);
|
|
299
338
|
this.logChange('groom', entryId, null, `status=${status}`, 'Routine grooming');
|
|
300
339
|
return {
|
|
301
340
|
entryId,
|
|
@@ -335,12 +374,9 @@ export class Curator {
|
|
|
335
374
|
// Detect duplicates
|
|
336
375
|
const duplicates = this.detectDuplicates(undefined, duplicateThreshold);
|
|
337
376
|
// Detect stale entries
|
|
338
|
-
const db = this.vault.getDb();
|
|
339
377
|
const now = Math.floor(Date.now() / 1000);
|
|
340
378
|
const staleThreshold = now - staleDaysThreshold * 86400;
|
|
341
|
-
const staleRows =
|
|
342
|
-
.prepare('SELECT id FROM entries WHERE updated_at < ?')
|
|
343
|
-
.all(staleThreshold);
|
|
379
|
+
const staleRows = this.provider.all('SELECT id FROM entries WHERE updated_at < ?', [staleThreshold]);
|
|
344
380
|
const staleEntries = staleRows.map((r) => r.id);
|
|
345
381
|
// Detect contradictions
|
|
346
382
|
const contradictions = this.detectContradictions(contradictionThreshold);
|
|
@@ -348,9 +384,9 @@ export class Curator {
|
|
|
348
384
|
if (!dryRun) {
|
|
349
385
|
// Archive stale entries
|
|
350
386
|
for (const entryId of staleEntries) {
|
|
351
|
-
|
|
387
|
+
this.provider.run(`INSERT INTO curator_entry_state (entry_id, status, last_groomed_at)
|
|
352
388
|
VALUES (?, 'archived', unixepoch())
|
|
353
|
-
ON CONFLICT(entry_id) DO UPDATE SET status = 'archived', last_groomed_at = unixepoch()
|
|
389
|
+
ON CONFLICT(entry_id) DO UPDATE SET status = 'archived', last_groomed_at = unixepoch()`, [entryId]);
|
|
354
390
|
this.logChange('archive', entryId, 'active', 'archived', 'Stale entry archived during consolidation');
|
|
355
391
|
mutations++;
|
|
356
392
|
}
|
|
@@ -378,10 +414,7 @@ export class Curator {
|
|
|
378
414
|
}
|
|
379
415
|
// ─── Changelog ──────────────────────────────────────────────────
|
|
380
416
|
getEntryHistory(entryId, limit) {
|
|
381
|
-
const
|
|
382
|
-
const rows = db
|
|
383
|
-
.prepare('SELECT * FROM curator_changelog WHERE entry_id = ? ORDER BY created_at DESC, id DESC LIMIT ?')
|
|
384
|
-
.all(entryId, limit ?? 50);
|
|
417
|
+
const rows = this.provider.all('SELECT * FROM curator_changelog WHERE entry_id = ? ORDER BY created_at DESC, id DESC LIMIT ?', [entryId, limit ?? 50]);
|
|
385
418
|
return rows.map((r) => this.rowToChangelog(r));
|
|
386
419
|
}
|
|
387
420
|
// ─── Health Audit ───────────────────────────────────────────────
|
|
@@ -422,12 +455,9 @@ export class Curator {
|
|
|
422
455
|
}
|
|
423
456
|
coverageScore = Math.max(0, coverageScore);
|
|
424
457
|
// Freshness: penalize stale entries
|
|
425
|
-
const db = this.vault.getDb();
|
|
426
458
|
const now = Math.floor(Date.now() / 1000);
|
|
427
459
|
const staleThreshold = now - DEFAULT_STALE_DAYS * 86400;
|
|
428
|
-
const staleCount =
|
|
429
|
-
.prepare('SELECT COUNT(*) as count FROM entries WHERE updated_at < ?')
|
|
430
|
-
.get(staleThreshold).count;
|
|
460
|
+
const staleCount = (this.provider.get('SELECT COUNT(*) as count FROM entries WHERE updated_at < ?', [staleThreshold]) ?? { count: 0 }).count;
|
|
431
461
|
const staleRatio = staleCount / entries.length;
|
|
432
462
|
const freshnessScore = 1 - staleRatio;
|
|
433
463
|
if (staleRatio > 0.3) {
|
|
@@ -462,9 +492,7 @@ export class Curator {
|
|
|
462
492
|
recommendations.push(`${lowTagEntries.length} entries have fewer than 2 tags — improve tagging.`);
|
|
463
493
|
}
|
|
464
494
|
// Penalize ungroomed entries
|
|
465
|
-
const groomedCount =
|
|
466
|
-
.prepare('SELECT COUNT(*) as count FROM curator_entry_state WHERE last_groomed_at IS NOT NULL')
|
|
467
|
-
.get().count;
|
|
495
|
+
const groomedCount = (this.provider.get('SELECT COUNT(*) as count FROM curator_entry_state WHERE last_groomed_at IS NOT NULL') ?? { count: 0 }).count;
|
|
468
496
|
if (groomedCount < entries.length) {
|
|
469
497
|
const ungroomed = entries.length - groomedCount;
|
|
470
498
|
const penalty = Math.min(10, Math.round((ungroomed / entries.length) * 10));
|
|
@@ -491,17 +519,11 @@ export class Curator {
|
|
|
491
519
|
const entry = this.vault.get(entryId);
|
|
492
520
|
if (!entry)
|
|
493
521
|
return { recorded: false, historyId: -1 };
|
|
494
|
-
const
|
|
495
|
-
const result = db
|
|
496
|
-
.prepare('INSERT INTO curator_entry_history (entry_id, snapshot, changed_by, change_reason, created_at) VALUES (?, ?, ?, ?, unixepoch())')
|
|
497
|
-
.run(entryId, JSON.stringify(entry), changedBy ?? 'system', changeReason ?? null);
|
|
522
|
+
const result = this.provider.run('INSERT INTO curator_entry_history (entry_id, snapshot, changed_by, change_reason, created_at) VALUES (?, ?, ?, ?, unixepoch())', [entryId, JSON.stringify(entry), changedBy ?? 'system', changeReason ?? null]);
|
|
498
523
|
return { recorded: true, historyId: Number(result.lastInsertRowid) };
|
|
499
524
|
}
|
|
500
525
|
getVersionHistory(entryId) {
|
|
501
|
-
const
|
|
502
|
-
const rows = db
|
|
503
|
-
.prepare('SELECT * FROM curator_entry_history WHERE entry_id = ? ORDER BY created_at ASC, id ASC')
|
|
504
|
-
.all(entryId);
|
|
526
|
+
const rows = this.provider.all('SELECT * FROM curator_entry_history WHERE entry_id = ? ORDER BY created_at ASC, id ASC', [entryId]);
|
|
505
527
|
return rows.map((row) => ({
|
|
506
528
|
historyId: row.id,
|
|
507
529
|
entryId: row.entry_id,
|
|
@@ -513,26 +535,17 @@ export class Curator {
|
|
|
513
535
|
}
|
|
514
536
|
// ─── Queue Stats ──────────────────────────────────────────────
|
|
515
537
|
getQueueStats() {
|
|
516
|
-
const
|
|
517
|
-
const
|
|
518
|
-
const groomedEntries = db
|
|
519
|
-
.prepare('SELECT COUNT(*) as count FROM curator_entry_state WHERE last_groomed_at IS NOT NULL')
|
|
520
|
-
.get().count;
|
|
538
|
+
const totalEntries = (this.provider.get('SELECT COUNT(*) as count FROM entries') ?? { count: 0 }).count;
|
|
539
|
+
const groomedEntries = (this.provider.get('SELECT COUNT(*) as count FROM curator_entry_state WHERE last_groomed_at IS NOT NULL') ?? { count: 0 }).count;
|
|
521
540
|
const ungroomedEntries = totalEntries - groomedEntries;
|
|
522
541
|
const now = Math.floor(Date.now() / 1000);
|
|
523
542
|
const staleThreshold = now - 30 * 86400;
|
|
524
543
|
const freshThreshold = now - 7 * 86400;
|
|
525
|
-
const staleEntries =
|
|
526
|
-
|
|
527
|
-
.get(staleThreshold).count;
|
|
528
|
-
const freshEntries = db
|
|
529
|
-
.prepare('SELECT COUNT(*) as count FROM curator_entry_state WHERE last_groomed_at IS NOT NULL AND last_groomed_at >= ?')
|
|
530
|
-
.get(freshThreshold).count;
|
|
544
|
+
const staleEntries = (this.provider.get('SELECT COUNT(*) as count FROM curator_entry_state WHERE last_groomed_at IS NOT NULL AND last_groomed_at < ?', [staleThreshold]) ?? { count: 0 }).count;
|
|
545
|
+
const freshEntries = (this.provider.get('SELECT COUNT(*) as count FROM curator_entry_state WHERE last_groomed_at IS NOT NULL AND last_groomed_at >= ?', [freshThreshold]) ?? { count: 0 }).count;
|
|
531
546
|
let avgDaysSinceGroom = 0;
|
|
532
547
|
if (groomedEntries > 0) {
|
|
533
|
-
const sumRow =
|
|
534
|
-
.prepare('SELECT SUM(? - last_groomed_at) as total FROM curator_entry_state WHERE last_groomed_at IS NOT NULL')
|
|
535
|
-
.get(now);
|
|
548
|
+
const sumRow = this.provider.get('SELECT SUM(? - last_groomed_at) as total FROM curator_entry_state WHERE last_groomed_at IS NOT NULL', [now]) ?? { total: 0 };
|
|
536
549
|
const totalSeconds = sumRow.total ?? 0;
|
|
537
550
|
avgDaysSinceGroom = Math.round((totalSeconds / groomedEntries / 86400) * 100) / 100;
|
|
538
551
|
}
|
|
@@ -631,8 +644,7 @@ export class Curator {
|
|
|
631
644
|
return vocabulary;
|
|
632
645
|
}
|
|
633
646
|
logChange(action, entryId, beforeValue, afterValue, reason) {
|
|
634
|
-
|
|
635
|
-
db.prepare('INSERT INTO curator_changelog (action, entry_id, before_value, after_value, reason) VALUES (?, ?, ?, ?, ?)').run(action, entryId, beforeValue, afterValue, reason);
|
|
647
|
+
this.provider.run('INSERT INTO curator_changelog (action, entry_id, before_value, after_value, reason) VALUES (?, ?, ?, ?, ?)', [action, entryId, beforeValue, afterValue, reason]);
|
|
636
648
|
}
|
|
637
649
|
rowToContradiction(row) {
|
|
638
650
|
return {
|