moflo 4.5.0 → 4.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/package.json +1 -1
  2. package/src/@claude-flow/cli/dist/src/commands/appliance.js +12 -12
  3. package/src/@claude-flow/cli/dist/src/commands/benchmark.js +2 -2
  4. package/src/@claude-flow/cli/dist/src/commands/claims.js +1 -1
  5. package/src/@claude-flow/cli/dist/src/commands/config.js +1 -1
  6. package/src/@claude-flow/cli/dist/src/commands/daemon.js +25 -3
  7. package/src/@claude-flow/cli/dist/src/commands/deployment.js +1 -1
  8. package/src/@claude-flow/cli/dist/src/commands/doctor.js +23 -6
  9. package/src/@claude-flow/cli/dist/src/commands/embeddings.js +1 -1
  10. package/src/@claude-flow/cli/dist/src/commands/hooks.js +1 -1
  11. package/src/@claude-flow/cli/dist/src/commands/init.js +14 -12
  12. package/src/@claude-flow/cli/dist/src/commands/neural.js +1 -1
  13. package/src/@claude-flow/cli/dist/src/commands/orc.d.ts +2 -2
  14. package/src/@claude-flow/cli/dist/src/commands/orc.js +12 -12
  15. package/src/@claude-flow/cli/dist/src/commands/performance.js +1 -1
  16. package/src/@claude-flow/cli/dist/src/commands/plugins.js +1 -1
  17. package/src/@claude-flow/cli/dist/src/commands/providers.js +1 -1
  18. package/src/@claude-flow/cli/dist/src/commands/security.js +1 -1
  19. package/src/@claude-flow/cli/dist/src/commands/start.js +11 -11
  20. package/src/@claude-flow/cli/dist/src/commands/status.js +3 -3
  21. package/src/@claude-flow/cli/dist/src/commands/transfer-store.js +1 -1
  22. package/src/@claude-flow/cli/dist/src/config/moflo-config.d.ts +30 -0
  23. package/src/@claude-flow/cli/dist/src/config/moflo-config.js +103 -7
  24. package/src/@claude-flow/cli/dist/src/index.d.ts +1 -1
  25. package/src/@claude-flow/cli/dist/src/index.js +3 -3
  26. package/src/@claude-flow/cli/dist/src/init/claudemd-generator.js +1 -1
  27. package/src/@claude-flow/cli/dist/src/init/executor.js +485 -472
  28. package/src/@claude-flow/cli/dist/src/init/helpers-generator.js +640 -640
  29. package/src/@claude-flow/cli/dist/src/init/moflo-init.js +530 -66
  30. package/src/@claude-flow/cli/dist/src/init/settings-generator.js +7 -12
  31. package/src/@claude-flow/cli/dist/src/init/statusline-generator.d.ts +1 -1
  32. package/src/@claude-flow/cli/dist/src/init/statusline-generator.js +784 -784
  33. package/src/@claude-flow/cli/dist/src/mcp-tools/agentdb-tools.js +12 -12
  34. package/src/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +122 -66
  35. package/src/@claude-flow/cli/dist/src/memory/intelligence.js +5 -1
  36. package/src/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +1 -1
  37. package/src/@claude-flow/cli/dist/src/memory/memory-initializer.js +371 -371
  38. package/src/@claude-flow/cli/dist/src/parser.d.ts +10 -0
  39. package/src/@claude-flow/cli/dist/src/parser.js +49 -3
  40. package/src/@claude-flow/cli/dist/src/plugins/store/discovery.js +1 -1
  41. package/src/@claude-flow/cli/dist/src/runtime/headless.js +30 -30
  42. package/src/@claude-flow/cli/dist/src/services/claim-service.js +1 -1
  43. package/src/@claude-flow/cli/dist/src/services/ruvector-training.js +11 -5
  44. package/src/@claude-flow/cli/dist/src/services/workflow-gate.d.ts +13 -3
  45. package/src/@claude-flow/cli/dist/src/services/workflow-gate.js +73 -5
  46. package/src/@claude-flow/cli/dist/src/types.d.ts +1 -1
  47. package/src/@claude-flow/cli/dist/src/types.js +1 -1
