@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.
Files changed (111) hide show
  1. package/README.md +12 -1
  2. package/dist/cjs/auth/capability-discovery.d.cts +3 -1
  3. package/dist/cjs/auth/capability-discovery.d.ts +3 -1
  4. package/dist/cjs/auth/capability-discovery.js +46 -32
  5. package/dist/cjs/auth/capability-discovery.js.map +1 -1
  6. package/dist/cjs/auth/discovery-fetch.d.cts +2 -0
  7. package/dist/cjs/auth/discovery-fetch.d.ts +2 -0
  8. package/dist/cjs/auth/discovery-fetch.js +85 -31
  9. package/dist/cjs/auth/discovery-fetch.js.map +1 -1
  10. package/dist/cjs/auth/interactive-oauth-flow.d.cts +1 -1
  11. package/dist/cjs/auth/interactive-oauth-flow.d.ts +1 -1
  12. package/dist/cjs/auth/interactive-oauth-flow.js +13 -6
  13. package/dist/cjs/auth/interactive-oauth-flow.js.map +1 -1
  14. package/dist/cjs/auth/oauth-callback-listener.d.cts +1 -1
  15. package/dist/cjs/auth/oauth-callback-listener.d.ts +1 -1
  16. package/dist/cjs/auth/oauth-callback-listener.js +40 -4
  17. package/dist/cjs/auth/oauth-callback-listener.js.map +1 -1
  18. package/dist/cjs/auth/rfc9728-discovery.d.cts +7 -2
  19. package/dist/cjs/auth/rfc9728-discovery.d.ts +7 -2
  20. package/dist/cjs/auth/rfc9728-discovery.js +120 -88
  21. package/dist/cjs/auth/rfc9728-discovery.js.map +1 -1
  22. package/dist/cjs/auth/types.d.cts +4 -0
  23. package/dist/cjs/auth/types.d.ts +4 -0
  24. package/dist/cjs/auth/types.js.map +1 -1
  25. package/dist/cjs/connection/connect-client.d.cts +9 -1
  26. package/dist/cjs/connection/connect-client.d.ts +9 -1
  27. package/dist/cjs/connection/connect-client.js +282 -75
  28. package/dist/cjs/connection/connect-client.js.map +1 -1
  29. package/dist/cjs/connection/existing-process-transport.d.cts +18 -18
  30. package/dist/cjs/connection/existing-process-transport.d.ts +18 -18
  31. package/dist/cjs/connection/existing-process-transport.js +187 -82
  32. package/dist/cjs/connection/existing-process-transport.js.map +1 -1
  33. package/dist/cjs/connection/wait-for-http-ready.d.cts +1 -1
  34. package/dist/cjs/connection/wait-for-http-ready.d.ts +1 -1
  35. package/dist/cjs/connection/wait-for-http-ready.js +30 -5
  36. package/dist/cjs/connection/wait-for-http-ready.js.map +1 -1
  37. package/dist/cjs/dcr/dcr-authenticator.d.cts +1 -1
  38. package/dist/cjs/dcr/dcr-authenticator.d.ts +1 -1
  39. package/dist/cjs/dcr/dcr-authenticator.js +29 -18
  40. package/dist/cjs/dcr/dcr-authenticator.js.map +1 -1
  41. package/dist/cjs/dcr/dynamic-client-registrar.js +2 -1
  42. package/dist/cjs/dcr/dynamic-client-registrar.js.map +1 -1
  43. package/dist/cjs/index.d.cts +1 -1
  44. package/dist/cjs/index.d.ts +1 -1
  45. package/dist/cjs/index.js.map +1 -1
  46. package/dist/cjs/spawn/owned-process-tree.d.cts +12 -0
  47. package/dist/cjs/spawn/owned-process-tree.d.ts +12 -0
  48. package/dist/cjs/spawn/owned-process-tree.js +93 -0
  49. package/dist/cjs/spawn/owned-process-tree.js.map +1 -0
  50. package/dist/cjs/spawn/spawn-server.d.cts +8 -32
  51. package/dist/cjs/spawn/spawn-server.d.ts +8 -32
  52. package/dist/cjs/spawn/spawn-server.js +406 -97
  53. package/dist/cjs/spawn/spawn-server.js.map +1 -1
  54. package/dist/cjs/spawn/spawn-servers.d.cts +18 -8
  55. package/dist/cjs/spawn/spawn-servers.d.ts +18 -8
  56. package/dist/cjs/spawn/spawn-servers.js +342 -113
  57. package/dist/cjs/spawn/spawn-servers.js.map +1 -1
  58. package/dist/cjs/types.d.cts +1 -1
  59. package/dist/cjs/types.d.ts +1 -1
  60. package/dist/cjs/types.js.map +1 -1
  61. package/dist/cjs/utils/path-utils.js +7 -4
  62. package/dist/cjs/utils/path-utils.js.map +1 -1
  63. package/dist/esm/auth/capability-discovery.d.ts +3 -1
  64. package/dist/esm/auth/capability-discovery.js +21 -11
  65. package/dist/esm/auth/capability-discovery.js.map +1 -1
  66. package/dist/esm/auth/discovery-fetch.d.ts +2 -0
  67. package/dist/esm/auth/discovery-fetch.js +64 -23
  68. package/dist/esm/auth/discovery-fetch.js.map +1 -1
  69. package/dist/esm/auth/interactive-oauth-flow.d.ts +1 -1
  70. package/dist/esm/auth/interactive-oauth-flow.js +13 -6
  71. package/dist/esm/auth/interactive-oauth-flow.js.map +1 -1
  72. package/dist/esm/auth/oauth-callback-listener.d.ts +1 -1
  73. package/dist/esm/auth/oauth-callback-listener.js +34 -4
  74. package/dist/esm/auth/oauth-callback-listener.js.map +1 -1
  75. package/dist/esm/auth/rfc9728-discovery.d.ts +7 -2
  76. package/dist/esm/auth/rfc9728-discovery.js +40 -16
  77. package/dist/esm/auth/rfc9728-discovery.js.map +1 -1
  78. package/dist/esm/auth/types.d.ts +4 -0
  79. package/dist/esm/auth/types.js.map +1 -1
  80. package/dist/esm/connection/connect-client.d.ts +9 -1
  81. package/dist/esm/connection/connect-client.js +97 -35
  82. package/dist/esm/connection/connect-client.js.map +1 -1
  83. package/dist/esm/connection/existing-process-transport.d.ts +18 -18
  84. package/dist/esm/connection/existing-process-transport.js +132 -70
  85. package/dist/esm/connection/existing-process-transport.js.map +1 -1
  86. package/dist/esm/connection/wait-for-http-ready.d.ts +1 -1
  87. package/dist/esm/connection/wait-for-http-ready.js +19 -4
  88. package/dist/esm/connection/wait-for-http-ready.js.map +1 -1
  89. package/dist/esm/dcr/dcr-authenticator.d.ts +1 -1
  90. package/dist/esm/dcr/dcr-authenticator.js +26 -15
  91. package/dist/esm/dcr/dcr-authenticator.js.map +1 -1
  92. package/dist/esm/dcr/dynamic-client-registrar.js +2 -1
  93. package/dist/esm/dcr/dynamic-client-registrar.js.map +1 -1
  94. package/dist/esm/index.d.ts +1 -1
  95. package/dist/esm/index.js.map +1 -1
  96. package/dist/esm/spawn/owned-process-tree.d.ts +12 -0
  97. package/dist/esm/spawn/owned-process-tree.js +39 -0
  98. package/dist/esm/spawn/owned-process-tree.js.map +1 -0
  99. package/dist/esm/spawn/spawn-server.d.ts +8 -32
  100. package/dist/esm/spawn/spawn-server.js +228 -99
  101. package/dist/esm/spawn/spawn-server.js.map +1 -1
  102. package/dist/esm/spawn/spawn-servers.d.ts +18 -8
  103. package/dist/esm/spawn/spawn-servers.js +180 -55
  104. package/dist/esm/spawn/spawn-servers.js.map +1 -1
  105. package/dist/esm/types.d.ts +1 -1
  106. package/dist/esm/types.js.map +1 -1
  107. package/dist/esm/utils/path-utils.js +7 -4
  108. package/dist/esm/utils/path-utils.js.map +1 -1
  109. package/package.json +8 -3
  110. package/schemas/servers.d.ts +24 -0
  111. 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 _child_process = require("child_process");
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
- * Normalize environment variables by merging with process.env and filtering undefined values.
247
- */ function normalizeEnv(env) {
248
- var merged = _object_spread({}, _process.env, env || {});
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, _opts_shell;
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
- // Merge environment variables
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: shell
514
+ shell: false
294
515
  };
