@sylphx/flow 1.7.0 → 1.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 (131) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/assets/agents/coder.md +72 -119
  3. package/assets/agents/orchestrator.md +26 -90
  4. package/assets/agents/reviewer.md +76 -47
  5. package/assets/agents/writer.md +82 -63
  6. package/assets/output-styles/silent.md +141 -8
  7. package/assets/rules/code-standards.md +9 -33
  8. package/assets/rules/core.md +67 -59
  9. package/package.json +2 -12
  10. package/src/commands/flow/execute.ts +470 -0
  11. package/src/commands/flow/index.ts +11 -0
  12. package/src/commands/flow/prompt.ts +35 -0
  13. package/src/commands/flow/setup.ts +312 -0
  14. package/src/commands/flow/targets.ts +18 -0
  15. package/src/commands/flow/types.ts +47 -0
  16. package/src/commands/flow-command.ts +18 -967
  17. package/src/commands/flow-orchestrator.ts +14 -5
  18. package/src/commands/hook-command.ts +1 -1
  19. package/src/commands/init-core.ts +12 -3
  20. package/src/commands/run-command.ts +1 -1
  21. package/src/config/rules.ts +1 -1
  22. package/src/core/error-handling.ts +1 -1
  23. package/src/core/loop-controller.ts +1 -1
  24. package/src/core/state-detector.ts +1 -1
  25. package/src/core/target-manager.ts +1 -1
  26. package/src/index.ts +1 -1
  27. package/src/shared/files/index.ts +1 -1
  28. package/src/shared/processing/index.ts +1 -1
  29. package/src/targets/claude-code.ts +3 -3
  30. package/src/targets/opencode.ts +3 -3
  31. package/src/utils/agent-enhancer.ts +2 -2
  32. package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
  33. package/src/utils/{paths.ts → config/paths.ts} +1 -1
  34. package/src/utils/{settings.ts → config/settings.ts} +1 -1
  35. package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
  36. package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
  37. package/src/utils/display/banner.ts +25 -0
  38. package/src/utils/display/status.ts +55 -0
  39. package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
  40. package/src/utils/files/jsonc.ts +36 -0
  41. package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
  42. package/src/utils/index.ts +42 -61
  43. package/src/utils/version.ts +47 -0
  44. package/src/components/benchmark-monitor.tsx +0 -331
  45. package/src/components/reindex-progress.tsx +0 -261
  46. package/src/composables/functional/index.ts +0 -14
  47. package/src/composables/functional/useEnvironment.ts +0 -171
  48. package/src/composables/functional/useFileSystem.ts +0 -139
  49. package/src/composables/index.ts +0 -4
  50. package/src/composables/useEnv.ts +0 -13
  51. package/src/composables/useRuntimeConfig.ts +0 -27
  52. package/src/core/ai-sdk.ts +0 -603
  53. package/src/core/app-factory.ts +0 -381
  54. package/src/core/builtin-agents.ts +0 -9
  55. package/src/core/command-system.ts +0 -550
  56. package/src/core/config-system.ts +0 -550
  57. package/src/core/connection-pool.ts +0 -390
  58. package/src/core/di-container.ts +0 -155
  59. package/src/core/headless-display.ts +0 -96
  60. package/src/core/interfaces/index.ts +0 -22
  61. package/src/core/interfaces/repository.interface.ts +0 -91
  62. package/src/core/interfaces/service.interface.ts +0 -133
  63. package/src/core/interfaces.ts +0 -96
  64. package/src/core/result.ts +0 -351
  65. package/src/core/service-config.ts +0 -252
  66. package/src/core/session-service.ts +0 -121
  67. package/src/core/storage-factory.ts +0 -115
  68. package/src/core/stream-handler.ts +0 -288
  69. package/src/core/type-utils.ts +0 -427
  70. package/src/core/unified-storage.ts +0 -456
  71. package/src/core/validation/limit.ts +0 -46
  72. package/src/core/validation/query.ts +0 -20
  73. package/src/db/auto-migrate.ts +0 -322
  74. package/src/db/base-database-client.ts +0 -144
  75. package/src/db/cache-db.ts +0 -218
  76. package/src/db/cache-schema.ts +0 -75
  77. package/src/db/database.ts +0 -70
  78. package/src/db/index.ts +0 -252
  79. package/src/db/memory-db.ts +0 -153
  80. package/src/db/memory-schema.ts +0 -29
  81. package/src/db/schema.ts +0 -289
  82. package/src/db/session-repository.ts +0 -733
  83. package/src/domains/index.ts +0 -6
  84. package/src/domains/utilities/index.ts +0 -6
  85. package/src/domains/utilities/time/index.ts +0 -5
  86. package/src/domains/utilities/time/tools.ts +0 -291
  87. package/src/services/agent-service.ts +0 -273
  88. package/src/services/evaluation-service.ts +0 -271
  89. package/src/services/functional/evaluation-logic.ts +0 -296
  90. package/src/services/functional/file-processor.ts +0 -273
  91. package/src/services/functional/index.ts +0 -12
  92. package/src/services/memory.service.ts +0 -476
  93. package/src/types/api/batch.ts +0 -108
  94. package/src/types/api/errors.ts +0 -118
  95. package/src/types/api/index.ts +0 -55
  96. package/src/types/api/requests.ts +0 -76
  97. package/src/types/api/responses.ts +0 -180
  98. package/src/types/api/websockets.ts +0 -85
  99. package/src/types/benchmark.ts +0 -49
  100. package/src/types/database.types.ts +0 -510
  101. package/src/types/memory-types.ts +0 -63
  102. package/src/utils/advanced-tokenizer.ts +0 -191
  103. package/src/utils/ai-model-fetcher.ts +0 -19
  104. package/src/utils/async-file-operations.ts +0 -516
  105. package/src/utils/audio-player.ts +0 -345
  106. package/src/utils/codebase-helpers.ts +0 -211
  107. package/src/utils/console-ui.ts +0 -79
  108. package/src/utils/database-errors.ts +0 -140
  109. package/src/utils/debug-logger.ts +0 -49
  110. package/src/utils/file-scanner.ts +0 -259
  111. package/src/utils/help.ts +0 -20
  112. package/src/utils/immutable-cache.ts +0 -106
  113. package/src/utils/jsonc.ts +0 -158
  114. package/src/utils/memory-tui.ts +0 -414
  115. package/src/utils/models-dev.ts +0 -91
  116. package/src/utils/parallel-operations.ts +0 -487
  117. package/src/utils/process-manager.ts +0 -155
  118. package/src/utils/prompts.ts +0 -120
  119. package/src/utils/search-tool-builder.ts +0 -214
  120. package/src/utils/session-manager.ts +0 -168
  121. package/src/utils/session-title.ts +0 -87
  122. package/src/utils/simplified-errors.ts +0 -410
  123. package/src/utils/template-engine.ts +0 -94
  124. package/src/utils/test-audio.ts +0 -71
  125. package/src/utils/todo-context.ts +0 -46
  126. package/src/utils/token-counter.ts +0 -288
  127. /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
  128. /package/src/utils/{logger.ts → display/logger.ts} +0 -0
  129. /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
  130. /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
  131. /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
- }
@@ -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';