@ai-ecoverse/mcpcat 0.15.7 → 0.15.9

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.
@@ -8119,37 +8119,55 @@ var StreamableHttpTransport = class extends TransportEvents {
8119
8119
  }
8120
8120
  };
8121
8121
 
8122
+ // src/client/reap.ts
8123
+ var POLL_MS = 25;
8124
+ async function gone(proc, exited, ms) {
8125
+ const end = Date.now() + ms;
8126
+ for (; ; ) {
8127
+ if (exited() && !await proc.groupAlive?.()) return true;
8128
+ if (Date.now() >= end) return false;
8129
+ await new Promise((r) => setTimeout(r, POLL_MS));
8130
+ }
8131
+ }
8132
+ async function reap(proc, graceMs) {
8133
+ let exited = false;
8134
+ void proc.wait().then(
8135
+ () => {
8136
+ exited = true;
8137
+ },
8138
+ () => {
8139
+ exited = true;
8140
+ }
8141
+ );
8142
+ try {
8143
+ await proc.kill("SIGTERM");
8144
+ } catch {
8145
+ }
8146
+ if (await gone(proc, () => exited, graceMs)) return;
8147
+ try {
8148
+ await proc.kill("SIGKILL");
8149
+ } catch {
8150
+ }
8151
+ await gone(proc, () => exited, graceMs);
8152
+ }
8153
+
8122
8154
  // src/client/stdio-registry.ts
8123
8155
  var GRACE_MS = 2e3;
8124
8156
  var registry = /* @__PURE__ */ new Set();
8125
8157
  function trackStdio(proc) {
8126
8158
  registry.add(proc);
8127
- void proc.wait().then(
8128
- () => registry.delete(proc),
8129
- () => registry.delete(proc)
8130
- );
8159
+ }
8160
+ async function reapStdio(proc, graceMs = GRACE_MS) {
8161
+ try {
8162
+ await reap(proc, graceMs);
8163
+ } finally {
8164
+ registry.delete(proc);
8165
+ }
8131
8166
  }
8132
8167
  async function killAllStdio() {
8133
8168
  const procs = [...registry];
8134
8169
  if (procs.length === 0) return;
8135
- await Promise.all(
8136
- procs.map(async (proc) => {
8137
- try {
8138
- await proc.kill("SIGTERM");
8139
- } catch {
8140
- }
8141
- const exited = await Promise.race([
8142
- proc.wait().then(() => true),
8143
- new Promise((r) => setTimeout(() => r(false), GRACE_MS))
8144
- ]);
8145
- if (!exited) {
8146
- try {
8147
- await proc.kill("SIGKILL");
8148
- } catch {
8149
- }
8150
- }
8151
- })
8152
- );
8170
+ await Promise.all(procs.map((proc) => reapStdio(proc)));
8153
8171
  registry.clear();
8154
8172
  }
8155
8173
 
@@ -8255,16 +8273,8 @@ var PlatformStdioTransport = class {
8255
8273
  await proc.stdin.close();
8256
8274
  } catch {
8257
8275
  }
8258
- const exited = await Promise.race([done, delay(grace)]);
8259
- if (!exited) {
8260
- await proc.kill("SIGTERM");
8261
- const exitedAfterTerm = await Promise.race([done, delay(closeTimeoutMs)]);
8262
- if (!exitedAfterTerm) {
8263
- await proc.kill("SIGKILL");
8264
- await done;
8265
- }
8266
- }
8267
- await proc.kill("SIGTERM");
8276
+ await Promise.race([done, delay(grace)]);
8277
+ await reapStdio(proc, closeTimeoutMs);
8268
8278
  this.emitClose();
8269
8279
  }
8270
8280
  async readStdout(pending) {
@@ -8948,10 +8958,7 @@ function buildConnectionMethods(rpc, discoverResult2, proc) {
8948
8958
  },
8949
8959
  async close() {
8950
8960
  rpc.close();
8951
- try {
8952
- await proc.kill("SIGTERM");
8953
- } catch {
8954
- }
8961
+ await reapStdio(proc);
8955
8962
  }
8956
8963
  };
