@brutalist/mcp 0.6.0 → 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.
Files changed (67) hide show
  1. package/README.md +3 -1
  2. package/dist/brutalist-server.d.ts +5 -0
  3. package/dist/brutalist-server.d.ts.map +1 -1
  4. package/dist/brutalist-server.js +244 -80
  5. package/dist/brutalist-server.js.map +1 -1
  6. package/dist/cli-agents.d.ts +7 -3
  7. package/dist/cli-agents.d.ts.map +1 -1
  8. package/dist/cli-agents.js +307 -48
  9. package/dist/cli-agents.js.map +1 -1
  10. package/dist/streaming/circuit-breaker.d.ts +186 -0
  11. package/dist/streaming/circuit-breaker.d.ts.map +1 -0
  12. package/dist/streaming/circuit-breaker.js +463 -0
  13. package/dist/streaming/circuit-breaker.js.map +1 -0
  14. package/dist/streaming/intelligent-buffer.d.ts +141 -0
  15. package/dist/streaming/intelligent-buffer.d.ts.map +1 -0
  16. package/dist/streaming/intelligent-buffer.js +555 -0
  17. package/dist/streaming/intelligent-buffer.js.map +1 -0
  18. package/dist/streaming/output-parser.d.ts +89 -0
  19. package/dist/streaming/output-parser.d.ts.map +1 -0
  20. package/dist/streaming/output-parser.js +349 -0
  21. package/dist/streaming/output-parser.js.map +1 -0
  22. package/dist/streaming/progress-tracker.d.ts +149 -0
  23. package/dist/streaming/progress-tracker.d.ts.map +1 -0
  24. package/dist/streaming/progress-tracker.js +519 -0
  25. package/dist/streaming/progress-tracker.js.map +1 -0
  26. package/dist/streaming/session-manager.d.ts +238 -0
  27. package/dist/streaming/session-manager.d.ts.map +1 -0
  28. package/dist/streaming/session-manager.js +546 -0
  29. package/dist/streaming/session-manager.js.map +1 -0
  30. package/dist/streaming/sse-transport.d.ts +95 -0
  31. package/dist/streaming/sse-transport.d.ts.map +1 -0
  32. package/dist/streaming/sse-transport.js +319 -0
  33. package/dist/streaming/sse-transport.js.map +1 -0
  34. package/dist/streaming/streaming-orchestrator.d.ts +153 -0
  35. package/dist/streaming/streaming-orchestrator.d.ts.map +1 -0
  36. package/dist/streaming/streaming-orchestrator.js +436 -0
  37. package/dist/streaming/streaming-orchestrator.js.map +1 -0
  38. package/dist/test-utils/process-manager.d.ts +61 -0
  39. package/dist/test-utils/process-manager.d.ts.map +1 -0
  40. package/dist/test-utils/process-manager.js +262 -0
  41. package/dist/test-utils/process-manager.js.map +1 -0
  42. package/dist/test-utils/server-harness.d.ts +73 -0
  43. package/dist/test-utils/server-harness.d.ts.map +1 -0
  44. package/dist/test-utils/server-harness.js +296 -0
  45. package/dist/test-utils/server-harness.js.map +1 -0
  46. package/dist/test-utils/streaming-fuzz.d.ts +57 -0
  47. package/dist/test-utils/streaming-fuzz.d.ts.map +1 -0
  48. package/dist/test-utils/streaming-fuzz.js +287 -0
  49. package/dist/test-utils/streaming-fuzz.js.map +1 -0
  50. package/dist/test-utils/test-isolation.d.ts +70 -0
  51. package/dist/test-utils/test-isolation.d.ts.map +1 -0
  52. package/dist/test-utils/test-isolation.js +193 -0
  53. package/dist/test-utils/test-isolation.js.map +1 -0
  54. package/dist/tool-definitions.d.ts.map +1 -1
  55. package/dist/tool-definitions.js +12 -6
  56. package/dist/tool-definitions.js.map +1 -1
  57. package/dist/types/brutalist.d.ts +3 -3
  58. package/dist/types/brutalist.d.ts.map +1 -1
  59. package/dist/types/tool-config.d.ts +0 -1
  60. package/dist/types/tool-config.d.ts.map +1 -1
  61. package/dist/types/tool-config.js +0 -1
  62. package/dist/types/tool-config.js.map +1 -1
  63. package/dist/utils/response-cache.d.ts +14 -7
  64. package/dist/utils/response-cache.d.ts.map +1 -1
  65. package/dist/utils/response-cache.js +173 -62
  66. package/dist/utils/response-cache.js.map +1 -1
  67. package/package.json +13 -3
