@ai-ecoverse/mcpcat 0.15.2 → 0.15.3

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.
@@ -6477,6 +6477,7 @@ var McpOAuthProvider = class {
6477
6477
  // src/auth/jerk-token-source.ts
6478
6478
  var MIN_VERSION = [0, 14, 1];
6479
6479
  var VERSION_TIMEOUT_MS = 2e3;
6480
+ var JERK_TIMEOUT_MS = 15e3;
6480
6481
  var cachedAvailable;
6481
6482
  function parseVersion(raw) {
6482
6483
  const match = raw.trim().match(/(\d+)\.(\d+)\.(\d+)/);
@@ -6523,23 +6524,39 @@ async function jerkAvailable(platform2) {
6523
6524
  return false;
6524
6525
  }
6525
6526
  try {
6526
- const proc = await platform2.spawn({ argv: ["jerk", "--version"] });
6527
- const timeout = new Promise((_, reject) => {
6528
- setTimeout(() => reject(new Error("timeout")), VERSION_TIMEOUT_MS);
6529
- });
6530
- const work = Promise.all([readAll(proc.stdout), proc.wait()]).then(([out, result]) => {
6531
- proc.stderr.cancel().catch(() => {
6532
- });
6533
- if (result.status !== 0) return false;
6534
- const ver = parseVersion(out);
6535
- return ver !== void 0 && versionSatisfied(ver);
6536
- });
6537
- cachedAvailable = await Promise.race([work, timeout]);
6527
+ const result = await runJerk(platform2, ["jerk", "--version"], VERSION_TIMEOUT_MS);
6528
+ const ver = result.status === 0 ? parseVersion(result.stdout) : void 0;
6529
+ cachedAvailable = ver !== void 0 && versionSatisfied(ver);
6538
6530
  } catch {
6539
6531
  cachedAvailable = false;
6540
6532
  }
6541
6533
  return cachedAvailable;
6542
6534
  }
6535
+ var JerkTimeoutError = class extends Error {
6536
+ command;
6537
+ constructor(argv) {
6538
+ const command = argv.slice(0, 3).join(" ");
6539
+ super(`jerk did not answer; run \`${command}\` yourself`);
6540
+ this.name = "JerkTimeoutError";
6541
+ this.command = command;
6542
+ }
6543
+ };
6544
+ async function runJerk(platform2, argv, timeoutMs) {
6545
+ const proc = await platform2.spawn({ argv, stdin: "ignore" });
6546
+ let timer;
6547
+ const expired = new Promise((resolve) => {
6548
+ timer = setTimeout(() => resolve("timeout"), timeoutMs);
6549
+ });
6550
+ const work = Promise.all([readAll(proc.stdout), readAll(proc.stderr), proc.wait()]);
6551
+ const outcome = await Promise.race([work, expired]);
6552
+ clearTimeout(timer);
6553
+ if (outcome === "timeout") {
6554
+ await proc.kill("SIGKILL");
6555
+ throw new JerkTimeoutError(argv);
6556
+ }
6557
+ const [stdout, stderr, result] = outcome;
6558
+ return { status: result.status, stdout, stderr };
6559
+ }
6543
6560
  function jerkId(name) {
6544
6561
  if (name.startsWith("mcp:")) return name;
6545
6562
  if (name.startsWith("url:")) return `mcp:${name}`;
@@ -6560,8 +6577,10 @@ var JerkSignInRequiredError = class extends Error {
6560
6577
  };
6561
6578
  var JerkTokenSource = class {
6562
6579
  platform;
6563
- constructor(platform2) {
6580
+ timeoutMs;
6581
+ constructor(platform2, timeoutMs = JERK_TIMEOUT_MS) {
6564
6582
  this.platform = platform2;
6583
+ this.timeoutMs = timeoutMs;
6565
6584
  }
6566
6585
  async getToken(name, serverUrl, scope) {
6567
6586
  const id = jerkId(name);
@@ -6569,12 +6588,7 @@ var JerkTokenSource = class {
6569
6588
  if (scope) {
6570
6589
  argv.push("--scope", scope);
6571
6590
  }
6572
- const proc = await this.platform.spawn({ argv });
6573
- const [outRaw, , result] = await Promise.all([
6574
- readAll(proc.stdout),
6575
- readAll(proc.stderr),
6576
- proc.wait()
6577
- ]);
6591
+ const result = await runJerk(this.platform, argv, this.timeoutMs);
6578
6592
  if (result.status === JERK_EXIT_SIGN_IN) {
6579
6593
  throw new JerkSignInRequiredError(id, scope);
6580
6594
  }
@@ -6584,7 +6598,7 @@ var JerkTokenSource = class {
6584
6598
  if (result.status !== 0) {
6585
6599
  return void 0;
6586
6600
  }
6587
- const parsed = JSON.parse(outRaw.trim());
6601
+ const parsed = JSON.parse(result.stdout.trim());
6588
6602
  if (!parsed.token) return void 0;
6589
6603
  return {
6590
6604
  accessToken: parsed.token,
@@ -8571,7 +8585,7 @@ async function createStatelessConnection(options) {
8571
8585
  token
8572
8586
  });
8573
8587
  } catch (authErr) {
8574
- if (authErr instanceof AuthStepUpError) throw authErr;
8588
+ if (authErr instanceof AuthStepUpError || authErr instanceof JerkTimeoutError) throw authErr;
8575
8589
  throw new McpAuthError(err.response.status, url);
8576
8590
  }
8577
8591
  }
@@ -11498,15 +11512,15 @@ function readMcpCommand(value) {
11498
11512
  }
11499
11513
  function readMcpPositionals(value) {
11500
11514
  if (!Array.isArray(value)) return [];
11501
- const positionals = [];
11515
+ const positionals2 = [];
11502
11516
  for (const entry of value) {
11503
11517
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
11504
11518
  const name = ownString(entry, "name");
11505
11519
  if (!name) continue;
11506
11520
  const required = Object.getOwnPropertyDescriptor(entry, "required")?.value;
11507
- positionals.push({ name, required: required !== false, description: "" });
11521
+ positionals2.push({ name, required: required !== false, description: "" });
11508
11522
  }
11509
- return positionals;
11523
+ return positionals2;
11510
11524
  }
11511
11525
  function readMcpFlags(value) {
11512
11526
  if (!Array.isArray(value)) return [];
@@ -13847,16 +13861,25 @@ async function signIn(options) {
13847
13861
 
13848
13862
  // src/cli/auth-verbs.ts
13849
13863
  var resolvedSource;
13850
- async function createTokenSource(platform2) {
13864
+ async function createTokenSource(platform2, timeoutMs = JERK_TIMEOUT_MS) {
13851
13865
  if (isKernel(platform2)) return new PiFileTokenSource(platform2);
13852
13866
  if (resolvedSource) return resolvedSource;
13853
13867
  if (await jerkAvailable(platform2)) {
13854
- resolvedSource = new JerkTokenSource(platform2);
13868
+ resolvedSource = new JerkTokenSource(platform2, timeoutMs);
13855
13869
  } else {
13856
13870
  resolvedSource = new PiFileTokenSource(platform2);
13857
13871
  }
13858
13872
  return resolvedSource;
13859
13873
  }
13874
+ var VALUE_FLAGS = /* @__PURE__ */ new Set(["--scope", "-m", "--timeout"]);
13875
+ function positionals(args2) {
13876
+ const out = [];
13877
+ for (let i = 0; i < args2.length; i++) {
13878
+ if (VALUE_FLAGS.has(args2[i])) i++;
13879
+ else if (!args2[i].startsWith("-")) out.push(args2[i]);
13880
+ }
13881
+ return out;
13882
+ }
13860
13883
  function resolveServerName(target) {
13861
13884
  try {
13862
13885
  const u = new URL(target.startsWith("http") ? target : `https://${target}`);
@@ -13937,18 +13960,10 @@ async function jerkLogin(platform2, target, args2) {
13937
13960
  if (result.status === JERK_EXIT_SIGN_IN) return 4;
13938
13961
  return result.status;
13939
13962
  }
13940
- async function jerkLogout(platform2, target) {
13963
+ async function jerkLogout(platform2, target, source) {
13941
13964
  const resolved = await resolveLoginTarget(platform2, target);
13942
13965
  const id = jerkMcpId(resolved.name);
13943
- const argv = ["jerk", id, "drop", "--yes"];
13944
- const proc = await platform2.spawn({ argv });
13945
- proc.stdin.close().catch(() => {
13946
- });
13947
- const [, , result] = await Promise.all([
13948
- readStream2(proc.stdout),
13949
- readStream2(proc.stderr),
13950
- proc.wait()
13951
- ]);
13966
+ const result = await runJerk(platform2, ["jerk", id, "drop", "--yes"], source.timeoutMs);
13952
13967
  if (result.status === 0) {
13953
13968
  await platform2.write(1, `Signed out of ${target}
13954
13969
  `);
@@ -13966,7 +13981,7 @@ async function runLogin(platform2, args2, source) {
13966
13981
  );
13967
13982
  return 4;
13968
13983
  }
13969
- const positional = args2.filter((a) => !a.startsWith("-"));
13984
+ const positional = positionals(args2);
13970
13985
  if (positional.length === 0) {
13971
13986
  await platform2.write(2, "mcpcat: login requires a target\n");
13972
13987
  return 2;
@@ -14057,7 +14072,7 @@ async function runLogout(platform2, args2, source) {
14057
14072
  await platform2.write(2, "mcpcat: logout is not available in seven.\n");
14058
14073
  return 4;
14059
14074
  }
14060
- const positional = args2.filter((a) => !a.startsWith("-"));
14075
+ const positional = positionals(args2);
14061
14076
  if (positional.length === 0) {
14062
14077
  await platform2.write(2, "mcpcat: logout requires a target\n");
14063
14078
  return 2;
@@ -14065,8 +14080,13 @@ async function runLogout(platform2, args2, source) {
14065
14080
  const target = positional[0];
14066
14081
  if (source instanceof JerkTokenSource) {
14067
14082
  try {
14068
- return await jerkLogout(platform2, target);
14083
+ return await jerkLogout(platform2, target, source);
14069
14084
  } catch (err) {
14085
+ if (err instanceof JerkTimeoutError) {
14086
+ await platform2.write(2, `mcpcat: ${err.message}
14087
+ `);
14088
+ return 4;
14089
+ }
14070
14090
  await platform2.write(2, `mcpcat: logout failed: ${err.message}
14071
14091
  `);
14072
14092
  return 1;
@@ -15225,6 +15245,10 @@ var VERBS_WITH_TARGET = /* @__PURE__ */ new Set([
15225
15245
  "prompts",
15226
15246
  "prompt"
15227
15247
  ]);
15248
+ function withoutVerb(args2, verb) {
15249
+ const at = args2.indexOf(verb);
15250
+ return [...args2.slice(0, at), ...args2.slice(at + 1)];
15251
+ }
15228
15252
  function resolveMaxPositional(positional) {
15229
15253
  if (positional.length === 0) return 3;
15230
15254
  const first = positional[0];
@@ -16052,12 +16076,12 @@ async function runInner(platform2, version, args2) {
16052
16076
  const discResult = await dispatchDiscoveryVerb(platform2, parsed, args2);
16053
16077
  if (discResult !== void 0) return discResult;
16054
16078
  if (parsed.verb === "login") {
16055
- const source = await createTokenSource(platform2);
16056
- return runLogin(platform2, args2.slice(1), source);
16079
+ const source = await createTokenSource(platform2, parsed.timeoutMs);
16080
+ return runLogin(platform2, withoutVerb(args2, "login"), source);
16057
16081
  }
16058
16082
  if (parsed.verb === "logout") {
16059
- const source = await createTokenSource(platform2);
16060
- return runLogout(platform2, args2.slice(1), source);
16083
+ const source = await createTokenSource(platform2, parsed.timeoutMs);
16084
+ return runLogout(platform2, withoutVerb(args2, "logout"), source);
16061
16085
  }
16062
16086
  if (UNIMPLEMENTED_VERBS.has(parsed.verb)) {
16063
16087
  await platform2.write(2, `mcpcat: '${parsed.verb}' is not implemented yet
@@ -16124,7 +16148,7 @@ function classifyError(err) {
16124
16148
  if (err instanceof McpAuthError) {
16125
16149
  return { code: EXIT_AUTH, kind: "auth", msg: err.message };
16126
16150
  }
16127
- if (err instanceof JerkSignInRequiredError) {
16151
+ if (err instanceof JerkSignInRequiredError || err instanceof JerkTimeoutError) {
16128
16152
  return { code: EXIT_AUTH, kind: "auth", msg: err.message };
16129
16153
  }
16130
16154
  if (err instanceof AuthStepUpError) {
@@ -16148,9 +16172,9 @@ function classifyError(err) {
16148
16172
  }
16149
16173
  return { code: EXIT_RPC_ERROR, kind: "rpc_error", msg };
16150
16174
  }
16151
- async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config, onCredentialObtained) {
16175
+ async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config, timeoutMs, onCredentialObtained) {
16152
16176
  if (hasAuthHeader || !url) return void 0;
16153
- const source = await createTokenSource(platform2);
16177
+ const source = await createTokenSource(platform2, timeoutMs);
16154
16178
  const entry = config.entry(target);
16155
16179
  const oauth = entry && "url" in entry.config ? entry.config.oauth : void 0;
16156
16180
  const name = entry ? target : `url:${new URL(url).origin}${new URL(url).pathname}`;
@@ -16182,7 +16206,7 @@ function classifyConnectionError(err, target, interrupted) {
16182
16206
  msg: `${err.reason} (${hint})`
16183
16207
  };
16184
16208
  }
16185
- if (err instanceof McpAuthError || err instanceof AuthStepUpError || err instanceof JerkSignInRequiredError) {
16209
+ if (err instanceof McpAuthError || err instanceof AuthStepUpError || err instanceof JerkSignInRequiredError || err instanceof JerkTimeoutError) {
16186
16210
  return classifyError(err);
16187
16211
  }
16188
16212
  if (err.name === "McpOAuthAuthorizationRequiredError" || err.name === "McpAuthRequiredError") {
@@ -16330,6 +16354,7 @@ async function runClientVerb(platform2, version, parsed) {
16330
16354
  resolved.url,
16331
16355
  target,
16332
16356
  config,
16357
+ timeoutMs,
16333
16358
  (secret) => {
16334
16359
  allSecrets.add(secret);
16335
16360
  verbose.secrets.add(secret);
@@ -16466,10 +16491,11 @@ var USE_PROCESS_GROUPS2 = process.platform !== "win32";
16466
16491
  function nodeSpawn(options) {
16467
16492
  return new Promise((resolve, reject) => {
16468
16493
  let rejected = false;
16494
+ const ignoreStdin = options.stdin === "ignore";
16469
16495
  const child = cpSpawn(options.argv[0], options.argv.slice(1), {
16470
16496
  env: options.env ?? process.env,
16471
16497
  cwd: options.cwd,
16472
- stdio: ["pipe", "pipe", "pipe"],
16498
+ stdio: [ignoreStdin ? "ignore" : "pipe", "pipe", "pipe"],
16473
16499
  detached: USE_PROCESS_GROUPS2
16474
16500
  });
16475
16501
  child.on("error", (err) => {
@@ -16480,7 +16506,7 @@ function nodeSpawn(options) {
16480
16506
  });
16481
16507
  const stdout = Readable.toWeb(child.stdout);
16482
16508
  const stderr = Readable.toWeb(child.stderr);
16483
- const stdin = Writable.toWeb(child.stdin);
16509
+ const stdin = ignoreStdin ? new WritableStream() : Writable.toWeb(child.stdin);
16484
16510
  const closePromise = new Promise((res) => {
16485
16511
  child.on("close", (code2, signal) => {
16486
16512
  res({
@@ -16687,5 +16713,5 @@ try {
16687
16713
  });
16688
16714
  } catch {
16689
16715
  }
16690
- var code = await run(platform, "0.15.2", args);
16716
+ var code = await run(platform, "0.15.3", args);
16691
16717
  process.exit(code);
@@ -6098,6 +6098,7 @@ var McpOAuthProvider = class {
6098
6098
  // src/auth/jerk-token-source.ts
6099
6099
  var MIN_VERSION = [0, 14, 1];
6100
6100
  var VERSION_TIMEOUT_MS = 2e3;
6101
+ var JERK_TIMEOUT_MS = 15e3;
6101
6102
  var cachedAvailable;
6102
6103
  function parseVersion(raw) {
6103
6104
  const match = raw.trim().match(/(\d+)\.(\d+)\.(\d+)/);
@@ -6144,23 +6145,39 @@ async function jerkAvailable(platform2) {
6144
6145
  return false;
6145
6146
  }
6146
6147
  try {
6147
- const proc = await platform2.spawn({ argv: ["jerk", "--version"] });
6148
- const timeout = new Promise((_, reject) => {
6149
- setTimeout(() => reject(new Error("timeout")), VERSION_TIMEOUT_MS);
6150
- });
6151
- const work = Promise.all([readAll(proc.stdout), proc.wait()]).then(([out, result]) => {
6152
- proc.stderr.cancel().catch(() => {
6153
- });
6154
- if (result.status !== 0) return false;
6155
- const ver = parseVersion(out);
6156
- return ver !== void 0 && versionSatisfied(ver);
6157
- });
6158
- cachedAvailable = await Promise.race([work, timeout]);
6148
+ const result = await runJerk(platform2, ["jerk", "--version"], VERSION_TIMEOUT_MS);
6149
+ const ver = result.status === 0 ? parseVersion(result.stdout) : void 0;
6150
+ cachedAvailable = ver !== void 0 && versionSatisfied(ver);
6159
6151
  } catch {
6160
6152
  cachedAvailable = false;
6161
6153
  }
6162
6154
  return cachedAvailable;
6163
6155
  }
6156
+ var JerkTimeoutError = class extends Error {
6157
+ command;
6158
+ constructor(argv) {
6159
+ const command = argv.slice(0, 3).join(" ");
6160
+ super(`jerk did not answer; run \`${command}\` yourself`);
6161
+ this.name = "JerkTimeoutError";
6162
+ this.command = command;
6163
+ }
6164
+ };
6165
+ async function runJerk(platform2, argv, timeoutMs) {
6166
+ const proc = await platform2.spawn({ argv, stdin: "ignore" });
6167
+ let timer;
6168
+ const expired = new Promise((resolve2) => {
6169
+ timer = setTimeout(() => resolve2("timeout"), timeoutMs);
6170
+ });
6171
+ const work = Promise.all([readAll(proc.stdout), readAll(proc.stderr), proc.wait()]);
6172
+ const outcome = await Promise.race([work, expired]);
6173
+ clearTimeout(timer);
6174
+ if (outcome === "timeout") {
6175
+ await proc.kill("SIGKILL");
6176
+ throw new JerkTimeoutError(argv);
6177
+ }
6178
+ const [stdout, stderr, result] = outcome;
6179
+ return { status: result.status, stdout, stderr };
6180
+ }
6164
6181
  function jerkId(name) {
6165
6182
  if (name.startsWith("mcp:")) return name;
6166
6183
  if (name.startsWith("url:")) return `mcp:${name}`;
@@ -6181,8 +6198,10 @@ var JerkSignInRequiredError = class extends Error {
6181
6198
  };
6182
6199
  var JerkTokenSource = class {
6183
6200
  platform;
6184
- constructor(platform2) {
6201
+ timeoutMs;
6202
+ constructor(platform2, timeoutMs = JERK_TIMEOUT_MS) {
6185
6203
  this.platform = platform2;
6204
+ this.timeoutMs = timeoutMs;
6186
6205
  }
6187
6206
  async getToken(name, serverUrl, scope) {
6188
6207
  const id = jerkId(name);
@@ -6190,12 +6209,7 @@ var JerkTokenSource = class {
6190
6209
  if (scope) {
6191
6210
  argv.push("--scope", scope);
6192
6211
  }
6193
- const proc = await this.platform.spawn({ argv });
6194
- const [outRaw, , result] = await Promise.all([
6195
- readAll(proc.stdout),
6196
- readAll(proc.stderr),
6197
- proc.wait()
6198
- ]);
6212
+ const result = await runJerk(this.platform, argv, this.timeoutMs);
6199
6213
  if (result.status === JERK_EXIT_SIGN_IN) {
6200
6214
  throw new JerkSignInRequiredError(id, scope);
6201
6215
  }
@@ -6205,7 +6219,7 @@ var JerkTokenSource = class {
6205
6219
  if (result.status !== 0) {
6206
6220
  return void 0;
6207
6221
  }
6208
- const parsed = JSON.parse(outRaw.trim());
6222
+ const parsed = JSON.parse(result.stdout.trim());
6209
6223
  if (!parsed.token) return void 0;
6210
6224
  return {
6211
6225
  accessToken: parsed.token,
@@ -8192,7 +8206,7 @@ async function createStatelessConnection(options) {
8192
8206
  token
8193
8207
  });
8194
8208
  } catch (authErr) {
8195
- if (authErr instanceof AuthStepUpError) throw authErr;
8209
+ if (authErr instanceof AuthStepUpError || authErr instanceof JerkTimeoutError) throw authErr;
8196
8210
  throw new McpAuthError(err.response.status, url);
8197
8211
  }
8198
8212
  }
@@ -11119,15 +11133,15 @@ function readMcpCommand(value) {
11119
11133
  }
11120
11134
  function readMcpPositionals(value) {
11121
11135
  if (!Array.isArray(value)) return [];
11122
- const positionals = [];
11136
+ const positionals2 = [];
11123
11137
  for (const entry of value) {
11124
11138
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
11125
11139
  const name = ownString(entry, "name");
11126
11140
  if (!name) continue;
11127
11141
  const required = Object.getOwnPropertyDescriptor(entry, "required")?.value;
11128
- positionals.push({ name, required: required !== false, description: "" });
11142
+ positionals2.push({ name, required: required !== false, description: "" });
11129
11143
  }
11130
- return positionals;
11144
+ return positionals2;
11131
11145
  }
11132
11146
  function readMcpFlags(value) {
11133
11147
  if (!Array.isArray(value)) return [];
@@ -13468,16 +13482,25 @@ async function signIn(options) {
13468
13482
 
13469
13483
  // src/cli/auth-verbs.ts
13470
13484
  var resolvedSource;
13471
- async function createTokenSource(platform2) {
13485
+ async function createTokenSource(platform2, timeoutMs = JERK_TIMEOUT_MS) {
13472
13486
  if (isKernel(platform2)) return new PiFileTokenSource(platform2);
13473
13487
  if (resolvedSource) return resolvedSource;
13474
13488
  if (await jerkAvailable(platform2)) {
13475
- resolvedSource = new JerkTokenSource(platform2);
13489
+ resolvedSource = new JerkTokenSource(platform2, timeoutMs);
13476
13490
  } else {
13477
13491
  resolvedSource = new PiFileTokenSource(platform2);
13478
13492
  }
13479
13493
  return resolvedSource;
13480
13494
  }
13495
+ var VALUE_FLAGS = /* @__PURE__ */ new Set(["--scope", "-m", "--timeout"]);
13496
+ function positionals(args) {
13497
+ const out = [];
13498
+ for (let i = 0; i < args.length; i++) {
13499
+ if (VALUE_FLAGS.has(args[i])) i++;
13500
+ else if (!args[i].startsWith("-")) out.push(args[i]);
13501
+ }
13502
+ return out;
13503
+ }
13481
13504
  function resolveServerName(target) {
13482
13505
  try {
13483
13506
  const u = new URL(target.startsWith("http") ? target : `https://${target}`);
@@ -13558,18 +13581,10 @@ async function jerkLogin(platform2, target, args) {
13558
13581
  if (result.status === JERK_EXIT_SIGN_IN) return 4;
13559
13582
  return result.status;
13560
13583
  }
13561
- async function jerkLogout(platform2, target) {
13584
+ async function jerkLogout(platform2, target, source) {
13562
13585
  const resolved = await resolveLoginTarget(platform2, target);
13563
13586
  const id = jerkMcpId(resolved.name);
13564
- const argv = ["jerk", id, "drop", "--yes"];
13565
- const proc = await platform2.spawn({ argv });
13566
- proc.stdin.close().catch(() => {
13567
- });
13568
- const [, , result] = await Promise.all([
13569
- readStream2(proc.stdout),
13570
- readStream2(proc.stderr),
13571
- proc.wait()
13572
- ]);
13587
+ const result = await runJerk(platform2, ["jerk", id, "drop", "--yes"], source.timeoutMs);
13573
13588
  if (result.status === 0) {
13574
13589
  await platform2.write(1, `Signed out of ${target}
13575
13590
  `);
@@ -13587,7 +13602,7 @@ async function runLogin(platform2, args, source) {
13587
13602
  );
13588
13603
  return 4;
13589
13604
  }
13590
- const positional = args.filter((a) => !a.startsWith("-"));
13605
+ const positional = positionals(args);
13591
13606
  if (positional.length === 0) {
13592
13607
  await platform2.write(2, "mcpcat: login requires a target\n");
13593
13608
  return 2;
@@ -13678,7 +13693,7 @@ async function runLogout(platform2, args, source) {
13678
13693
  await platform2.write(2, "mcpcat: logout is not available in seven.\n");
13679
13694
  return 4;
13680
13695
  }
13681
- const positional = args.filter((a) => !a.startsWith("-"));
13696
+ const positional = positionals(args);
13682
13697
  if (positional.length === 0) {
13683
13698
  await platform2.write(2, "mcpcat: logout requires a target\n");
13684
13699
  return 2;
@@ -13686,8 +13701,13 @@ async function runLogout(platform2, args, source) {
13686
13701
  const target = positional[0];
13687
13702
  if (source instanceof JerkTokenSource) {
13688
13703
  try {
13689
- return await jerkLogout(platform2, target);
13704
+ return await jerkLogout(platform2, target, source);
13690
13705
  } catch (err) {
13706
+ if (err instanceof JerkTimeoutError) {
13707
+ await platform2.write(2, `mcpcat: ${err.message}
13708
+ `);
13709
+ return 4;
13710
+ }
13691
13711
  await platform2.write(2, `mcpcat: logout failed: ${err.message}
13692
13712
  `);
13693
13713
  return 1;
@@ -14846,6 +14866,10 @@ var VERBS_WITH_TARGET = /* @__PURE__ */ new Set([
14846
14866
  "prompts",
14847
14867
  "prompt"
14848
14868
  ]);
14869
+ function withoutVerb(args, verb) {
14870
+ const at = args.indexOf(verb);
14871
+ return [...args.slice(0, at), ...args.slice(at + 1)];
14872
+ }
14849
14873
  function resolveMaxPositional(positional) {
14850
14874
  if (positional.length === 0) return 3;
14851
14875
  const first = positional[0];
@@ -15673,12 +15697,12 @@ async function runInner(platform2, version, args) {
15673
15697
  const discResult = await dispatchDiscoveryVerb(platform2, parsed, args);
15674
15698
  if (discResult !== void 0) return discResult;
15675
15699
  if (parsed.verb === "login") {
15676
- const source = await createTokenSource(platform2);
15677
- return runLogin(platform2, args.slice(1), source);
15700
+ const source = await createTokenSource(platform2, parsed.timeoutMs);
15701
+ return runLogin(platform2, withoutVerb(args, "login"), source);
15678
15702
  }
15679
15703
  if (parsed.verb === "logout") {
15680
- const source = await createTokenSource(platform2);
15681
- return runLogout(platform2, args.slice(1), source);
15704
+ const source = await createTokenSource(platform2, parsed.timeoutMs);
15705
+ return runLogout(platform2, withoutVerb(args, "logout"), source);
15682
15706
  }
15683
15707
  if (UNIMPLEMENTED_VERBS.has(parsed.verb)) {
15684
15708
  await platform2.write(2, `mcpcat: '${parsed.verb}' is not implemented yet
@@ -15745,7 +15769,7 @@ function classifyError(err) {
15745
15769
  if (err instanceof McpAuthError) {
15746
15770
  return { code: EXIT_AUTH, kind: "auth", msg: err.message };
15747
15771
  }
15748
- if (err instanceof JerkSignInRequiredError) {
15772
+ if (err instanceof JerkSignInRequiredError || err instanceof JerkTimeoutError) {
15749
15773
  return { code: EXIT_AUTH, kind: "auth", msg: err.message };
15750
15774
  }
15751
15775
  if (err instanceof AuthStepUpError) {
@@ -15769,9 +15793,9 @@ function classifyError(err) {
15769
15793
  }
15770
15794
  return { code: EXIT_RPC_ERROR, kind: "rpc_error", msg };
15771
15795
  }
15772
- async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config, onCredentialObtained) {
15796
+ async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config, timeoutMs, onCredentialObtained) {
15773
15797
  if (hasAuthHeader || !url) return void 0;
15774
- const source = await createTokenSource(platform2);
15798
+ const source = await createTokenSource(platform2, timeoutMs);
15775
15799
  const entry = config.entry(target);
15776
15800
  const oauth = entry && "url" in entry.config ? entry.config.oauth : void 0;
15777
15801
  const name = entry ? target : `url:${new URL(url).origin}${new URL(url).pathname}`;
@@ -15803,7 +15827,7 @@ function classifyConnectionError(err, target, interrupted) {
15803
15827
  msg: `${err.reason} (${hint})`
15804
15828
  };
15805
15829
  }
15806
- if (err instanceof McpAuthError || err instanceof AuthStepUpError || err instanceof JerkSignInRequiredError) {
15830
+ if (err instanceof McpAuthError || err instanceof AuthStepUpError || err instanceof JerkSignInRequiredError || err instanceof JerkTimeoutError) {
15807
15831
  return classifyError(err);
15808
15832
  }
15809
15833
  if (err.name === "McpOAuthAuthorizationRequiredError" || err.name === "McpAuthRequiredError") {
@@ -15951,6 +15975,7 @@ async function runClientVerb(platform2, version, parsed) {
15951
15975
  resolved.url,
15952
15976
  target,
15953
15977
  config,
15978
+ timeoutMs,
15954
15979
  (secret) => {
15955
15980
  allSecrets.add(secret);
15956
15981
  verbose.secrets.add(secret);
@@ -16108,7 +16133,7 @@ async function kernelSpawn(ctx, options) {
16108
16133
  argv: options.argv,
16109
16134
  env: options.env,
16110
16135
  cwd: options.cwd,
16111
- stdin: "pipe",
16136
+ stdin: options.stdin === "ignore" ? "null" : "pipe",
16112
16137
  stdout: "pipe",
16113
16138
  stderr: "pipe",
16114
16139
  ...tryGroup ? { pgid: 0 } : {}
@@ -16137,7 +16162,7 @@ async function kernelSpawn(ctx, options) {
16137
16162
  }
16138
16163
  const useGroupKill = groupSpawnSupported;
16139
16164
  return {
16140
- stdin: result.stdin,
16165
+ stdin: result.stdin ?? new WritableStream(),
16141
16166
  stdout: result.stdout,
16142
16167
  stderr: result.stderr,
16143
16168
  wait: () => result.wait(),
@@ -16369,7 +16394,7 @@ async function main(ctx) {
16369
16394
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
16370
16395
  });
16371
16396
  const args = ctx.argv.slice(1);
16372
- return run(platform2, "0.15.2", args);
16397
+ return run(platform2, "0.15.3", args);
16373
16398
  }
16374
16399
  export {
16375
16400
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.15.2",
3
+ "version": "0.15.3",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -56,7 +56,7 @@
56
56
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
57
57
  },
58
58
  "devDependencies": {
59
- "@ai-ecoverse/slicc-kernel": "1.88.0",
59
+ "@ai-ecoverse/slicc-kernel": "1.88.1",
60
60
  "@ai-ecoverse/slicc-shared-web": "1.13.1",
61
61
  "@biomejs/biome": "2.5.15",
62
62
  "@earendil-works/pi-codemode": "1.2.0",