@velvetmonkey/vault-core 2.0.119 → 2.0.121
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/sqlite.d.ts +1 -1
- package/dist/sqlite.js +58 -3
- package/package.json +1 -1
package/dist/sqlite.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export interface StateDb {
|
|
|
75
75
|
close: () => void;
|
|
76
76
|
}
|
|
77
77
|
/** Current schema version - bump when schema changes */
|
|
78
|
-
export declare const SCHEMA_VERSION =
|
|
78
|
+
export declare const SCHEMA_VERSION = 30;
|
|
79
79
|
/** State database filename */
|
|
80
80
|
export declare const STATE_DB_FILENAME = "state.db";
|
|
81
81
|
/** Directory for flywheel state */
|
package/dist/sqlite.js
CHANGED
|
@@ -16,7 +16,7 @@ import * as path from 'path';
|
|
|
16
16
|
// Constants
|
|
17
17
|
// =============================================================================
|
|
18
18
|
/** Current schema version - bump when schema changes */
|
|
19
|
-
export const SCHEMA_VERSION =
|
|
19
|
+
export const SCHEMA_VERSION = 30;
|
|
20
20
|
/** State database filename */
|
|
21
21
|
export const STATE_DB_FILENAME = 'state.db';
|
|
22
22
|
/** Directory for flywheel state */
|
|
@@ -164,6 +164,7 @@ CREATE TABLE IF NOT EXISTS wikilink_feedback (
|
|
|
164
164
|
created_at TEXT DEFAULT (datetime('now'))
|
|
165
165
|
);
|
|
166
166
|
CREATE INDEX IF NOT EXISTS idx_wl_feedback_entity ON wikilink_feedback(entity);
|
|
167
|
+
CREATE INDEX IF NOT EXISTS idx_wl_feedback_note_path ON wikilink_feedback(note_path);
|
|
167
168
|
|
|
168
169
|
-- Wikilink suppressions (v4: auto-suppress false positives)
|
|
169
170
|
CREATE TABLE IF NOT EXISTS wikilink_suppressions (
|
|
@@ -205,7 +206,9 @@ CREATE TABLE IF NOT EXISTS tool_invocations (
|
|
|
205
206
|
session_id TEXT,
|
|
206
207
|
note_paths TEXT,
|
|
207
208
|
duration_ms INTEGER,
|
|
208
|
-
success INTEGER NOT NULL DEFAULT 1
|
|
209
|
+
success INTEGER NOT NULL DEFAULT 1,
|
|
210
|
+
response_tokens INTEGER,
|
|
211
|
+
baseline_tokens INTEGER
|
|
209
212
|
);
|
|
210
213
|
CREATE INDEX IF NOT EXISTS idx_tool_inv_ts ON tool_invocations(timestamp);
|
|
211
214
|
CREATE INDEX IF NOT EXISTS idx_tool_inv_tool ON tool_invocations(tool_name, timestamp);
|
|
@@ -424,6 +427,19 @@ CREATE TABLE IF NOT EXISTS session_summaries (
|
|
|
424
427
|
ended_at INTEGER NOT NULL,
|
|
425
428
|
tool_count INTEGER
|
|
426
429
|
);
|
|
430
|
+
|
|
431
|
+
-- Retrieval co-occurrence (v30): notes retrieved together build implicit edges
|
|
432
|
+
CREATE TABLE IF NOT EXISTS retrieval_cooccurrence (
|
|
433
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
434
|
+
note_a TEXT NOT NULL,
|
|
435
|
+
note_b TEXT NOT NULL,
|
|
436
|
+
session_id TEXT NOT NULL,
|
|
437
|
+
timestamp INTEGER NOT NULL,
|
|
438
|
+
weight REAL NOT NULL DEFAULT 1.0,
|
|
439
|
+
UNIQUE(note_a, note_b, session_id)
|
|
440
|
+
);
|
|
441
|
+
CREATE INDEX IF NOT EXISTS idx_retcooc_notes ON retrieval_cooccurrence(note_a, note_b);
|
|
442
|
+
CREATE INDEX IF NOT EXISTS idx_retcooc_ts ON retrieval_cooccurrence(timestamp);
|
|
427
443
|
`;
|
|
428
444
|
// =============================================================================
|
|
429
445
|
// Database Initialization
|
|
@@ -565,6 +581,16 @@ function initSchema(db) {
|
|
|
565
581
|
// (created by SCHEMA_SQL above via CREATE TABLE IF NOT EXISTS)
|
|
566
582
|
// v28: content_hashes table (persist watcher content hashes across restarts)
|
|
567
583
|
// (created by SCHEMA_SQL above via CREATE TABLE IF NOT EXISTS)
|
|
584
|
+
// v29: index on wikilink_feedback(note_path) for temporal analysis queries
|
|
585
|
+
// (created by SCHEMA_SQL above via CREATE INDEX IF NOT EXISTS)
|
|
586
|
+
// v30: token economics columns on tool_invocations
|
|
587
|
+
if (currentVersion < 30) {
|
|
588
|
+
const hasResponseTokens = db.prepare(`SELECT COUNT(*) as cnt FROM pragma_table_info('tool_invocations') WHERE name = 'response_tokens'`).get();
|
|
589
|
+
if (hasResponseTokens.cnt === 0) {
|
|
590
|
+
db.exec('ALTER TABLE tool_invocations ADD COLUMN response_tokens INTEGER');
|
|
591
|
+
db.exec('ALTER TABLE tool_invocations ADD COLUMN baseline_tokens INTEGER');
|
|
592
|
+
}
|
|
593
|
+
}
|
|
568
594
|
db.prepare('INSERT OR IGNORE INTO schema_version (version) VALUES (?)').run(SCHEMA_VERSION);
|
|
569
595
|
}
|
|
570
596
|
}
|
|
@@ -575,6 +601,32 @@ function deleteStateDbFiles(dbPath) {
|
|
|
575
601
|
fs.unlinkSync(p);
|
|
576
602
|
}
|
|
577
603
|
}
|
|
604
|
+
/** Back up state.db before opening (skip if missing or 0 bytes). */
|
|
605
|
+
function backupStateDb(dbPath) {
|
|
606
|
+
try {
|
|
607
|
+
if (!fs.existsSync(dbPath))
|
|
608
|
+
return;
|
|
609
|
+
const stat = fs.statSync(dbPath);
|
|
610
|
+
if (stat.size === 0)
|
|
611
|
+
return;
|
|
612
|
+
fs.copyFileSync(dbPath, dbPath + '.backup');
|
|
613
|
+
}
|
|
614
|
+
catch (err) {
|
|
615
|
+
console.error(`[vault-core] Failed to back up state.db: ${err instanceof Error ? err.message : err}`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
/** Preserve a corrupted database for inspection before deleting. */
|
|
619
|
+
function preserveCorruptedDb(dbPath) {
|
|
620
|
+
try {
|
|
621
|
+
if (fs.existsSync(dbPath)) {
|
|
622
|
+
fs.copyFileSync(dbPath, dbPath + '.corrupt');
|
|
623
|
+
console.error(`[vault-core] Corrupted database preserved at ${dbPath}.corrupt`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
catch {
|
|
627
|
+
// Best effort — don't block recovery
|
|
628
|
+
}
|
|
629
|
+
}
|
|
578
630
|
/**
|
|
579
631
|
* Open or create the state database for a vault
|
|
580
632
|
*
|
|
@@ -583,6 +635,8 @@ function deleteStateDbFiles(dbPath) {
|
|
|
583
635
|
*/
|
|
584
636
|
export function openStateDb(vaultPath) {
|
|
585
637
|
const dbPath = getStateDbPath(vaultPath);
|
|
638
|
+
// Back up existing database before any mutations
|
|
639
|
+
backupStateDb(dbPath);
|
|
586
640
|
// Guard: Delete corrupted 0-byte database files
|
|
587
641
|
// This can happen when better-sqlite3 fails to compile (e.g., Node 24)
|
|
588
642
|
// and creates an empty file instead of a valid SQLite database
|
|
@@ -599,10 +653,11 @@ export function openStateDb(vaultPath) {
|
|
|
599
653
|
initSchema(db);
|
|
600
654
|
}
|
|
601
655
|
catch (err) {
|
|
602
|
-
// Corrupted database (e.g., "file is not a database") — delete and retry once
|
|
656
|
+
// Corrupted database (e.g., "file is not a database") — preserve, delete, and retry once
|
|
603
657
|
if (fs.existsSync(dbPath)) {
|
|
604
658
|
const msg = err instanceof Error ? err.message : String(err);
|
|
605
659
|
console.error(`[vault-core] Corrupted state.db (${msg}) — deleting and recreating`);
|
|
660
|
+
preserveCorruptedDb(dbPath);
|
|
606
661
|
try {
|
|
607
662
|
db?.close();
|
|
608
663
|
}
|
package/package.json
CHANGED