@brutalist/mcp 0.5.1 → 0.6.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.
- package/README.md +65 -63
- package/dist/brutalist-server.d.ts +15 -0
- package/dist/brutalist-server.d.ts.map +1 -1
- package/dist/brutalist-server.js +405 -357
- package/dist/brutalist-server.js.map +1 -1
- package/dist/cli-agents.d.ts +8 -3
- package/dist/cli-agents.d.ts.map +1 -1
- package/dist/cli-agents.js +352 -50
- package/dist/cli-agents.js.map +1 -1
- package/dist/streaming/circuit-breaker.d.ts +186 -0
- package/dist/streaming/circuit-breaker.d.ts.map +1 -0
- package/dist/streaming/circuit-breaker.js +463 -0
- package/dist/streaming/circuit-breaker.js.map +1 -0
- package/dist/streaming/intelligent-buffer.d.ts +141 -0
- package/dist/streaming/intelligent-buffer.d.ts.map +1 -0
- package/dist/streaming/intelligent-buffer.js +555 -0
- package/dist/streaming/intelligent-buffer.js.map +1 -0
- package/dist/streaming/output-parser.d.ts +89 -0
- package/dist/streaming/output-parser.d.ts.map +1 -0
- package/dist/streaming/output-parser.js +349 -0
- package/dist/streaming/output-parser.js.map +1 -0
- package/dist/streaming/progress-tracker.d.ts +149 -0
- package/dist/streaming/progress-tracker.d.ts.map +1 -0
- package/dist/streaming/progress-tracker.js +519 -0
- package/dist/streaming/progress-tracker.js.map +1 -0
- package/dist/streaming/session-manager.d.ts +238 -0
- package/dist/streaming/session-manager.d.ts.map +1 -0
- package/dist/streaming/session-manager.js +546 -0
- package/dist/streaming/session-manager.js.map +1 -0
- package/dist/streaming/sse-transport.d.ts +95 -0
- package/dist/streaming/sse-transport.d.ts.map +1 -0
- package/dist/streaming/sse-transport.js +319 -0
- package/dist/streaming/sse-transport.js.map +1 -0
- package/dist/streaming/streaming-orchestrator.d.ts +153 -0
- package/dist/streaming/streaming-orchestrator.d.ts.map +1 -0
- package/dist/streaming/streaming-orchestrator.js +436 -0
- package/dist/streaming/streaming-orchestrator.js.map +1 -0
- package/dist/test-utils/process-manager.d.ts +61 -0
- package/dist/test-utils/process-manager.d.ts.map +1 -0
- package/dist/test-utils/process-manager.js +262 -0
- package/dist/test-utils/process-manager.js.map +1 -0
- package/dist/test-utils/server-harness.d.ts +73 -0
- package/dist/test-utils/server-harness.d.ts.map +1 -0
- package/dist/test-utils/server-harness.js +296 -0
- package/dist/test-utils/server-harness.js.map +1 -0
- package/dist/test-utils/streaming-fuzz.d.ts +57 -0
- package/dist/test-utils/streaming-fuzz.d.ts.map +1 -0
- package/dist/test-utils/streaming-fuzz.js +287 -0
- package/dist/test-utils/streaming-fuzz.js.map +1 -0
- package/dist/test-utils/test-isolation.d.ts +70 -0
- package/dist/test-utils/test-isolation.d.ts.map +1 -0
- package/dist/test-utils/test-isolation.js +193 -0
- package/dist/test-utils/test-isolation.js.map +1 -0
- package/dist/tool-definitions.d.ts +6 -0
- package/dist/tool-definitions.d.ts.map +1 -0
- package/dist/tool-definitions.js +217 -0
- package/dist/tool-definitions.js.map +1 -0
- package/dist/types/brutalist.d.ts +3 -19
- package/dist/types/brutalist.d.ts.map +1 -1
- package/dist/types/tool-config.d.ts +51 -0
- package/dist/types/tool-config.d.ts.map +1 -0
- package/dist/types/tool-config.js +24 -0
- package/dist/types/tool-config.js.map +1 -0
- package/dist/utils/pagination.d.ts +2 -2
- package/dist/utils/pagination.d.ts.map +1 -1
- package/dist/utils/pagination.js +1 -1
- package/dist/utils/pagination.js.map +1 -1
- package/dist/utils/response-cache.d.ts +96 -0
- package/dist/utils/response-cache.d.ts.map +1 -0
- package/dist/utils/response-cache.js +371 -0
- package/dist/utils/response-cache.js.map +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +22 -3
- package/dist/utils.js.map +1 -1
- package/package.json +14 -4
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
import { CLIAgentOrchestrator } from '../cli-agents.js';
|
|
4
|
+
import { SessionManager } from './session-manager.js';
|
|
5
|
+
import { EnhancedSSETransport } from './sse-transport.js';
|
|
6
|
+
import { ProgressTracker } from './progress-tracker.js';
|
|
7
|
+
import { CircuitBreaker, CachedResponseFallback, DegradedServiceFallback } from './circuit-breaker.js';
|
|
8
|
+
/**
|
|
9
|
+
* Advanced streaming CLI orchestrator with comprehensive real-time capabilities
|
|
10
|
+
*
|
|
11
|
+
* Integrates all streaming components:
|
|
12
|
+
* - Real-time output parsing with semantic boundaries
|
|
13
|
+
* - Intelligent buffering with adaptive throttling
|
|
14
|
+
* - Session management with lifecycle tracking
|
|
15
|
+
* - SSE transport with session isolation
|
|
16
|
+
* - Progress tracking with milestone detection
|
|
17
|
+
* - Circuit breaker with fallback strategies
|
|
18
|
+
* - Comprehensive monitoring and analytics
|
|
19
|
+
*/
|
|
20
|
+
export class StreamingCLIOrchestrator extends EventEmitter {
|
|
21
|
+
cliOrchestrator;
|
|
22
|
+
sessionManager;
|
|
23
|
+
sseTransport;
|
|
24
|
+
circuitBreakers = new Map();
|
|
25
|
+
responseCache = new Map();
|
|
26
|
+
activeAnalyses = new Map();
|
|
27
|
+
config;
|
|
28
|
+
metrics = {
|
|
29
|
+
totalAnalyses: 0,
|
|
30
|
+
successfulAnalyses: 0,
|
|
31
|
+
failedAnalyses: 0,
|
|
32
|
+
totalEventsSent: 0,
|
|
33
|
+
totalCircuitBreakerTrips: 0,
|
|
34
|
+
totalFallbacksUsed: 0,
|
|
35
|
+
averageAnalysisDuration: 0
|
|
36
|
+
};
|
|
37
|
+
cleanupTimer;
|
|
38
|
+
constructor(config) {
|
|
39
|
+
super();
|
|
40
|
+
this.config = {
|
|
41
|
+
maxConcurrentAnalyses: 10,
|
|
42
|
+
defaultTimeout: 600000, // 10 minutes
|
|
43
|
+
circuitBreakerConfig: {
|
|
44
|
+
failureThreshold: 5,
|
|
45
|
+
recoveryTimeout: 30000,
|
|
46
|
+
successThreshold: 3,
|
|
47
|
+
timeout: 120000,
|
|
48
|
+
monitoringWindow: 300000,
|
|
49
|
+
minimumRequests: 10
|
|
50
|
+
},
|
|
51
|
+
enableMetrics: true,
|
|
52
|
+
cleanupInterval: 300000, // 5 minutes
|
|
53
|
+
...config
|
|
54
|
+
};
|
|
55
|
+
this.cliOrchestrator = new CLIAgentOrchestrator();
|
|
56
|
+
this.sessionManager = new SessionManager();
|
|
57
|
+
this.sseTransport = new EnhancedSSETransport(this.sessionManager);
|
|
58
|
+
this.setupEventHandlers();
|
|
59
|
+
this.setupCircuitBreakers();
|
|
60
|
+
this.startCleanupTimer();
|
|
61
|
+
logger.info('🚀 Streaming CLI Orchestrator initialized', {
|
|
62
|
+
maxConcurrentAnalyses: this.config.maxConcurrentAnalyses,
|
|
63
|
+
circuitBreakerEnabled: true,
|
|
64
|
+
progressTrackingEnabled: true
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Execute CLI analysis with full streaming capabilities
|
|
69
|
+
*/
|
|
70
|
+
async executeWithStreaming(analysisType, cliAgents, systemPrompt, userPrompt, options = {}) {
|
|
71
|
+
const sessionId = options.sessionId || `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
72
|
+
const startTime = Date.now();
|
|
73
|
+
// Check concurrent analysis limit
|
|
74
|
+
if (this.activeAnalyses.size >= this.config.maxConcurrentAnalyses) {
|
|
75
|
+
throw new Error(`Maximum concurrent analyses reached (${this.config.maxConcurrentAnalyses})`);
|
|
76
|
+
}
|
|
77
|
+
logger.info(`🎬 Starting streaming analysis: ${analysisType} for session ${sessionId}`, {
|
|
78
|
+
agents: cliAgents,
|
|
79
|
+
enableProgress: options.enableProgress,
|
|
80
|
+
enableCircuitBreaker: options.enableCircuitBreaker
|
|
81
|
+
});
|
|
82
|
+
// Create session and progress tracker
|
|
83
|
+
const sessionContext = this.sessionManager.createSession(sessionId, {
|
|
84
|
+
analysisType,
|
|
85
|
+
agents: cliAgents,
|
|
86
|
+
startTime
|
|
87
|
+
});
|
|
88
|
+
const progressTracker = options.enableProgress !== false
|
|
89
|
+
? new ProgressTracker(sessionId, analysisType)
|
|
90
|
+
: undefined;
|
|
91
|
+
// Track active analysis
|
|
92
|
+
this.activeAnalyses.set(sessionId, {
|
|
93
|
+
sessionId,
|
|
94
|
+
progressTracker: progressTracker,
|
|
95
|
+
startTime,
|
|
96
|
+
options
|
|
97
|
+
});
|
|
98
|
+
// Setup progress tracking if enabled
|
|
99
|
+
if (progressTracker) {
|
|
100
|
+
progressTracker.on('progress', (progressEvent) => {
|
|
101
|
+
this.sessionManager.emitToSession(sessionId, {
|
|
102
|
+
type: 'agent_progress',
|
|
103
|
+
agent: 'system',
|
|
104
|
+
content: `Progress: ${Math.round(progressEvent.progress.overall * 100)}% - ${progressEvent.phase}`,
|
|
105
|
+
timestamp: Date.now(),
|
|
106
|
+
sessionId,
|
|
107
|
+
metadata: {
|
|
108
|
+
progressEvent,
|
|
109
|
+
milestone: progressEvent.milestone?.name,
|
|
110
|
+
estimatedCompletion: progressEvent.estimatedCompletion
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const analysisResult = {
|
|
116
|
+
success: false,
|
|
117
|
+
responses: [],
|
|
118
|
+
sessionId,
|
|
119
|
+
analysis: {
|
|
120
|
+
startTime,
|
|
121
|
+
endTime: 0,
|
|
122
|
+
duration: 0,
|
|
123
|
+
eventsEmitted: 0,
|
|
124
|
+
progressMilestones: 0,
|
|
125
|
+
circuitBreakerTrips: 0,
|
|
126
|
+
fallbacksUsed: 0
|
|
127
|
+
},
|
|
128
|
+
streaming: {
|
|
129
|
+
connectedClients: 0,
|
|
130
|
+
eventsSent: 0,
|
|
131
|
+
averageLatency: 0,
|
|
132
|
+
bufferHits: 0
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
try {
|
|
136
|
+
// Enhanced CLI options with streaming callbacks
|
|
137
|
+
const enhancedOptions = {
|
|
138
|
+
...options,
|
|
139
|
+
sessionId,
|
|
140
|
+
onStreamingEvent: this.createStreamingEventHandler(sessionId, progressTracker, analysisResult),
|
|
141
|
+
timeout: options.streamingTimeout || this.config.defaultTimeout
|
|
142
|
+
};
|
|
143
|
+
// Execute CLI agents with circuit breaker protection if enabled
|
|
144
|
+
if (options.enableCircuitBreaker !== false) {
|
|
145
|
+
analysisResult.responses = await this.executeWithCircuitBreaker(cliAgents, systemPrompt, userPrompt, enhancedOptions);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
// Direct execution without circuit breaker
|
|
149
|
+
analysisResult.responses = await this.cliOrchestrator.executeCLIAgents(cliAgents, systemPrompt, userPrompt, enhancedOptions);
|
|
150
|
+
}
|
|
151
|
+
analysisResult.success = analysisResult.responses.some(r => r.success);
|
|
152
|
+
// Mark progress as complete
|
|
153
|
+
if (progressTracker) {
|
|
154
|
+
progressTracker.markComplete();
|
|
155
|
+
}
|
|
156
|
+
this.metrics.successfulAnalyses++;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
logger.error(`💥 Streaming analysis failed for session ${sessionId}:`, error);
|
|
160
|
+
analysisResult.success = false;
|
|
161
|
+
analysisResult.errors = [error instanceof Error ? error.message : String(error)];
|
|
162
|
+
// Handle fallback if configured
|
|
163
|
+
if (options.fallbackResponse) {
|
|
164
|
+
analysisResult.responses = [{
|
|
165
|
+
agent: 'claude', // Use a valid agent type for fallback
|
|
166
|
+
success: true,
|
|
167
|
+
output: typeof options.fallbackResponse === 'string'
|
|
168
|
+
? options.fallbackResponse
|
|
169
|
+
: JSON.stringify(options.fallbackResponse),
|
|
170
|
+
executionTime: Date.now() - startTime,
|
|
171
|
+
command: 'fallback',
|
|
172
|
+
workingDirectory: options.workingDirectory || process.cwd(),
|
|
173
|
+
exitCode: 0
|
|
174
|
+
}];
|
|
175
|
+
analysisResult.analysis.fallbacksUsed++;
|
|
176
|
+
this.metrics.totalFallbacksUsed++;
|
|
177
|
+
}
|
|
178
|
+
this.metrics.failedAnalyses++;
|
|
179
|
+
}
|
|
180
|
+
finally {
|
|
181
|
+
const endTime = Date.now();
|
|
182
|
+
analysisResult.analysis.endTime = endTime;
|
|
183
|
+
analysisResult.analysis.duration = endTime - startTime;
|
|
184
|
+
// Get streaming stats
|
|
185
|
+
const sessionConnections = this.sseTransport.getSessionConnections(sessionId);
|
|
186
|
+
analysisResult.streaming.connectedClients = sessionConnections.length;
|
|
187
|
+
analysisResult.streaming.eventsSent = sessionConnections.reduce((sum, conn) => sum + conn.eventsSent, 0);
|
|
188
|
+
// Get session metrics
|
|
189
|
+
const sessionStats = this.sessionManager.getSessionStats(sessionId);
|
|
190
|
+
if (sessionStats) {
|
|
191
|
+
analysisResult.analysis.eventsEmitted = sessionStats.eventsEmitted;
|
|
192
|
+
analysisResult.streaming.bufferHits = sessionStats.bufferStats.flushCount;
|
|
193
|
+
}
|
|
194
|
+
// Update global metrics
|
|
195
|
+
this.metrics.totalAnalyses++;
|
|
196
|
+
this.updateAverageAnalysisDuration(analysisResult.analysis.duration);
|
|
197
|
+
// Cleanup
|
|
198
|
+
this.activeAnalyses.delete(sessionId);
|
|
199
|
+
this.sessionManager.completeSession(sessionId);
|
|
200
|
+
// Keep SSE connections open briefly for final events
|
|
201
|
+
setTimeout(() => {
|
|
202
|
+
this.sseTransport.disconnectSession(sessionId, 'analysis_complete');
|
|
203
|
+
}, 5000);
|
|
204
|
+
logger.info(`🏁 Streaming analysis completed: ${sessionId} (${analysisResult.analysis.duration}ms)`, {
|
|
205
|
+
success: analysisResult.success,
|
|
206
|
+
eventsEmitted: analysisResult.analysis.eventsEmitted,
|
|
207
|
+
connectedClients: analysisResult.streaming.connectedClients
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return analysisResult;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create streaming event handler for session
|
|
214
|
+
*/
|
|
215
|
+
createStreamingEventHandler(sessionId, progressTracker, result) {
|
|
216
|
+
return (event) => {
|
|
217
|
+
// Process event through progress tracker
|
|
218
|
+
if (progressTracker) {
|
|
219
|
+
progressTracker.processEvent(event);
|
|
220
|
+
}
|
|
221
|
+
// Emit to session manager (which handles SSE transport)
|
|
222
|
+
this.sessionManager.emitToSession(sessionId, event);
|
|
223
|
+
// Update metrics
|
|
224
|
+
result.analysis.eventsEmitted++;
|
|
225
|
+
this.metrics.totalEventsSent++;
|
|
226
|
+
// Emit orchestrator-level event
|
|
227
|
+
this.emit('streamingEvent', { sessionId, event });
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Execute CLI agents with circuit breaker protection
|
|
232
|
+
*/
|
|
233
|
+
async executeWithCircuitBreaker(cliAgents, systemPrompt, userPrompt, options) {
|
|
234
|
+
const responses = [];
|
|
235
|
+
for (const agent of cliAgents) {
|
|
236
|
+
const circuitBreaker = this.circuitBreakers.get(agent);
|
|
237
|
+
if (!circuitBreaker) {
|
|
238
|
+
throw new Error(`No circuit breaker configured for agent: ${agent}`);
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
const response = await circuitBreaker.execute(async () => {
|
|
242
|
+
return await this.cliOrchestrator.executeCLIAgent(agent, systemPrompt, userPrompt, options);
|
|
243
|
+
}, { id: `${agent}_${options.sessionId}` });
|
|
244
|
+
responses.push(response);
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
logger.warn(`Circuit breaker blocked execution for ${agent}:`, error);
|
|
248
|
+
// Circuit breaker handled the error, continue with other agents
|
|
249
|
+
responses.push({
|
|
250
|
+
agent: agent,
|
|
251
|
+
success: false,
|
|
252
|
+
output: '',
|
|
253
|
+
error: `Circuit breaker: ${error instanceof Error ? error.message : String(error)}`,
|
|
254
|
+
executionTime: 0,
|
|
255
|
+
command: 'circuit_breaker_blocked',
|
|
256
|
+
workingDirectory: options.workingDirectory || process.cwd(),
|
|
257
|
+
exitCode: -1
|
|
258
|
+
});
|
|
259
|
+
this.metrics.totalCircuitBreakerTrips++;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return responses;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Setup event handlers for internal components
|
|
266
|
+
*/
|
|
267
|
+
setupEventHandlers() {
|
|
268
|
+
// Session manager events
|
|
269
|
+
this.sessionManager.on('sessionCreated', (sessionId) => {
|
|
270
|
+
logger.debug(`📝 Session created: ${sessionId}`);
|
|
271
|
+
this.emit('sessionCreated', sessionId);
|
|
272
|
+
});
|
|
273
|
+
this.sessionManager.on('sessionCompleted', (sessionId) => {
|
|
274
|
+
logger.debug(`✅ Session completed: ${sessionId}`);
|
|
275
|
+
this.emit('sessionCompleted', sessionId);
|
|
276
|
+
});
|
|
277
|
+
// SSE transport events
|
|
278
|
+
this.sseTransport.on('connectionClosed', (data) => {
|
|
279
|
+
logger.debug(`🔌 SSE connection closed: ${data.connectionId} (${data.reason})`);
|
|
280
|
+
this.emit('connectionClosed', data);
|
|
281
|
+
});
|
|
282
|
+
// Circuit breaker events
|
|
283
|
+
this.on('circuitBreakerStateChanged', (data) => {
|
|
284
|
+
logger.info(`🔌 Circuit breaker state changed: ${data.agent} -> ${data.state}`);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Setup circuit breakers for each CLI agent
|
|
289
|
+
*/
|
|
290
|
+
setupCircuitBreakers() {
|
|
291
|
+
const agents = ['claude', 'codex', 'gemini'];
|
|
292
|
+
for (const agent of agents) {
|
|
293
|
+
const circuitBreaker = new CircuitBreaker(this.config.circuitBreakerConfig, `${agent}_breaker`);
|
|
294
|
+
// Add fallback strategies
|
|
295
|
+
if (this.responseCache.size > 0) {
|
|
296
|
+
circuitBreaker.addFallbackStrategy(new CachedResponseFallback(this.responseCache));
|
|
297
|
+
}
|
|
298
|
+
circuitBreaker.addFallbackStrategy(new DegradedServiceFallback({
|
|
299
|
+
agent,
|
|
300
|
+
success: false,
|
|
301
|
+
output: `${agent.toUpperCase()} is temporarily unavailable. This is a degraded response.`,
|
|
302
|
+
error: 'Circuit breaker fallback',
|
|
303
|
+
executionTime: 0,
|
|
304
|
+
command: 'fallback',
|
|
305
|
+
workingDirectory: process.cwd(),
|
|
306
|
+
exitCode: -1
|
|
307
|
+
}));
|
|
308
|
+
// Setup event forwarding
|
|
309
|
+
circuitBreaker.on('stateChanged', (data) => {
|
|
310
|
+
this.emit('circuitBreakerStateChanged', { agent, ...data });
|
|
311
|
+
});
|
|
312
|
+
circuitBreaker.on('fallbackSuccess', (data) => {
|
|
313
|
+
this.metrics.totalFallbacksUsed++;
|
|
314
|
+
this.emit('fallbackUsed', { agent, ...data });
|
|
315
|
+
});
|
|
316
|
+
this.circuitBreakers.set(agent, circuitBreaker);
|
|
317
|
+
logger.debug(`🔌 Circuit breaker configured for ${agent}`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Update average analysis duration metric
|
|
322
|
+
*/
|
|
323
|
+
updateAverageAnalysisDuration(duration) {
|
|
324
|
+
const totalAnalyses = this.metrics.totalAnalyses;
|
|
325
|
+
const currentAverage = this.metrics.averageAnalysisDuration;
|
|
326
|
+
// Calculate new average using online algorithm
|
|
327
|
+
this.metrics.averageAnalysisDuration =
|
|
328
|
+
(currentAverage * (totalAnalyses - 1) + duration) / totalAnalyses;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Start cleanup timer for stale sessions and cache
|
|
332
|
+
*/
|
|
333
|
+
startCleanupTimer() {
|
|
334
|
+
this.cleanupTimer = setInterval(() => {
|
|
335
|
+
this.performCleanup();
|
|
336
|
+
}, this.config.cleanupInterval);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Perform periodic cleanup
|
|
340
|
+
*/
|
|
341
|
+
performCleanup() {
|
|
342
|
+
const now = Date.now();
|
|
343
|
+
const staleThreshold = 30 * 60 * 1000; // 30 minutes
|
|
344
|
+
// Clean up stale analyses
|
|
345
|
+
for (const [sessionId, analysis] of this.activeAnalyses) {
|
|
346
|
+
if (now - analysis.startTime > staleThreshold) {
|
|
347
|
+
logger.warn(`🧹 Cleaning up stale analysis: ${sessionId}`);
|
|
348
|
+
this.activeAnalyses.delete(sessionId);
|
|
349
|
+
this.sessionManager.completeSession(sessionId);
|
|
350
|
+
this.sseTransport.disconnectSession(sessionId, 'cleanup_stale');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Clean up response cache (keep last 100 entries)
|
|
354
|
+
if (this.responseCache.size > 100) {
|
|
355
|
+
const entries = Array.from(this.responseCache.entries());
|
|
356
|
+
entries.splice(0, entries.length - 100);
|
|
357
|
+
this.responseCache.clear();
|
|
358
|
+
for (const [key, value] of entries) {
|
|
359
|
+
this.responseCache.set(key, value);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
logger.debug(`🧹 Cleanup completed: ${this.activeAnalyses.size} active analyses, ${this.responseCache.size} cached responses`);
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Get orchestrator statistics
|
|
366
|
+
*/
|
|
367
|
+
getStats() {
|
|
368
|
+
const circuitBreakerStats = {};
|
|
369
|
+
for (const [agent, breaker] of this.circuitBreakers) {
|
|
370
|
+
circuitBreakerStats[agent] = breaker.getStats();
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
metrics: { ...this.metrics },
|
|
374
|
+
activeAnalyses: this.activeAnalyses.size,
|
|
375
|
+
sessionManager: this.sessionManager.getGlobalStats(),
|
|
376
|
+
sseTransport: this.sseTransport.getStats(),
|
|
377
|
+
circuitBreakers: circuitBreakerStats
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Get active session IDs
|
|
382
|
+
*/
|
|
383
|
+
getActiveSessions() {
|
|
384
|
+
return Array.from(this.activeAnalyses.keys());
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Force disconnect session
|
|
388
|
+
*/
|
|
389
|
+
disconnectSession(sessionId, reason = 'forced_disconnect') {
|
|
390
|
+
logger.info(`🔌 Force disconnecting session: ${sessionId}`);
|
|
391
|
+
this.activeAnalyses.delete(sessionId);
|
|
392
|
+
this.sessionManager.completeSession(sessionId);
|
|
393
|
+
this.sseTransport.disconnectSession(sessionId, reason);
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Reset circuit breaker for specific agent
|
|
397
|
+
*/
|
|
398
|
+
resetCircuitBreaker(agent) {
|
|
399
|
+
const circuitBreaker = this.circuitBreakers.get(agent);
|
|
400
|
+
if (circuitBreaker) {
|
|
401
|
+
circuitBreaker.reset();
|
|
402
|
+
logger.info(`🔄 Circuit breaker reset for ${agent}`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Add response to cache for fallback strategies
|
|
407
|
+
*/
|
|
408
|
+
cacheResponse(key, response) {
|
|
409
|
+
this.responseCache.set(key, response);
|
|
410
|
+
logger.debug(`💾 Cached response: ${key}`);
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Shutdown orchestrator and cleanup resources
|
|
414
|
+
*/
|
|
415
|
+
shutdown() {
|
|
416
|
+
logger.info('🛑 Shutting down Streaming CLI Orchestrator');
|
|
417
|
+
// Stop cleanup timer
|
|
418
|
+
if (this.cleanupTimer) {
|
|
419
|
+
clearInterval(this.cleanupTimer);
|
|
420
|
+
}
|
|
421
|
+
// Disconnect all sessions
|
|
422
|
+
for (const sessionId of this.activeAnalyses.keys()) {
|
|
423
|
+
this.disconnectSession(sessionId, 'orchestrator_shutdown');
|
|
424
|
+
}
|
|
425
|
+
// Shutdown components
|
|
426
|
+
this.sseTransport.shutdown();
|
|
427
|
+
this.sessionManager.shutdown();
|
|
428
|
+
// Shutdown circuit breakers
|
|
429
|
+
for (const [agent, breaker] of this.circuitBreakers) {
|
|
430
|
+
breaker.shutdown();
|
|
431
|
+
}
|
|
432
|
+
this.removeAllListeners();
|
|
433
|
+
logger.info('✅ Streaming CLI Orchestrator shutdown complete');
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
//# sourceMappingURL=streaming-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming-orchestrator.js","sourceRoot":"","sources":["../../src/streaming/streaming-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAmC,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAwB,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAsD7H;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,wBAAyB,SAAQ,YAAY;IAChD,eAAe,CAAuB;IACtC,cAAc,CAAiB;IAC/B,YAAY,CAAuB;IACnC,eAAe,GAAG,IAAI,GAAG,EAA0B,CAAC;IACpD,aAAa,GAAG,IAAI,GAAG,EAAe,CAAC;IACvC,cAAc,GAAG,IAAI,GAAG,EAK5B,CAAC;IAEG,MAAM,CAA8B;IACpC,OAAO,GAAG;QAChB,aAAa,EAAE,CAAC;QAChB,kBAAkB,EAAE,CAAC;QACrB,cAAc,EAAE,CAAC;QACjB,eAAe,EAAE,CAAC;QAClB,wBAAwB,EAAE,CAAC;QAC3B,kBAAkB,EAAE,CAAC;QACrB,uBAAuB,EAAE,CAAC;KAC3B,CAAC;IAEM,YAAY,CAAkB;IAEtC,YAAY,MAA6C;QACvD,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,MAAM,GAAG;YACZ,qBAAqB,EAAE,EAAE;YACzB,cAAc,EAAE,MAAM,EAAE,aAAa;YACrC,oBAAoB,EAAE;gBACpB,gBAAgB,EAAE,CAAC;gBACnB,eAAe,EAAE,KAAK;gBACtB,gBAAgB,EAAE,CAAC;gBACnB,OAAO,EAAE,MAAM;gBACf,gBAAgB,EAAE,MAAM;gBACxB,eAAe,EAAE,EAAE;aACpB;YACD,aAAa,EAAE,IAAI;YACnB,eAAe,EAAE,MAAM,EAAE,YAAY;YACrC,GAAG,MAAM;SACV,CAAC;QAEF,IAAI,CAAC,eAAe,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAClD,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAElE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,MAAM,CAAC,IAAI,CAAC,2CAA2C,EAAE;YACvD,qBAAqB,EAAE,IAAI,CAAC,MAAM,CAAC,qBAAqB;YACxD,qBAAqB,EAAE,IAAI;YAC3B,uBAAuB,EAAE,IAAI;SAC9B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,oBAAoB,CACxB,YAAoB,EACpB,SAAmB,EACnB,YAAoB,EACpB,UAAkB,EAClB,UAAqC,EAAE;QAEvC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,WAAW,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC1G,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,kCAAkC;QAClC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,CAAC,MAAM,CAAC,qBAAqB,GAAG,CAAC,CAAC;QAChG,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,mCAAmC,YAAY,gBAAgB,SAAS,EAAE,EAAE;YACtF,MAAM,EAAE,SAAS;YACjB,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;SACnD,CAAC,CAAC;QAEH,sCAAsC;QACtC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,SAAS,EAAE;YAClE,YAAY;YACZ,MAAM,EAAE,SAAS;YACjB,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,eAAe,GAAG,OAAO,CAAC,cAAc,KAAK,KAAK;YACtD,CAAC,CAAC,IAAI,eAAe,CAAC,SAAS,EAAE,YAAY,CAAC;YAC9C,CAAC,CAAC,SAAS,CAAC;QAEd,wBAAwB;QACxB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE;YACjC,SAAS;YACT,eAAe,EAAE,eAAgB;YACjC,SAAS;YACT,OAAO;SACR,CAAC,CAAC;QAEH,qCAAqC;QACrC,IAAI,eAAe,EAAE,CAAC;YACpB,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,aAAa,EAAE,EAAE;gBAC/C,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,SAAS,EAAE;oBAC3C,IAAI,EAAE,gBAAgB;oBACtB,KAAK,EAAE,QAAe;oBACtB,OAAO,EAAE,aAAa,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,aAAa,CAAC,KAAK,EAAE;oBAClG,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB,SAAS;oBACT,QAAQ,EAAE;wBACR,aAAa;wBACb,SAAS,EAAE,aAAa,CAAC,SAAS,EAAE,IAAI;wBACxC,mBAAmB,EAAE,aAAa,CAAC,mBAAmB;qBACvD;iBACF,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,cAAc,GAA6B;YAC/C,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,EAAE;YACb,SAAS;YACT,QAAQ,EAAE;gBACR,SAAS;gBACT,OAAO,EAAE,CAAC;gBACV,QAAQ,EAAE,CAAC;gBACX,aAAa,EAAE,CAAC;gBAChB,kBAAkB,EAAE,CAAC;gBACrB,mBAAmB,EAAE,CAAC;gBACtB,aAAa,EAAE,CAAC;aACjB;YACD,SAAS,EAAE;gBACT,gBAAgB,EAAE,CAAC;gBACnB,UAAU,EAAE,CAAC;gBACb,cAAc,EAAE,CAAC;gBACjB,UAAU,EAAE,CAAC;aACd;SACF,CAAC;QAEF,IAAI,CAAC;YACH,gDAAgD;YAChD,MAAM,eAAe,GAAoB;gBACvC,GAAG,OAAO;gBACV,SAAS;gBACT,gBAAgB,EAAE,IAAI,CAAC,2BAA2B,CAAC,SAAS,EAAE,eAAe,EAAE,cAAc,CAAC;gBAC9F,OAAO,EAAE,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc;aAChE,CAAC;YAEF,gEAAgE;YAChE,IAAI,OAAO,CAAC,oBAAoB,KAAK,KAAK,EAAE,CAAC;gBAC3C,cAAc,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAC7D,SAAS,EACT,YAAY,EACZ,UAAU,EACV,eAAe,CAChB,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,2CAA2C;gBAC3C,cAAc,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,gBAAgB,CACpE,SAAS,EACT,YAAY,EACZ,UAAU,EACV,eAAe,CAChB,CAAC;YACJ,CAAC;YAED,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAEvE,4BAA4B;YAC5B,IAAI,eAAe,EAAE,CAAC;gBACpB,eAAe,CAAC,YAAY,EAAE,CAAC;YACjC,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAEpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,4CAA4C,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;YAE9E,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC;YAC/B,cAAc,CAAC,MAAM,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAEjF,gCAAgC;YAChC,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;gBAC7B,cAAc,CAAC,SAAS,GAAG,CAAC;wBAC1B,KAAK,EAAE,QAAQ,EAAE,sCAAsC;wBACvD,OAAO,EAAE,IAAI;wBACb,MAAM,EAAE,OAAO,OAAO,CAAC,gBAAgB,KAAK,QAAQ;4BAClD,CAAC,CAAC,OAAO,CAAC,gBAAgB;4BAC1B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,gBAAgB,CAAC;wBAC5C,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;wBACrC,OAAO,EAAE,UAAU;wBACnB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,EAAE;wBAC3D,QAAQ,EAAE,CAAC;qBACZ,CAAC,CAAC;gBAEH,cAAc,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;gBACxC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;YACpC,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAEhC,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE3B,cAAc,CAAC,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;YAC1C,cAAc,CAAC,QAAQ,CAAC,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;YAEvD,sBAAsB;YACtB,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;YAC9E,cAAc,CAAC,SAAS,CAAC,gBAAgB,GAAG,kBAAkB,CAAC,MAAM,CAAC;YACtE,cAAc,CAAC,SAAS,CAAC,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAEzG,sBAAsB;YACtB,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YACpE,IAAI,YAAY,EAAE,CAAC;gBACjB,cAAc,CAAC,QAAQ,CAAC,aAAa,GAAG,YAAY,CAAC,aAAa,CAAC;gBACnE,cAAc,CAAC,SAAS,CAAC,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,UAAU,CAAC;YAC5E,CAAC;YAED,wBAAwB;YACxB,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC7B,IAAI,CAAC,6BAA6B,CAAC,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAErE,UAAU;YACV,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACtC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAE/C,qDAAqD;YACrD,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;YACtE,CAAC,EAAE,IAAI,CAAC,CAAC;YAET,MAAM,CAAC,IAAI,CAAC,oCAAoC,SAAS,KAAK,cAAc,CAAC,QAAQ,CAAC,QAAQ,KAAK,EAAE;gBACnG,OAAO,EAAE,cAAc,CAAC,OAAO;gBAC/B,aAAa,EAAE,cAAc,CAAC,QAAQ,CAAC,aAAa;gBACpD,gBAAgB,EAAE,cAAc,CAAC,SAAS,CAAC,gBAAgB;aAC5D,CAAC,CAAC;QACL,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;OAEG;IACK,2BAA2B,CACjC,SAAiB,EACjB,eAA4C,EAC5C,MAAgC;QAEhC,OAAO,CAAC,KAAqB,EAAE,EAAE;YAC/B,yCAAyC;YACzC,IAAI,eAAe,EAAE,CAAC;gBACpB,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;YAED,wDAAwD;YACxD,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAEpD,iBAAiB;YACjB,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;YAE/B,gCAAgC;YAChC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,yBAAyB,CACrC,SAAmB,EACnB,YAAoB,EACpB,UAAkB,EAClB,OAAwB;QAExB,MAAM,SAAS,GAAuB,EAAE,CAAC;QAEzC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC9B,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACvD,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,4CAA4C,KAAK,EAAE,CAAC,CAAC;YACvE,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;oBACvD,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,eAAe,CAC/C,KAAK,EACL,YAAY,EACZ,UAAU,EACV,OAAO,CACR,CAAC;gBACJ,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBAE5C,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAE3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,yCAAyC,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC;gBAEtE,gEAAgE;gBAChE,SAAS,CAAC,IAAI,CAAC;oBACb,KAAK,EAAE,KAAsC;oBAC7C,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,EAAE;oBACV,KAAK,EAAE,oBAAoB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;oBACnF,aAAa,EAAE,CAAC;oBAChB,OAAO,EAAE,yBAAyB;oBAClC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,EAAE;oBAC3D,QAAQ,EAAE,CAAC,CAAC;iBACb,CAAC,CAAC;gBAEH,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,yBAAyB;QACzB,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,SAAiB,EAAE,EAAE;YAC7D,MAAM,CAAC,KAAK,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,SAAiB,EAAE,EAAE;YAC/D,MAAM,CAAC,KAAK,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,uBAAuB;QACvB,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,IAAS,EAAE,EAAE;YACrD,MAAM,CAAC,KAAK,CAAC,6BAA6B,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;YAChF,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,yBAAyB;QACzB,IAAI,CAAC,EAAE,CAAC,4BAA4B,EAAE,CAAC,IAAI,EAAE,EAAE;YAC7C,MAAM,CAAC,IAAI,CAAC,qCAAqC,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,GAAG,KAAK,UAAU,CAAC,CAAC;YAEhG,0BAA0B;YAC1B,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAChC,cAAc,CAAC,mBAAmB,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;YACrF,CAAC;YAED,cAAc,CAAC,mBAAmB,CAAC,IAAI,uBAAuB,CAAC;gBAC7D,KAAK;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,2DAA2D;gBACzF,KAAK,EAAE,0BAA0B;gBACjC,aAAa,EAAE,CAAC;gBAChB,OAAO,EAAE,UAAU;gBACnB,gBAAgB,EAAE,OAAO,CAAC,GAAG,EAAE;gBAC/B,QAAQ,EAAE,CAAC,CAAC;aACb,CAAC,CAAC,CAAC;YAEJ,yBAAyB;YACzB,cAAc,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzC,IAAI,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;YAEH,cAAc,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC5C,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YAEhD,MAAM,CAAC,KAAK,CAAC,qCAAqC,KAAK,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED;;OAEG;IACK,6BAA6B,CAAC,QAAgB;QACpD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC;QAE5D,+CAA+C;QAC/C,IAAI,CAAC,OAAO,CAAC,uBAAuB;YAClC,CAAC,cAAc,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,aAAa,CAAC;IACtE,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;YACnC,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;QAEpD,0BAA0B;QAC1B,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxD,IAAI,GAAG,GAAG,QAAQ,CAAC,SAAS,GAAG,cAAc,EAAE,CAAC;gBAC9C,MAAM,CAAC,IAAI,CAAC,kCAAkC,SAAS,EAAE,CAAC,CAAC;gBAC3D,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBACtC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;gBAC/C,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,kDAAkD;QAClD,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;YACxC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;gBACnC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,cAAc,CAAC,IAAI,qBAAqB,IAAI,CAAC,aAAa,CAAC,IAAI,mBAAmB,CAAC,CAAC;IACjI,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,MAAM,mBAAmB,GAAwB,EAAE,CAAC;QACpD,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACpD,mBAAmB,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QAClD,CAAC;QAED,OAAO;YACL,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE;YAC5B,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI;YACxC,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE;YACpD,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;YAC1C,eAAe,EAAE,mBAAmB;SACrC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,SAAiB,EAAE,MAAM,GAAG,mBAAmB;QAC/D,MAAM,CAAC,IAAI,CAAC,mCAAmC,SAAS,EAAE,CAAC,CAAC;QAE5D,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,KAAa;QAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvD,IAAI,cAAc,EAAE,CAAC;YACnB,cAAc,CAAC,KAAK,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,GAAW,EAAE,QAAa;QACtC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAE3D,qBAAqB;QACrB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACnC,CAAC;QAED,0BAA0B;QAC1B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC;YACnD,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;QAC7D,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;QAE/B,4BAA4B;QAC5B,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACpD,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,MAAM,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAChE,CAAC;CACF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ChildProcess } from 'child_process';
|
|
2
|
+
export interface ManagedProcess {
|
|
3
|
+
pid: number;
|
|
4
|
+
command: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
process: ChildProcess;
|
|
7
|
+
stdout: string;
|
|
8
|
+
stderr: string;
|
|
9
|
+
killed: boolean;
|
|
10
|
+
startTime: number;
|
|
11
|
+
}
|
|
12
|
+
export interface SpawnOptions {
|
|
13
|
+
cwd?: string;
|
|
14
|
+
timeout?: number;
|
|
15
|
+
maxBuffer?: number;
|
|
16
|
+
input?: string;
|
|
17
|
+
env?: Record<string, string>;
|
|
18
|
+
onProgress?: (chunk: string, type: 'stdout' | 'stderr') => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Cross-platform process manager that tracks all spawned processes
|
|
22
|
+
* and ensures proper cleanup, preventing orphaned processes in tests
|
|
23
|
+
*/
|
|
24
|
+
export declare class ProcessManager {
|
|
25
|
+
private static instance;
|
|
26
|
+
private processes;
|
|
27
|
+
private readonly isWindows;
|
|
28
|
+
private cleanupRegistered;
|
|
29
|
+
private constructor();
|
|
30
|
+
static getInstance(): ProcessManager;
|
|
31
|
+
private registerCleanupHandlers;
|
|
32
|
+
/**
|
|
33
|
+
* Spawn a managed process with automatic tracking and cleanup
|
|
34
|
+
*/
|
|
35
|
+
spawn(command: string, args: string[], options?: SpawnOptions): Promise<{
|
|
36
|
+
stdout: string;
|
|
37
|
+
stderr: string;
|
|
38
|
+
exitCode: number | null;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Kill a process and all its children (cross-platform)
|
|
42
|
+
*/
|
|
43
|
+
killProcessTree(pid: number, signal?: NodeJS.Signals): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Get all currently running managed processes
|
|
46
|
+
*/
|
|
47
|
+
getRunningProcesses(): ManagedProcess[];
|
|
48
|
+
/**
|
|
49
|
+
* Clean up all tracked processes
|
|
50
|
+
*/
|
|
51
|
+
cleanup(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Get diagnostic information about running processes
|
|
54
|
+
*/
|
|
55
|
+
getDiagnostics(): string;
|
|
56
|
+
/**
|
|
57
|
+
* Assert no processes are leaked (for test cleanup validation)
|
|
58
|
+
*/
|
|
59
|
+
assertNoLeakedProcesses(): void;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=process-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/test-utils/process-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmB,MAAM,eAAe,CAAC;AAI9D,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,KAAK,IAAI,CAAC;CACjE;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiB;IACxC,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO;IAKP,MAAM,CAAC,WAAW,IAAI,cAAc;IAOpC,OAAO,CAAC,uBAAuB;IAkB/B;;OAEG;IACG,KAAK,CACT,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IA0HvE;;OAEG;IACG,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDrF;;OAEG;IACH,mBAAmB,IAAI,cAAc,EAAE;IAIvC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB9B;;OAEG;IACH,cAAc,IAAI,MAAM;IAqBxB;;OAEG;IACH,uBAAuB,IAAI,IAAI;CAOhC"}
|