@@ -0,0 +1,319 @@
1
+ import { EventEmitter } from 'events';
2
+ import { logger } from '../logger.js';
3
+ /**
4
+ * Enhanced Server-Sent Events transport with session isolation
5
+ *
6
+ * Features:
7
+ * - Session-scoped connections with isolation guarantees
8
+ * - Connection pooling with resource limits
9
+ * - Heartbeat monitoring and automatic cleanup
10
+ * - Graceful connection management
11
+ * - Event filtering and routing by session
12
+ * - Memory-efficient streaming with backpressure
13
+ */
14
+ export class EnhancedSSETransport extends EventEmitter {
15
+ connections = new Map();
16
+ sessionManager;
17
+ heartbeatInterval = null;
18
+ // Configuration constants
19
+ MAX_CONNECTIONS = 100;
20
+ HEARTBEAT_INTERVAL = 30000; // 30 seconds
21
+ CONNECTION_TIMEOUT = 300000; // 5 minutes
22
+ MAX_EVENTS_PER_CONNECTION = 10000;
23
+ constructor(sessionManager) {
24
+ super();
25
+ this.sessionManager = sessionManager;
26
+ this.startHeartbeat();
27
+ // Handle session events
28
+ this.sessionManager.on('streamingEvent', this.handleSessionEvent.bind(this));
29
+ this.sessionManager.on('sessionComplete', this.handleSessionComplete.bind(this));
30
+ }
31
+ /**
32
+ * Establish SSE connection for a session
33
+ */
34
+ async connect(req, res, sessionId) {
35
+ const connectionId = `${sessionId}-${Date.now()}`;
36
+ const clientOrigin = req.headers.origin || 'unknown';
37
+ // Validate session exists
38
+ if (!this.sessionManager.hasSession(sessionId)) {
39
+ res.status(404).json({ error: 'Session not found' });
40
+ return;
41
+ }
42
+ // Check connection limits
43
+ if (this.connections.size >= this.MAX_CONNECTIONS) {
44
+ logger.warn(`🚫 SSE connection limit reached (${this.MAX_CONNECTIONS})`);
45
+ res.status(503).json({ error: 'Connection limit reached' });
46
+ return;
47
+ }
48
+ // Set SSE headers
49
+ res.writeHead(200, {
50
+ 'Content-Type': 'text/event-stream',
51
+ 'Cache-Control': 'no-cache',
52
+ 'Connection': 'keep-alive',
53
+ 'Access-Control-Allow-Origin': clientOrigin,
54
+ 'Access-Control-Allow-Credentials': 'true'
55
+ });
56
+ // Send initial connection event
57
+ this.sendEvent(res, {
58
+ type: 'connection',
59
+ data: {
60
+ connectionId,
61
+ sessionId,
62
+ connectedAt: Date.now()
63
+ }
64
+ });
65
+ // Create connection record
66
+ const connection = {
67
+ id: connectionId,
68
+ sessionId,
69
+ response: res,
70
+ clientOrigin,
71
+ connectedAt: Date.now(),
72
+ lastActivity: Date.now(),
73
+ eventsSent: 0,
74
+ isActive: true
75
+ };
76
+ this.connections.set(connectionId, connection);
77
+ logger.info(`🔗 SSE connection established: ${connectionId} for session ${sessionId}`);
78
+ // Handle client disconnect
79
+ req.on('close', () => {
80
+ this.disconnect(connectionId, 'client_disconnect');
81
+ });
82
+ req.on('error', (error) => {
83
+ logger.error(`💥 SSE connection error for ${connectionId}:`, error);
84
+ this.disconnect(connectionId, 'connection_error');
85
+ });
86
+ // Send buffered events for this session
87
+ this.sendBufferedEvents(connection);
88
+ }
89
+ /**
90
+ * Handle streaming events from session manager
91
+ */
92
+ handleSessionEvent(event) {
93
+ if (!event.sessionId) {
94
+ logger.warn('⚠️ Received streaming event without session ID');
95
+ return;
96
+ }
97
+ // Find connections for this session
98
+ const sessionConnections = Array.from(this.connections.values())
99
+ .filter(conn => conn.sessionId === event.sessionId && conn.isActive);
100
+ if (sessionConnections.length === 0) {
101
+ logger.debug(`📭 No active SSE connections for session ${event.sessionId}`);
102
+ return;
103
+ }
104
+ // Send event to all session connections
105
+ for (const connection of sessionConnections) {
106
+ this.sendStreamingEvent(connection, event);
107
+ }
108
+ }
109
+ /**
110
+ * Handle session completion
111
+ */
112
+ handleSessionComplete(sessionId) {
113
+ logger.info(`🏁 Session ${sessionId} completed, closing SSE connections`);
114
+ const sessionConnections = Array.from(this.connections.values())
115
+ .filter(conn => conn.sessionId === sessionId);
116
+ for (const connection of sessionConnections) {
117
+ this.sendEvent(connection.response, {
118
+ type: 'session_complete',
119
+ data: {
120
+ sessionId,
121
+ completedAt: Date.now()
122
+ }
123
+ });
124
+ this.disconnect(connection.id, 'session_complete');
125
+ }
126
+ }
127
+ /**
128
+ * Send streaming event to specific connection
129
+ */
130
+ sendStreamingEvent(connection, event) {
131
+ if (!connection.isActive) {
132
+ return;
133
+ }
134
+ // Check event limit
135
+ if (connection.eventsSent >= this.MAX_EVENTS_PER_CONNECTION) {
136
+ logger.warn(`📊 Connection ${connection.id} reached event limit`);
137
+ this.disconnect(connection.id, 'event_limit_reached');
138
+ return;
139
+ }
140
+ try {
141
+ this.sendEvent(connection.response, {
142
+ type: 'streaming_event',
143
+ data: event
144
+ });
145
+ connection.eventsSent++;
146
+ connection.lastActivity = Date.now();
147
+ }
148
+ catch (error) {
149
+ logger.error(`💥 Failed to send event to ${connection.id}:`, error);
150
+ this.disconnect(connection.id, 'send_error');
151
+ }
152
+ }
153
+ /**
154
+ * Send buffered events for a newly connected session
155
+ */
156
+ sendBufferedEvents(connection) {
157
+ const sessionContext = this.sessionManager.getSession(connection.sessionId);
158
+ if (!sessionContext) {
159
+ return;
160
+ }
161
+ const bufferedEvents = sessionContext.eventBuffer.flush(connection.sessionId);
162
+ if (bufferedEvents && bufferedEvents.events.length > 0) {
163
+ logger.info(`📤 Sending ${bufferedEvents.events.length} buffered events to ${connection.id}`);
164
+ for (const event of bufferedEvents.events) {
165
+ this.sendStreamingEvent(connection, event);
166
+ }
167
+ }
168
+ }
169
+ /**
170
+ * Send raw SSE event
171
+ */
172
+ sendEvent(res, event) {
173
+ const eventId = Date.now().toString();
174
+ const eventData = JSON.stringify(event.data);
175
+ res.write(`id: ${eventId}\n`);
176
+ res.write(`event: ${event.type}\n`);
177
+ res.write(`data: ${eventData}\n\n`);
178
+ }
179
+ /**
180
+ * Disconnect and cleanup SSE connection
181
+ */
182
+ disconnect(connectionId, reason) {
183
+ const connection = this.connections.get(connectionId);
184
+ if (!connection) {
185
+ return;
186
+ }
187
+ logger.info(`🔌 Disconnecting SSE ${connectionId}: ${reason}`);
188
+ connection.isActive = false;
189
+ try {
190
+ if (!connection.response.destroyed) {
191
+ this.sendEvent(connection.response, {
192
+ type: 'disconnect',
193
+ data: {
194
+ reason,
195
+ disconnectedAt: Date.now(),
196
+ eventsSent: connection.eventsSent
197
+ }
198
+ });
199
+ connection.response.end();
200
+ }
201
+ }
202
+ catch (error) {
203
+ logger.debug(`Failed to send disconnect event: ${error}`);
204
+ }
205
+ this.connections.delete(connectionId);
206
+ this.emit('connectionClosed', {
207
+ connectionId,
208
+ sessionId: connection.sessionId,
209
+ reason,
210
+ duration: Date.now() - connection.connectedAt,
211
+ eventsSent: connection.eventsSent
212
+ });
213
+ }
214
+ /**
215
+ * Start heartbeat monitoring
216
+ */
217
+ startHeartbeat() {
218
+ this.heartbeatInterval = setInterval(() => {
219
+ this.checkConnectionHealth();
220
+ }, this.HEARTBEAT_INTERVAL);
221
+ }
222
+ /**
223
+ * Check connection health and cleanup stale connections
224
+ */
225
+ checkConnectionHealth() {
226
+ const now = Date.now();
227
+ const staleConnections = [];
228
+ for (const [connectionId, connection] of this.connections) {
229
+ if (!connection.isActive) {
230
+ staleConnections.push(connectionId);
231
+ continue;
232
+ }
233
+ // Check for timeout
234
+ if (now - connection.lastActivity > this.CONNECTION_TIMEOUT) {
235
+ logger.info(`⏰ Connection ${connectionId} timed out`);
236
+ staleConnections.push(connectionId);
237
+ continue;
238
+ }
239
+ // Send heartbeat
240
+ try {
241
+ this.sendEvent(connection.response, {
242
+ type: 'heartbeat',
243
+ data: {
244
+ timestamp: now,
245
+ sessionId: connection.sessionId
246
+ }
247
+ });
248
+ connection.lastActivity = now;
249
+ }
250
+ catch (error) {
251
+ logger.debug(`Heartbeat failed for ${connectionId}, marking for cleanup`);
252
+ staleConnections.push(connectionId);
253
+ }
254
+ }
255
+ // Cleanup stale connections
256
+ for (const connectionId of staleConnections) {
257
+ this.disconnect(connectionId, 'stale_connection');
258
+ }
259
+ if (this.connections.size > 0) {
260
+ logger.debug(`💓 Heartbeat: ${this.connections.size} active SSE connections`);
261
+ }
262
+ }
263
+ /**
264
+ * Get connection statistics
265
+ */
266
+ getStats() {
267
+ const activeConnections = Array.from(this.connections.values())
268
+ .filter(conn => conn.isActive);
269
+ const sessionDistribution = {};
270
+ let totalEvents = 0;
271
+ for (const connection of activeConnections) {
272
+ sessionDistribution[connection.sessionId] =
273
+ (sessionDistribution[connection.sessionId] || 0) + 1;
274
+ totalEvents += connection.eventsSent;
275
+ }
276
+ return {
277
+ totalConnections: this.connections.size,
278
+ activeConnections: activeConnections.length,
279
+ sessionDistribution,
280
+ averageEventsPerConnection: activeConnections.length > 0
281
+ ? totalEvents / activeConnections.length
282
+ : 0
283
+ };
284
+ }
285
+ /**
286
+ * Force disconnect all connections for a session
287
+ */
288
+ disconnectSession(sessionId, reason = 'forced_disconnect') {
289
+ const sessionConnections = Array.from(this.connections.values())
290
+ .filter(conn => conn.sessionId === sessionId);
291
+ for (const connection of sessionConnections) {
292
+ this.disconnect(connection.id, reason);
293
+ }
294
+ }
295
+ /**
296
+ * Cleanup and shutdown transport
297
+ */
298
+ shutdown() {
299
+ logger.info('🛑 Shutting down SSE transport');
300
+ if (this.heartbeatInterval) {
301
+ clearInterval(this.heartbeatInterval);
302
+ this.heartbeatInterval = null;
303
+ }
304
+ // Disconnect all connections
305
+ const connectionIds = Array.from(this.connections.keys());
306
+ for (const connectionId of connectionIds) {
307
+ this.disconnect(connectionId, 'server_shutdown');
308
+ }
309
+ this.removeAllListeners();
310
+ }
311
+ /**
312
+ * Get active connection for session (for testing)
313
+ */
314
+ getSessionConnections(sessionId) {
315
+ return Array.from(this.connections.values())
316
+ .filter(conn => conn.sessionId === sessionId && conn.isActive);
317
+ }
318
+ }
319
+ //# sourceMappingURL=sse-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-transport.js","sourceRoot":"","sources":["../../src/streaming/sse-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAkBtC;;;;;;;;;;GAUG;AACH,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IAC5C,WAAW,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC/C,cAAc,CAAiB;IAC/B,iBAAiB,GAA0B,IAAI,CAAC;IAExD,0BAA0B;IACT,eAAe,GAAG,GAAG,CAAC;IACtB,kBAAkB,GAAG,KAAK,CAAC,CAAC,aAAa;IACzC,kBAAkB,GAAG,MAAM,CAAC,CAAC,YAAY;IACzC,yBAAyB,GAAG,KAAK,CAAC;IAEnD,YAAY,cAA8B;QACxC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,wBAAwB;QACxB,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,SAAiB;QAC1D,MAAM,YAAY,GAAG,GAAG,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAClD,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,SAAS,CAAC;QAErD,0BAA0B;QAC1B,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,0BAA0B;QAC1B,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;YACzE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QAED,kBAAkB;QAClB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,UAAU;YAC3B,YAAY,EAAE,YAAY;YAC1B,6BAA6B,EAAE,YAAY;YAC3C,kCAAkC,EAAE,MAAM;SAC3C,CAAC,CAAC;QAEH,gCAAgC;QAChC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YAClB,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE;gBACJ,YAAY;gBACZ,SAAS;gBACT,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;aACxB;SACF,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,UAAU,GAAkB;YAChC,EAAE,EAAE,YAAY;YAChB,SAAS;YACT,QAAQ,EAAE,GAAG;YACb,YAAY;YACZ,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;YACvB,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;YACxB,UAAU,EAAE,CAAC;YACb,QAAQ,EAAE,IAAI;SACf,CAAC;QAEF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAE/C,MAAM,CAAC,IAAI,CAAC,kCAAkC,YAAY,gBAAgB,SAAS,EAAE,CAAC,CAAC;QAEvF,2BAA2B;QAC3B,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACxB,MAAM,CAAC,KAAK,CAAC,+BAA+B,YAAY,GAAG,EAAE,KAAK,CAAC,CAAC;YACpE,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,wCAAwC;QACxC,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,KAAqB;QAC9C,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,oCAAoC;QACpC,MAAM,kBAAkB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;aAC7D,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvE,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,MAAM,CAAC,KAAK,CAAC,4CAA4C,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YAC5E,OAAO;QACT,CAAC;QAED,wCAAwC;QACxC,KAAK,MAAM,UAAU,IAAI,kBAAkB,EAAE,CAAC;YAC5C,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,qBAAqB,CAAC,SAAiB;QAC7C,MAAM,CAAC,IAAI,CAAC,cAAc,SAAS,qCAAqC,CAAC,CAAC;QAE1E,MAAM,kBAAkB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;aAC7D,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;QAEhD,KAAK,MAAM,UAAU,IAAI,kBAAkB,EAAE,CAAC;YAC5C,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE;gBAClC,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE;oBACJ,SAAS;oBACT,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;iBACxB;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,UAAyB,EAAE,KAAqB;QACzE,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,oBAAoB;QACpB,IAAI,UAAU,CAAC,UAAU,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;YAC5D,MAAM,CAAC,IAAI,CAAC,iBAAiB,UAAU,CAAC,EAAE,sBAAsB,CAAC,CAAC;YAClE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE;gBAClC,IAAI,EAAE,iBAAiB;gBACvB,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;YAEH,UAAU,CAAC,UAAU,EAAE,CAAC;YACxB,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,UAAU,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YACpE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,UAAyB;QAClD,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC5E,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,MAAM,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAE9E,IAAI,cAAc,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,CAAC,IAAI,CAAC,cAAc,cAAc,CAAC,MAAM,CAAC,MAAM,uBAAuB,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;YAE9F,KAAK,MAAM,KAAK,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;gBAC1C,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,GAAa,EAAE,KAAkC;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,GAAG,CAAC,KAAK,CAAC,OAAO,OAAO,IAAI,CAAC,CAAC;QAC9B,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;QACpC,GAAG,CAAC,KAAK,CAAC,SAAS,SAAS,MAAM,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,YAAoB,EAAE,MAAc;QACrD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,wBAAwB,YAAY,KAAK,MAAM,EAAE,CAAC,CAAC;QAE/D,UAAU,CAAC,QAAQ,GAAG,KAAK,CAAC;QAE5B,IAAI,CAAC;YACH,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACnC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE;oBAClC,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE;wBACJ,MAAM;wBACN,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE;wBAC1B,UAAU,EAAE,UAAU,CAAC,UAAU;qBAClC;iBACF,CAAC,CAAC;gBAEH,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAEtC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC5B,YAAY;YACZ,SAAS,EAAE,UAAU,CAAC,SAAS;YAC/B,MAAM;YACN,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,WAAW;YAC7C,UAAU,EAAE,UAAU,CAAC,UAAU;SAClC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,IAAI,CAAC,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;YACxC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/B,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,qBAAqB;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,gBAAgB,GAAa,EAAE,CAAC;QAEtC,KAAK,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1D,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;gBACzB,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACpC,SAAS;YACX,CAAC;YAED,oBAAoB;YACpB,IAAI,GAAG,GAAG,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC5D,MAAM,CAAC,IAAI,CAAC,gBAAgB,YAAY,YAAY,CAAC,CAAC;gBACtD,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACpC,SAAS;YACX,CAAC;YAED,iBAAiB;YACjB,IAAI,CAAC;gBACH,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE;oBAClC,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE;wBACJ,SAAS,EAAE,GAAG;wBACd,SAAS,EAAE,UAAU,CAAC,SAAS;qBAChC;iBACF,CAAC,CAAC;gBAEH,UAAU,CAAC,YAAY,GAAG,GAAG,CAAC;YAChC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,wBAAwB,YAAY,uBAAuB,CAAC,CAAC;gBAC1E,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,KAAK,MAAM,YAAY,IAAI,gBAAgB,EAAE,CAAC;YAC5C,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,WAAW,CAAC,IAAI,yBAAyB,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QAMN,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;aAC5D,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEjC,MAAM,mBAAmB,GAA2B,EAAE,CAAC;QACvD,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,MAAM,UAAU,IAAI,iBAAiB,EAAE,CAAC;YAC3C,mBAAmB,CAAC,UAAU,CAAC,SAAS,CAAC;gBACvC,CAAC,mBAAmB,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACvD,WAAW,IAAI,UAAU,CAAC,UAAU,CAAC;QACvC,CAAC;QAED,OAAO;YACL,gBAAgB,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YACvC,iBAAiB,EAAE,iBAAiB,CAAC,MAAM;YAC3C,mBAAmB;YACnB,0BAA0B,EAAE,iBAAiB,CAAC,MAAM,GAAG,CAAC;gBACtD,CAAC,CAAC,WAAW,GAAG,iBAAiB,CAAC,MAAM;gBACxC,CAAC,CAAC,CAAC;SACN,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,SAAiB,EAAE,MAAM,GAAG,mBAAmB;QAC/D,MAAM,kBAAkB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;aAC7D,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;QAEhD,KAAK,MAAM,UAAU,IAAI,kBAAkB,EAAE,CAAC;YAC5C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAE9C,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,aAAa,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACtC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAChC,CAAC;QAED,6BAA6B;QAC7B,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,SAAiB;QACrC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;aACzC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnE,CAAC;CACF"}
@@ -0,0 +1,153 @@
1
+ import { EventEmitter } from 'events';
2
+ import { CLIAgentOptions } from '../cli-agents.js';
3
+ import { CLIAgentResponse } from '../types/brutalist.js';
4
+ import { CircuitBreakerConfig } from './circuit-breaker.js';
5
+ /**
6
+ * Enhanced streaming CLI execution options
7
+ */
8
+ export interface StreamingExecutionOptions extends CLIAgentOptions {
9
+ enableProgress?: boolean;
10
+ enableCircuitBreaker?: boolean;
11
+ fallbackResponse?: any;
12
+ cacheResponses?: boolean;
13
+ streamingTimeout?: number;
14
+ bufferConfig?: {
15
+ maxBatchSize?: number;
16
+ throttleDelay?: number;
17
+ priorityRules?: Record<string, any>;
18
+ };
19
+ }
20
+ /**
21
+ * Streaming execution result with enhanced metadata
22
+ */
23
+ export interface StreamingExecutionResult {
24
+ success: boolean;
25
+ responses: CLIAgentResponse[];
26
+ sessionId: string;
27
+ analysis: {
28
+ startTime: number;
29
+ endTime: number;
30
+ duration: number;
31
+ eventsEmitted: number;
32
+ progressMilestones: number;
33
+ circuitBreakerTrips: number;
34
+ fallbacksUsed: number;
35
+ };
36
+ streaming: {
37
+ connectedClients: number;
38
+ eventsSent: number;
39
+ averageLatency: number;
40
+ bufferHits: number;
41
+ };
42
+ errors?: string[];
43
+ }
44
+ /**
45
+ * Streaming orchestrator configuration
46
+ */
47
+ export interface StreamingOrchestratorConfig {
48
+ maxConcurrentAnalyses: number;
49
+ defaultTimeout: number;
50
+ circuitBreakerConfig: CircuitBreakerConfig;
51
+ enableMetrics: boolean;
52
+ cleanupInterval: number;
53
+ }
54
+ /**
55
+ * Advanced streaming CLI orchestrator with comprehensive real-time capabilities
56
+ *
57
+ * Integrates all streaming components:
58
+ * - Real-time output parsing with semantic boundaries
59
+ * - Intelligent buffering with adaptive throttling
60
+ * - Session management with lifecycle tracking
61
+ * - SSE transport with session isolation
62
+ * - Progress tracking with milestone detection
63
+ * - Circuit breaker with fallback strategies
64
+ * - Comprehensive monitoring and analytics
65
+ */
66
+ export declare class StreamingCLIOrchestrator extends EventEmitter {
67
+ private cliOrchestrator;
68
+ private sessionManager;
69
+ private sseTransport;
70
+ private circuitBreakers;
71
+ private responseCache;
72
+ private activeAnalyses;
73
+ private config;
74
+ private metrics;
75
+ private cleanupTimer?;
76
+ constructor(config?: Partial<StreamingOrchestratorConfig>);
77
+ /**
78
+ * Execute CLI analysis with full streaming capabilities
79
+ */
80
+ executeWithStreaming(analysisType: string, cliAgents: string[], systemPrompt: string, userPrompt: string, options?: StreamingExecutionOptions): Promise<StreamingExecutionResult>;
81
+ /**
82
+ * Create streaming event handler for session
83
+ */
84
+ private createStreamingEventHandler;
85
+ /**
86
+ * Execute CLI agents with circuit breaker protection
87
+ */
88
+ private executeWithCircuitBreaker;
89
+ /**
90
+ * Setup event handlers for internal components
91
+ */
92
+ private setupEventHandlers;
93
+ /**
94
+ * Setup circuit breakers for each CLI agent
95
+ */
96
+ private setupCircuitBreakers;
97
+ /**
98
+ * Update average analysis duration metric
99
+ */
100
+ private updateAverageAnalysisDuration;
101
+ /**
102
+ * Start cleanup timer for stale sessions and cache
103
+ */
104
+ private startCleanupTimer;
105
+ /**
106
+ * Perform periodic cleanup
107
+ */
108
+ private performCleanup;
109
+ /**
110
+ * Get orchestrator statistics
111
+ */
112
+ getStats(): {
113
+ metrics: {
114
+ totalAnalyses: number;
115
+ successfulAnalyses: number;
116
+ failedAnalyses: number;
117
+ totalEventsSent: number;
118
+ totalCircuitBreakerTrips: number;
119
+ totalFallbacksUsed: number;
120
+ averageAnalysisDuration: number;
121
+ };
122
+ activeAnalyses: number;
123
+ sessionManager: import("./session-manager.js").SessionManagerStats;
124
+ sseTransport: {
125
+ totalConnections: number;
126
+ activeConnections: number;
127
+ sessionDistribution: Record<string, number>;
128
+ averageEventsPerConnection: number;
129
+ };
130
+ circuitBreakers: Record<string, any>;
131
+ };
132
+ /**
133
+ * Get active session IDs
134
+ */
135
+ getActiveSessions(): string[];
136
+ /**
137
+ * Force disconnect session
138
+ */
139
+ disconnectSession(sessionId: string, reason?: string): void;
140
+ /**
141
+ * Reset circuit breaker for specific agent
142
+ */
143
+ resetCircuitBreaker(agent: string): void;
144
+ /**
145
+ * Add response to cache for fallback strategies
146
+ */
147
+ cacheResponse(key: string, response: any): void;
148
+ /**
149
+ * Shutdown orchestrator and cleanup resources
150
+ */
151
+ shutdown(): void;
152
+ }
153
+ //# sourceMappingURL=streaming-orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-orchestrator.d.ts","sourceRoot":"","sources":["../../src/streaming/streaming-orchestrator.ts"],"names":[],"mappings":"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"}