8957
8964
  }
@@ -12821,6 +12828,14 @@ function concat(chunks) {
12821
12828
  return out;
12822
12829
  }
12823
12830
  var KILL_GRACE_MS = 2e3;
12831
+ var SIGNAL_EXIT = { SIGINT: 130, SIGTERM: 143, SIGHUP: 129 };
12832
+ async function trapShutdown(platform2, handler) {
12833
+ await Promise.all(
12834
+ ["SIGINT", "SIGTERM", "SIGHUP"].map(
12835
+ (sig) => platform2.onSignal?.(sig, () => handler(sig))
12836
+ )
12837
+ );
12838
+ }
12824
12839
  async function killInflight() {
12825
12840
  const procs = [...inflightProcs];
12826
12841
  if (procs.length === 0) return;
@@ -13030,28 +13045,29 @@ function createToolExecutor(platform2, clis, allTools, childEnv, options, serveC
13030
13045
  async function discoverWithSignal(platform2, commands, childEnv, cwd) {
13031
13046
  const clis = [];
13032
13047
  let earlyShutdown = false;
13048
+ let shutdownExit = SIGNAL_EXIT.SIGTERM;
13033
13049
  let inflightDone;
13034
13050
  const earlyAbort = new AbortController();
13035
- const onShutdown = () => {
13051
+ const onShutdown = (sig) => {
13052
+ if (earlyShutdown) return;
13036
13053
  earlyShutdown = true;
13054
+ shutdownExit = SIGNAL_EXIT[sig];
13037
13055
  earlyAbort.abort();
13038
13056
  inflightDone = killInflight();
13039
13057
  };
13040
- platform2.onSignal?.("SIGTERM", onShutdown);
13041
- platform2.onSignal?.("SIGINT", onShutdown);
13042
- platform2.onSignal?.("SIGHUP", onShutdown);
13058
+ await trapShutdown(platform2, onShutdown);
13043
13059
  for (const cmd of commands) {
13044
13060
  try {
13045
13061
  const cli = await discoverCli(platform2, cmd.path, cmd.name, childEnv, cwd, earlyAbort.signal);
13046
13062
  clis.push(cli);
13047
13063
  } catch (err) {
13048
- if (earlyShutdown) return { exitCode: 143, inflightDone };
13064
+ if (earlyShutdown) return { exitCode: shutdownExit, inflightDone };
13049
13065
  await platform2.write(2, `mcpcat serve: ${err.message}
13050
13066
  `);
13051
13067
  return { exitCode: 2 };
13052
13068
  }
13053
13069
  }
13054
- if (earlyShutdown) return { exitCode: 143, inflightDone };
13070
+ if (earlyShutdown) return { exitCode: shutdownExit, inflightDone };
13055
13071
  return { clis };
13056
13072
  }
13057
13073
  async function resolveBearer(platform2, options) {
@@ -13380,11 +13396,7 @@ async function runWebMcpHttp(platform2, options, getTools, callTool, serverName,
13380
13396
  });
13381
13397
  }
13382
13398
  };
13383
- if (platform2.onSignal) {
13384
- platform2.onSignal("SIGINT", shutdown);
13385
- platform2.onSignal("SIGTERM", shutdown);
13386
- platform2.onSignal("SIGHUP", shutdown);
13387
- }
13399
+ await trapShutdown(platform2, shutdown);
13388
13400
  if (generatedBearer && resolvedBearer) {
13389
13401
  tokenFilePath = await publishBearer(
13390
13402
  platform2,
@@ -13584,11 +13596,7 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13584
13596
  });
13585
13597
  }
13586
13598
  };
13587
- if (platform2.onSignal) {
13588
- platform2.onSignal("SIGINT", shutdown);
13589
- platform2.onSignal("SIGTERM", shutdown);
13590
- platform2.onSignal("SIGHUP", shutdown);
13591
- }
13599
+ await trapShutdown(platform2, shutdown);
13592
13600
  if (generatedBearer && resolvedBearer) {
13593
13601
  tokenFilePath = await publishBearer(
13594
13602
  platform2,
@@ -13769,11 +13777,7 @@ async function runHttpServer(platform2, options, tools, call, serverName, versio
13769
13777
  });
13770
13778
  }
