@kwonye/mcpx 0.1.100 → 0.1.101
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/{cli-28g7x9rn.js → cli-6wh8qx2y.js} +9 -3
- package/dist/{cli-dy7x0zrg.js → cli-6zq2fd6h.js} +1 -1
- package/dist/{cli-b0xrqsjc.js → cli-9k3wmag6.js} +286 -363
- package/dist/{cli-ct7asw78.js → cli-aawpvhhe.js} +13 -10
- package/dist/{cli-1ewrsfj4.js → cli-hh7rthhx.js} +4 -1
- package/dist/{cli-etmrz2c4.js → cli-qzzjkt0q.js} +1120 -715
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +352 -88
- package/dist/{config-yx5m60fv.js → config-fbgyqmv1.js} +2 -2
- package/dist/core/auth-probe.d.ts +6 -1
- package/dist/core/auth-probe.d.ts.map +1 -1
- package/dist/core/daemon.d.ts.map +1 -1
- package/dist/core/identifiers.d.ts +3 -0
- package/dist/core/identifiers.d.ts.map +1 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +22 -6
- package/dist/core/marketplace.d.ts.map +1 -1
- package/dist/core/oauth.d.ts +77 -2
- package/dist/core/oauth.d.ts.map +1 -1
- package/dist/core/paths.d.ts +1 -0
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/plugin-cache.d.ts.map +1 -1
- package/dist/core/plugin-host.d.ts.map +1 -1
- package/dist/core/plugin-lifecycle.d.ts.map +1 -1
- package/dist/core/plugin-manager.d.ts.map +1 -1
- package/dist/core/plugin-parse.d.ts.map +1 -1
- package/dist/core/plugin-projections.d.ts.map +1 -1
- package/dist/core/plugin-source.d.ts.map +1 -1
- package/dist/core/secrets.d.ts.map +1 -1
- package/dist/core/skill-projections.d.ts.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/update-manager.d.ts.map +1 -1
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/{marketplace-pwabb3ea.js → marketplace-zem0m4mw.js} +5 -5
- package/dist/{plugin-host-9xcpnehq.js → plugin-host-5jmyt0td.js} +13 -39
- package/dist/{plugin-manager-19q55n69.js → plugin-manager-rw05c2x3.js} +4 -4
- package/dist/{registry-yvbxcaq6.js → registry-04kfpjh0.js} +2 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,15 +4,19 @@ import {
|
|
|
4
4
|
applyAuthReference,
|
|
5
5
|
buildStatusReport,
|
|
6
6
|
checkForUpdates,
|
|
7
|
+
clearOAuthCredentials,
|
|
7
8
|
defaultAuthSecretName,
|
|
8
9
|
extractRequiredInputs,
|
|
9
10
|
fetchRegistryServerDetail,
|
|
10
11
|
getDaemonStatus,
|
|
12
|
+
getOAuthCredentialStatus,
|
|
11
13
|
getStagedCliPath,
|
|
12
14
|
getStagedUpdate,
|
|
15
|
+
isOAuthReference,
|
|
13
16
|
listAuthBindings,
|
|
14
17
|
mapRegistryToSpec,
|
|
15
18
|
maybePrefixBearer,
|
|
19
|
+
oauthReferenceServerName,
|
|
16
20
|
performRollback,
|
|
17
21
|
performUpdate,
|
|
18
22
|
probeHttpAuthRequirement,
|
|
@@ -29,8 +33,8 @@ import {
|
|
|
29
33
|
startDaemon,
|
|
30
34
|
stopDaemon,
|
|
31
35
|
toSecretRef
|
|
32
|
-
} from "./cli-
|
|
33
|
-
import"./cli-
|
|
36
|
+
} from "./cli-qzzjkt0q.js";
|
|
37
|
+
import"./cli-aawpvhhe.js";
|
|
34
38
|
import {
|
|
35
39
|
APP_VERSION,
|
|
36
40
|
deleteSkill,
|
|
@@ -45,14 +49,14 @@ import {
|
|
|
45
49
|
persistSyncState,
|
|
46
50
|
saveSkill,
|
|
47
51
|
syncAllClients
|
|
48
|
-
} from "./cli-
|
|
52
|
+
} from "./cli-9k3wmag6.js";
|
|
49
53
|
import {
|
|
50
54
|
ConfigLoadError,
|
|
51
55
|
loadConfig,
|
|
52
56
|
loadMergedConfig,
|
|
53
57
|
loadProjectConfig,
|
|
54
58
|
resolveActiveConfig
|
|
55
|
-
} from "./cli-
|
|
59
|
+
} from "./cli-6zq2fd6h.js";
|
|
56
60
|
import {
|
|
57
61
|
SecretsManager,
|
|
58
62
|
addServer,
|
|
@@ -62,12 +66,12 @@ import {
|
|
|
62
66
|
removeServer,
|
|
63
67
|
rotateGatewayToken,
|
|
64
68
|
setServerEnabled
|
|
65
|
-
} from "./cli-
|
|
69
|
+
} from "./cli-hh7rthhx.js";
|
|
66
70
|
import {
|
|
67
71
|
getConfigPath,
|
|
68
72
|
getManagedIndexPath,
|
|
69
73
|
getSecretsStorePath
|
|
70
|
-
} from "./cli-
|
|
74
|
+
} from "./cli-6wh8qx2y.js";
|
|
71
75
|
import {
|
|
72
76
|
__require,
|
|
73
77
|
isServerEnabled
|
|
@@ -77,7 +81,7 @@ import {
|
|
|
77
81
|
import { Command } from "commander";
|
|
78
82
|
import fs from "node:fs";
|
|
79
83
|
import path from "node:path";
|
|
80
|
-
import { execFileSync } from "node:child_process";
|
|
84
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
81
85
|
import { pathToFileURL } from "node:url";
|
|
82
86
|
import { emitKeypressEvents } from "node:readline";
|
|
83
87
|
import { createInterface } from "node:readline/promises";
|
|
@@ -1195,7 +1199,13 @@ function parseAddServerSpec(values, options) {
|
|
|
1195
1199
|
throw new Error("Usage: mcpx add [--transport auto|http|stdio] <name> <url|command> [args...]");
|
|
1196
1200
|
}
|
|
1197
1201
|
const name = values[0] ?? "";
|
|
1202
|
+
if (!name.trim()) {
|
|
1203
|
+
throw new Error("Server name must be non-empty.");
|
|
1204
|
+
}
|
|
1198
1205
|
const target = values[1] ?? "";
|
|
1206
|
+
if (!target.trim()) {
|
|
1207
|
+
throw new Error("Server target (URL or command) must be non-empty.");
|
|
1208
|
+
}
|
|
1199
1209
|
const trailing = values.slice(2);
|
|
1200
1210
|
const requestedTransport = normalizeTransport(options.transport);
|
|
1201
1211
|
const transport = requestedTransport === "auto" ? isHttpUrl(target) && trailing.length === 0 ? "http" : "stdio" : requestedTransport;
|
|
@@ -1229,6 +1239,9 @@ function parseAddServerSpec(values, options) {
|
|
|
1229
1239
|
const [key, value] = parseEnvVar(item);
|
|
1230
1240
|
env[key] = value;
|
|
1231
1241
|
}
|
|
1242
|
+
if (options.cwd !== undefined && options.cwd !== null && !options.cwd.trim()) {
|
|
1243
|
+
throw new Error("--cwd must be non-empty when provided.");
|
|
1244
|
+
}
|
|
1232
1245
|
const spec = {
|
|
1233
1246
|
transport: "stdio",
|
|
1234
1247
|
command: target,
|
|
@@ -1249,6 +1262,9 @@ function redactAuthValue(value) {
|
|
|
1249
1262
|
if (value.startsWith("secret://")) {
|
|
1250
1263
|
return value;
|
|
1251
1264
|
}
|
|
1265
|
+
if (isOAuthReference(value)) {
|
|
1266
|
+
return value;
|
|
1267
|
+
}
|
|
1252
1268
|
return "<inline>";
|
|
1253
1269
|
}
|
|
1254
1270
|
function parseClientList(values) {
|
|
@@ -1348,15 +1364,15 @@ function isNegativeChoice(value) {
|
|
|
1348
1364
|
}
|
|
1349
1365
|
async function maybeAutoConfigureAuthForAddedServer(serverName, spec, secrets) {
|
|
1350
1366
|
if (spec.transport === "http") {
|
|
1351
|
-
|
|
1352
|
-
} else {
|
|
1353
|
-
await maybeConfigureStdioAuth(serverName, spec, secrets);
|
|
1367
|
+
return maybeConfigureHttpAuth(serverName, spec, secrets);
|
|
1354
1368
|
}
|
|
1369
|
+
await maybeConfigureStdioAuth(serverName, spec, secrets);
|
|
1370
|
+
return { deferredOAuthLogin: false };
|
|
1355
1371
|
}
|
|
1356
1372
|
async function maybeConfigureHttpAuth(serverName, spec, secrets) {
|
|
1357
1373
|
const probe = await probeHttpAuthRequirement(spec, secrets);
|
|
1358
1374
|
if (!probe.authRequired) {
|
|
1359
|
-
return;
|
|
1375
|
+
return { deferredOAuthLogin: false };
|
|
1360
1376
|
}
|
|
1361
1377
|
process.stdout.write(`Upstream "${serverName}" responded with ${probe.status ?? 401} and appears to require auth.
|
|
1362
1378
|
`);
|
|
@@ -1367,31 +1383,46 @@ async function maybeConfigureHttpAuth(serverName, spec, secrets) {
|
|
|
1367
1383
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
1368
1384
|
process.stdout.write(`Run \`mcpx auth set ${serverName} --header Authorization --value "<token>"\` to configure auth.
|
|
1369
1385
|
`);
|
|
1370
|
-
|
|
1386
|
+
if (probe.oauthSupport === "supported") {
|
|
1387
|
+
process.stdout.write(`This server supports OAuth -- run \`mcpx auth login ${serverName}\` to sign in with your browser instead.
|
|
1388
|
+
`);
|
|
1389
|
+
}
|
|
1390
|
+
return { deferredOAuthLogin: false };
|
|
1371
1391
|
}
|
|
1372
1392
|
const rl = createInterface({
|
|
1373
1393
|
input: process.stdin,
|
|
1374
1394
|
output: process.stdout
|
|
1375
1395
|
});
|
|
1376
1396
|
try {
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
process.stdout.write(`Skipping auth setup.
|
|
1397
|
+
if (probe.oauthSupport === "supported") {
|
|
1398
|
+
process.stdout.write(`This server supports OAuth.
|
|
1380
1399
|
`);
|
|
1381
|
-
|
|
1400
|
+
const useOAuth = await promptLine(rl, "Sign in with browser? (Y/n): ");
|
|
1401
|
+
if (!isNegativeChoice(useOAuth)) {
|
|
1402
|
+
process.stdout.write(`Will sign in with your browser once "${serverName}" is added.
|
|
1403
|
+
`);
|
|
1404
|
+
return { deferredOAuthLogin: true };
|
|
1405
|
+
}
|
|
1406
|
+
} else {
|
|
1407
|
+
const shouldConfigure = await promptLine(rl, "Configure auth now? (Y/n): ");
|
|
1408
|
+
if (isNegativeChoice(shouldConfigure)) {
|
|
1409
|
+
process.stdout.write(`Skipping auth setup.
|
|
1410
|
+
`);
|
|
1411
|
+
return { deferredOAuthLogin: false };
|
|
1412
|
+
}
|
|
1382
1413
|
}
|
|
1383
1414
|
const currentHeaderBinding = listAuthBindings(spec).find((binding) => binding.kind === "header");
|
|
1384
1415
|
const headerName = await promptLineWithDefault(rl, "Header name", currentHeaderBinding?.key ?? "Authorization");
|
|
1385
1416
|
if (!headerName) {
|
|
1386
1417
|
process.stdout.write(`Skipping auth setup (empty header name).
|
|
1387
1418
|
`);
|
|
1388
|
-
return;
|
|
1419
|
+
return { deferredOAuthLogin: false };
|
|
1389
1420
|
}
|
|
1390
1421
|
const authValueInput = await promptLine(rl, "Auth value/token (blank to skip): ");
|
|
1391
1422
|
if (!authValueInput) {
|
|
1392
1423
|
process.stdout.write(`Skipping auth setup.
|
|
1393
1424
|
`);
|
|
1394
|
-
return;
|
|
1425
|
+
return { deferredOAuthLogin: false };
|
|
1395
1426
|
}
|
|
1396
1427
|
const target = resolveAuthTarget(spec, headerName, undefined);
|
|
1397
1428
|
const authValue = maybePrefixBearer(target, authValueInput, false);
|
|
@@ -1401,7 +1432,7 @@ async function maybeConfigureHttpAuth(serverName, spec, secrets) {
|
|
|
1401
1432
|
if (!secretName) {
|
|
1402
1433
|
process.stdout.write(`Skipping auth setup (empty secret name).
|
|
1403
1434
|
`);
|
|
1404
|
-
return;
|
|
1435
|
+
return { deferredOAuthLogin: false };
|
|
1405
1436
|
}
|
|
1406
1437
|
secrets.setSecret(secretName, authValue);
|
|
1407
1438
|
applyAuthReference(spec, target, toSecretRef(secretName));
|
|
@@ -1410,7 +1441,7 @@ async function maybeConfigureHttpAuth(serverName, spec, secrets) {
|
|
|
1410
1441
|
} catch (error) {
|
|
1411
1442
|
process.stdout.write(`Auto auth setup skipped: ${error.message}
|
|
1412
1443
|
`);
|
|
1413
|
-
return;
|
|
1444
|
+
return { deferredOAuthLogin: false };
|
|
1414
1445
|
} finally {
|
|
1415
1446
|
rl.close();
|
|
1416
1447
|
}
|
|
@@ -1423,6 +1454,43 @@ async function maybeConfigureHttpAuth(serverName, spec, secrets) {
|
|
|
1423
1454
|
`);
|
|
1424
1455
|
} else {
|
|
1425
1456
|
process.stdout.write(`Auth check passed.
|
|
1457
|
+
`);
|
|
1458
|
+
}
|
|
1459
|
+
return { deferredOAuthLogin: false };
|
|
1460
|
+
}
|
|
1461
|
+
async function performOAuthLogout(serverName, spec, secrets) {
|
|
1462
|
+
const removedSecrets = clearOAuthCredentials(serverName, secrets);
|
|
1463
|
+
let removedBinding = null;
|
|
1464
|
+
if (spec.transport === "http" && spec.headers?.Authorization && isOAuthReference(spec.headers.Authorization) && oauthReferenceServerName(spec.headers.Authorization) === serverName) {
|
|
1465
|
+
await mutateConfig((freshConfig) => {
|
|
1466
|
+
const freshSpec = getServerSpecOrThrow(freshConfig, serverName);
|
|
1467
|
+
removeAuthReference(freshSpec, { kind: "header", key: "Authorization" });
|
|
1468
|
+
});
|
|
1469
|
+
removedBinding = "Authorization";
|
|
1470
|
+
}
|
|
1471
|
+
let sync;
|
|
1472
|
+
if (removedBinding) {
|
|
1473
|
+
const syncSourceConfig = loadConfig();
|
|
1474
|
+
sync = syncAllClients(syncSourceConfig, secrets);
|
|
1475
|
+
await mutateConfig((freshConfig) => {
|
|
1476
|
+
persistSyncState(sync, freshConfig);
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
return { removedSecrets, removedBinding, sync };
|
|
1480
|
+
}
|
|
1481
|
+
async function runDeferredOAuthLogin(serverName, spec, secrets, configPath) {
|
|
1482
|
+
try {
|
|
1483
|
+
await runOAuthLogin(serverName, spec, secrets, (url) => {
|
|
1484
|
+
process.stdout.write(`Opening browser to sign in to "${serverName}"...
|
|
1485
|
+
`);
|
|
1486
|
+
openInBrowser(url);
|
|
1487
|
+
}, configPath);
|
|
1488
|
+
process.stdout.write(`OAuth login complete for "${serverName}".
|
|
1489
|
+
`);
|
|
1490
|
+
} catch (error) {
|
|
1491
|
+
process.stdout.write(`OAuth sign-in failed: ${error instanceof Error ? error.message : String(error)}
|
|
1492
|
+
`);
|
|
1493
|
+
process.stdout.write(`Run \`mcpx auth login ${serverName}\` to try again.
|
|
1426
1494
|
`);
|
|
1427
1495
|
}
|
|
1428
1496
|
}
|
|
@@ -1444,9 +1512,9 @@ async function maybeConfigureStdioAuth(serverName, spec, secrets) {
|
|
|
1444
1512
|
output: process.stdout
|
|
1445
1513
|
});
|
|
1446
1514
|
try {
|
|
1447
|
-
const shouldMigrate = await promptLine(rl, "Store them in the
|
|
1515
|
+
const shouldMigrate = await promptLine(rl, "Store them in the encrypted secret store instead? (Y/n): ");
|
|
1448
1516
|
if (isNegativeChoice(shouldMigrate)) {
|
|
1449
|
-
process.stdout.write(`Skipping
|
|
1517
|
+
process.stdout.write(`Skipping secret migration.
|
|
1450
1518
|
`);
|
|
1451
1519
|
return;
|
|
1452
1520
|
}
|
|
@@ -1459,7 +1527,7 @@ async function maybeConfigureStdioAuth(serverName, spec, secrets) {
|
|
|
1459
1527
|
`);
|
|
1460
1528
|
}
|
|
1461
1529
|
} catch (error) {
|
|
1462
|
-
process.stdout.write(`
|
|
1530
|
+
process.stdout.write(`Secret migration skipped: ${error.message}
|
|
1463
1531
|
`);
|
|
1464
1532
|
} finally {
|
|
1465
1533
|
rl.close();
|
|
@@ -1803,7 +1871,7 @@ async function clearServerAuthInteractively(rl, serverName) {
|
|
|
1803
1871
|
}
|
|
1804
1872
|
let shouldDeleteSecret = false;
|
|
1805
1873
|
if (selected.secretName) {
|
|
1806
|
-
const shouldDelete = (await promptLine(rl, `Delete
|
|
1874
|
+
const shouldDelete = (await promptLine(rl, `Delete stored secret "${selected.secretName}" too? (y/N): `)).toLowerCase();
|
|
1807
1875
|
shouldDeleteSecret = shouldDelete === "y" || shouldDelete === "yes";
|
|
1808
1876
|
}
|
|
1809
1877
|
const removed = await mutateConfig((freshConfig) => {
|
|
@@ -1830,6 +1898,38 @@ async function clearServerAuthInteractively(rl, serverName) {
|
|
|
1830
1898
|
`);
|
|
1831
1899
|
}
|
|
1832
1900
|
}
|
|
1901
|
+
async function signInWithBrowserInteractively(serverName) {
|
|
1902
|
+
const config = loadConfig();
|
|
1903
|
+
const spec = getServerSpecOrThrow(config, serverName);
|
|
1904
|
+
if (spec.transport !== "http") {
|
|
1905
|
+
process.stdout.write(`OAuth login only supports HTTP servers.
|
|
1906
|
+
`);
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
const secrets = new SecretsManager;
|
|
1910
|
+
await runOAuthLogin(serverName, spec, secrets, (url) => {
|
|
1911
|
+
process.stdout.write(`Opening browser to sign in to "${serverName}"...
|
|
1912
|
+
`);
|
|
1913
|
+
openInBrowser(url);
|
|
1914
|
+
});
|
|
1915
|
+
process.stdout.write(`OAuth login complete for "${serverName}".
|
|
1916
|
+
`);
|
|
1917
|
+
}
|
|
1918
|
+
async function signOutInteractively(rl, serverName) {
|
|
1919
|
+
const confirmation = await promptLine(rl, `Sign out of "${serverName}"? (y/N): `);
|
|
1920
|
+
if (!["y", "yes"].includes(confirmation.trim().toLowerCase())) {
|
|
1921
|
+
process.stdout.write(`Cancelled.
|
|
1922
|
+
`);
|
|
1923
|
+
return;
|
|
1924
|
+
}
|
|
1925
|
+
const config = loadConfig();
|
|
1926
|
+
const spec = getServerSpecOrThrow(config, serverName);
|
|
1927
|
+
const secrets = new SecretsManager;
|
|
1928
|
+
const { removedSecrets, removedBinding } = await performOAuthLogout(serverName, spec, secrets);
|
|
1929
|
+
const bindingNote = removedBinding ? ` and the ${removedBinding} binding` : "";
|
|
1930
|
+
process.stdout.write(`Signed out of "${serverName}". Removed ${removedSecrets.length} stored credential${removedSecrets.length === 1 ? "" : "s"}${bindingNote}.
|
|
1931
|
+
`);
|
|
1932
|
+
}
|
|
1833
1933
|
async function reconnectGatewayAndSync(cliPath) {
|
|
1834
1934
|
const config = loadConfig();
|
|
1835
1935
|
const secrets = new SecretsManager;
|
|
@@ -1930,31 +2030,55 @@ async function runServerActionsMenu(rl, serverName, cliPath) {
|
|
|
1930
2030
|
`);
|
|
1931
2031
|
return;
|
|
1932
2032
|
}
|
|
1933
|
-
const
|
|
1934
|
-
|
|
1935
|
-
{
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
]
|
|
1941
|
-
if (
|
|
2033
|
+
const isOAuthBound = server.authBindings.some((binding) => binding.kind === "header" && binding.key === "Authorization" && isOAuthReference(binding.value));
|
|
2034
|
+
const actions = [
|
|
2035
|
+
{
|
|
2036
|
+
label: "\uD83D\uDD10 Configure auth",
|
|
2037
|
+
detail: "Set or update auth binding for this MCP.",
|
|
2038
|
+
run: () => configureServerAuthInteractively(rl, serverName, false)
|
|
2039
|
+
}
|
|
2040
|
+
];
|
|
2041
|
+
if (server.transport === "http" && !isOAuthBound) {
|
|
2042
|
+
actions.push({
|
|
2043
|
+
label: "\uD83C\uDF10 Sign in with browser",
|
|
2044
|
+
detail: "Run OAuth login for this MCP.",
|
|
2045
|
+
run: () => signInWithBrowserInteractively(serverName)
|
|
2046
|
+
});
|
|
2047
|
+
}
|
|
2048
|
+
actions.push({
|
|
2049
|
+
label: "♻️ Re-authenticate",
|
|
2050
|
+
detail: "Replace token for an existing auth binding.",
|
|
2051
|
+
run: () => configureServerAuthInteractively(rl, serverName, true)
|
|
2052
|
+
});
|
|
2053
|
+
if (isOAuthBound) {
|
|
2054
|
+
actions.push({
|
|
2055
|
+
label: "\uD83D\uDEAA Sign out",
|
|
2056
|
+
detail: "Clear stored OAuth credentials for this MCP.",
|
|
2057
|
+
run: () => signOutInteractively(rl, serverName)
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
actions.push({
|
|
2061
|
+
label: "\uD83E\uDDF9 Clear authentication",
|
|
2062
|
+
detail: "Remove a specific auth binding.",
|
|
2063
|
+
run: () => clearServerAuthInteractively(rl, serverName)
|
|
2064
|
+
}, {
|
|
2065
|
+
label: server.enabled ? "⏸️ Disable" : "▶️ Enable",
|
|
2066
|
+
detail: "Toggle this MCP across mcpx and all synced clients.",
|
|
2067
|
+
run: () => setServerEnabledInteractively(rl, serverName, !server.enabled, cliPath)
|
|
2068
|
+
}, {
|
|
2069
|
+
label: "\uD83D\uDD04 Reconnect",
|
|
2070
|
+
detail: "Restart daemon and sync all managed client entries.",
|
|
2071
|
+
run: () => reconnectGatewayAndSync(cliPath)
|
|
2072
|
+
});
|
|
2073
|
+
const backIndex = actions.length;
|
|
2074
|
+
const selection = await promptMenuSelection(rl, buildServerActionTitle(server), [...actions.map(({ label, detail }) => ({ label, detail })), { label: "← Back", detail: "Return to MCP list." }], "q");
|
|
2075
|
+
if (selection === null || selection === backIndex) {
|
|
1942
2076
|
return;
|
|
1943
2077
|
}
|
|
1944
2078
|
try {
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
await configureServerAuthInteractively(rl, serverName, true);
|
|
1949
|
-
} else if (action === 2) {
|
|
1950
|
-
await clearServerAuthInteractively(rl, serverName);
|
|
1951
|
-
} else if (action === 3) {
|
|
1952
|
-
const updated = await setServerEnabledInteractively(rl, serverName, !server.enabled, cliPath);
|
|
1953
|
-
if (updated) {
|
|
1954
|
-
return;
|
|
1955
|
-
}
|
|
1956
|
-
} else if (action === 4) {
|
|
1957
|
-
await reconnectGatewayAndSync(cliPath);
|
|
2079
|
+
const shouldClose = await actions[selection].run();
|
|
2080
|
+
if (shouldClose === true) {
|
|
2081
|
+
return;
|
|
1958
2082
|
}
|
|
1959
2083
|
} catch (error) {
|
|
1960
2084
|
process.stdout.write(`${error.message}
|
|
@@ -2079,8 +2203,8 @@ Value: ` : `${input.name} (${input.kind}): `;
|
|
|
2079
2203
|
spec.env = Object.keys(env).length > 0 ? env : undefined;
|
|
2080
2204
|
}
|
|
2081
2205
|
}
|
|
2082
|
-
await maybeAutoConfigureAuthForAddedServer(shortName, spec, secrets);
|
|
2083
|
-
const { type, projectPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2206
|
+
const authSetup = await maybeAutoConfigureAuthForAddedServer(shortName, spec, secrets);
|
|
2207
|
+
const { type, projectPath, configPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2084
2208
|
addServer(config, shortName, spec, options.force ?? false);
|
|
2085
2209
|
});
|
|
2086
2210
|
if (type === "project" && projectPath) {
|
|
@@ -2090,10 +2214,13 @@ Value: ` : `${input.name} (${input.kind}): `;
|
|
|
2090
2214
|
}
|
|
2091
2215
|
process.stdout.write(`Added server: ${shortName} (${spec.transport}) from registry "${registryName}"${type === "project" ? ` (project: ${projectPath})` : ""}
|
|
2092
2216
|
`);
|
|
2217
|
+
if (authSetup.deferredOAuthLogin && spec.transport === "http") {
|
|
2218
|
+
await runDeferredOAuthLogin(shortName, spec, secrets, configPath);
|
|
2219
|
+
}
|
|
2093
2220
|
} else {
|
|
2094
2221
|
const parsed = parseAddServerSpec(safeValues, options);
|
|
2095
|
-
await maybeAutoConfigureAuthForAddedServer(parsed.name, parsed.spec, secrets);
|
|
2096
|
-
const { type, projectPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2222
|
+
const authSetup = await maybeAutoConfigureAuthForAddedServer(parsed.name, parsed.spec, secrets);
|
|
2223
|
+
const { type, projectPath, configPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2097
2224
|
addServer(config, parsed.name, parsed.spec, options.force ?? false);
|
|
2098
2225
|
});
|
|
2099
2226
|
if (type === "project" && projectPath) {
|
|
@@ -2103,6 +2230,9 @@ Value: ` : `${input.name} (${input.kind}): `;
|
|
|
2103
2230
|
}
|
|
2104
2231
|
process.stdout.write(`Added server: ${parsed.name} (${parsed.spec.transport})${type === "project" ? ` (project: ${projectPath})` : ""}
|
|
2105
2232
|
`);
|
|
2233
|
+
if (authSetup.deferredOAuthLogin && parsed.spec.transport === "http") {
|
|
2234
|
+
await runDeferredOAuthLogin(parsed.name, parsed.spec, secrets, configPath);
|
|
2235
|
+
}
|
|
2106
2236
|
}
|
|
2107
2237
|
process.stdout.write(`Auto-syncing managed gateway entries across all supported clients...
|
|
2108
2238
|
`);
|
|
@@ -2114,6 +2244,9 @@ function registerRemoveCommand(parent, cliPath) {
|
|
|
2114
2244
|
const { type, projectPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2115
2245
|
removeServer(config, name, options.force ?? false);
|
|
2116
2246
|
});
|
|
2247
|
+
if (type === "global") {
|
|
2248
|
+
clearOAuthCredentials(name, new SecretsManager);
|
|
2249
|
+
}
|
|
2117
2250
|
process.stdout.write(`Removed server: ${name} ${type === "project" ? `from project: ${projectPath}` : "globally"}
|
|
2118
2251
|
`);
|
|
2119
2252
|
process.stdout.write(`Auto-syncing managed gateway entries across all supported clients...
|
|
@@ -2321,14 +2454,14 @@ function registerDaemonCommands(program) {
|
|
|
2321
2454
|
});
|
|
2322
2455
|
}
|
|
2323
2456
|
function registerSecretsCommands(program) {
|
|
2324
|
-
const secret = program.command("secret").description("Manage
|
|
2325
|
-
secret.command("set <name>").option("--value <value>", "Secret value").description("Set
|
|
2457
|
+
const secret = program.command("secret").description("Manage encrypted secrets");
|
|
2458
|
+
secret.command("set <name>").option("--value <value>", "Secret value").description("Set an encrypted secret").action((name, options) => {
|
|
2326
2459
|
const value = options.value ?? readSecretValueFromStdin();
|
|
2327
2460
|
new SecretsManager().setSecret(name, value);
|
|
2328
2461
|
process.stdout.write(`Secret set: ${name}
|
|
2329
2462
|
`);
|
|
2330
2463
|
});
|
|
2331
|
-
secret.command("rm <name>").description("Remove
|
|
2464
|
+
secret.command("rm <name>").description("Remove an encrypted secret").action((name) => {
|
|
2332
2465
|
new SecretsManager().removeSecret(name);
|
|
2333
2466
|
process.stdout.write(`Secret removed: ${name}
|
|
2334
2467
|
`);
|
|
@@ -2346,6 +2479,21 @@ function registerSecretsCommands(program) {
|
|
|
2346
2479
|
}
|
|
2347
2480
|
});
|
|
2348
2481
|
}
|
|
2482
|
+
function openInBrowser(url) {
|
|
2483
|
+
const [command, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
|
|
2484
|
+
const printFallback = () => {
|
|
2485
|
+
process.stdout.write(`Could not open a browser automatically. Open this URL to continue:
|
|
2486
|
+
${url}
|
|
2487
|
+
`);
|
|
2488
|
+
};
|
|
2489
|
+
try {
|
|
2490
|
+
const child = spawn(command, args, { detached: true, stdio: "ignore" });
|
|
2491
|
+
child.on("error", printFallback);
|
|
2492
|
+
child.unref();
|
|
2493
|
+
} catch {
|
|
2494
|
+
printFallback();
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2349
2497
|
function registerAuthCommands(program) {
|
|
2350
2498
|
const auth = program.command("auth").description("Auth utilities");
|
|
2351
2499
|
auth.command("login <server>").description("Run browser OAuth login for an HTTP upstream server").action(async (server) => {
|
|
@@ -2356,20 +2504,49 @@ function registerAuthCommands(program) {
|
|
|
2356
2504
|
}
|
|
2357
2505
|
const secrets = new SecretsManager;
|
|
2358
2506
|
await runOAuthLogin(server, spec, secrets, (url) => {
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
}
|
|
2363
|
-
if (process.platform === "win32") {
|
|
2364
|
-
execFileSync("cmd", ["/c", "start", "", url], { stdio: "ignore" });
|
|
2365
|
-
return;
|
|
2366
|
-
}
|
|
2367
|
-
execFileSync("xdg-open", [url], { stdio: "ignore" });
|
|
2507
|
+
process.stdout.write(`Opening browser to sign in to "${server}"...
|
|
2508
|
+
`);
|
|
2509
|
+
openInBrowser(url);
|
|
2368
2510
|
});
|
|
2369
2511
|
process.stdout.write(`OAuth login complete for "${server}".
|
|
2370
2512
|
`);
|
|
2371
2513
|
});
|
|
2372
|
-
auth.command("
|
|
2514
|
+
auth.command("logout <server>").option("-y, --yes", "Skip confirmation prompt").option("--json", "Output JSON").description("Sign out of OAuth for a server and clear stored credentials").action(async (server, options) => {
|
|
2515
|
+
const config = loadConfig();
|
|
2516
|
+
const spec = getServerSpecOrThrow(config, server);
|
|
2517
|
+
if (!options.yes) {
|
|
2518
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
2519
|
+
throw new Error("Sign-out requires --yes in non-interactive mode.");
|
|
2520
|
+
}
|
|
2521
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
2522
|
+
try {
|
|
2523
|
+
const answer = await promptLine(rl, `Sign out of "${server}"? (y/N): `);
|
|
2524
|
+
if (!["y", "yes"].includes(answer.trim().toLowerCase())) {
|
|
2525
|
+
return;
|
|
2526
|
+
}
|
|
2527
|
+
} finally {
|
|
2528
|
+
rl.close();
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
const secrets = new SecretsManager;
|
|
2532
|
+
const { removedSecrets, removedBinding, sync } = await performOAuthLogout(server, spec, secrets);
|
|
2533
|
+
if (options.json) {
|
|
2534
|
+
process.stdout.write(`${JSON.stringify({ server, removedSecrets, removedBinding, sync }, null, 2)}
|
|
2535
|
+
`);
|
|
2536
|
+
return;
|
|
2537
|
+
}
|
|
2538
|
+
if (removedSecrets.length === 0 && !removedBinding) {
|
|
2539
|
+
process.stdout.write(`"${server}" was not signed in with OAuth. Nothing to do.
|
|
2540
|
+
`);
|
|
2541
|
+
return;
|
|
2542
|
+
}
|
|
2543
|
+
const bindingNote = removedBinding ? ` and the ${removedBinding} binding` : "";
|
|
2544
|
+
process.stdout.write(`Signed out of "${server}". Removed ${removedSecrets.length} stored credential${removedSecrets.length === 1 ? "" : "s"}${bindingNote}.
|
|
2545
|
+
`);
|
|
2546
|
+
process.stdout.write(`Re-run \`mcpx auth login ${server}\` to sign back in.
|
|
2547
|
+
`);
|
|
2548
|
+
});
|
|
2549
|
+
auth.command("set <server>").option("--header <name>", "HTTP header name (default for HTTP servers: Authorization)").option("--env <name>", "Env var name (required for stdio servers)").option("--value <value>", "Auth value/token (if omitted, read from stdin)").option("--secret-name <name>", "Override stored secret name").option("--raw", "Do not auto-prefix Authorization values with Bearer").description("Store auth as an encrypted secret and bind it to an upstream server").action(async (server, options) => {
|
|
2373
2550
|
const config = loadConfig();
|
|
2374
2551
|
const spec = getServerSpecOrThrow(config, server);
|
|
2375
2552
|
const target = resolveAuthTarget(spec, options.header, options.env);
|
|
@@ -2387,7 +2564,7 @@ function registerAuthCommands(program) {
|
|
|
2387
2564
|
process.stdout.write(`Stored secret: ${secretName}
|
|
2388
2565
|
`);
|
|
2389
2566
|
});
|
|
2390
|
-
auth.command("rm <server>").option("--header <name>", "HTTP header name (default for HTTP servers: Authorization)").option("--env <name>", "Env var name (required for stdio servers)").option("--delete-secret", "Delete referenced
|
|
2567
|
+
auth.command("rm <server>").option("--header <name>", "HTTP header name (default for HTTP servers: Authorization)").option("--env <name>", "Env var name (required for stdio servers)").option("--delete-secret", "Delete the referenced stored secret when removing binding").description("Remove auth binding from an upstream server").action(async (server, options) => {
|
|
2391
2568
|
const config = loadConfig();
|
|
2392
2569
|
const spec = getServerSpecOrThrow(config, server);
|
|
2393
2570
|
const target = resolveAuthTarget(spec, options.header, options.env);
|
|
@@ -2405,9 +2582,15 @@ function registerAuthCommands(program) {
|
|
|
2405
2582
|
if (secretName) {
|
|
2406
2583
|
new SecretsManager().removeSecret(secretName);
|
|
2407
2584
|
process.stdout.write(`Removed binding and deleted secret: ${secretName}
|
|
2585
|
+
`);
|
|
2586
|
+
} else if (isOAuthReference(removedValue)) {
|
|
2587
|
+
const removed = clearOAuthCredentials(oauthReferenceServerName(removedValue), new SecretsManager);
|
|
2588
|
+
process.stdout.write(`Removed binding and deleted ${removed.length} OAuth credential${removed.length === 1 ? "" : "s"}.
|
|
2589
|
+
`);
|
|
2590
|
+
process.stdout.write(`(Equivalent to \`mcpx auth logout ${server}\`.)
|
|
2408
2591
|
`);
|
|
2409
2592
|
} else {
|
|
2410
|
-
process.stdout.write(`Removed binding. Value was inline (no
|
|
2593
|
+
process.stdout.write(`Removed binding. Value was inline (no stored secret deleted).
|
|
2411
2594
|
`);
|
|
2412
2595
|
}
|
|
2413
2596
|
} else {
|
|
@@ -2455,6 +2638,78 @@ function registerAuthCommands(program) {
|
|
|
2455
2638
|
}
|
|
2456
2639
|
}
|
|
2457
2640
|
});
|
|
2641
|
+
auth.command("status [server]").option("--json", "Output JSON").description("Show OAuth sign-in and token/secret auth status (offline, no network calls)").action((server, options) => {
|
|
2642
|
+
const config = loadConfig();
|
|
2643
|
+
const names = server ? [server] : Object.keys(config.servers);
|
|
2644
|
+
const secrets = new SecretsManager;
|
|
2645
|
+
const entries = names.map((name) => {
|
|
2646
|
+
const spec = getServerSpecOrThrow(config, name);
|
|
2647
|
+
const oauth = getOAuthCredentialStatus(name, spec, secrets);
|
|
2648
|
+
const bindings = listAuthBindings(spec).map((binding) => {
|
|
2649
|
+
if (isOAuthReference(binding.value)) {
|
|
2650
|
+
return { kind: binding.kind, key: binding.key, source: "oauth", secretName: null, secretPresent: null };
|
|
2651
|
+
}
|
|
2652
|
+
const secretName = secretRefName(binding.value);
|
|
2653
|
+
if (secretName) {
|
|
2654
|
+
return { kind: binding.kind, key: binding.key, source: "secret", secretName, secretPresent: secrets.getSecret(secretName) !== null };
|
|
2655
|
+
}
|
|
2656
|
+
return { kind: binding.kind, key: binding.key, source: "inline", secretName: null, secretPresent: null };
|
|
2657
|
+
});
|
|
2658
|
+
return { server: name, transport: spec.transport, oauth, bindings };
|
|
2659
|
+
});
|
|
2660
|
+
if (options.json) {
|
|
2661
|
+
process.stdout.write(`${JSON.stringify({ servers: entries }, null, 2)}
|
|
2662
|
+
`);
|
|
2663
|
+
return;
|
|
2664
|
+
}
|
|
2665
|
+
if (entries.length === 0) {
|
|
2666
|
+
process.stdout.write(`No upstream servers configured.
|
|
2667
|
+
`);
|
|
2668
|
+
return;
|
|
2669
|
+
}
|
|
2670
|
+
const oauthEntries = entries.filter((e) => e.oauth.bound || e.oauth.signedIn);
|
|
2671
|
+
const secretRows = entries.flatMap((e) => e.bindings.filter((b) => b.source !== "oauth").map((b) => ({ entry: e, binding: b })));
|
|
2672
|
+
if (oauthEntries.length > 0) {
|
|
2673
|
+
process.stdout.write(`OAuth sign-ins
|
|
2674
|
+
`);
|
|
2675
|
+
for (const entry of oauthEntries) {
|
|
2676
|
+
process.stdout.write(`- ${entry.server} (${entry.transport})
|
|
2677
|
+
`);
|
|
2678
|
+
if (!entry.oauth.signedIn) {
|
|
2679
|
+
process.stdout.write(` status bound but not signed in — run \`mcpx auth login ${entry.server}\`
|
|
2680
|
+
`);
|
|
2681
|
+
continue;
|
|
2682
|
+
}
|
|
2683
|
+
process.stdout.write(` status ${entry.oauth.expired ? "expired" : "signed in"}
|
|
2684
|
+
`);
|
|
2685
|
+
if (entry.oauth.expiresAt) {
|
|
2686
|
+
process.stdout.write(` expires ${new Date(entry.oauth.expiresAt).toLocaleString()}
|
|
2687
|
+
`);
|
|
2688
|
+
}
|
|
2689
|
+
process.stdout.write(` refresh ${entry.oauth.hasRefreshToken ? "available" : `none — run \`mcpx auth login ${entry.server}\` to re-authenticate`}
|
|
2690
|
+
`);
|
|
2691
|
+
process.stdout.write(` client ${entry.oauth.clientRegistered ? "registered" : "not registered"}
|
|
2692
|
+
`);
|
|
2693
|
+
}
|
|
2694
|
+
process.stdout.write(`
|
|
2695
|
+
`);
|
|
2696
|
+
}
|
|
2697
|
+
if (secretRows.length > 0) {
|
|
2698
|
+
process.stdout.write(`Token / secret auth
|
|
2699
|
+
`);
|
|
2700
|
+
for (const { entry, binding } of secretRows) {
|
|
2701
|
+
const label = binding.source === "secret" ? `secret://${binding.secretName}${binding.secretPresent ? "" : " MISSING"}` : "<inline>";
|
|
2702
|
+
process.stdout.write(`- ${entry.server} (${entry.transport}) ${binding.kind}:${binding.key} ${label}
|
|
2703
|
+
`);
|
|
2704
|
+
}
|
|
2705
|
+
process.stdout.write(`
|
|
2706
|
+
`);
|
|
2707
|
+
}
|
|
2708
|
+
if (oauthEntries.length === 0 && secretRows.length === 0) {
|
|
2709
|
+
process.stdout.write(`No auth configured for any server.
|
|
2710
|
+
`);
|
|
2711
|
+
}
|
|
2712
|
+
});
|
|
2458
2713
|
auth.command("rotate-local-token").description("Rotate bearer token used for local client->mcpx auth").action(async () => {
|
|
2459
2714
|
const config = loadConfig();
|
|
2460
2715
|
const secrets = new SecretsManager;
|
|
@@ -2491,11 +2746,20 @@ function registerSkillsCommands(program) {
|
|
|
2491
2746
|
saveSkill(id, `# ${id}
|
|
2492
2747
|
|
|
2493
2748
|
Add your instructions here.`);
|
|
2749
|
+
const summary = syncAllClients(loadConfig(), new SecretsManager);
|
|
2750
|
+
await mutateConfig((config) => persistSyncState(summary, config));
|
|
2494
2751
|
process.stdout.write(`Skill "${id}" created.
|
|
2495
2752
|
`);
|
|
2496
2753
|
});
|
|
2497
|
-
skill.command("rm <id>").description("Remove a skill").action((id) => {
|
|
2754
|
+
skill.command("rm <id>").description("Remove a skill").action(async (id) => {
|
|
2755
|
+
if (!getSkill(id)) {
|
|
2756
|
+
process.stderr.write(`Skill "${id}" not found.
|
|
2757
|
+
`);
|
|
2758
|
+
process.exit(1);
|
|
2759
|
+
}
|
|
2498
2760
|
deleteSkill(id);
|
|
2761
|
+
const summary = syncAllClients(loadConfig(), new SecretsManager);
|
|
2762
|
+
await mutateConfig((config) => persistSyncState(summary, config));
|
|
2499
2763
|
process.stdout.write(`Skill "${id}" removed.
|
|
2500
2764
|
`);
|
|
2501
2765
|
});
|
|
@@ -2591,11 +2855,11 @@ function registerProjectCommands(program, cliPath) {
|
|
|
2591
2855
|
name: projectName,
|
|
2592
2856
|
servers: {}
|
|
2593
2857
|
};
|
|
2594
|
-
const { saveProjectConfig } = await import("./config-
|
|
2858
|
+
const { saveProjectConfig } = await import("./config-fbgyqmv1.js");
|
|
2595
2859
|
saveProjectConfig(localConfig, targetPath);
|
|
2596
2860
|
process.stdout.write(`Initialized project configuration at: ${targetPath}
|
|
2597
2861
|
`);
|
|
2598
|
-
const { registerProject: registerProject2 } = await import("./registry-
|
|
2862
|
+
const { registerProject: registerProject2 } = await import("./registry-04kfpjh0.js");
|
|
2599
2863
|
await mutateConfig((globalConfig) => {
|
|
2600
2864
|
registerProject2(globalConfig, process.cwd(), projectName);
|
|
2601
2865
|
});
|
|
@@ -2626,7 +2890,7 @@ function registerProjectCommands(program, cliPath) {
|
|
|
2626
2890
|
process.exit(1);
|
|
2627
2891
|
}
|
|
2628
2892
|
const entry = globalConfig.projects[resolvedPath];
|
|
2629
|
-
const { unregisterProject: unregisterProject2 } = await import("./registry-
|
|
2893
|
+
const { unregisterProject: unregisterProject2 } = await import("./registry-04kfpjh0.js");
|
|
2630
2894
|
await mutateConfig((freshConfig) => {
|
|
2631
2895
|
unregisterProject2(freshConfig, resolvedPath);
|
|
2632
2896
|
});
|
|
@@ -2640,7 +2904,7 @@ function registerProjectCommands(program, cliPath) {
|
|
|
2640
2904
|
function registerPluginCommands(program, _cliPath) {
|
|
2641
2905
|
const plugin = program.command("plugin").description("Manage plugins");
|
|
2642
2906
|
plugin.command("inspect <source>").description("Inspect plugin manifest and components").action(async (source) => {
|
|
2643
|
-
const { inspectPlugin } = await import("./plugin-manager-
|
|
2907
|
+
const { inspectPlugin } = await import("./plugin-manager-rw05c2x3.js");
|
|
2644
2908
|
try {
|
|
2645
2909
|
const info = await inspectPlugin(source);
|
|
2646
2910
|
process.stdout.write(JSON.stringify(info, null, 2) + `
|
|
@@ -2657,7 +2921,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2657
2921
|
const marketplaceName = source.includes("@") ? source.slice(source.lastIndexOf("@") + 1) : "";
|
|
2658
2922
|
let p;
|
|
2659
2923
|
if (config.marketplaces?.[marketplaceName]) {
|
|
2660
|
-
const { inspectMarketplacePlugin, installMarketplacePlugin } = await import("./marketplace-
|
|
2924
|
+
const { inspectMarketplacePlugin, installMarketplacePlugin } = await import("./marketplace-zem0m4mw.js");
|
|
2661
2925
|
const detail = await inspectMarketplacePlugin(source);
|
|
2662
2926
|
process.stdout.write(`${detail.displayName} (${source})
|
|
2663
2927
|
`);
|
|
@@ -2685,7 +2949,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2685
2949
|
}
|
|
2686
2950
|
p = await installMarketplacePlugin(source);
|
|
2687
2951
|
} else {
|
|
2688
|
-
const { installPlugin } = await import("./plugin-manager-
|
|
2952
|
+
const { installPlugin } = await import("./plugin-manager-rw05c2x3.js");
|
|
2689
2953
|
p = await installPlugin(source, { name: options.name, enabled: options.enable !== false });
|
|
2690
2954
|
}
|
|
2691
2955
|
process.stdout.write(`Plugin installed: ${p.id}
|
|
@@ -2698,13 +2962,13 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2698
2962
|
});
|
|
2699
2963
|
const marketplace = plugin.command("marketplace").description("Manage plugin marketplaces");
|
|
2700
2964
|
marketplace.command("list").description("List configured plugin marketplaces").action(async () => {
|
|
2701
|
-
const { listMarketplaces } = await import("./marketplace-
|
|
2965
|
+
const { listMarketplaces } = await import("./marketplace-zem0m4mw.js");
|
|
2702
2966
|
process.stdout.write(JSON.stringify(await listMarketplaces(), null, 2) + `
|
|
2703
2967
|
`);
|
|
2704
2968
|
});
|
|
2705
2969
|
marketplace.command("add <source>").option("--manifest <path>", "Marketplace manifest path inside the source").description("Add a Claude or Codex plugin marketplace").action(async (source, options) => {
|
|
2706
2970
|
try {
|
|
2707
|
-
const { addMarketplace } = await import("./marketplace-
|
|
2971
|
+
const { addMarketplace } = await import("./marketplace-zem0m4mw.js");
|
|
2708
2972
|
const added = await addMarketplace(source, options.manifest);
|
|
2709
2973
|
process.stdout.write(`Marketplace added: ${added.name}
|
|
2710
2974
|
`);
|
|
@@ -2716,7 +2980,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2716
2980
|
});
|
|
2717
2981
|
marketplace.command("update [name]").description("Refresh one marketplace, or every configured marketplace").action(async (name) => {
|
|
2718
2982
|
try {
|
|
2719
|
-
const { listMarketplaces, refreshMarketplaceWithPlugins } = await import("./marketplace-
|
|
2983
|
+
const { listMarketplaces, refreshMarketplaceWithPlugins } = await import("./marketplace-zem0m4mw.js");
|
|
2720
2984
|
const names = name ? [name] : (await listMarketplaces()).map((entry) => entry.name);
|
|
2721
2985
|
for (const marketplaceName of names) {
|
|
2722
2986
|
const result = await refreshMarketplaceWithPlugins(marketplaceName);
|
|
@@ -2746,7 +3010,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2746
3010
|
rl.close();
|
|
2747
3011
|
}
|
|
2748
3012
|
}
|
|
2749
|
-
const { removeMarketplace } = await import("./marketplace-
|
|
3013
|
+
const { removeMarketplace } = await import("./marketplace-zem0m4mw.js");
|
|
2750
3014
|
await removeMarketplace(name);
|
|
2751
3015
|
process.stdout.write(`Marketplace removed: ${name}
|
|
2752
3016
|
`);
|
|
@@ -2757,7 +3021,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2757
3021
|
}
|
|
2758
3022
|
});
|
|
2759
3023
|
plugin.command("discover [query]").option("--marketplace <name>", "Filter by marketplace").option("--category <category>", "Filter by category").description("Browse available marketplace plugins").action(async (query, options) => {
|
|
2760
|
-
const { listMarketplacePlugins } = await import("./marketplace-
|
|
3024
|
+
const { listMarketplacePlugins } = await import("./marketplace-zem0m4mw.js");
|
|
2761
3025
|
let listings = await listMarketplacePlugins(query);
|
|
2762
3026
|
if (options.marketplace)
|
|
2763
3027
|
listings = listings.filter((entry) => entry.marketplace === options.marketplace);
|
|
@@ -2768,7 +3032,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2768
3032
|
});
|
|
2769
3033
|
plugin.command("details <plugin>").description("Inspect a plugin@marketplace listing").action(async (qualified) => {
|
|
2770
3034
|
try {
|
|
2771
|
-
const { inspectMarketplacePlugin } = await import("./marketplace-
|
|
3035
|
+
const { inspectMarketplacePlugin } = await import("./marketplace-zem0m4mw.js");
|
|
2772
3036
|
process.stdout.write(JSON.stringify(await inspectMarketplacePlugin(qualified), null, 2) + `
|
|
2773
3037
|
`);
|
|
2774
3038
|
} catch (error) {
|
|
@@ -2778,7 +3042,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2778
3042
|
}
|
|
2779
3043
|
});
|
|
2780
3044
|
plugin.command("approve <name> <component>").description("Approve a plugin component (hooks, mcpServers)").action(async (name, component) => {
|
|
2781
|
-
const { approvePluginComponent } = await import("./plugin-manager-
|
|
3045
|
+
const { approvePluginComponent } = await import("./plugin-manager-rw05c2x3.js");
|
|
2782
3046
|
try {
|
|
2783
3047
|
await approvePluginComponent(name, component);
|
|
2784
3048
|
process.stdout.write(`Approved ${component} for plugin ${name}
|
|
@@ -2790,7 +3054,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2790
3054
|
}
|
|
2791
3055
|
});
|
|
2792
3056
|
plugin.command("prepare <name>").description("Install plugin dependencies").action(async (name) => {
|
|
2793
|
-
const { preparePlugin } = await import("./plugin-manager-
|
|
3057
|
+
const { preparePlugin } = await import("./plugin-manager-rw05c2x3.js");
|
|
2794
3058
|
try {
|
|
2795
3059
|
await preparePlugin(name);
|
|
2796
3060
|
process.stdout.write(`Plugin ${name} prepared
|
|
@@ -2802,7 +3066,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2802
3066
|
}
|
|
2803
3067
|
});
|
|
2804
3068
|
plugin.command("update <name>").description("Update plugin to latest version").action(async (name) => {
|
|
2805
|
-
const { updatePlugin } = await import("./plugin-manager-
|
|
3069
|
+
const { updatePlugin } = await import("./plugin-manager-rw05c2x3.js");
|
|
2806
3070
|
try {
|
|
2807
3071
|
const p = await updatePlugin(name);
|
|
2808
3072
|
process.stdout.write(`Plugin ${name} updated to ${p.version}
|
|
@@ -2814,7 +3078,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2814
3078
|
}
|
|
2815
3079
|
});
|
|
2816
3080
|
plugin.command("uninstall <name>").option("--keep-data", "Keep plugin data after uninstall").description("Uninstall plugin").action(async (name, options) => {
|
|
2817
|
-
const { uninstallPlugin } = await import("./plugin-manager-
|
|
3081
|
+
const { uninstallPlugin } = await import("./plugin-manager-rw05c2x3.js");
|
|
2818
3082
|
try {
|
|
2819
3083
|
await uninstallPlugin(name, options.keepData || false);
|
|
2820
3084
|
process.stdout.write(`Plugin ${name} uninstalled
|
|
@@ -2828,13 +3092,13 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2828
3092
|
plugin.command("enable <name>").option("--project <path>", "Scope this enable to a single registered project instead of globally").description("Enable plugin (globally, or for one project with --project)").action(async (name, options) => {
|
|
2829
3093
|
try {
|
|
2830
3094
|
if (options.project) {
|
|
2831
|
-
const { setPluginProjectOverride } = await import("./plugin-manager-
|
|
3095
|
+
const { setPluginProjectOverride } = await import("./plugin-manager-rw05c2x3.js");
|
|
2832
3096
|
const resolvedPath = path.resolve(options.project);
|
|
2833
3097
|
await setPluginProjectOverride(name, resolvedPath, { enabled: true });
|
|
2834
3098
|
process.stdout.write(`Plugin ${name} enabled for project: ${resolvedPath}
|
|
2835
3099
|
`);
|
|
2836
3100
|
} else {
|
|
2837
|
-
const { enablePlugin } = await import("./plugin-manager-
|
|
3101
|
+
const { enablePlugin } = await import("./plugin-manager-rw05c2x3.js");
|
|
2838
3102
|
await enablePlugin(name);
|
|
2839
3103
|
process.stdout.write(`Plugin ${name} enabled
|
|
2840
3104
|
`);
|
|
@@ -2848,13 +3112,13 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2848
3112
|
plugin.command("disable <name>").option("--project <path>", "Scope this disable to a single registered project instead of globally").description("Disable plugin (globally, or for one project with --project)").action(async (name, options) => {
|
|
2849
3113
|
try {
|
|
2850
3114
|
if (options.project) {
|
|
2851
|
-
const { setPluginProjectOverride } = await import("./plugin-manager-
|
|
3115
|
+
const { setPluginProjectOverride } = await import("./plugin-manager-rw05c2x3.js");
|
|
2852
3116
|
const resolvedPath = path.resolve(options.project);
|
|
2853
3117
|
await setPluginProjectOverride(name, resolvedPath, { enabled: false });
|
|
2854
3118
|
process.stdout.write(`Plugin ${name} disabled for project: ${resolvedPath}
|
|
2855
3119
|
`);
|
|
2856
3120
|
} else {
|
|
2857
|
-
const { disablePlugin } = await import("./plugin-manager-
|
|
3121
|
+
const { disablePlugin } = await import("./plugin-manager-rw05c2x3.js");
|
|
2858
3122
|
await disablePlugin(name);
|
|
2859
3123
|
process.stdout.write(`Plugin ${name} disabled
|
|
2860
3124
|
`);
|
|
@@ -2866,7 +3130,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2866
3130
|
}
|
|
2867
3131
|
});
|
|
2868
3132
|
plugin.command("status [name]").description("Show plugin status").action(async (name) => {
|
|
2869
|
-
const { getPluginStatus, listPlugins } = await import("./plugin-manager-
|
|
3133
|
+
const { getPluginStatus, listPlugins } = await import("./plugin-manager-rw05c2x3.js");
|
|
2870
3134
|
try {
|
|
2871
3135
|
if (name) {
|
|
2872
3136
|
const p = await getPluginStatus(name);
|
|
@@ -2891,7 +3155,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2891
3155
|
}
|
|
2892
3156
|
function registerPluginHostCommand(program) {
|
|
2893
3157
|
program.command("plugin-host <plugin> <server>").description("Run a plugin MCP server under mcpx policy enforcement").action(async (plugin, server) => {
|
|
2894
|
-
const { runPluginHost } = await import("./plugin-host-
|
|
3158
|
+
const { runPluginHost } = await import("./plugin-host-5jmyt0td.js");
|
|
2895
3159
|
runPluginHost(plugin, server);
|
|
2896
3160
|
});
|
|
2897
3161
|
}
|