@@ -191,6 +191,43 @@ class EventTransport {
191191 }
192192 }
193193
194+ /**
195+ * Flush pending writes to ensure all events are delivered
196+ * Returns a promise that resolves when the stream is drained
197+ */
198+ async flush ( ) : Promise < void > {
199+ if ( this . useStderr || ! this . pipeStream ) {
200+ return ;
201+ }
202+
203+ return new Promise < void > ( ( resolve ) => {
204+ if ( ! this . pipeStream ) {
205+ resolve ( ) ;
206+ return ;
207+ }
208+
209+ // If stream is already drained, resolve immediately
210+ if ( this . pipeStream . writableNeedDrain === false ) {
211+ resolve ( ) ;
212+ return ;
213+ }
214+
215+ // Wait for drain event
216+ const onDrain = ( ) => {
217+ resolve ( ) ;
218+ } ;
219+
220+ this . pipeStream . once ( 'drain' , onDrain ) ;
221+
222+ // Also resolve on error or close to avoid hanging
223+ this . pipeStream . once ( 'error' , ( ) => resolve ( ) ) ;
224+ this . pipeStream . once ( 'close' , ( ) => resolve ( ) ) ;
225+
226+ // Timeout fallback - don't wait forever
227+ setTimeout ( ( ) => resolve ( ) , 100 ) ;
228+ } ) ;
229+ }
230+
194231 /**
195232 * Close the transport
196233 */
@@ -334,6 +371,14 @@ export const emit = {
334371 raw ( event : Omit < WorkflowEvent , '__mcp_event__' | 'timestamp' > ) : void {
335372 transport . send ( event ) ;
336373 } ,
374+
375+ /**
376+ * Flush all pending events to ensure they are delivered
377+ * Call this before workflow exits to ensure all events are sent
378+ */
379+ async flush ( ) : Promise < void > {
380+ await transport . flush ( ) ;
381+ } ,
337382} ;
338383
339384/**
0 commit comments