13771
13779
  };
13772
- if (platform2.onSignal) {
13773
- platform2.onSignal("SIGINT", shutdown);
13774
- platform2.onSignal("SIGTERM", shutdown);
13775
- platform2.onSignal("SIGHUP", shutdown);
13776
- }
13780
+ await trapShutdown(platform2, shutdown);
13777
13781
  if (generatedBearer && resolvedBearer) {
13778
13782
  tokenFilePath = await publishBearer(
13779
13783
  platform2,
@@ -16174,8 +16178,10 @@ async function dispatchMultiTarget(platform2, parsed, version) {
16174
16178
  });
16175
16179
  platform2.exit(exitCode);
16176
16180
  }
16177
- platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143));
16178
- platform2.onSignal?.("SIGHUP", () => void killTreeAndExit(129));
16181
+ await Promise.all([
16182
+ platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143)),
16183
+ platform2.onSignal?.("SIGHUP", () => void killTreeAndExit(129))
16184
+ ]);
16179
16185
  const config = await MergedConfigSource.load(platform2);
16180
16186
  if (parsed.verb === "code") {
16181
16187
  let source;
@@ -16536,12 +16542,14 @@ async function runClientVerb(platform2, version, parsed) {
16536
16542
  });
16537
16543
  platform2.exit(exitCode);
16538
16544
  }
16539
- platform2.onSignal?.("SIGINT", () => {
16540
- interrupted = true;
16541
- sigintController.abort();
16542
- });
16543
- platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143));
16544
- platform2.onSignal?.("SIGHUP", () => void killTreeAndExit(129));
16545
+ await Promise.all([
16546
+ platform2.onSignal?.("SIGINT", () => {
16547
+ interrupted = true;
16548
+ sigintController.abort();
16549
+ }),
16550
+ platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143)),
16551
+ platform2.onSignal?.("SIGHUP", () => void killTreeAndExit(129))
16552
+ ]);
16545
16553
  const showProgress = !parsed.silent && (parsed.verbose || platform2.isatty(2));
16546
16554
  const onProgress = (progress, total, message) => {
16547
16555
  if (!showProgress) return;
@@ -16768,6 +16776,15 @@ function nodeSpawn(options) {
16768
16776
  child.kill(sig);
16769
16777
  } catch {
16770
16778
  }
16779
+ },
16780
+ async groupAlive() {
16781
+ if (!USE_PROCESS_GROUPS2 || child.pid === void 0) return false;
16782
+ try {
16783
+ process.kill(-child.pid, 0);
16784
+ return true;
16785
+ } catch {
16786
+ return false;
16787
+ }
16771
16788
  }
16772
16789
  });
16773
16790
  }
@@ -16946,5 +16963,5 @@ try {
16946
16963
  });
16947
16964
  } catch {
16948
16965
  }
16949
- var code = await run(platform, "0.15.7", args);
16966
+ var code = await run(platform, "0.15.9", args);
16950
16967
  process.exit(code);
@@ -7740,37 +7740,55 @@ var StreamableHttpTransport = class extends TransportEvents {
7740
7740
  }
7741
7741
  };
7742
7742
 
7743
+ // src/client/reap.ts
7744
+ var POLL_MS = 25;
7745
+ async function gone(proc, exited, ms) {
7746
+ const end = Date.now() + ms;
7747
+ for (; ; ) {
7748
+ if (exited() && !await proc.groupAlive?.()) return true;
7749
+ if (Date.now() >= end) return false;
7750
+ await new Promise((r) => setTimeout(r, POLL_MS));
7751
+ }
7752
+ }
7753
+ async function reap(proc, graceMs) {
7754
+ let exited = false;
7755
+ void proc.wait().then(
7756
+ () => {
7757
+ exited = true;
7758
+ },
7759
+ () => {
7760
+ exited = true;
7761
+ }
7762
+ );
7763
+ try {
7764
+ await proc.kill("SIGTERM");
7765
+ } catch {
7766
+ }
7767
+ if (await gone(proc, () => exited, graceMs)) return;
7768
+ try {
7769
+ await proc.kill("SIGKILL");
7770
+ } catch {
7771
+ }
7772
+ await gone(proc, () => exited, graceMs);
7773
+ }
7774
+
7743
7775
  // src/client/stdio-registry.ts
