moflo 4.0.1 → 4.0.3

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 (91) hide show
  1. package/.claude/guidance/agent-bootstrap.md +12 -6
  2. package/bin/setup-project.mjs +201 -0
  3. package/package.json +114 -109
  4. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +194 -81
  5. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +1892 -1841
  6. package/v3/@claude-flow/memory/README.md +587 -0
  7. package/v3/@claude-flow/memory/dist/agent-memory-scope.d.ts +131 -0
  8. package/v3/@claude-flow/memory/dist/agent-memory-scope.js +223 -0
  9. package/v3/@claude-flow/memory/dist/agent-memory-scope.test.d.ts +8 -0
  10. package/v3/@claude-flow/memory/dist/agent-memory-scope.test.js +463 -0
  11. package/v3/@claude-flow/memory/dist/agentdb-adapter.d.ts +165 -0
  12. package/v3/@claude-flow/memory/dist/agentdb-adapter.js +806 -0
  13. package/v3/@claude-flow/memory/dist/agentdb-backend.d.ts +214 -0
  14. package/v3/@claude-flow/memory/dist/agentdb-backend.js +844 -0
  15. package/v3/@claude-flow/memory/dist/agentdb-backend.test.d.ts +7 -0
  16. package/v3/@claude-flow/memory/dist/agentdb-backend.test.js +258 -0
  17. package/v3/@claude-flow/memory/dist/application/commands/delete-memory.command.d.ts +65 -0
  18. package/v3/@claude-flow/memory/dist/application/commands/delete-memory.command.js +129 -0
  19. package/v3/@claude-flow/memory/dist/application/commands/store-memory.command.d.ts +48 -0
  20. package/v3/@claude-flow/memory/dist/application/commands/store-memory.command.js +72 -0
  21. package/v3/@claude-flow/memory/dist/application/index.d.ts +12 -0
  22. package/v3/@claude-flow/memory/dist/application/index.js +15 -0
  23. package/v3/@claude-flow/memory/dist/application/queries/search-memory.query.d.ts +72 -0
  24. package/v3/@claude-flow/memory/dist/application/queries/search-memory.query.js +143 -0
  25. package/v3/@claude-flow/memory/dist/application/services/memory-application-service.d.ts +121 -0
  26. package/v3/@claude-flow/memory/dist/application/services/memory-application-service.js +190 -0
  27. package/v3/@claude-flow/memory/dist/auto-memory-bridge.d.ts +226 -0
  28. package/v3/@claude-flow/memory/dist/auto-memory-bridge.js +709 -0
  29. package/v3/@claude-flow/memory/dist/auto-memory-bridge.test.d.ts +8 -0
  30. package/v3/@claude-flow/memory/dist/auto-memory-bridge.test.js +754 -0
  31. package/v3/@claude-flow/memory/dist/benchmark.test.d.ts +2 -0
  32. package/v3/@claude-flow/memory/dist/benchmark.test.js +277 -0
  33. package/v3/@claude-flow/memory/dist/cache-manager.d.ts +134 -0
  34. package/v3/@claude-flow/memory/dist/cache-manager.js +407 -0
  35. package/v3/@claude-flow/memory/dist/controller-registry.d.ts +216 -0
  36. package/v3/@claude-flow/memory/dist/controller-registry.js +893 -0
  37. package/v3/@claude-flow/memory/dist/controller-registry.test.d.ts +14 -0
  38. package/v3/@claude-flow/memory/dist/controller-registry.test.js +636 -0
  39. package/v3/@claude-flow/memory/dist/database-provider.d.ts +87 -0
  40. package/v3/@claude-flow/memory/dist/database-provider.js +410 -0
  41. package/v3/@claude-flow/memory/dist/database-provider.test.d.ts +7 -0
  42. package/v3/@claude-flow/memory/dist/database-provider.test.js +285 -0
  43. package/v3/@claude-flow/memory/dist/domain/entities/memory-entry.d.ts +143 -0
  44. package/v3/@claude-flow/memory/dist/domain/entities/memory-entry.js +226 -0
  45. package/v3/@claude-flow/memory/dist/domain/index.d.ts +11 -0
  46. package/v3/@claude-flow/memory/dist/domain/index.js +12 -0
  47. package/v3/@claude-flow/memory/dist/domain/repositories/memory-repository.interface.d.ts +102 -0
  48. package/v3/@claude-flow/memory/dist/domain/repositories/memory-repository.interface.js +11 -0
  49. package/v3/@claude-flow/memory/dist/domain/services/memory-domain-service.d.ts +105 -0
  50. package/v3/@claude-flow/memory/dist/domain/services/memory-domain-service.js +297 -0
  51. package/v3/@claude-flow/memory/dist/hnsw-index.d.ts +111 -0
  52. package/v3/@claude-flow/memory/dist/hnsw-index.js +781 -0
  53. package/v3/@claude-flow/memory/dist/hnsw-lite.d.ts +23 -0
  54. package/v3/@claude-flow/memory/dist/hnsw-lite.js +168 -0
  55. package/v3/@claude-flow/memory/dist/hybrid-backend.d.ts +245 -0
  56. package/v3/@claude-flow/memory/dist/hybrid-backend.js +569 -0
  57. package/v3/@claude-flow/memory/dist/hybrid-backend.test.d.ts +8 -0
  58. package/v3/@claude-flow/memory/dist/hybrid-backend.test.js +320 -0
  59. package/v3/@claude-flow/memory/dist/index.d.ts +208 -0
  60. package/v3/@claude-flow/memory/dist/index.js +362 -0
  61. package/v3/@claude-flow/memory/dist/infrastructure/index.d.ts +17 -0
  62. package/v3/@claude-flow/memory/dist/infrastructure/index.js +16 -0
  63. package/v3/@claude-flow/memory/dist/infrastructure/repositories/hybrid-memory-repository.d.ts +66 -0
  64. package/v3/@claude-flow/memory/dist/infrastructure/repositories/hybrid-memory-repository.js +409 -0
  65. package/v3/@claude-flow/memory/dist/learning-bridge.d.ts +137 -0
  66. package/v3/@claude-flow/memory/dist/learning-bridge.js +335 -0
  67. package/v3/@claude-flow/memory/dist/learning-bridge.test.d.ts +8 -0
  68. package/v3/@claude-flow/memory/dist/learning-bridge.test.js +578 -0
  69. package/v3/@claude-flow/memory/dist/memory-graph.d.ts +100 -0
  70. package/v3/@claude-flow/memory/dist/memory-graph.js +333 -0
  71. package/v3/@claude-flow/memory/dist/memory-graph.test.d.ts +8 -0
  72. package/v3/@claude-flow/memory/dist/memory-graph.test.js +609 -0
  73. package/v3/@claude-flow/memory/dist/migration.d.ts +68 -0
  74. package/v3/@claude-flow/memory/dist/migration.js +513 -0
  75. package/v3/@claude-flow/memory/dist/persistent-sona.d.ts +144 -0
  76. package/v3/@claude-flow/memory/dist/persistent-sona.js +332 -0
  77. package/v3/@claude-flow/memory/dist/query-builder.d.ts +211 -0
  78. package/v3/@claude-flow/memory/dist/query-builder.js +438 -0
  79. package/v3/@claude-flow/memory/dist/rvf-backend.d.ts +51 -0
  80. package/v3/@claude-flow/memory/dist/rvf-backend.js +481 -0
  81. package/v3/@claude-flow/memory/dist/rvf-learning-store.d.ts +139 -0
  82. package/v3/@claude-flow/memory/dist/rvf-learning-store.js +295 -0
  83. package/v3/@claude-flow/memory/dist/rvf-migration.d.ts +45 -0
  84. package/v3/@claude-flow/memory/dist/rvf-migration.js +254 -0
  85. package/v3/@claude-flow/memory/dist/sqlite-backend.d.ts +121 -0
  86. package/v3/@claude-flow/memory/dist/sqlite-backend.js +564 -0
  87. package/v3/@claude-flow/memory/dist/sqljs-backend.d.ts +128 -0
  88. package/v3/@claude-flow/memory/dist/sqljs-backend.js +601 -0
  89. package/v3/@claude-flow/memory/dist/types.d.ts +484 -0
  90. package/v3/@claude-flow/memory/dist/types.js +58 -0
  91. package/v3/@claude-flow/memory/package.json +46 -0
