@mcpcloud/cli 0.26.0 → 0.27.0
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/README.md +7 -1
- package/dist/index.js +408 -75
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -507,9 +507,12 @@ _Generated from the live command tree by `bun run docs:readme` — do not edit b
|
|
|
507
507
|
| `mcp servers deps add <server> <child>` | Compose <child>'s tools into <server>. Both accept an id, name or slug. |
|
|
508
508
|
| `mcp servers deps list [server]` | List the servers this one composes. |
|
|
509
509
|
| `mcp servers deps rm <server> <dependencyId>` | Remove a composed dependency (id from `deps list`). |
|
|
510
|
-
| `mcp servers end-user` | Read and set a server's end-user plane: the access switch
|
|
510
|
+
| `mcp servers end-user` | Read and set a server's end-user plane: the access switch, the tool allowlist customers may call, and how they sign in. |
|
|
511
511
|
| `mcp servers end-user get <server>` | Show the end-user access configuration: switch, connect page, allowed tools, branding, and how customers sign in. |
|
|
512
512
|
| `mcp servers end-user set <server>` | Enable or disable end-user access, and/or replace the tool allowlist. |
|
|
513
|
+
| `mcp servers end-user sign-in` | How customers sign in: the one mode, and the settings of the chosen one. |
|
|
514
|
+
| `mcp servers end-user sign-in get <server>` | Show the chosen sign-in mode, the door customers actually meet, and each mode’s settings. |
|
|
515
|
+
| `mcp servers end-user sign-in set <server>` | Choose how customers sign in and set its settings. Sends only what the flags name; choosing a mode turns the others off. |
|
|
513
516
|
| `mcp servers env` | Manage server runtime environment bindings (encrypted secrets injected by the proxy). |
|
|
514
517
|
| `mcp servers env get <server> <bindingName>` | Show metadata for one env binding. Plaintext is never returned — values are write-only. |
|
|
515
518
|
| `mcp servers env list <server>` | List a server's env bindings (metadata only; values are never returned). |
|
|
@@ -531,6 +534,9 @@ _Generated from the live command tree by `bun run docs:readme` — do not edit b
|
|
|
531
534
|
| `mcp servers ingest` | Create a server from an OpenAPI spec (file, URL, or @- stdin) or a GraphQL endpoint. Wraps POST /api/v1/server/ingest. |
|
|
532
535
|
| `mcp servers list` | List servers |
|
|
533
536
|
| `mcp servers logs <server>` | Show recent deployment events for a server's latest deployment |
|
|
537
|
+
| `mcp servers oauth` | Read and set a server's OAuth provider: the endpoints, client credentials, scopes and tool coverage it uses for delegated authorization. |
|
|
538
|
+
| `mcp servers oauth get <server>` | Show the OAuth provider: status, endpoints, client id, whether a secret is on file, scopes, tool coverage, and the callback URL to register. |
|
|
539
|
+
| `mcp servers oauth set <server>` | Set the OAuth provider. Partial: a flag left off keeps what is stored. |
|
|
534
540
|
| `mcp servers oauth-connections <server>` | List OAuth provider connections bound to this server |
|
|
535
541
|
| `mcp servers pause <server>` | Pause the server's latest active deployment (traffic stops; worker is preserved) |
|
|
536
542
|
| `mcp servers promote <server>` | Ship the bytes a lane is serving into another lane. Config, secrets and member credentials stay with the target. |
|
package/dist/index.js
CHANGED
|
@@ -6243,9 +6243,20 @@ function registerServerShapingCommands(servers) {
|
|
|
6243
6243
|
}
|
|
6244
6244
|
|
|
6245
6245
|
// src/commands/servers-end-user.ts
|
|
6246
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
6247
|
+
|
|
6248
|
+
// src/commands/servers-end-user-sign-in.ts
|
|
6246
6249
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
6247
6250
|
var END_USER_PATH = "/api/v1/server/end-user-access";
|
|
6248
|
-
|
|
6251
|
+
var CUSTOMER_SIGN_IN_PATH = "/api/v1/server/customer-sign-in";
|
|
6252
|
+
var MODES = ["account", "page", "upstream", "federation"];
|
|
6253
|
+
var MODE_LABEL = {
|
|
6254
|
+
account: "an MCPCloud account",
|
|
6255
|
+
page: "sign-in on your page",
|
|
6256
|
+
upstream: "your OAuth provider",
|
|
6257
|
+
federation: "your own sign-in (federation)"
|
|
6258
|
+
};
|
|
6259
|
+
async function readSignIn(serverRef, opts) {
|
|
6249
6260
|
const orgId = await resolveOrgId(opts.org);
|
|
6250
6261
|
const serverId = await resolveServerId(serverRef, orgId, undefined);
|
|
6251
6262
|
return await api.get(END_USER_PATH, {
|
|
@@ -6253,6 +6264,164 @@ async function readEndUserAccess(serverRef, opts) {
|
|
|
6253
6264
|
serverId
|
|
6254
6265
|
});
|
|
6255
6266
|
}
|
|
6267
|
+
function printSignIn(data) {
|
|
6268
|
+
const chosen = data.customerSignIn;
|
|
6269
|
+
if (!chosen) {
|
|
6270
|
+
printKeyValue({
|
|
6271
|
+
server: `${data.server.name} (${data.server.id})`,
|
|
6272
|
+
"sign-in": "unknown — this deployment does not report the choice"
|
|
6273
|
+
});
|
|
6274
|
+
return;
|
|
6275
|
+
}
|
|
6276
|
+
const live = data.signInMode ?? "account";
|
|
6277
|
+
const methods = Object.entries(chosen.page).filter(([, on]) => on).map(([name]) => name);
|
|
6278
|
+
const identity = chosen.identity;
|
|
6279
|
+
printKeyValue({
|
|
6280
|
+
server: `${data.server.name} (${data.server.id})`,
|
|
6281
|
+
"chosen mode": MODE_LABEL[chosen.mode],
|
|
6282
|
+
"live door": live === chosen.mode || chosen.mode === "page" && live === "account" && methods.length > 0 ? "the chosen mode" : `${MODE_LABEL[live] ?? live} — the chosen mode is not finished`,
|
|
6283
|
+
"page methods": methods.length > 0 ? methods.join(", ") : "none",
|
|
6284
|
+
"identity source": identity.source === "idToken" ? `id_token${identity.endpoint ? ` (fallback ${identity.endpoint} → ${identity.userIdPath ?? "(no path)"})` : ""}` : identity.endpoint ? `${identity.endpoint} → ${identity.userIdPath ?? "(no path)"}` : "not configured",
|
|
6285
|
+
provider: data.upstreamSignIn?.providerLabel ?? "—",
|
|
6286
|
+
federation: data.signIn.configured ? `${data.signIn.status} (${data.signIn.issuer}, keys via ${data.signIn.keySource})` : "not configured",
|
|
6287
|
+
"sign-in url": data.signIn.signInUrl ?? "—"
|
|
6288
|
+
});
|
|
6289
|
+
}
|
|
6290
|
+
function onOff(value, flag) {
|
|
6291
|
+
if (value === undefined)
|
|
6292
|
+
return;
|
|
6293
|
+
const normalized = value.trim().toLowerCase();
|
|
6294
|
+
if (normalized === "on" || normalized === "true")
|
|
6295
|
+
return true;
|
|
6296
|
+
if (normalized === "off" || normalized === "false")
|
|
6297
|
+
return false;
|
|
6298
|
+
throw new Error(`${flag} must be on or off.`);
|
|
6299
|
+
}
|
|
6300
|
+
function textOrNull(value) {
|
|
6301
|
+
if (value === undefined)
|
|
6302
|
+
return;
|
|
6303
|
+
const trimmed = value.trim();
|
|
6304
|
+
if (trimmed.toLowerCase() === "none")
|
|
6305
|
+
return null;
|
|
6306
|
+
return trimmed.startsWith("@") ? readFileSync5(trimmed.slice(1), "utf8").trim() : trimmed;
|
|
6307
|
+
}
|
|
6308
|
+
function buildCustomerSignInBody(opts) {
|
|
6309
|
+
const body = {};
|
|
6310
|
+
if (opts.mode !== undefined) {
|
|
6311
|
+
if (!MODES.includes(opts.mode)) {
|
|
6312
|
+
throw new Error(`--mode must be one of ${MODES.join(", ")}.`);
|
|
6313
|
+
}
|
|
6314
|
+
body.mode = opts.mode;
|
|
6315
|
+
}
|
|
6316
|
+
const page = {};
|
|
6317
|
+
for (const [flag, key] of [
|
|
6318
|
+
["--email-code", "emailCode"],
|
|
6319
|
+
["--google", "google"],
|
|
6320
|
+
["--github", "github"]
|
|
6321
|
+
]) {
|
|
6322
|
+
const value = onOff(opts[key], flag);
|
|
6323
|
+
if (value !== undefined)
|
|
6324
|
+
page[key] = value;
|
|
6325
|
+
}
|
|
6326
|
+
if (Object.keys(page).length > 0)
|
|
6327
|
+
body.page = page;
|
|
6328
|
+
const identity = {};
|
|
6329
|
+
if (opts.identitySource !== undefined) {
|
|
6330
|
+
if (opts.identitySource !== "idToken" && opts.identitySource !== "userinfo") {
|
|
6331
|
+
throw new Error("--identity-source must be idToken or userinfo.");
|
|
6332
|
+
}
|
|
6333
|
+
identity.source = opts.identitySource;
|
|
6334
|
+
}
|
|
6335
|
+
for (const [flag, key] of [
|
|
6336
|
+
["identityEndpoint", "endpoint"],
|
|
6337
|
+
["identityUserIdPath", "userIdPath"],
|
|
6338
|
+
["identityEmailPath", "emailPath"],
|
|
6339
|
+
["identityNamePath", "namePath"]
|
|
6340
|
+
]) {
|
|
6341
|
+
const value = textOrNull(opts[flag]);
|
|
6342
|
+
if (value !== undefined)
|
|
6343
|
+
identity[key] = value;
|
|
6344
|
+
}
|
|
6345
|
+
if (Object.keys(identity).length > 0)
|
|
6346
|
+
body.identity = identity;
|
|
6347
|
+
const federationGiven = opts.federationIssuer !== undefined || opts.federationJwksUri !== undefined || opts.federationJwks !== undefined || opts.federationSignInUrl !== undefined;
|
|
6348
|
+
if (federationGiven) {
|
|
6349
|
+
if (!opts.federationIssuer?.trim()) {
|
|
6350
|
+
throw new Error("--federation-issuer is required when setting federation.");
|
|
6351
|
+
}
|
|
6352
|
+
const federation = { issuer: opts.federationIssuer.trim() };
|
|
6353
|
+
for (const [flag, key] of [
|
|
6354
|
+
["federationJwksUri", "jwksUri"],
|
|
6355
|
+
["federationJwks", "jwks"],
|
|
6356
|
+
["federationSignInUrl", "signInUrl"]
|
|
6357
|
+
]) {
|
|
6358
|
+
const value = textOrNull(opts[flag]);
|
|
6359
|
+
if (value !== undefined)
|
|
6360
|
+
federation[key] = value;
|
|
6361
|
+
}
|
|
6362
|
+
body.federation = federation;
|
|
6363
|
+
}
|
|
6364
|
+
if (Object.keys(body).length === 0) {
|
|
6365
|
+
throw new Error("Pass at least one of --mode, a page method, an identity flag, or the federation flags.");
|
|
6366
|
+
}
|
|
6367
|
+
return body;
|
|
6368
|
+
}
|
|
6369
|
+
function registerServerEndUserSignInCommands(endUser) {
|
|
6370
|
+
const signIn = endUser.command("sign-in").description("How customers sign in: the one mode, and the settings of the chosen one.");
|
|
6371
|
+
signIn.command("get <server>").description("Show the chosen sign-in mode, the door customers actually meet, and each mode’s settings.").option("--org <organizationId>", "Organization ID").action(runAction(async (serverRef, opts) => {
|
|
6372
|
+
const data = await readSignIn(serverRef, opts);
|
|
6373
|
+
if (isJsonMode()) {
|
|
6374
|
+
printJson(data.customerSignIn ?? data);
|
|
6375
|
+
return;
|
|
6376
|
+
}
|
|
6377
|
+
printSignIn(data);
|
|
6378
|
+
}));
|
|
6379
|
+
signIn.command("set <server>").description("Choose how customers sign in and set its settings. Sends only what the flags name; choosing a mode turns the others off.").option("--org <organizationId>", "Organization ID").option("--mode <mode>", `One of ${MODES.join(", ")}`).option("--email-code <on|off>", "Sign-in on your page: the emailed code").option("--google <on|off>", "Sign-in on your page: MCPCloud’s Google app").option("--github <on|off>", "Sign-in on your page: MCPCloud’s GitHub app").option("--identity-source <idToken|userinfo>", "Where MCPCloud reads the user id after an OAuth sign-in").option("--identity-endpoint <url>", "Identity endpoint (`none` clears it)").option("--identity-user-id-path <path>", "JSON path to the stable user id").option("--identity-email-path <path>", "JSON path to the email (display only)").option("--identity-name-path <path>", "JSON path to the name (display only)").option("--federation-issuer <iss>", "Federation: the issuer your assertions carry").option("--federation-jwks-uri <url>", "Federation: where your public keys are published").option("--federation-jwks <json|@path>", "Federation: your public keys inline").option("--federation-sign-in-url <url>", "Federation: where signed-out visitors are sent (`none` clears it)").addHelpText("after", [
|
|
6380
|
+
"",
|
|
6381
|
+
"One mode per server. Choosing one turns the others off and keeps their",
|
|
6382
|
+
"settings. Federation cannot be chosen before its trust exists: pass the",
|
|
6383
|
+
"--federation-* flags in the same call.",
|
|
6384
|
+
"",
|
|
6385
|
+
"Everything here applies on the next sign-in — no redeploy. The provider",
|
|
6386
|
+
"itself is `mcp servers oauth set`.",
|
|
6387
|
+
"",
|
|
6388
|
+
"Examples:",
|
|
6389
|
+
" $ mcp servers end-user sign-in set srv_123 --mode upstream --identity-source idToken",
|
|
6390
|
+
" $ mcp servers end-user sign-in set srv_123 --mode upstream \\",
|
|
6391
|
+
" --identity-endpoint https://api.example.com/v1/me --identity-user-id-path userId",
|
|
6392
|
+
" $ mcp servers end-user sign-in set srv_123 --mode page --email-code on --github on",
|
|
6393
|
+
" $ mcp servers end-user sign-in set srv_123 --mode federation \\",
|
|
6394
|
+
" --federation-issuer https://ids.example.com --federation-jwks-uri https://ids.example.com/.well-known/jwks.json"
|
|
6395
|
+
].join(`
|
|
6396
|
+
`)).action(runAction(async (serverRef, opts) => {
|
|
6397
|
+
const body = buildCustomerSignInBody(opts);
|
|
6398
|
+
const orgId = await resolveOrgId(opts.org);
|
|
6399
|
+
const serverId = await resolveServerId(serverRef, orgId, undefined);
|
|
6400
|
+
await api.put(CUSTOMER_SIGN_IN_PATH, {
|
|
6401
|
+
organizationId: orgId,
|
|
6402
|
+
serverId,
|
|
6403
|
+
...body
|
|
6404
|
+
});
|
|
6405
|
+
const updated = await readSignIn(serverRef, opts);
|
|
6406
|
+
if (isJsonMode()) {
|
|
6407
|
+
printJson(updated.customerSignIn ?? updated);
|
|
6408
|
+
return;
|
|
6409
|
+
}
|
|
6410
|
+
printSuccess(`Customers of ${updated.server.name} sign in with ${MODE_LABEL[updated.customerSignIn?.mode ?? "account"]}.`);
|
|
6411
|
+
printSignIn(updated);
|
|
6412
|
+
}));
|
|
6413
|
+
}
|
|
6414
|
+
|
|
6415
|
+
// src/commands/servers-end-user.ts
|
|
6416
|
+
var END_USER_PATH2 = "/api/v1/server/end-user-access";
|
|
6417
|
+
async function readEndUserAccess(serverRef, opts) {
|
|
6418
|
+
const orgId = await resolveOrgId(opts.org);
|
|
6419
|
+
const serverId = await resolveServerId(serverRef, orgId, undefined);
|
|
6420
|
+
return await api.get(END_USER_PATH2, {
|
|
6421
|
+
organizationId: orgId,
|
|
6422
|
+
serverId
|
|
6423
|
+
});
|
|
6424
|
+
}
|
|
6256
6425
|
function describeSignInMode(data) {
|
|
6257
6426
|
const upstream = data.upstreamSignIn;
|
|
6258
6427
|
const provider = upstream?.providerLabel ?? "the OAuth provider";
|
|
@@ -6272,6 +6441,7 @@ function printEndUserAccess(data) {
|
|
|
6272
6441
|
server: `${data.server.name} (${data.server.id})`,
|
|
6273
6442
|
access: data.endUserAccess,
|
|
6274
6443
|
"sign-in mode": describeSignInMode(data),
|
|
6444
|
+
"chosen mode": data.customerSignIn?.mode ?? "—",
|
|
6275
6445
|
"connect page": data.connectPageUrl ?? "—",
|
|
6276
6446
|
"allowed tools": data.allowedTools.length > 0 ? `${data.allowedTools.length}: ${data.allowedTools.join(", ")}` : "none — end users can call nothing",
|
|
6277
6447
|
"display name": data.branding?.displayName ?? "—",
|
|
@@ -6284,7 +6454,7 @@ function printEndUserAccess(data) {
|
|
|
6284
6454
|
});
|
|
6285
6455
|
}
|
|
6286
6456
|
function parseToolList(raw) {
|
|
6287
|
-
const text = raw.startsWith("@") ?
|
|
6457
|
+
const text = raw.startsWith("@") ? readFileSync6(raw.slice(1), "utf8") : raw;
|
|
6288
6458
|
const trimmed = text.trim();
|
|
6289
6459
|
if (trimmed.startsWith("[")) {
|
|
6290
6460
|
const parsed = JSON.parse(trimmed);
|
|
@@ -6296,7 +6466,8 @@ function parseToolList(raw) {
|
|
|
6296
6466
|
return trimmed.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
6297
6467
|
}
|
|
6298
6468
|
function registerServerEndUserCommands(servers) {
|
|
6299
|
-
const endUser = servers.command("end-user").alias("end-users").description("Read and set a server's end-user plane: the access switch
|
|
6469
|
+
const endUser = servers.command("end-user").alias("end-users").description("Read and set a server's end-user plane: the access switch, the tool allowlist customers may call, and how they sign in.");
|
|
6470
|
+
registerServerEndUserSignInCommands(endUser);
|
|
6300
6471
|
endUser.command("get <server>").description("Show the end-user access configuration: switch, connect page, allowed tools, branding, and how customers sign in.").option("--org <organizationId>", "Organization ID").addHelpText("after", [
|
|
6301
6472
|
"",
|
|
6302
6473
|
"End users are deny-by-default, so `allowed tools` is exhaustive — a",
|
|
@@ -6341,7 +6512,7 @@ function registerServerEndUserCommands(servers) {
|
|
|
6341
6512
|
const orgId = await resolveOrgId(opts.org);
|
|
6342
6513
|
const enabled = opts.enable ? true : opts.disable ? false : current.endUserAccess === "enabled";
|
|
6343
6514
|
const allowedTools = opts.allowTools ? parseToolList(opts.allowTools) : null;
|
|
6344
|
-
await api.put(
|
|
6515
|
+
await api.put(END_USER_PATH2, {
|
|
6345
6516
|
organizationId: orgId,
|
|
6346
6517
|
projectId: current.server.projectId,
|
|
6347
6518
|
serverId: current.server.id,
|
|
@@ -6362,8 +6533,168 @@ function registerServerEndUserCommands(servers) {
|
|
|
6362
6533
|
}));
|
|
6363
6534
|
}
|
|
6364
6535
|
|
|
6536
|
+
// src/commands/servers-oauth.ts
|
|
6537
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
6538
|
+
var OAUTH_PROVIDER_PATH = "/api/v1/server/oauth-provider";
|
|
6539
|
+
async function readProvider(serverRef, opts) {
|
|
6540
|
+
const orgId = await resolveOrgId(opts.org);
|
|
6541
|
+
const serverId = await resolveServerId(serverRef, orgId, undefined);
|
|
6542
|
+
return await api.get(OAUTH_PROVIDER_PATH, {
|
|
6543
|
+
organizationId: orgId,
|
|
6544
|
+
serverId
|
|
6545
|
+
});
|
|
6546
|
+
}
|
|
6547
|
+
function printProvider(data) {
|
|
6548
|
+
const { oauth } = data;
|
|
6549
|
+
printKeyValue({
|
|
6550
|
+
server: `${data.server.name} (${data.server.id})`,
|
|
6551
|
+
status: !oauth.enabled ? "disabled" : oauth.configured ? "enabled and configured" : "enabled — incomplete",
|
|
6552
|
+
provider: oauth.providerKey ? `${oauth.providerLabel ?? oauth.providerKey} (${oauth.providerKey}, ${oauth.providerKind ?? "oauth2"})` : "not set up",
|
|
6553
|
+
"authorization url": oauth.authorizationUrl ?? "—",
|
|
6554
|
+
"token url": oauth.tokenUrl ?? "—",
|
|
6555
|
+
"revocation url": oauth.revocationUrl ?? "—",
|
|
6556
|
+
"client id": oauth.clientId ?? "—",
|
|
6557
|
+
"client secret": oauth.hasClientSecret ? "on file (write-only)" : "none",
|
|
6558
|
+
scopes: oauth.scopes.length > 0 ? oauth.scopes.join(" ") : "—",
|
|
6559
|
+
"tool coverage": oauth.applyToAllTools ? "every tool (regenerate + deploy to apply a change)" : "only tools whose spec declares OAuth",
|
|
6560
|
+
"callback url": oauth.callbackUrl ?? "—"
|
|
6561
|
+
});
|
|
6562
|
+
}
|
|
6563
|
+
function urlOrNull(value) {
|
|
6564
|
+
if (value === undefined)
|
|
6565
|
+
return;
|
|
6566
|
+
return value.trim().toLowerCase() === "none" ? null : value.trim();
|
|
6567
|
+
}
|
|
6568
|
+
function readClientSecret(opts) {
|
|
6569
|
+
if (opts.clientSecretStdin && opts.clientSecretEnv) {
|
|
6570
|
+
throw new Error("--client-secret-stdin and --client-secret-env are mutually exclusive.");
|
|
6571
|
+
}
|
|
6572
|
+
if (opts.clientSecretStdin) {
|
|
6573
|
+
const secret = readFileSync7(0, "utf8").trim();
|
|
6574
|
+
if (!secret)
|
|
6575
|
+
throw new Error("No client secret was read from stdin.");
|
|
6576
|
+
return secret;
|
|
6577
|
+
}
|
|
6578
|
+
if (opts.clientSecretEnv) {
|
|
6579
|
+
const secret = process.env[opts.clientSecretEnv]?.trim();
|
|
6580
|
+
if (!secret) {
|
|
6581
|
+
throw new Error(`${opts.clientSecretEnv} is not set in the environment.`);
|
|
6582
|
+
}
|
|
6583
|
+
return secret;
|
|
6584
|
+
}
|
|
6585
|
+
return;
|
|
6586
|
+
}
|
|
6587
|
+
function buildOAuthProviderBody(opts) {
|
|
6588
|
+
if (opts.enable && opts.disable) {
|
|
6589
|
+
throw new Error("--enable and --disable are mutually exclusive.");
|
|
6590
|
+
}
|
|
6591
|
+
if (opts.kind !== undefined && opts.kind !== "oauth2" && opts.kind !== "openIdConnect") {
|
|
6592
|
+
throw new Error("--kind must be oauth2 or openIdConnect.");
|
|
6593
|
+
}
|
|
6594
|
+
const clientSecret = readClientSecret(opts);
|
|
6595
|
+
if (clientSecret !== undefined && opts.clearClientSecret) {
|
|
6596
|
+
throw new Error("A new client secret and --clear-client-secret are mutually exclusive.");
|
|
6597
|
+
}
|
|
6598
|
+
const body = {};
|
|
6599
|
+
if (opts.enable)
|
|
6600
|
+
body.enabled = true;
|
|
6601
|
+
if (opts.disable)
|
|
6602
|
+
body.enabled = false;
|
|
6603
|
+
if (opts.provider !== undefined)
|
|
6604
|
+
body.providerKey = opts.provider.trim();
|
|
6605
|
+
if (opts.label !== undefined)
|
|
6606
|
+
body.providerLabel = opts.label.trim() || null;
|
|
6607
|
+
if (opts.kind !== undefined)
|
|
6608
|
+
body.providerKind = opts.kind;
|
|
6609
|
+
for (const [flag, key] of [
|
|
6610
|
+
["authorizationUrl", "authorizationUrl"],
|
|
6611
|
+
["tokenUrl", "tokenUrl"],
|
|
6612
|
+
["revocationUrl", "revocationUrl"]
|
|
6613
|
+
]) {
|
|
6614
|
+
const value = urlOrNull(opts[flag]);
|
|
6615
|
+
if (value !== undefined)
|
|
6616
|
+
body[key] = value;
|
|
6617
|
+
}
|
|
6618
|
+
if (opts.clientId !== undefined)
|
|
6619
|
+
body.clientId = opts.clientId.trim() || null;
|
|
6620
|
+
if (clientSecret !== undefined)
|
|
6621
|
+
body.clientSecret = clientSecret;
|
|
6622
|
+
if (opts.clearClientSecret)
|
|
6623
|
+
body.clearClientSecret = true;
|
|
6624
|
+
if (opts.scopes !== undefined) {
|
|
6625
|
+
body.scopes = opts.scopes.split(/[\s,]+/).map((scope) => scope.trim()).filter(Boolean);
|
|
6626
|
+
}
|
|
6627
|
+
if (opts.applyToAllTools !== undefined)
|
|
6628
|
+
body.applyToAllTools = opts.applyToAllTools;
|
|
6629
|
+
if (Object.keys(body).length === 0) {
|
|
6630
|
+
throw new Error("Pass at least one provider flag to change.");
|
|
6631
|
+
}
|
|
6632
|
+
return body;
|
|
6633
|
+
}
|
|
6634
|
+
function registerServerOAuthCommands(servers) {
|
|
6635
|
+
const oauth = servers.command("oauth").description("Read and set a server's OAuth provider: the endpoints, client credentials, scopes and tool coverage it uses for delegated authorization.");
|
|
6636
|
+
oauth.command("get <server>").description("Show the OAuth provider: status, endpoints, client id, whether a secret is on file, scopes, tool coverage, and the callback URL to register.").option("--org <organizationId>", "Organization ID").addHelpText("after", [
|
|
6637
|
+
"",
|
|
6638
|
+
"The client secret is write-only: this shows whether one is on file,",
|
|
6639
|
+
"never the value.",
|
|
6640
|
+
"",
|
|
6641
|
+
"Examples:",
|
|
6642
|
+
" $ mcp servers oauth get srv_123",
|
|
6643
|
+
" $ mcp --json servers oauth get srv_123 | jq '.oauth.callbackUrl'"
|
|
6644
|
+
].join(`
|
|
6645
|
+
`)).action(runAction(async (serverRef, opts) => {
|
|
6646
|
+
const data = await readProvider(serverRef, opts);
|
|
6647
|
+
if (isJsonMode()) {
|
|
6648
|
+
printJson(data);
|
|
6649
|
+
return;
|
|
6650
|
+
}
|
|
6651
|
+
printProvider(data);
|
|
6652
|
+
}));
|
|
6653
|
+
oauth.command("set <server>").description("Set the OAuth provider. Partial: a flag left off keeps what is stored.").option("--org <organizationId>", "Organization ID").option("--enable", "Use this provider for delegated authorization").option("--disable", "Stop using it (settings are kept)").option("--provider <key>", "Preset key (github, google, slack, …) or any identifier for a custom provider").option("--label <label>", "Shown to customers: “Continue with <label>”").option("--kind <oauth2|openIdConnect>", "Provider kind").option("--authorization-url <url>", "Authorization endpoint (`none` clears it)").option("--token-url <url>", "Token endpoint (`none` clears it)").option("--revocation-url <url>", "Revocation endpoint (`none` clears it)").option("--client-id <id>", "OAuth client id").option("--client-secret-stdin", "Read the client secret from stdin").option("--client-secret-env <VAR>", "Read the client secret from this environment variable").option("--clear-client-secret", "Remove the stored client secret").option("--scopes <list>", "Replace the scopes (comma or space separated)").option("--apply-to-all-tools", "Use this provider for every tool").option("--no-apply-to-all-tools", "Only for tools whose spec declares OAuth").addHelpText("after", [
|
|
6654
|
+
"",
|
|
6655
|
+
"Provider, credentials and scopes apply to new sign-ins and token",
|
|
6656
|
+
"refreshes immediately. --apply-to-all-tools is baked into the worker:",
|
|
6657
|
+
"regenerate and deploy to apply it.",
|
|
6658
|
+
"",
|
|
6659
|
+
"The secret never goes on the command line. Pipe it in, or name a",
|
|
6660
|
+
"variable:",
|
|
6661
|
+
' $ printf %s "$SECRET" | mcp servers oauth set srv_123 --client-secret-stdin',
|
|
6662
|
+
" $ mcp servers oauth set srv_123 --client-secret-env GATHERD_OAUTH_SECRET",
|
|
6663
|
+
"",
|
|
6664
|
+
"Examples:",
|
|
6665
|
+
" $ mcp servers oauth set srv_123 --provider custom --label Gatherd \\",
|
|
6666
|
+
" --authorization-url https://gatherd.dev/oauth/authorize \\",
|
|
6667
|
+
" --token-url https://gatherd.dev/oauth/token --client-id abc \\",
|
|
6668
|
+
" --scopes read,write --enable --apply-to-all-tools",
|
|
6669
|
+
" $ mcp servers oauth set srv_123 --disable"
|
|
6670
|
+
].join(`
|
|
6671
|
+
`)).action(runAction(async (serverRef, opts) => {
|
|
6672
|
+
const body = buildOAuthProviderBody(opts);
|
|
6673
|
+
const orgId = await resolveOrgId(opts.org);
|
|
6674
|
+
const serverId = await resolveServerId(serverRef, orgId, undefined);
|
|
6675
|
+
await api.put(OAUTH_PROVIDER_PATH, {
|
|
6676
|
+
organizationId: orgId,
|
|
6677
|
+
serverId,
|
|
6678
|
+
...body
|
|
6679
|
+
});
|
|
6680
|
+
const updated = await readProvider(serverRef, opts);
|
|
6681
|
+
if (isJsonMode()) {
|
|
6682
|
+
printJson(updated);
|
|
6683
|
+
return;
|
|
6684
|
+
}
|
|
6685
|
+
printSuccess(`OAuth provider saved for ${updated.server.name}.`);
|
|
6686
|
+
printProvider(updated);
|
|
6687
|
+
if (updated.oauth.callbackUrl) {
|
|
6688
|
+
printInfo(` Register ${updated.oauth.callbackUrl} with the provider.`);
|
|
6689
|
+
}
|
|
6690
|
+
if (body.applyToAllTools !== undefined) {
|
|
6691
|
+
printInfo(" Tool coverage changed: regenerate and deploy to apply it.");
|
|
6692
|
+
}
|
|
6693
|
+
}));
|
|
6694
|
+
}
|
|
6695
|
+
|
|
6365
6696
|
// src/commands/servers-env.ts
|
|
6366
|
-
import { existsSync as existsSync3, readFileSync as
|
|
6697
|
+
import { existsSync as existsSync3, readFileSync as readFileSync8 } from "node:fs";
|
|
6367
6698
|
import { resolve } from "node:path";
|
|
6368
6699
|
function registerServerEnvCommands(servers) {
|
|
6369
6700
|
const env = servers.command("env").description("Manage server runtime environment bindings (encrypted secrets injected by the proxy).");
|
|
@@ -6512,7 +6843,7 @@ async function resolveSetValue(args) {
|
|
|
6512
6843
|
printError(`--from-file path not found: ${path}`);
|
|
6513
6844
|
throw new CliExitError(1);
|
|
6514
6845
|
}
|
|
6515
|
-
return
|
|
6846
|
+
return readFileSync8(path, "utf-8");
|
|
6516
6847
|
}
|
|
6517
6848
|
return await readStdin();
|
|
6518
6849
|
}
|
|
@@ -6991,7 +7322,7 @@ function registerServerSandboxVariableCommands(servers) {
|
|
|
6991
7322
|
}
|
|
6992
7323
|
|
|
6993
7324
|
// src/lib/mcp-invoke.ts
|
|
6994
|
-
import { existsSync as existsSync4, readFileSync as
|
|
7325
|
+
import { existsSync as existsSync4, readFileSync as readFileSync9 } from "node:fs";
|
|
6995
7326
|
import { resolve as resolve2 } from "node:path";
|
|
6996
7327
|
var DEFAULT_TIMEOUT_MS3 = 60000;
|
|
6997
7328
|
var invokeRequestId = 1;
|
|
@@ -7213,7 +7544,7 @@ async function parseToolArguments(opts) {
|
|
|
7213
7544
|
if (!existsSync4(filePath)) {
|
|
7214
7545
|
return { ok: false, reason: "file-not-found", path: filePath };
|
|
7215
7546
|
}
|
|
7216
|
-
source =
|
|
7547
|
+
source = readFileSync9(filePath, "utf-8");
|
|
7217
7548
|
} else {
|
|
7218
7549
|
source = raw;
|
|
7219
7550
|
}
|
|
@@ -7876,7 +8207,7 @@ import { isAbsolute as isAbsolute2, resolve as resolve4 } from "node:path";
|
|
|
7876
8207
|
import { createHash as createHash2 } from "node:crypto";
|
|
7877
8208
|
import {
|
|
7878
8209
|
existsSync as existsSync5,
|
|
7879
|
-
readFileSync as
|
|
8210
|
+
readFileSync as readFileSync10,
|
|
7880
8211
|
watch as fsWatch
|
|
7881
8212
|
} from "node:fs";
|
|
7882
8213
|
import { dirname as dirname3 } from "node:path";
|
|
@@ -7931,7 +8262,7 @@ function summarizeDiff(diff) {
|
|
|
7931
8262
|
`) };
|
|
7932
8263
|
}
|
|
7933
8264
|
function readSpecFile(specPath) {
|
|
7934
|
-
const content =
|
|
8265
|
+
const content = readFileSync10(specPath, "utf-8");
|
|
7935
8266
|
return { content, hash: hashSpecContent(content) };
|
|
7936
8267
|
}
|
|
7937
8268
|
function watchSpecFile(options) {
|
|
@@ -7951,7 +8282,7 @@ function watchSpecFile(options) {
|
|
|
7951
8282
|
return;
|
|
7952
8283
|
let content;
|
|
7953
8284
|
try {
|
|
7954
|
-
content =
|
|
8285
|
+
content = readFileSync10(options.specPath, "utf-8");
|
|
7955
8286
|
} catch {
|
|
7956
8287
|
return;
|
|
7957
8288
|
}
|
|
@@ -8796,8 +9127,9 @@ function registerServerUpdateCommand(servers) {
|
|
|
8796
9127
|
servers.command("update <server>").description("Update a server (name, description, tool surface, upstream key mode, runtime token TTL, spec source URL)").option("--org <organizationId>", "Organization ID").option("--name <name>", "New display name").option("--description <text>", "New description").option("--discovery-mode <all|wrapper>", 'Tool surface: "all" registers every operation; "wrapper" registers searchTools/getToolDefinition/useTool INSTEAD (operations are called through useTool).').option("--code-mode <off|opt-in|default>", "Code Mode: expose codemode_execute so an agent can script several calls in one sandboxed run. Served by the edge, so it takes effect on the next deploy.").option("--upstream-api-key-mode <shared|perMember>", "Whose upstream credential the server uses: one shared key, or each member their own (Pro and above). perMember needs a protected access mode (privateOrg or unlisted) — refused while the active deployment is public.").option("--runtime-token-ttl <seconds|default>", 'Runtime token lifetime in seconds (60-86400; the default AND cap for minted tokens). Pass "default" to restore the 300s platform default.').option("--source-url <url>", "Read this server’s spec from a different URL from now on. The URL is fetched and parsed as the server’s source type first, and the report shows what a regenerate from it would change. Tools are not touched until you regenerate.").option("--dry-run", "With --source-url: fetch, parse and report without storing anything").addHelpText("after", [
|
|
8797
9128
|
"",
|
|
8798
9129
|
"Notes:",
|
|
8799
|
-
"
|
|
8800
|
-
"
|
|
9130
|
+
" The OAuth provider is `mcp servers oauth set`; how customers sign in is",
|
|
9131
|
+
" `mcp servers end-user sign-in set`. Other runtime defaults (deployment",
|
|
9132
|
+
" defaults, runtime bindings) are set via `mcp servers deploy --upstream-*`.",
|
|
8801
9133
|
" --discovery-mode and --code-mode change the server's TOOL SURFACE and",
|
|
8802
9134
|
" reach clients on the next `mcp servers deploy`. Check what is live with",
|
|
8803
9135
|
" `mcp servers get <server> --probe`.",
|
|
@@ -9085,7 +9417,7 @@ function registerServerMutationCommands(servers) {
|
|
|
9085
9417
|
}
|
|
9086
9418
|
|
|
9087
9419
|
// src/lib/spec-pipeline.ts
|
|
9088
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as
|
|
9420
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "node:fs";
|
|
9089
9421
|
import { dirname as dirname4, join as join5, resolve as resolve5 } from "node:path";
|
|
9090
9422
|
var SOURCE_TYPES = ["openapi", "graphql", "url"];
|
|
9091
9423
|
function isHttpUrl(value) {
|
|
@@ -9118,7 +9450,7 @@ async function readSpecSource(spec, override, options = {}) {
|
|
|
9118
9450
|
if (!existsSync7(filePath)) {
|
|
9119
9451
|
throw new Error(`Spec file not found: ${filePath}`);
|
|
9120
9452
|
}
|
|
9121
|
-
content =
|
|
9453
|
+
content = readFileSync11(filePath, "utf-8");
|
|
9122
9454
|
pathHint = filePath;
|
|
9123
9455
|
}
|
|
9124
9456
|
if (!content.trim()) {
|
|
@@ -9301,7 +9633,7 @@ function registerServerSpecCommands(servers) {
|
|
|
9301
9633
|
}
|
|
9302
9634
|
|
|
9303
9635
|
// src/commands/servers-test-authoring.ts
|
|
9304
|
-
import { readFileSync as
|
|
9636
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
9305
9637
|
var EXECUTION_PROFILES = [
|
|
9306
9638
|
"mockBindings",
|
|
9307
9639
|
"previewBindings",
|
|
@@ -9319,9 +9651,9 @@ function parseTimeoutMs(value, fallbackMs) {
|
|
|
9319
9651
|
}
|
|
9320
9652
|
function readValueOption(raw) {
|
|
9321
9653
|
if (raw === "@-")
|
|
9322
|
-
return
|
|
9654
|
+
return readFileSync12(0, "utf8");
|
|
9323
9655
|
if (raw.startsWith("@"))
|
|
9324
|
-
return
|
|
9656
|
+
return readFileSync12(raw.slice(1), "utf8");
|
|
9325
9657
|
return raw;
|
|
9326
9658
|
}
|
|
9327
9659
|
async function resolveServerAndProject(serverRef, org) {
|
|
@@ -9683,6 +10015,7 @@ function registerServerCommands(program) {
|
|
|
9683
10015
|
const servers = program.command("servers").description("Manage MCP servers");
|
|
9684
10016
|
registerServerDepsCommands(servers);
|
|
9685
10017
|
registerServerEndUserCommands(servers);
|
|
10018
|
+
registerServerOAuthCommands(servers);
|
|
9686
10019
|
registerServerTraceCommands(servers);
|
|
9687
10020
|
registerServerGitCommands(servers);
|
|
9688
10021
|
registerServerCommitCommand(servers);
|
|
@@ -9867,7 +10200,7 @@ import { existsSync as existsSync10 } from "node:fs";
|
|
|
9867
10200
|
import { join as join8, relative } from "node:path";
|
|
9868
10201
|
|
|
9869
10202
|
// src/lib/dev/state.ts
|
|
9870
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as
|
|
10203
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync4 } from "node:fs";
|
|
9871
10204
|
import { join as join6, resolve as resolve6 } from "node:path";
|
|
9872
10205
|
function cachedStateMatchesTarget(cached, target) {
|
|
9873
10206
|
return cached !== null && cached.serverId === target.serverId && cached.organizationId === target.organizationId;
|
|
@@ -9896,7 +10229,7 @@ function readState(cwd) {
|
|
|
9896
10229
|
if (!existsSync8(path))
|
|
9897
10230
|
return null;
|
|
9898
10231
|
try {
|
|
9899
|
-
const parsed = JSON.parse(
|
|
10232
|
+
const parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
9900
10233
|
if (!parsed || typeof parsed !== "object")
|
|
9901
10234
|
return null;
|
|
9902
10235
|
const s = parsed;
|
|
@@ -9937,7 +10270,7 @@ function ensureGitignore(cwd) {
|
|
|
9937
10270
|
import {
|
|
9938
10271
|
existsSync as existsSync9,
|
|
9939
10272
|
mkdirSync as mkdirSync6,
|
|
9940
|
-
readFileSync as
|
|
10273
|
+
readFileSync as readFileSync14,
|
|
9941
10274
|
readdirSync,
|
|
9942
10275
|
rmSync,
|
|
9943
10276
|
writeFileSync as writeFileSync5
|
|
@@ -10151,7 +10484,7 @@ function readToolsState(devRootDir, serverId) {
|
|
|
10151
10484
|
if (!existsSync9(file))
|
|
10152
10485
|
return null;
|
|
10153
10486
|
try {
|
|
10154
|
-
const parsed = JSON.parse(
|
|
10487
|
+
const parsed = JSON.parse(readFileSync14(file, "utf-8"));
|
|
10155
10488
|
if (!parsed || typeof parsed !== "object")
|
|
10156
10489
|
return null;
|
|
10157
10490
|
const s = parsed;
|
|
@@ -10231,7 +10564,7 @@ function readLocalTool(devRootDir, serverId, toolName) {
|
|
|
10231
10564
|
const stateEntry = state?.tools[toolName];
|
|
10232
10565
|
if (!stateEntry)
|
|
10233
10566
|
return null;
|
|
10234
|
-
const view = parseToolMarkdown(
|
|
10567
|
+
const view = parseToolMarkdown(readFileSync14(filePath, "utf-8"));
|
|
10235
10568
|
return {
|
|
10236
10569
|
view,
|
|
10237
10570
|
cloudId: stateEntry.id,
|
|
@@ -10436,14 +10769,14 @@ async function runToolsDelete(toolName, opts) {
|
|
|
10436
10769
|
}
|
|
10437
10770
|
|
|
10438
10771
|
// src/commands/tools-diff.ts
|
|
10439
|
-
import { existsSync as existsSync12, readFileSync as
|
|
10772
|
+
import { existsSync as existsSync12, readFileSync as readFileSync16 } from "node:fs";
|
|
10440
10773
|
import { relative as relative2 } from "node:path";
|
|
10441
10774
|
|
|
10442
10775
|
// src/lib/dev/handlers-sync.ts
|
|
10443
10776
|
import {
|
|
10444
10777
|
existsSync as existsSync11,
|
|
10445
10778
|
mkdirSync as mkdirSync7,
|
|
10446
|
-
readFileSync as
|
|
10779
|
+
readFileSync as readFileSync15,
|
|
10447
10780
|
statSync,
|
|
10448
10781
|
writeFileSync as writeFileSync6
|
|
10449
10782
|
} from "node:fs";
|
|
@@ -10490,7 +10823,7 @@ async function pushLocalHandlerEdit(args) {
|
|
|
10490
10823
|
if (!resolved) {
|
|
10491
10824
|
return { kind: "unknown-tool", slug: args.slug };
|
|
10492
10825
|
}
|
|
10493
|
-
const source =
|
|
10826
|
+
const source = readFileSync15(filePath, "utf-8");
|
|
10494
10827
|
const hash = hashSource(source);
|
|
10495
10828
|
if (lastPushedHash.get(filePath) === hash) {
|
|
10496
10829
|
return { kind: "noop" };
|
|
@@ -10649,7 +10982,7 @@ function inspectLocalHandler(args) {
|
|
|
10649
10982
|
if (!existsSync11(filePath))
|
|
10650
10983
|
return { kind: "no-local-file" };
|
|
10651
10984
|
const cached = lastPushedHash.get(filePath);
|
|
10652
|
-
const onDisk = hashSource(
|
|
10985
|
+
const onDisk = hashSource(readFileSync15(filePath, "utf-8"));
|
|
10653
10986
|
if (cached !== undefined) {
|
|
10654
10987
|
return cached === onDisk ? { kind: "matches-cache" } : { kind: "differs-from-cache" };
|
|
10655
10988
|
}
|
|
@@ -10770,7 +11103,7 @@ function buildMetadataDiff(args) {
|
|
|
10770
11103
|
let local = null;
|
|
10771
11104
|
let parseError = null;
|
|
10772
11105
|
try {
|
|
10773
|
-
local = parseToolMarkdown(
|
|
11106
|
+
local = parseToolMarkdown(readFileSync16(filePath, "utf-8"));
|
|
10774
11107
|
} catch (err) {
|
|
10775
11108
|
parseError = err instanceof Error ? err.message : String(err);
|
|
10776
11109
|
}
|
|
@@ -10813,7 +11146,7 @@ async function buildHandlerDiff(args) {
|
|
|
10813
11146
|
const slug = handlerSlugFromToolName(args.toolName);
|
|
10814
11147
|
const filePath = `${serverBundleHandlersDir(args.devRootDir)}/${slug}.ts`;
|
|
10815
11148
|
const hasLocal = existsSync12(filePath);
|
|
10816
|
-
const localContent = hasLocal ?
|
|
11149
|
+
const localContent = hasLocal ? readFileSync16(filePath, "utf-8") : null;
|
|
10817
11150
|
const localPath = hasLocal ? relative2(args.cwd, filePath) || filePath : null;
|
|
10818
11151
|
const changed = hasLocal ? localContent !== cloudResult.snapshot.content : true;
|
|
10819
11152
|
return {
|
|
@@ -10928,7 +11261,7 @@ import { join as join11, relative as relative3 } from "node:path";
|
|
|
10928
11261
|
|
|
10929
11262
|
// src/lib/editor-shell.ts
|
|
10930
11263
|
import { spawn as spawn2 } from "node:child_process";
|
|
10931
|
-
import { existsSync as existsSync13, readFileSync as
|
|
11264
|
+
import { existsSync as existsSync13, readFileSync as readFileSync17 } from "node:fs";
|
|
10932
11265
|
import { platform as platform2 } from "node:os";
|
|
10933
11266
|
import { delimiter, join as join10 } from "node:path";
|
|
10934
11267
|
var DEFAULT_FALLBACKS = ["vi"];
|
|
@@ -11014,7 +11347,7 @@ async function runEditor(args) {
|
|
|
11014
11347
|
message: `${command} exited with code ${exitCode}. The file may be unsaved; re-run after fixing.`
|
|
11015
11348
|
};
|
|
11016
11349
|
}
|
|
11017
|
-
const contents =
|
|
11350
|
+
const contents = readFileSync17(args.filePath, "utf-8");
|
|
11018
11351
|
return { ok: true, contents, command };
|
|
11019
11352
|
}
|
|
11020
11353
|
|
|
@@ -11818,7 +12151,7 @@ import { existsSync as existsSync16 } from "node:fs";
|
|
|
11818
12151
|
import { relative as relative6 } from "node:path";
|
|
11819
12152
|
|
|
11820
12153
|
// src/commands/tools-rename-input.ts
|
|
11821
|
-
import { existsSync as existsSync15, readFileSync as
|
|
12154
|
+
import { existsSync as existsSync15, readFileSync as readFileSync18 } from "node:fs";
|
|
11822
12155
|
import { isAbsolute as isAbsolute3, resolve as resolve7 } from "node:path";
|
|
11823
12156
|
var MODES_HINT = "Pass exactly one of: <old> <new>, --from-operation-ids, or --map @renames.json.";
|
|
11824
12157
|
function resolveRenameSelection(args) {
|
|
@@ -11853,7 +12186,7 @@ function readRenameMap(ref, cwd) {
|
|
|
11853
12186
|
throw new CliExitError(1, `--map file not found: ${path}`);
|
|
11854
12187
|
let parsed;
|
|
11855
12188
|
try {
|
|
11856
|
-
parsed = JSON.parse(
|
|
12189
|
+
parsed = JSON.parse(readFileSync18(path, "utf-8"));
|
|
11857
12190
|
} catch (err) {
|
|
11858
12191
|
throw new CliExitError(1, `--map file is not valid JSON (${path}): ${err instanceof Error ? err.message : String(err)}`);
|
|
11859
12192
|
}
|
|
@@ -12531,13 +12864,13 @@ function isAgentKey(value) {
|
|
|
12531
12864
|
}
|
|
12532
12865
|
|
|
12533
12866
|
// src/commands/skills-lifecycle.ts
|
|
12534
|
-
import { readFileSync as
|
|
12867
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
12535
12868
|
function readValueOption2(raw) {
|
|
12536
12869
|
if (raw === "@-") {
|
|
12537
|
-
return
|
|
12870
|
+
return readFileSync19(0, "utf8");
|
|
12538
12871
|
}
|
|
12539
12872
|
if (raw.startsWith("@")) {
|
|
12540
|
-
return
|
|
12873
|
+
return readFileSync19(raw.slice(1), "utf8");
|
|
12541
12874
|
}
|
|
12542
12875
|
return raw;
|
|
12543
12876
|
}
|
|
@@ -12887,7 +13220,7 @@ function registerSkillMutationCommands(skills) {
|
|
|
12887
13220
|
}
|
|
12888
13221
|
|
|
12889
13222
|
// src/commands/skills-test-authoring.ts
|
|
12890
|
-
import { readFileSync as
|
|
13223
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
12891
13224
|
var FIXTURE_MODES = [
|
|
12892
13225
|
"baseline",
|
|
12893
13226
|
"validationFailure",
|
|
@@ -12896,9 +13229,9 @@ var FIXTURE_MODES = [
|
|
|
12896
13229
|
];
|
|
12897
13230
|
function readValueOption3(raw) {
|
|
12898
13231
|
if (raw === "@-")
|
|
12899
|
-
return
|
|
13232
|
+
return readFileSync20(0, "utf8");
|
|
12900
13233
|
if (raw.startsWith("@"))
|
|
12901
|
-
return
|
|
13234
|
+
return readFileSync20(raw.slice(1), "utf8");
|
|
12902
13235
|
return raw;
|
|
12903
13236
|
}
|
|
12904
13237
|
function parseAssertionsOption(raw) {
|
|
@@ -13951,14 +14284,14 @@ function registerSkillCommands(program) {
|
|
|
13951
14284
|
}
|
|
13952
14285
|
|
|
13953
14286
|
// src/lib/dev/prepare.ts
|
|
13954
|
-
import { existsSync as existsSync24, readFileSync as
|
|
14287
|
+
import { existsSync as existsSync24, readFileSync as readFileSync24, writeFileSync as writeFileSync12 } from "node:fs";
|
|
13955
14288
|
import { join as join19, relative as relative8, resolve as resolve9 } from "node:path";
|
|
13956
14289
|
|
|
13957
14290
|
// src/lib/dev/bundle-sync.ts
|
|
13958
14291
|
import {
|
|
13959
14292
|
existsSync as existsSync18,
|
|
13960
14293
|
mkdirSync as mkdirSync9,
|
|
13961
|
-
readFileSync as
|
|
14294
|
+
readFileSync as readFileSync21,
|
|
13962
14295
|
rmSync as rmSync2,
|
|
13963
14296
|
writeFileSync as writeFileSync8
|
|
13964
14297
|
} from "node:fs";
|
|
@@ -14095,7 +14428,7 @@ import { spawnSync } from "node:child_process";
|
|
|
14095
14428
|
import {
|
|
14096
14429
|
existsSync as existsSync19,
|
|
14097
14430
|
mkdirSync as mkdirSync10,
|
|
14098
|
-
readFileSync as
|
|
14431
|
+
readFileSync as readFileSync22,
|
|
14099
14432
|
writeFileSync as writeFileSync9
|
|
14100
14433
|
} from "node:fs";
|
|
14101
14434
|
import { dirname as dirname8, join as join14 } from "node:path";
|
|
@@ -14190,7 +14523,7 @@ function isGitAvailable() {
|
|
|
14190
14523
|
}
|
|
14191
14524
|
function applyLocalExcludes(repoDir) {
|
|
14192
14525
|
const excludePath = join14(repoDir, ".git", "info", "exclude");
|
|
14193
|
-
const existing = existsSync19(excludePath) ?
|
|
14526
|
+
const existing = existsSync19(excludePath) ? readFileSync22(excludePath, "utf-8") : "";
|
|
14194
14527
|
const next = mergeLocalExcludes(existing);
|
|
14195
14528
|
if (next === null)
|
|
14196
14529
|
return;
|
|
@@ -29576,7 +29909,7 @@ import {
|
|
|
29576
29909
|
appendFileSync as appendFileSync2,
|
|
29577
29910
|
existsSync as existsSync22,
|
|
29578
29911
|
mkdirSync as mkdirSync13,
|
|
29579
|
-
readFileSync as
|
|
29912
|
+
readFileSync as readFileSync23,
|
|
29580
29913
|
readdirSync as readdirSync2,
|
|
29581
29914
|
renameSync,
|
|
29582
29915
|
statSync as statSync2
|
|
@@ -29628,7 +29961,7 @@ function readAll(dir) {
|
|
|
29628
29961
|
for (const path of [...listRotatedFiles(dir), activeFilePath(dir)]) {
|
|
29629
29962
|
if (!existsSync22(path))
|
|
29630
29963
|
continue;
|
|
29631
|
-
out.push(...parseLines(
|
|
29964
|
+
out.push(...parseLines(readFileSync23(path, "utf-8")));
|
|
29632
29965
|
}
|
|
29633
29966
|
return out;
|
|
29634
29967
|
}
|
|
@@ -29780,9 +30113,9 @@ function printEnvBindingHint(dest, envPath, cwd) {
|
|
|
29780
30113
|
let example = "";
|
|
29781
30114
|
let envJson = "{}";
|
|
29782
30115
|
try {
|
|
29783
|
-
example =
|
|
30116
|
+
example = readFileSync24(examplePath, "utf-8");
|
|
29784
30117
|
if (existsSync24(envPath))
|
|
29785
|
-
envJson =
|
|
30118
|
+
envJson = readFileSync24(envPath, "utf-8");
|
|
29786
30119
|
} catch {
|
|
29787
30120
|
return;
|
|
29788
30121
|
}
|
|
@@ -29955,7 +30288,7 @@ async function prepareDev(opts) {
|
|
|
29955
30288
|
|
|
29956
30289
|
// src/lib/dev/tree-sync.ts
|
|
29957
30290
|
import { createHash as createHash4 } from "node:crypto";
|
|
29958
|
-
import { existsSync as existsSync25, mkdirSync as mkdirSync14, readdirSync as readdirSync3, readFileSync as
|
|
30291
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync14, readdirSync as readdirSync3, readFileSync as readFileSync25, writeFileSync as writeFileSync13 } from "node:fs";
|
|
29959
30292
|
import { join as join20 } from "node:path";
|
|
29960
30293
|
var AUTHORING_GUIDE_FILE = "AGENTS.md";
|
|
29961
30294
|
var STRUCTURAL_FRONTMATTER_KEYS = [
|
|
@@ -29977,7 +30310,7 @@ function listToolFiles(devRootDir, serverId) {
|
|
|
29977
30310
|
}
|
|
29978
30311
|
function readToolFile(devRootDir, serverId, toolName) {
|
|
29979
30312
|
const file = join20(serverToolsDir(devRootDir, serverId), `${toolName}.md`);
|
|
29980
|
-
const raw =
|
|
30313
|
+
const raw = readFileSync25(file, "utf-8");
|
|
29981
30314
|
try {
|
|
29982
30315
|
return { raw, view: parseToolMarkdown(raw) };
|
|
29983
30316
|
} catch (err) {
|
|
@@ -30105,7 +30438,7 @@ function listHandlerFiles(devRootDir) {
|
|
|
30105
30438
|
return [];
|
|
30106
30439
|
return readdirSync3(dir).filter((entry) => entry.endsWith(".ts") && !entry.endsWith(".definition.ts")).sort().map((entry) => ({
|
|
30107
30440
|
slug: entry.slice(0, -3),
|
|
30108
|
-
source:
|
|
30441
|
+
source: readFileSync25(join20(dir, entry), "utf-8")
|
|
30109
30442
|
}));
|
|
30110
30443
|
}
|
|
30111
30444
|
function writeHandlerManifest(args) {
|
|
@@ -30133,7 +30466,7 @@ function recordHandlerPushed(args) {
|
|
|
30133
30466
|
serverId: args.serverId,
|
|
30134
30467
|
version: 1
|
|
30135
30468
|
};
|
|
30136
|
-
manifest.handlers[args.slug] = hashSource2(
|
|
30469
|
+
manifest.handlers[args.slug] = hashSource2(readFileSync25(file, "utf-8"));
|
|
30137
30470
|
writeFileSync13(handlerManifestPath(args.devRootDir, args.serverId), JSON.stringify(manifest, null, 2), "utf-8");
|
|
30138
30471
|
}
|
|
30139
30472
|
function readHandlerManifest(devRootDir, serverId) {
|
|
@@ -30141,7 +30474,7 @@ function readHandlerManifest(devRootDir, serverId) {
|
|
|
30141
30474
|
if (!existsSync25(file))
|
|
30142
30475
|
return null;
|
|
30143
30476
|
try {
|
|
30144
|
-
const parsed = JSON.parse(
|
|
30477
|
+
const parsed = JSON.parse(readFileSync25(file, "utf-8"));
|
|
30145
30478
|
return parsed.version === 1 && parsed.handlers ? parsed : null;
|
|
30146
30479
|
} catch {
|
|
30147
30480
|
return null;
|
|
@@ -31165,7 +31498,7 @@ import { isAbsolute as isAbsolute5, relative as relative9, resolve as resolve11
|
|
|
31165
31498
|
import {
|
|
31166
31499
|
existsSync as existsSync26,
|
|
31167
31500
|
mkdirSync as mkdirSync15,
|
|
31168
|
-
readFileSync as
|
|
31501
|
+
readFileSync as readFileSync26,
|
|
31169
31502
|
readdirSync as readdirSync4,
|
|
31170
31503
|
unlinkSync,
|
|
31171
31504
|
writeFileSync as writeFileSync14
|
|
@@ -31209,7 +31542,7 @@ function listSessions() {
|
|
|
31209
31542
|
continue;
|
|
31210
31543
|
const path = join22(dir, entry);
|
|
31211
31544
|
try {
|
|
31212
|
-
const parsed = JSON.parse(
|
|
31545
|
+
const parsed = JSON.parse(readFileSync26(path, "utf-8"));
|
|
31213
31546
|
if (typeof parsed.pid !== "number") {
|
|
31214
31547
|
unlinkSync(path);
|
|
31215
31548
|
continue;
|
|
@@ -32581,19 +32914,19 @@ import { homedir as homedir4 } from "node:os";
|
|
|
32581
32914
|
import { join as join27 } from "node:path";
|
|
32582
32915
|
|
|
32583
32916
|
// src/lib/dev/agent-connectors/json-config-utils.ts
|
|
32584
|
-
import { existsSync as existsSync32, mkdirSync as mkdirSync16, readFileSync as
|
|
32917
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync16, readFileSync as readFileSync27, writeFileSync as writeFileSync15 } from "node:fs";
|
|
32585
32918
|
import { dirname as dirname10, join as join26, basename } from "node:path";
|
|
32586
32919
|
function readJsonFile(path) {
|
|
32587
32920
|
if (!existsSync32(path))
|
|
32588
32921
|
return { ok: true, value: {} };
|
|
32589
32922
|
try {
|
|
32590
|
-
const raw =
|
|
32923
|
+
const raw = readFileSync27(path, "utf-8");
|
|
32591
32924
|
if (!raw.trim())
|
|
32592
32925
|
return { ok: true, value: {} };
|
|
32593
32926
|
return { ok: true, value: JSON.parse(raw) };
|
|
32594
32927
|
} catch {
|
|
32595
32928
|
try {
|
|
32596
|
-
return { ok: false, raw:
|
|
32929
|
+
return { ok: false, raw: readFileSync27(path, "utf-8") };
|
|
32597
32930
|
} catch {
|
|
32598
32931
|
return { ok: false };
|
|
32599
32932
|
}
|
|
@@ -32615,7 +32948,7 @@ function backupConfig(args) {
|
|
|
32615
32948
|
const filename = `${args.agentId}__${basename(args.configPath)}.bak`;
|
|
32616
32949
|
const backupPath = join26(args.backupsDir, filename);
|
|
32617
32950
|
if (!existsSync32(backupPath)) {
|
|
32618
|
-
const raw =
|
|
32951
|
+
const raw = readFileSync27(args.configPath, "utf-8");
|
|
32619
32952
|
writeFileSync15(backupPath, raw, "utf-8");
|
|
32620
32953
|
}
|
|
32621
32954
|
return { backupPath, existed: true };
|
|
@@ -32626,7 +32959,7 @@ function restoreFromBackup(args) {
|
|
|
32626
32959
|
if (!existsSync32(backupPath)) {
|
|
32627
32960
|
return { restored: false };
|
|
32628
32961
|
}
|
|
32629
|
-
const raw =
|
|
32962
|
+
const raw = readFileSync27(backupPath, "utf-8");
|
|
32630
32963
|
mkdirSync16(dirname10(args.configPath), { recursive: true });
|
|
32631
32964
|
writeFileSync15(args.configPath, raw, "utf-8");
|
|
32632
32965
|
return { restored: true };
|
|
@@ -32715,7 +33048,7 @@ var claudeCodeConnector = {
|
|
|
32715
33048
|
import {
|
|
32716
33049
|
existsSync as existsSync34,
|
|
32717
33050
|
mkdirSync as mkdirSync17,
|
|
32718
|
-
readFileSync as
|
|
33051
|
+
readFileSync as readFileSync28,
|
|
32719
33052
|
unlinkSync as unlinkSync3,
|
|
32720
33053
|
writeFileSync as writeFileSync17
|
|
32721
33054
|
} from "node:fs";
|
|
@@ -32774,7 +33107,7 @@ var codexConnector = {
|
|
|
32774
33107
|
});
|
|
32775
33108
|
let existing = "";
|
|
32776
33109
|
if (existsSync34(path)) {
|
|
32777
|
-
existing =
|
|
33110
|
+
existing = readFileSync28(path, "utf-8");
|
|
32778
33111
|
}
|
|
32779
33112
|
const conflict = findSectionRange(existing, args.name) !== null;
|
|
32780
33113
|
let next = existing;
|
|
@@ -32796,7 +33129,7 @@ var codexConnector = {
|
|
|
32796
33129
|
async remove(args) {
|
|
32797
33130
|
const path = configPath2();
|
|
32798
33131
|
if (existsSync34(path)) {
|
|
32799
|
-
const existing =
|
|
33132
|
+
const existing = readFileSync28(path, "utf-8");
|
|
32800
33133
|
const range = findSectionRange(existing, args.name);
|
|
32801
33134
|
if (range) {
|
|
32802
33135
|
const next = existing.slice(0, range.start) + existing.slice(range.end);
|
|
@@ -32809,7 +33142,7 @@ var codexConnector = {
|
|
|
32809
33142
|
agentId: this.id
|
|
32810
33143
|
});
|
|
32811
33144
|
if (!restored.restored && existsSync34(path)) {
|
|
32812
|
-
const after =
|
|
33145
|
+
const after = readFileSync28(path, "utf-8");
|
|
32813
33146
|
if (!after.trim()) {
|
|
32814
33147
|
try {
|
|
32815
33148
|
unlinkSync3(path);
|
|
@@ -34292,12 +34625,12 @@ async function confirmRollback(deploymentId) {
|
|
|
34292
34625
|
}
|
|
34293
34626
|
|
|
34294
34627
|
// src/commands/doctor.ts
|
|
34295
|
-
import { existsSync as existsSync40, statSync as statSync6, readFileSync as
|
|
34628
|
+
import { existsSync as existsSync40, statSync as statSync6, readFileSync as readFileSync30 } from "node:fs";
|
|
34296
34629
|
import { homedir as homedir9, platform as platform6 } from "node:os";
|
|
34297
34630
|
import { join as join33, delimiter as delimiter3 } from "node:path";
|
|
34298
34631
|
|
|
34299
34632
|
// src/lib/version-check.ts
|
|
34300
|
-
import { existsSync as existsSync39, mkdirSync as mkdirSync18, readFileSync as
|
|
34633
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync18, readFileSync as readFileSync29, writeFileSync as writeFileSync21 } from "node:fs";
|
|
34301
34634
|
import { join as join32 } from "node:path";
|
|
34302
34635
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
34303
34636
|
var FETCH_TIMEOUT_MS2 = 2000;
|
|
@@ -34312,7 +34645,7 @@ function readCache() {
|
|
|
34312
34645
|
if (!existsSync39(cacheFile()))
|
|
34313
34646
|
return null;
|
|
34314
34647
|
try {
|
|
34315
|
-
const raw = JSON.parse(
|
|
34648
|
+
const raw = JSON.parse(readFileSync29(cacheFile(), "utf-8"));
|
|
34316
34649
|
if (typeof raw.latest !== "string" || typeof raw.fetchedAt !== "number")
|
|
34317
34650
|
return null;
|
|
34318
34651
|
return { latest: raw.latest, fetchedAt: raw.fetchedAt };
|
|
@@ -34458,7 +34791,7 @@ function checkConfigFile() {
|
|
|
34458
34791
|
} catch {}
|
|
34459
34792
|
}
|
|
34460
34793
|
try {
|
|
34461
|
-
JSON.parse(
|
|
34794
|
+
JSON.parse(readFileSync30(path, "utf-8"));
|
|
34462
34795
|
} catch (err) {
|
|
34463
34796
|
return {
|
|
34464
34797
|
name: "Config file",
|
|
@@ -35341,7 +35674,7 @@ function registerInstallationCommands(program) {
|
|
|
35341
35674
|
}
|
|
35342
35675
|
|
|
35343
35676
|
// src/commands/invoke.ts
|
|
35344
|
-
import { existsSync as existsSync41, readFileSync as
|
|
35677
|
+
import { existsSync as existsSync41, readFileSync as readFileSync31 } from "node:fs";
|
|
35345
35678
|
import { join as join34 } from "node:path";
|
|
35346
35679
|
|
|
35347
35680
|
// src/lib/dev/local-invoke.ts
|
|
@@ -35434,9 +35767,9 @@ function selectCodeModeInvocation(args) {
|
|
|
35434
35767
|
}
|
|
35435
35768
|
function readCodeOption(raw) {
|
|
35436
35769
|
if (raw === "@-")
|
|
35437
|
-
return
|
|
35770
|
+
return readFileSync31(0, "utf-8");
|
|
35438
35771
|
if (raw.startsWith("@"))
|
|
35439
|
-
return
|
|
35772
|
+
return readFileSync31(raw.slice(1), "utf-8");
|
|
35440
35773
|
return raw;
|
|
35441
35774
|
}
|
|
35442
35775
|
function parseTimeoutMs4(value, fallbackMs) {
|
|
@@ -35718,7 +36051,7 @@ async function runLocalInvoke(args) {
|
|
|
35718
36051
|
throw new CliExitError(1);
|
|
35719
36052
|
}
|
|
35720
36053
|
const env = {
|
|
35721
|
-
...args.envFile ? parseEnvFile(
|
|
36054
|
+
...args.envFile ? parseEnvFile(readFileSync31(args.envFile, "utf-8")) : {},
|
|
35722
36055
|
...parseEnvPairs(args.envPairs)
|
|
35723
36056
|
};
|
|
35724
36057
|
const port = await findAvailablePort({ range: 40, start: 43117 });
|
|
@@ -36710,7 +37043,7 @@ import {
|
|
|
36710
37043
|
existsSync as existsSync42,
|
|
36711
37044
|
mkdirSync as mkdirSync19,
|
|
36712
37045
|
readdirSync as readdirSync5,
|
|
36713
|
-
readFileSync as
|
|
37046
|
+
readFileSync as readFileSync32,
|
|
36714
37047
|
rmSync as rmSync3,
|
|
36715
37048
|
statSync as statSync7
|
|
36716
37049
|
} from "node:fs";
|
|
@@ -36730,7 +37063,7 @@ function readManifestFromPackageDir(packageDir) {
|
|
|
36730
37063
|
return null;
|
|
36731
37064
|
let pkg;
|
|
36732
37065
|
try {
|
|
36733
|
-
pkg = JSON.parse(
|
|
37066
|
+
pkg = JSON.parse(readFileSync32(pkgPath, "utf-8"));
|
|
36734
37067
|
} catch {
|
|
36735
37068
|
return null;
|
|
36736
37069
|
}
|
|
@@ -38483,7 +38816,7 @@ function displayValueFor(field, value) {
|
|
|
38483
38816
|
import {
|
|
38484
38817
|
existsSync as existsSync43,
|
|
38485
38818
|
mkdirSync as mkdirSync20,
|
|
38486
|
-
readFileSync as
|
|
38819
|
+
readFileSync as readFileSync33,
|
|
38487
38820
|
writeFileSync as writeFileSync22
|
|
38488
38821
|
} from "node:fs";
|
|
38489
38822
|
import { join as join36 } from "node:path";
|
|
@@ -38565,7 +38898,7 @@ function readTuiState() {
|
|
|
38565
38898
|
return {};
|
|
38566
38899
|
let parsed;
|
|
38567
38900
|
try {
|
|
38568
|
-
parsed = JSON.parse(
|
|
38901
|
+
parsed = JSON.parse(readFileSync33(path, "utf-8"));
|
|
38569
38902
|
} catch {
|
|
38570
38903
|
return {};
|
|
38571
38904
|
}
|