7744
7776
  var GRACE_MS = 2e3;
7745
7777
  var registry = /* @__PURE__ */ new Set();
7746
7778
  function trackStdio(proc) {
7747
7779
  registry.add(proc);
7748
- void proc.wait().then(
7749
- () => registry.delete(proc),
7750
- () => registry.delete(proc)
7751
- );
7780
+ }
7781
+ async function reapStdio(proc, graceMs = GRACE_MS) {
7782
+ try {
7783
+ await reap(proc, graceMs);
7784
+ } finally {
7785
+ registry.delete(proc);
7786
+ }
7752
7787
  }
7753
7788
  async function killAllStdio() {
7754
7789
  const procs = [...registry];
7755
7790
  if (procs.length === 0) return;
7756
- await Promise.all(
7757
- procs.map(async (proc) => {
7758
- try {
7759
- await proc.kill("SIGTERM");
7760
- } catch {
7761
- }
7762
- const exited = await Promise.race([
7763
- proc.wait().then(() => true),
7764
- new Promise((r) => setTimeout(() => r(false), GRACE_MS))
7765
- ]);
7766
- if (!exited) {
7767
- try {
7768
- await proc.kill("SIGKILL");
7769
- } catch {
7770
- }
7771
- }
7772
- })
7773
- );
7791
+ await Promise.all(procs.map((proc) => reapStdio(proc)));
7774
7792
  registry.clear();
7775
7793
  }
7776
7794
 
@@ -7876,16 +7894,8 @@ var PlatformStdioTransport = class {
7876
7894
  await proc.stdin.close();
7877
7895
  } catch {
7878
7896
  }
7879
- const exited = await Promise.race([done, delay(grace)]);
7880
- if (!exited) {
7881
- await proc.kill("SIGTERM");
7882
- const exitedAfterTerm = await Promise.race([done, delay(closeTimeoutMs)]);
7883
- if (!exitedAfterTerm) {
7884
- await proc.kill("SIGKILL");
7885
- await done;
7886
- }
7887
- }
7888
- await proc.kill("SIGTERM");
7897
+ await Promise.race([done, delay(grace)]);
7898
+ await reapStdio(proc, closeTimeoutMs);
7889
7899
  this.emitClose();
7890
7900
  }
7891
7901
  async readStdout(pending) {
@@ -8569,10 +8579,7 @@ function buildConnectionMethods(rpc, discoverResult2, proc) {
8569
8579
  },
8570
8580
  async close() {
8571
8581
  rpc.close();
8572
- try {
8573
- await proc.kill("SIGTERM");
8574
- } catch {
8575
- }
8582
+ await reapStdio(proc);
8576
8583
  }
8577
8584
  };
8578
8585
  }
@@ -12442,6 +12449,14 @@ function concat(chunks) {
12442
12449
  return out;
12443
12450
  }
12444
12451
  var KILL_GRACE_MS = 2e3;
