@kwonye/mcpx 0.1.99 → 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.
Files changed (40) hide show
  1. package/dist/{cli-28g7x9rn.js → cli-6wh8qx2y.js} +9 -3
  2. package/dist/{cli-dy7x0zrg.js → cli-6zq2fd6h.js} +1 -1
  3. package/dist/{cli-b0xrqsjc.js → cli-9k3wmag6.js} +286 -363
  4. package/dist/{cli-ct7asw78.js → cli-aawpvhhe.js} +13 -10
  5. package/dist/{cli-1ewrsfj4.js → cli-hh7rthhx.js} +4 -1
  6. package/dist/{cli-7x2n23em.js → cli-qzzjkt0q.js} +1132 -723
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +352 -88
  9. package/dist/{config-yx5m60fv.js → config-fbgyqmv1.js} +2 -2
  10. package/dist/core/auth-probe.d.ts +6 -1
  11. package/dist/core/auth-probe.d.ts.map +1 -1
  12. package/dist/core/daemon.d.ts +1 -0
  13. package/dist/core/daemon.d.ts.map +1 -1
  14. package/dist/core/identifiers.d.ts +3 -0
  15. package/dist/core/identifiers.d.ts.map +1 -0
  16. package/dist/core/index.d.ts +2 -2
  17. package/dist/core/index.d.ts.map +1 -1
  18. package/dist/core/index.js +22 -6
  19. package/dist/core/marketplace.d.ts.map +1 -1
  20. package/dist/core/oauth.d.ts +77 -2
  21. package/dist/core/oauth.d.ts.map +1 -1
  22. package/dist/core/paths.d.ts +1 -0
  23. package/dist/core/paths.d.ts.map +1 -1
  24. package/dist/core/plugin-cache.d.ts.map +1 -1
  25. package/dist/core/plugin-host.d.ts.map +1 -1
  26. package/dist/core/plugin-lifecycle.d.ts.map +1 -1
  27. package/dist/core/plugin-manager.d.ts.map +1 -1
  28. package/dist/core/plugin-parse.d.ts.map +1 -1
  29. package/dist/core/plugin-projections.d.ts.map +1 -1
  30. package/dist/core/plugin-source.d.ts.map +1 -1
  31. package/dist/core/secrets.d.ts.map +1 -1
  32. package/dist/core/skill-projections.d.ts.map +1 -1
  33. package/dist/core/skills.d.ts.map +1 -1
  34. package/dist/core/update-manager.d.ts.map +1 -1
  35. package/dist/gateway/server.d.ts.map +1 -1
  36. package/dist/{marketplace-pwabb3ea.js → marketplace-zem0m4mw.js} +5 -5
  37. package/dist/{plugin-host-9xcpnehq.js → plugin-host-5jmyt0td.js} +13 -39
  38. package/dist/{plugin-manager-19q55n69.js → plugin-manager-rw05c2x3.js} +4 -4
  39. package/dist/{registry-yvbxcaq6.js → registry-04kfpjh0.js} +2 -2
  40. 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-7x2n23em.js";
33
- import"./cli-ct7asw78.js";
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-b0xrqsjc.js";
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-dy7x0zrg.js";
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-1ewrsfj4.js";
69
+ } from "./cli-hh7rthhx.js";
66
70
  import {
67
71
  getConfigPath,
68
72
  getManagedIndexPath,
69
73
  getSecretsStorePath
70
- } from "./cli-28g7x9rn.js";
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
- await maybeConfigureHttpAuth(serverName, spec, secrets);
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
- return;
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
- const shouldConfigure = await promptLine(rl, "Configure auth now? (Y/n): ");
1378
- if (isNegativeChoice(shouldConfigure)) {
1379
- process.stdout.write(`Skipping auth setup.
1397
+ if (probe.oauthSupport === "supported") {
1398
+ process.stdout.write(`This server supports OAuth.
1380
1399
  `);
1381
- return;
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 system keychain instead? (Y/n): ");
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 keychain migration.
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(`Keychain migration skipped: ${error.message}
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 keychain secret "${selected.secretName}" too? (y/N): `)).toLowerCase();
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 action = await promptMenuSelection(rl, buildServerActionTitle(server), [
1934
- { label: "\uD83D\uDD10 Configure auth", detail: "Set or update auth binding for this MCP." },
1935
- { label: "♻️ Re-authenticate", detail: "Replace token for an existing auth binding." },
1936
- { label: "\uD83E\uDDF9 Clear authentication", detail: "Remove a specific auth binding." },
1937
- { label: server.enabled ? "⏸️ Disable" : "▶️ Enable", detail: "Toggle this MCP across mcpx and all synced clients." },
1938
- { label: "\uD83D\uDD04 Reconnect", detail: "Restart daemon and sync all managed client entries." },
1939
- { label: "← Back", detail: "Return to MCP list." }
1940
- ], "q");
1941
- if (action === null || action === 5) {
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
- if (action === 0) {
1946
- await configureServerAuthInteractively(rl, serverName, false);
1947
- } else if (action === 1) {
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 keychain-backed secrets");
2325
- secret.command("set <name>").option("--value <value>", "Secret value").description("Set secret in OS keychain").action((name, options) => {
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 secret from OS keychain").action((name) => {
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
- if (process.platform === "darwin") {
2360
- execFileSync("open", [url], { stdio: "ignore" });
2361
- return;
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("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 keychain secret name").option("--raw", "Do not auto-prefix Authorization values with Bearer").description("Store auth in keychain and bind it to an upstream server").action(async (server, options) => {
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 keychain secret when removing binding").description("Remove auth binding from an upstream server").action(async (server, options) => {
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 keychain secret deleted).
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-yx5m60fv.js");
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-yvbxcaq6.js");
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-yvbxcaq6.js");
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-19q55n69.js");
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-pwabb3ea.js");
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-19q55n69.js");
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-pwabb3ea.js");
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-pwabb3ea.js");
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-pwabb3ea.js");
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-pwabb3ea.js");
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-pwabb3ea.js");
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-pwabb3ea.js");
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-19q55n69.js");
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-19q55n69.js");
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-19q55n69.js");
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-19q55n69.js");
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-19q55n69.js");
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-19q55n69.js");
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-19q55n69.js");
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-19q55n69.js");
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-19q55n69.js");
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-9xcpnehq.js");
3158
+ const { runPluginHost } = await import("./plugin-host-5jmyt0td.js");
2895
3159
  runPluginHost(plugin, server);
2896
3160
  });
2897
3161
  }