@mcp-use/cli 3.0.2-canary.0 → 3.0.2-canary.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.
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAwIA,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC5B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAuYD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA4qBzE"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AA4IA,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC5B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAueD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAwsBzE"}
package/dist/index.cjs CHANGED
@@ -1222,6 +1222,13 @@ var GitHubAuthRequiredError = class extends Error {
1222
1222
  this.authorizeUrl = authorizeUrl;
1223
1223
  }
1224
1224
  };
1225
+ var ApiUnauthorizedError = class extends Error {
1226
+ status = 401;
1227
+ constructor(message = "Your session has expired or your API key is invalid.") {
1228
+ super(message);
1229
+ this.name = "ApiUnauthorizedError";
1230
+ }
1231
+ };
1225
1232
  var McpUseAPI = class _McpUseAPI {
1226
1233
  baseUrl;
1227
1234
  apiKey;
@@ -1263,11 +1270,7 @@ var McpUseAPI = class _McpUseAPI {
1263
1270
  });
1264
1271
  clearTimeout(timeoutId);
1265
1272
  if (response.status === 401) {
1266
- const err = new Error(
1267
- "Your session has expired or your API key is invalid."
1268
- );
1269
- err.status = 401;
1270
- throw err;
1273
+ throw new ApiUnauthorizedError();
1271
1274
  }