12452
+ var SIGNAL_EXIT = { SIGINT: 130, SIGTERM: 143, SIGHUP: 129 };
12453
+ async function trapShutdown(platform2, handler) {
12454
+ await Promise.all(
12455
+ ["SIGINT", "SIGTERM", "SIGHUP"].map(
12456
+ (sig) => platform2.onSignal?.(sig, () => handler(sig))
12457
+ )
12458
+ );
12459
+ }
12445
12460
  async function killInflight() {
12446
12461
  const procs = [...inflightProcs];
12447
12462
  if (procs.length === 0) return;
@@ -12651,28 +12666,29 @@ function createToolExecutor(platform2, clis, allTools, childEnv, options, serveC
12651
12666
  async function discoverWithSignal(platform2, commands, childEnv, cwd) {
12652
12667
  const clis = [];
12653
12668
  let earlyShutdown = false;
12669
+ let shutdownExit = SIGNAL_EXIT.SIGTERM;
12654
12670
  let inflightDone;
12655
12671
  const earlyAbort = new AbortController();
12656
- const onShutdown = () => {
12672
+ const onShutdown = (sig) => {
12673
+ if (earlyShutdown) return;
12657
12674
  earlyShutdown = true;
12675
+ shutdownExit = SIGNAL_EXIT[sig];
12658
12676
  earlyAbort.abort();
12659
12677
  inflightDone = killInflight();
12660
12678
  };
12661
- platform2.onSignal?.("SIGTERM", onShutdown);
12662
- platform2.onSignal?.("SIGINT", onShutdown);
12663
- platform2.onSignal?.("SIGHUP", onShutdown);
12679
+ await trapShutdown(platform2, onShutdown);
12664
12680
  for (const cmd of commands) {
12665
12681
  try {
12666
12682
  const cli = await discoverCli(platform2, cmd.path, cmd.name, childEnv, cwd, earlyAbort.signal);
12667
12683
  clis.push(cli);
12668
12684
  } catch (err) {
12669
- if (earlyShutdown) return { exitCode: 143, inflightDone };
12685
+ if (earlyShutdown) return { exitCode: shutdownExit, inflightDone };
12670
12686
  await platform2.write(2, `mcpcat serve: ${err.message}
12671
12687
  `);
12672
12688
  return { exitCode: 2 };
12673
12689
  }
12674
12690
  }
12675
- if (earlyShutdown) return { exitCode: 143, inflightDone };
12691
+ if (earlyShutdown) return { exitCode: shutdownExit, inflightDone };
12676
12692
  return { clis };
12677
12693
  }
12678
12694
  async function resolveBearer(platform2, options) {
@@ -13001,11 +13017,7 @@ async function runWebMcpHttp(platform2, options, getTools, callTool, serverName,
13001
13017
  });
13002
13018
  }
13003
13019
  };
13004
- if (platform2.onSignal) {
13005
- platform2.onSignal("SIGINT", shutdown);
13006
- platform2.onSignal("SIGTERM", shutdown);
13007
- platform2.onSignal("SIGHUP", shutdown);
13008
- }
13020
+ await trapShutdown(platform2, shutdown);
13009
13021
  if (generatedBearer && resolvedBearer) {
13010
13022
  tokenFilePath = await publishBearer(
13011
13023
  platform2,
@@ -13205,11 +13217,7 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13205
13217
  });
13206
13218
  }
13207
13219
  };
13208
- if (platform2.onSignal) {
13209
- platform2.onSignal("SIGINT", shutdown);
13210
- platform2.onSignal("SIGTERM", shutdown);
13211
- platform2.onSignal("SIGHUP", shutdown);
13212
- }
13220
+ await trapShutdown(platform2, shutdown);
13213
13221
  if (generatedBearer && resolvedBearer) {
13214
13222
  tokenFilePath = await publishBearer(
13215
13223
  platform2,
@@ -13390,11 +13398,7 @@ async function runHttpServer(platform2, options, tools, call, serverName, versio
13390
13398
  });
13391
13399
  }
13392
13400
  };
13393
- if (platform2.onSignal) {
13394
- platform2.onSignal("SIGINT", shutdown);
13395
- platform2.onSignal("SIGTERM", shutdown);
13396
- platform2.onSignal("SIGHUP", shutdown);
13397
- }
13401
+ await trapShutdown(platform2, shutdown);
13398
13402
  if (generatedBearer && resolvedBearer) {
13399
13403
  tokenFilePath = await publishBearer(
13400
13404
  platform2,
@@ -15795,8 +15799,10 @@ async function dispatchMultiTarget(platform2, parsed, version) {
15795
15799
  });
15796
15800
  platform2.exit(exitCode);
15797
15801
  }
