@mcp-z/client 2.2.3 → 2.3.0
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 +12 -1
- package/dist/cjs/auth/capability-discovery.d.cts +3 -1
- package/dist/cjs/auth/capability-discovery.d.ts +3 -1
- package/dist/cjs/auth/capability-discovery.js +46 -32
- package/dist/cjs/auth/capability-discovery.js.map +1 -1
- package/dist/cjs/auth/discovery-fetch.d.cts +2 -0
- package/dist/cjs/auth/discovery-fetch.d.ts +2 -0
- package/dist/cjs/auth/discovery-fetch.js +85 -31
- package/dist/cjs/auth/discovery-fetch.js.map +1 -1
- package/dist/cjs/auth/interactive-oauth-flow.d.cts +1 -1
- package/dist/cjs/auth/interactive-oauth-flow.d.ts +1 -1
- package/dist/cjs/auth/interactive-oauth-flow.js +13 -6
- package/dist/cjs/auth/interactive-oauth-flow.js.map +1 -1
- package/dist/cjs/auth/oauth-callback-listener.d.cts +1 -1
- package/dist/cjs/auth/oauth-callback-listener.d.ts +1 -1
- package/dist/cjs/auth/oauth-callback-listener.js +40 -4
- package/dist/cjs/auth/oauth-callback-listener.js.map +1 -1
- package/dist/cjs/auth/rfc9728-discovery.d.cts +7 -2
- package/dist/cjs/auth/rfc9728-discovery.d.ts +7 -2
- package/dist/cjs/auth/rfc9728-discovery.js +120 -88
- package/dist/cjs/auth/rfc9728-discovery.js.map +1 -1
- package/dist/cjs/auth/types.d.cts +4 -0
- package/dist/cjs/auth/types.d.ts +4 -0
- package/dist/cjs/auth/types.js.map +1 -1
- package/dist/cjs/connection/connect-client.d.cts +9 -1
- package/dist/cjs/connection/connect-client.d.ts +9 -1
- package/dist/cjs/connection/connect-client.js +282 -75
- package/dist/cjs/connection/connect-client.js.map +1 -1
- package/dist/cjs/connection/existing-process-transport.d.cts +18 -18
- package/dist/cjs/connection/existing-process-transport.d.ts +18 -18
- package/dist/cjs/connection/existing-process-transport.js +187 -82
- package/dist/cjs/connection/existing-process-transport.js.map +1 -1
- package/dist/cjs/connection/wait-for-http-ready.d.cts +1 -1
- package/dist/cjs/connection/wait-for-http-ready.d.ts +1 -1
- package/dist/cjs/connection/wait-for-http-ready.js +30 -5
- package/dist/cjs/connection/wait-for-http-ready.js.map +1 -1
- package/dist/cjs/dcr/dcr-authenticator.d.cts +1 -1
- package/dist/cjs/dcr/dcr-authenticator.d.ts +1 -1
- package/dist/cjs/dcr/dcr-authenticator.js +29 -18
- package/dist/cjs/dcr/dcr-authenticator.js.map +1 -1
- package/dist/cjs/dcr/dynamic-client-registrar.js +2 -1
- package/dist/cjs/dcr/dynamic-client-registrar.js.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/spawn/owned-process-tree.d.cts +12 -0
- package/dist/cjs/spawn/owned-process-tree.d.ts +12 -0
- package/dist/cjs/spawn/owned-process-tree.js +93 -0
- package/dist/cjs/spawn/owned-process-tree.js.map +1 -0
- package/dist/cjs/spawn/spawn-server.d.cts +8 -32
- package/dist/cjs/spawn/spawn-server.d.ts +8 -32
- package/dist/cjs/spawn/spawn-server.js +406 -97
- package/dist/cjs/spawn/spawn-server.js.map +1 -1
- package/dist/cjs/spawn/spawn-servers.d.cts +18 -8
- package/dist/cjs/spawn/spawn-servers.d.ts +18 -8
- package/dist/cjs/spawn/spawn-servers.js +342 -113
- package/dist/cjs/spawn/spawn-servers.js.map +1 -1
- package/dist/cjs/types.d.cts +1 -1
- package/dist/cjs/types.d.ts +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/path-utils.js +7 -4
- package/dist/cjs/utils/path-utils.js.map +1 -1
- package/dist/esm/auth/capability-discovery.d.ts +3 -1
- package/dist/esm/auth/capability-discovery.js +21 -11
- package/dist/esm/auth/capability-discovery.js.map +1 -1
- package/dist/esm/auth/discovery-fetch.d.ts +2 -0
- package/dist/esm/auth/discovery-fetch.js +64 -23
- package/dist/esm/auth/discovery-fetch.js.map +1 -1
- package/dist/esm/auth/interactive-oauth-flow.d.ts +1 -1
- package/dist/esm/auth/interactive-oauth-flow.js +13 -6
- package/dist/esm/auth/interactive-oauth-flow.js.map +1 -1
- package/dist/esm/auth/oauth-callback-listener.d.ts +1 -1
- package/dist/esm/auth/oauth-callback-listener.js +34 -4
- package/dist/esm/auth/oauth-callback-listener.js.map +1 -1
- package/dist/esm/auth/rfc9728-discovery.d.ts +7 -2
- package/dist/esm/auth/rfc9728-discovery.js +40 -16
- package/dist/esm/auth/rfc9728-discovery.js.map +1 -1
- package/dist/esm/auth/types.d.ts +4 -0
- package/dist/esm/auth/types.js.map +1 -1
- package/dist/esm/connection/connect-client.d.ts +9 -1
- package/dist/esm/connection/connect-client.js +97 -35
- package/dist/esm/connection/connect-client.js.map +1 -1
- package/dist/esm/connection/existing-process-transport.d.ts +18 -18
- package/dist/esm/connection/existing-process-transport.js +132 -70
- package/dist/esm/connection/existing-process-transport.js.map +1 -1
- package/dist/esm/connection/wait-for-http-ready.d.ts +1 -1
- package/dist/esm/connection/wait-for-http-ready.js +19 -4
- package/dist/esm/connection/wait-for-http-ready.js.map +1 -1
- package/dist/esm/dcr/dcr-authenticator.d.ts +1 -1
- package/dist/esm/dcr/dcr-authenticator.js +26 -15
- package/dist/esm/dcr/dcr-authenticator.js.map +1 -1
- package/dist/esm/dcr/dynamic-client-registrar.js +2 -1
- package/dist/esm/dcr/dynamic-client-registrar.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/spawn/owned-process-tree.d.ts +12 -0
- package/dist/esm/spawn/owned-process-tree.js +39 -0
- package/dist/esm/spawn/owned-process-tree.js.map +1 -0
- package/dist/esm/spawn/spawn-server.d.ts +8 -32
- package/dist/esm/spawn/spawn-server.js +228 -99
- package/dist/esm/spawn/spawn-server.js.map +1 -1
- package/dist/esm/spawn/spawn-servers.d.ts +18 -8
- package/dist/esm/spawn/spawn-servers.js +180 -55
- package/dist/esm/spawn/spawn-servers.js.map +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/path-utils.js +7 -4
- package/dist/esm/utils/path-utils.js.map +1 -1
- package/package.json +8 -3
- package/schemas/servers.d.ts +24 -0
- package/schemas/servers.schema.json +31 -0
|
@@ -11,10 +11,12 @@ Object.defineProperty(exports, "spawnProcess", {
|
|
|
11
11
|
return spawnProcess;
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
|
-
var
|
|
14
|
+
var _crossspawn = /*#__PURE__*/ _interop_require_default(require("cross-spawn"));
|
|
15
|
+
var _path = /*#__PURE__*/ _interop_require_wildcard(require("path"));
|
|
15
16
|
var _process = /*#__PURE__*/ _interop_require_wildcard(require("process"));
|
|
16
17
|
var _loggerts = require("../utils/logger.js");
|
|
17
18
|
var _pathutilsts = require("../utils/path-utils.js");
|
|
19
|
+
var _ownedprocesstreets = require("./owned-process-tree.js");
|
|
18
20
|
function _array_like_to_array(arr, len) {
|
|
19
21
|
if (len == null || len > arr.length) len = arr.length;
|
|
20
22
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
@@ -60,6 +62,17 @@ function _define_property(obj, key, value) {
|
|
|
60
62
|
} else obj[key] = value;
|
|
61
63
|
return obj;
|
|
62
64
|
}
|
|
65
|
+
function _instanceof(left, right) {
|
|
66
|
+
"@swc/helpers - instanceof";
|
|
67
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
68
|
+
return !!right[Symbol.hasInstance](left);
|
|
69
|
+
} else return left instanceof right;
|
|
70
|
+
}
|
|
71
|
+
function _interop_require_default(obj) {
|
|
72
|
+
return obj && obj.__esModule ? obj : {
|
|
73
|
+
default: obj
|
|
74
|
+
};
|
|
75
|
+
}
|
|
63
76
|
function _getRequireWildcardCache(nodeInterop) {
|
|
64
77
|
if (typeof WeakMap !== "function") return null;
|
|
65
78
|
var cacheBabelInterop = new WeakMap();
|
|
@@ -242,18 +255,18 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
242
255
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
243
256
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
244
257
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
258
|
+
var DEFAULT_CLOSE_TIMEOUT_MS = 5000;
|
|
259
|
+
var PROCESS_TERMINATION_TIMEOUT_MS = 5000;
|
|
260
|
+
var PROCESS_POLL_INTERVAL_MS = 25;
|
|
261
|
+
function normalizeEnv(env) {
|
|
262
|
+
var inheritEnv = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
|
|
263
|
+
var merged = _object_spread({}, inheritEnv ? _process.env : {}, env || {});
|
|
249
264
|
var result = {};
|
|
250
265
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
251
266
|
try {
|
|
252
267
|
for(var _iterator = Object.entries(merged)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
253
268
|
var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
|
|
254
|
-
if (value !== undefined)
|
|
255
|
-
result[key] = value;
|
|
256
|
-
}
|
|
269
|
+
if (value !== undefined) result[key] = value;
|
|
257
270
|
}
|
|
258
271
|
} catch (err) {
|
|
259
272
|
_didIteratorError = true;
|
|
@@ -271,18 +284,226 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
271
284
|
}
|
|
272
285
|
return result;
|
|
273
286
|
}
|
|
287
|
+
function delay(ms) {
|
|
288
|
+
return new Promise(function(resolve) {
|
|
289
|
+
return setTimeout(resolve, ms);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
function waitForCompletion(closeEvent, childClosed, tree, timeoutMs) {
|
|
293
|
+
return _async_to_generator(function() {
|
|
294
|
+
var _tmp, deadline, lastError, processGroupEmpty, closed;
|
|
295
|
+
return _ts_generator(this, function(_state) {
|
|
296
|
+
switch(_state.label){
|
|
297
|
+
case 0:
|
|
298
|
+
if (!!tree) return [
|
|
299
|
+
3,
|
|
300
|
+
2
|
|
301
|
+
];
|
|
302
|
+
_tmp = {};
|
|
303
|
+
return [
|
|
304
|
+
4,
|
|
305
|
+
waitForChildClose(closeEvent, timeoutMs)
|
|
306
|
+
];
|
|
307
|
+
case 1:
|
|
308
|
+
return [
|
|
309
|
+
2,
|
|
310
|
+
(_tmp.closed = _state.sent() !== undefined, _tmp)
|
|
311
|
+
];
|
|
312
|
+
case 2:
|
|
313
|
+
deadline = Date.now() + timeoutMs;
|
|
314
|
+
_state.label = 3;
|
|
315
|
+
case 3:
|
|
316
|
+
if (!true) return [
|
|
317
|
+
3,
|
|
318
|
+
5
|
|
319
|
+
];
|
|
320
|
+
processGroupEmpty = false;
|
|
321
|
+
try {
|
|
322
|
+
processGroupEmpty = tree.isEmpty();
|
|
323
|
+
lastError = undefined;
|
|
324
|
+
} catch (error) {
|
|
325
|
+
lastError = _instanceof(error, Error) ? error : new Error(String(error));
|
|
326
|
+
}
|
|
327
|
+
closed = childClosed();
|
|
328
|
+
if (closed && processGroupEmpty) return [
|
|
329
|
+
2,
|
|
330
|
+
{
|
|
331
|
+
closed: closed,
|
|
332
|
+
processGroupEmpty: processGroupEmpty
|
|
333
|
+
}
|
|
334
|
+
];
|
|
335
|
+
if (Date.now() >= deadline) return [
|
|
336
|
+
2,
|
|
337
|
+
_object_spread({
|
|
338
|
+
closed: closed,
|
|
339
|
+
processGroupEmpty: processGroupEmpty
|
|
340
|
+
}, lastError && {
|
|
341
|
+
error: lastError
|
|
342
|
+
})
|
|
343
|
+
];
|
|
344
|
+
return [
|
|
345
|
+
4,
|
|
346
|
+
delay(Math.min(PROCESS_POLL_INTERVAL_MS, Math.max(1, deadline - Date.now())))
|
|
347
|
+
];
|
|
348
|
+
case 4:
|
|
349
|
+
_state.sent();
|
|
350
|
+
return [
|
|
351
|
+
3,
|
|
352
|
+
3
|
|
353
|
+
];
|
|
354
|
+
case 5:
|
|
355
|
+
return [
|
|
356
|
+
2
|
|
357
|
+
];
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
})();
|
|
361
|
+
}
|
|
362
|
+
function isCompletionSuccessful(completion) {
|
|
363
|
+
return completion.closed && completion.processGroupEmpty !== false;
|
|
364
|
+
}
|
|
365
|
+
function terminateChild(child, tree) {
|
|
366
|
+
if (tree) return tree.terminate();
|
|
367
|
+
try {
|
|
368
|
+
return {
|
|
369
|
+
killed: child.kill('SIGKILL')
|
|
370
|
+
};
|
|
371
|
+
} catch (error) {
|
|
372
|
+
return {
|
|
373
|
+
killed: false,
|
|
374
|
+
error: asError(error)
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
function waitForChildClose(closeEvent, timeoutMs) {
|
|
379
|
+
var timer;
|
|
380
|
+
return Promise.race([
|
|
381
|
+
closeEvent,
|
|
382
|
+
new Promise(function(resolve) {
|
|
383
|
+
timer = setTimeout(function() {
|
|
384
|
+
return resolve(undefined);
|
|
385
|
+
}, timeoutMs);
|
|
386
|
+
})
|
|
387
|
+
]).finally(function() {
|
|
388
|
+
if (timer) clearTimeout(timer);
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
function requestProcessSignal(child, signal) {
|
|
392
|
+
if (!child.pid) throw new Error('Cannot request cooperative shutdown because the server has no process ID');
|
|
393
|
+
if (_process.platform === 'win32') throw new Error('POSIX process signals are not available on Windows');
|
|
394
|
+
try {
|
|
395
|
+
_process.kill(-child.pid, signal);
|
|
396
|
+
} catch (error) {
|
|
397
|
+
if (!(_instanceof(error, Error) && 'code' in error && error.code === 'ESRCH')) throw error;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
function asError(error) {
|
|
401
|
+
return _instanceof(error, Error) ? error : new Error(String(error));
|
|
402
|
+
}
|
|
403
|
+
function withCause(message, cause) {
|
|
404
|
+
return new Error(message, {
|
|
405
|
+
cause: cause
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
function runStopCommand(command, cwd, timeoutMs, inheritEnv) {
|
|
409
|
+
return _async_to_generator(function() {
|
|
410
|
+
var stopCwd, env, args, child, spawnError, closed, closeEventValue, closeEvent, result, tree, completion, _completion_error, _termination_error, termination, afterTermination, details, reason, remaining, _closeEventValue_code;
|
|
411
|
+
return _ts_generator(this, function(_state) {
|
|
412
|
+
switch(_state.label){
|
|
413
|
+
case 0:
|
|
414
|
+
stopCwd = command.cwd ? _path.resolve(cwd, command.cwd) : cwd;
|
|
415
|
+
env = normalizeEnv(command.env, inheritEnv);
|
|
416
|
+
args = command.args ? (0, _pathutilsts.resolveArgsPaths)(command.args, stopCwd) : [];
|
|
417
|
+
child = (0, _crossspawn.default)(command.command, args, {
|
|
418
|
+
cwd: stopCwd,
|
|
419
|
+
env: env,
|
|
420
|
+
stdio: 'ignore',
|
|
421
|
+
shell: false,
|
|
422
|
+
detached: _process.platform !== 'win32',
|
|
423
|
+
windowsHide: true
|
|
424
|
+
});
|
|
425
|
+
closed = false;
|
|
426
|
+
closeEvent = new Promise(function(resolve) {
|
|
427
|
+
child.once('error', function(error) {
|
|
428
|
+
spawnError = error;
|
|
429
|
+
});
|
|
430
|
+
child.once('close', function(code, signal) {
|
|
431
|
+
closed = true;
|
|
432
|
+
closeEventValue = {
|
|
433
|
+
code: code,
|
|
434
|
+
signal: signal
|
|
435
|
+
};
|
|
436
|
+
resolve({
|
|
437
|
+
code: code,
|
|
438
|
+
signal: signal
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
if (!!child.pid) return [
|
|
443
|
+
3,
|
|
444
|
+
2
|
|
445
|
+
];
|
|
446
|
+
return [
|
|
447
|
+
4,
|
|
448
|
+
waitForChildClose(closeEvent, timeoutMs)
|
|
449
|
+
];
|
|
450
|
+
case 1:
|
|
451
|
+
result = _state.sent();
|
|
452
|
+
if (!result) throw new Error("Stop command did not start or close within ".concat(timeoutMs, "ms"));
|
|
453
|
+
if (spawnError) throw withCause("Stop command could not be started: ".concat(spawnError.message), spawnError);
|
|
454
|
+
_state.label = 2;
|
|
455
|
+
case 2:
|
|
456
|
+
tree = child.pid && _process.platform !== 'win32' ? new _ownedprocesstreets.OwnedProcessTree(child.pid) : undefined;
|
|
457
|
+
return [
|
|
458
|
+
4,
|
|
459
|
+
waitForCompletion(closeEvent, function() {
|
|
460
|
+
return closed;
|
|
461
|
+
}, tree, timeoutMs)
|
|
462
|
+
];
|
|
463
|
+
case 3:
|
|
464
|
+
completion = _state.sent();
|
|
465
|
+
if (!!isCompletionSuccessful(completion)) return [
|
|
466
|
+
3,
|
|
467
|
+
5
|
|
468
|
+
];
|
|
469
|
+
termination = terminateChild(child, tree);
|
|
470
|
+
return [
|
|
471
|
+
4,
|
|
472
|
+
waitForCompletion(closeEvent, function() {
|
|
473
|
+
return closed;
|
|
474
|
+
}, tree, PROCESS_TERMINATION_TIMEOUT_MS)
|
|
475
|
+
];
|
|
476
|
+
case 4:
|
|
477
|
+
afterTermination = _state.sent();
|
|
478
|
+
details = [
|
|
479
|
+
(_completion_error = completion.error) === null || _completion_error === void 0 ? void 0 : _completion_error.message,
|
|
480
|
+
(_termination_error = termination.error) === null || _termination_error === void 0 ? void 0 : _termination_error.message
|
|
481
|
+
].filter(Boolean).join('; ');
|
|
482
|
+
reason = "Stop command exceeded ".concat(timeoutMs, "ms and required emergency process termination");
|
|
483
|
+
remaining = !isCompletionSuccessful(afterTermination) ? '; stop command or its POSIX process group remained alive' : '';
|
|
484
|
+
throw new Error("".concat(reason).concat(details ? ": ".concat(details) : '').concat(remaining));
|
|
485
|
+
case 5:
|
|
486
|
+
if (spawnError) throw withCause("Stop command could not be started: ".concat(spawnError.message), spawnError);
|
|
487
|
+
if (closeEventValue && (closeEventValue.code !== 0 || closeEventValue.signal !== null)) {
|
|
488
|
+
;
|
|
489
|
+
throw new Error("Stop command exited with code ".concat((_closeEventValue_code = closeEventValue.code) !== null && _closeEventValue_code !== void 0 ? _closeEventValue_code : 'unknown').concat(closeEventValue.signal ? " (signal ".concat(closeEventValue.signal, ")") : ''));
|
|
490
|
+
}
|
|
491
|
+
return [
|
|
492
|
+
2
|
|
493
|
+
];
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
})();
|
|
497
|
+
}
|
|
274
498
|
function spawnProcess(opts) {
|
|
275
|
-
var _opts_cwd, _opts_stdio,
|
|
499
|
+
var _opts_cwd, _opts_stdio, _opts_inheritEnv;
|
|
276
500
|
var name = opts.name;
|
|
277
501
|
var command = opts.command;
|
|
278
502
|
var cwd = (_opts_cwd = opts.cwd) !== null && _opts_cwd !== void 0 ? _opts_cwd : _process.cwd();
|
|
279
503
|
var stdio = (_opts_stdio = opts.stdio) !== null && _opts_stdio !== void 0 ? _opts_stdio : 'inherit';
|
|
280
|
-
var shell = (_opts_shell = opts.shell) !== null && _opts_shell !== void 0 ? _opts_shell : _process.platform === 'win32';
|
|
281
|
-
// Resolve paths in args relative to the working directory
|
|
282
504
|
var args = opts.args ? (0, _pathutilsts.resolveArgsPaths)(opts.args, cwd) : [];
|
|
283
|
-
|
|
284
|
-
var env = normalizeEnv(opts.env);
|
|
285
|
-
// Create resolved config for return value
|
|
505
|
+
var inheritEnv = (_opts_inheritEnv = opts.inheritEnv) !== null && _opts_inheritEnv !== void 0 ? _opts_inheritEnv : true;
|
|
506
|
+
var env = normalizeEnv(opts.env, inheritEnv);
|
|
286
507
|
var resolvedConfig = {
|
|
287
508
|
name: name,
|
|
288
509
|
command: command,
|
|
@@ -290,109 +511,197 @@ function spawnProcess(opts) {
|
|
|
290
511
|
cwd: cwd,
|
|
291
512
|
env: env,
|
|
292
513
|
stdio: stdio,
|
|
293
|
-
shell:
|
|
514
|
+
shell: false
|
|
294
515
|
};
|
|
295
|
-
// Log spawn operation
|
|
296
516
|
_loggerts.logger.info("[".concat(name, "] → ").concat(command, " ").concat(args.join(' ')));
|
|
297
|
-
|
|
298
|
-
var spawnOpts = {
|
|
517
|
+
var child = (0, _crossspawn.default)(command, args, {
|
|
299
518
|
cwd: cwd,
|
|
300
519
|
env: env,
|
|
301
520
|
stdio: stdio,
|
|
302
|
-
shell:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
// Pipe stdio if not inherited
|
|
306
|
-
if (child.stderr) child.stderr.on('data', function(chunk) {
|
|
307
|
-
_process.stderr.write(chunk);
|
|
521
|
+
shell: false,
|
|
522
|
+
detached: _process.platform !== 'win32',
|
|
523
|
+
windowsHide: true
|
|
308
524
|
});
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
return _loggerts.logger.info("[".concat(name, "] exited (code=").concat(code, ", signal=").concat(sig || 'none', ")"));
|
|
525
|
+
if (child.stderr) child.stderr.on('data', function(chunk) {
|
|
526
|
+
return _process.stderr.write(chunk);
|
|
312
527
|
});
|
|
313
|
-
|
|
314
|
-
|
|
528
|
+
var isClosed = false;
|
|
529
|
+
var _closeEventValue;
|
|
530
|
+
var closeEvent = new Promise(function(resolve) {
|
|
531
|
+
child.once('close', function(code, signal) {
|
|
532
|
+
isClosed = true;
|
|
533
|
+
_closeEventValue = {
|
|
534
|
+
code: code,
|
|
535
|
+
signal: signal
|
|
536
|
+
};
|
|
537
|
+
_loggerts.logger.info("[".concat(name, "] closed (code=").concat(code, ", signal=").concat(signal || 'none', ")"));
|
|
538
|
+
resolve({
|
|
539
|
+
code: code,
|
|
540
|
+
signal: signal
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
child.once('error', function(error) {
|
|
544
|
+
return _loggerts.logger.info("[".concat(name, "] process error: ").concat(error.message));
|
|
545
|
+
});
|
|
315
546
|
});
|
|
316
|
-
|
|
317
|
-
var
|
|
318
|
-
|
|
547
|
+
var tree = child.pid && _process.platform !== 'win32' ? new _ownedprocesstreets.OwnedProcessTree(child.pid) : undefined;
|
|
548
|
+
var closePromise;
|
|
549
|
+
var performClose = function performClose(signal, timeoutMs) {
|
|
319
550
|
return _async_to_generator(function() {
|
|
320
|
-
var
|
|
551
|
+
var timedOut, killed, errors, stopSucceeded, error, completion, termination;
|
|
321
552
|
return _ts_generator(this, function(_state) {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
553
|
+
switch(_state.label){
|
|
554
|
+
case 0:
|
|
555
|
+
if (!!child.pid) return [
|
|
556
|
+
3,
|
|
557
|
+
2
|
|
558
|
+
];
|
|
559
|
+
return [
|
|
560
|
+
4,
|
|
561
|
+
waitForChildClose(closeEvent, timeoutMs)
|
|
562
|
+
];
|
|
563
|
+
case 1:
|
|
564
|
+
_state.sent();
|
|
565
|
+
throw new Error("Cannot verify shutdown of server '".concat(name, "' because it has no process ID"));
|
|
566
|
+
case 2:
|
|
567
|
+
timedOut = false;
|
|
568
|
+
killed = false;
|
|
569
|
+
errors = [];
|
|
570
|
+
stopSucceeded = false;
|
|
571
|
+
if (!opts.stop) return [
|
|
572
|
+
3,
|
|
573
|
+
7
|
|
574
|
+
];
|
|
575
|
+
_state.label = 3;
|
|
576
|
+
case 3:
|
|
577
|
+
_state.trys.push([
|
|
578
|
+
3,
|
|
579
|
+
5,
|
|
580
|
+
,
|
|
581
|
+
6
|
|
582
|
+
]);
|
|
583
|
+
return [
|
|
584
|
+
4,
|
|
585
|
+
runStopCommand(opts.stop, cwd, timeoutMs, inheritEnv)
|
|
586
|
+
];
|
|
587
|
+
case 4:
|
|
588
|
+
_state.sent();
|
|
589
|
+
stopSucceeded = true;
|
|
590
|
+
return [
|
|
591
|
+
3,
|
|
592
|
+
6
|
|
593
|
+
];
|
|
594
|
+
case 5:
|
|
595
|
+
error = _state.sent();
|
|
596
|
+
errors.push(withCause("Server '".concat(name, "' application stop command failed: ").concat(asError(error).message), asError(error)));
|
|
597
|
+
return [
|
|
598
|
+
3,
|
|
599
|
+
6
|
|
600
|
+
];
|
|
601
|
+
case 6:
|
|
602
|
+
return [
|
|
603
|
+
3,
|
|
604
|
+
8
|
|
605
|
+
];
|
|
606
|
+
case 7:
|
|
607
|
+
if (child.stdin && !child.stdin.destroyed && !child.stdin.writableEnded) {
|
|
608
|
+
child.stdin.end();
|
|
609
|
+
} else if (_process.platform !== 'win32') {
|
|
610
|
+
try {
|
|
611
|
+
requestProcessSignal(child, signal);
|
|
612
|
+
} catch (error) {
|
|
613
|
+
errors.push(withCause("Server '".concat(name, "' cooperative signal failed: ").concat(asError(error).message), asError(error)));
|
|
614
|
+
}
|
|
329
615
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
616
|
+
_state.label = 8;
|
|
617
|
+
case 8:
|
|
618
|
+
return [
|
|
619
|
+
4,
|
|
620
|
+
waitForCompletion(closeEvent, function() {
|
|
621
|
+
return isClosed;
|
|
622
|
+
}, tree, timeoutMs)
|
|
623
|
+
];
|
|
624
|
+
case 9:
|
|
625
|
+
completion = _state.sent();
|
|
626
|
+
if (completion.error) errors.push(withCause("Could not inspect the owned process tree for server '".concat(name, "'"), completion.error));
|
|
627
|
+
if (!!isCompletionSuccessful(completion)) return [
|
|
628
|
+
3,
|
|
629
|
+
12
|
|
630
|
+
];
|
|
631
|
+
timedOut = true;
|
|
632
|
+
if (!(!opts.stop && child.stdin && _process.platform !== 'win32')) return [
|
|
633
|
+
3,
|
|
634
|
+
11
|
|
635
|
+
];
|
|
349
636
|
try {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
wasKilled = true;
|
|
354
|
-
}
|
|
355
|
-
} catch (_) {}
|
|
356
|
-
// Even if kill fails, resolve
|
|
357
|
-
resolveOnce(true);
|
|
358
|
-
}, timeoutMs);
|
|
359
|
-
// Listen for 'close' event (not 'exit') to wait for stdio close
|
|
360
|
-
child.once('close', function() {
|
|
361
|
-
resolveOnce(false);
|
|
362
|
-
});
|
|
363
|
-
// Also listen for 'error' event in case spawn failed
|
|
364
|
-
// This prevents promise from hanging forever if process never started
|
|
365
|
-
child.once('error', function() {
|
|
366
|
-
resolveOnce(false);
|
|
367
|
-
});
|
|
368
|
-
// Send graceful shutdown signal
|
|
369
|
-
try {
|
|
370
|
-
// Check one more time before killing
|
|
371
|
-
if (child.exitCode !== null) {
|
|
372
|
-
resolveOnce(false);
|
|
373
|
-
return;
|
|
637
|
+
requestProcessSignal(child, signal);
|
|
638
|
+
} catch (error) {
|
|
639
|
+
errors.push(withCause("Server '".concat(name, "' cooperative signal failed: ").concat(asError(error).message), asError(error)));
|
|
374
640
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
641
|
+
return [
|
|
642
|
+
4,
|
|
643
|
+
waitForCompletion(closeEvent, function() {
|
|
644
|
+
return isClosed;
|
|
645
|
+
}, tree, timeoutMs)
|
|
646
|
+
];
|
|
647
|
+
case 10:
|
|
648
|
+
completion = _state.sent();
|
|
649
|
+
if (completion.error) errors.push(withCause("Could not inspect the owned process tree for server '".concat(name, "'"), completion.error));
|
|
650
|
+
return [
|
|
651
|
+
3,
|
|
652
|
+
12
|
|
653
|
+
];
|
|
654
|
+
case 11:
|
|
655
|
+
if (!opts.stop && _process.platform !== 'win32' && !child.stdin) {
|
|
656
|
+
// The first signal was sent before waiting for an inherited-stdio HTTP process.
|
|
379
657
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
658
|
+
_state.label = 12;
|
|
659
|
+
case 12:
|
|
660
|
+
if (!!isCompletionSuccessful(completion)) return [
|
|
661
|
+
3,
|
|
662
|
+
14
|
|
663
|
+
];
|
|
664
|
+
termination = terminateChild(child, tree);
|
|
665
|
+
killed || (killed = termination.killed);
|
|
666
|
+
if (termination.error) errors.push(withCause("Emergency termination failed for server '".concat(name, "'"), termination.error));
|
|
667
|
+
return [
|
|
668
|
+
4,
|
|
669
|
+
waitForCompletion(closeEvent, function() {
|
|
670
|
+
return isClosed;
|
|
671
|
+
}, tree, PROCESS_TERMINATION_TIMEOUT_MS)
|
|
672
|
+
];
|
|
673
|
+
case 13:
|
|
674
|
+
completion = _state.sent();
|
|
675
|
+
if (!isCompletionSuccessful(completion)) {
|
|
676
|
+
errors.push(new Error("Server '".concat(name, "' did not close").concat(completion.processGroupEmpty === false ? ' with its POSIX process group' : '', " after emergency termination")));
|
|
677
|
+
}
|
|
678
|
+
_state.label = 14;
|
|
679
|
+
case 14:
|
|
680
|
+
if (opts.stop && !stopSucceeded && errors.length === 0) {
|
|
681
|
+
errors.push(new Error("Server '".concat(name, "' application stop command did not complete successfully")));
|
|
682
|
+
}
|
|
683
|
+
if (errors.length > 0) throw new AggregateError(errors, "Server '".concat(name, "' shutdown completed with ").concat(errors.length, " failure(s)"));
|
|
684
|
+
return [
|
|
685
|
+
2,
|
|
686
|
+
{
|
|
687
|
+
timedOut: timedOut,
|
|
688
|
+
killed: killed
|
|
689
|
+
}
|
|
690
|
+
];
|
|
691
|
+
}
|
|
389
692
|
});
|
|
390
693
|
})();
|
|
391
694
|
};
|
|
695
|
+
var close = function close() {
|
|
696
|
+
var signal = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 'SIGINT', closeOptions = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
697
|
+
var _closeOptions_timeoutMs;
|
|
698
|
+
closePromise !== null && closePromise !== void 0 ? closePromise : closePromise = performClose(signal, (_closeOptions_timeoutMs = closeOptions.timeoutMs) !== null && _closeOptions_timeoutMs !== void 0 ? _closeOptions_timeoutMs : DEFAULT_CLOSE_TIMEOUT_MS);
|
|
699
|
+
return closePromise;
|
|
700
|
+
};
|
|
392
701
|
return {
|
|
393
702
|
config: resolvedConfig,
|
|
394
703
|
process: child,
|
|
395
|
-
close:
|
|
704
|
+
close: close
|
|
396
705
|
};
|
|
397
706
|
}
|
|
398
707
|
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/spawn/spawn-server.ts"],"sourcesContent":["/**\n * Low-level single server spawning utilities.\n * Provides core process spawning with path resolution, environment management, and lifecycle control.\n */\n\nimport { type ChildProcess, type SpawnOptions, type StdioOptions, spawn } from 'child_process';\nimport * as process from 'process';\nimport { logger } from '../utils/logger.ts';\nimport { resolveArgsPaths } from '../utils/path-utils.ts';\n\n/**\n * Options for spawning a single server process.\n * @internal\n */\nexport interface SpawnProcessOptions {\n /** Server name for logging */\n name: string;\n /** Command to execute (e.g., 'node', 'npx') */\n command: string;\n /** Command arguments (paths will be resolved relative to cwd) */\n args?: string[];\n /** Working directory (must be absolute path) */\n cwd?: string;\n /** Additional environment variables (merged with process.env) */\n env?: Record<string, string>;\n /** Standard I/O configuration */\n stdio?: StdioOptions;\n /** Use shell for command execution (default: false, true on Windows) */\n shell?: boolean;\n}\n\n/**\n * Handle to a spawned server process.\n * Provides access to the process, resolved config, and lifecycle control.\n * @hidden\n */\nexport interface ServerProcess {\n /**\n * The resolved server configuration that was actually used.\n * Useful for debugging and understanding what was spawned.\n */\n config: {\n name: string;\n command: string;\n args: string[];\n cwd: string;\n env: Record<string, string>;\n stdio: StdioOptions;\n shell: boolean;\n };\n\n /**\n * The spawned child process.\n */\n process: ChildProcess;\n\n /**\n * Close the server gracefully.\n * Sends the specified signal (default: SIGINT), then SIGKILL after timeout.\n *\n * @param signal - Signal to send (default: SIGINT)\n * @param opts - Options including timeout\n * @returns Promise resolving to whether the process timed out and was force-killed\n */\n close: (signal?: NodeJS.Signals, opts?: { timeoutMs?: number }) => Promise<{ timedOut: boolean; killed: boolean }>;\n}\n\n/**\n * Normalize environment variables by merging with process.env and filtering undefined values.\n */\nfunction normalizeEnv(env?: Record<string, string>): Record<string, string> {\n const merged = { ...process.env, ...(env || {}) };\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(merged)) {\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Spawn a single server process with path resolution and environment management.\n *\n * @internal\n * @param opts - Server spawn options\n * @returns ServerProcess handle with resolved config, process, and stop function\n *\n * @example\n * const handle = spawnProcess({\n * name: 'echo',\n * command: 'node',\n * args: ['./bin/server.js', '--port', '3000'],\n * cwd: '/home/user/project/test/lib/servers/echo',\n * env: { LOG_LEVEL: 'error' }\n * });\n *\n * // Later...\n * await handle.close();\n */\nexport function spawnProcess(opts: SpawnProcessOptions): ServerProcess {\n const name = opts.name;\n const command = opts.command;\n const cwd = opts.cwd ?? process.cwd();\n const stdio = opts.stdio ?? 'inherit';\n const shell = opts.shell ?? process.platform === 'win32';\n\n // Resolve paths in args relative to the working directory\n const args = opts.args ? resolveArgsPaths(opts.args, cwd) : [];\n\n // Merge environment variables\n const env = normalizeEnv(opts.env);\n\n // Create resolved config for return value\n const resolvedConfig = {\n name,\n command,\n args,\n cwd,\n env,\n stdio,\n shell,\n };\n\n // Log spawn operation\n logger.info(`[${name}] → ${command} ${args.join(' ')}`);\n\n // Spawn the process\n const spawnOpts: SpawnOptions = { cwd, env, stdio, shell };\n const child = spawn(command, args, spawnOpts);\n\n // Pipe stdio if not inherited\n if (child.stderr)\n child.stderr.on('data', (chunk) => {\n process.stderr.write(chunk);\n });\n\n // Attach lifecycle logging\n child.on('exit', (code, sig) => logger.info(`[${name}] exited (code=${code}, signal=${sig || 'none'})`));\n child.on('error', (err) => logger.info(`[${name}] process error: ${err.message}`));\n\n // Create stop function with graceful shutdown\n const stop = async (signal: NodeJS.Signals = 'SIGINT', opts: { timeoutMs?: number } = {}): Promise<{ timedOut: boolean; killed: boolean }> => {\n // If already exited, return immediately\n if (child.exitCode !== null || child.signalCode !== null) {\n return { timedOut: false, killed: false };\n }\n\n const timeoutMs = opts.timeoutMs ?? 500;\n\n // Wait for 'close' event (process exit + stdio streams closed)\n // This is better than 'exit' because it ensures stdio is fully cleaned up\n const closePromise = new Promise<{ timedOut: boolean; killed: boolean }>((resolve) => {\n let isResolved = false;\n let wasKilled = false;\n\n const resolveOnce = (timedOut: boolean) => {\n if (isResolved) return;\n isResolved = true;\n clearTimeout(timeout);\n resolve({ timedOut, killed: wasKilled });\n };\n\n // Set timeout for forceful kill\n const timeout = setTimeout(() => {\n try {\n // Check again before SIGKILL\n if (child.exitCode === null && !child.killed) {\n child.kill('SIGKILL');\n wasKilled = true;\n }\n } catch (_) {}\n // Even if kill fails, resolve\n resolveOnce(true);\n }, timeoutMs);\n\n // Listen for 'close' event (not 'exit') to wait for stdio close\n child.once('close', () => {\n resolveOnce(false);\n });\n\n // Also listen for 'error' event in case spawn failed\n // This prevents promise from hanging forever if process never started\n child.once('error', () => {\n resolveOnce(false);\n });\n\n // Send graceful shutdown signal\n try {\n // Check one more time before killing\n if (child.exitCode !== null) {\n resolveOnce(false);\n return;\n }\n\n const killed = child.kill(signal);\n // If kill returned false, process already exited\n if (!killed) {\n resolveOnce(false);\n }\n } catch (_err) {\n // If kill throws, process is gone or unreachable\n resolveOnce(false);\n }\n });\n\n return closePromise;\n };\n\n return {\n config: resolvedConfig,\n process: child,\n close: stop,\n };\n}\n"],"names":["spawnProcess","normalizeEnv","env","merged","process","result","Object","entries","key","value","undefined","opts","name","command","cwd","stdio","shell","platform","args","resolveArgsPaths","resolvedConfig","logger","info","join","spawnOpts","child","spawn","stderr","on","chunk","write","code","sig","err","message","stop","signal","timeoutMs","closePromise","exitCode","signalCode","timedOut","killed","Promise","resolve","isResolved","wasKilled","resolveOnce","clearTimeout","timeout","setTimeout","kill","_","once","_err","config","close"],"mappings":"AAAA;;;CAGC;;;;+BAiGeA;;;eAAAA;;;6BA/F+D;+DACtD;wBACF;2BACU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DjC;;CAEC,GACD,SAASC,aAAaC,GAA4B;IAChD,IAAMC,SAAS,mBAAKC,SAAQF,GAAG,EAAMA,OAAO,CAAC;IAC7C,IAAMG,SAAiC,CAAC;QACnC,kCAAA,2BAAA;;QAAL,QAAK,YAAsBC,OAAOC,OAAO,CAACJ,4BAArC,SAAA,6BAAA,QAAA,yBAAA,iCAA8C;YAA9C,mCAAA,iBAAOK,sBAAKC;YACf,IAAIA,UAAUC,WAAW;gBACvBL,MAAM,CAACG,IAAI,GAAGC;YAChB;QACF;;QAJK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAKL,OAAOJ;AACT;AAqBO,SAASL,aAAaW,IAAyB;QAGxCA,WACEA,aACAA;IAJd,IAAMC,OAAOD,KAAKC,IAAI;IACtB,IAAMC,UAAUF,KAAKE,OAAO;IAC5B,IAAMC,OAAMH,YAAAA,KAAKG,GAAG,cAARH,uBAAAA,YAAYP,SAAQU,GAAG;IACnC,IAAMC,SAAQJ,cAAAA,KAAKI,KAAK,cAAVJ,yBAAAA,cAAc;IAC5B,IAAMK,SAAQL,cAAAA,KAAKK,KAAK,cAAVL,yBAAAA,cAAcP,SAAQa,QAAQ,KAAK;IAEjD,0DAA0D;IAC1D,IAAMC,OAAOP,KAAKO,IAAI,GAAGC,IAAAA,6BAAgB,EAACR,KAAKO,IAAI,EAAEJ,OAAO,EAAE;IAE9D,8BAA8B;IAC9B,IAAMZ,MAAMD,aAAaU,KAAKT,GAAG;IAEjC,0CAA0C;IAC1C,IAAMkB,iBAAiB;QACrBR,MAAAA;QACAC,SAAAA;QACAK,MAAAA;QACAJ,KAAAA;QACAZ,KAAAA;QACAa,OAAAA;QACAC,OAAAA;IACF;IAEA,sBAAsB;IACtBK,gBAAM,CAACC,IAAI,CAAC,AAAC,IAAcT,OAAXD,MAAK,QAAiBM,OAAXL,SAAQ,KAAkB,OAAfK,KAAKK,IAAI,CAAC;IAEhD,oBAAoB;IACpB,IAAMC,YAA0B;QAAEV,KAAAA;QAAKZ,KAAAA;QAAKa,OAAAA;QAAOC,OAAAA;IAAM;IACzD,IAAMS,QAAQC,IAAAA,oBAAK,EAACb,SAASK,MAAMM;IAEnC,8BAA8B;IAC9B,IAAIC,MAAME,MAAM,EACdF,MAAME,MAAM,CAACC,EAAE,CAAC,QAAQ,SAACC;QACvBzB,SAAQuB,MAAM,CAACG,KAAK,CAACD;IACvB;IAEF,2BAA2B;IAC3BJ,MAAMG,EAAE,CAAC,QAAQ,SAACG,MAAMC;eAAQX,gBAAM,CAACC,IAAI,CAAC,AAAC,IAAyBS,OAAtBnB,MAAK,mBAAiCoB,OAAhBD,MAAK,aAAyB,OAAdC,OAAO,QAAO;;IACpGP,MAAMG,EAAE,CAAC,SAAS,SAACK;eAAQZ,gBAAM,CAACC,IAAI,CAAC,AAAC,IAA2BW,OAAxBrB,MAAK,qBAA+B,OAAZqB,IAAIC,OAAO;;IAE9E,8CAA8C;IAC9C,IAAMC,OAAO;YAAOC,0EAAyB,UAAUzB,0EAA+B,CAAC;;gBAMnEA,iBAAZ0B,WAIAC;;gBATN,wCAAwC;gBACxC,IAAIb,MAAMc,QAAQ,KAAK,QAAQd,MAAMe,UAAU,KAAK,MAAM;oBACxD;;wBAAO;4BAAEC,UAAU;4BAAOC,QAAQ;wBAAM;;gBAC1C;gBAEML,aAAY1B,kBAAAA,OAAK0B,SAAS,cAAd1B,6BAAAA,kBAAkB;gBAEpC,+DAA+D;gBAC/D,0EAA0E;gBACpE2B,eAAe,IAAIK,QAAgD,SAACC;oBACxE,IAAIC,aAAa;oBACjB,IAAIC,YAAY;oBAEhB,IAAMC,cAAc,qBAACN;wBACnB,IAAII,YAAY;wBAChBA,aAAa;wBACbG,aAAaC;wBACbL,QAAQ;4BAAEH,UAAAA;4BAAUC,QAAQI;wBAAU;oBACxC;oBAEA,gCAAgC;oBAChC,IAAMG,UAAUC,WAAW;wBACzB,IAAI;4BACF,6BAA6B;4BAC7B,IAAIzB,MAAMc,QAAQ,KAAK,QAAQ,CAACd,MAAMiB,MAAM,EAAE;gCAC5CjB,MAAM0B,IAAI,CAAC;gCACXL,YAAY;4BACd;wBACF,EAAE,OAAOM,GAAG,CAAC;wBACb,8BAA8B;wBAC9BL,YAAY;oBACd,GAAGV;oBAEH,gEAAgE;oBAChEZ,MAAM4B,IAAI,CAAC,SAAS;wBAClBN,YAAY;oBACd;oBAEA,qDAAqD;oBACrD,sEAAsE;oBACtEtB,MAAM4B,IAAI,CAAC,SAAS;wBAClBN,YAAY;oBACd;oBAEA,gCAAgC;oBAChC,IAAI;wBACF,qCAAqC;wBACrC,IAAItB,MAAMc,QAAQ,KAAK,MAAM;4BAC3BQ,YAAY;4BACZ;wBACF;wBAEA,IAAML,SAASjB,MAAM0B,IAAI,CAACf;wBAC1B,iDAAiD;wBACjD,IAAI,CAACM,QAAQ;4BACXK,YAAY;wBACd;oBACF,EAAE,OAAOO,MAAM;wBACb,iDAAiD;wBACjDP,YAAY;oBACd;gBACF;gBAEA;;oBAAOT;;;QACT;;IAEA,OAAO;QACLiB,QAAQnC;QACRhB,SAASqB;QACT+B,OAAOrB;IACT;AACF"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/client/src/spawn/spawn-server.ts"],"sourcesContent":["/**\n * Low-level single server spawning utilities.\n * Provides core process spawning with path resolution, environment management, and lifecycle control.\n */\n\nimport type { ChildProcess, StdioOptions } from 'child_process';\nimport crossSpawn from 'cross-spawn';\nimport * as path from 'path';\nimport * as process from 'process';\nimport type { StopCommandConfig } from '../types.ts';\nimport { logger } from '../utils/logger.ts';\nimport { resolveArgsPaths } from '../utils/path-utils.ts';\nimport { OwnedProcessTree } from './owned-process-tree.ts';\n\nconst DEFAULT_CLOSE_TIMEOUT_MS = 5000;\nconst PROCESS_TERMINATION_TIMEOUT_MS = 5000;\nconst PROCESS_POLL_INTERVAL_MS = 25;\n\ninterface ProcessCloseEvent {\n code: number | null;\n signal: NodeJS.Signals | null;\n}\n\ninterface ProcessCompletion {\n closed: boolean;\n processGroupEmpty?: boolean;\n error?: Error;\n}\n\n/**\n * Options for spawning a single server process.\n * @internal\n */\nexport interface SpawnProcessOptions {\n /** Server name for logging */\n name: string;\n /** Command to execute (e.g., 'node', 'npx') */\n command: string;\n /** Command arguments (paths will be resolved relative to cwd) */\n args?: string[];\n /** Working directory (must be absolute path) */\n cwd?: string;\n /** Additional environment variables (merged with process.env) */\n env?: Record<string, string>;\n /** Whether to add process.env to env; registry callers provide a pre-merged environment */\n inheritEnv?: boolean;\n /** Standard I/O configuration */\n stdio?: StdioOptions;\n /** Application-specific shutdown command for an owned HTTP server */\n stop?: StopCommandConfig;\n}\n\n/**\n * Handle to a spawned server process.\n * Provides access to the process, resolved config, and lifecycle control.\n * @hidden\n */\nexport interface ServerProcess {\n config: {\n name: string;\n command: string;\n args: string[];\n cwd: string;\n env: Record<string, string>;\n stdio: StdioOptions;\n shell: false;\n };\n process: ChildProcess;\n close: (signal?: NodeJS.Signals, opts?: { timeoutMs?: number }) => Promise<{ timedOut: boolean; killed: boolean }>;\n}\n\nfunction normalizeEnv(env?: Record<string, string>, inheritEnv = true): Record<string, string> {\n const merged = { ...(inheritEnv ? process.env : {}), ...(env || {}) };\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(merged)) {\n if (value !== undefined) result[key] = value;\n }\n return result;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function waitForCompletion(closeEvent: Promise<ProcessCloseEvent>, childClosed: () => boolean, tree: OwnedProcessTree | undefined, timeoutMs: number): Promise<ProcessCompletion> {\n if (!tree) return { closed: (await waitForChildClose(closeEvent, timeoutMs)) !== undefined };\n\n const deadline = Date.now() + timeoutMs;\n let lastError: Error | undefined;\n while (true) {\n let processGroupEmpty = false;\n try {\n processGroupEmpty = tree.isEmpty();\n lastError = undefined;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n }\n const closed = childClosed();\n if (closed && processGroupEmpty) return { closed, processGroupEmpty };\n if (Date.now() >= deadline) return { closed, processGroupEmpty, ...(lastError && { error: lastError }) };\n await delay(Math.min(PROCESS_POLL_INTERVAL_MS, Math.max(1, deadline - Date.now())));\n }\n}\n\nfunction isCompletionSuccessful(completion: ProcessCompletion): boolean {\n return completion.closed && completion.processGroupEmpty !== false;\n}\n\nfunction terminateChild(child: ChildProcess, tree: OwnedProcessTree | undefined): { killed: boolean; error?: Error } {\n if (tree) return tree.terminate();\n try {\n return { killed: child.kill('SIGKILL') };\n } catch (error) {\n return { killed: false, error: asError(error) };\n }\n}\n\nfunction waitForChildClose(closeEvent: Promise<ProcessCloseEvent>, timeoutMs: number): Promise<ProcessCloseEvent | undefined> {\n let timer: NodeJS.Timeout | undefined;\n return Promise.race([\n closeEvent,\n new Promise<undefined>((resolve) => {\n timer = setTimeout(() => resolve(undefined), timeoutMs);\n }),\n ]).finally(() => {\n if (timer) clearTimeout(timer);\n });\n}\n\nfunction requestProcessSignal(child: ChildProcess, signal: NodeJS.Signals): void {\n if (!child.pid) throw new Error('Cannot request cooperative shutdown because the server has no process ID');\n if (process.platform === 'win32') throw new Error('POSIX process signals are not available on Windows');\n try {\n process.kill(-child.pid, signal);\n } catch (error) {\n if (!(error instanceof Error && 'code' in error && error.code === 'ESRCH')) throw error;\n }\n}\n\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction withCause(message: string, cause: Error): Error {\n return new Error(message, { cause });\n}\n\nasync function runStopCommand(command: StopCommandConfig, cwd: string, timeoutMs: number, inheritEnv: boolean): Promise<void> {\n const stopCwd = command.cwd ? path.resolve(cwd, command.cwd) : cwd;\n const env = normalizeEnv(command.env, inheritEnv);\n const args = command.args ? resolveArgsPaths(command.args, stopCwd) : [];\n const child = crossSpawn(command.command, args, {\n cwd: stopCwd,\n env,\n stdio: 'ignore',\n shell: false,\n detached: process.platform !== 'win32',\n windowsHide: true,\n });\n let spawnError: Error | undefined;\n let closed = false;\n let closeEventValue: ProcessCloseEvent | undefined;\n const closeEvent = new Promise<ProcessCloseEvent>((resolve) => {\n child.once('error', (error) => {\n spawnError = error;\n });\n child.once('close', (code, signal) => {\n closed = true;\n closeEventValue = { code, signal };\n resolve({ code, signal });\n });\n });\n\n if (!child.pid) {\n const result = await waitForChildClose(closeEvent, timeoutMs);\n if (!result) throw new Error(`Stop command did not start or close within ${timeoutMs}ms`);\n if (spawnError) throw withCause(`Stop command could not be started: ${spawnError.message}`, spawnError);\n }\n\n const tree = child.pid && process.platform !== 'win32' ? new OwnedProcessTree(child.pid) : undefined;\n const completion = await waitForCompletion(closeEvent, () => closed, tree, timeoutMs);\n if (!isCompletionSuccessful(completion)) {\n const termination = terminateChild(child, tree);\n const afterTermination = await waitForCompletion(closeEvent, () => closed, tree, PROCESS_TERMINATION_TIMEOUT_MS);\n const details = [completion.error?.message, termination.error?.message].filter(Boolean).join('; ');\n const reason = `Stop command exceeded ${timeoutMs}ms and required emergency process termination`;\n const remaining = !isCompletionSuccessful(afterTermination) ? '; stop command or its POSIX process group remained alive' : '';\n throw new Error(`${reason}${details ? `: ${details}` : ''}${remaining}`);\n }\n\n if (spawnError) throw withCause(`Stop command could not be started: ${spawnError.message}`, spawnError);\n if (closeEventValue && (closeEventValue.code !== 0 || closeEventValue.signal !== null)) {\n throw new Error(`Stop command exited with code ${closeEventValue.code ?? 'unknown'}${closeEventValue.signal ? ` (signal ${closeEventValue.signal})` : ''}`);\n }\n}\n\n/**\n * Spawn a single server process with path resolution and environment management.\n *\n * @internal\n * @param opts - Server spawn options\n * @returns ServerProcess handle with resolved config and lifecycle control\n */\nexport function spawnProcess(opts: SpawnProcessOptions): ServerProcess {\n const name = opts.name;\n const command = opts.command;\n const cwd = opts.cwd ?? process.cwd();\n const stdio = opts.stdio ?? 'inherit';\n const args = opts.args ? resolveArgsPaths(opts.args, cwd) : [];\n const inheritEnv = opts.inheritEnv ?? true;\n const env = normalizeEnv(opts.env, inheritEnv);\n const resolvedConfig = { name, command, args, cwd, env, stdio, shell: false as const };\n\n logger.info(`[${name}] → ${command} ${args.join(' ')}`);\n const child = crossSpawn(command, args, {\n cwd,\n env,\n stdio,\n shell: false,\n detached: process.platform !== 'win32',\n windowsHide: true,\n });\n\n if (child.stderr) child.stderr.on('data', (chunk) => process.stderr.write(chunk));\n\n let isClosed = false;\n let _closeEventValue: ProcessCloseEvent | undefined;\n const closeEvent = new Promise<ProcessCloseEvent>((resolve) => {\n child.once('close', (code, signal) => {\n isClosed = true;\n _closeEventValue = { code, signal };\n logger.info(`[${name}] closed (code=${code}, signal=${signal || 'none'})`);\n resolve({ code, signal });\n });\n child.once('error', (error) => logger.info(`[${name}] process error: ${error.message}`));\n });\n const tree = child.pid && process.platform !== 'win32' ? new OwnedProcessTree(child.pid) : undefined;\n let closePromise: Promise<{ timedOut: boolean; killed: boolean }> | undefined;\n\n const performClose = async (signal: NodeJS.Signals, timeoutMs: number): Promise<{ timedOut: boolean; killed: boolean }> => {\n if (!child.pid) {\n await waitForChildClose(closeEvent, timeoutMs);\n throw new Error(`Cannot verify shutdown of server '${name}' because it has no process ID`);\n }\n\n let timedOut = false;\n let killed = false;\n const errors: Error[] = [];\n let stopSucceeded = false;\n\n if (opts.stop) {\n try {\n await runStopCommand(opts.stop, cwd, timeoutMs, inheritEnv);\n stopSucceeded = true;\n } catch (error) {\n errors.push(withCause(`Server '${name}' application stop command failed: ${asError(error).message}`, asError(error)));\n }\n } else if (child.stdin && !child.stdin.destroyed && !child.stdin.writableEnded) {\n child.stdin.end();\n } else if (process.platform !== 'win32') {\n try {\n requestProcessSignal(child, signal);\n } catch (error) {\n errors.push(withCause(`Server '${name}' cooperative signal failed: ${asError(error).message}`, asError(error)));\n }\n }\n\n let completion = await waitForCompletion(closeEvent, () => isClosed, tree, timeoutMs);\n if (completion.error) errors.push(withCause(`Could not inspect the owned process tree for server '${name}'`, completion.error));\n\n if (!isCompletionSuccessful(completion)) {\n timedOut = true;\n if (!opts.stop && child.stdin && process.platform !== 'win32') {\n try {\n requestProcessSignal(child, signal);\n } catch (error) {\n errors.push(withCause(`Server '${name}' cooperative signal failed: ${asError(error).message}`, asError(error)));\n }\n completion = await waitForCompletion(closeEvent, () => isClosed, tree, timeoutMs);\n if (completion.error) errors.push(withCause(`Could not inspect the owned process tree for server '${name}'`, completion.error));\n } else if (!opts.stop && process.platform !== 'win32' && !child.stdin) {\n // The first signal was sent before waiting for an inherited-stdio HTTP process.\n }\n }\n\n if (!isCompletionSuccessful(completion)) {\n const termination = terminateChild(child, tree);\n killed ||= termination.killed;\n if (termination.error) errors.push(withCause(`Emergency termination failed for server '${name}'`, termination.error));\n completion = await waitForCompletion(closeEvent, () => isClosed, tree, PROCESS_TERMINATION_TIMEOUT_MS);\n if (!isCompletionSuccessful(completion)) {\n errors.push(new Error(`Server '${name}' did not close${completion.processGroupEmpty === false ? ' with its POSIX process group' : ''} after emergency termination`));\n }\n }\n\n if (opts.stop && !stopSucceeded && errors.length === 0) {\n errors.push(new Error(`Server '${name}' application stop command did not complete successfully`));\n }\n if (errors.length > 0) throw new AggregateError(errors, `Server '${name}' shutdown completed with ${errors.length} failure(s)`);\n return { timedOut, killed };\n };\n\n const close = (signal: NodeJS.Signals = 'SIGINT', closeOptions: { timeoutMs?: number } = {}): Promise<{ timedOut: boolean; killed: boolean }> => {\n closePromise ??= performClose(signal, closeOptions.timeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS);\n return closePromise;\n };\n\n return { config: resolvedConfig, process: child, close };\n}\n"],"names":["spawnProcess","DEFAULT_CLOSE_TIMEOUT_MS","PROCESS_TERMINATION_TIMEOUT_MS","PROCESS_POLL_INTERVAL_MS","normalizeEnv","env","inheritEnv","merged","process","result","Object","entries","key","value","undefined","delay","ms","Promise","resolve","setTimeout","waitForCompletion","closeEvent","childClosed","tree","timeoutMs","deadline","lastError","processGroupEmpty","closed","waitForChildClose","Date","now","isEmpty","error","Error","String","Math","min","max","isCompletionSuccessful","completion","terminateChild","child","terminate","killed","kill","asError","timer","race","finally","clearTimeout","requestProcessSignal","signal","pid","platform","code","withCause","message","cause","runStopCommand","command","cwd","stopCwd","args","spawnError","closeEventValue","termination","afterTermination","details","reason","remaining","path","resolveArgsPaths","crossSpawn","stdio","shell","detached","windowsHide","once","OwnedProcessTree","filter","Boolean","join","opts","name","resolvedConfig","logger","info","stderr","on","chunk","write","isClosed","_closeEventValue","closePromise","performClose","timedOut","errors","stopSucceeded","stop","push","stdin","destroyed","writableEnded","end","length","AggregateError","close","closeOptions","config"],"mappings":"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"}
|