@@ -45,20 +45,20 @@ export type StdioServerParameters = {
45
45
export const DEFAULT_INHERITED_ENV_VARS =
46
46
process . platform === "win32"
47
47
? [
48
- "APPDATA" ,
49
- "HOMEDRIVE" ,
50
- "HOMEPATH" ,
51
- "LOCALAPPDATA" ,
52
- "PATH" ,
53
- "PROCESSOR_ARCHITECTURE" ,
54
- "SYSTEMDRIVE" ,
55
- "SYSTEMROOT" ,
56
- "TEMP" ,
57
- "USERNAME" ,
58
- "USERPROFILE" ,
59
- ]
48
+ "APPDATA" ,
49
+ "HOMEDRIVE" ,
50
+ "HOMEPATH" ,
51
+ "LOCALAPPDATA" ,
52
+ "PATH" ,
53
+ "PROCESSOR_ARCHITECTURE" ,
54
+ "SYSTEMDRIVE" ,
55
+ "SYSTEMROOT" ,
56
+ "TEMP" ,
57
+ "USERNAME" ,
58
+ "USERPROFILE" ,
59
+ ]
60
60
: /* list inspired by the default env inheritance of sudo */
61
- [ "HOME" , "LOGNAME" , "PATH" , "SHELL" , "TERM" , "USER" ] ;
61
+ [ "HOME" , "LOGNAME" , "PATH" , "SHELL" , "TERM" , "USER" ] ;
62
62
63
63
/**
64
64
* Returns a default environment object including only environment variables deemed safe to inherit.
@@ -112,7 +112,7 @@ export class StdioClientTransport implements Transport {
112
112
async start ( ) : Promise < void > {
113
113
if ( this . _process ) {
114
114
throw new Error (
115
- "StdioClientTransport already started! If using Client class, note that connect() calls start() automatically."
115
+ "StdioClientTransport already started! If using Client class, note that connect() calls start() automatically." ,
116
116
) ;
117
117
}
118
118
@@ -127,7 +127,7 @@ export class StdioClientTransport implements Transport {
127
127
signal : this . _abortController . signal ,
128
128
windowsHide : process . platform === "win32" && isElectron ( ) ,
129
129
cwd : this . _serverParams . cwd ,
130
- }
130
+ } ,
131
131
) ;
132
132
133
133
this . _process . on ( "error" , ( error ) => {
@@ -201,8 +201,35 @@ export class StdioClientTransport implements Transport {
201
201
202
202
async close ( ) : Promise < void > {
203
203
this . _abortController . abort ( ) ;
204
+
205
+ const taskProcess = this . _process ;
204
206
this . _process = undefined ;
205
207
this . _readBuffer . clear ( ) ;
208
+
209
+ if ( ! taskProcess || taskProcess . exitCode !== null ) {
210
+ return ;
211
+ }
212
+
213
+ taskProcess . kill ( "SIGTERM" ) ;
214
+
215
+ const exited = await Promise . race ( [
216
+ new Promise < boolean > ( ( resolve ) => {
217
+ const onExit = ( ) => resolve ( true ) ;
218
+ taskProcess . once ( "exit" , onExit ) ;
219
+ taskProcess . once ( "close" , onExit ) ;
220
+ } ) ,
221
+ new Promise < boolean > ( ( resolve ) => {
222
+ setTimeout ( ( ) => resolve ( false ) , 1000 ) ;
223
+ } ) ,
224
+ ] ) ;
225
+
226
+ if ( ! exited ) {
227
+ taskProcess . kill ( "SIGKILL" ) ;
228
+ await new Promise < void > ( ( resolve ) => {
229
+ taskProcess . once ( "exit" , resolve ) ;
230
+ taskProcess . once ( "close" , resolve ) ;
231
+ } ) ;
232
+ }
206
233
}
207
234
208
235
send ( message : JSONRPCMessage ) : Promise < void > {
0 commit comments