295
- // Log spawn operation
296
516
  _loggerts.logger.info("[".concat(name, "] → ").concat(command, " ").concat(args.join(' ')));
297
- // Spawn the process
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: shell
303
- };
304
- var child = (0, _child_process.spawn)(command, args, spawnOpts);
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
- // Attach lifecycle logging
310
- child.on('exit', function(code, sig) {
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
- child.on('error', function(err) {
314
- return _loggerts.logger.info("[".concat(name, "] process error: ").concat(err.message));
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
- // Create stop function with graceful shutdown
317
- var stop = function stop() {
318
- var signal = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 'SIGINT', _$opts = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
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 _opts_timeoutMs, timeoutMs, closePromise;
551
+ var timedOut, killed, errors, stopSucceeded, error, completion, termination;
321
552
  return _ts_generator(this, function(_state) {
322
- // If already exited, return immediately
323
- if (child.exitCode !== null || child.signalCode !== null) {
324
- return [
325
- 2,
326
- {
327
- timedOut: false,
328
- killed: false
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
- timeoutMs = (_opts_timeoutMs = _$opts.timeoutMs) !== null && _opts_timeoutMs !== void 0 ? _opts_timeoutMs : 500;
333
- // Wait for 'close' event (process exit + stdio streams closed)
334
- // This is better than 'exit' because it ensures stdio is fully cleaned up
335
- closePromise = new Promise(function(resolve) {
336
- var isResolved = false;
337
- var wasKilled = false;
338
- var resolveOnce = function resolveOnce(timedOut) {
339
- if (isResolved) return;
340
- isResolved = true;
341
- clearTimeout(timeout);
342
- resolve({
343
- timedOut: timedOut,
344
- killed: wasKilled
345
- });
346
- };
347
- // Set timeout for forceful kill
348
- var timeout = setTimeout(function() {
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
- // Check again before SIGKILL
351
- if (child.exitCode === null && !child.killed) {
352
- child.kill('SIGKILL');
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
- var killed = child.kill(signal);
376
- // If kill returned false, process already exited
377
- if (!killed) {
378
- resolveOnce(false);
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
- } catch (_err) {
381
- // If kill throws, process is gone or unreachable
382
- resolveOnce(false);
383
- }
384
- });
385
- return [
386
- 2,
387
- closePromise
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: stop
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":"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"}
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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"}