@@ -81,7 +81,7 @@ export const agentdbControllers = {
81
81
  const bridge = await getBridge();
82
82
  const controllers = await bridge.bridgeListControllers();
83
83
  if (!controllers)
84
- return { available: false, controllers: [], error: 'Bridge not available' };
84
+ return { available: false, controllers: [], error: 'AgentDB bridge not available — @claude-flow/memory not installed or missing controller-registry. Use memory_store/memory_search tools instead.' };
85
85
  return {
86
86
  available: true,
87
87
  controllers,
@@ -118,7 +118,7 @@ export const agentdbPatternStore = {
118
118
  type: validateString(params.type, 'type', 200) ?? 'general',
119
119
  confidence: validateScore(params.confidence, 0.8),
120
120
  });
121
- return result ?? { success: false, error: 'Bridge not available' };
121
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
122
122
  }
123
123
  catch (error) {
124
124
  return { success: false, error: sanitizeError(error) };
@@ -182,7 +182,7 @@ export const agentdbFeedback = {
182
182
  quality: validateScore(params.quality, 0.85),
183
183
  agent: validateString(params.agent, 'agent', 200) ?? undefined,
184
184
  });
185
- return result ?? { success: false, error: 'Bridge not available' };
185
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
186
186
  }
187
187
  catch (error) {
188
188
  return { success: false, error: sanitizeError(error) };
@@ -221,7 +221,7 @@ export const agentdbCausalEdge = {
221
221
  relation,
222
222
  weight: typeof params.weight === 'number' ? validateScore(params.weight, 0.5) : undefined,
223
223
  });
224
- return result ?? { success: false, error: 'Bridge not available' };
224
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
225
225
  }
226
226
  catch (error) {
227
227
  return { success: false, error: sanitizeError(error) };
@@ -279,7 +279,7 @@ export const agentdbSessionStart = {
279
279
  sessionId,
280
280
  context: validateString(params.context, 'context', 10_000) ?? undefined,
281
281
  });
282
- return result ?? { success: false, error: 'Bridge not available' };
282
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
283
283
  }
284
284
  catch (error) {
285
285
  return { success: false, error: sanitizeError(error) };
@@ -310,7 +310,7 @@ export const agentdbSessionEnd = {
310
310
  summary: validateString(params.summary, 'summary', 50_000) ?? undefined,
311
311
  tasksCompleted: validatePositiveInt(params.tasksCompleted, 0, 10_000),
312
312
  });
313
- return result ?? { success: false, error: 'Bridge not available' };
313
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
314
314
  }
315
315
  catch (error) {
316
316
  return { success: false, error: sanitizeError(error) };
@@ -349,7 +349,7 @@ export const agentdbHierarchicalStore = {
349
349
  }
350
350
  const bridge = await getBridge();
351
351
  const result = await bridge.bridgeHierarchicalStore({ key, value, tier });
352
- return result ?? { success: false, error: 'Bridge not available' };
352
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
353
353
  }
354
354
  catch (error) {
355
355
  return { success: false, error: sanitizeError(error) };
@@ -384,7 +384,7 @@ export const agentdbHierarchicalRecall = {
384
384
  tier: tier ?? undefined,
385
385
  topK: validatePositiveInt(params.topK, 5, MAX_TOP_K),
386
386
  });
387
- return result ?? { results: [], error: 'Bridge not available' };
387
+ return result ?? { results: [], error: 'AgentDB bridge not available. Use memory_search instead.' };
388
388
  }
389
389
  catch (error) {
390
390
  return { results: [], error: sanitizeError(error) };
@@ -409,7 +409,7 @@ export const agentdbConsolidate = {
409
409
  minAge: typeof params.minAge === 'number' ? Math.max(0, params.minAge) : undefined,
410
410
  maxEntries: validatePositiveInt(params.maxEntries, 1000, 10_000),
411
411
  });
