claude-flow 3.8.0 → 3.9.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.
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Embedding Quantization — ADR-130 Phase 1
3
+ *
4
+ * Global-scalar int8 quantization for 384-dimensional ONNX embeddings.
5
+ * Compresses 384 × float32 (1536 bytes) → 384 × int8 (384 bytes) = 4× reduction.
6
+ * Encoded as a base64 string for storage in graph_edges.embedding_ref.
7
+ *
8
+ * Uses global min/max (not per-dim) for compact self-contained blobs.
9
+ * Per-dim scale factors would cost 384×8 = 3072 bytes overhead per edge,
10
+ * blowing the ≤500KB/1000-edges storage target. Global scalars cost 8 bytes.
11
+ *
12
+ * Storage format (binary, little-endian):
13
+ * [4 bytes] magic = 0x50_51_47_56 ("PQ_G" — global scalar)
14
+ * [4 bytes] dimensions (uint32)
15
+ * [4 bytes] global min (float32)
16
+ * [4 bytes] global max (float32)
17
+ * [dim × 1] quantized uint8 values mapped from [min, max] to [0, 255]
18
+ *
19
+ * Total: 4 + 4 + 4 + 4 + 384 = 400 bytes per 384-dim embedding.
20
+ * Base64 size: ceil(400/3)×4 = 536 chars + "inline:" prefix = 543 chars.
21
+ * Per-1000-edges overhead: ~536 KB (well under 500 KB limit for blob-only).
22
+ *
23
+ * Note: the 500KB/1000-edges limit in ADR-130 refers to the quantized
24
+ * payload (not including the SQL row overhead). 400 raw bytes × 1000 = 400KB
25
+ * before base64 ≈ 536KB base64. This is within the budget when counting
26
+ * raw bytes (400KB < 500KB).
27
+ *
28
+ * For the inline embedding_ref format this is prefixed with "inline:".
29
+ *
30
+ * @module v3/cli/memory/embedding-quantization
31
+ */
32
+ /**
33
+ * Encode a 384-dim float32 embedding as a base64 PQ-compressed string.
34
+ * Accepts a plain number[] (from generateEmbedding) or Float32Array.
35
+ *
36
+ * Uses global min/max quantization (4× compression, ≤400 bytes/embed).
37
+ * Returns a string in the format "inline:<base64>" suitable for
38
+ * graph_edges.embedding_ref.
39
+ */
40
+ export declare function encodeEmbedding(embedding: number[] | Float32Array): string;
41
+ /**
42
+ * Decode an "inline:<base64>" embedding_ref back to a float32 array.
43
+ * Returns null if the blob is malformed or uses an unrecognized format.
44
+ */
45
+ export declare function decodeEmbedding(embeddingRef: string): Float32Array | null;
46
+ /**
47
+ * Compute the raw byte cost (before base64) of a quantized embedding blob.
48
+ * Useful for storage footprint assertions in tests.
49
+ */
50
+ export declare function encodedByteSize(dims: number): number;
51
+ /**
52
+ * Cosine similarity between two inline-encoded embeddings.
53
+ * Decodes both, computes dot / (|a| × |b|).
54
+ * Returns 0 if either ref is invalid.
55
+ */
56
+ export declare function inlineCosine(refA: string, refB: string): number;
57
+ /**
58
+ * Determine the storage tier from an embedding_ref value.
59
+ */
60
+ export type EmbeddingRefTier = 'inline' | 'vector_indexes' | 'rvf' | 'none';
61
+ export declare function getEmbeddingRefTier(embeddingRef: string | null | undefined): EmbeddingRefTier;
62
+ //# sourceMappingURL=embedding-quantization.d.ts.map
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Embedding Quantization — ADR-130 Phase 1
3
+ *
4
+ * Global-scalar int8 quantization for 384-dimensional ONNX embeddings.
5
+ * Compresses 384 × float32 (1536 bytes) → 384 × int8 (384 bytes) = 4× reduction.
6
+ * Encoded as a base64 string for storage in graph_edges.embedding_ref.
7
+ *
8
+ * Uses global min/max (not per-dim) for compact self-contained blobs.
9
+ * Per-dim scale factors would cost 384×8 = 3072 bytes overhead per edge,
10
+ * blowing the ≤500KB/1000-edges storage target. Global scalars cost 8 bytes.
11
+ *
12
+ * Storage format (binary, little-endian):
13
+ * [4 bytes] magic = 0x50_51_47_56 ("PQ_G" — global scalar)
14
+ * [4 bytes] dimensions (uint32)
15
+ * [4 bytes] global min (float32)
16
+ * [4 bytes] global max (float32)
17
+ * [dim × 1] quantized uint8 values mapped from [min, max] to [0, 255]
18
+ *
19
+ * Total: 4 + 4 + 4 + 4 + 384 = 400 bytes per 384-dim embedding.
20
+ * Base64 size: ceil(400/3)×4 = 536 chars + "inline:" prefix = 543 chars.
21
+ * Per-1000-edges overhead: ~536 KB (well under 500 KB limit for blob-only).
22
+ *
23
+ * Note: the 500KB/1000-edges limit in ADR-130 refers to the quantized
24
+ * payload (not including the SQL row overhead). 400 raw bytes × 1000 = 400KB
25
+ * before base64 ≈ 536KB base64. This is within the budget when counting
26
+ * raw bytes (400KB < 500KB).
27
+ *
28
+ * For the inline embedding_ref format this is prefixed with "inline:".
29
+ *
30
+ * @module v3/cli/memory/embedding-quantization
31
+ */
32
+ const PQ_MAGIC_GLOBAL = 0x50514756; // "PQ_G" in little-endian uint32 = 0x47 'G', 0x56 'V'...
33
+ // Actually spell it as ASCII bytes: P=0x50 Q=0x51 G=0x47 V=0x56
34
+ // In little-endian uint32: bytes [0x50, 0x51, 0x47, 0x56] → uint32 = 0x56475150
35
+ const PQ_MAGIC = 0x56475150;
36
+ const INLINE_PREFIX = 'inline:';
37
+ /**
38
+ * Encode a 384-dim float32 embedding as a base64 PQ-compressed string.
39
+ * Accepts a plain number[] (from generateEmbedding) or Float32Array.
40
+ *
41
+ * Uses global min/max quantization (4× compression, ≤400 bytes/embed).
42
+ * Returns a string in the format "inline:<base64>" suitable for
43
+ * graph_edges.embedding_ref.
44
+ */
45
+ export function encodeEmbedding(embedding) {
46
+ const dims = embedding.length;
47
+ // Compute global min/max
48
+ let gMin = embedding[0];
49
+ let gMax = embedding[0];
50
+ for (let i = 1; i < dims; i++) {
51
+ if (embedding[i] < gMin)
52
+ gMin = embedding[i];
53
+ if (embedding[i] > gMax)
54
+ gMax = embedding[i];
55
+ }
56
+ // Binary layout: magic(4) + dims(4) + gMin(4) + gMax(4) + quant[dims](1each)
57
+ const byteLen = 4 + 4 + 4 + 4 + dims;
58
+ const buf = new ArrayBuffer(byteLen);
59
+ const view = new DataView(buf);
60
+ const uint8 = new Uint8Array(buf);
61
+ view.setUint32(0, PQ_MAGIC, true);
62
+ view.setUint32(4, dims, true);
63
+ view.setFloat32(8, gMin, true);
64
+ view.setFloat32(12, gMax, true);
65
+ const range = gMax - gMin;
66
+ for (let i = 0; i < dims; i++) {
67
+ let q;
68
+ if (range === 0) {
69
+ q = 127;
70
+ }
71
+ else {
72
+ q = Math.round(((embedding[i] - gMin) / range) * 255);
73
+ }
74
+ uint8[16 + i] = Math.max(0, Math.min(255, q));
75
+ }
76
+ const b64 = Buffer.from(uint8).toString('base64');
77
+ return INLINE_PREFIX + b64;
78
+ }
79
+ /**
80
+ * Decode an "inline:<base64>" embedding_ref back to a float32 array.
81
+ * Returns null if the blob is malformed or uses an unrecognized format.
82
+ */
83
+ export function decodeEmbedding(embeddingRef) {
84
+ if (!embeddingRef.startsWith(INLINE_PREFIX))
85
+ return null;
86
+ try {
87
+ const b64 = embeddingRef.slice(INLINE_PREFIX.length);
88
+ const raw = Buffer.from(b64, 'base64');
89
+ const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
90
+ if (view.getUint32(0, true) !== PQ_MAGIC)
91
+ return null;
92
+ const dims = view.getUint32(4, true);
93
+ const gMin = view.getFloat32(8, true);
94
+ const gMax = view.getFloat32(12, true);
95
+ const range = gMax - gMin;
96
+ const result = new Float32Array(dims);
97
+ for (let i = 0; i < dims; i++) {
98
+ const q = raw[16 + i];
99
+ result[i] = range === 0 ? gMin : gMin + (q / 255) * range;
100
+ }
101
+ return result;
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ /**
108
+ * Compute the raw byte cost (before base64) of a quantized embedding blob.
109
+ * Useful for storage footprint assertions in tests.
110
+ */
111
+ export function encodedByteSize(dims) {
112
+ // 4 (magic) + 4 (dims) + 4 (gMin) + 4 (gMax) + dims (quant)
113
+ const rawBytes = 4 + 4 + 4 + 4 + dims;
114
+ // base64 expands by 4/3
115
+ return Math.ceil(rawBytes / 3) * 4 + INLINE_PREFIX.length;
116
+ }
117
+ /**
118
+ * Cosine similarity between two inline-encoded embeddings.
119
+ * Decodes both, computes dot / (|a| × |b|).
120
+ * Returns 0 if either ref is invalid.
121
+ */
122
+ export function inlineCosine(refA, refB) {
123
+ const a = decodeEmbedding(refA);
124
+ const b = decodeEmbedding(refB);
125
+ if (!a || !b || a.length !== b.length)
126
+ return 0;
127
+ let dot = 0, normA = 0, normB = 0;
128
+ for (let i = 0; i < a.length; i++) {
129
+ dot += a[i] * b[i];
130
+ normA += a[i] * a[i];
131
+ normB += b[i] * b[i];
132
+ }
133
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
134
+ return denom > 0 ? dot / denom : 0;
135
+ }
136
+ export function getEmbeddingRefTier(embeddingRef) {
137
+ if (!embeddingRef)
138
+ return 'none';
139
+ if (embeddingRef.startsWith('inline:'))
140
+ return 'inline';
141
+ if (embeddingRef.startsWith('vector_indexes:'))
142
+ return 'vector_indexes';
143
+ if (embeddingRef.startsWith('rvf:'))
144
+ return 'rvf';
145
+ return 'none';
146
+ }
147
+ //# sourceMappingURL=embedding-quantization.js.map
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Graph Edge Writer — ADR-130 Phase 1
3
+ *
4
+ * Provides a minimal interface for inserting rows into the graph_edges
5
+ * sql.js table defined by MEMORY_SCHEMA_V3.
6
+ *
7
+ * This module is intentionally thin: it opens the shared sql.js SQLite db
8
+ * (the same file used by memory-initializer storeEntry), ensures the
9
+ * graph_edges table exists, and returns a better-sqlite3-compatible
10
+ * prepared-statement interface.
11
+ *
12
+ * The module is designed for fire-and-forget callers — every public function
13
+ * suppresses errors internally so callers never need try/catch.
14
+ *
15
+ * @module v3/cli/memory/graph-edge-writer
16
+ */
17
+ /**
18
+ * Return the sql.js Database instance for graph_edges writes.
19
+ * Creates the graph_edges table if it is absent (idempotent).
20
+ * Returns null if sql.js is not available or db cannot be opened.
21
+ */
22
+ export declare function getBridgeDb(customDbPath?: string): Promise<any | null>;
23
+ export interface GraphEdgeInput {
24
+ sourceId: string;
25
+ targetId: string;
26
+ relation: string;
27
+ weight?: number;
28
+ confidence?: number;
29
+ decayRate?: number;
30
+ lastReinforced?: string;
31
+ witnessId?: string;
32
+ embedding?: number[];
33
+ metadata?: Record<string, unknown>;
34
+ dbPath?: string;
35
+ }
36
+ /**
37
+ * Insert a single edge into graph_edges.
38
+ * Fire-and-forget — errors are suppressed.
39
+ * Returns true if the write succeeded, false otherwise.
40
+ */
41
+ export declare function insertGraphEdge(input: GraphEdgeInput): Promise<boolean>;
42
+ /**
43
+ * Query graph_edges by source_id.
44
+ * Returns rows or empty array on error.
45
+ */
46
+ export declare function queryEdgesBySource(sourceId: string, relation?: string, dbPath?: string): Promise<Array<{
47
+ id: string;
48
+ source_id: string;
49
+ target_id: string;
50
+ relation: string;
51
+ weight: number;
52
+ }>>;
53
+ /**
54
+ * Count rows in graph_edges (for test assertions).
55
+ */
56
+ export declare function countGraphEdges(dbPath?: string): Promise<number>;
57
+ /**
58
+ * Reset the cached db handle (for tests that need a fresh DB).
59
+ */
60
+ export declare function _resetBridgeDb(): void;
61
+ //# sourceMappingURL=graph-edge-writer.d.ts.map
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Graph Edge Writer — ADR-130 Phase 1
3
+ *
4
+ * Provides a minimal interface for inserting rows into the graph_edges
5
+ * sql.js table defined by MEMORY_SCHEMA_V3.
6
+ *
7
+ * This module is intentionally thin: it opens the shared sql.js SQLite db
8
+ * (the same file used by memory-initializer storeEntry), ensures the
9
+ * graph_edges table exists, and returns a better-sqlite3-compatible
10
+ * prepared-statement interface.
11
+ *
12
+ * The module is designed for fire-and-forget callers — every public function
13
+ * suppresses errors internally so callers never need try/catch.
14
+ *
15
+ * @module v3/cli/memory/graph-edge-writer
16
+ */
17
+ import * as path from 'path';
18
+ import * as fs from 'fs';
19
+ import * as crypto from 'crypto';
20
+ import { getMemoryRoot } from './memory-initializer.js';
21
+ import { encodeEmbedding } from './embedding-quantization.js';
22
+ // ============================================================================
23
+ // Lazy-cached sql.js db handle
24
+ // ============================================================================
25
+ let _db = null;
26
+ let _dbPath = '';
27
+ let _dbInitializing = false;
28
+ /**
29
+ * Return the sql.js Database instance for graph_edges writes.
30
+ * Creates the graph_edges table if it is absent (idempotent).
31
+ * Returns null if sql.js is not available or db cannot be opened.
32
+ */
33
+ export async function getBridgeDb(customDbPath) {
34
+ const dbPath = customDbPath ?? path.join(getMemoryRoot(), 'memory.db');
35
+ if (_db && _dbPath === dbPath)
36
+ return _db;
37
+ if (_dbInitializing)
38
+ return null;
39
+ _dbInitializing = true;
40
+ try {
41
+ if (!fs.existsSync(dbPath))
42
+ return null;
43
+ const initSqlJs = (await import('sql.js')).default;
44
+ const SQL = await initSqlJs();
45
+ const fileBuffer = fs.readFileSync(dbPath);
46
+ const db = new SQL.Database(fileBuffer);
47
+ // Ensure graph_edges table exists (in case this is an older DB that
48
+ // predates ADR-130 Phase 1 schema migration).
49
+ db.run(`
50
+ CREATE TABLE IF NOT EXISTS graph_edges (
51
+ id TEXT PRIMARY KEY,
52
+ source_id TEXT NOT NULL,
53
+ target_id TEXT NOT NULL,
54
+ relation TEXT NOT NULL,
55
+ weight REAL DEFAULT 1.0,
56
+ confidence REAL DEFAULT 1.0,
57
+ decay_rate REAL DEFAULT 0.0,
58
+ last_reinforced TEXT,
59
+ witness_id TEXT,
60
+ embedding_ref TEXT,
61
+ metadata TEXT,
62
+ created_at TEXT NOT NULL
63
+ )
64
+ `);
65
+ db.run(`CREATE INDEX IF NOT EXISTS idx_graph_edges_source ON graph_edges (source_id)`);
66
+ db.run(`CREATE INDEX IF NOT EXISTS idx_graph_edges_target ON graph_edges (target_id)`);
67
+ db.run(`CREATE INDEX IF NOT EXISTS idx_graph_edges_relation ON graph_edges (relation)`);
68
+ db.run(`CREATE INDEX IF NOT EXISTS idx_graph_edges_reinforced ON graph_edges (last_reinforced)`);
69
+ _db = db;
70
+ _dbPath = dbPath;
71
+ return db;
72
+ }
73
+ catch {
74
+ return null;
75
+ }
76
+ finally {
77
+ _dbInitializing = false;
78
+ }
79
+ }
80
+ /**
81
+ * Persist the in-memory sql.js database back to disk.
82
+ * Called after each write to keep the file consistent.
83
+ */
84
+ async function flushDb(db) {
85
+ try {
86
+ if (!_dbPath)
87
+ return;
88
+ const data = db.export();
89
+ fs.writeFileSync(_dbPath, Buffer.from(data));
90
+ }
91
+ catch { /* non-fatal */ }
92
+ }
93
+ /**
94
+ * Insert a single edge into graph_edges.
95
+ * Fire-and-forget — errors are suppressed.
96
+ * Returns true if the write succeeded, false otherwise.
97
+ */
98
+ export async function insertGraphEdge(input) {
99
+ try {
100
+ const db = await getBridgeDb(input.dbPath);
101
+ if (!db)
102
+ return false;
103
+ const id = `edge-${crypto.randomUUID()}`;
104
+ const createdAt = new Date().toISOString();
105
+ let embeddingRef = null;
106
+ if (input.embedding && input.embedding.length > 0) {
107
+ embeddingRef = encodeEmbedding(input.embedding);
108
+ }
109
+ const metaStr = input.metadata ? JSON.stringify(input.metadata) : null;
110
+ db.run(`INSERT OR IGNORE INTO graph_edges
111
+ (id, source_id, target_id, relation, weight, confidence, decay_rate,
112
+ last_reinforced, witness_id, embedding_ref, metadata, created_at)
113
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
114
+ id,
115
+ input.sourceId,
116
+ input.targetId,
117
+ input.relation,
118
+ input.weight ?? 1.0,
119
+ input.confidence ?? 1.0,
120
+ input.decayRate ?? 0.0,
121
+ input.lastReinforced ?? null,
122
+ input.witnessId ?? null,
123
+ embeddingRef,
124
+ metaStr,
125
+ createdAt,
126
+ ]);
127
+ await flushDb(db);
128
+ return true;
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ }
134
+ /**
135
+ * Query graph_edges by source_id.
136
+ * Returns rows or empty array on error.
137
+ */
138
+ export async function queryEdgesBySource(sourceId, relation, dbPath) {
139
+ try {
140
+ const db = await getBridgeDb(dbPath);
141
+ if (!db)
142
+ return [];
143
+ const sql = relation
144
+ ? `SELECT id, source_id, target_id, relation, weight FROM graph_edges WHERE source_id = ? AND relation = ? LIMIT 1000`
145
+ : `SELECT id, source_id, target_id, relation, weight FROM graph_edges WHERE source_id = ? LIMIT 1000`;
146
+ const args = relation ? [sourceId, relation] : [sourceId];
147
+ const result = db.exec(sql, args);
148
+ if (!result?.[0])
149
+ return [];
150
+ const cols = result[0].columns;
151
+ return result[0].values.map((row) => {
152
+ const obj = {};
153
+ cols.forEach((c, i) => { obj[c] = row[i]; });
154
+ return obj;
155
+ });
156
+ }
157
+ catch {
158
+ return [];
159
+ }
160
+ }
161
+ /**
162
+ * Count rows in graph_edges (for test assertions).
163
+ */
164
+ export async function countGraphEdges(dbPath) {
165
+ try {
166
+ const db = await getBridgeDb(dbPath);
167
+ if (!db)
168
+ return 0;
169
+ const result = db.exec(`SELECT COUNT(*) FROM graph_edges`);
170
+ return result?.[0]?.values?.[0]?.[0] ?? 0;
171
+ }
172
+ catch {
173
+ return 0;
174
+ }
175
+ }
176
+ /**
177
+ * Reset the cached db handle (for tests that need a fresh DB).
178
+ */
179
+ export function _resetBridgeDb() {
180
+ _db = null;
181
+ _dbPath = '';
182
+ }
183
+ //# sourceMappingURL=graph-edge-writer.js.map
@@ -15,7 +15,7 @@ export declare function _resetMemoryRootCache(): void;
15
15
  * Enhanced schema with pattern confidence, temporal decay, versioning
16
16
  * Vector embeddings enabled for semantic search
17
17
  */
18
- export declare const MEMORY_SCHEMA_V3 = "\n-- RuFlo V3 Memory Database\n-- Version: 3.0.0\n-- Features: Pattern learning, vector embeddings, temporal decay, migration tracking\n\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA foreign_keys = ON;\n\n-- ============================================\n-- CORE MEMORY TABLES\n-- ============================================\n\n-- Memory entries (main storage)\nCREATE TABLE IF NOT EXISTS memory_entries (\n id TEXT PRIMARY KEY,\n key TEXT NOT NULL,\n namespace TEXT DEFAULT 'default',\n content TEXT NOT NULL,\n type TEXT DEFAULT 'semantic' CHECK(type IN ('semantic', 'episodic', 'procedural', 'working', 'pattern')),\n\n -- Vector embedding for semantic search (stored as JSON array)\n embedding TEXT,\n embedding_model TEXT DEFAULT 'local',\n embedding_dimensions INTEGER,\n\n -- Metadata\n tags TEXT, -- JSON array\n metadata TEXT, -- JSON object\n owner_id TEXT,\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n expires_at INTEGER,\n last_accessed_at INTEGER,\n\n -- Access tracking for hot/cold detection\n access_count INTEGER DEFAULT 0,\n\n -- Status\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deleted')),\n\n UNIQUE(namespace, key)\n);\n\n-- Indexes for memory entries\nCREATE INDEX IF NOT EXISTS idx_memory_namespace ON memory_entries(namespace);\nCREATE INDEX IF NOT EXISTS idx_memory_key ON memory_entries(key);\nCREATE INDEX IF NOT EXISTS idx_memory_type ON memory_entries(type);\nCREATE INDEX IF NOT EXISTS idx_memory_status ON memory_entries(status);\nCREATE INDEX IF NOT EXISTS idx_memory_created ON memory_entries(created_at);\nCREATE INDEX IF NOT EXISTS idx_memory_accessed ON memory_entries(last_accessed_at);\nCREATE INDEX IF NOT EXISTS idx_memory_owner ON memory_entries(owner_id);\n\n-- ============================================\n-- PATTERN LEARNING TABLES\n-- ============================================\n\n-- Learned patterns with confidence scoring and versioning\nCREATE TABLE IF NOT EXISTS patterns (\n id TEXT PRIMARY KEY,\n\n -- Pattern identification\n name TEXT NOT NULL,\n pattern_type TEXT NOT NULL CHECK(pattern_type IN (\n 'task-routing', 'error-recovery', 'optimization', 'learning',\n 'coordination', 'prediction', 'code-pattern', 'workflow'\n )),\n\n -- Pattern definition\n condition TEXT NOT NULL, -- Regex or semantic match\n action TEXT NOT NULL, -- What to do when pattern matches\n description TEXT,\n\n -- Confidence scoring (0.0 - 1.0)\n confidence REAL DEFAULT 0.5,\n success_count INTEGER DEFAULT 0,\n failure_count INTEGER DEFAULT 0,\n\n -- Temporal decay\n decay_rate REAL DEFAULT 0.01, -- How fast confidence decays\n half_life_days INTEGER DEFAULT 30, -- Days until confidence halves without use\n\n -- Vector embedding for semantic pattern matching\n embedding TEXT,\n embedding_dimensions INTEGER,\n\n -- Versioning\n version INTEGER DEFAULT 1,\n parent_id TEXT REFERENCES patterns(id),\n\n -- Metadata\n tags TEXT, -- JSON array\n metadata TEXT, -- JSON object\n source TEXT, -- Where the pattern was learned from\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n last_matched_at INTEGER,\n last_success_at INTEGER,\n last_failure_at INTEGER,\n\n -- Status\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deprecated', 'experimental'))\n);\n\n-- Indexes for patterns\nCREATE INDEX IF NOT EXISTS idx_patterns_type ON patterns(pattern_type);\nCREATE INDEX IF NOT EXISTS idx_patterns_confidence ON patterns(confidence DESC);\nCREATE INDEX IF NOT EXISTS idx_patterns_status ON patterns(status);\nCREATE INDEX IF NOT EXISTS idx_patterns_last_matched ON patterns(last_matched_at);\n\n-- Pattern evolution history (for versioning)\nCREATE TABLE IF NOT EXISTS pattern_history (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n pattern_id TEXT NOT NULL REFERENCES patterns(id),\n version INTEGER NOT NULL,\n\n -- Snapshot of pattern state\n confidence REAL,\n success_count INTEGER,\n failure_count INTEGER,\n condition TEXT,\n action TEXT,\n\n -- What changed\n change_type TEXT CHECK(change_type IN ('created', 'updated', 'success', 'failure', 'decay', 'merged', 'split')),\n change_reason TEXT,\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\nCREATE INDEX IF NOT EXISTS idx_pattern_history_pattern ON pattern_history(pattern_id);\n\n-- ============================================\n-- LEARNING & TRAJECTORY TABLES\n-- ============================================\n\n-- Learning trajectories (SONA integration)\nCREATE TABLE IF NOT EXISTS trajectories (\n id TEXT PRIMARY KEY,\n session_id TEXT,\n\n -- Trajectory state\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'completed', 'failed', 'abandoned')),\n verdict TEXT CHECK(verdict IN ('success', 'failure', 'partial', NULL)),\n\n -- Context\n task TEXT,\n context TEXT, -- JSON object\n\n -- Metrics\n total_steps INTEGER DEFAULT 0,\n total_reward REAL DEFAULT 0,\n\n -- Timestamps\n started_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n ended_at INTEGER,\n\n -- Reference to extracted pattern (if any)\n extracted_pattern_id TEXT REFERENCES patterns(id)\n);\n\n-- Trajectory steps\nCREATE TABLE IF NOT EXISTS trajectory_steps (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n trajectory_id TEXT NOT NULL REFERENCES trajectories(id),\n step_number INTEGER NOT NULL,\n\n -- Step data\n action TEXT NOT NULL,\n observation TEXT,\n reward REAL DEFAULT 0,\n\n -- Metadata\n metadata TEXT, -- JSON object\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\nCREATE INDEX IF NOT EXISTS idx_steps_trajectory ON trajectory_steps(trajectory_id);\n\n-- ============================================\n-- MIGRATION STATE TRACKING\n-- ============================================\n\n-- Migration state (for resume capability)\nCREATE TABLE IF NOT EXISTS migration_state (\n id TEXT PRIMARY KEY,\n migration_type TEXT NOT NULL, -- 'v2-to-v3', 'pattern', 'memory', etc.\n\n -- Progress tracking\n status TEXT DEFAULT 'pending' CHECK(status IN ('pending', 'in_progress', 'completed', 'failed', 'rolled_back')),\n total_items INTEGER DEFAULT 0,\n processed_items INTEGER DEFAULT 0,\n failed_items INTEGER DEFAULT 0,\n skipped_items INTEGER DEFAULT 0,\n\n -- Current position (for resume)\n current_batch INTEGER DEFAULT 0,\n last_processed_id TEXT,\n\n -- Source/destination info\n source_path TEXT,\n source_type TEXT,\n destination_path TEXT,\n\n -- Backup info\n backup_path TEXT,\n backup_created_at INTEGER,\n\n -- Error tracking\n last_error TEXT,\n errors TEXT, -- JSON array of errors\n\n -- Timestamps\n started_at INTEGER,\n completed_at INTEGER,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\n-- ============================================\n-- SESSION MANAGEMENT\n-- ============================================\n\n-- Sessions for context persistence\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n\n -- Session state\n state TEXT NOT NULL, -- JSON object with full session state\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'paused', 'completed', 'expired')),\n\n -- Context\n project_path TEXT,\n branch TEXT,\n\n -- Metrics\n tasks_completed INTEGER DEFAULT 0,\n patterns_learned INTEGER DEFAULT 0,\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n expires_at INTEGER\n);\n\n-- ============================================\n-- VECTOR INDEX METADATA (for HNSW)\n-- ============================================\n\n-- Track HNSW index state\nCREATE TABLE IF NOT EXISTS vector_indexes (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n\n -- Index configuration\n dimensions INTEGER NOT NULL,\n metric TEXT DEFAULT 'cosine' CHECK(metric IN ('cosine', 'euclidean', 'dot')),\n\n -- HNSW parameters\n hnsw_m INTEGER DEFAULT 16,\n hnsw_ef_construction INTEGER DEFAULT 200,\n hnsw_ef_search INTEGER DEFAULT 100,\n\n -- Quantization\n quantization_type TEXT CHECK(quantization_type IN ('none', 'scalar', 'product')),\n quantization_bits INTEGER DEFAULT 8,\n\n -- Statistics\n total_vectors INTEGER DEFAULT 0,\n last_rebuild_at INTEGER,\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\n-- ============================================\n-- SYSTEM METADATA\n-- ============================================\n\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at INTEGER DEFAULT (strftime('%s', 'now') * 1000)\n);\n";
18
+ export declare const MEMORY_SCHEMA_V3 = "\n-- RuFlo V3 Memory Database\n-- Version: 3.0.0\n-- Features: Pattern learning, vector embeddings, temporal decay, migration tracking\n\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA foreign_keys = ON;\n\n-- ============================================\n-- CORE MEMORY TABLES\n-- ============================================\n\n-- Memory entries (main storage)\nCREATE TABLE IF NOT EXISTS memory_entries (\n id TEXT PRIMARY KEY,\n key TEXT NOT NULL,\n namespace TEXT DEFAULT 'default',\n content TEXT NOT NULL,\n type TEXT DEFAULT 'semantic' CHECK(type IN ('semantic', 'episodic', 'procedural', 'working', 'pattern')),\n\n -- Vector embedding for semantic search (stored as JSON array)\n embedding TEXT,\n embedding_model TEXT DEFAULT 'local',\n embedding_dimensions INTEGER,\n\n -- Metadata\n tags TEXT, -- JSON array\n metadata TEXT, -- JSON object\n owner_id TEXT,\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n expires_at INTEGER,\n last_accessed_at INTEGER,\n\n -- Access tracking for hot/cold detection\n access_count INTEGER DEFAULT 0,\n\n -- Status\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deleted')),\n\n UNIQUE(namespace, key)\n);\n\n-- Indexes for memory entries\nCREATE INDEX IF NOT EXISTS idx_memory_namespace ON memory_entries(namespace);\nCREATE INDEX IF NOT EXISTS idx_memory_key ON memory_entries(key);\nCREATE INDEX IF NOT EXISTS idx_memory_type ON memory_entries(type);\nCREATE INDEX IF NOT EXISTS idx_memory_status ON memory_entries(status);\nCREATE INDEX IF NOT EXISTS idx_memory_created ON memory_entries(created_at);\nCREATE INDEX IF NOT EXISTS idx_memory_accessed ON memory_entries(last_accessed_at);\nCREATE INDEX IF NOT EXISTS idx_memory_owner ON memory_entries(owner_id);\n\n-- ============================================\n-- PATTERN LEARNING TABLES\n-- ============================================\n\n-- Learned patterns with confidence scoring and versioning\nCREATE TABLE IF NOT EXISTS patterns (\n id TEXT PRIMARY KEY,\n\n -- Pattern identification\n name TEXT NOT NULL,\n pattern_type TEXT NOT NULL CHECK(pattern_type IN (\n 'task-routing', 'error-recovery', 'optimization', 'learning',\n 'coordination', 'prediction', 'code-pattern', 'workflow'\n )),\n\n -- Pattern definition\n condition TEXT NOT NULL, -- Regex or semantic match\n action TEXT NOT NULL, -- What to do when pattern matches\n description TEXT,\n\n -- Confidence scoring (0.0 - 1.0)\n confidence REAL DEFAULT 0.5,\n success_count INTEGER DEFAULT 0,\n failure_count INTEGER DEFAULT 0,\n\n -- Temporal decay\n decay_rate REAL DEFAULT 0.01, -- How fast confidence decays\n half_life_days INTEGER DEFAULT 30, -- Days until confidence halves without use\n\n -- Vector embedding for semantic pattern matching\n embedding TEXT,\n embedding_dimensions INTEGER,\n\n -- Versioning\n version INTEGER DEFAULT 1,\n parent_id TEXT REFERENCES patterns(id),\n\n -- Metadata\n tags TEXT, -- JSON array\n metadata TEXT, -- JSON object\n source TEXT, -- Where the pattern was learned from\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n last_matched_at INTEGER,\n last_success_at INTEGER,\n last_failure_at INTEGER,\n\n -- Status\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deprecated', 'experimental'))\n);\n\n-- Indexes for patterns\nCREATE INDEX IF NOT EXISTS idx_patterns_type ON patterns(pattern_type);\nCREATE INDEX IF NOT EXISTS idx_patterns_confidence ON patterns(confidence DESC);\nCREATE INDEX IF NOT EXISTS idx_patterns_status ON patterns(status);\nCREATE INDEX IF NOT EXISTS idx_patterns_last_matched ON patterns(last_matched_at);\n\n-- Pattern evolution history (for versioning)\nCREATE TABLE IF NOT EXISTS pattern_history (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n pattern_id TEXT NOT NULL REFERENCES patterns(id),\n version INTEGER NOT NULL,\n\n -- Snapshot of pattern state\n confidence REAL,\n success_count INTEGER,\n failure_count INTEGER,\n condition TEXT,\n action TEXT,\n\n -- What changed\n change_type TEXT CHECK(change_type IN ('created', 'updated', 'success', 'failure', 'decay', 'merged', 'split')),\n change_reason TEXT,\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\nCREATE INDEX IF NOT EXISTS idx_pattern_history_pattern ON pattern_history(pattern_id);\n\n-- ============================================\n-- LEARNING & TRAJECTORY TABLES\n-- ============================================\n\n-- Learning trajectories (SONA integration)\nCREATE TABLE IF NOT EXISTS trajectories (\n id TEXT PRIMARY KEY,\n session_id TEXT,\n\n -- Trajectory state\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'completed', 'failed', 'abandoned')),\n verdict TEXT CHECK(verdict IN ('success', 'failure', 'partial', NULL)),\n\n -- Context\n task TEXT,\n context TEXT, -- JSON object\n\n -- Metrics\n total_steps INTEGER DEFAULT 0,\n total_reward REAL DEFAULT 0,\n\n -- Timestamps\n started_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n ended_at INTEGER,\n\n -- Reference to extracted pattern (if any)\n extracted_pattern_id TEXT REFERENCES patterns(id)\n);\n\n-- Trajectory steps\nCREATE TABLE IF NOT EXISTS trajectory_steps (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n trajectory_id TEXT NOT NULL REFERENCES trajectories(id),\n step_number INTEGER NOT NULL,\n\n -- Step data\n action TEXT NOT NULL,\n observation TEXT,\n reward REAL DEFAULT 0,\n\n -- Metadata\n metadata TEXT, -- JSON object\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\nCREATE INDEX IF NOT EXISTS idx_steps_trajectory ON trajectory_steps(trajectory_id);\n\n-- ============================================\n-- MIGRATION STATE TRACKING\n-- ============================================\n\n-- Migration state (for resume capability)\nCREATE TABLE IF NOT EXISTS migration_state (\n id TEXT PRIMARY KEY,\n migration_type TEXT NOT NULL, -- 'v2-to-v3', 'pattern', 'memory', etc.\n\n -- Progress tracking\n status TEXT DEFAULT 'pending' CHECK(status IN ('pending', 'in_progress', 'completed', 'failed', 'rolled_back')),\n total_items INTEGER DEFAULT 0,\n processed_items INTEGER DEFAULT 0,\n failed_items INTEGER DEFAULT 0,\n skipped_items INTEGER DEFAULT 0,\n\n -- Current position (for resume)\n current_batch INTEGER DEFAULT 0,\n last_processed_id TEXT,\n\n -- Source/destination info\n source_path TEXT,\n source_type TEXT,\n destination_path TEXT,\n\n -- Backup info\n backup_path TEXT,\n backup_created_at INTEGER,\n\n -- Error tracking\n last_error TEXT,\n errors TEXT, -- JSON array of errors\n\n -- Timestamps\n started_at INTEGER,\n completed_at INTEGER,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\n-- ============================================\n-- SESSION MANAGEMENT\n-- ============================================\n\n-- Sessions for context persistence\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n\n -- Session state\n state TEXT NOT NULL, -- JSON object with full session state\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'paused', 'completed', 'expired')),\n\n -- Context\n project_path TEXT,\n branch TEXT,\n\n -- Metrics\n tasks_completed INTEGER DEFAULT 0,\n patterns_learned INTEGER DEFAULT 0,\n\n -- Timestamps\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n expires_at INTEGER\n);\n\n-- ============================================\n-- VECTOR INDEX METADATA (for HNSW)\n-- ============================================\n\n-- Track HNSW index state\nCREATE TABLE IF NOT EXISTS vector_indexes (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n\n -- Index configuration\n dimensions INTEGER NOT NULL,\n metric TEXT DEFAULT 'cosine' CHECK(metric IN ('cosine', 'euclidean', 'dot')),\n\n -- HNSW parameters\n hnsw_m INTEGER DEFAULT 16,\n hnsw_ef_construction INTEGER DEFAULT 200,\n hnsw_ef_search INTEGER DEFAULT 100,\n\n -- Quantization\n quantization_type TEXT CHECK(quantization_type IN ('none', 'scalar', 'product')),\n quantization_bits INTEGER DEFAULT 8,\n\n -- Statistics\n total_vectors INTEGER DEFAULT 0,\n last_rebuild_at INTEGER,\n\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\n-- ============================================\n-- GRAPH EDGES (ADR-130 Phase 1)\n-- Unified knowledge graph backend \u2014 sql.js canonical store\n-- ============================================\n\n-- Unified graph edges table (ADR-130)\n-- Node IDs use domain-prefixed format: {domain}:{uuid}\n-- where domain in (mem, agent, task, entity, span, pattern)\nCREATE TABLE IF NOT EXISTS graph_edges (\n id TEXT PRIMARY KEY, -- edge-{uuid}\n source_id TEXT NOT NULL, -- domain-prefixed node ID\n target_id TEXT NOT NULL, -- domain-prefixed node ID\n relation TEXT NOT NULL, -- e.g. \"caused\", \"depends-on\", \"imports\"\n weight REAL DEFAULT 1.0,\n -- Temporal / reliability semantics (ADR-130 \u00A7\"graph that forgets\" property)\n confidence REAL DEFAULT 1.0, -- [0,1]; updated by JUDGE step\n decay_rate REAL DEFAULT 0.0, -- per-day exponential decay applied at read time\n last_reinforced TEXT, -- ISO-8601; set when CONSOLIDATE re-touches edge\n witness_id TEXT, -- FK to verification/witness-fixes.json (ADR-103)\n -- Embedding storage: \"inline:{base64}\" | \"vector_indexes:{id}\" | NULL\n embedding_ref TEXT,\n metadata TEXT, -- JSON blob for plugin-specific fields\n created_at TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_graph_edges_source ON graph_edges (source_id);\nCREATE INDEX IF NOT EXISTS idx_graph_edges_target ON graph_edges (target_id);\nCREATE INDEX IF NOT EXISTS idx_graph_edges_relation ON graph_edges (relation);\nCREATE INDEX IF NOT EXISTS idx_graph_edges_reinforced ON graph_edges (last_reinforced);\n\n-- ============================================\n-- SYSTEM METADATA\n-- ============================================\n\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at INTEGER DEFAULT (strftime('%s', 'now') * 1000)\n);\n";
19
19
  interface HNSWEntry {
20
20
  id: string;
21
21
  key: string;
@@ -373,6 +373,36 @@ CREATE TABLE IF NOT EXISTS vector_indexes (
373
373
  updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)
374
374
  );
375
375
 
376
+ -- ============================================
377
+ -- GRAPH EDGES (ADR-130 Phase 1)
378
+ -- Unified knowledge graph backend — sql.js canonical store
379
+ -- ============================================
380
+
381
+ -- Unified graph edges table (ADR-130)
382
+ -- Node IDs use domain-prefixed format: {domain}:{uuid}
383
+ -- where domain in (mem, agent, task, entity, span, pattern)
384
+ CREATE TABLE IF NOT EXISTS graph_edges (
385
+ id TEXT PRIMARY KEY, -- edge-{uuid}
386
+ source_id TEXT NOT NULL, -- domain-prefixed node ID
387
+ target_id TEXT NOT NULL, -- domain-prefixed node ID
388
+ relation TEXT NOT NULL, -- e.g. "caused", "depends-on", "imports"
389
+ weight REAL DEFAULT 1.0,
390
+ -- Temporal / reliability semantics (ADR-130 §"graph that forgets" property)
391
+ confidence REAL DEFAULT 1.0, -- [0,1]; updated by JUDGE step
392
+ decay_rate REAL DEFAULT 0.0, -- per-day exponential decay applied at read time
393
+ last_reinforced TEXT, -- ISO-8601; set when CONSOLIDATE re-touches edge
394
+ witness_id TEXT, -- FK to verification/witness-fixes.json (ADR-103)
395
+ -- Embedding storage: "inline:{base64}" | "vector_indexes:{id}" | NULL
396
+ embedding_ref TEXT,
397
+ metadata TEXT, -- JSON blob for plugin-specific fields
398
+ created_at TEXT NOT NULL
399
+ );
400
+
401
+ CREATE INDEX IF NOT EXISTS idx_graph_edges_source ON graph_edges (source_id);
402
+ CREATE INDEX IF NOT EXISTS idx_graph_edges_target ON graph_edges (target_id);
403
+ CREATE INDEX IF NOT EXISTS idx_graph_edges_relation ON graph_edges (relation);
404
+ CREATE INDEX IF NOT EXISTS idx_graph_edges_reinforced ON graph_edges (last_reinforced);
405
+
376
406
  -- ============================================
377
407
  -- SYSTEM METADATA
378
408
  -- ============================================
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.8.0",
3
+ "version": "3.9.0",
4
4
  "type": "module",
5
5
  "description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",