@@ -0,0 +1,23 @@
1
+ export interface HnswSearchResult {
2
+ id: string;
3
+ score: number;
4
+ }
5
+ export declare class HnswLite {
6
+ private vectors;
7
+ private neighbors;
8
+ private readonly dimensions;
9
+ private readonly maxNeighbors;
10
+ private readonly efConstruction;
11
+ private readonly metric;
12
+ constructor(dimensions: number, m: number, efConstruction: number, metric: string);
13
+ get size(): number;
14
+ add(id: string, vector: Float32Array): void;
15
+ remove(id: string): void;
16
+ search(query: Float32Array, k: number, threshold?: number): HnswSearchResult[];
17
+ private bruteForce;
18
+ private findNearest;
19
+ private pruneNeighbors;
20
+ private similarity;
21
+ }
22
+ export declare function cosineSimilarity(a: Float32Array, b: Float32Array): number;
23
+ //# sourceMappingURL=hnsw-lite.d.ts.map
@@ -0,0 +1,168 @@
1
+ export class HnswLite {
2
+ vectors = new Map();
3
+ neighbors = new Map();
4
+ dimensions;
5
+ maxNeighbors;
6
+ efConstruction;
7
+ metric;
8
+ constructor(dimensions, m, efConstruction, metric) {
9
+ this.dimensions = dimensions;
10
+ this.maxNeighbors = m;
11
+ this.efConstruction = efConstruction;
12
+ this.metric = metric;
13
+ }
14
+ get size() {
15
+ return this.vectors.size;
16
+ }
17
+ add(id, vector) {
18
+ this.vectors.set(id, vector);
19
+ if (this.vectors.size === 1) {
20
+ this.neighbors.set(id, new Set());
21
+ return;
22
+ }
23
+ const nearest = this.findNearest(vector, this.maxNeighbors);
24
+ const neighborSet = new Set();
25
+ for (const n of nearest) {
26
+ neighborSet.add(n.id);
27
+ const nNeighbors = this.neighbors.get(n.id);
28
+ if (nNeighbors) {
29
+ nNeighbors.add(id);
30
+ if (nNeighbors.size > this.maxNeighbors * 2) {
31
+ this.pruneNeighbors(n.id);
32
+ }
33
+ }
34
+ }
35
+ this.neighbors.set(id, neighborSet);
36
+ }
37
+ remove(id) {
38
+ this.vectors.delete(id);
39
+ const myNeighbors = this.neighbors.get(id);
40
+ if (myNeighbors) {
41
+ for (const nId of myNeighbors) {
42
+ this.neighbors.get(nId)?.delete(id);
43
+ }
44
+ }
45
+ this.neighbors.delete(id);
46
+ }
47
+ search(query, k, threshold) {
48
+ if (this.vectors.size === 0)
49
+ return [];
50
+ if (this.vectors.size <= k * 2) {
51
+ return this.bruteForce(query, k, threshold);
52
+ }
53
+ const visited = new Set();
54
+ const candidates = [];
55
+ let entryId;
56
+ let bestScore = -1;
57
+ for (const [id] of this.vectors) {
58
+ const score = this.similarity(query, this.vectors.get(id));
59
+ if (score > bestScore) {
60
+ bestScore = score;
61
+ entryId = id;
62
+ }
63
+ if (visited.size >= Math.min(this.efConstruction, this.vectors.size))
64
+ break;
65
+ visited.add(id);
66
+ candidates.push({ id, score });
67
+ }
68
+ if (entryId) {
69
+ const queue = [entryId];
70
+ let idx = 0;
71
+ while (idx < queue.length && visited.size < this.efConstruction * 2) {
72
+ const currentId = queue[idx++];
73
+ const currentNeighbors = this.neighbors.get(currentId);
74
+ if (!currentNeighbors)
75
+ continue;
76
+ for (const nId of currentNeighbors) {
77
+ if (visited.has(nId))
78
+ continue;
79
+ visited.add(nId);
80
+ const vec = this.vectors.get(nId);
81
+ if (!vec)
82
+ continue;
83
+ const score = this.similarity(query, vec);
84
+ candidates.push({ id: nId, score });
85
+ queue.push(nId);
86
+ }
87
+ }
88
+ }
89
+ candidates.sort((a, b) => b.score - a.score);
90
+ let filtered = candidates;
91
+ if (threshold !== undefined) {
92
+ filtered = filtered.filter(c => c.score >= threshold);
93
+ }
94
+ return filtered.slice(0, k);
95
+ }
96
+ bruteForce(query, k, threshold) {
97
+ const results = [];
98
+ for (const [id, vec] of this.vectors) {
99
+ const score = this.similarity(query, vec);
100
+ if (threshold !== undefined && score < threshold)
101
+ continue;
102
+ results.push({ id, score });
103
+ }
104
+ results.sort((a, b) => b.score - a.score);
105
+ return results.slice(0, k);
106
+ }
107
+ findNearest(query, k) {
108
+ return this.bruteForce(query, k);
109
+ }
110
+ pruneNeighbors(id) {
111
+ const myNeighbors = this.neighbors.get(id);
112
+ if (!myNeighbors)
113
+ return;
114
+ const vec = this.vectors.get(id);
115
+ if (!vec)
116
+ return;
117
+ const scored = [];
118
+ for (const nId of myNeighbors) {
119
+ const nVec = this.vectors.get(nId);
120
+ if (!nVec)
121
+ continue;
122
+ scored.push({ id: nId, score: this.similarity(vec, nVec) });
123
+ }
124
+ scored.sort((a, b) => b.score - a.score);
125
+ const keep = new Set(scored.slice(0, this.maxNeighbors).map(s => s.id));
126
+ for (const nId of myNeighbors) {
127
+ if (!keep.has(nId)) {
128
+ myNeighbors.delete(nId);
129
+ }
130
+ }
131
+ }
132
+ similarity(a, b) {
133
+ if (this.metric === 'dot')
134
+ return dotProduct(a, b);
135
+ if (this.metric === 'euclidean')
136
+ return 1 / (1 + euclideanDistance(a, b));
137
+ return cosineSimilarity(a, b);
138
+ }
139
+ }
140
+ export function cosineSimilarity(a, b) {
141
+ let dot = 0;
142
+ let normA = 0;
143
+ let normB = 0;
144
+ for (let i = 0; i < a.length; i++) {
145
+ dot += a[i] * b[i];
146
+ normA += a[i] * a[i];
147
+ normB += b[i] * b[i];
148
+ }
149
+ if (normA === 0 || normB === 0)
150
+ return 0;
151
+ return dot / (Math.sqrt(normA) * Math.sqrt(normB));
152
+ }
153
+ function dotProduct(a, b) {
154
+ let sum = 0;
155
+ for (let i = 0; i < a.length; i++) {
156
+ sum += a[i] * b[i];
157
+ }
158
+ return sum;
159
+ }
160
+ function euclideanDistance(a, b) {
161
+ let sum = 0;
162
+ for (let i = 0; i < a.length; i++) {
163
+ const d = a[i] - b[i];
164
+ sum += d * d;
165
+ }
166
+ return Math.sqrt(sum);
167
+ }
168
+ //# sourceMappingURL=hnsw-lite.js.map
@@ -0,0 +1,245 @@
1
+ /**
2
+ * HybridBackend - Combines SQLite (structured queries) + AgentDB (vector search)
3
+ *
4
+ * Per ADR-009: "HybridBackend (SQLite + AgentDB) as default"
5
+ * - SQLite for: Structured queries, ACID transactions, exact matches
6
+ * - AgentDB for: Semantic search, vector similarity, RAG
7
+ *
8
+ * @module v3/memory/hybrid-backend
9
+ */
10
+ import { EventEmitter } from 'node:events';
11
+ import { IMemoryBackend, MemoryEntry, MemoryEntryUpdate, MemoryQuery, SearchOptions, SearchResult, BackendStats, HealthCheckResult, EmbeddingGenerator } from './types.js';
12
+ import { SQLiteBackend, SQLiteBackendConfig } from './sqlite-backend.js';
13
+ import { AgentDBBackend, AgentDBBackendConfig } from './agentdb-backend.js';
14
+ /**
15
+ * Configuration for HybridBackend
16
+ */
17
+ export interface HybridBackendConfig {
18
+ /** SQLite configuration */
19
+ sqlite?: Partial<SQLiteBackendConfig>;
20
+ /** AgentDB configuration */
21
+ agentdb?: Partial<AgentDBBackendConfig>;
22
+ /** Default namespace */
23
+ defaultNamespace?: string;
24
+ /** Embedding generator function */
25
+ embeddingGenerator?: EmbeddingGenerator;
26
+ /** Query routing strategy */
27
+ routingStrategy?: 'auto' | 'sqlite-first' | 'agentdb-first';
28
+ /** Enable dual-write (write to both backends) */
29
+ dualWrite?: boolean;
30
+ /** Semantic search threshold for hybrid queries */
31
+ semanticThreshold?: number;
32
+ /** Maximum results to fetch from each backend in hybrid queries */
33
+ hybridMaxResults?: number;
34
+ }
35
+ /**
36
+ * Structured Query Interface
37
+ * Optimized for SQLite's strengths
38
+ */
39
+ export interface StructuredQuery {
40
+ /** Exact key match */
41
+ key?: string;
42
+ /** Key prefix match */
43
+ keyPrefix?: string;
44
+ /** Namespace filter */
45
+ namespace?: string;
46
+ /** Owner filter */
47
+ ownerId?: string;
48
+ /** Type filter */
49
+ type?: string;
50
+ /** Time range filters */
51
+ createdAfter?: number;
52
+ createdBefore?: number;
53
+ updatedAfter?: number;
54
+ updatedBefore?: number;
55
+ /** Pagination */
56
+ limit?: number;
57
+ offset?: number;
58
+ }
59
+ /**
60
+ * Semantic Query Interface
61
+ * Optimized for AgentDB's vector search
62
+ */
63
+ export interface SemanticQuery {
64
+ /** Content to search for (will be embedded) */
65
+ content?: string;
66
+ /** Pre-computed embedding */
67
+ embedding?: Float32Array;
68
+ /** Number of results */
69
+ k?: number;
70
+ /** Similarity threshold (0-1) */
71
+ threshold?: number;
72
+ /** Additional filters */
73
+ filters?: Partial<MemoryQuery>;
74
+ }
75
+ /**
76
+ * Hybrid Query Interface
77
+ * Combines structured + semantic search
78
+ */
79
+ export interface HybridQuery {
80
+ /** Semantic component */
81
+ semantic: SemanticQuery;
82
+ /** Structured component */
83
+ structured?: StructuredQuery;
84
+ /** How to combine results */
85
+ combineStrategy?: 'union' | 'intersection' | 'semantic-first' | 'structured-first';
86
+ /** Weights for score combination */
87
+ weights?: {
88
+ semantic: number;
89
+ structured: number;
90
+ };
91
+ }
92
+ /**
93
+ * HybridBackend Implementation
94
+ *
95
+ * Intelligently routes queries between SQLite and AgentDB:
96
+ * - Exact matches, prefix queries → SQLite
97
+ * - Semantic search, similarity → AgentDB
98
+ * - Complex hybrid queries → Both backends with intelligent merging
99
+ */
100
+ export declare class HybridBackend extends EventEmitter implements IMemoryBackend {
101
+ private sqlite;
102
+ private agentdb;
103
+ private config;
104
+ private initialized;
105
+ private stats;
106
+ constructor(config?: HybridBackendConfig);
107
+ /**
108
+ * Initialize both backends
109
+ */
110
+ initialize(): Promise<void>;
111
+ /**
112
+ * Shutdown both backends
113
+ */
114
+ shutdown(): Promise<void>;
115
+ /**
116
+ * Store in both backends (dual-write for consistency)
117
+ */
118
+ store(entry: MemoryEntry): Promise<void>;
119
+ /**
120
+ * Get from AgentDB (has caching enabled)
121
+ */
122
+ get(id: string): Promise<MemoryEntry | null>;
123
+ /**
124
+ * Get by key (SQLite optimized for exact matches)
125
+ */
126
+ getByKey(namespace: string, key: string): Promise<MemoryEntry | null>;
127
+ /**
128
+ * Update in both backends
129
+ */
130
+ update(id: string, update: MemoryEntryUpdate): Promise<MemoryEntry | null>;
131
+ /**
132
+ * Delete from both backends
133
+ */
134
+ delete(id: string): Promise<boolean>;
135
+ /**
136
+ * Query routing - semantic goes to AgentDB, structured to SQLite
137
+ */
138
+ query(query: MemoryQuery): Promise<MemoryEntry[]>;
139
+ /**
140
+ * Structured queries (SQL)
141
+ * Routes to SQLite for optimal performance
142
+ */
143
+ queryStructured(query: StructuredQuery): Promise<MemoryEntry[]>;
144
+ /**
145
+ * Semantic queries (vector)
146
+ * Routes to AgentDB for HNSW-based vector search
147
+ */
148
+ querySemantic(query: SemanticQuery): Promise<MemoryEntry[]>;
149
+ /**
150
+ * Hybrid queries (combine both)
151
+ * Intelligently merges results from both backends
152
+ */
153
+ queryHybrid(query: HybridQuery): Promise<MemoryEntry[]>;
154
+ /**
155
+ * Semantic vector search (routes to AgentDB)
156
+ */
157
+ search(embedding: Float32Array, options: SearchOptions): Promise<SearchResult[]>;
158
+ /**
159
+ * Bulk insert to both backends
160
+ */
161
+ bulkInsert(entries: MemoryEntry[]): Promise<void>;
162
+ /**
163
+ * Bulk delete from both backends
164
+ */
165
+ bulkDelete(ids: string[]): Promise<number>;
166
+ /**
167
+ * Count entries (use SQLite for efficiency)
168
+ */
169
+ count(namespace?: string): Promise<number>;
170
+ /**
171
+ * List namespaces (use SQLite)
172
+ */
173
+ listNamespaces(): Promise<string[]>;
174
+ /**
175
+ * Clear namespace in both backends
176
+ */
177
+ clearNamespace(namespace: string): Promise<number>;
178
+ /**
179
+ * Get combined statistics from both backends
180
+ */
181
+ getStats(): Promise<BackendStats>;
182
+ /**
183
+ * Health check for both backends
184
+ */
185
+ healthCheck(): Promise<HealthCheckResult>;
186
+ /**
187
+ * Auto-route queries based on properties
188
+ */
189
+ private autoRoute;
190
+ /**
191
+ * Internal hybrid query implementation
192
+ */
193
+ private queryHybridInternal;
194
+ /**
195
+ * Combine results using union (all unique results)
196
+ */
197
+ private combineUnion;
198
+ /**
199
+ * Combine results using intersection (only common results)
200
+ */
201
+ private combineIntersection;
202
+ /**
203
+ * Semantic-first: Prefer semantic results, add structured if not present
204
+ */
205
+ private combineSemanticFirst;
206
+ /**
207
+ * Structured-first: Prefer structured results, add semantic if not present
208
+ */
209
+ private combineStructuredFirst;
210
+ /**
211
+ * Record feedback for a memory entry.
212
+ * Delegates to AgentDB's recordFeedback when available.
213
+ * Gracefully degrades to a no-op when AgentDB is unavailable.
214
+ */
215
+ recordFeedback(entryId: string, feedback: {
216
+ score: number;
217
+ label?: string;
218
+ context?: Record<string, unknown>;
219
+ }): Promise<boolean>;
220
+ /**
221
+ * Verify a witness chain for a memory entry.
222
+ * Delegates to AgentDB's verifyWitnessChain when available.
223
+ */
224
+ verifyWitnessChain(entryId: string): Promise<{
225
+ valid: boolean;
226
+ chainLength: number;
227
+ errors: string[];
228
+ }>;
229
+ /**
230
+ * Get the witness chain for a memory entry.
231
+ * Delegates to AgentDB's getWitnessChain when available.
232
+ */
233
+ getWitnessChain(entryId: string): Promise<Array<{
234
+ hash: string;
235
+ timestamp: number;
236
+ operation: string;
237
+ }>>;
238
+ /**
239
+ * Get underlying backends for advanced operations
240
+ */
241
+ getSQLiteBackend(): SQLiteBackend;
242
+ getAgentDBBackend(): AgentDBBackend;
243
+ }
244
+ export default HybridBackend;
245
+ //# sourceMappingURL=hybrid-backend.d.ts.map