@ai-ecoverse/mcpcat 0.17.4 → 0.17.5

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.
@@ -8453,22 +8453,20 @@ function mcpNameForMethod(method, params) {
8453
8453
  function makeAbort(timeoutMs, externalSignal) {
8454
8454
  const controller = new AbortController();
8455
8455
  const timer = setTimeout(() => controller.abort(), timeoutMs);
8456
- if (externalSignal) {
8457
- if (externalSignal.aborted) {
8456
+ const onAbort = () => {
8457
+ clearTimeout(timer);
8458
+ controller.abort();
8459
+ };
8460
+ if (externalSignal?.aborted) onAbort();
8461
+ else externalSignal?.addEventListener("abort", onAbort, { once: true });
8462
+ return {
8463
+ controller,
8464
+ stopTimer: () => clearTimeout(timer),
8465
+ detach: () => {
8458
8466
  clearTimeout(timer);
8459
- controller.abort();
8460
- } else {
8461
- externalSignal.addEventListener(
8462
- "abort",
8463
- () => {
8464
- clearTimeout(timer);
8465
- controller.abort();
8466
- },
8467
- { once: true }
8468
- );
8467
+ externalSignal?.removeEventListener("abort", onAbort);
8469
8468
  }
8470
- }
8471
- return { controller, timer };
8469
+ };
8472
8470
  }
8473
8471
  function logHeaders(verbose, dir, entries) {
8474
8472
  for (const [k, v] of entries) {
@@ -8586,7 +8584,7 @@ async function createStatelessConnection(options) {
8586
8584
  verbose.request(method, body);
8587
8585
  logHeaders(verbose, ">", Object.entries(headers));
8588
8586
  }
8589
- const { controller, timer } = makeAbort(timeoutMs, externalSignal);
8587
+ const { controller, stopTimer, detach } = makeAbort(timeoutMs, externalSignal);
8590
8588
  try {
8591
8589
  const res = await fetchImpl(url, {
8592
8590
  method: "POST",
@@ -8598,14 +8596,15 @@ async function createStatelessConnection(options) {
8598
8596
  verbose.http("<", `HTTP/1.1 ${res.status} ${res.statusText}`);
8599
8597
  logHeaders(verbose, "<", res.headers.entries());
8600
8598
  }
8601
- return { res, token };
8599
+ return { res, token, detach };
8602
8600
  } catch (err) {
8601
+ detach();
8603
8602
  if (controller.signal.aborted && !externalSignal?.aborted) {
8604
8603
  throw new McpTimeoutError2(method, timeoutMs);
8605
8604
  }
8606
8605
  throw err;
8607
8606
  } finally {
8608
- clearTimeout(timer);
8607
+ stopTimer();
8609
8608
  }
8610
8609
  }
8611
8610
  async function parseResponse(res, id) {
@@ -8654,19 +8653,22 @@ async function createStatelessConnection(options) {
8654
8653
  params: { ...cleanParams, _meta: meta }
8655
8654
  });
8656
8655
  for (let attempt = 0; attempt < 2; attempt++) {
8657
- const { res, token } = await doFetch(method, params, body);
8658
- if (res.status >= 400) {
8659
- try {
8660
- await handleErrorStatus(res, method);
8661
- } catch (err) {
8662
- if (err instanceof AuthRetryableError && attempt === 0) {
8663
- await handleAuthError(err, token);
8664
- continue;
8656
+ const { res, token, detach } = await doFetch(method, params, body);
8657
+ let retry;
8658
+ try {
8659
+ if (res.status >= 400) {
8660
+ try {
8661
+ await handleErrorStatus(res, method);
8662
+ } catch (err) {
8663
+ if (!(err instanceof AuthRetryableError && attempt === 0)) throw err;
8664
+ retry = err;
8665
8665
  }
8666
- throw err;
8667
8666
  }
8667
+ if (!retry) return await parseResponse(res, id);
8668
+ } finally {
8669
+ detach();
8668
8670
  }
8669
- return parseResponse(res, id);
8671
+ await handleAuthError(retry, token);
8670
8672
  }
8671
8673
  throw new McpAuthError(401, url);
8672
8674
  }
@@ -8858,6 +8860,19 @@ function createStdioJsonRpc(proc, platform2, options) {
8858
8860
  writer.releaseLock();
8859
8861
  }
8860
8862
  }
8863
+ function raceDeadline(linePromise, method, remaining) {
8864
+ let timer;
8865
+ let onAbort;
8866
+ const stop = new Promise((_, reject) => {
8867
+ timer = setTimeout(() => reject(new McpTimeoutError2(method, timeoutMs)), remaining);
8868
+ onAbort = () => reject(new McpTimeoutError2(method, timeoutMs));
8869
+ externalSignal?.addEventListener("abort", onAbort, { once: true });
8870
+ });
8871
+ return Promise.race([linePromise, stop]).finally(() => {
8872
+ clearTimeout(timer);
8873
+ if (onAbort) externalSignal?.removeEventListener("abort", onAbort);
8874
+ });
8875
+ }
8861
8876
  async function request(method, params) {
8862
8877
  const id = nextId2++;
8863
8878
  const meta = {
@@ -8881,11 +8896,7 @@ function createStdioJsonRpc(proc, platform2, options) {
8881
8896
  while (Date.now() < deadline) {
8882
8897
  const remaining = deadline - Date.now();
8883
8898
  if (externalSignal?.aborted) throw new McpTimeoutError2(method, timeoutMs);
8884
- const linePromise = readLine2();
8885
- const timeoutPromise = new Promise(
8886
- (_, reject) => setTimeout(() => reject(new McpTimeoutError2(method, timeoutMs)), remaining)
8887
- );
8888
- const line = await Promise.race([linePromise, timeoutPromise]);
8899
+ const line = await raceDeadline(readLine2(), method, remaining);
8889
8900
  const parsed = JSON.parse(line);
8890
8901
  if (verbose?.enabled) verbose.response(line);
8891
8902
  if (parsed.id === id) {
@@ -17014,5 +17025,5 @@ try {
17014
17025
  });
17015
17026
  } catch {
17016
17027
  }
17017
- var code = await run(platform, "0.17.4", args);
17028
+ var code = await run(platform, "0.17.5", args);
17018
17029
  process.exit(code);
@@ -8074,22 +8074,20 @@ function mcpNameForMethod(method, params) {
8074
8074
  function makeAbort(timeoutMs, externalSignal) {
8075
8075
  const controller = new AbortController();
8076
8076
  const timer = setTimeout(() => controller.abort(), timeoutMs);
8077
- if (externalSignal) {
8078
- if (externalSignal.aborted) {
8077
+ const onAbort = () => {
8078
+ clearTimeout(timer);
8079
+ controller.abort();
8080
+ };
8081
+ if (externalSignal?.aborted) onAbort();
8082
+ else externalSignal?.addEventListener("abort", onAbort, { once: true });
8083
+ return {
8084
+ controller,
8085
+ stopTimer: () => clearTimeout(timer),
8086
+ detach: () => {
8079
8087
  clearTimeout(timer);
8080
- controller.abort();
8081
- } else {
8082
- externalSignal.addEventListener(
8083
- "abort",
8084
- () => {
8085
- clearTimeout(timer);
8086
- controller.abort();
8087
- },
8088
- { once: true }
8089
- );
8088
+ externalSignal?.removeEventListener("abort", onAbort);
8090
8089
  }
8091
- }
8092
- return { controller, timer };
8090
+ };
8093
8091
  }
8094
8092
  function logHeaders(verbose, dir, entries) {
8095
8093
  for (const [k, v] of entries) {
@@ -8207,7 +8205,7 @@ async function createStatelessConnection(options) {
8207
8205
  verbose.request(method, body);
8208
8206
  logHeaders(verbose, ">", Object.entries(headers));
8209
8207
  }
8210
- const { controller, timer } = makeAbort(timeoutMs, externalSignal);
8208
+ const { controller, stopTimer, detach } = makeAbort(timeoutMs, externalSignal);
8211
8209
  try {
8212
8210
  const res = await fetchImpl(url, {
8213
8211
  method: "POST",
@@ -8219,14 +8217,15 @@ async function createStatelessConnection(options) {
8219
8217
  verbose.http("<", `HTTP/1.1 ${res.status} ${res.statusText}`);
8220
8218
  logHeaders(verbose, "<", res.headers.entries());
8221
8219
  }
8222
- return { res, token };
8220
+ return { res, token, detach };
8223
8221
  } catch (err) {
8222
+ detach();
8224
8223
  if (controller.signal.aborted && !externalSignal?.aborted) {
8225
8224
  throw new McpTimeoutError2(method, timeoutMs);
8226
8225
  }
8227
8226
  throw err;
8228
8227
  } finally {
8229
- clearTimeout(timer);
8228
+ stopTimer();
8230
8229
  }
8231
8230
  }
8232
8231
  async function parseResponse(res, id) {
@@ -8275,19 +8274,22 @@ async function createStatelessConnection(options) {
8275
8274
  params: { ...cleanParams, _meta: meta }
8276
8275
  });
8277
8276
  for (let attempt = 0; attempt < 2; attempt++) {
8278
- const { res, token } = await doFetch(method, params, body);
8279
- if (res.status >= 400) {
8280
- try {
8281
- await handleErrorStatus(res, method);
8282
- } catch (err) {
8283
- if (err instanceof AuthRetryableError && attempt === 0) {
8284
- await handleAuthError(err, token);
8285
- continue;
8277
+ const { res, token, detach } = await doFetch(method, params, body);
8278
+ let retry;
8279
+ try {
8280
+ if (res.status >= 400) {
8281
+ try {
8282
+ await handleErrorStatus(res, method);
8283
+ } catch (err) {
8284
+ if (!(err instanceof AuthRetryableError && attempt === 0)) throw err;
8285
+ retry = err;
8286
8286
  }
8287
- throw err;
8288
8287
  }
8288
+ if (!retry) return await parseResponse(res, id);
8289
+ } finally {
8290
+ detach();
8289
8291
  }
8290
- return parseResponse(res, id);
8292
+ await handleAuthError(retry, token);
8291
8293
  }
8292
8294
  throw new McpAuthError(401, url);
8293
8295
  }
@@ -8479,6 +8481,19 @@ function createStdioJsonRpc(proc, platform2, options) {
8479
8481
  writer.releaseLock();
8480
8482
  }
8481
8483
  }
8484
+ function raceDeadline(linePromise, method, remaining) {
8485
+ let timer;
8486
+ let onAbort;
8487
+ const stop = new Promise((_, reject) => {
8488
+ timer = setTimeout(() => reject(new McpTimeoutError2(method, timeoutMs)), remaining);
8489
+ onAbort = () => reject(new McpTimeoutError2(method, timeoutMs));
8490
+ externalSignal?.addEventListener("abort", onAbort, { once: true });
8491
+ });
8492
+ return Promise.race([linePromise, stop]).finally(() => {
8493
+ clearTimeout(timer);
8494
+ if (onAbort) externalSignal?.removeEventListener("abort", onAbort);
8495
+ });
8496
+ }
8482
8497
  async function request(method, params) {
8483
8498
  const id = nextId2++;
8484
8499
  const meta = {
@@ -8502,11 +8517,7 @@ function createStdioJsonRpc(proc, platform2, options) {
8502
8517
  while (Date.now() < deadline) {
8503
8518
  const remaining = deadline - Date.now();
8504
8519
  if (externalSignal?.aborted) throw new McpTimeoutError2(method, timeoutMs);
8505
- const linePromise = readLine2();
8506
- const timeoutPromise = new Promise(
8507
- (_, reject) => setTimeout(() => reject(new McpTimeoutError2(method, timeoutMs)), remaining)
8508
- );
8509
- const line = await Promise.race([linePromise, timeoutPromise]);
8520
+ const line = await raceDeadline(readLine2(), method, remaining);
8510
8521
  const parsed = JSON.parse(line);
8511
8522
  if (verbose?.enabled) verbose.response(line);
8512
8523
  if (parsed.id === id) {
@@ -16736,7 +16747,7 @@ async function main(ctx) {
16736
16747
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
16737
16748
  });
16738
16749
  const args = ctx.argv.slice(1);
16739
- return run(platform2, "0.17.4", args);
16750
+ return run(platform2, "0.17.5", args);
16740
16751
  }
16741
16752
  export {
16742
16753
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.17.4",
3
+ "version": "0.17.5",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -61,15 +61,15 @@
61
61
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
62
62
  },
63
63
  "devDependencies": {
64
- "@ai-ecoverse/slicc-bios": "1.33.1",
65
- "@ai-ecoverse/slicc-kernel": "1.140.0",
64
+ "@ai-ecoverse/slicc-bios": "1.35.0",
65
+ "@ai-ecoverse/slicc-kernel": "1.141.2",
66
66
  "@ai-ecoverse/slicc-shared-web": "1.29.2",
67
67
  "@biomejs/biome": "2.5.15",
68
68
  "@earendil-works/pi-codemode": "1.2.0",
69
69
  "@earendil-works/pi-mcp": "1.2.0",
70
70
  "@types/node": "26.6.5",
71
71
  "esbuild": "0.28.2",
72
- "kernel-cert-new": "npm:@ai-ecoverse/slicc-kernel@1.140.0",
72
+ "kernel-cert-new": "npm:@ai-ecoverse/slicc-kernel@1.141.2",
73
73
  "lefthook": "2.2.2",
74
74
  "monocart-coverage-reports": "2.13.2",
75
75
  "proper-lockfile": "4.1.2",