@ai-ecoverse/mcpcat 0.29.0 → 0.29.1

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.
@@ -8560,6 +8560,17 @@ function within(promise, ms) {
8560
8560
  });
8561
8561
  return Promise.race([promise, stale]).finally(() => clearTimeout(timer));
8562
8562
  }
8563
+ function idleClock(onMessage, idleMs) {
8564
+ let deadline = Date.now() + idleMs;
8565
+ return {
8566
+ left: () => Math.max(0, deadline - Date.now()),
8567
+ onMessage: async (method, params) => {
8568
+ const out = await onMessage(method, params);
8569
+ deadline = Date.now() + idleMs;
8570
+ return out;
8571
+ }
8572
+ };
8573
+ }
8563
8574
  async function dispatchStreamData(data, id, onMessage, verbose, rpcError5) {
8564
8575
  let msg;
8565
8576
  try {
@@ -8852,18 +8863,19 @@ async function readEventStream(res, id, onMessage, idleMs, t) {
8852
8863
  const reader = res.body.getReader();
8853
8864
  const decoder3 = new TextDecoder();
8854
8865
  const parse = createSseParser();
8866
+ const clock = idleClock(onMessage, idleMs);
8855
8867
  try {
8856
8868
  for (; ; ) {
8857
8869
  let chunk;
8858
8870
  try {
8859
- chunk = await within(reader.read(), idleMs);
8871
+ chunk = await within(reader.read(), clock.left());
8860
8872
  } catch {
8861
8873
  return t.externalSignal?.aborted ? "aborted" : "dropped";
8862
8874
  }
8863
8875
  if (chunk === STALE) return "stale";
8864
8876
  if (chunk.done) return "dropped";
8865
8877
  for (const data of parse(decoder3.decode(chunk.value, { stream: true }))) {
8866
- const end = await dispatchStreamData(data, id, onMessage, t.verbose, rpcError);
8878
+ const end = await dispatchStreamData(data, id, clock.onMessage, t.verbose, rpcError);
8867
8879
  if (end) return end;
8868
8880
  }
8869
8881
  }
@@ -9344,8 +9356,9 @@ function createStdioJsonRpc(proc, platform2, options) {
9344
9356
  const body = wireBody(id, method, params);
9345
9357
  if (verbose?.enabled) verbose.request(method, body);
9346
9358
  await send(body);
9359
+ const clock = idleClock(onMessage, streamOptions.idleMs);
9347
9360
  for (; ; ) {
9348
- const line = await nextLine(streamOptions.idleMs, signals);
9361
+ const line = await nextLine(clock.left(), signals);
9349
9362
  if (line === ABORTED) {
9350
9363
  await cancel(id, "interrupted");
9351
9364
  return "aborted";
@@ -9354,7 +9367,7 @@ function createStdioJsonRpc(proc, platform2, options) {
9354
9367
  await cancel(id, "no heartbeat");
9355
9368
  return "stale";
9356
9369
  }
9357
- const end = await dispatchStreamData(line, id, onMessage, verbose, rpcError2);
9370
+ const end = await dispatchStreamData(line, id, clock.onMessage, verbose, rpcError2);
9358
9371
  if (end === "stopped") await cancel(id, "done");
9359
9372
  if (end) return end;
9360
9373
  }
@@ -17355,6 +17368,7 @@ var POLL_FLOOR_MS = 1e3;
17355
17368
  var BACKOFF_START_MS = 500;
17356
17369
  var BACKOFF_MAX_MS = 3e4;
17357
17370
  var SEEN_LIMIT = 256;
17371
+ var HANDLER_GRACE_MS = 2e3;
17358
17372
  var FORBIDDEN = -32024;
17359
17373
  var EVENTS_VALUE_FLAGS = /* @__PURE__ */ new Set([
17360
17374
  "-H",
@@ -17646,13 +17660,12 @@ var Subscriber = class {
17646
17660
  seen = [];
17647
17661
  seenSet = /* @__PURE__ */ new Set();
17648
17662
  delivered = 0;
17649
- handlerProc;
17650
17663
  o;
17651
17664
  constructor(options) {
17652
17665
  this.o = options;
17653
17666
  }
17654
17667
  async start() {
17655
- const { args: args2, platform: platform2, signal } = this.o;
17668
+ const { args: args2, platform: platform2 } = this.o;
17656
17669
  if (args2.cursorFile) {
17657
17670
  const state = await loadCursorFile(platform2, args2.cursorFile);
17658
17671
  this.cursor = state.cursor;
@@ -17661,18 +17674,8 @@ var Subscriber = class {
17661
17674
  }
17662
17675
  if (args2.sinceNow) this.cursor = null;
17663
17676
  if (args2.cursor !== void 0) this.cursor = args2.cursor;
17664
- const onAbort = () => {
17665
- const proc = this.handlerProc;
17666
- if (proc) void Promise.resolve(proc.kill("SIGTERM")).catch(() => {
17667
- });
17668
- };
17669
- signal.addEventListener("abort", onAbort, { once: true });
17670
- try {
17671
- const mode = pickDelivery(this.o.event, args2.delivery);
17672
- return mode === "push" ? await this.push() : await this.poll();
17673
- } finally {
17674
- signal.removeEventListener("abort", onAbort);
17675
- }
17677
+ const mode = pickDelivery(this.o.event, args2.delivery);
17678
+ return mode === "push" ? await this.push() : await this.poll();
17676
17679
  }
17677
17680
  notice(text) {
17678
17681
  if (this.o.args.silent) return Promise.resolve();
@@ -17690,7 +17693,7 @@ var Subscriber = class {
17690
17693
  }
17691
17694
  async persist(force = false) {
17692
17695
  const path = this.o.args.cursorFile;
17693
- if (!path || !force && this.persisted === this.cursor) return;
17696
+ if (!path || this.o.signal.aborted || !force && this.persisted === this.cursor) return;
17694
17697
  const body = JSON.stringify({
17695
17698
  event: this.o.event.name,
17696
17699
  cursor: this.cursor,
@@ -17711,6 +17714,7 @@ var Subscriber = class {
17711
17714
  await this.persist();
17712
17715
  }
17713
17716
  async deliver(occurrence, cursor) {
17717
+ if (this.o.signal.aborted) return;
17714
17718
  const id = typeof occurrence.eventId === "string" ? occurrence.eventId : void 0;
17715
17719
  if (id !== void 0 && this.seenSet.has(id)) {
17716
17720
  if (cursor !== void 0) await this.moveTo(cursor, false);
@@ -17723,7 +17727,7 @@ var Subscriber = class {
17723
17727
  await this.persist(true);
17724
17728
  }
17725
17729
  async handle(occurrence) {
17726
- const { platform: platform2, args: args2 } = this.o;
17730
+ const { platform: platform2, args: args2, signal } = this.o;
17727
17731
  const line = `${sanitizeJson(JSON.stringify(occurrence))}
17728
17732
  `;
17729
17733
  if (!args2.handler) {
@@ -17743,7 +17747,9 @@ var Subscriber = class {
17743
17747
  } catch (err) {
17744
17748
  throw new McpcatError(EXIT_USAGE, `cannot run ${args2.handler[0]}: ${err.message}`);
17745
17749
  }
17746
- this.handlerProc = proc;
17750
+ const stop = () => void reap(proc, HANDLER_GRACE_MS);
17751
+ if (signal.aborted) stop();
17752
+ else signal.addEventListener("abort", stop, { once: true });
17747
17753
  const feed = async () => {
17748
17754
  const writer = proc.stdin.getWriter();
17749
17755
  try {
@@ -17772,12 +17778,12 @@ var Subscriber = class {
17772
17778
  pipe(proc.stderr, 2),
17773
17779
  proc.wait()
17774
17780
  ]);
17775
- if (status.status !== 0 && !this.o.signal.aborted) {
17781
+ if (status.status !== 0 && !signal.aborted) {
17776
17782
  const how = status.signal ? `was killed by ${status.signal}` : `exited ${status.status}`;
17777
17783
  await this.notice(`${args2.handler[0]} ${how} for event ${String(occurrence.eventId)}`);
17778
17784
  }
17779
17785
  } finally {
17780
- this.handlerProc = void 0;
17786
+ signal.removeEventListener("abort", stop);
17781
17787
  }
17782
17788
  }
17783
17789
  async backoff(delay, reason, verb = "retrying") {
@@ -20578,5 +20584,5 @@ try {
20578
20584
  });
20579
20585
  } catch {
20580
20586
  }
20581
- var code = await run(platform, "0.29.0", args);
20587
+ var code = await run(platform, "0.29.1", args);
20582
20588
  process.exit(code);
@@ -8181,6 +8181,17 @@ function within(promise, ms) {
8181
8181
  });
8182
8182
  return Promise.race([promise, stale]).finally(() => clearTimeout(timer));
8183
8183
  }
8184
+ function idleClock(onMessage, idleMs) {
8185
+ let deadline = Date.now() + idleMs;
8186
+ return {
8187
+ left: () => Math.max(0, deadline - Date.now()),
8188
+ onMessage: async (method, params) => {
8189
+ const out = await onMessage(method, params);
8190
+ deadline = Date.now() + idleMs;
8191
+ return out;
8192
+ }
8193
+ };
8194
+ }
8184
8195
  async function dispatchStreamData(data, id, onMessage, verbose, rpcError5) {
8185
8196
  let msg;
8186
8197
  try {
@@ -8473,18 +8484,19 @@ async function readEventStream(res, id, onMessage, idleMs, t) {
8473
8484
  const reader = res.body.getReader();
8474
8485
  const decoder3 = new TextDecoder();
8475
8486
  const parse = createSseParser();
8487
+ const clock = idleClock(onMessage, idleMs);
8476
8488
  try {
8477
8489
  for (; ; ) {
8478
8490
  let chunk;
8479
8491
  try {
8480
- chunk = await within(reader.read(), idleMs);
8492
+ chunk = await within(reader.read(), clock.left());
8481
8493
  } catch {
8482
8494
  return t.externalSignal?.aborted ? "aborted" : "dropped";
8483
8495
  }
8484
8496
  if (chunk === STALE) return "stale";
8485
8497
  if (chunk.done) return "dropped";
8486
8498
  for (const data of parse(decoder3.decode(chunk.value, { stream: true }))) {
8487
- const end = await dispatchStreamData(data, id, onMessage, t.verbose, rpcError);
8499
+ const end = await dispatchStreamData(data, id, clock.onMessage, t.verbose, rpcError);
8488
8500
  if (end) return end;
8489
8501
  }
8490
8502
  }
@@ -8965,8 +8977,9 @@ function createStdioJsonRpc(proc, platform2, options) {
8965
8977
  const body = wireBody(id, method, params);
8966
8978
  if (verbose?.enabled) verbose.request(method, body);
8967
8979
  await send(body);
8980
+ const clock = idleClock(onMessage, streamOptions.idleMs);
8968
8981
  for (; ; ) {
8969
- const line = await nextLine(streamOptions.idleMs, signals);
8982
+ const line = await nextLine(clock.left(), signals);
8970
8983
  if (line === ABORTED) {
8971
8984
  await cancel(id, "interrupted");
8972
8985
  return "aborted";
@@ -8975,7 +8988,7 @@ function createStdioJsonRpc(proc, platform2, options) {
8975
8988
  await cancel(id, "no heartbeat");
8976
8989
  return "stale";
8977
8990
  }
8978
- const end = await dispatchStreamData(line, id, onMessage, verbose, rpcError2);
8991
+ const end = await dispatchStreamData(line, id, clock.onMessage, verbose, rpcError2);
8979
8992
  if (end === "stopped") await cancel(id, "done");
8980
8993
  if (end) return end;
8981
8994
  }
@@ -16872,6 +16885,7 @@ var POLL_FLOOR_MS = 1e3;
16872
16885
  var BACKOFF_START_MS = 500;
16873
16886
  var BACKOFF_MAX_MS = 3e4;
16874
16887
  var SEEN_LIMIT = 256;
16888
+ var HANDLER_GRACE_MS = 2e3;
16875
16889
  var FORBIDDEN = -32024;
16876
16890
  var EVENTS_VALUE_FLAGS = /* @__PURE__ */ new Set([
16877
16891
  "-H",
@@ -17163,13 +17177,12 @@ var Subscriber = class {
17163
17177
  seen = [];
17164
17178
  seenSet = /* @__PURE__ */ new Set();
17165
17179
  delivered = 0;
17166
- handlerProc;
17167
17180
  o;
17168
17181
  constructor(options) {
17169
17182
  this.o = options;
17170
17183
  }
17171
17184
  async start() {
17172
- const { args, platform: platform2, signal } = this.o;
17185
+ const { args, platform: platform2 } = this.o;
17173
17186
  if (args.cursorFile) {
17174
17187
  const state = await loadCursorFile(platform2, args.cursorFile);
17175
17188
  this.cursor = state.cursor;
@@ -17178,18 +17191,8 @@ var Subscriber = class {
17178
17191
  }
17179
17192
  if (args.sinceNow) this.cursor = null;
17180
17193
  if (args.cursor !== void 0) this.cursor = args.cursor;
17181
- const onAbort = () => {
17182
- const proc = this.handlerProc;
17183
- if (proc) void Promise.resolve(proc.kill("SIGTERM")).catch(() => {
17184
- });
17185
- };
17186
- signal.addEventListener("abort", onAbort, { once: true });
17187
- try {
17188
- const mode = pickDelivery(this.o.event, args.delivery);
17189
- return mode === "push" ? await this.push() : await this.poll();
17190
- } finally {
17191
- signal.removeEventListener("abort", onAbort);
17192
- }
17194
+ const mode = pickDelivery(this.o.event, args.delivery);
17195
+ return mode === "push" ? await this.push() : await this.poll();
17193
17196
  }
17194
17197
  notice(text) {
17195
17198
  if (this.o.args.silent) return Promise.resolve();
@@ -17207,7 +17210,7 @@ var Subscriber = class {
17207
17210
  }
17208
17211
  async persist(force = false) {
17209
17212
  const path = this.o.args.cursorFile;
17210
- if (!path || !force && this.persisted === this.cursor) return;
17213
+ if (!path || this.o.signal.aborted || !force && this.persisted === this.cursor) return;
17211
17214
  const body = JSON.stringify({
17212
17215
  event: this.o.event.name,
17213
17216
  cursor: this.cursor,
@@ -17228,6 +17231,7 @@ var Subscriber = class {
17228
17231
  await this.persist();
17229
17232
  }
17230
17233
  async deliver(occurrence, cursor) {
17234
+ if (this.o.signal.aborted) return;
17231
17235
  const id = typeof occurrence.eventId === "string" ? occurrence.eventId : void 0;
17232
17236
  if (id !== void 0 && this.seenSet.has(id)) {
17233
17237
  if (cursor !== void 0) await this.moveTo(cursor, false);
@@ -17240,7 +17244,7 @@ var Subscriber = class {
17240
17244
  await this.persist(true);
17241
17245
  }
17242
17246
  async handle(occurrence) {
17243
- const { platform: platform2, args } = this.o;
17247
+ const { platform: platform2, args, signal } = this.o;
17244
17248
  const line = `${sanitizeJson(JSON.stringify(occurrence))}
17245
17249
  `;
17246
17250
  if (!args.handler) {
@@ -17260,7 +17264,9 @@ var Subscriber = class {
17260
17264
  } catch (err) {
17261
17265
  throw new McpcatError(EXIT_USAGE, `cannot run ${args.handler[0]}: ${err.message}`);
17262
17266
  }
17263
- this.handlerProc = proc;
17267
+ const stop = () => void reap(proc, HANDLER_GRACE_MS);
17268
+ if (signal.aborted) stop();
17269
+ else signal.addEventListener("abort", stop, { once: true });
17264
17270
  const feed = async () => {
17265
17271
  const writer = proc.stdin.getWriter();
17266
17272
  try {
@@ -17289,12 +17295,12 @@ var Subscriber = class {
17289
17295
  pipe(proc.stderr, 2),
17290
17296
  proc.wait()
17291
17297
  ]);
17292
- if (status.status !== 0 && !this.o.signal.aborted) {
17298
+ if (status.status !== 0 && !signal.aborted) {
17293
17299
  const how = status.signal ? `was killed by ${status.signal}` : `exited ${status.status}`;
17294
17300
  await this.notice(`${args.handler[0]} ${how} for event ${String(occurrence.eventId)}`);
17295
17301
  }
17296
17302
  } finally {
17297
- this.handlerProc = void 0;
17303
+ signal.removeEventListener("abort", stop);
17298
17304
  }
17299
17305
  }
17300
17306
  async backoff(delay, reason, verb = "retrying") {
@@ -19805,7 +19811,7 @@ async function main(ctx) {
19805
19811
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
19806
19812
  });
19807
19813
  const args = ctx.argv.slice(1);
19808
- return run(platform2, "0.29.0", args);
19814
+ return run(platform2, "0.29.1", args);
19809
19815
  }
19810
19816
  export {
19811
19817
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.29.0",
3
+ "version": "0.29.1",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",