412
- return result ?? { success: false, error: 'Bridge not available' };
412
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
413
413
  }
414
414
  catch (error) {
415
415
  return { success: false, error: sanitizeError(error) };
@@ -475,7 +475,7 @@ export const agentdbBatch = {
475
475
  operation,
476
476
  entries: validatedEntries,
477
477
  });
478
- return result ?? { success: false, error: 'Bridge not available' };
478
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
479
479
  }
480
480
  catch (error) {
481
481
  return { success: false, error: sanitizeError(error) };
@@ -504,7 +504,7 @@ export const agentdbContextSynthesize = {
504
504
  query,
505
505
  maxEntries: validatePositiveInt(params.maxEntries, 10, MAX_TOP_K),
506
506
  });
507
- return result ?? { success: false, error: 'Bridge not available' };
507
+ return result ?? { success: false, error: 'AgentDB bridge not available. Use memory_store/memory_search instead.' };
508
508
  }
509
509
  catch (error) {
510
510
  return { success: false, error: sanitizeError(error) };
@@ -529,7 +529,7 @@ export const agentdbSemanticRoute = {
529
529
  return { route: null, error: 'input is required (non-empty string, max 10KB)' };
530
530
  const bridge = await getBridge();
531
531
  const result = await bridge.bridgeSemanticRoute({ input });
532
- return result ?? { route: null, error: 'Bridge not available' };
532
+ return result ?? { route: null, error: 'AgentDB bridge not available. Use hooks route instead.' };
533
533
  }
534
534
  catch (error) {
535
535
  return { route: null, error: sanitizeError(error) };
@@ -3,7 +3,7 @@
3
3
  * Provides intelligent hooks functionality via MCP protocol
4
4
  */
5
5
  import { mkdirSync, writeFileSync, existsSync, readFileSync, statSync } from 'fs';
6
- import { join, resolve } from 'path';
6
+ import { dirname, join, resolve } from 'path';
7
7
  // Real vector search functions - lazy loaded to avoid circular imports
8
8
  let searchEntriesFn = null;
9
9
  async function getRealSearchFunction() {
@@ -121,6 +121,81 @@ function generateSimpleEmbedding(text, dimension = 384) {
121
121
  }
122
122
  return embedding;
123
123
  }
124
+ // ── Runtime routing outcome persistence ──────────────────────────────
125
+ // Closes the learning loop: post-task records outcomes → route loads them.
126
+ const ROUTING_OUTCOMES_PATH = join(resolve('.'), '.claude-flow/routing-outcomes.json');
127
+ const ROUTING_STOPWORDS = new Set([
128
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had',
129
+ 'do', 'does', 'did', 'will', 'would', 'could', 'should', 'may', 'might', 'shall', 'can',
130
+ 'to', 'of', 'in', 'for', 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',
131
+ 'before', 'after', 'above', 'below', 'between', 'under', 'again', 'further', 'then', 'once',
132
+ 'it', 'its', 'this', 'that', 'these', 'those', 'i', 'me', 'my', 'we', 'our', 'you', 'your',
133
+ 'he', 'she', 'they', 'them', 'and', 'but', 'or', 'nor', 'not', 'no', 'so', 'if', 'when', 'than',
134
+ 'very', 'just', 'also', 'only', 'both', 'each', 'all', 'any', 'few', 'more', 'most', 'other',
135
+ 'some', 'such', 'same', 'new', 'now', 'here', 'there', 'where', 'how', 'what', 'which', 'who',
136
+ ]);
137
+ function extractKeywords(text) {
138
+ if (!text)
139
+ return [];
140
+ return text.toLowerCase()
141
+ .replace(/[^a-z0-9\s-]/g, ' ')
142
+ .split(/\s+/)
143
+ .filter(w => w.length > 2 && !ROUTING_STOPWORDS.has(w));
144
+ }
145
+ function loadRoutingOutcomes() {
146
+ try {
147
+ if (existsSync(ROUTING_OUTCOMES_PATH)) {
148
+ const data = JSON.parse(readFileSync(ROUTING_OUTCOMES_PATH, 'utf-8'));
149
+ return data.outcomes || [];
150
+ }
151
+ }
152
+ catch { /* corrupt file, start fresh */ }
153
+ return [];
154
+ }
155
+ function saveRoutingOutcomes(outcomes) {
156
+ try {
157
+ const dir = dirname(ROUTING_OUTCOMES_PATH);
158
+ if (!existsSync(dir))
159
+ mkdirSync(dir, { recursive: true });
160
+ // Cap at 500 entries to bound file size
161
+ const capped = outcomes.slice(-500);
162
+ writeFileSync(ROUTING_OUTCOMES_PATH, JSON.stringify({ outcomes: capped }, null, 2));
163
+ }
164
+ catch { /* non-critical */ }
165
+ }
166
+ /**
167
+ * Build learned patterns from past routing outcomes.
168
+ * Called by hooks_route to incorporate runtime learning into routing decisions.
169
+ */
170
+ function learnedPatternsFromOutcomes() {
171
+ const outcomes = loadRoutingOutcomes();
172
+ if (outcomes.length === 0)
173
+ return {};
174
+ // Group successful outcomes by agent
175
+ const agentKeywords = new Map();
176
+ for (const o of outcomes) {
177
+ if (!o.success || o.quality < 0.5)
178
+ continue;
179
+ if (!agentKeywords.has(o.agent))
180
+ agentKeywords.set(o.agent, new Map());
181
+ const kwMap = agentKeywords.get(o.agent);
182
+ for (const kw of o.keywords) {
183
+ kwMap.set(kw, (kwMap.get(kw) || 0) + 1);
184
+ }
185
+ }
186
+ const learned = {};
187
+ for (const [agent, kwMap] of agentKeywords) {
188
+ // Take top-10 most frequent keywords for this agent
189
+ const sorted = [...kwMap.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10);
190
+ if (sorted.length >= 2) { // Need at least 2 keywords for a meaningful pattern
191
+ learned[`learned-${agent}`] = {
192
+ keywords: sorted.map(([kw]) => kw),
193
+ agents: [agent],
194
+ };
195
+ }
196
+ }
197
+ return learned;
198
+ }
124
199
  // Task patterns used by both native and pure-JS routers
125
200
  const TASK_PATTERNS = {
126
201
  'security-task': {
@@ -176,50 +251,8 @@ const TASK_PATTERNS = {
176
251
  * Load learned routing patterns from persisted file.
177
252
  * These are outcomes from previous task executions stored by hooksPostTask.
178
253
  */
179
- const ROUTING_OUTCOMES_PATH = '.claude-flow/routing-outcomes.json';
180
- function loadRoutingOutcomes() {
181
- try {
182
- const fullPath = join(process.cwd(), ROUTING_OUTCOMES_PATH);
183
- if (!existsSync(fullPath))
184
- return [];
185
- const data = JSON.parse(readFileSync(fullPath, 'utf-8'));
186
- return Array.isArray(data) ? data : [];
187
- }
188
- catch {
189
- return [];
190
- }
191
- }
192
- function saveRoutingOutcome(task, agentType, confidence) {
193
- try {
194
- const fullPath = join(process.cwd(), ROUTING_OUTCOMES_PATH);
195
- const dir = resolve(fullPath, '..');
196
- if (!existsSync(dir))
197
- mkdirSync(dir, { recursive: true });
198
- const existing = loadRoutingOutcomes();
199
- // Extract keywords for pattern matching
200
- const keywords = task.toLowerCase()
201
- .replace(/[^a-z0-9\s]/g, ' ')
202
- .split(/\s+/)
203
- .filter(w => w.length > 3)
204
- .slice(0, 5);
205
- if (keywords.length > 0) {
206
- existing.push({
207
- pattern: `learned-${agentType}`,
208
- agentType,
209
- confidence,
210
- keywords,
211
- task: task.slice(0, 200),
212
- timestamp: new Date().toISOString(),
213
- });
214
- // Keep last 500 outcomes
215
- const trimmed = existing.slice(-500);
216
- writeFileSync(fullPath, JSON.stringify(trimmed, null, 2));
217
- }
218
- }
219
- catch {
220
- // Silently fail — routing outcome persistence is best-effort
221
- }
222
- }
254
+ // Old loadRoutingOutcomes/saveRoutingOutcome removed — replaced by
255
+ // RoutingOutcome-based persistence at top of file (upstream adcfe6fad).
223
256
  /**
224
257
  * Get the semantic router with environment detection.
225
258
  * Tries native VectorDb first (HNSW, 16k routes/s), falls back to pure JS (47k routes/s cosine).
@@ -255,13 +288,11 @@ async function getSemanticRouter() {
255
288
  }
256
289
  }
257
290
  // Also load learned patterns from previous task executions
258
- const learnedPatterns = loadRoutingOutcomes();
259
- for (const lp of learnedPatterns) {
260
- // Index per-keyword embeddings for finer-grained matching
261
- const kws = lp.keywords || [lp.pattern];
262
- for (const kw of kws) {
291
+ const learned = learnedPatternsFromOutcomes();
292
+ for (const [patternName, { keywords }] of Object.entries(learned)) {
293
+ for (const kw of keywords) {
263
294
  const embedding = generateSimpleEmbedding(kw);
264
- const entryKey = `learned-${lp.agentType}:${kw}`;
295
+ const entryKey = `${patternName}:${kw}`;
265
296
  db.insert(entryKey, embedding);
266
297
  TASK_PATTERN_EMBEDDINGS.set(entryKey, embedding);
267
298
  }
@@ -289,13 +320,12 @@ async function getSemanticRouter() {
289
320
  });
290
321
  }
291
322
  // Also load learned patterns from previous task executions
292
- const learnedPatterns = loadRoutingOutcomes();
293
- for (const lp of learnedPatterns) {
294
- const kws = lp.keywords || [lp.pattern];
295
- const embeddings = kws.map(kw => generateSimpleEmbedding(kw));
296
- semanticRouter.addIntentWithEmbeddings(`learned-${lp.agentType}`, embeddings, { agents: [lp.agentType], keywords: kws, confidence: lp.confidence });
297
- kws.forEach((kw, i) => {
298
- TASK_PATTERN_EMBEDDINGS.set(`learned-${lp.agentType}:${kw}`, embeddings[i]);
323
+ const learned = learnedPatternsFromOutcomes();
324
+ for (const [patternName, { keywords, agents }] of Object.entries(learned)) {
325
+ const embeddings = keywords.map(kw => generateSimpleEmbedding(kw));
326
+ semanticRouter.addIntentWithEmbeddings(patternName, embeddings, { agents, keywords });
327
+ keywords.forEach((kw, i) => {
328
+ TASK_PATTERN_EMBEDDINGS.set(`${patternName}:${kw}`, embeddings[i]);
299
329
  });
300
330
  }
301
331
  routerBackend = 'pure-js';
@@ -1054,18 +1084,43 @@ export const hooksPostTask = {
1054
1084
  // Non-fatal
1055
1085
  }
1056
1086
  // Persist routing outcome for future learned pattern matching
1057
- let routingOutcomeSaved = false;
1058
- if (storeDecisions && agent && task) {
1087
+ // Persist routing outcome for runtime learning (file-based, always reliable)
1088
+ const taskText = params.task || '';
1089
+ const outcomeKeywords = extractKeywords(taskText);
1090
+ let outcomePersisted = false;
1091
+ if (taskText && agent && agent.length <= 100 && /^[a-zA-Z0-9_-]+$/.test(agent)) {
1059
1092
  try {
1060
- saveRoutingOutcome(task, agent, quality);
1061
- routingOutcomeSaved = true;
1093
+ const outcomes = loadRoutingOutcomes();
1094
+ outcomes.push({
1095
+ task: taskText,
1096
+ agent,
1097
+ success,
1098
+ quality,
1099
+ keywords: outcomeKeywords,
1100
+ timestamp: new Date().toISOString(),
1101
+ });
1102
+ saveRoutingOutcomes(outcomes);
1103
+ outcomePersisted = true;
1062
1104
  // Sync learning metrics for dashboard
1063
1105
  const { getAgentRouter } = await import('../services/agent-router.js');
1064
1106
  getAgentRouter().syncLearningMetrics();
1065
1107
  }
1066
- catch {
1067
- // Best-effort persistence
1108
+ catch { /* non-critical */ }
1109
+ }
1110
+ // Optionally store in memory DB for cross-session vector retrieval
1111
+ if (params.storeDecisions && taskText && agent) {
1112
+ try {
1113
+ const storeFn = await getRealStoreFunction();
1114
+ if (storeFn) {
1115
+ await storeFn({
1116
+ key: `routing-decision:${taskId}`,
1117
+ namespace: 'patterns',
1118
+ value: JSON.stringify({ task: taskText, agent, success, quality, keywords: outcomeKeywords }),
1119
+ tags: ['routing-decision'],
1120
+ });
1121
+ }
1068
1122
  }
1123
+ catch { /* non-critical */ }
1069
1124
  }
1070
1125
  const duration = Date.now() - startTime;
1071
1126
  return {
@@ -1077,6 +1132,7 @@ export const hooksPostTask = {
1077
1132
  newPatterns: success ? 1 : 0,
1078
1133
  trajectoryId: `traj-${Date.now()}`,
1079
1134
  controller: feedbackResult?.controller || 'none',
1135
+ outcomePersisted,
1080
1136
  },
1081
1137
  quality,
1082
1138
  feedback: feedbackResult ? {
@@ -1085,9 +1141,9 @@ export const hooksPostTask = {
1085
1141
  updates: feedbackResult.updated,
1086
1142
  } : { recorded: false, controller: 'unavailable', updates: 0 },
1087
1143
  routingOutcome: {
1088
- saved: routingOutcomeSaved,
1144
+ saved: outcomePersisted,
1089
1145
  agent: agent || null,
1090
- task: task || null,
1146
+ task: taskText || null,
1091
1147
  },
1092
1148
  timestamp: new Date().toISOString(),
1093
1149
  };
@@ -545,9 +545,13 @@ export async function findSimilarPatterns(query, options) {
545
545
  const queryResult = await generateEmbedding(query);
546
546
  queryEmbedding = queryResult.embedding;
547
547
  }
548
+ // Hash-fallback embeddings (128-dim) produce lower cosine similarities
549
+ // than ONNX/transformer embeddings, so use a lower default threshold
550
+ const isHashFallback = queryEmbedding.length === 128;
551
+ const defaultThreshold = isHashFallback ? 0.1 : 0.5;
548
552
  const results = reasoningBank.findSimilar(queryEmbedding, {
549
553
  k: options?.k ?? 5,
550
- threshold: options?.threshold ?? 0.5,
554
+ threshold: options?.threshold ?? defaultThreshold,
551
555
  type: options?.type
552
556
  });
553
557
  return results.map((r) => ({
@@ -12,7 +12,7 @@
12
12
  * Enhanced schema with pattern confidence, temporal decay, versioning
13
13
  * Vector embeddings enabled for semantic search
14
14
  */
15
- 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";
15
+ export declare const MEMORY_SCHEMA_V3 = "\n-- MoFlo 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";
16
16
  interface HNSWEntry {
17
17
  id: string;
18
18
  key: string;