agentic-qe 2.8.0 → 2.8.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 (142) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +1 -1
  3. package/dist/agents/BaseAgent.d.ts +128 -0
  4. package/dist/agents/BaseAgent.d.ts.map +1 -1
  5. package/dist/agents/BaseAgent.js +256 -0
  6. package/dist/agents/BaseAgent.js.map +1 -1
  7. package/dist/cli/commands/supabase/index.d.ts +20 -0
  8. package/dist/cli/commands/supabase/index.d.ts.map +1 -0
  9. package/dist/cli/commands/supabase/index.js +632 -0
  10. package/dist/cli/commands/supabase/index.js.map +1 -0
  11. package/dist/cli/index.js +3 -0
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/core/memory/HNSWVectorMemory.js +1 -1
  14. package/dist/mcp/handlers/NewDomainToolsHandler.d.ts +8 -8
  15. package/dist/mcp/handlers/NewDomainToolsHandler.d.ts.map +1 -1
  16. package/dist/mcp/handlers/NewDomainToolsHandler.js.map +1 -1
  17. package/dist/mcp/handlers/ruvector/RuVectorHandler.d.ts +54 -0
  18. package/dist/mcp/handlers/ruvector/RuVectorHandler.d.ts.map +1 -0
  19. package/dist/mcp/handlers/ruvector/RuVectorHandler.js +325 -0
  20. package/dist/mcp/handlers/ruvector/RuVectorHandler.js.map +1 -0
  21. package/dist/mcp/handlers/ruvector/index.d.ts +5 -0
  22. package/dist/mcp/handlers/ruvector/index.d.ts.map +1 -0
  23. package/dist/mcp/handlers/ruvector/index.js +9 -0
  24. package/dist/mcp/handlers/ruvector/index.js.map +1 -0
  25. package/dist/mcp/server-instructions.d.ts +1 -1
  26. package/dist/mcp/server-instructions.js +1 -1
  27. package/dist/mcp/server.d.ts.map +1 -1
  28. package/dist/mcp/server.js +100 -22
  29. package/dist/mcp/server.js.map +1 -1
  30. package/dist/nervous-system/adapters/BTSPAdapter.d.ts +342 -0
  31. package/dist/nervous-system/adapters/BTSPAdapter.d.ts.map +1 -0
  32. package/dist/nervous-system/adapters/BTSPAdapter.js +494 -0
  33. package/dist/nervous-system/adapters/BTSPAdapter.js.map +1 -0
  34. package/dist/nervous-system/adapters/CircadianController.d.ts +560 -0
  35. package/dist/nervous-system/adapters/CircadianController.d.ts.map +1 -0
  36. package/dist/nervous-system/adapters/CircadianController.js +882 -0
  37. package/dist/nervous-system/adapters/CircadianController.js.map +1 -0
  38. package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.d.ts +337 -0
  39. package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.d.ts.map +1 -0
  40. package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.js +532 -0
  41. package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.js.map +1 -0
  42. package/dist/nervous-system/adapters/HdcMemoryAdapter.d.ts +444 -0
  43. package/dist/nervous-system/adapters/HdcMemoryAdapter.d.ts.map +1 -0
  44. package/dist/nervous-system/adapters/HdcMemoryAdapter.js +715 -0
  45. package/dist/nervous-system/adapters/HdcMemoryAdapter.js.map +1 -0
  46. package/dist/nervous-system/adapters/ReflexLayer.d.ts +231 -0
  47. package/dist/nervous-system/adapters/ReflexLayer.d.ts.map +1 -0
  48. package/dist/nervous-system/adapters/ReflexLayer.js +309 -0
  49. package/dist/nervous-system/adapters/ReflexLayer.js.map +1 -0
  50. package/dist/nervous-system/index.d.ts +25 -0
  51. package/dist/nervous-system/index.d.ts.map +1 -0
  52. package/dist/nervous-system/index.js +80 -0
  53. package/dist/nervous-system/index.js.map +1 -0
  54. package/dist/nervous-system/integration/BTSPLearningEngine.d.ts +266 -0
  55. package/dist/nervous-system/integration/BTSPLearningEngine.d.ts.map +1 -0
  56. package/dist/nervous-system/integration/BTSPLearningEngine.js +587 -0
  57. package/dist/nervous-system/integration/BTSPLearningEngine.js.map +1 -0
  58. package/dist/nervous-system/integration/CircadianAgent.d.ts +389 -0
  59. package/dist/nervous-system/integration/CircadianAgent.d.ts.map +1 -0
  60. package/dist/nervous-system/integration/CircadianAgent.js +696 -0
  61. package/dist/nervous-system/integration/CircadianAgent.js.map +1 -0
  62. package/dist/nervous-system/integration/HybridPatternStore.d.ts +244 -0
  63. package/dist/nervous-system/integration/HybridPatternStore.d.ts.map +1 -0
  64. package/dist/nervous-system/integration/HybridPatternStore.js +622 -0
  65. package/dist/nervous-system/integration/HybridPatternStore.js.map +1 -0
  66. package/dist/nervous-system/integration/NervousSystemEnhancement.d.ts +459 -0
  67. package/dist/nervous-system/integration/NervousSystemEnhancement.d.ts.map +1 -0
  68. package/dist/nervous-system/integration/NervousSystemEnhancement.js +921 -0
  69. package/dist/nervous-system/integration/NervousSystemEnhancement.js.map +1 -0
  70. package/dist/nervous-system/integration/WorkspaceAgent.d.ts +398 -0
  71. package/dist/nervous-system/integration/WorkspaceAgent.d.ts.map +1 -0
  72. package/dist/nervous-system/integration/WorkspaceAgent.js +722 -0
  73. package/dist/nervous-system/integration/WorkspaceAgent.js.map +1 -0
  74. package/dist/nervous-system/integration/index.d.ts +22 -0
  75. package/dist/nervous-system/integration/index.d.ts.map +1 -0
  76. package/dist/nervous-system/integration/index.js +44 -0
  77. package/dist/nervous-system/integration/index.js.map +1 -0
  78. package/dist/nervous-system/persistence/BTSPSerializer.d.ts +96 -0
  79. package/dist/nervous-system/persistence/BTSPSerializer.d.ts.map +1 -0
  80. package/dist/nervous-system/persistence/BTSPSerializer.js +223 -0
  81. package/dist/nervous-system/persistence/BTSPSerializer.js.map +1 -0
  82. package/dist/nervous-system/persistence/CircadianSerializer.d.ts +90 -0
  83. package/dist/nervous-system/persistence/CircadianSerializer.d.ts.map +1 -0
  84. package/dist/nervous-system/persistence/CircadianSerializer.js +239 -0
  85. package/dist/nervous-system/persistence/CircadianSerializer.js.map +1 -0
  86. package/dist/nervous-system/persistence/HdcSerializer.d.ts +100 -0
  87. package/dist/nervous-system/persistence/HdcSerializer.d.ts.map +1 -0
  88. package/dist/nervous-system/persistence/HdcSerializer.js +259 -0
  89. package/dist/nervous-system/persistence/HdcSerializer.js.map +1 -0
  90. package/dist/nervous-system/persistence/INervousSystemStore.d.ts +208 -0
  91. package/dist/nervous-system/persistence/INervousSystemStore.d.ts.map +1 -0
  92. package/dist/nervous-system/persistence/INervousSystemStore.js +11 -0
  93. package/dist/nervous-system/persistence/INervousSystemStore.js.map +1 -0
  94. package/dist/nervous-system/persistence/NervousSystemPersistenceManager.d.ts +187 -0
  95. package/dist/nervous-system/persistence/NervousSystemPersistenceManager.d.ts.map +1 -0
  96. package/dist/nervous-system/persistence/NervousSystemPersistenceManager.js +411 -0
  97. package/dist/nervous-system/persistence/NervousSystemPersistenceManager.js.map +1 -0
  98. package/dist/nervous-system/persistence/SQLiteNervousSystemStore.d.ts +98 -0
  99. package/dist/nervous-system/persistence/SQLiteNervousSystemStore.d.ts.map +1 -0
  100. package/dist/nervous-system/persistence/SQLiteNervousSystemStore.js +510 -0
  101. package/dist/nervous-system/persistence/SQLiteNervousSystemStore.js.map +1 -0
  102. package/dist/nervous-system/persistence/index.d.ts +22 -0
  103. package/dist/nervous-system/persistence/index.d.ts.map +1 -0
  104. package/dist/nervous-system/persistence/index.js +45 -0
  105. package/dist/nervous-system/persistence/index.js.map +1 -0
  106. package/dist/nervous-system/wasm-loader.d.ts +52 -0
  107. package/dist/nervous-system/wasm-loader.d.ts.map +1 -0
  108. package/dist/nervous-system/wasm-loader.js +188 -0
  109. package/dist/nervous-system/wasm-loader.js.map +1 -0
  110. package/dist/persistence/HybridPersistenceProvider.d.ts +184 -0
  111. package/dist/persistence/HybridPersistenceProvider.d.ts.map +1 -0
  112. package/dist/persistence/HybridPersistenceProvider.js +1086 -0
  113. package/dist/persistence/HybridPersistenceProvider.js.map +1 -0
  114. package/dist/persistence/IPersistenceProvider.d.ts +657 -0
  115. package/dist/persistence/IPersistenceProvider.d.ts.map +1 -0
  116. package/dist/persistence/IPersistenceProvider.js +11 -0
  117. package/dist/persistence/IPersistenceProvider.js.map +1 -0
  118. package/dist/persistence/SupabaseConfig.d.ts +176 -0
  119. package/dist/persistence/SupabaseConfig.d.ts.map +1 -0
  120. package/dist/persistence/SupabaseConfig.js +277 -0
  121. package/dist/persistence/SupabaseConfig.js.map +1 -0
  122. package/dist/persistence/SupabasePersistenceProvider.d.ts +143 -0
  123. package/dist/persistence/SupabasePersistenceProvider.d.ts.map +1 -0
  124. package/dist/persistence/SupabasePersistenceProvider.js +955 -0
  125. package/dist/persistence/SupabasePersistenceProvider.js.map +1 -0
  126. package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.d.ts +213 -0
  127. package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.d.ts.map +1 -0
  128. package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.js +468 -0
  129. package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.js.map +1 -0
  130. package/dist/persistence/adapters/MemorySyncAdapter.d.ts +115 -0
  131. package/dist/persistence/adapters/MemorySyncAdapter.d.ts.map +1 -0
  132. package/dist/persistence/adapters/MemorySyncAdapter.js +291 -0
  133. package/dist/persistence/adapters/MemorySyncAdapter.js.map +1 -0
  134. package/dist/persistence/adapters/index.d.ts +11 -0
  135. package/dist/persistence/adapters/index.d.ts.map +1 -0
  136. package/dist/persistence/adapters/index.js +20 -0
  137. package/dist/persistence/adapters/index.js.map +1 -0
  138. package/dist/persistence/index.d.ts +14 -0
  139. package/dist/persistence/index.d.ts.map +1 -1
  140. package/dist/persistence/index.js +36 -1
  141. package/dist/persistence/index.js.map +1 -1
  142. package/package.json +3 -1
