@sylphx/flow 1.8.0 → 1.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.
- package/CHANGELOG.md +72 -0
- package/assets/output-styles/silent.md +145 -8
- package/assets/rules/core.md +19 -2
- package/package.json +2 -12
- package/src/commands/flow/execute.ts +470 -0
- package/src/commands/flow/index.ts +11 -0
- package/src/commands/flow/prompt.ts +35 -0
- package/src/commands/flow/setup.ts +312 -0
- package/src/commands/flow/targets.ts +18 -0
- package/src/commands/flow/types.ts +47 -0
- package/src/commands/flow-command.ts +18 -967
- package/src/commands/flow-orchestrator.ts +14 -5
- package/src/commands/hook-command.ts +1 -1
- package/src/commands/init-core.ts +12 -3
- package/src/commands/run-command.ts +1 -1
- package/src/config/rules.ts +1 -1
- package/src/core/error-handling.ts +1 -1
- package/src/core/loop-controller.ts +1 -1
- package/src/core/state-detector.ts +1 -1
- package/src/core/target-manager.ts +1 -1
- package/src/index.ts +1 -1
- package/src/shared/files/index.ts +1 -1
- package/src/shared/processing/index.ts +1 -1
- package/src/targets/claude-code.ts +3 -3
- package/src/targets/opencode.ts +3 -3
- package/src/utils/agent-enhancer.ts +2 -2
- package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
- package/src/utils/{paths.ts → config/paths.ts} +1 -1
- package/src/utils/{settings.ts → config/settings.ts} +1 -1
- package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
- package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
- package/src/utils/display/banner.ts +25 -0
- package/src/utils/display/status.ts +55 -0
- package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
- package/src/utils/files/jsonc.ts +36 -0
- package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
- package/src/utils/index.ts +42 -61
- package/src/utils/version.ts +47 -0
- package/src/components/benchmark-monitor.tsx +0 -331
- package/src/components/reindex-progress.tsx +0 -261
- package/src/composables/functional/index.ts +0 -14
- package/src/composables/functional/useEnvironment.ts +0 -171
- package/src/composables/functional/useFileSystem.ts +0 -139
- package/src/composables/index.ts +0 -4
- package/src/composables/useEnv.ts +0 -13
- package/src/composables/useRuntimeConfig.ts +0 -27
- package/src/core/ai-sdk.ts +0 -603
- package/src/core/app-factory.ts +0 -381
- package/src/core/builtin-agents.ts +0 -9
- package/src/core/command-system.ts +0 -550
- package/src/core/config-system.ts +0 -550
- package/src/core/connection-pool.ts +0 -390
- package/src/core/di-container.ts +0 -155
- package/src/core/headless-display.ts +0 -96
- package/src/core/interfaces/index.ts +0 -22
- package/src/core/interfaces/repository.interface.ts +0 -91
- package/src/core/interfaces/service.interface.ts +0 -133
- package/src/core/interfaces.ts +0 -96
- package/src/core/result.ts +0 -351
- package/src/core/service-config.ts +0 -252
- package/src/core/session-service.ts +0 -121
- package/src/core/storage-factory.ts +0 -115
- package/src/core/stream-handler.ts +0 -288
- package/src/core/type-utils.ts +0 -427
- package/src/core/unified-storage.ts +0 -456
- package/src/core/validation/limit.ts +0 -46
- package/src/core/validation/query.ts +0 -20
- package/src/db/auto-migrate.ts +0 -322
- package/src/db/base-database-client.ts +0 -144
- package/src/db/cache-db.ts +0 -218
- package/src/db/cache-schema.ts +0 -75
- package/src/db/database.ts +0 -70
- package/src/db/index.ts +0 -252
- package/src/db/memory-db.ts +0 -153
- package/src/db/memory-schema.ts +0 -29
- package/src/db/schema.ts +0 -289
- package/src/db/session-repository.ts +0 -733
- package/src/domains/index.ts +0 -6
- package/src/domains/utilities/index.ts +0 -6
- package/src/domains/utilities/time/index.ts +0 -5
- package/src/domains/utilities/time/tools.ts +0 -291
- package/src/services/agent-service.ts +0 -273
- package/src/services/evaluation-service.ts +0 -271
- package/src/services/functional/evaluation-logic.ts +0 -296
- package/src/services/functional/file-processor.ts +0 -273
- package/src/services/functional/index.ts +0 -12
- package/src/services/memory.service.ts +0 -476
- package/src/types/api/batch.ts +0 -108
- package/src/types/api/errors.ts +0 -118
- package/src/types/api/index.ts +0 -55
- package/src/types/api/requests.ts +0 -76
- package/src/types/api/responses.ts +0 -180
- package/src/types/api/websockets.ts +0 -85
- package/src/types/benchmark.ts +0 -49
- package/src/types/database.types.ts +0 -510
- package/src/types/memory-types.ts +0 -63
- package/src/utils/advanced-tokenizer.ts +0 -191
- package/src/utils/ai-model-fetcher.ts +0 -19
- package/src/utils/async-file-operations.ts +0 -516
- package/src/utils/audio-player.ts +0 -345
- package/src/utils/codebase-helpers.ts +0 -211
- package/src/utils/console-ui.ts +0 -79
- package/src/utils/database-errors.ts +0 -140
- package/src/utils/debug-logger.ts +0 -49
- package/src/utils/file-scanner.ts +0 -259
- package/src/utils/help.ts +0 -20
- package/src/utils/immutable-cache.ts +0 -106
- package/src/utils/jsonc.ts +0 -158
- package/src/utils/memory-tui.ts +0 -414
- package/src/utils/models-dev.ts +0 -91
- package/src/utils/parallel-operations.ts +0 -487
- package/src/utils/process-manager.ts +0 -155
- package/src/utils/prompts.ts +0 -120
- package/src/utils/search-tool-builder.ts +0 -214
- package/src/utils/session-manager.ts +0 -168
- package/src/utils/session-title.ts +0 -87
- package/src/utils/simplified-errors.ts +0 -410
- package/src/utils/template-engine.ts +0 -94
- package/src/utils/test-audio.ts +0 -71
- package/src/utils/todo-context.ts +0 -46
- package/src/utils/token-counter.ts +0 -288
- /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
- /package/src/utils/{logger.ts → display/logger.ts} +0 -0
- /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
- /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
- /package/src/utils/{security.ts → security/security.ts} +0 -0
|
@@ -1,390 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Database Connection Pool
|
|
3
|
-
*
|
|
4
|
-
* Manages a pool of database connections for better performance and resource management
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export interface ConnectionConfig {
|
|
8
|
-
maxConnections?: number;
|
|
9
|
-
minConnections?: number;
|
|
10
|
-
acquireTimeout?: number;
|
|
11
|
-
idleTimeout?: number;
|
|
12
|
-
maxLifetime?: number;
|
|
13
|
-
healthCheckInterval?: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface Connection<T = any> {
|
|
17
|
-
id: string;
|
|
18
|
-
instance: T;
|
|
19
|
-
createdAt: number;
|
|
20
|
-
lastUsed: number;
|
|
21
|
-
isInUse: boolean;
|
|
22
|
-
isHealthy: boolean;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface ConnectionPoolInstance<T> {
|
|
26
|
-
acquire(): Promise<T>;
|
|
27
|
-
release(connectionInstance: T): Promise<void>;
|
|
28
|
-
getStats(): {
|
|
29
|
-
totalConnections: number;
|
|
30
|
-
activeConnections: number;
|
|
31
|
-
idleConnections: number;
|
|
32
|
-
unhealthyConnections: number;
|
|
33
|
-
maxConnections?: number;
|
|
34
|
-
minConnections?: number;
|
|
35
|
-
};
|
|
36
|
-
dispose(): Promise<void>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Create a connection pool for database connections
|
|
41
|
-
*/
|
|
42
|
-
export function createConnectionPool<T>(
|
|
43
|
-
createConnection: () => Promise<T>,
|
|
44
|
-
destroyConnection: (connection: T) => Promise<void>,
|
|
45
|
-
healthCheck: (connection: T) => Promise<boolean>,
|
|
46
|
-
configInput: ConnectionConfig = {}
|
|
47
|
-
): ConnectionPoolInstance<T> {
|
|
48
|
-
// Closure-based state
|
|
49
|
-
const connections = new Map<string, Connection<T>>();
|
|
50
|
-
let availableConnections: string[] = [];
|
|
51
|
-
let connectionCount = 0;
|
|
52
|
-
let healthCheckTimer: NodeJS.Timeout | undefined;
|
|
53
|
-
let isDisposing = false;
|
|
54
|
-
|
|
55
|
-
const config: Required<ConnectionConfig> = {
|
|
56
|
-
maxConnections: 10,
|
|
57
|
-
minConnections: 2,
|
|
58
|
-
acquireTimeout: 30000,
|
|
59
|
-
idleTimeout: 300000,
|
|
60
|
-
maxLifetime: 3600000,
|
|
61
|
-
healthCheckInterval: 60000,
|
|
62
|
-
...configInput,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Generate a unique connection ID
|
|
67
|
-
*/
|
|
68
|
-
const generateConnectionId = (): string => {
|
|
69
|
-
return `conn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Check if a connection is valid
|
|
74
|
-
*/
|
|
75
|
-
const isConnectionValid = (connection: Connection<T>): boolean => {
|
|
76
|
-
const now = Date.now();
|
|
77
|
-
|
|
78
|
-
// Check age
|
|
79
|
-
if (now - connection.createdAt > config.maxLifetime) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Check if it's idle for too long (but only if not in use)
|
|
84
|
-
if (!connection.isInUse && now - connection.lastUsed > config.idleTimeout) {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Check health
|
|
89
|
-
return connection.isHealthy;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Create a new connection
|
|
94
|
-
*/
|
|
95
|
-
const createNewConnection = async (): Promise<T> => {
|
|
96
|
-
const startTime = Date.now();
|
|
97
|
-
const connectionInstance = await createConnection();
|
|
98
|
-
const createTime = Date.now() - startTime;
|
|
99
|
-
|
|
100
|
-
const connection: Connection<T> = {
|
|
101
|
-
id: generateConnectionId(),
|
|
102
|
-
instance: connectionInstance,
|
|
103
|
-
createdAt: Date.now(),
|
|
104
|
-
lastUsed: Date.now(),
|
|
105
|
-
isInUse: true,
|
|
106
|
-
isHealthy: true,
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
connections.set(connection.id, connection);
|
|
110
|
-
connectionCount++;
|
|
111
|
-
|
|
112
|
-
console.debug(
|
|
113
|
-
`New connection created in ${createTime}ms, total connections: ${connectionCount}`
|
|
114
|
-
);
|
|
115
|
-
return connectionInstance;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Wait for a connection to become available
|
|
120
|
-
*/
|
|
121
|
-
const waitForConnection = async (): Promise<T> => {
|
|
122
|
-
const timeout = config.acquireTimeout;
|
|
123
|
-
const startTime = Date.now();
|
|
124
|
-
|
|
125
|
-
return new Promise((resolve, reject) => {
|
|
126
|
-
const checkInterval = setInterval(() => {
|
|
127
|
-
if (isDisposing) {
|
|
128
|
-
clearInterval(checkInterval);
|
|
129
|
-
reject(new Error('Connection pool is disposing'));
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (availableConnections.length > 0) {
|
|
134
|
-
clearInterval(checkInterval);
|
|
135
|
-
const connectionId = availableConnections.shift()!;
|
|
136
|
-
const connection = connections.get(connectionId)!;
|
|
137
|
-
|
|
138
|
-
if (isConnectionValid(connection)) {
|
|
139
|
-
connection.isInUse = true;
|
|
140
|
-
connection.lastUsed = Date.now();
|
|
141
|
-
resolve(connection.instance);
|
|
142
|
-
} else {
|
|
143
|
-
// Remove invalid connection and try again
|
|
144
|
-
connections.delete(connectionId);
|
|
145
|
-
connectionCount--;
|
|
146
|
-
destroyConnection(connection.instance).catch(console.error);
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Check timeout
|
|
152
|
-
if (Date.now() - startTime > timeout) {
|
|
153
|
-
clearInterval(checkInterval);
|
|
154
|
-
reject(new Error('Connection acquire timeout'));
|
|
155
|
-
}
|
|
156
|
-
}, 100);
|
|
157
|
-
});
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Maintain minimum connections
|
|
162
|
-
*/
|
|
163
|
-
const maintainMinConnections = async (): Promise<void> => {
|
|
164
|
-
const minConnections = config.minConnections;
|
|
165
|
-
const availableCount = availableConnections.length;
|
|
166
|
-
|
|
167
|
-
if (availableCount < minConnections && connectionCount < config.maxConnections) {
|
|
168
|
-
const needed = minConnections - availableCount;
|
|
169
|
-
for (let i = 0; i < needed; i++) {
|
|
170
|
-
createNewConnection()
|
|
171
|
-
.then((connection) => release(connection))
|
|
172
|
-
.catch((error) => console.error('Failed to maintain minimum connection:', error));
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Start health check timer
|
|
179
|
-
*/
|
|
180
|
-
const startHealthCheck = (): void => {
|
|
181
|
-
const interval = config.healthCheckInterval;
|
|
182
|
-
|
|
183
|
-
healthCheckTimer = setInterval(async () => {
|
|
184
|
-
if (isDisposing) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
for (const [id, connection] of connections) {
|
|
189
|
-
try {
|
|
190
|
-
const isHealthy = await healthCheck(connection.instance);
|
|
191
|
-
|
|
192
|
-
if (isHealthy) {
|
|
193
|
-
connection.isHealthy = true;
|
|
194
|
-
} else {
|
|
195
|
-
connection.isHealthy = false;
|
|
196
|
-
console.warn(`Connection ${id} failed health check`);
|
|
197
|
-
|
|
198
|
-
// Remove unhealthy connection if not in use
|
|
199
|
-
if (!connection.isInUse) {
|
|
200
|
-
connections.delete(id);
|
|
201
|
-
connectionCount--;
|
|
202
|
-
const index = availableConnections.indexOf(id);
|
|
203
|
-
if (index > -1) {
|
|
204
|
-
availableConnections.splice(index, 1);
|
|
205
|
-
}
|
|
206
|
-
await destroyConnection(connection.instance);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
} catch (error) {
|
|
210
|
-
console.error(`Health check failed for connection ${id}:`, error);
|
|
211
|
-
connection.isHealthy = false;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Maintain minimum connections
|
|
216
|
-
await maintainMinConnections();
|
|
217
|
-
}, interval);
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Initialize minimum connections
|
|
222
|
-
*/
|
|
223
|
-
const initializeMinConnections = async (): Promise<void> => {
|
|
224
|
-
const minConnections = config.minConnections;
|
|
225
|
-
const promises = [];
|
|
226
|
-
|
|
227
|
-
for (let i = 0; i < minConnections; i++) {
|
|
228
|
-
promises.push(
|
|
229
|
-
createNewConnection()
|
|
230
|
-
.then((connection) => release(connection))
|
|
231
|
-
.catch((error) => console.error('Failed to initialize minimum connection:', error))
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
await Promise.all(promises);
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Acquire a connection from the pool
|
|
240
|
-
*/
|
|
241
|
-
const acquire = async (): Promise<T> => {
|
|
242
|
-
if (isDisposing) {
|
|
243
|
-
throw new Error('Connection pool is disposing');
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Try to get an available connection
|
|
247
|
-
while (availableConnections.length > 0) {
|
|
248
|
-
const connectionId = availableConnections.shift()!;
|
|
249
|
-
const connection = connections.get(connectionId)!;
|
|
250
|
-
|
|
251
|
-
if (isConnectionValid(connection)) {
|
|
252
|
-
connection.isInUse = true;
|
|
253
|
-
connection.lastUsed = Date.now();
|
|
254
|
-
return connection.instance;
|
|
255
|
-
}
|
|
256
|
-
// Remove invalid connection
|
|
257
|
-
connections.delete(connectionId);
|
|
258
|
-
connectionCount--;
|
|
259
|
-
await destroyConnection(connection.instance);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Create new connection if under limit
|
|
263
|
-
if (connectionCount < config.maxConnections) {
|
|
264
|
-
return await createNewConnection();
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Wait for a connection to become available
|
|
268
|
-
return await waitForConnection();
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Release a connection back to the pool
|
|
273
|
-
*/
|
|
274
|
-
const release = async (connectionInstance: T): Promise<void> => {
|
|
275
|
-
for (const [id, connection] of connections) {
|
|
276
|
-
if (connection.instance === connectionInstance) {
|
|
277
|
-
connection.isInUse = false;
|
|
278
|
-
connection.lastUsed = Date.now();
|
|
279
|
-
availableConnections.push(id);
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Connection not found in pool, destroy it
|
|
285
|
-
await destroyConnection(connectionInstance);
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Get pool statistics
|
|
290
|
-
*/
|
|
291
|
-
const getStats = () => {
|
|
292
|
-
const activeConnections = Array.from(connections.values()).filter((c) => c.isInUse).length;
|
|
293
|
-
const idleConnections = availableConnections.length;
|
|
294
|
-
const unhealthyConnections = Array.from(connections.values()).filter(
|
|
295
|
-
(c) => !c.isHealthy
|
|
296
|
-
).length;
|
|
297
|
-
|
|
298
|
-
return {
|
|
299
|
-
totalConnections: connectionCount,
|
|
300
|
-
activeConnections,
|
|
301
|
-
idleConnections,
|
|
302
|
-
unhealthyConnections,
|
|
303
|
-
maxConnections: config.maxConnections,
|
|
304
|
-
minConnections: config.minConnections,
|
|
305
|
-
};
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Close all connections and dispose the pool
|
|
310
|
-
*/
|
|
311
|
-
const dispose = async (): Promise<void> => {
|
|
312
|
-
isDisposing = true;
|
|
313
|
-
|
|
314
|
-
if (healthCheckTimer) {
|
|
315
|
-
clearInterval(healthCheckTimer);
|
|
316
|
-
healthCheckTimer = undefined;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const destroyPromises = Array.from(connections.values()).map(async (connection) => {
|
|
320
|
-
try {
|
|
321
|
-
await destroyConnection(connection.instance);
|
|
322
|
-
} catch (error) {
|
|
323
|
-
console.error('Error destroying connection during pool disposal:', error);
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
await Promise.all(destroyPromises);
|
|
328
|
-
|
|
329
|
-
connections.clear();
|
|
330
|
-
availableConnections = [];
|
|
331
|
-
connectionCount = 0;
|
|
332
|
-
|
|
333
|
-
console.log('Connection pool disposed');
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
// Initialize pool
|
|
337
|
-
startHealthCheck();
|
|
338
|
-
initializeMinConnections();
|
|
339
|
-
|
|
340
|
-
return {
|
|
341
|
-
acquire,
|
|
342
|
-
release,
|
|
343
|
-
getStats,
|
|
344
|
-
dispose,
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* @deprecated Use createConnectionPool() for new code
|
|
350
|
-
*/
|
|
351
|
-
export class ConnectionPool<T> {
|
|
352
|
-
private instance: ConnectionPoolInstance<T>;
|
|
353
|
-
|
|
354
|
-
constructor(
|
|
355
|
-
createConnection: () => Promise<T>,
|
|
356
|
-
destroyConnection: (connection: T) => Promise<void>,
|
|
357
|
-
healthCheck: (connection: T) => Promise<boolean>,
|
|
358
|
-
config: ConnectionConfig = {}
|
|
359
|
-
) {
|
|
360
|
-
this.instance = createConnectionPool(createConnection, destroyConnection, healthCheck, config);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
async acquire(): Promise<T> {
|
|
364
|
-
return this.instance.acquire();
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
async release(connectionInstance: T): Promise<void> {
|
|
368
|
-
return this.instance.release(connectionInstance);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
getStats() {
|
|
372
|
-
return this.instance.getStats();
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
async dispose(): Promise<void> {
|
|
376
|
-
return this.instance.dispose();
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Create a connection pool for database connections
|
|
382
|
-
*/
|
|
383
|
-
export function createDatabaseConnectionPool(
|
|
384
|
-
createDbConnection: () => Promise<any>,
|
|
385
|
-
destroyDbConnection: (connection: any) => Promise<void>,
|
|
386
|
-
healthCheckFn: (connection: any) => Promise<boolean>,
|
|
387
|
-
config?: ConnectionConfig
|
|
388
|
-
): ConnectionPoolInstance<any> {
|
|
389
|
-
return createConnectionPool(createDbConnection, destroyDbConnection, healthCheckFn, config);
|
|
390
|
-
}
|
package/src/core/di-container.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lightweight Dependency Injection Container
|
|
3
|
-
*
|
|
4
|
-
* A minimal DI container focusing on core services: database, logging, configuration
|
|
5
|
-
* Uses constructor injection pattern for better testability
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export type ServiceFactory<T> = () => T | Promise<T>;
|
|
9
|
-
export type ServiceLifetime = 'singleton' | 'transient' | 'scoped';
|
|
10
|
-
|
|
11
|
-
export interface ServiceDescriptor<T = any> {
|
|
12
|
-
factory: ServiceFactory<T>;
|
|
13
|
-
lifetime: ServiceLifetime;
|
|
14
|
-
instance?: T;
|
|
15
|
-
isResolved?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export class DIContainer {
|
|
19
|
-
private services = new Map<string, ServiceDescriptor>();
|
|
20
|
-
private scopedInstances = new Map<string, any>();
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Register a service with the container
|
|
24
|
-
*/
|
|
25
|
-
register<T>(
|
|
26
|
-
token: string,
|
|
27
|
-
factory: ServiceFactory<T>,
|
|
28
|
-
lifetime: ServiceLifetime = 'singleton'
|
|
29
|
-
): void {
|
|
30
|
-
this.services.set(token, {
|
|
31
|
-
factory,
|
|
32
|
-
lifetime,
|
|
33
|
-
isResolved: false,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Register a singleton instance
|
|
39
|
-
*/
|
|
40
|
-
registerInstance<T>(token: string, instance: T): void {
|
|
41
|
-
this.services.set(token, {
|
|
42
|
-
factory: () => instance,
|
|
43
|
-
lifetime: 'singleton',
|
|
44
|
-
instance,
|
|
45
|
-
isResolved: true,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Resolve a service from the container
|
|
51
|
-
*/
|
|
52
|
-
async resolve<T>(token: string): Promise<T> {
|
|
53
|
-
const descriptor = this.services.get(token);
|
|
54
|
-
|
|
55
|
-
if (!descriptor) {
|
|
56
|
-
throw new Error(`Service not registered: ${token}`);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
switch (descriptor.lifetime) {
|
|
60
|
-
case 'singleton':
|
|
61
|
-
return this.resolveSingleton<T>(descriptor);
|
|
62
|
-
case 'transient':
|
|
63
|
-
return this.resolveTransient<T>(descriptor);
|
|
64
|
-
case 'scoped':
|
|
65
|
-
return this.resolveScoped<T>(token, descriptor);
|
|
66
|
-
default:
|
|
67
|
-
throw new Error(`Unsupported service lifetime: ${descriptor.lifetime}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Check if a service is registered
|
|
73
|
-
*/
|
|
74
|
-
isRegistered(token: string): boolean {
|
|
75
|
-
return this.services.has(token);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Create a new scope for scoped services
|
|
80
|
-
*/
|
|
81
|
-
createScope(): DIContainer {
|
|
82
|
-
const scope = new DIContainer();
|
|
83
|
-
// Copy all service descriptors but not instances
|
|
84
|
-
for (const [token, descriptor] of this.services) {
|
|
85
|
-
scope.services.set(token, { ...descriptor });
|
|
86
|
-
}
|
|
87
|
-
return scope;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Clear scoped instances (useful for request cleanup)
|
|
92
|
-
*/
|
|
93
|
-
clearScope(): void {
|
|
94
|
-
this.scopedInstances.clear();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Dispose all singleton services that have dispose method
|
|
99
|
-
*/
|
|
100
|
-
async dispose(): Promise<void> {
|
|
101
|
-
for (const descriptor of this.services.values()) {
|
|
102
|
-
if (descriptor.instance && typeof descriptor.instance.dispose === 'function') {
|
|
103
|
-
try {
|
|
104
|
-
await descriptor.instance.dispose();
|
|
105
|
-
} catch (error) {
|
|
106
|
-
console.error('Error disposing service:', error);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
this.services.clear();
|
|
111
|
-
this.scopedInstances.clear();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private async resolveSingleton<T>(descriptor: ServiceDescriptor<T>): Promise<T> {
|
|
115
|
-
if (descriptor.isResolved && descriptor.instance) {
|
|
116
|
-
return descriptor.instance;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const instance = await descriptor.factory();
|
|
120
|
-
descriptor.instance = instance;
|
|
121
|
-
descriptor.isResolved = true;
|
|
122
|
-
|
|
123
|
-
return instance;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private async resolveTransient<T>(descriptor: ServiceDescriptor<T>): Promise<T> {
|
|
127
|
-
return await descriptor.factory();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
private async resolveScoped<T>(token: string, descriptor: ServiceDescriptor<T>): Promise<T> {
|
|
131
|
-
if (this.scopedInstances.has(token)) {
|
|
132
|
-
return this.scopedInstances.get(token);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const instance = await descriptor.factory();
|
|
136
|
-
this.scopedInstances.set(token, instance);
|
|
137
|
-
|
|
138
|
-
return instance;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Global container instance
|
|
143
|
-
export const container = new DIContainer();
|
|
144
|
-
|
|
145
|
-
// Service tokens constants
|
|
146
|
-
export const SERVICE_TOKENS = {
|
|
147
|
-
DATABASE: 'database',
|
|
148
|
-
LOGGER: 'logger',
|
|
149
|
-
CONFIG: 'config',
|
|
150
|
-
MEMORY_STORAGE: 'memoryStorage',
|
|
151
|
-
SEARCH_SERVICE: 'searchService',
|
|
152
|
-
MCP_SERVICE: 'mcpService',
|
|
153
|
-
EMBEDDING_PROVIDER: 'embeddingProvider',
|
|
154
|
-
TARGET_MANAGER: 'targetManager',
|
|
155
|
-
} as const;
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Headless Display
|
|
3
|
-
* Formatting and display logic for headless mode (non-TUI)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import chalk from 'chalk';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Format tool arguments for display
|
|
10
|
-
*/
|
|
11
|
-
function formatArgs(args: unknown): string {
|
|
12
|
-
if (!args || typeof args !== 'object') {
|
|
13
|
-
return '';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const argsStr = Object.keys(args).length === 0
|
|
17
|
-
? ''
|
|
18
|
-
: JSON.stringify(args, null, 2);
|
|
19
|
-
|
|
20
|
-
if (!argsStr) {
|
|
21
|
-
return '';
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const lines = argsStr.split('\n');
|
|
25
|
-
const truncated = lines.length > 5
|
|
26
|
-
? lines.slice(0, 5).join('\n') + chalk.dim('\n … +' + (lines.length - 5) + ' lines')
|
|
27
|
-
: argsStr;
|
|
28
|
-
|
|
29
|
-
return truncated;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Format tool result for display
|
|
34
|
-
*/
|
|
35
|
-
function formatResult(result: unknown): string {
|
|
36
|
-
const resultStr = JSON.stringify(result, null, 2);
|
|
37
|
-
const lines = resultStr.split('\n');
|
|
38
|
-
const truncated = lines.length > 5
|
|
39
|
-
? lines.slice(0, 5).join('\n') + chalk.dim('\n … +' + (lines.length - 5) + ' lines')
|
|
40
|
-
: resultStr;
|
|
41
|
-
|
|
42
|
-
return truncated;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Display callbacks for headless mode
|
|
47
|
-
*/
|
|
48
|
-
export function createHeadlessDisplay(quiet: boolean) {
|
|
49
|
-
let hasOutput = false;
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
onToolCall: (toolName: string, args: unknown) => {
|
|
53
|
-
if (quiet) return;
|
|
54
|
-
|
|
55
|
-
// Flush stdout to ensure proper ordering
|
|
56
|
-
if (hasOutput) {
|
|
57
|
-
process.stdout.write('\n');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const argsStr = formatArgs(args);
|
|
61
|
-
if (argsStr) {
|
|
62
|
-
process.stderr.write(`\n${chalk.green('⏺')} ${chalk.bold(toolName)}\n`);
|
|
63
|
-
process.stderr.write(chalk.dim(` ⎿ ${argsStr.split('\n').join('\n ')}\n`));
|
|
64
|
-
} else {
|
|
65
|
-
process.stderr.write(`\n${chalk.green('⏺')} ${chalk.bold(toolName)}\n`);
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
onToolResult: (toolName: string, result: unknown, duration: number) => {
|
|
70
|
-
if (quiet) return;
|
|
71
|
-
|
|
72
|
-
const resultStr = formatResult(result);
|
|
73
|
-
process.stderr.write(`${chalk.green('●')} ${chalk.bold(toolName)} ${chalk.dim(`(${duration}ms)`)}\n`);
|
|
74
|
-
process.stderr.write(chalk.dim(` ⎿ ${resultStr.split('\n').join('\n ')}\n\n`));
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
onTextDelta: (text: string) => {
|
|
78
|
-
if (!hasOutput) {
|
|
79
|
-
hasOutput = true;
|
|
80
|
-
// Add newline before first text output if we're not in quiet mode
|
|
81
|
-
if (!quiet) {
|
|
82
|
-
process.stdout.write('\n');
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
process.stdout.write(text);
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
onComplete: () => {
|
|
89
|
-
if (hasOutput) {
|
|
90
|
-
process.stdout.write('\n\n');
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
hasOutput: () => hasOutput,
|
|
95
|
-
};
|
|
96
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core interfaces for dependency inversion
|
|
3
|
-
* All abstractions in one place
|
|
4
|
-
*
|
|
5
|
-
* DESIGN RATIONALE:
|
|
6
|
-
* - Single source of truth for contracts
|
|
7
|
-
* - Enables dependency injection
|
|
8
|
-
* - Facilitates testing
|
|
9
|
-
* - Clear separation of interface and implementation
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
// Re-export commonly used types from existing interfaces
|
|
13
|
-
export type {
|
|
14
|
-
CoreService,
|
|
15
|
-
FileProcessor,
|
|
16
|
-
IDatabaseConnection,
|
|
17
|
-
ILogger,
|
|
18
|
-
InitializationOptions,
|
|
19
|
-
TargetManager,
|
|
20
|
-
} from '../interfaces.js';
|
|
21
|
-
export * from './repository.interface.js';
|
|
22
|
-
export * from './service.interface.js';
|