agentic-qe 2.8.0 → 2.8.2

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 (226) hide show
  1. package/CHANGELOG.md +148 -0
  2. package/README.md +1 -1
  3. package/dist/agents/BaseAgent.d.ts +329 -0
  4. package/dist/agents/BaseAgent.d.ts.map +1 -1
  5. package/dist/agents/BaseAgent.js +657 -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/code-intelligence/embeddings/EmbeddingCacheFactory.d.ts +135 -0
  14. package/dist/code-intelligence/embeddings/EmbeddingCacheFactory.d.ts.map +1 -0
  15. package/dist/code-intelligence/embeddings/EmbeddingCacheFactory.js +301 -0
  16. package/dist/code-intelligence/embeddings/EmbeddingCacheFactory.js.map +1 -0
  17. package/dist/code-intelligence/embeddings/NomicEmbedder.d.ts +78 -6
  18. package/dist/code-intelligence/embeddings/NomicEmbedder.d.ts.map +1 -1
  19. package/dist/code-intelligence/embeddings/NomicEmbedder.js +162 -21
  20. package/dist/code-intelligence/embeddings/NomicEmbedder.js.map +1 -1
  21. package/dist/code-intelligence/embeddings/backends/MemoryBackend.d.ts +59 -0
  22. package/dist/code-intelligence/embeddings/backends/MemoryBackend.d.ts.map +1 -0
  23. package/dist/code-intelligence/embeddings/backends/MemoryBackend.js +173 -0
  24. package/dist/code-intelligence/embeddings/backends/MemoryBackend.js.map +1 -0
  25. package/dist/code-intelligence/embeddings/backends/RedisBackend.d.ts +50 -0
  26. package/dist/code-intelligence/embeddings/backends/RedisBackend.d.ts.map +1 -0
  27. package/dist/code-intelligence/embeddings/backends/RedisBackend.js +279 -0
  28. package/dist/code-intelligence/embeddings/backends/RedisBackend.js.map +1 -0
  29. package/dist/code-intelligence/embeddings/backends/SQLiteBackend.d.ts +64 -0
  30. package/dist/code-intelligence/embeddings/backends/SQLiteBackend.d.ts.map +1 -0
  31. package/dist/code-intelligence/embeddings/backends/SQLiteBackend.js +314 -0
  32. package/dist/code-intelligence/embeddings/backends/SQLiteBackend.js.map +1 -0
  33. package/dist/code-intelligence/embeddings/backends/index.d.ts +16 -0
  34. package/dist/code-intelligence/embeddings/backends/index.d.ts.map +1 -0
  35. package/dist/code-intelligence/embeddings/backends/index.js +28 -0
  36. package/dist/code-intelligence/embeddings/backends/index.js.map +1 -0
  37. package/dist/code-intelligence/embeddings/backends/types.d.ts +177 -0
  38. package/dist/code-intelligence/embeddings/backends/types.d.ts.map +1 -0
  39. package/dist/code-intelligence/embeddings/backends/types.js +30 -0
  40. package/dist/code-intelligence/embeddings/backends/types.js.map +1 -0
  41. package/dist/code-intelligence/embeddings/index.d.ts +7 -0
  42. package/dist/code-intelligence/embeddings/index.d.ts.map +1 -1
  43. package/dist/code-intelligence/embeddings/index.js +16 -1
  44. package/dist/code-intelligence/embeddings/index.js.map +1 -1
  45. package/dist/core/memory/HNSWVectorMemory.js +1 -1
  46. package/dist/infrastructure/index.d.ts +15 -0
  47. package/dist/infrastructure/index.d.ts.map +1 -0
  48. package/dist/infrastructure/index.js +44 -0
  49. package/dist/infrastructure/index.js.map +1 -0
  50. package/dist/infrastructure/network/AgentRateLimiter.d.ts +59 -0
  51. package/dist/infrastructure/network/AgentRateLimiter.d.ts.map +1 -0
  52. package/dist/infrastructure/network/AgentRateLimiter.js +186 -0
  53. package/dist/infrastructure/network/AgentRateLimiter.js.map +1 -0
  54. package/dist/infrastructure/network/AuditLogger.d.ts +102 -0
  55. package/dist/infrastructure/network/AuditLogger.d.ts.map +1 -0
  56. package/dist/infrastructure/network/AuditLogger.js +284 -0
  57. package/dist/infrastructure/network/AuditLogger.js.map +1 -0
  58. package/dist/infrastructure/network/DomainWhitelist.d.ts +111 -0
  59. package/dist/infrastructure/network/DomainWhitelist.d.ts.map +1 -0
  60. package/dist/infrastructure/network/DomainWhitelist.js +216 -0
  61. package/dist/infrastructure/network/DomainWhitelist.js.map +1 -0
  62. package/dist/infrastructure/network/NetworkPolicyManager.d.ts +97 -0
  63. package/dist/infrastructure/network/NetworkPolicyManager.d.ts.map +1 -0
  64. package/dist/infrastructure/network/NetworkPolicyManager.js +309 -0
  65. package/dist/infrastructure/network/NetworkPolicyManager.js.map +1 -0
  66. package/dist/infrastructure/network/index.d.ts +19 -0
  67. package/dist/infrastructure/network/index.d.ts.map +1 -0
  68. package/dist/infrastructure/network/index.js +46 -0
  69. package/dist/infrastructure/network/index.js.map +1 -0
  70. package/dist/infrastructure/network/policies/default-policies.d.ts +78 -0
  71. package/dist/infrastructure/network/policies/default-policies.d.ts.map +1 -0
  72. package/dist/infrastructure/network/policies/default-policies.js +312 -0
  73. package/dist/infrastructure/network/policies/default-policies.js.map +1 -0
  74. package/dist/infrastructure/network/types.d.ts +214 -0
  75. package/dist/infrastructure/network/types.d.ts.map +1 -0
  76. package/dist/infrastructure/network/types.js +25 -0
  77. package/dist/infrastructure/network/types.js.map +1 -0
  78. package/dist/infrastructure/sandbox/ResourceMonitor.d.ts +124 -0
  79. package/dist/infrastructure/sandbox/ResourceMonitor.d.ts.map +1 -0
  80. package/dist/infrastructure/sandbox/ResourceMonitor.js +305 -0
  81. package/dist/infrastructure/sandbox/ResourceMonitor.js.map +1 -0
  82. package/dist/infrastructure/sandbox/SandboxManager.d.ts +122 -0
  83. package/dist/infrastructure/sandbox/SandboxManager.d.ts.map +1 -0
  84. package/dist/infrastructure/sandbox/SandboxManager.js +527 -0
  85. package/dist/infrastructure/sandbox/SandboxManager.js.map +1 -0
  86. package/dist/infrastructure/sandbox/index.d.ts +18 -0
  87. package/dist/infrastructure/sandbox/index.d.ts.map +1 -0
  88. package/dist/infrastructure/sandbox/index.js +38 -0
  89. package/dist/infrastructure/sandbox/index.js.map +1 -0
  90. package/dist/infrastructure/sandbox/profiles/agent-profiles.d.ts +53 -0
  91. package/dist/infrastructure/sandbox/profiles/agent-profiles.d.ts.map +1 -0
  92. package/dist/infrastructure/sandbox/profiles/agent-profiles.js +433 -0
  93. package/dist/infrastructure/sandbox/profiles/agent-profiles.js.map +1 -0
  94. package/dist/infrastructure/sandbox/types.d.ts +227 -0
  95. package/dist/infrastructure/sandbox/types.d.ts.map +1 -0
  96. package/dist/infrastructure/sandbox/types.js +63 -0
  97. package/dist/infrastructure/sandbox/types.js.map +1 -0
  98. package/dist/mcp/handlers/NewDomainToolsHandler.d.ts +8 -8
  99. package/dist/mcp/handlers/NewDomainToolsHandler.d.ts.map +1 -1
  100. package/dist/mcp/handlers/NewDomainToolsHandler.js.map +1 -1
  101. package/dist/mcp/handlers/ruvector/RuVectorHandler.d.ts +54 -0
  102. package/dist/mcp/handlers/ruvector/RuVectorHandler.d.ts.map +1 -0
  103. package/dist/mcp/handlers/ruvector/RuVectorHandler.js +325 -0
  104. package/dist/mcp/handlers/ruvector/RuVectorHandler.js.map +1 -0
  105. package/dist/mcp/handlers/ruvector/index.d.ts +5 -0
  106. package/dist/mcp/handlers/ruvector/index.d.ts.map +1 -0
  107. package/dist/mcp/handlers/ruvector/index.js +9 -0
  108. package/dist/mcp/handlers/ruvector/index.js.map +1 -0
  109. package/dist/mcp/server-instructions.d.ts +1 -1
  110. package/dist/mcp/server-instructions.js +1 -1
  111. package/dist/mcp/server.d.ts.map +1 -1
  112. package/dist/mcp/server.js +100 -22
  113. package/dist/mcp/server.js.map +1 -1
  114. package/dist/nervous-system/adapters/BTSPAdapter.d.ts +342 -0
  115. package/dist/nervous-system/adapters/BTSPAdapter.d.ts.map +1 -0
  116. package/dist/nervous-system/adapters/BTSPAdapter.js +494 -0
  117. package/dist/nervous-system/adapters/BTSPAdapter.js.map +1 -0
  118. package/dist/nervous-system/adapters/CircadianController.d.ts +560 -0
  119. package/dist/nervous-system/adapters/CircadianController.d.ts.map +1 -0
  120. package/dist/nervous-system/adapters/CircadianController.js +882 -0
  121. package/dist/nervous-system/adapters/CircadianController.js.map +1 -0
  122. package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.d.ts +337 -0
  123. package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.d.ts.map +1 -0
  124. package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.js +532 -0
  125. package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.js.map +1 -0
  126. package/dist/nervous-system/adapters/HdcMemoryAdapter.d.ts +444 -0
  127. package/dist/nervous-system/adapters/HdcMemoryAdapter.d.ts.map +1 -0
  128. package/dist/nervous-system/adapters/HdcMemoryAdapter.js +715 -0
  129. package/dist/nervous-system/adapters/HdcMemoryAdapter.js.map +1 -0
  130. package/dist/nervous-system/adapters/ReflexLayer.d.ts +231 -0
  131. package/dist/nervous-system/adapters/ReflexLayer.d.ts.map +1 -0
  132. package/dist/nervous-system/adapters/ReflexLayer.js +309 -0
  133. package/dist/nervous-system/adapters/ReflexLayer.js.map +1 -0
  134. package/dist/nervous-system/index.d.ts +25 -0
  135. package/dist/nervous-system/index.d.ts.map +1 -0
  136. package/dist/nervous-system/index.js +80 -0
  137. package/dist/nervous-system/index.js.map +1 -0
  138. package/dist/nervous-system/integration/BTSPLearningEngine.d.ts +266 -0
  139. package/dist/nervous-system/integration/BTSPLearningEngine.d.ts.map +1 -0
  140. package/dist/nervous-system/integration/BTSPLearningEngine.js +587 -0
  141. package/dist/nervous-system/integration/BTSPLearningEngine.js.map +1 -0
  142. package/dist/nervous-system/integration/CircadianAgent.d.ts +389 -0
  143. package/dist/nervous-system/integration/CircadianAgent.d.ts.map +1 -0
  144. package/dist/nervous-system/integration/CircadianAgent.js +696 -0
  145. package/dist/nervous-system/integration/CircadianAgent.js.map +1 -0
  146. package/dist/nervous-system/integration/HybridPatternStore.d.ts +244 -0
  147. package/dist/nervous-system/integration/HybridPatternStore.d.ts.map +1 -0
  148. package/dist/nervous-system/integration/HybridPatternStore.js +622 -0
  149. package/dist/nervous-system/integration/HybridPatternStore.js.map +1 -0
  150. package/dist/nervous-system/integration/NervousSystemEnhancement.d.ts +459 -0
  151. package/dist/nervous-system/integration/NervousSystemEnhancement.d.ts.map +1 -0
  152. package/dist/nervous-system/integration/NervousSystemEnhancement.js +921 -0
  153. package/dist/nervous-system/integration/NervousSystemEnhancement.js.map +1 -0
  154. package/dist/nervous-system/integration/WorkspaceAgent.d.ts +398 -0
  155. package/dist/nervous-system/integration/WorkspaceAgent.d.ts.map +1 -0
  156. package/dist/nervous-system/integration/WorkspaceAgent.js +722 -0
  157. package/dist/nervous-system/integration/WorkspaceAgent.js.map +1 -0
  158. package/dist/nervous-system/integration/index.d.ts +22 -0
  159. package/dist/nervous-system/integration/index.d.ts.map +1 -0
  160. package/dist/nervous-system/integration/index.js +44 -0
  161. package/dist/nervous-system/integration/index.js.map +1 -0
  162. package/dist/nervous-system/persistence/BTSPSerializer.d.ts +96 -0
  163. package/dist/nervous-system/persistence/BTSPSerializer.d.ts.map +1 -0
  164. package/dist/nervous-system/persistence/BTSPSerializer.js +223 -0
  165. package/dist/nervous-system/persistence/BTSPSerializer.js.map +1 -0
  166. package/dist/nervous-system/persistence/CircadianSerializer.d.ts +90 -0
  167. package/dist/nervous-system/persistence/CircadianSerializer.d.ts.map +1 -0
  168. package/dist/nervous-system/persistence/CircadianSerializer.js +239 -0
  169. package/dist/nervous-system/persistence/CircadianSerializer.js.map +1 -0
  170. package/dist/nervous-system/persistence/HdcSerializer.d.ts +100 -0
  171. package/dist/nervous-system/persistence/HdcSerializer.d.ts.map +1 -0
  172. package/dist/nervous-system/persistence/HdcSerializer.js +259 -0
  173. package/dist/nervous-system/persistence/HdcSerializer.js.map +1 -0
  174. package/dist/nervous-system/persistence/INervousSystemStore.d.ts +208 -0
  175. package/dist/nervous-system/persistence/INervousSystemStore.d.ts.map +1 -0
  176. package/dist/nervous-system/persistence/INervousSystemStore.js +11 -0
  177. package/dist/nervous-system/persistence/INervousSystemStore.js.map +1 -0
  178. package/dist/nervous-system/persistence/NervousSystemPersistenceManager.d.ts +187 -0
  179. package/dist/nervous-system/persistence/NervousSystemPersistenceManager.d.ts.map +1 -0
  180. package/dist/nervous-system/persistence/NervousSystemPersistenceManager.js +411 -0
  181. package/dist/nervous-system/persistence/NervousSystemPersistenceManager.js.map +1 -0
  182. package/dist/nervous-system/persistence/SQLiteNervousSystemStore.d.ts +98 -0
  183. package/dist/nervous-system/persistence/SQLiteNervousSystemStore.d.ts.map +1 -0
  184. package/dist/nervous-system/persistence/SQLiteNervousSystemStore.js +510 -0
  185. package/dist/nervous-system/persistence/SQLiteNervousSystemStore.js.map +1 -0
  186. package/dist/nervous-system/persistence/index.d.ts +22 -0
  187. package/dist/nervous-system/persistence/index.d.ts.map +1 -0
  188. package/dist/nervous-system/persistence/index.js +45 -0
  189. package/dist/nervous-system/persistence/index.js.map +1 -0
  190. package/dist/nervous-system/wasm-loader.d.ts +52 -0
  191. package/dist/nervous-system/wasm-loader.d.ts.map +1 -0
  192. package/dist/nervous-system/wasm-loader.js +188 -0
  193. package/dist/nervous-system/wasm-loader.js.map +1 -0
  194. package/dist/persistence/HybridPersistenceProvider.d.ts +184 -0
  195. package/dist/persistence/HybridPersistenceProvider.d.ts.map +1 -0
  196. package/dist/persistence/HybridPersistenceProvider.js +1086 -0
  197. package/dist/persistence/HybridPersistenceProvider.js.map +1 -0
  198. package/dist/persistence/IPersistenceProvider.d.ts +657 -0
  199. package/dist/persistence/IPersistenceProvider.d.ts.map +1 -0
  200. package/dist/persistence/IPersistenceProvider.js +11 -0
  201. package/dist/persistence/IPersistenceProvider.js.map +1 -0
  202. package/dist/persistence/SupabaseConfig.d.ts +176 -0
  203. package/dist/persistence/SupabaseConfig.d.ts.map +1 -0
  204. package/dist/persistence/SupabaseConfig.js +277 -0
  205. package/dist/persistence/SupabaseConfig.js.map +1 -0
  206. package/dist/persistence/SupabasePersistenceProvider.d.ts +143 -0
  207. package/dist/persistence/SupabasePersistenceProvider.d.ts.map +1 -0
  208. package/dist/persistence/SupabasePersistenceProvider.js +959 -0
  209. package/dist/persistence/SupabasePersistenceProvider.js.map +1 -0
  210. package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.d.ts +213 -0
  211. package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.d.ts.map +1 -0
  212. package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.js +468 -0
  213. package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.js.map +1 -0
  214. package/dist/persistence/adapters/MemorySyncAdapter.d.ts +115 -0
  215. package/dist/persistence/adapters/MemorySyncAdapter.d.ts.map +1 -0
  216. package/dist/persistence/adapters/MemorySyncAdapter.js +291 -0
  217. package/dist/persistence/adapters/MemorySyncAdapter.js.map +1 -0
  218. package/dist/persistence/adapters/index.d.ts +11 -0
  219. package/dist/persistence/adapters/index.d.ts.map +1 -0
  220. package/dist/persistence/adapters/index.js +20 -0
  221. package/dist/persistence/adapters/index.js.map +1 -0
  222. package/dist/persistence/index.d.ts +14 -0
  223. package/dist/persistence/index.d.ts.map +1 -1
  224. package/dist/persistence/index.js +36 -1
  225. package/dist/persistence/index.js.map +1 -1
  226. package/package.json +7 -1
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ /**
3
+ * Redis Storage Backend for Embedding Cache
4
+ *
5
+ * Distributed caching with automatic TTL expiration.
6
+ * Best for multi-process/multi-server deployments.
7
+ *
8
+ * @module code-intelligence/embeddings/backends/RedisBackend
9
+ * @see Issue #146 - Security Hardening: SP-2 Dedicated Embedding Cache
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RedisStorageBackend = void 0;
13
+ const ioredis_1 = require("ioredis");
14
+ const types_js_1 = require("./types.js");
15
+ /**
16
+ * Default Redis configuration
17
+ */
18
+ const DEFAULT_REDIS_CONFIG = {
19
+ host: 'localhost',
20
+ port: 6379,
21
+ db: 0,
22
+ keyPrefix: 'emb:',
23
+ ttlSeconds: 86400, // 24 hours
24
+ connectTimeoutMs: 5000,
25
+ tls: false,
26
+ };
27
+ /**
28
+ * Redis-based embedding storage backend
29
+ *
30
+ * Features:
31
+ * - Distributed caching across processes
32
+ * - Automatic TTL expiration via Redis SETEX
33
+ * - Connection pooling via ioredis
34
+ * - Graceful degradation on connection failure
35
+ */
36
+ class RedisStorageBackend {
37
+ constructor(config) {
38
+ this.name = 'redis';
39
+ this.type = 'redis';
40
+ this.client = null;
41
+ this.initialized = false;
42
+ this.healthy = false;
43
+ this.config = {
44
+ host: config.host,
45
+ port: config.port,
46
+ password: config.password ?? '',
47
+ db: config.db ?? DEFAULT_REDIS_CONFIG.db,
48
+ keyPrefix: config.keyPrefix ?? DEFAULT_REDIS_CONFIG.keyPrefix,
49
+ ttlSeconds: config.ttlSeconds ?? DEFAULT_REDIS_CONFIG.ttlSeconds,
50
+ connectTimeoutMs: config.connectTimeoutMs ?? DEFAULT_REDIS_CONFIG.connectTimeoutMs,
51
+ tls: config.tls ?? DEFAULT_REDIS_CONFIG.tls,
52
+ maxSize: config.maxSize ?? 0,
53
+ defaultTtlMs: config.defaultTtlMs ?? types_js_1.DEFAULT_TTL_MS,
54
+ debug: config.debug ?? false,
55
+ retryStrategy: config.retryStrategy ?? ((times) => Math.min(times * 100, 3000)),
56
+ };
57
+ }
58
+ async initialize() {
59
+ if (this.initialized)
60
+ return;
61
+ try {
62
+ this.client = new ioredis_1.Redis({
63
+ host: this.config.host,
64
+ port: this.config.port,
65
+ password: this.config.password || undefined,
66
+ db: this.config.db,
67
+ connectTimeout: this.config.connectTimeoutMs,
68
+ tls: this.config.tls ? {} : undefined,
69
+ retryStrategy: this.config.retryStrategy,
70
+ lazyConnect: true,
71
+ });
72
+ // Set up event handlers
73
+ this.client.on('connect', () => {
74
+ this.healthy = true;
75
+ this.log('Connected to Redis');
76
+ });
77
+ this.client.on('error', (error) => {
78
+ this.healthy = false;
79
+ this.log(`Redis error: ${error.message}`);
80
+ });
81
+ this.client.on('close', () => {
82
+ this.healthy = false;
83
+ this.log('Redis connection closed');
84
+ });
85
+ // Connect
86
+ await this.client.connect();
87
+ await this.client.ping();
88
+ this.initialized = true;
89
+ this.healthy = true;
90
+ this.log('Redis backend initialized');
91
+ }
92
+ catch (error) {
93
+ this.healthy = false;
94
+ throw new Error(`Failed to initialize Redis backend: ${error.message}`);
95
+ }
96
+ }
97
+ async close() {
98
+ if (this.client) {
99
+ await this.client.quit();
100
+ this.client = null;
101
+ }
102
+ this.initialized = false;
103
+ this.healthy = false;
104
+ this.log('Redis backend closed');
105
+ }
106
+ async isHealthy() {
107
+ if (!this.client || !this.initialized)
108
+ return false;
109
+ try {
110
+ await this.client.ping();
111
+ this.healthy = true;
112
+ return true;
113
+ }
114
+ catch {
115
+ this.healthy = false;
116
+ return false;
117
+ }
118
+ }
119
+ async get(key) {
120
+ this.ensureClient();
121
+ try {
122
+ const data = await this.client.get(this.prefixKey(key));
123
+ if (!data)
124
+ return null;
125
+ return this.deserialize(data);
126
+ }
127
+ catch (error) {
128
+ this.log(`Get error: ${error.message}`);
129
+ return null;
130
+ }
131
+ }
132
+ async set(key, entry) {
133
+ this.ensureClient();
134
+ try {
135
+ const serialized = this.serialize(entry);
136
+ await this.client.setex(this.prefixKey(key), this.config.ttlSeconds, serialized);
137
+ }
138
+ catch (error) {
139
+ this.log(`Set error: ${error.message}`);
140
+ throw error;
141
+ }
142
+ }
143
+ async has(key) {
144
+ this.ensureClient();
145
+ try {
146
+ const exists = await this.client.exists(this.prefixKey(key));
147
+ return exists === 1;
148
+ }
149
+ catch {
150
+ return false;
151
+ }
152
+ }
153
+ async delete(key) {
154
+ this.ensureClient();
155
+ try {
156
+ const result = await this.client.del(this.prefixKey(key));
157
+ return result === 1;
158
+ }
159
+ catch {
160
+ return false;
161
+ }
162
+ }
163
+ async clear() {
164
+ this.ensureClient();
165
+ try {
166
+ // Use SCAN to find all keys with our prefix
167
+ const pattern = `${this.config.keyPrefix}*`;
168
+ let cursor = '0';
169
+ const keysToDelete = [];
170
+ do {
171
+ const [nextCursor, keys] = await this.client.scan(cursor, 'MATCH', pattern, 'COUNT', 1000);
172
+ cursor = nextCursor;
173
+ keysToDelete.push(...keys);
174
+ } while (cursor !== '0');
175
+ // Delete in batches
176
+ if (keysToDelete.length > 0) {
177
+ const pipeline = this.client.pipeline();
178
+ for (const key of keysToDelete) {
179
+ pipeline.del(key);
180
+ }
181
+ await pipeline.exec();
182
+ }
183
+ this.log(`Cleared ${keysToDelete.length} keys`);
184
+ }
185
+ catch (error) {
186
+ this.log(`Clear error: ${error.message}`);
187
+ throw error;
188
+ }
189
+ }
190
+ async size() {
191
+ this.ensureClient();
192
+ try {
193
+ const pattern = `${this.config.keyPrefix}*`;
194
+ let cursor = '0';
195
+ let count = 0;
196
+ do {
197
+ const [nextCursor, keys] = await this.client.scan(cursor, 'MATCH', pattern, 'COUNT', 1000);
198
+ cursor = nextCursor;
199
+ count += keys.length;
200
+ } while (cursor !== '0');
201
+ return count;
202
+ }
203
+ catch {
204
+ return 0;
205
+ }
206
+ }
207
+ async *keys() {
208
+ this.ensureClient();
209
+ const pattern = `${this.config.keyPrefix}*`;
210
+ let cursor = '0';
211
+ do {
212
+ const [nextCursor, keys] = await this.client.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
213
+ cursor = nextCursor;
214
+ for (const key of keys) {
215
+ // Remove prefix before yielding
216
+ yield key.substring(this.config.keyPrefix.length);
217
+ }
218
+ } while (cursor !== '0');
219
+ }
220
+ async pruneExpired(_maxAgeMs) {
221
+ // Redis handles TTL expiration automatically
222
+ // This method is a no-op for Redis
223
+ this.log('Redis handles TTL expiration automatically');
224
+ return 0;
225
+ }
226
+ /**
227
+ * Get backend statistics
228
+ */
229
+ async getStats() {
230
+ const size = await this.size();
231
+ return {
232
+ name: this.name,
233
+ type: this.type,
234
+ size,
235
+ memoryUsageBytes: size * types_js_1.BYTES_PER_ENTRY,
236
+ healthy: this.healthy,
237
+ lastHealthCheck: new Date(),
238
+ metrics: {
239
+ ttlSeconds: this.config.ttlSeconds,
240
+ db: this.config.db,
241
+ },
242
+ };
243
+ }
244
+ // ============================================
245
+ // Private Methods
246
+ // ============================================
247
+ prefixKey(key) {
248
+ return `${this.config.keyPrefix}${key}`;
249
+ }
250
+ serialize(entry) {
251
+ // Use MessagePack-style binary encoding for efficiency
252
+ // For now, use JSON (can optimize later)
253
+ return JSON.stringify({
254
+ e: entry.embedding,
255
+ t: entry.timestamp,
256
+ m: entry.model,
257
+ });
258
+ }
259
+ deserialize(data) {
260
+ const parsed = JSON.parse(data);
261
+ return {
262
+ embedding: parsed.e,
263
+ timestamp: parsed.t,
264
+ model: parsed.m,
265
+ };
266
+ }
267
+ ensureClient() {
268
+ if (!this.client || !this.initialized) {
269
+ throw new Error('Redis client not initialized. Call initialize() first.');
270
+ }
271
+ }
272
+ log(message) {
273
+ if (this.config.debug) {
274
+ console.log(`[RedisBackend] ${message}`);
275
+ }
276
+ }
277
+ }
278
+ exports.RedisStorageBackend = RedisStorageBackend;
279
+ //# sourceMappingURL=RedisBackend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisBackend.js","sourceRoot":"","sources":["../../../../src/code-intelligence/embeddings/backends/RedisBackend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * SQLite Storage Backend for Embedding Cache
3
+ *
4
+ * Persistent local storage with efficient binary embedding storage.
5
+ * Best for single-server deployments requiring persistence.
6
+ *
7
+ * @module code-intelligence/embeddings/backends/SQLiteBackend
8
+ * @see Issue #146 - Security Hardening: SP-2 Dedicated Embedding Cache
9
+ */
10
+ import type { EmbeddingCacheEntry } from '../types.js';
11
+ import type { EmbeddingStorageBackend, SQLiteBackendConfig, BackendStats } from './types.js';
12
+ /**
13
+ * SQLite-based embedding storage backend
14
+ *
15
+ * Features:
16
+ * - Persistent storage across restarts
17
+ * - Efficient binary BLOB storage for embeddings
18
+ * - WAL mode for concurrent access
19
+ * - Indexed timestamp for fast TTL queries
20
+ */
21
+ export declare class SQLiteStorageBackend implements EmbeddingStorageBackend {
22
+ readonly name = "sqlite";
23
+ readonly type: "sqlite";
24
+ private db;
25
+ private config;
26
+ private initialized;
27
+ private stmtGet;
28
+ private stmtSet;
29
+ private stmtHas;
30
+ private stmtDelete;
31
+ private stmtSize;
32
+ private stmtPrune;
33
+ constructor(config: SQLiteBackendConfig);
34
+ initialize(): Promise<void>;
35
+ close(): Promise<void>;
36
+ isHealthy(): Promise<boolean>;
37
+ get(key: string): Promise<EmbeddingCacheEntry | null>;
38
+ set(key: string, entry: EmbeddingCacheEntry): Promise<void>;
39
+ has(key: string): Promise<boolean>;
40
+ delete(key: string): Promise<boolean>;
41
+ clear(): Promise<void>;
42
+ size(): Promise<number>;
43
+ keys(): AsyncIterable<string>;
44
+ pruneExpired(maxAgeMs: number): Promise<number>;
45
+ /**
46
+ * Get backend statistics
47
+ */
48
+ getStats(): Promise<BackendStats>;
49
+ /**
50
+ * Run VACUUM to reclaim space
51
+ */
52
+ vacuum(): Promise<void>;
53
+ /**
54
+ * Get database file size in bytes
55
+ */
56
+ getDatabaseSize(): Promise<number>;
57
+ private prepareStatements;
58
+ private serializeEmbedding;
59
+ private deserializeEmbedding;
60
+ private isExpired;
61
+ private ensureDb;
62
+ private log;
63
+ }
64
+ //# sourceMappingURL=SQLiteBackend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SQLiteBackend.d.ts","sourceRoot":"","sources":["../../../../src/code-intelligence/embeddings/backends/SQLiteBackend.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EACV,uBAAuB,EACvB,mBAAmB,EACnB,YAAY,EACb,MAAM,YAAY,CAAC;AAapB;;;;;;;;GAQG;AACH,qBAAa,oBAAqB,YAAW,uBAAuB;IAClE,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAElC,OAAO,CAAC,EAAE,CAAkC;IAC5C,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,WAAW,CAAkB;IAGrC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,SAAS,CAAmC;gBAExC,MAAM,EAAE,mBAAmB;IAajC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBtB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAW7B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IA6BrD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAelC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAWtB,IAAI,IAAI,aAAa,CAAC,MAAM,CAAC;IAU9B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBrD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;IA2BvC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAiBxC,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,GAAG;CAKZ"}
@@ -0,0 +1,314 @@
1
+ "use strict";
2
+ /**
3
+ * SQLite Storage Backend for Embedding Cache
4
+ *
5
+ * Persistent local storage with efficient binary embedding storage.
6
+ * Best for single-server deployments requiring persistence.
7
+ *
8
+ * @module code-intelligence/embeddings/backends/SQLiteBackend
9
+ * @see Issue #146 - Security Hardening: SP-2 Dedicated Embedding Cache
10
+ */
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SQLiteStorageBackend = void 0;
16
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
17
+ const types_js_1 = require("./types.js");
18
+ /**
19
+ * Default SQLite configuration
20
+ */
21
+ const DEFAULT_SQLITE_CONFIG = {
22
+ tableName: 'embedding_cache',
23
+ walMode: true,
24
+ busyTimeoutMs: 5000,
25
+ vacuumOnClose: false,
26
+ };
27
+ /**
28
+ * SQLite-based embedding storage backend
29
+ *
30
+ * Features:
31
+ * - Persistent storage across restarts
32
+ * - Efficient binary BLOB storage for embeddings
33
+ * - WAL mode for concurrent access
34
+ * - Indexed timestamp for fast TTL queries
35
+ */
36
+ class SQLiteStorageBackend {
37
+ constructor(config) {
38
+ this.name = 'sqlite';
39
+ this.type = 'sqlite';
40
+ this.db = null;
41
+ this.initialized = false;
42
+ // Prepared statements for performance
43
+ this.stmtGet = null;
44
+ this.stmtSet = null;
45
+ this.stmtHas = null;
46
+ this.stmtDelete = null;
47
+ this.stmtSize = null;
48
+ this.stmtPrune = null;
49
+ this.config = {
50
+ dbPath: config.dbPath,
51
+ tableName: config.tableName ?? DEFAULT_SQLITE_CONFIG.tableName,
52
+ walMode: config.walMode ?? DEFAULT_SQLITE_CONFIG.walMode,
53
+ busyTimeoutMs: config.busyTimeoutMs ?? DEFAULT_SQLITE_CONFIG.busyTimeoutMs,
54
+ vacuumOnClose: config.vacuumOnClose ?? DEFAULT_SQLITE_CONFIG.vacuumOnClose,
55
+ maxSize: config.maxSize ?? 0,
56
+ defaultTtlMs: config.defaultTtlMs ?? types_js_1.DEFAULT_TTL_MS,
57
+ debug: config.debug ?? false,
58
+ };
59
+ }
60
+ async initialize() {
61
+ if (this.initialized)
62
+ return;
63
+ try {
64
+ this.db = new better_sqlite3_1.default(this.config.dbPath);
65
+ // Configure database
66
+ this.db.pragma(`busy_timeout = ${this.config.busyTimeoutMs}`);
67
+ if (this.config.walMode) {
68
+ this.db.pragma('journal_mode = WAL');
69
+ }
70
+ // Create table
71
+ this.db.exec(`
72
+ CREATE TABLE IF NOT EXISTS ${this.config.tableName} (
73
+ key TEXT PRIMARY KEY,
74
+ embedding BLOB NOT NULL,
75
+ model TEXT NOT NULL,
76
+ timestamp INTEGER NOT NULL,
77
+ created_at INTEGER DEFAULT (strftime('%s', 'now'))
78
+ );
79
+
80
+ CREATE INDEX IF NOT EXISTS idx_${this.config.tableName}_timestamp
81
+ ON ${this.config.tableName}(timestamp);
82
+ `);
83
+ // Prepare statements
84
+ this.prepareStatements();
85
+ this.initialized = true;
86
+ this.log('SQLite backend initialized');
87
+ }
88
+ catch (error) {
89
+ throw new Error(`Failed to initialize SQLite backend: ${error.message}`);
90
+ }
91
+ }
92
+ async close() {
93
+ if (this.db) {
94
+ if (this.config.vacuumOnClose) {
95
+ this.db.exec('VACUUM');
96
+ }
97
+ this.db.close();
98
+ this.db = null;
99
+ }
100
+ // Clear prepared statements
101
+ this.stmtGet = null;
102
+ this.stmtSet = null;
103
+ this.stmtHas = null;
104
+ this.stmtDelete = null;
105
+ this.stmtSize = null;
106
+ this.stmtPrune = null;
107
+ this.initialized = false;
108
+ this.log('SQLite backend closed');
109
+ }
110
+ async isHealthy() {
111
+ if (!this.db || !this.initialized)
112
+ return false;
113
+ try {
114
+ this.db.exec('SELECT 1');
115
+ return true;
116
+ }
117
+ catch {
118
+ return false;
119
+ }
120
+ }
121
+ async get(key) {
122
+ this.ensureDb();
123
+ try {
124
+ const row = this.stmtGet.get(key);
125
+ if (!row)
126
+ return null;
127
+ // Check if expired
128
+ if (this.isExpired(row.timestamp)) {
129
+ await this.delete(key);
130
+ return null;
131
+ }
132
+ return {
133
+ embedding: this.deserializeEmbedding(row.embedding),
134
+ model: row.model,
135
+ timestamp: row.timestamp,
136
+ };
137
+ }
138
+ catch (error) {
139
+ this.log(`Get error: ${error.message}`);
140
+ return null;
141
+ }
142
+ }
143
+ async set(key, entry) {
144
+ this.ensureDb();
145
+ try {
146
+ const embeddingBlob = this.serializeEmbedding(entry.embedding);
147
+ this.stmtSet.run(key, embeddingBlob, entry.model, entry.timestamp);
148
+ }
149
+ catch (error) {
150
+ this.log(`Set error: ${error.message}`);
151
+ throw error;
152
+ }
153
+ }
154
+ async has(key) {
155
+ this.ensureDb();
156
+ try {
157
+ const row = this.stmtHas.get(key);
158
+ if (!row || row.count === 0)
159
+ return false;
160
+ // Also check expiration
161
+ const entry = await this.get(key);
162
+ return entry !== null;
163
+ }
164
+ catch {
165
+ return false;
166
+ }
167
+ }
168
+ async delete(key) {
169
+ this.ensureDb();
170
+ try {
171
+ const result = this.stmtDelete.run(key);
172
+ return result.changes > 0;
173
+ }
174
+ catch {
175
+ return false;
176
+ }
177
+ }
178
+ async clear() {
179
+ this.ensureDb();
180
+ try {
181
+ this.db.exec(`DELETE FROM ${this.config.tableName}`);
182
+ this.log('Cache cleared');
183
+ }
184
+ catch (error) {
185
+ this.log(`Clear error: ${error.message}`);
186
+ throw error;
187
+ }
188
+ }
189
+ async size() {
190
+ this.ensureDb();
191
+ try {
192
+ const row = this.stmtSize.get();
193
+ return row?.count ?? 0;
194
+ }
195
+ catch {
196
+ return 0;
197
+ }
198
+ }
199
+ async *keys() {
200
+ this.ensureDb();
201
+ const stmt = this.db.prepare(`SELECT key FROM ${this.config.tableName}`);
202
+ for (const row of stmt.iterate()) {
203
+ yield row.key;
204
+ }
205
+ }
206
+ async pruneExpired(maxAgeMs) {
207
+ this.ensureDb();
208
+ try {
209
+ const threshold = Date.now() - maxAgeMs;
210
+ const result = this.stmtPrune.run(threshold);
211
+ if (result.changes > 0) {
212
+ this.log(`Pruned ${result.changes} expired entries`);
213
+ }
214
+ return result.changes;
215
+ }
216
+ catch (error) {
217
+ this.log(`Prune error: ${error.message}`);
218
+ return 0;
219
+ }
220
+ }
221
+ /**
222
+ * Get backend statistics
223
+ */
224
+ async getStats() {
225
+ const size = await this.size();
226
+ let dbSizeBytes = 0;
227
+ if (this.db) {
228
+ try {
229
+ const row = this.db.prepare('SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()').get();
230
+ dbSizeBytes = row?.size ?? 0;
231
+ }
232
+ catch {
233
+ dbSizeBytes = size * types_js_1.BYTES_PER_ENTRY;
234
+ }
235
+ }
236
+ return {
237
+ name: this.name,
238
+ type: this.type,
239
+ size,
240
+ memoryUsageBytes: dbSizeBytes,
241
+ healthy: this.initialized,
242
+ lastHealthCheck: new Date(),
243
+ metrics: {
244
+ walMode: this.config.walMode ? 1 : 0,
245
+ defaultTtlMs: this.config.defaultTtlMs,
246
+ },
247
+ };
248
+ }
249
+ /**
250
+ * Run VACUUM to reclaim space
251
+ */
252
+ async vacuum() {
253
+ this.ensureDb();
254
+ this.db.exec('VACUUM');
255
+ this.log('VACUUM completed');
256
+ }
257
+ /**
258
+ * Get database file size in bytes
259
+ */
260
+ async getDatabaseSize() {
261
+ this.ensureDb();
262
+ try {
263
+ const row = this.db.prepare('SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()').get();
264
+ return row?.size ?? 0;
265
+ }
266
+ catch {
267
+ return 0;
268
+ }
269
+ }
270
+ // ============================================
271
+ // Private Methods
272
+ // ============================================
273
+ prepareStatements() {
274
+ const table = this.config.tableName;
275
+ this.stmtGet = this.db.prepare(`SELECT embedding, model, timestamp FROM ${table} WHERE key = ?`);
276
+ this.stmtSet = this.db.prepare(`INSERT OR REPLACE INTO ${table} (key, embedding, model, timestamp) VALUES (?, ?, ?, ?)`);
277
+ this.stmtHas = this.db.prepare(`SELECT COUNT(*) as count FROM ${table} WHERE key = ?`);
278
+ this.stmtDelete = this.db.prepare(`DELETE FROM ${table} WHERE key = ?`);
279
+ this.stmtSize = this.db.prepare(`SELECT COUNT(*) as count FROM ${table}`);
280
+ this.stmtPrune = this.db.prepare(`DELETE FROM ${table} WHERE timestamp < ?`);
281
+ }
282
+ serializeEmbedding(embedding) {
283
+ // Store as Float64Array for precision
284
+ const buffer = Buffer.alloc(embedding.length * 8);
285
+ for (let i = 0; i < embedding.length; i++) {
286
+ buffer.writeDoubleLE(embedding[i], i * 8);
287
+ }
288
+ return buffer;
289
+ }
290
+ deserializeEmbedding(buffer) {
291
+ const embedding = [];
292
+ for (let i = 0; i < buffer.length; i += 8) {
293
+ embedding.push(buffer.readDoubleLE(i));
294
+ }
295
+ return embedding;
296
+ }
297
+ isExpired(timestamp) {
298
+ if (this.config.defaultTtlMs === 0)
299
+ return false;
300
+ return Date.now() - timestamp > this.config.defaultTtlMs;
301
+ }
302
+ ensureDb() {
303
+ if (!this.db || !this.initialized) {
304
+ throw new Error('SQLite database not initialized. Call initialize() first.');
305
+ }
306
+ }
307
+ log(message) {
308
+ if (this.config.debug) {
309
+ console.log(`[SQLiteBackend] ${message}`);
310
+ }
311
+ }
312
+ }
313
+ exports.SQLiteStorageBackend = SQLiteStorageBackend;
314
+ //# sourceMappingURL=SQLiteBackend.js.map