77  type  CapabilitiesResponse , 
88  APIServerURLEnvironmentVariable , 
99}  from  "../agent/client" ; 
10+ import  {  RWLock  }  from  "../local/rw-lock" ; 
1011
1112export  interface  AgentLog  { 
1213  readonly  level : "log"  |  "error" ; 
@@ -53,6 +54,8 @@ export default function useAgent(options: UseAgentOptions) {
5354    setAgent ( undefined ) ; 
5455    setCapabilities ( undefined ) ; 
5556
57+     let  lock : RWLock  |  undefined ; 
58+ 
5659    ( async  ( )  =>  { 
5760      const  port  =  await  getRandomPort ( ) ; 
5861      const  proc  =  spawn ( "node" ,  [ "--no-deprecation" ,  buildResult . entry ] ,  { 
@@ -64,11 +67,27 @@ export default function useAgent(options: UseAgentOptions) {
6467          PORT : port . toString ( ) , 
6568          HOST : "127.0.0.1" , 
6669        } , 
70+         // keep the child process tied to the parent process 
71+         detached : false , 
6772      } ) ; 
68-       controller . signal . addEventListener ( "abort" ,  ( )  =>  { 
73+       const   cleanup   =  ( )  =>  { 
6974        try  { 
7075          proc . kill ( ) ; 
7176        }  catch  { } 
77+       } ; 
78+ 
79+       // Clean up - when the parent process exits, kill the child process. 
80+       process . once ( "exit" ,  cleanup ) ; 
81+       process . once ( "SIGINT" ,  cleanup ) ; 
82+       process . once ( "SIGTERM" ,  cleanup ) ; 
83+       process . once ( "uncaughtException" ,  cleanup ) ; 
84+ 
85+       controller . signal . addEventListener ( "abort" ,  ( )  =>  { 
86+         process . off ( "exit" ,  cleanup ) ; 
87+         process . off ( "SIGINT" ,  cleanup ) ; 
88+         process . off ( "SIGTERM" ,  cleanup ) ; 
89+         process . off ( "uncaughtException" ,  cleanup ) ; 
90+         cleanup ( ) ; 
7291      } ) ; 
7392      let  ready  =  false ; 
7493      proc . stdout . on ( "data" ,  ( data )  =>  { 
@@ -114,6 +133,7 @@ export default function useAgent(options: UseAgentOptions) {
114133      const  client  =  new  Client ( { 
115134        baseUrl : `http://127.0.0.1:${ port }  ` , 
116135      } ) ; 
136+       lock  =  client . agentLock ; 
117137      // Wait for the health endpoint to be alive. 
118138      while  ( ! controller . signal . aborted )  { 
119139        try  { 
@@ -139,7 +159,12 @@ export default function useAgent(options: UseAgentOptions) {
139159    } ) ; 
140160    return  ( )  =>  { 
141161      isCleanup  =  true ; 
142-       controller . abort ( ) ; 
162+       ( async  ( )  =>  { 
163+         // Acquire write lock before cleaning up this agent instance 
164+         // This waits for any active streams using this agent to complete 
165+         using _writeLock  =  await  lock ?. write ( ) ; 
166+         controller . abort ( ) ; 
167+       } ) ( ) ; 
143168    } ; 
144169  } ,  [ buildResult ,  env ,  apiServerUrl ] ) ; 
145170
0 commit comments