@@ -0,0 +1,955 @@
1
+ "use strict";
2
+ /**
3
+ * Supabase Persistence Provider
4
+ *
5
+ * Cloud persistence provider using Supabase PostgreSQL with RuVector extension.
6
+ * Supports multi-tenant data isolation via Row-Level Security and
7
+ * vector similarity search for intelligent experience/pattern matching.
8
+ *
9
+ * @module persistence/SupabasePersistenceProvider
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SupabasePersistenceProvider = void 0;
13
+ exports.createSupabasePersistenceProvider = createSupabasePersistenceProvider;
14
+ const supabase_js_1 = require("@supabase/supabase-js");
15
+ const SupabaseConfig_js_1 = require("./SupabaseConfig.js");
16
+ // ============================================
17
+ // Provider Implementation
18
+ // ============================================
19
+ /**
20
+ * Supabase cloud persistence provider
21
+ *
22
+ * Implements IPersistenceProvider using Supabase PostgreSQL backend.
23
+ * Features:
24
+ * - Multi-tenant data isolation via RLS
25
+ * - Vector similarity search via RuVector
26
+ * - Automatic embedding generation (optional)
27
+ * - Sharing between users/teams
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const provider = new SupabasePersistenceProvider({
32
+ * connection: {
33
+ * url: 'https://xxx.supabase.co',
34
+ * anonKey: 'xxx',
35
+ * },
36
+ * project: { projectId: 'my-project' },
37
+ * });
38
+ *
39
+ * await provider.initialize();
40
+ *
41
+ * // Store an experience
42
+ * await provider.storeExperience({
43
+ * id: 'exp-1',
44
+ * agentId: 'test-gen',
45
+ * agentType: 'test-generator',
46
+ * taskType: 'unit-test-generation',
47
+ * context: { sourceFile: 'UserService.ts' },
48
+ * outcome: { result: 'success', confidence: 0.95 },
49
+ * privacyLevel: 'team',
50
+ * isAnonymized: false,
51
+ * shareCount: 0,
52
+ * createdAt: new Date(),
53
+ * });
54
+ *
55
+ * // Search for similar experiences
56
+ * const similar = await provider.searchSimilarExperiences(embedding, 10);
57
+ * ```
58
+ */
59
+ class SupabasePersistenceProvider {
60
+ /**
61
+ * Create a new Supabase persistence provider
62
+ *
63
+ * @param configOverrides Configuration overrides
64
+ */
65
+ constructor(configOverrides = {}) {
66
+ this.client = null;
67
+ this.projectId = null;
68
+ this.initialized = false;
69
+ this.config = (0, SupabaseConfig_js_1.buildSupabaseConfig)(configOverrides);
70
+ }
71
+ // ============================================
72
+ // Lifecycle
73
+ // ============================================
74
+ async initialize() {
75
+ if (this.initialized) {
76
+ return;
77
+ }
78
+ // Create Supabase client
79
+ this.client = (0, supabase_js_1.createClient)(this.config.connection.url, this.config.connection.anonKey);
80
+ // Get or create project
81
+ this.projectId = await this.ensureProject();
82
+ this.initialized = true;
83
+ }
84
+ async shutdown() {
85
+ // Supabase client doesn't need explicit cleanup
86
+ this.client = null;
87
+ this.initialized = false;
88
+ }
89
+ // ============================================
90
+ // Learning Experiences
91
+ // ============================================
92
+ async storeExperience(experience) {
93
+ this.ensureInitialized();
94
+ const row = {
95
+ id: experience.id,
96
+ project_id: this.projectId,
97
+ agent_id: experience.agentId,
98
+ agent_type: experience.agentType,
99
+ task_type: experience.taskType,
100
+ context: experience.context,
101
+ outcome: experience.outcome,
102
+ embedding: experience.embedding ?? null,
103
+ privacy_level: experience.privacyLevel,
104
+ is_anonymized: experience.isAnonymized,
105
+ share_count: experience.shareCount,
106
+ confidence: experience.outcome.confidence,
107
+ created_at: experience.createdAt.toISOString(),
108
+ created_by: experience.createdBy ?? null,
109
+ };
110
+ const { error } = await this.client
111
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.EXPERIENCES)
112
+ .upsert(row, { onConflict: 'id' });
113
+ if (error) {
114
+ throw new Error(`Failed to store experience: ${error.message}`);
115
+ }
116
+ }
117
+ async queryExperiences(query) {
118
+ this.ensureInitialized();
119
+ let queryBuilder = this.client
120
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.EXPERIENCES)
121
+ .select('*')
122
+ .eq('project_id', this.projectId);
123
+ // Apply filters
124
+ if (query.agentId) {
125
+ queryBuilder = queryBuilder.eq('agent_id', query.agentId);
126
+ }
127
+ if (query.agentType) {
128
+ queryBuilder = queryBuilder.eq('agent_type', query.agentType);
129
+ }
130
+ if (query.taskType) {
131
+ queryBuilder = queryBuilder.eq('task_type', query.taskType);
132
+ }
133
+ if (query.outcome) {
134
+ queryBuilder = queryBuilder.eq('outcome->result', query.outcome);
135
+ }
136
+ if (query.privacyLevel) {
137
+ queryBuilder = queryBuilder.eq('privacy_level', query.privacyLevel);
138
+ }
139
+ if (query.minConfidence !== undefined) {
140
+ queryBuilder = queryBuilder.gte('confidence', query.minConfidence);
141
+ }
142
+ if (query.startDate) {
143
+ queryBuilder = queryBuilder.gte('created_at', query.startDate.toISOString());
144
+ }
145
+ if (query.endDate) {
146
+ queryBuilder = queryBuilder.lte('created_at', query.endDate.toISOString());
147
+ }
148
+ // Apply pagination
149
+ if (query.offset) {
150
+ queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 50) - 1);
151
+ }
152
+ else if (query.limit) {
153
+ queryBuilder = queryBuilder.limit(query.limit);
154
+ }
155
+ // Order by created_at descending
156
+ queryBuilder = queryBuilder.order('created_at', { ascending: false });
157
+ const { data, error } = await queryBuilder;
158
+ if (error) {
159
+ throw new Error(`Failed to query experiences: ${error.message}`);
160
+ }
161
+ return data.map(this.rowToExperience);
162
+ }
163
+ async searchSimilarExperiences(embedding, limit) {
164
+ this.ensureInitialized();
165
+ // Use RPC function for vector similarity search
166
+ const { data, error } = await this.client.rpc('search_similar_experiences', {
167
+ query_embedding: embedding,
168
+ match_threshold: 0.7,
169
+ match_count: limit,
170
+ });
171
+ if (error) {
172
+ throw new Error(`Failed to search experiences: ${error.message}`);
173
+ }
174
+ // The RPC returns a different shape, map it
175
+ return data.map((row) => ({
176
+ ...this.rowToExperience(row),
177
+ // Could add similarity score to metadata if needed
178
+ }));
179
+ }
180
+ // ============================================
181
+ // Patterns
182
+ // ============================================
183
+ async storePattern(pattern) {
184
+ this.ensureInitialized();
185
+ const row = {
186
+ id: pattern.id,
187
+ project_id: this.projectId,
188
+ type: pattern.type,
189
+ domain: pattern.domain ?? 'general',
190
+ framework: pattern.framework ?? null,
191
+ content: pattern.content ?? '',
192
+ embedding: pattern.embedding ?? null,
193
+ confidence: pattern.confidence,
194
+ usage_count: pattern.usageCount,
195
+ last_used: pattern.lastUsed?.toISOString() ?? null,
196
+ verdict: pattern.verdict ?? null,
197
+ privacy_level: pattern.privacyLevel,
198
+ is_anonymized: pattern.isAnonymized,
199
+ source_hash: pattern.sourceHash ?? null,
200
+ metadata: pattern.metadata,
201
+ created_at: pattern.createdAt.toISOString(),
202
+ };
203
+ const { error } = await this.client
204
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.PATTERNS)
205
+ .upsert(row, { onConflict: 'id' });
206
+ if (error) {
207
+ throw new Error(`Failed to store pattern: ${error.message}`);
208
+ }
209
+ }
210
+ async queryPatterns(query) {
211
+ this.ensureInitialized();
212
+ let queryBuilder = this.client
213
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.PATTERNS)
214
+ .select('*')
215
+ .eq('project_id', this.projectId);
216
+ // Apply filters
217
+ if (query.type) {
218
+ queryBuilder = queryBuilder.eq('type', query.type);
219
+ }
220
+ if (query.domain) {
221
+ queryBuilder = queryBuilder.eq('domain', query.domain);
222
+ }
223
+ if (query.framework) {
224
+ queryBuilder = queryBuilder.eq('framework', query.framework);
225
+ }
226
+ if (query.privacyLevel) {
227
+ queryBuilder = queryBuilder.eq('privacy_level', query.privacyLevel);
228
+ }
229
+ if (query.minConfidence !== undefined) {
230
+ queryBuilder = queryBuilder.gte('confidence', query.minConfidence);
231
+ }
232
+ // Apply pagination
233
+ if (query.offset) {
234
+ queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 50) - 1);
235
+ }
236
+ else if (query.limit) {
237
+ queryBuilder = queryBuilder.limit(query.limit);
238
+ }
239
+ // Order by usage_count descending (most used first)
240
+ queryBuilder = queryBuilder.order('usage_count', { ascending: false });
241
+ const { data, error } = await queryBuilder;
242
+ if (error) {
243
+ throw new Error(`Failed to query patterns: ${error.message}`);
244
+ }
245
+ return data.map(this.rowToPattern);
246
+ }
247
+ async searchSimilarPatterns(embedding, limit) {
248
+ this.ensureInitialized();
249
+ // Use RPC function for vector similarity search
250
+ const { data, error } = await this.client.rpc('search_similar_patterns', {
251
+ query_embedding: embedding,
252
+ match_threshold: 0.7,
253
+ match_count: limit,
254
+ });
255
+ if (error) {
256
+ throw new Error(`Failed to search patterns: ${error.message}`);
257
+ }
258
+ // Map RPC result to StoredPattern
259
+ return data.map(this.rowToPattern);
260
+ }
261
+ // ============================================
262
+ // Nervous System State
263
+ // ============================================
264
+ async saveNervousSystemState(agentId, component, state) {
265
+ this.ensureInitialized();
266
+ const isBinary = state instanceof Uint8Array;
267
+ const row = {
268
+ project_id: this.projectId,
269
+ agent_id: agentId,
270
+ component,
271
+ state_data: isBinary ? this.uint8ArrayToBase64(state) : null,
272
+ state_json: isBinary ? null : state,
273
+ version: 1,
274
+ updated_at: new Date().toISOString(),
275
+ };
276
+ const { error } = await this.client
277
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.NERVOUS_SYSTEM)
278
+ .upsert(row, {
279
+ onConflict: 'project_id,agent_id,component',
280
+ });
281
+ if (error) {
282
+ throw new Error(`Failed to save nervous system state: ${error.message}`);
283
+ }
284
+ }
285
+ async loadNervousSystemState(agentId, component) {
286
+ this.ensureInitialized();
287
+ const { data, error } = await this.client
288
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.NERVOUS_SYSTEM)
289
+ .select('*')
290
+ .eq('project_id', this.projectId)
291
+ .eq('agent_id', agentId)
292
+ .eq('component', component)
293
+ .single();
294
+ if (error) {
295
+ if (error.code === 'PGRST116') {
296
+ // No rows returned
297
+ return null;
298
+ }
299
+ throw new Error(`Failed to load nervous system state: ${error.message}`);
300
+ }
301
+ const row = data;
302
+ if (row.state_data) {
303
+ return this.base64ToUint8Array(row.state_data);
304
+ }
305
+ return row.state_json;
306
+ }
307
+ async deleteNervousSystemState(agentId) {
308
+ this.ensureInitialized();
309
+ const { error } = await this.client
310
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.NERVOUS_SYSTEM)
311
+ .delete()
312
+ .eq('project_id', this.projectId)
313
+ .eq('agent_id', agentId);
314
+ if (error) {
315
+ throw new Error(`Failed to delete nervous system state: ${error.message}`);
316
+ }
317
+ }
318
+ async listAgentsWithState() {
319
+ this.ensureInitialized();
320
+ const { data, error } = await this.client
321
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.NERVOUS_SYSTEM)
322
+ .select('agent_id')
323
+ .eq('project_id', this.projectId);
324
+ if (error) {
325
+ throw new Error(`Failed to list agents: ${error.message}`);
326
+ }
327
+ // Get unique agent IDs
328
+ const agentIds = new Set(data.map((r) => r.agent_id));
329
+ return Array.from(agentIds);
330
+ }
331
+ // ============================================
332
+ // Sharing (Cloud-specific)
333
+ // ============================================
334
+ async shareExperience(experienceId, privacyLevel) {
335
+ this.ensureInitialized();
336
+ const { error } = await this.client
337
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.EXPERIENCES)
338
+ .update({
339
+ privacy_level: privacyLevel,
340
+ share_count: this.client.rpc('increment_share_count'),
341
+ })
342
+ .eq('id', experienceId)
343
+ .eq('project_id', this.projectId);
344
+ if (error) {
345
+ throw new Error(`Failed to share experience: ${error.message}`);
346
+ }
347
+ }
348
+ async importSharedExperiences(query) {
349
+ this.ensureInitialized();
350
+ let queryBuilder = this.client
351
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.EXPERIENCES)
352
+ .select('*');
353
+ // Build privacy filter
354
+ const privacyFilters = [];
355
+ if (query.includePublic) {
356
+ privacyFilters.push('public');
357
+ }
358
+ if (query.includeTeam) {
359
+ privacyFilters.push('team');
360
+ }
361
+ if (privacyFilters.length > 0) {
362
+ queryBuilder = queryBuilder.in('privacy_level', privacyFilters);
363
+ }
364
+ // Exclude own project's experiences
365
+ queryBuilder = queryBuilder.neq('project_id', this.projectId);
366
+ // Apply other filters
367
+ if (query.agentType) {
368
+ queryBuilder = queryBuilder.eq('agent_type', query.agentType);
369
+ }
370
+ if (query.taskType) {
371
+ queryBuilder = queryBuilder.eq('task_type', query.taskType);
372
+ }
373
+ if (query.minQuality !== undefined) {
374
+ queryBuilder = queryBuilder.gte('confidence', query.minQuality);
375
+ }
376
+ // Apply pagination
377
+ if (query.limit) {
378
+ queryBuilder = queryBuilder.limit(query.limit);
379
+ }
380
+ const { data, error } = await queryBuilder;
381
+ if (error) {
382
+ throw new Error(`Failed to import shared experiences: ${error.message}`);
383
+ }
384
+ return data.map(this.rowToExperience);
385
+ }
386
+ async sharePattern(patternId, privacyLevel) {
387
+ this.ensureInitialized();
388
+ const { error } = await this.client
389
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.PATTERNS)
390
+ .update({ privacy_level: privacyLevel })
391
+ .eq('id', patternId)
392
+ .eq('project_id', this.projectId);
393
+ if (error) {
394
+ throw new Error(`Failed to share pattern: ${error.message}`);
395
+ }
396
+ }
397
+ async importSharedPatterns(query) {
398
+ this.ensureInitialized();
399
+ let queryBuilder = this.client
400
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.PATTERNS)
401
+ .select('*');
402
+ // Only public patterns for import
403
+ if (query.includePublic) {
404
+ queryBuilder = queryBuilder.eq('privacy_level', 'public');
405
+ }
406
+ // Exclude own project
407
+ queryBuilder = queryBuilder.neq('project_id', this.projectId);
408
+ // Apply filters
409
+ if (query.type) {
410
+ queryBuilder = queryBuilder.eq('type', query.type);
411
+ }
412
+ if (query.domain) {
413
+ queryBuilder = queryBuilder.eq('domain', query.domain);
414
+ }
415
+ if (query.framework) {
416
+ queryBuilder = queryBuilder.eq('framework', query.framework);
417
+ }
418
+ if (query.minConfidence !== undefined) {
419
+ queryBuilder = queryBuilder.gte('confidence', query.minConfidence);
420
+ }
421
+ // Apply pagination
422
+ if (query.limit) {
423
+ queryBuilder = queryBuilder.limit(query.limit);
424
+ }
425
+ const { data, error } = await queryBuilder;
426
+ if (error) {
427
+ throw new Error(`Failed to import shared patterns: ${error.message}`);
428
+ }
429
+ return data.map(this.rowToPattern);
430
+ }
431
+ // ============================================
432
+ // Memory Entries
433
+ // ============================================
434
+ async storeMemoryEntry(entry) {
435
+ this.ensureInitialized();
436
+ const row = {
437
+ project_id: this.projectId,
438
+ key: entry.key,
439
+ partition: entry.partition,
440
+ value: entry.value,
441
+ owner: entry.owner,
442
+ access_level: entry.accessLevel,
443
+ team_id: entry.teamId ?? null,
444
+ swarm_id: entry.swarmId ?? null,
445
+ metadata: entry.metadata ?? null,
446
+ created_at: entry.createdAt.toISOString(),
447
+ expires_at: entry.expiresAt?.toISOString() ?? null,
448
+ };
449
+ const { error } = await this.client
450
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
451
+ .upsert(row, { onConflict: 'project_id,partition,key' });
452
+ if (error) {
453
+ throw new Error(`Failed to store memory entry: ${error.message}`);
454
+ }
455
+ }
456
+ async storeMemoryEntries(entries) {
457
+ if (entries.length === 0)
458
+ return;
459
+ this.ensureInitialized();
460
+ const rows = entries.map((entry) => ({
461
+ project_id: this.projectId,
462
+ key: entry.key,
463
+ partition: entry.partition,
464
+ value: entry.value,
465
+ owner: entry.owner,
466
+ access_level: entry.accessLevel,
467
+ team_id: entry.teamId ?? null,
468
+ swarm_id: entry.swarmId ?? null,
469
+ metadata: entry.metadata ?? null,
470
+ created_at: entry.createdAt.toISOString(),
471
+ expires_at: entry.expiresAt?.toISOString() ?? null,
472
+ }));
473
+ const { error } = await this.client
474
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
475
+ .upsert(rows, { onConflict: 'project_id,partition,key' });
476
+ if (error) {
477
+ throw new Error(`Failed to store memory entries: ${error.message}`);
478
+ }
479
+ }
480
+ async getMemoryEntry(key, partition = 'default') {
481
+ this.ensureInitialized();
482
+ const { data, error } = await this.client
483
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
484
+ .select('*')
485
+ .eq('project_id', this.projectId)
486
+ .eq('partition', partition)
487
+ .eq('key', key)
488
+ .single();
489
+ if (error) {
490
+ if (error.code === 'PGRST116') {
491
+ return null;
492
+ }
493
+ throw new Error(`Failed to get memory entry: ${error.message}`);
494
+ }
495
+ return this.rowToMemoryEntry(data);
496
+ }
497
+ async queryMemoryEntries(query) {
498
+ this.ensureInitialized();
499
+ let queryBuilder = this.client
500
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
501
+ .select('*')
502
+ .eq('project_id', this.projectId);
503
+ if (query.partition) {
504
+ queryBuilder = queryBuilder.eq('partition', query.partition);
505
+ }
506
+ if (query.owner) {
507
+ queryBuilder = queryBuilder.eq('owner', query.owner);
508
+ }
509
+ if (query.keyPattern) {
510
+ queryBuilder = queryBuilder.ilike('key', query.keyPattern.replace('*', '%'));
511
+ }
512
+ if (query.accessLevel) {
513
+ queryBuilder = queryBuilder.eq('access_level', query.accessLevel);
514
+ }
515
+ if (!query.includeExpired) {
516
+ queryBuilder = queryBuilder.or('expires_at.is.null,expires_at.gt.now()');
517
+ }
518
+ if (query.offset) {
519
+ queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 100) - 1);
520
+ }
521
+ else if (query.limit) {
522
+ queryBuilder = queryBuilder.limit(query.limit);
523
+ }
524
+ const { data, error } = await queryBuilder;
525
+ if (error) {
526
+ throw new Error(`Failed to query memory entries: ${error.message}`);
527
+ }
528
+ return data.map(this.rowToMemoryEntry);
529
+ }
530
+ async deleteMemoryEntries(keyPattern, partition) {
531
+ this.ensureInitialized();
532
+ let queryBuilder = this.client
533
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
534
+ .delete()
535
+ .eq('project_id', this.projectId)
536
+ .ilike('key', keyPattern.replace('*', '%'));
537
+ if (partition) {
538
+ queryBuilder = queryBuilder.eq('partition', partition);
539
+ }
540
+ const { data, error } = await queryBuilder.select('id');
541
+ if (error) {
542
+ throw new Error(`Failed to delete memory entries: ${error.message}`);
543
+ }
544
+ return data.length;
545
+ }
546
+ // ============================================
547
+ // Events
548
+ // ============================================
549
+ async storeEvent(event) {
550
+ this.ensureInitialized();
551
+ const row = {
552
+ id: event.id,
553
+ project_id: this.projectId,
554
+ type: event.type,
555
+ payload: event.payload,
556
+ source: event.source,
557
+ timestamp: event.timestamp.toISOString(),
558
+ ttl: event.ttl,
559
+ };
560
+ const { error } = await this.client
561
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.EVENTS)
562
+ .insert(row);
563
+ if (error) {
564
+ throw new Error(`Failed to store event: ${error.message}`);
565
+ }
566
+ }
567
+ async storeEvents(events) {
568
+ if (events.length === 0)
569
+ return;
570
+ this.ensureInitialized();
571
+ const rows = events.map((event) => ({
572
+ id: event.id,
573
+ project_id: this.projectId,
574
+ type: event.type,
575
+ payload: event.payload,
576
+ source: event.source,
577
+ timestamp: event.timestamp.toISOString(),
578
+ ttl: event.ttl,
579
+ }));
580
+ const { error } = await this.client
581
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.EVENTS)
582
+ .insert(rows);
583
+ if (error) {
584
+ throw new Error(`Failed to store events: ${error.message}`);
585
+ }
586
+ }
587
+ async queryEvents(query) {
588
+ this.ensureInitialized();
589
+ let queryBuilder = this.client
590
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.EVENTS)
591
+ .select('*')
592
+ .eq('project_id', this.projectId);
593
+ if (query.type) {
594
+ queryBuilder = queryBuilder.eq('type', query.type);
595
+ }
596
+ if (query.source) {
597
+ queryBuilder = queryBuilder.eq('source', query.source);
598
+ }
599
+ if (query.startTime) {
600
+ queryBuilder = queryBuilder.gte('timestamp', query.startTime.toISOString());
601
+ }
602
+ if (query.endTime) {
603
+ queryBuilder = queryBuilder.lte('timestamp', query.endTime.toISOString());
604
+ }
605
+ queryBuilder = queryBuilder.order('timestamp', { ascending: false });
606
+ if (query.offset) {
607
+ queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 100) - 1);
608
+ }
609
+ else if (query.limit) {
610
+ queryBuilder = queryBuilder.limit(query.limit);
611
+ }
612
+ const { data, error } = await queryBuilder;
613
+ if (error) {
614
+ throw new Error(`Failed to query events: ${error.message}`);
615
+ }
616
+ return data.map(this.rowToEvent);
617
+ }
618
+ async deleteOldEvents(olderThan) {
619
+ this.ensureInitialized();
620
+ const { data, error } = await this.client
621
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.EVENTS)
622
+ .delete()
623
+ .eq('project_id', this.projectId)
624
+ .lt('timestamp', olderThan.toISOString())
625
+ .select('id');
626
+ if (error) {
627
+ throw new Error(`Failed to delete old events: ${error.message}`);
628
+ }
629
+ return data.length;
630
+ }
631
+ // ============================================
632
+ // Code Chunks
633
+ // ============================================
634
+ async storeCodeChunk(chunk) {
635
+ this.ensureInitialized();
636
+ const row = {
637
+ id: chunk.id,
638
+ project_id: this.projectId,
639
+ file_path: chunk.filePath,
640
+ start_line: chunk.startLine,
641
+ end_line: chunk.endLine,
642
+ chunk_type: chunk.chunkType,
643
+ name: chunk.name ?? null,
644
+ language: chunk.language,
645
+ content: chunk.content,
646
+ embedding: chunk.embedding ?? null,
647
+ metadata: chunk.metadata ?? null,
648
+ commit_sha: chunk.commitSha ?? null,
649
+ indexed_at: chunk.indexedAt.toISOString(),
650
+ };
651
+ const { error } = await this.client
652
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
653
+ .upsert(row, { onConflict: 'project_id,file_path,start_line,end_line' });
654
+ if (error) {
655
+ throw new Error(`Failed to store code chunk: ${error.message}`);
656
+ }
657
+ }
658
+ async storeCodeChunks(chunks) {
659
+ if (chunks.length === 0)
660
+ return;
661
+ this.ensureInitialized();
662
+ const rows = chunks.map((chunk) => ({
663
+ id: chunk.id,
664
+ project_id: this.projectId,
665
+ file_path: chunk.filePath,
666
+ start_line: chunk.startLine,
667
+ end_line: chunk.endLine,
668
+ chunk_type: chunk.chunkType,
669
+ name: chunk.name ?? null,
670
+ language: chunk.language,
671
+ content: chunk.content,
672
+ embedding: chunk.embedding ?? null,
673
+ metadata: chunk.metadata ?? null,
674
+ commit_sha: chunk.commitSha ?? null,
675
+ indexed_at: chunk.indexedAt.toISOString(),
676
+ }));
677
+ const { error } = await this.client
678
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
679
+ .upsert(rows, { onConflict: 'project_id,file_path,start_line,end_line' });
680
+ if (error) {
681
+ throw new Error(`Failed to store code chunks: ${error.message}`);
682
+ }
683
+ }
684
+ async queryCodeChunks(query) {
685
+ this.ensureInitialized();
686
+ let queryBuilder = this.client
687
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
688
+ .select('*')
689
+ .eq('project_id', query.projectId ?? this.projectId);
690
+ if (query.filePattern) {
691
+ queryBuilder = queryBuilder.ilike('file_path', query.filePattern.replace('*', '%'));
692
+ }
693
+ if (query.chunkType) {
694
+ queryBuilder = queryBuilder.eq('chunk_type', query.chunkType);
695
+ }
696
+ if (query.language) {
697
+ queryBuilder = queryBuilder.eq('language', query.language);
698
+ }
699
+ if (query.namePattern) {
700
+ queryBuilder = queryBuilder.ilike('name', query.namePattern.replace('*', '%'));
701
+ }
702
+ if (query.offset) {
703
+ queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 100) - 1);
704
+ }
705
+ else if (query.limit) {
706
+ queryBuilder = queryBuilder.limit(query.limit);
707
+ }
708
+ const { data, error } = await queryBuilder;
709
+ if (error) {
710
+ throw new Error(`Failed to query code chunks: ${error.message}`);
711
+ }
712
+ return data.map(this.rowToCodeChunk);
713
+ }
714
+ async searchSimilarCode(embedding, options) {
715
+ this.ensureInitialized();
716
+ const { data, error } = await this.client.rpc('search_similar_code', {
717
+ query_embedding: embedding,
718
+ match_threshold: options?.minScore ?? 0.7,
719
+ match_count: options?.limit ?? 10,
720
+ filter_project_id: options?.projectId ?? this.projectId,
721
+ filter_language: options?.language ?? null,
722
+ });
723
+ if (error) {
724
+ throw new Error(`Failed to search similar code: ${error.message}`);
725
+ }
726
+ return data.map((row) => ({
727
+ chunk: this.rowToCodeChunk(row),
728
+ score: row.similarity,
729
+ }));
730
+ }
731
+ async deleteCodeChunksForFile(projectId, filePath) {
732
+ this.ensureInitialized();
733
+ const { data, error } = await this.client
734
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
735
+ .delete()
736
+ .eq('project_id', projectId)
737
+ .eq('file_path', filePath)
738
+ .select('id');
739
+ if (error) {
740
+ throw new Error(`Failed to delete code chunks for file: ${error.message}`);
741
+ }
742
+ return data.length;
743
+ }
744
+ async deleteCodeChunksForProject(projectId) {
745
+ this.ensureInitialized();
746
+ const { data, error } = await this.client
747
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
748
+ .delete()
749
+ .eq('project_id', projectId)
750
+ .select('id');
751
+ if (error) {
752
+ throw new Error(`Failed to delete code chunks for project: ${error.message}`);
753
+ }
754
+ return data.length;
755
+ }
756
+ // ============================================
757
+ // Info
758
+ // ============================================
759
+ getProviderInfo() {
760
+ return {
761
+ type: 'supabase',
762
+ features: [
763
+ 'cloud-persistence',
764
+ 'vector-search',
765
+ 'multi-tenant',
766
+ 'rls-security',
767
+ 'experience-sharing',
768
+ 'pattern-sharing',
769
+ 'real-time-sync',
770
+ 'memory-sync',
771
+ 'event-sync',
772
+ 'code-intelligence-sync',
773
+ ],
774
+ initialized: this.initialized,
775
+ location: this.config.connection.url,
776
+ };
777
+ }
778
+ // ============================================
779
+ // Private Methods
780
+ // ============================================
781
+ ensureInitialized() {
782
+ if (!this.initialized || !this.client) {
783
+ throw new Error('SupabasePersistenceProvider not initialized. Call initialize() first.');
784
+ }
785
+ }
786
+ /**
787
+ * Get or create the project for this provider
788
+ */
789
+ async ensureProject() {
790
+ // If project ID is configured, use it
791
+ if (this.config.project.projectId) {
792
+ return this.config.project.projectId;
793
+ }
794
+ // Try to get current user's default project
795
+ const { data: user } = await this.client.auth.getUser();
796
+ if (user?.user) {
797
+ const { data: projects } = await this.client
798
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.PROJECTS)
799
+ .select('id')
800
+ .eq('owner_id', user.user.id)
801
+ .limit(1);
802
+ if (projects && projects.length > 0) {
803
+ return projects[0].id;
804
+ }
805
+ // Create a default project
806
+ const { data: newProject, error } = await this.client
807
+ .from(SupabaseConfig_js_1.SUPABASE_TABLES.PROJECTS)
808
+ .insert({
809
+ name: 'Default Project',
810
+ owner_id: user.user.id,
811
+ settings: this.config.sharing,
812
+ })
813
+ .select('id')
814
+ .single();
815
+ if (error) {
816
+ throw new Error(`Failed to create project: ${error.message}`);
817
+ }
818
+ return newProject.id;
819
+ }
820
+ // For anonymous usage, generate a local project ID
821
+ return `local-${Date.now()}`;
822
+ }
823
+ /**
824
+ * Convert database row to LearningExperience
825
+ */
826
+ rowToExperience(row) {
827
+ return {
828
+ id: row.id,
829
+ agentId: row.agent_id,
830
+ agentType: row.agent_type,
831
+ taskType: row.task_type,
832
+ context: row.context,
833
+ outcome: row.outcome,
834
+ embedding: row.embedding ?? undefined,
835
+ privacyLevel: row.privacy_level,
836
+ isAnonymized: row.is_anonymized,
837
+ shareCount: row.share_count,
838
+ createdAt: new Date(row.created_at),
839
+ createdBy: row.created_by ?? undefined,
840
+ };
841
+ }
842
+ /**
843
+ * Convert database row to StoredPattern
844
+ */
845
+ rowToPattern(row) {
846
+ return {
847
+ id: row.id,
848
+ projectId: row.project_id,
849
+ type: row.type,
850
+ domain: row.domain,
851
+ framework: row.framework ?? undefined,
852
+ content: row.content,
853
+ embedding: row.embedding ?? undefined,
854
+ confidence: row.confidence,
855
+ usageCount: row.usage_count,
856
+ lastUsed: row.last_used ? new Date(row.last_used) : undefined,
857
+ verdict: row.verdict ?? undefined,
858
+ privacyLevel: row.privacy_level,
859
+ isAnonymized: row.is_anonymized,
860
+ sourceHash: row.source_hash ?? undefined,
861
+ metadata: row.metadata,
862
+ createdAt: new Date(row.created_at),
863
+ };
864
+ }
865
+ /**
866
+ * Convert database row to MemoryEntry
867
+ */
868
+ rowToMemoryEntry(row) {
869
+ return {
870
+ key: row.key,
871
+ value: row.value,
872
+ partition: row.partition,
873
+ owner: row.owner,
874
+ accessLevel: row.access_level,
875
+ teamId: row.team_id ?? undefined,
876
+ swarmId: row.swarm_id ?? undefined,
877
+ metadata: row.metadata ?? undefined,
878
+ createdAt: new Date(row.created_at),
879
+ expiresAt: row.expires_at ? new Date(row.expires_at) : null,
880
+ };
881
+ }
882
+ /**
883
+ * Convert database row to EventRecord
884
+ */
885
+ rowToEvent(row) {
886
+ return {
887
+ id: row.id,
888
+ type: row.type,
889
+ payload: row.payload,
890
+ source: row.source,
891
+ timestamp: new Date(row.timestamp),
892
+ ttl: row.ttl,
893
+ };
894
+ }
895
+ /**
896
+ * Convert database row to CodeChunk
897
+ */
898
+ rowToCodeChunk(row) {
899
+ return {
900
+ id: row.id,
901
+ projectId: row.project_id,
902
+ filePath: row.file_path,
903
+ startLine: row.start_line,
904
+ endLine: row.end_line,
905
+ chunkType: row.chunk_type,
906
+ name: row.name ?? undefined,
907
+ language: row.language,
908
+ content: row.content,
909
+ embedding: row.embedding ?? undefined,
910
+ metadata: row.metadata ?? undefined,
911
+ commitSha: row.commit_sha ?? undefined,
912
+ indexedAt: new Date(row.indexed_at),
913
+ };
914
+ }
915
+ /**
916
+ * Convert Uint8Array to base64 string for storage
917
+ */
918
+ uint8ArrayToBase64(data) {
919
+ if (typeof Buffer !== 'undefined') {
920
+ return Buffer.from(data).toString('base64');
921
+ }
922
+ // Browser fallback
923
+ let binary = '';
924
+ for (let i = 0; i < data.length; i++) {
925
+ binary += String.fromCharCode(data[i]);
926
+ }
927
+ return btoa(binary);
928
+ }
929
+ /**
930
+ * Convert base64 string back to Uint8Array
931
+ */
932
+ base64ToUint8Array(base64) {
933
+ if (typeof Buffer !== 'undefined') {
934
+ return new Uint8Array(Buffer.from(base64, 'base64'));
935
+ }
936
+ // Browser fallback
937
+ const binary = atob(base64);
938
+ const bytes = new Uint8Array(binary.length);
939
+ for (let i = 0; i < binary.length; i++) {
940
+ bytes[i] = binary.charCodeAt(i);
941
+ }
942
+ return bytes;
943
+ }
944
+ }
945
+ exports.SupabasePersistenceProvider = SupabasePersistenceProvider;
946
+ /**
947
+ * Factory function to create a Supabase persistence provider
948
+ *
949
+ * @param config Configuration overrides
950
+ * @returns Configured provider instance
951
+ */
952
+ function createSupabasePersistenceProvider(config = {}) {
953
+ return new SupabasePersistenceProvider(config);
954
+ }
955
+ //# sourceMappingURL=SupabasePersistenceProvider.js.map