@ai-ecoverse/mcpcat 0.29.0 → 0.29.2

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,22 @@ function within(promise, ms) {
8560
8560
  });
8561
8561
  return Promise.race([promise, stale]).finally(() => clearTimeout(timer));
8562
8562
  }
8563
+ var LIVENESS = /* @__PURE__ */ new Set([
8564
+ "notifications/events/active",
8565
+ "notifications/events/event",
8566
+ "notifications/events/heartbeat"
8567
+ ]);
8568
+ function idleClock(onMessage, idleMs) {
8569
+ let deadline = Date.now() + idleMs;
8570
+ return {
8571
+ left: () => Math.max(0, deadline - Date.now()),
8572
+ onMessage: async (method, params) => {
8573
+ const out = await onMessage(method, params);
8574
+ if (LIVENESS.has(method)) deadline = Date.now() + idleMs;
8575
+ return out;
8576
+ }
8577
+ };
8578
+ }
8563
8579
  async function dispatchStreamData(data, id, onMessage, verbose, rpcError5) {
8564
8580
  let msg;
8565
8581
  try {
@@ -8852,18 +8868,19 @@ async function readEventStream(res, id, onMessage, idleMs, t) {
8852
8868
  const reader = res.body.getReader();
8853
8869
  const decoder3 = new TextDecoder();
8854
8870
  const parse = createSseParser();
8871
+ const clock = idleClock(onMessage, idleMs);
8855
8872
  try {
8856
8873
  for (; ; ) {
8857
8874
  let chunk;
8858
8875
  try {
8859
- chunk = await within(reader.read(), idleMs);
8876
+ chunk = await within(reader.read(), clock.left());
8860
8877
  } catch {
8861
8878
  return t.externalSignal?.aborted ? "aborted" : "dropped";
8862
8879
  }
8863
8880
  if (chunk === STALE) return "stale";
8864
8881
  if (chunk.done) return "dropped";
8865
8882
  for (const data of parse(decoder3.decode(chunk.value, { stream: true }))) {
8866
- const end = await dispatchStreamData(data, id, onMessage, t.verbose, rpcError);
8883
+ const end = await dispatchStreamData(data, id, clock.onMessage, t.verbose, rpcError);
8867
8884
  if (end) return end;
8868
8885
  }
8869
8886
  }
@@ -9344,8 +9361,9 @@ function createStdioJsonRpc(proc, platform2, options) {
9344
9361
  const body = wireBody(id, method, params);
9345
9362
  if (verbose?.enabled) verbose.request(method, body);
9346
9363
  await send(body);
9364
+ const clock = idleClock(onMessage, streamOptions.idleMs);
9347
9365
  for (; ; ) {
9348
- const line = await nextLine(streamOptions.idleMs, signals);
9366
+ const line = await nextLine(clock.left(), signals);
9349
9367
  if (line === ABORTED) {
9350
9368
  await cancel(id, "interrupted");
9351
9369
  return "aborted";
@@ -9354,7 +9372,7 @@ function createStdioJsonRpc(proc, platform2, options) {
9354
9372
  await cancel(id, "no heartbeat");
9355
9373
  return "stale";
9356
9374
  }
9357
- const end = await dispatchStreamData(line, id, onMessage, verbose, rpcError2);
9375
+ const end = await dispatchStreamData(line, id, clock.onMessage, verbose, rpcError2);
9358
9376
  if (end === "stopped") await cancel(id, "done");
9359
9377
  if (end) return end;
9360
9378
  }
@@ -17355,6 +17373,7 @@ var POLL_FLOOR_MS = 1e3;
17355
17373
  var BACKOFF_START_MS = 500;
17356
17374
  var BACKOFF_MAX_MS = 3e4;
17357
17375
  var SEEN_LIMIT = 256;
17376
+ var HANDLER_GRACE_MS = 2e3;
17358
17377
  var FORBIDDEN = -32024;
17359
17378
  var EVENTS_VALUE_FLAGS = /* @__PURE__ */ new Set([
17360
17379
  "-H",
@@ -17646,13 +17665,12 @@ var Subscriber = class {
17646
17665
  seen = [];
17647
17666
  seenSet = /* @__PURE__ */ new Set();
17648
17667
  delivered = 0;
17649
- handlerProc;
17650
17668
  o;
17651
17669
  constructor(options) {
17652
17670
  this.o = options;
17653
17671
  }
17654
17672
  async start() {
17655
- const { args: args2, platform: platform2, signal } = this.o;
17673
+ const { args: args2, platform: platform2 } = this.o;
17656
17674
  if (args2.cursorFile) {
17657
17675
  const state = await loadCursorFile(platform2, args2.cursorFile);
17658
17676
  this.cursor = state.cursor;
@@ -17661,18 +17679,8 @@ var Subscriber = class {
17661
17679
  }
17662
17680
  if (args2.sinceNow) this.cursor = null;
17663
17681
  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
- }
17682
+ const mode = pickDelivery(this.o.event, args2.delivery);
17683
+ return mode === "push" ? await this.push() : await this.poll();
17676
17684
  }
17677
17685
  notice(text) {
17678
17686
  if (this.o.args.silent) return Promise.resolve();
@@ -17690,7 +17698,7 @@ var Subscriber = class {
17690
17698
  }
17691
17699
  async persist(force = false) {
17692
17700
  const path = this.o.args.cursorFile;
17693
- if (!path || !force && this.persisted === this.cursor) return;
17701
+ if (!path || this.o.signal.aborted || !force && this.persisted === this.cursor) return;
17694
17702
  const body = JSON.stringify({
17695
17703
  event: this.o.event.name,
17696
17704
  cursor: this.cursor,
@@ -17711,6 +17719,7 @@ var Subscriber = class {
17711
17719
  await this.persist();
17712
17720
  }
17713
17721
  async deliver(occurrence, cursor) {
17722
+ if (this.o.signal.aborted) return;
17714
17723
  const id = typeof occurrence.eventId === "string" ? occurrence.eventId : void 0;
17715
17724
  if (id !== void 0 && this.seenSet.has(id)) {
17716
17725
  if (cursor !== void 0) await this.moveTo(cursor, false);
@@ -17723,7 +17732,7 @@ var Subscriber = class {
17723
17732
  await this.persist(true);
17724
17733
  }
17725
17734
  async handle(occurrence) {
17726
- const { platform: platform2, args: args2 } = this.o;
17735
+ const { platform: platform2, args: args2, signal } = this.o;
17727
17736
  const line = `${sanitizeJson(JSON.stringify(occurrence))}
17728
17737
  `;
17729
17738
  if (!args2.handler) {
@@ -17743,7 +17752,9 @@ var Subscriber = class {
17743
17752
  } catch (err) {
17744
17753
  throw new McpcatError(EXIT_USAGE, `cannot run ${args2.handler[0]}: ${err.message}`);
17745
17754
  }
17746
- this.handlerProc = proc;
17755
+ const stop = () => void reap(proc, HANDLER_GRACE_MS);
17756
+ if (signal.aborted) stop();
17757
+ else signal.addEventListener("abort", stop, { once: true });
17747
17758
  const feed = async () => {
17748
17759
  const writer = proc.stdin.getWriter();
17749
17760
  try {
@@ -17772,12 +17783,12 @@ var Subscriber = class {
17772
17783
  pipe(proc.stderr, 2),
17773
17784
  proc.wait()
17774
17785
  ]);
17775
- if (status.status !== 0 && !this.o.signal.aborted) {
17786
+ if (status.status !== 0 && !signal.aborted) {
17776
17787
  const how = status.signal ? `was killed by ${status.signal}` : `exited ${status.status}`;
17777
17788
  await this.notice(`${args2.handler[0]} ${how} for event ${String(occurrence.eventId)}`);
17778
17789
  }
17779
17790
  } finally {
17780
- this.handlerProc = void 0;
17791
+ signal.removeEventListener("abort", stop);
17781
17792
  }
17782
17793
  }
17783
17794
  async backoff(delay, reason, verb = "retrying") {
@@ -20578,5 +20589,5 @@ try {
20578
20589
  });
20579
20590
  } catch {
20580
20591
  }
20581
- var code = await run(platform, "0.29.0", args);
20592
+ var code = await run(platform, "0.29.2", args);
20582
20593
  process.exit(code);
@@ -8181,6 +8181,22 @@ function within(promise, ms) {
8181
8181
  });
8182
8182
  return Promise.race([promise, stale]).finally(() => clearTimeout(timer));
8183
8183
  }
8184
+ var LIVENESS = /* @__PURE__ */ new Set([
8185
+ "notifications/events/active",
8186
+ "notifications/events/event",
8187
+ "notifications/events/heartbeat"
8188
+ ]);
8189
+ function idleClock(onMessage, idleMs) {
8190
+ let deadline = Date.now() + idleMs;
8191
+ return {
8192
+ left: () => Math.max(0, deadline - Date.now()),
8193
+ onMessage: async (method, params) => {
8194
+ const out = await onMessage(method, params);
8195
+ if (LIVENESS.has(method)) deadline = Date.now() + idleMs;
8196
+ return out;
8197
+ }
8198
+ };
8199
+ }
8184
8200
  async function dispatchStreamData(data, id, onMessage, verbose, rpcError5) {
8185
8201
  let msg;
8186
8202
  try {
@@ -8473,18 +8489,19 @@ async function readEventStream(res, id, onMessage, idleMs, t) {
8473
8489
  const reader = res.body.getReader();
8474
8490
  const decoder3 = new TextDecoder();
8475
8491
  const parse = createSseParser();
8492
+ const clock = idleClock(onMessage, idleMs);
8476
8493
  try {
8477
8494
  for (; ; ) {
8478
8495
  let chunk;
8479
8496
  try {
8480
- chunk = await within(reader.read(), idleMs);
8497
+ chunk = await within(reader.read(), clock.left());
8481
8498
  } catch {
8482
8499
  return t.externalSignal?.aborted ? "aborted" : "dropped";
8483
8500
  }
8484
8501
  if (chunk === STALE) return "stale";
8485
8502
  if (chunk.done) return "dropped";
8486
8503
  for (const data of parse(decoder3.decode(chunk.value, { stream: true }))) {
8487
- const end = await dispatchStreamData(data, id, onMessage, t.verbose, rpcError);
8504
+ const end = await dispatchStreamData(data, id, clock.onMessage, t.verbose, rpcError);
8488
8505
  if (end) return end;
8489
8506
  }
8490
8507
  }
@@ -8965,8 +8982,9 @@ function createStdioJsonRpc(proc, platform2, options) {
8965
8982
  const body = wireBody(id, method, params);
8966
8983
  if (verbose?.enabled) verbose.request(method, body);
8967
8984
  await send(body);
8985
+ const clock = idleClock(onMessage, streamOptions.idleMs);
8968
8986
  for (; ; ) {
8969
- const line = await nextLine(streamOptions.idleMs, signals);
8987
+ const line = await nextLine(clock.left(), signals);
8970
8988
  if (line === ABORTED) {
8971
8989
  await cancel(id, "interrupted");
8972
8990
  return "aborted";
@@ -8975,7 +8993,7 @@ function createStdioJsonRpc(proc, platform2, options) {
8975
8993
  await cancel(id, "no heartbeat");
8976
8994
  return "stale";
8977
8995
  }
8978
- const end = await dispatchStreamData(line, id, onMessage, verbose, rpcError2);
8996
+ const end = await dispatchStreamData(line, id, clock.onMessage, verbose, rpcError2);
8979
8997
  if (end === "stopped") await cancel(id, "done");
8980
8998
  if (end) return end;
8981
8999
  }
@@ -16872,6 +16890,7 @@ var POLL_FLOOR_MS = 1e3;
16872
16890
  var BACKOFF_START_MS = 500;
16873
16891
  var BACKOFF_MAX_MS = 3e4;
16874
16892
  var SEEN_LIMIT = 256;
16893
+ var HANDLER_GRACE_MS = 2e3;
16875
16894
  var FORBIDDEN = -32024;
16876
16895
  var EVENTS_VALUE_FLAGS = /* @__PURE__ */ new Set([
16877
16896
  "-H",
@@ -17163,13 +17182,12 @@ var Subscriber = class {
17163
17182
  seen = [];
17164
17183
  seenSet = /* @__PURE__ */ new Set();
17165
17184
  delivered = 0;
17166
- handlerProc;
17167
17185
  o;
17168
17186
  constructor(options) {
17169
17187
  this.o = options;
17170
17188
  }
17171
17189
  async start() {
17172
- const { args, platform: platform2, signal } = this.o;
17190
+ const { args, platform: platform2 } = this.o;
17173
17191
  if (args.cursorFile) {
17174
17192
  const state = await loadCursorFile(platform2, args.cursorFile);
17175
17193
  this.cursor = state.cursor;
@@ -17178,18 +17196,8 @@ var Subscriber = class {
17178
17196
  }
17179
17197
  if (args.sinceNow) this.cursor = null;
17180
17198
  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
- }
17199
+ const mode = pickDelivery(this.o.event, args.delivery);
17200
+ return mode === "push" ? await this.push() : await this.poll();
17193
17201
  }
17194
17202
  notice(text) {
17195
17203
  if (this.o.args.silent) return Promise.resolve();
@@ -17207,7 +17215,7 @@ var Subscriber = class {
17207
17215
  }
17208
17216
  async persist(force = false) {
17209
17217
  const path = this.o.args.cursorFile;
17210
- if (!path || !force && this.persisted === this.cursor) return;
17218
+ if (!path || this.o.signal.aborted || !force && this.persisted === this.cursor) return;
17211
17219
  const body = JSON.stringify({
17212
17220
  event: this.o.event.name,
17213
17221
  cursor: this.cursor,
@@ -17228,6 +17236,7 @@ var Subscriber = class {
17228
17236
  await this.persist();
17229
17237
  }
17230
17238
  async deliver(occurrence, cursor) {
17239
+ if (this.o.signal.aborted) return;
17231
17240
  const id = typeof occurrence.eventId === "string" ? occurrence.eventId : void 0;
17232
17241
  if (id !== void 0 && this.seenSet.has(id)) {
17233
17242
  if (cursor !== void 0) await this.moveTo(cursor, false);
@@ -17240,7 +17249,7 @@ var Subscriber = class {
17240
17249
  await this.persist(true);
17241
17250
  }
17242
17251
  async handle(occurrence) {
17243
- const { platform: platform2, args } = this.o;
17252
+ const { platform: platform2, args, signal } = this.o;
17244
17253
  const line = `${sanitizeJson(JSON.stringify(occurrence))}
17245
17254
  `;
17246
17255
  if (!args.handler) {
@@ -17260,7 +17269,9 @@ var Subscriber = class {
17260
17269
  } catch (err) {
17261
17270
  throw new McpcatError(EXIT_USAGE, `cannot run ${args.handler[0]}: ${err.message}`);
17262
17271
  }
17263
- this.handlerProc = proc;
17272
+ const stop = () => void reap(proc, HANDLER_GRACE_MS);
17273
+ if (signal.aborted) stop();
17274
+ else signal.addEventListener("abort", stop, { once: true });
17264
17275
  const feed = async () => {
17265
17276
  const writer = proc.stdin.getWriter();
17266
17277
  try {
@@ -17289,12 +17300,12 @@ var Subscriber = class {
17289
17300
  pipe(proc.stderr, 2),
17290
17301
  proc.wait()
17291
17302
  ]);
17292
- if (status.status !== 0 && !this.o.signal.aborted) {
17303
+ if (status.status !== 0 && !signal.aborted) {
17293
17304
  const how = status.signal ? `was killed by ${status.signal}` : `exited ${status.status}`;
17294
17305
  await this.notice(`${args.handler[0]} ${how} for event ${String(occurrence.eventId)}`);
17295
17306
  }
17296
17307
  } finally {
17297
- this.handlerProc = void 0;
17308
+ signal.removeEventListener("abort", stop);
17298
17309
  }
17299
17310
  }
17300
17311
  async backoff(delay, reason, verb = "retrying") {
@@ -19805,7 +19816,7 @@ async function main(ctx) {
19805
19816
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
19806
19817
  });
19807
19818
  const args = ctx.argv.slice(1);
19808
- return run(platform2, "0.29.0", args);
19819
+ return run(platform2, "0.29.2", args);
19809
19820
  }
19810
19821
  export {
19811
19822
  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.2",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",