1272
1275
  if (!response.ok) {
1273
1276
  const errorText = await response.text();
@@ -2825,10 +2828,10 @@ var import_node_path5 = __toESM(require("path"), 1);
2825
2828
  // src/utils/git.ts
2826
2829
  var import_node_child_process8 = require("child_process");
2827
2830
  var import_node_util7 = require("util");
2828
- var execAsync = (0, import_node_util7.promisify)(import_node_child_process8.exec);
2829
- async function gitCommand(command, cwd = process.cwd()) {
2831
+ var execFileAsync5 = (0, import_node_util7.promisify)(import_node_child_process8.execFile);
2832
+ async function gitCommand(args, cwd = process.cwd()) {
2830
2833
  try {
2831
- const { stdout } = await execAsync(command, { cwd });
2834
+ const { stdout } = await execFileAsync5("git", args, { cwd });
2832
2835
  return stdout.trim();
2833
2836
  } catch (error) {
2834
2837
  return null;
@@ -2850,9 +2853,10 @@ ${trimmed}`);
2850
2853
  this.exitCode = opts.exitCode;
2851
2854
  }
2852
2855
  };
2853
- async function gitCommandOrThrow(command, cwd = process.cwd()) {
2856
+ async function gitCommandOrThrow(args, cwd = process.cwd()) {
2857
+ const command = `git ${args.join(" ")}`;
2854
2858
  try {
2855
- const { stdout } = await execAsync(command, { cwd });
2859
+ const { stdout } = await execFileAsync5("git", args, { cwd });
2856
2860
  return stdout.trim();
2857
2861
  } catch (error) {
2858
2862
  const e = error;
@@ -2865,11 +2869,11 @@ async function gitCommandOrThrow(command, cwd = process.cwd()) {
2865
2869
  }
2866
2870
  }
2867
2871
  async function isGitRepo(cwd = process.cwd()) {
2868
- const result = await gitCommand("git rev-parse --is-inside-work-tree", cwd);
2872
+ const result = await gitCommand(["rev-parse", "--is-inside-work-tree"], cwd);
2869
2873
  return result === "true";
2870
2874
  }
2871
2875
  async function getRemoteUrl(cwd = process.cwd()) {
2872
- return gitCommand("git config --get remote.origin.url", cwd);
2876
+ return gitCommand(["config", "--get", "remote.origin.url"], cwd);
2873
2877
  }
2874
2878
  function parseGitHubUrl(url) {
2875
2879
  const sshMatch = url.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
@@ -2884,16 +2888,16 @@ function parseGitHubUrl(url) {
2884
2888
  };
2885
2889
  }
2886
2890
  async function getCurrentBranch(cwd = process.cwd()) {
2887
- return gitCommand("git rev-parse --abbrev-ref HEAD", cwd);
2891
+ return gitCommand(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
2888
2892
  }
2889
2893
  async function getCommitSha(cwd = process.cwd()) {
2890
- return gitCommand("git rev-parse HEAD", cwd);
2894
+ return gitCommand(["rev-parse", "HEAD"], cwd);
2891
2895
  }
2892
2896
  async function getCommitMessage(cwd = process.cwd()) {
2893
- return gitCommand("git log -1 --pretty=%B", cwd);
2897
+ return gitCommand(["log", "-1", "--pretty=%B"], cwd);
2894
2898
  }
2895
2899
  async function hasUncommittedChanges(cwd = process.cwd()) {
2896
- const result = await gitCommand("git status --porcelain", cwd);
2900
+ const result = await gitCommand(["status", "--porcelain"], cwd);
2897
2901
  return result !== null && result.length > 0;
2898
2902
  }
2899
2903
  async function getGitInfo(cwd = process.cwd()) {
@@ -2926,24 +2930,21 @@ async function getGitInfo(cwd = process.cwd()) {
2926
2930
  hasUncommittedChanges: uncommittedChanges
2927
2931
  };
2928
2932
  }
2929
- function shellQuote(message) {
2930
- return `"${message.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
2931
- }
2932
2933
  async function gitInit(cwd, message = "Initial commit") {
2933
- await gitCommandOrThrow("git init", cwd);
2934
- await gitCommandOrThrow("git add .", cwd);
2935
- await gitCommandOrThrow(`git commit -m ${shellQuote(message)}`, cwd);
2936
- await gitCommandOrThrow("git branch -M main", cwd);
2937
- await gitCommandOrThrow("git rev-parse HEAD", cwd);
2934
+ await gitCommandOrThrow(["init"], cwd);
2935
+ await gitCommandOrThrow(["add", "."], cwd);
2936
+ await gitCommandOrThrow(["commit", "-m", message], cwd);
2937
+ await gitCommandOrThrow(["branch", "-M", "main"], cwd);
2938
+ await gitCommandOrThrow(["rev-parse", "HEAD"], cwd);
2938
2939
  }
2939
2940
  async function gitAddRemoteAndPush(cwd, cloneUrl, branch = "main") {
2940
- await gitCommandOrThrow(`git remote add origin ${cloneUrl}`, cwd);
2941
- await gitCommandOrThrow(`git push -u origin ${branch}`, cwd);
2941
+ await gitCommandOrThrow(["remote", "add", "origin", cloneUrl], cwd);
2942
+ await gitCommandOrThrow(["push", "-u", "origin", branch], cwd);
2942
2943
  }
2943
2944
  async function gitCommitAndPush(cwd, message, branch = "main") {
2944
- await gitCommandOrThrow("git add .", cwd);
2945
- await gitCommandOrThrow(`git commit -m ${shellQuote(message)}`, cwd);
2946
- await gitCommandOrThrow(`git push origin ${branch}`, cwd);
2945
+ await gitCommandOrThrow(["add", "."], cwd);
2946
+ await gitCommandOrThrow(["commit", "-m", message], cwd);
2947
+ await gitCommandOrThrow(["push", "origin", branch], cwd);
2947
2948
  }
2948
2949
  function isGitHubUrl(url) {
2949
2950
  try {
@@ -3344,6 +3345,58 @@ async function displayDeploymentProgress(api, deploymentId, progressOptions) {
3344
3345
  source_default.gray("Check status with: ") + source_default.white(`mcp-use deployments get ${deploymentId}`)
3345
3346
  );
3346
3347
  }
3348
+ async function promptReauthenticateOn401(options, orgIdToRestore) {
3349
+ console.log(source_default.red("\n\u2717 Session expired or API key invalid."));
3350
+ if (options.yes) {
3351
+ console.log(
3352
+ source_default.gray(" Run mcp-use login to re-authenticate, then retry.")
3353
+ );
3354
+ process.exit(1);
3355
+ }
3356
+ const should = await prompt(source_default.white("Log in again? (Y/n): "), "y");
3357
+ if (!should) {
3358
+ process.exit(1);
3359
+ }
3360
+ await loginCommand({ silent: false });
3361
+ if (!await isLoggedIn()) {
3362
+ console.log(source_default.red("\u2717 Login failed. Please try again."));
3363
+ process.exit(1);
3364
+ }
3365
+ const fresh = await McpUseAPI.create();
3366
+ if (orgIdToRestore) {
3367
+ fresh.setOrgId(orgIdToRestore);
3368
+ }
3369
+ return fresh;
3370
+ }
3371
+ async function ensureApiSessionForDeploy(api, options, orgIdToRestore) {
3372
+ let client = api;
3373
+ for (; ; ) {
3374
+ try {
3375
+ await client.testAuth();
3376
+ return client;
3377
+ } catch (e) {
3378
+ if (!(e instanceof ApiUnauthorizedError)) throw e;
3379
+ client = await promptReauthenticateOn401(options, orgIdToRestore);
3380
+ }
3381
+ }
3382
+ }
3383
+ async function getGitHubConnectionStatusWith401Retry(api, options, orgIdToRestore) {
3384
+ let client = api;
3385
+ for (let attempt = 0; attempt < 2; attempt++) {
3386
+ try {
3387
+ const status = await client.getGitHubConnectionStatus();
3388
+ return { api: client, status };
3389
+ } catch (e) {
3390
+ if (e instanceof ApiUnauthorizedError && attempt === 0) {
3391
+ client = await promptReauthenticateOn401(options, orgIdToRestore);
3392
+ await client.testAuth();
3393
+ continue;
3394
+ }
3395
+ throw e;
3396
+ }
3397
+ }
3398
+ throw new Error("Unreachable");
3399
+ }
3347
3400
  async function checkRepoAccess(api, owner, repo) {
3348
3401
  try {
3349
3402
  const resp = await api.getGitHubRepos(true);
@@ -3354,6 +3407,7 @@ async function checkRepoAccess(api, owner, repo) {
3354
3407
  }
3355
3408
  async function promptGitHubInstallation(api, reason, repoName, opts) {
3356
3409
  const yes = !!opts?.yes;
3410
+ const reauth = opts?.reauth;
3357
3411
  console.log();
3358
3412
  if (reason === "not_connected") {
3359
3413
  console.log(source_default.yellow("\u26A0\uFE0F GitHub account not connected"));
@@ -3377,9 +3431,23 @@ async function promptGitHubInstallation(api, reason, repoName, opts) {
3377
3431
  ),
3378
3432
  "y"
3379
3433
  );
3380
- if (!shouldInstall) return false;
3434
+ if (!shouldInstall) return { ok: false, api };
3435
+ let client = api;
3381
3436
  try {
3382
- const appName = await api.getGitHubAppName();
3437
+ let appName;
3438
+ for (; ; ) {
3439
+ try {
3440
+ appName = await client.getGitHubAppName();
3441
+ break;
3442
+ } catch (e) {
3443
+ if (e instanceof ApiUnauthorizedError && reauth) {
3444
+ client = await reauth();
3445
+ await client.testAuth();
3446
+ continue;
3447
+ }
3448
+ throw e;
3449
+ }
3450
+ }
3383
3451
  const installUrl = `https://github.com/apps/${appName}/installations/new`;
3384
3452
  console.log(source_default.cyan(`
3385
3453
  Opening browser...`));
@@ -3403,23 +3471,34 @@ Opening browser...`));
3403
3471
  while (Date.now() < deadline) {
3404
3472
  await new Promise((r) => setTimeout(r, 2e3));
3405
3473
  try {
3406
- const status = await api.getGitHubConnectionStatus();
3474
+ const status = await client.getGitHubConnectionStatus();
3407
3475
  if (status.is_connected) {
3408
- if (!repoName) return true;
3476
+ if (!repoName) return { ok: true, api: client };
3409
3477
  const [o, r] = repoName.split("/");
3410
- if (o && r && await checkRepoAccess(api, o, r)) return true;
3478
+ if (o && r && await checkRepoAccess(client, o, r)) {
3479
+ return { ok: true, api: client };
3480
+ }
3481
+ }
3482
+ } catch (e) {
3483
+ if (e instanceof ApiUnauthorizedError && reauth) {
3484
+ client = await reauth();
3485
+ await client.testAuth();
3486
+ continue;
3411
3487
  }
3412
- } catch {
3413
3488
  }
3414
3489
  }
3415
3490
  }
3416
- return true;
3417
- } catch {
3491
+ return { ok: true, api: client };
3492
+ } catch (e) {
3493
+ if (e instanceof ApiUnauthorizedError) {
3494
+ console.log(source_default.red("\n\u2717 Session expired or API key invalid."));
3495
+ process.exit(1);
3496
+ }
3418
3497
  console.log(source_default.yellow("\n\u26A0\uFE0F Unable to open browser automatically"));
3419
3498
  console.log(
3420
3499
  source_default.white("Please visit: ") + source_default.cyan("https://manufact.com/cloud/settings")
3421
3500
  );
3422
- return false;
3501
+ return { ok: false, api: client };
3423
3502
  }
3424
3503
  }
3425
3504
  async function deployCommand(options) {
@@ -3462,7 +3541,8 @@ async function deployCommand(options) {
3462
3541
  process.exit(1);
3463
3542
  }
3464
3543
  }
3465
- const api = await McpUseAPI.create();
3544
+ let api = await McpUseAPI.create();
3545
+ let resolvedOrgId;
3466
3546
  if (options.org) {
3467
3547
  const authInfo = await api.testAuth();
3468
3548
  const match = (authInfo.orgs ?? []).find(
@@ -3470,6 +3550,7 @@ async function deployCommand(options) {
3470
3550
  );
3471
3551
  if (match) {
3472
3552
  api.setOrgId(match.id);
3553
+ resolvedOrgId = match.id;
3473
3554
  const slug = match.slug ? source_default.gray(` (${match.slug})`) : "";
3474
3555
  console.log(
3475
3556
  source_default.gray("Organization: ") + source_default.cyan(match.name) + slug
@@ -3508,6 +3589,7 @@ async function deployCommand(options) {
3508
3589
  process.exit(1);
3509
3590
  }
3510
3591
  api.setOrgId(selectedOrg.id);
3592
+ resolvedOrgId = selectedOrg.id;
3511
3593
  await writeConfig({
3512
3594
  ...config,
3513
3595
  orgId: selectedOrg.id,
@@ -3518,6 +3600,8 @@ async function deployCommand(options) {
3518
3600
  source_default.gray("Organization: ") + source_default.cyan(selectedOrg.name)
3519
3601
  );
3520
3602
  } else {
3603
+ resolvedOrgId = config.orgId;
3604
+ api.setOrgId(config.orgId);
3521
3605
  if (config.orgName) {
3522
3606
  const slug = config.orgSlug ? source_default.gray(` (${config.orgSlug})`) : "";
3523
3607
  console.log(
@@ -3526,21 +3610,39 @@ async function deployCommand(options) {
3526
3610
  }
3527
3611
  }
3528
3612
  }
3613
+ api = await ensureApiSessionForDeploy(api, options, resolvedOrgId);
3529
3614
  console.log(source_default.cyan.bold("\n\u{1F680} Deploying to Manufact cloud...\n"));
3530
- let connectionStatus = await api.getGitHubConnectionStatus().catch(() => null);
3531
- if (!connectionStatus?.is_connected) {
3615
+ const reauth = () => promptReauthenticateOn401(options, resolvedOrgId);
3616
+ let ghConn = await getGitHubConnectionStatusWith401Retry(
3617
+ api,
3618
+ options,
3619
+ resolvedOrgId
3620
+ );
3621
+ api = ghConn.api;
3622
+ let connectionStatus = ghConn.status;
3623
+ if (!connectionStatus.is_connected) {
3532
3624
  const installed = await promptGitHubInstallation(
3533
3625
  api,
3534
3626
  "not_connected",
3535
3627
  void 0,
3536
- { yes: options.yes }
3628
+ {
3629
+ yes: options.yes,
3630
+ reauth
3631
+ }
3537
3632
  );
3538
- if (!installed) {
3633
+ if (!installed.ok) {
3539
3634
  console.log(source_default.gray("Deployment cancelled."));
3540
3635
  process.exit(0);
3541
3636
  }
3542
- connectionStatus = await api.getGitHubConnectionStatus().catch(() => null);
3543
- if (!connectionStatus?.is_connected) {
3637
+ api = installed.api;
3638
+ ghConn = await getGitHubConnectionStatusWith401Retry(
3639
+ api,
3640
+ options,
3641
+ resolvedOrgId
3642
+ );
3643
+ api = ghConn.api;
3644
+ connectionStatus = ghConn.status;
3645
+ if (!connectionStatus.is_connected) {
3544
3646
  console.log(source_default.red("\n\u2717 GitHub connection could not be verified."));
3545
3647
  console.log(
3546
3648
  source_default.cyan(
@@ -3819,11 +3921,16 @@ async function deployCommand(options) {
3819
3921
  api,
3820
3922
  "no_access",
3821
3923
  repoFullName,
3822
- { yes: options.yes, installationId: githubInstallationId }
3924
+ {
3925
+ yes: options.yes,
3926
+ installationId: githubInstallationId,
3927
+ reauth: () => promptReauthenticateOn401(options, resolvedOrgId)
3928
+ }
3823
3929
  );
3824
- if (!configured) {
3930
+ if (!configured.ok) {
3825
3931
  process.exit(0);
3826
3932
  }
3933
+ api = configured.api;
3827
3934
  const retry = await checkRepoAccess(api, gitInfo.owner, gitInfo.repo);
3828
3935
  if (!retry) {
3829
3936
  const appName = await api.getGitHubAppName();