15798
- platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143));
15799
- platform2.onSignal?.("SIGHUP", () => void killTreeAndExit(129));
15802
+ await Promise.all([
15803
+ platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143)),
15804
+ platform2.onSignal?.("SIGHUP", () => void killTreeAndExit(129))
15805
+ ]);
15800
15806
  const config = await MergedConfigSource.load(platform2);
15801
15807
  if (parsed.verb === "code") {
15802
15808
  let source;
@@ -16157,12 +16163,14 @@ async function runClientVerb(platform2, version, parsed) {
16157
16163
  });
16158
16164
  platform2.exit(exitCode);
16159
16165
  }
16160
- platform2.onSignal?.("SIGINT", () => {
16161
- interrupted = true;
16162
- sigintController.abort();
16163
- });
16164
- platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143));
16165
- platform2.onSignal?.("SIGHUP", () => void killTreeAndExit(129));
16166
+ await Promise.all([
16167
+ platform2.onSignal?.("SIGINT", () => {
16168
+ interrupted = true;
16169
+ sigintController.abort();
16170
+ }),
16171
+ platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143)),
16172
+ platform2.onSignal?.("SIGHUP", () => void killTreeAndExit(129))
16173
+ ]);
16166
16174
  const showProgress = !parsed.silent && (parsed.verbose || platform2.isatty(2));
16167
16175
  const onProgress = (progress, total, message) => {
16168
16176
  if (!showProgress) return;
@@ -16410,6 +16418,15 @@ async function kernelSpawn(ctx, options) {
16410
16418
  await ctx.kill(childPid, signal);
16411
16419
  } catch {
16412
16420
  }
16421
+ },
16422
+ async groupAlive() {
16423
+ if (!useGroupKill) return false;
16424
+ try {
16425
+ await ctx.kill(-childPid, "SIGCONT");
16426
+ return true;
16427
+ } catch {
16428
+ return false;
16429
+ }
16413
16430
  }
16414
16431
  };
16415
16432
  }
@@ -16645,8 +16662,8 @@ function createKernelPlatform(ctx, options) {
16645
16662
  exit(code) {
16646
16663
  ctx.exit(code);
16647
16664
  },
16648
- onSignal(signal, handler) {
16649
- ctx.signals.on(signal, handler);
16665
+ async onSignal(signal, handler) {
16666
+ await ctx.signals.on(signal, handler);
16650
16667
  },
16651
16668
  async seal(request) {
16652
16669
  return kernelSeal(ctx, request);
@@ -16667,7 +16684,7 @@ async function main(ctx) {
16667
16684
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
16668
16685
  });
16669
16686
  const args = ctx.argv.slice(1);
16670
- return run(platform2, "0.15.7", args);
16687
+ return run(platform2, "0.15.9", args);
16671
16688
  }
16672
16689
  export {
16673
16690
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.15.7",
3
+ "version": "0.15.9",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -56,14 +56,15 @@
56
56
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
57
57
  },
58
58
  "devDependencies": {
59
- "@ai-ecoverse/slicc-bios": "1.0.1",
60
- "@ai-ecoverse/slicc-kernel": "1.94.1",
61
- "@ai-ecoverse/slicc-shared-web": "1.19.0",
59
+ "@ai-ecoverse/slicc-bios": "1.2.0",
60
+ "@ai-ecoverse/slicc-kernel": "1.97.0",
61
+ "@ai-ecoverse/slicc-shared-web": "1.20.0",
62
62
  "@biomejs/biome": "2.5.15",
63
63
  "@earendil-works/pi-codemode": "1.2.0",
64
64
  "@earendil-works/pi-mcp": "1.2.0",
65
65
  "@types/node": "26.6.5",
66
66
  "esbuild": "0.28.2",
67
+ "kernel-cert-new": "npm:@ai-ecoverse/slicc-kernel@1.97.0",
67
68
  "monocart-coverage-reports": "2.13.2",
68
69
  "proper-lockfile": "4.1.2",
69
70
  "quickjs-wasi": "3.6.2",