@mcp-use/cli 3.0.2-canary.0 → 3.0.2-canary.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.
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/index.cjs +154 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +155 -48
- package/dist/index.js.map +1 -1
- package/dist/utils/api.d.ts +5 -0
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1202,6 +1202,13 @@ var GitHubAuthRequiredError = class extends Error {
|
|
|
1202
1202
|
this.authorizeUrl = authorizeUrl;
|
|
1203
1203
|
}
|
|
1204
1204
|
};
|
|
1205
|
+
var ApiUnauthorizedError = class extends Error {
|
|
1206
|
+
status = 401;
|
|
1207
|
+
constructor(message = "Your session has expired or your API key is invalid.") {
|
|
1208
|
+
super(message);
|
|
1209
|
+
this.name = "ApiUnauthorizedError";
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1205
1212
|
var McpUseAPI = class _McpUseAPI {
|
|
1206
1213
|
baseUrl;
|
|
1207
1214
|
apiKey;
|
|
@@ -1243,11 +1250,7 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1243
1250
|
});
|
|
1244
1251
|
clearTimeout(timeoutId);
|
|
1245
1252
|
if (response.status === 401) {
|
|
1246
|
-
|
|
1247
|
-
"Your session has expired or your API key is invalid."
|
|
1248
|
-
);
|
|
1249
|
-
err.status = 401;
|
|
1250
|
-
throw err;
|
|
1253
|
+
throw new ApiUnauthorizedError();
|
|
1251
1254
|
}
|
|
1252
1255
|
if (!response.ok) {
|
|
1253
1256
|
const errorText = await response.text();
|
|
@@ -2803,12 +2806,12 @@ import { promises as fs9 } from "fs";
|
|
|
2803
2806
|
import path5 from "path";
|
|
2804
2807
|
|
|
2805
2808
|
// src/utils/git.ts
|
|
2806
|
-
import {
|
|
2809
|
+
import { execFile as execFile7 } from "child_process";
|
|
2807
2810
|
import { promisify as promisify7 } from "util";
|
|
2808
|
-
var
|
|
2809
|
-
async function gitCommand(
|
|
2811
|
+
var execFileAsync5 = promisify7(execFile7);
|
|
2812
|
+
async function gitCommand(args, cwd = process.cwd()) {
|
|
2810
2813
|
try {
|
|
2811
|
-
const { stdout } = await
|
|
2814
|
+
const { stdout } = await execFileAsync5("git", args, { cwd });
|
|
2812
2815
|
return stdout.trim();
|
|
2813
2816
|
} catch (error) {
|
|
2814
2817
|
return null;
|
|
@@ -2830,9 +2833,10 @@ ${trimmed}`);
|
|
|
2830
2833
|
this.exitCode = opts.exitCode;
|
|
2831
2834
|
}
|
|
2832
2835
|
};
|
|
2833
|
-
async function gitCommandOrThrow(
|
|
2836
|
+
async function gitCommandOrThrow(args, cwd = process.cwd()) {
|
|
2837
|
+
const command = `git ${args.join(" ")}`;
|
|
2834
2838
|
try {
|
|
2835
|
-
const { stdout } = await
|
|
2839
|
+
const { stdout } = await execFileAsync5("git", args, { cwd });
|
|
2836
2840
|
return stdout.trim();
|
|
2837
2841
|
} catch (error) {
|
|
2838
2842
|
const e = error;
|
|
@@ -2845,11 +2849,11 @@ async function gitCommandOrThrow(command, cwd = process.cwd()) {
|
|
|
2845
2849
|
}
|
|
2846
2850
|
}
|
|
2847
2851
|
async function isGitRepo(cwd = process.cwd()) {
|
|
2848
|
-
const result = await gitCommand("
|
|
2852
|
+
const result = await gitCommand(["rev-parse", "--is-inside-work-tree"], cwd);
|
|
2849
2853
|
return result === "true";
|
|
2850
2854
|
}
|
|
2851
2855
|
async function getRemoteUrl(cwd = process.cwd()) {
|
|
2852
|
-
return gitCommand("
|
|
2856
|
+
return gitCommand(["config", "--get", "remote.origin.url"], cwd);
|
|
2853
2857
|
}
|
|
2854
2858
|
function parseGitHubUrl(url) {
|
|
2855
2859
|
const sshMatch = url.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
|
|
@@ -2864,16 +2868,16 @@ function parseGitHubUrl(url) {
|
|
|
2864
2868
|
};
|
|
2865
2869
|
}
|
|
2866
2870
|
async function getCurrentBranch(cwd = process.cwd()) {
|
|
2867
|
-
return gitCommand("
|
|
2871
|
+
return gitCommand(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
|
|
2868
2872
|
}
|
|
2869
2873
|
async function getCommitSha(cwd = process.cwd()) {
|
|
2870
|
-
return gitCommand("
|
|
2874
|
+
return gitCommand(["rev-parse", "HEAD"], cwd);
|
|
2871
2875
|
}
|
|
2872
2876
|
async function getCommitMessage(cwd = process.cwd()) {
|
|
2873
|
-
return gitCommand("
|
|
2877
|
+
return gitCommand(["log", "-1", "--pretty=%B"], cwd);
|
|
2874
2878
|
}
|
|
2875
2879
|
async function hasUncommittedChanges(cwd = process.cwd()) {
|
|
2876
|
-
const result = await gitCommand("
|
|
2880
|
+
const result = await gitCommand(["status", "--porcelain"], cwd);
|
|
2877
2881
|
return result !== null && result.length > 0;
|
|
2878
2882
|
}
|
|
2879
2883
|
async function getGitInfo(cwd = process.cwd()) {
|
|
@@ -2906,24 +2910,21 @@ async function getGitInfo(cwd = process.cwd()) {
|
|
|
2906
2910
|
hasUncommittedChanges: uncommittedChanges
|
|
2907
2911
|
};
|
|
2908
2912
|
}
|
|
2909
|
-
function shellQuote(message) {
|
|
2910
|
-
return `"${message.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
2911
|
-
}
|
|
2912
2913
|
async function gitInit(cwd, message = "Initial commit") {
|
|
2913
|
-
await gitCommandOrThrow("
|
|
2914
|
-
await gitCommandOrThrow("
|
|
2915
|
-
await gitCommandOrThrow(
|
|
2916
|
-
await gitCommandOrThrow("
|
|
2917
|
-
await gitCommandOrThrow("
|
|
2914
|
+
await gitCommandOrThrow(["init"], cwd);
|
|
2915
|
+
await gitCommandOrThrow(["add", "."], cwd);
|
|
2916
|
+
await gitCommandOrThrow(["commit", "-m", message], cwd);
|
|
2917
|
+
await gitCommandOrThrow(["branch", "-M", "main"], cwd);
|
|
2918
|
+
await gitCommandOrThrow(["rev-parse", "HEAD"], cwd);
|
|
2918
2919
|
}
|
|
2919
2920
|
async function gitAddRemoteAndPush(cwd, cloneUrl, branch = "main") {
|
|
2920
|
-
await gitCommandOrThrow(
|
|
2921
|
-
await gitCommandOrThrow(
|
|
2921
|
+
await gitCommandOrThrow(["remote", "add", "origin", cloneUrl], cwd);
|
|
2922
|
+
await gitCommandOrThrow(["push", "-u", "origin", branch], cwd);
|
|
2922
2923
|
}
|
|
2923
2924
|
async function gitCommitAndPush(cwd, message, branch = "main") {
|
|
2924
|
-
await gitCommandOrThrow("
|
|
2925
|
-
await gitCommandOrThrow(
|
|
2926
|
-
await gitCommandOrThrow(
|
|
2925
|
+
await gitCommandOrThrow(["add", "."], cwd);
|
|
2926
|
+
await gitCommandOrThrow(["commit", "-m", message], cwd);
|
|
2927
|
+
await gitCommandOrThrow(["push", "origin", branch], cwd);
|
|
2927
2928
|
}
|
|
2928
2929
|
function isGitHubUrl(url) {
|
|
2929
2930
|
try {
|
|
@@ -3324,6 +3325,58 @@ async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
|
3324
3325
|
source_default.gray("Check status with: ") + source_default.white(`mcp-use deployments get ${deploymentId}`)
|
|
3325
3326
|
);
|
|
3326
3327
|
}
|
|
3328
|
+
async function promptReauthenticateOn401(options, orgIdToRestore) {
|
|
3329
|
+
console.log(source_default.red("\n\u2717 Session expired or API key invalid."));
|
|
3330
|
+
if (options.yes) {
|
|
3331
|
+
console.log(
|
|
3332
|
+
source_default.gray(" Run mcp-use login to re-authenticate, then retry.")
|
|
3333
|
+
);
|
|
3334
|
+
process.exit(1);
|
|
3335
|
+
}
|
|
3336
|
+
const should = await prompt(source_default.white("Log in again? (Y/n): "), "y");
|
|
3337
|
+
if (!should) {
|
|
3338
|
+
process.exit(1);
|
|
3339
|
+
}
|
|
3340
|
+
await loginCommand({ silent: false });
|
|
3341
|
+
if (!await isLoggedIn()) {
|
|
3342
|
+
console.log(source_default.red("\u2717 Login failed. Please try again."));
|
|
3343
|
+
process.exit(1);
|
|
3344
|
+
}
|
|
3345
|
+
const fresh = await McpUseAPI.create();
|
|
3346
|
+
if (orgIdToRestore) {
|
|
3347
|
+
fresh.setOrgId(orgIdToRestore);
|
|
3348
|
+
}
|
|
3349
|
+
return fresh;
|
|
3350
|
+
}
|
|
3351
|
+
async function ensureApiSessionForDeploy(api, options, orgIdToRestore) {
|
|
3352
|
+
let client = api;
|
|
3353
|
+
for (; ; ) {
|
|
3354
|
+
try {
|
|
3355
|
+
await client.testAuth();
|
|
3356
|
+
return client;
|
|
3357
|
+
} catch (e) {
|
|
3358
|
+
if (!(e instanceof ApiUnauthorizedError)) throw e;
|
|
3359
|
+
client = await promptReauthenticateOn401(options, orgIdToRestore);
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
async function getGitHubConnectionStatusWith401Retry(api, options, orgIdToRestore) {
|
|
3364
|
+
let client = api;
|
|
3365
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
3366
|
+
try {
|
|
3367
|
+
const status = await client.getGitHubConnectionStatus();
|
|
3368
|
+
return { api: client, status };
|
|
3369
|
+
} catch (e) {
|
|
3370
|
+
if (e instanceof ApiUnauthorizedError && attempt === 0) {
|
|
3371
|
+
client = await promptReauthenticateOn401(options, orgIdToRestore);
|
|
3372
|
+
await client.testAuth();
|
|
3373
|
+
continue;
|
|
3374
|
+
}
|
|
3375
|
+
throw e;
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
throw new Error("Unreachable");
|
|
3379
|
+
}
|
|
3327
3380
|
async function checkRepoAccess(api, owner, repo) {
|
|
3328
3381
|
try {
|
|
3329
3382
|
const resp = await api.getGitHubRepos(true);
|
|
@@ -3334,6 +3387,7 @@ async function checkRepoAccess(api, owner, repo) {
|
|
|
3334
3387
|
}
|
|
3335
3388
|
async function promptGitHubInstallation(api, reason, repoName, opts) {
|
|
3336
3389
|
const yes = !!opts?.yes;
|
|
3390
|
+
const reauth = opts?.reauth;
|
|
3337
3391
|
console.log();
|
|
3338
3392
|
if (reason === "not_connected") {
|
|
3339
3393
|
console.log(source_default.yellow("\u26A0\uFE0F GitHub account not connected"));
|
|
@@ -3357,9 +3411,23 @@ async function promptGitHubInstallation(api, reason, repoName, opts) {
|
|
|
3357
3411
|
),
|
|
3358
3412
|
"y"
|
|
3359
3413
|
);
|
|
3360
|
-
if (!shouldInstall) return false;
|
|
3414
|
+
if (!shouldInstall) return { ok: false, api };
|
|
3415
|
+
let client = api;
|
|
3361
3416
|
try {
|
|
3362
|
-
|
|
3417
|
+
let appName;
|
|
3418
|
+
for (; ; ) {
|
|
3419
|
+
try {
|
|
3420
|
+
appName = await client.getGitHubAppName();
|
|
3421
|
+
break;
|
|
3422
|
+
} catch (e) {
|
|
3423
|
+
if (e instanceof ApiUnauthorizedError && reauth) {
|
|
3424
|
+
client = await reauth();
|
|
3425
|
+
await client.testAuth();
|
|
3426
|
+
continue;
|
|
3427
|
+
}
|
|
3428
|
+
throw e;
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3363
3431
|
const installUrl = `https://github.com/apps/${appName}/installations/new`;
|
|
3364
3432
|
console.log(source_default.cyan(`
|
|
3365
3433
|
Opening browser...`));
|
|
@@ -3383,23 +3451,34 @@ Opening browser...`));
|
|
|
3383
3451
|
while (Date.now() < deadline) {
|
|
3384
3452
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
3385
3453
|
try {
|
|
3386
|
-
const status = await
|
|
3454
|
+
const status = await client.getGitHubConnectionStatus();
|
|
3387
3455
|
if (status.is_connected) {
|
|
3388
|
-
if (!repoName) return true;
|
|
3456
|
+
if (!repoName) return { ok: true, api: client };
|
|
3389
3457
|
const [o, r] = repoName.split("/");
|
|
3390
|
-
if (o && r && await checkRepoAccess(
|
|
3458
|
+
if (o && r && await checkRepoAccess(client, o, r)) {
|
|
3459
|
+
return { ok: true, api: client };
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
} catch (e) {
|
|
3463
|
+
if (e instanceof ApiUnauthorizedError && reauth) {
|
|
3464
|
+
client = await reauth();
|
|
3465
|
+
await client.testAuth();
|
|
3466
|
+
continue;
|
|
3391
3467
|
}
|
|
3392
|
-
} catch {
|
|
3393
3468
|
}
|
|
3394
3469
|
}
|
|
3395
3470
|
}
|
|
3396
|
-
return true;
|
|
3397
|
-
} catch {
|
|
3471
|
+
return { ok: true, api: client };
|
|
3472
|
+
} catch (e) {
|
|
3473
|
+
if (e instanceof ApiUnauthorizedError) {
|
|
3474
|
+
console.log(source_default.red("\n\u2717 Session expired or API key invalid."));
|
|
3475
|
+
process.exit(1);
|
|
3476
|
+
}
|
|
3398
3477
|
console.log(source_default.yellow("\n\u26A0\uFE0F Unable to open browser automatically"));
|
|
3399
3478
|
console.log(
|
|
3400
3479
|
source_default.white("Please visit: ") + source_default.cyan("https://manufact.com/cloud/settings")
|
|
3401
3480
|
);
|
|
3402
|
-
return false;
|
|
3481
|
+
return { ok: false, api: client };
|
|
3403
3482
|
}
|
|
3404
3483
|
}
|
|
3405
3484
|
async function deployCommand(options) {
|
|
@@ -3442,7 +3521,8 @@ async function deployCommand(options) {
|
|
|
3442
3521
|
process.exit(1);
|
|
3443
3522
|
}
|
|
3444
3523
|
}
|
|
3445
|
-
|
|
3524
|
+
let api = await McpUseAPI.create();
|
|
3525
|
+
let resolvedOrgId;
|
|
3446
3526
|
if (options.org) {
|
|
3447
3527
|
const authInfo = await api.testAuth();
|
|
3448
3528
|
const match = (authInfo.orgs ?? []).find(
|
|
@@ -3450,6 +3530,7 @@ async function deployCommand(options) {
|
|
|
3450
3530
|
);
|
|
3451
3531
|
if (match) {
|
|
3452
3532
|
api.setOrgId(match.id);
|
|
3533
|
+
resolvedOrgId = match.id;
|
|
3453
3534
|
const slug = match.slug ? source_default.gray(` (${match.slug})`) : "";
|
|
3454
3535
|
console.log(
|
|
3455
3536
|
source_default.gray("Organization: ") + source_default.cyan(match.name) + slug
|
|
@@ -3488,6 +3569,7 @@ async function deployCommand(options) {
|
|
|
3488
3569
|
process.exit(1);
|
|
3489
3570
|
}
|
|
3490
3571
|
api.setOrgId(selectedOrg.id);
|
|
3572
|
+
resolvedOrgId = selectedOrg.id;
|
|
3491
3573
|
await writeConfig({
|
|
3492
3574
|
...config,
|
|
3493
3575
|
orgId: selectedOrg.id,
|
|
@@ -3498,6 +3580,8 @@ async function deployCommand(options) {
|
|
|
3498
3580
|
source_default.gray("Organization: ") + source_default.cyan(selectedOrg.name)
|
|
3499
3581
|
);
|
|
3500
3582
|
} else {
|
|
3583
|
+
resolvedOrgId = config.orgId;
|
|
3584
|
+
api.setOrgId(config.orgId);
|
|
3501
3585
|
if (config.orgName) {
|
|
3502
3586
|
const slug = config.orgSlug ? source_default.gray(` (${config.orgSlug})`) : "";
|
|
3503
3587
|
console.log(
|
|
@@ -3506,21 +3590,39 @@ async function deployCommand(options) {
|
|
|
3506
3590
|
}
|
|
3507
3591
|
}
|
|
3508
3592
|
}
|
|
3593
|
+
api = await ensureApiSessionForDeploy(api, options, resolvedOrgId);
|
|
3509
3594
|
console.log(source_default.cyan.bold("\n\u{1F680} Deploying to Manufact cloud...\n"));
|
|
3510
|
-
|
|
3511
|
-
|
|
3595
|
+
const reauth = () => promptReauthenticateOn401(options, resolvedOrgId);
|
|
3596
|
+
let ghConn = await getGitHubConnectionStatusWith401Retry(
|
|
3597
|
+
api,
|
|
3598
|
+
options,
|
|
3599
|
+
resolvedOrgId
|
|
3600
|
+
);
|
|
3601
|
+
api = ghConn.api;
|
|
3602
|
+
let connectionStatus = ghConn.status;
|
|
3603
|
+
if (!connectionStatus.is_connected) {
|
|
3512
3604
|
const installed = await promptGitHubInstallation(
|
|
3513
3605
|
api,
|
|
3514
3606
|
"not_connected",
|
|
3515
3607
|
void 0,
|
|
3516
|
-
{
|
|
3608
|
+
{
|
|
3609
|
+
yes: options.yes,
|
|
3610
|
+
reauth
|
|
3611
|
+
}
|
|
3517
3612
|
);
|
|
3518
|
-
if (!installed) {
|
|
3613
|
+
if (!installed.ok) {
|
|
3519
3614
|
console.log(source_default.gray("Deployment cancelled."));
|
|
3520
3615
|
process.exit(0);
|
|
3521
3616
|
}
|
|
3522
|
-
|
|
3523
|
-
|
|
3617
|
+
api = installed.api;
|
|
3618
|
+
ghConn = await getGitHubConnectionStatusWith401Retry(
|
|
3619
|
+
api,
|
|
3620
|
+
options,
|
|
3621
|
+
resolvedOrgId
|
|
3622
|
+
);
|
|
3623
|
+
api = ghConn.api;
|
|
3624
|
+
connectionStatus = ghConn.status;
|
|
3625
|
+
if (!connectionStatus.is_connected) {
|
|
3524
3626
|
console.log(source_default.red("\n\u2717 GitHub connection could not be verified."));
|
|
3525
3627
|
console.log(
|
|
3526
3628
|
source_default.cyan(
|
|
@@ -3799,11 +3901,16 @@ async function deployCommand(options) {
|
|
|
3799
3901
|
api,
|
|
3800
3902
|
"no_access",
|
|
3801
3903
|
repoFullName,
|
|
3802
|
-
{
|
|
3904
|
+
{
|
|
3905
|
+
yes: options.yes,
|
|
3906
|
+
installationId: githubInstallationId,
|
|
3907
|
+
reauth: () => promptReauthenticateOn401(options, resolvedOrgId)
|
|
3908
|
+
}
|
|
3803
3909
|
);
|
|
3804
|
-
if (!configured) {
|
|
3910
|
+
if (!configured.ok) {
|
|
3805
3911
|
process.exit(0);
|
|
3806
3912
|
}
|
|
3913
|
+
api = configured.api;
|
|
3807
3914
|
const retry = await checkRepoAccess(api, gitInfo.owner, gitInfo.repo);
|
|
3808
3915
|
if (!retry) {
|
|
3809
3916
|
const appName = await api.getGitHubAppName();
|