@rosthq/cli 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +113 -21
- package/dist/index.js.map +3 -3
- package/dist/mcp-install.d.ts +15 -0
- package/dist/mcp-install.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAoB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAYrE,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAoB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAYrE,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAK1C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,KAAK,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,mBAAmB,CAAC;CAC1C,CAAC;AAEF,wBAAsB,IAAI,CAAC,IAAI,WAAwB,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyKnG;AAwXD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAUxF"}
|
package/dist/index.js
CHANGED
|
@@ -42241,7 +42241,7 @@ Agents should explain the job, the required tool category, the minimum permissio
|
|
|
42241
42241
|
order: 48,
|
|
42242
42242
|
title: "CLI and MCP installation guide",
|
|
42243
42243
|
summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
|
|
42244
|
-
version: "2026-06-18.
|
|
42244
|
+
version: "2026-06-18.8",
|
|
42245
42245
|
public: true,
|
|
42246
42246
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
42247
42247
|
stages: ["company_setup", "staffing"],
|
|
@@ -42306,7 +42306,7 @@ The MCP server is remote and token-backed. There is no local MCP daemon to insta
|
|
|
42306
42306
|
A headless agent cannot complete setup unattended. Two things always require a human, so plan to announce the handoff rather than stall silently:
|
|
42307
42307
|
|
|
42308
42308
|
- **Device-code approval at first login.** \`{{cli}} login --device\` prints a code; a human must open the workspace URL in a browser, sign in with Google, match the code, and approve.
|
|
42309
|
-
- **Durable gated commands.** Setting or approving a Charter, staffing a seat, and taking an agent live each open a confirmation that a human approves (an agent never approves its own request \u2014 see the confirmations-guide). The CLI surfaces the \`confirmation_id\` and an \`approveVia\` URL for the human. (\`{{cli}} mcp install\` is
|
|
42309
|
+
- **Durable gated commands.** Setting or approving a Charter, staffing a seat, and taking an agent live each open a confirmation that a human approves (an agent never approves its own request \u2014 see the confirmations-guide). The CLI surfaces the \`confirmation_id\` and an \`approveVia\` URL for the human. (\`{{cli}} mcp install\` is a partial exception: for an **interactive** operator it completes its own token-mint approval inline; in a **headless/agent** session it surfaces the confirmation and stops unless \`--skip-permissions\` / \`{{envPrefix}}_CLI_SKIP_PERMISSIONS=1\` is set \u2014 see Approving the token mint below.)
|
|
42310
42310
|
|
|
42311
42311
|
Treat these as blocking prerequisites: the agent prepares the request and waits for the human approver.
|
|
42312
42312
|
|
|
@@ -42420,6 +42420,8 @@ Or use the one-shot helper: \`{{cli}} init\` logs in when needed, optionally sel
|
|
|
42420
42420
|
|
|
42421
42421
|
A direct \`mcp install\` now **requires an explicit \`--scope\`** \u2014 there is no silent default. Choose \`--scope seat --seat-id <id>\` (the narrowest scope, limited to one seat's Charter and permission manifest \u2014 prefer it for day-to-day operation) or \`--scope tenant-admin\` (can administer the whole company \u2014 reserve it for initial setup). Running \`mcp install\` without \`--scope\` errors and mints nothing, naming both options. (The first-run helper \`{{cli}} init\` is the exception: it defaults to \`--scope tenant-admin\` because no seats exist yet at setup; and \`--rotate\` inherits the old token's scope, so it does not need \`--scope\` either.)
|
|
42422
42422
|
|
|
42423
|
+
\`mcp install\` accepts an optional \`--skip-permissions\` flag (equivalently \`{{envPrefix}}_CLI_SKIP_PERMISSIONS=1\`). It governs the token-mint approval in a non-interactive session \u2014 see Approving the token mint below. An interactive operator never needs it.
|
|
42424
|
+
|
|
42423
42425
|
Claude Code (tenant-admin):
|
|
42424
42426
|
|
|
42425
42427
|
\`\`\`bash
|
|
@@ -42450,9 +42452,13 @@ The \`<seat-id>\` comes from \`{{cli}} command seat.create\` output or \`rost_ge
|
|
|
42450
42452
|
|
|
42451
42453
|
### Approving the token mint
|
|
42452
42454
|
|
|
42453
|
-
Minting a token is a human-gated authority change at the command layer.
|
|
42455
|
+
Minting a token (and the inline revoke that \`--rotate\` performs) is a human-gated authority change at the command layer. How \`{{cli}} mcp install\` handles that approval depends on whether it runs in an interactive session:
|
|
42456
|
+
|
|
42457
|
+
- **Interactive operator (a human at a real terminal).** The CLI completes the approval **inline**: the operator who ran the command is the human in the loop, so it runs the gated mint, completes the confirmation for that same command, and prints the registration block \u2014 a single step, no separate URL to click.
|
|
42458
|
+
- **Non-interactive / headless / agent session.** The CLI does **not** approve its own request. By default it **surfaces the confirmation and stops**, minting nothing: it prints the \`confirmation_id\`, the exact \`{{cli}} command confirmation.approve --json '{"confirmation_id":"<id>"}'\` command, and the \`approveVia\` URL when the server provided one, then exits non-zero ("pending human approval"). A human then approves it (in a browser or with that approve command) \u2014 and that approval **executes the mint and returns the token in the approve output** (shown once), so register it with your client from there. Do **not** re-run \`mcp install\` after approving: that starts a second mint and orphans the first token. (For an unattended agent that should mint and register in one step, use \`--skip-permissions\` below.)
|
|
42459
|
+
- **Opting into auto-approval in a headless session.** Pass \`--skip-permissions\` on \`mcp install\`, or set \`{{envPrefix}}_CLI_SKIP_PERMISSIONS=1\`, to auto-approve the mint/revoke confirmation inline even without a TTY. This is a deliberate loosening (the running session stands in for the human approver) \u2014 use it only for trusted automation where you accept that the agent approves its own token mint.
|
|
42454
42460
|
|
|
42455
|
-
The broader rule still holds for durable changes an agent proposes \u2014 charters, decisions, compass and charter amendments \u2014 where an agent never approves its own request and a human approves the surfaced \`approveVia\` confirmation. See the confirmations-guide for the four confirmation levels and that flow.
|
|
42461
|
+
The broader rule still holds for durable changes an agent proposes \u2014 charters, decisions, compass and charter amendments \u2014 where an agent never approves its own request and a human approves the surfaced \`approveVia\` confirmation. See the confirmations-guide for the four confirmation levels and that flow.
|
|
42456
42462
|
|
|
42457
42463
|
### Handling the printed token (read this before you paste anything)
|
|
42458
42464
|
|
|
@@ -42654,8 +42660,9 @@ These ergonomic wrappers (including the \`{{cli}} agent\` group) require **{{cli
|
|
|
42654
42660
|
|
|
42655
42661
|
| Command | Purpose | Scope | Safe example |
|
|
42656
42662
|
|---|---|---|---|
|
|
42657
|
-
| \`{{cli}} mcp install --client claude-code|codex|cursor --scope tenant-admin|seat [--seat-id <id>] [--expires-in <days>|--no-expiry]\` | **Direct install** syntax. \`--scope\` is **required** (seat is narrower \u2014 prefer it for day-to-day; tenant-admin can administer the whole company). \`--expires-in <days>\` (1..365) or \`--no-expiry\` sets the token TTL (default 90 days). | Tenant | \`{{cli}} mcp install --client codex --scope tenant-admin --expires-in 30\` |
|
|
42663
|
+
| \`{{cli}} mcp install --client claude-code|codex|cursor --scope tenant-admin|seat [--seat-id <id>] [--expires-in <days>|--no-expiry] [--skip-permissions]\` | **Direct install** syntax. \`--scope\` is **required** (seat is narrower \u2014 prefer it for day-to-day; tenant-admin can administer the whole company). \`--expires-in <days>\` (1..365) or \`--no-expiry\` sets the token TTL (default 90 days). \`--skip-permissions\` auto-approves the token-mint confirmation in a non-interactive session (see below). | Tenant | \`{{cli}} mcp install --client codex --scope tenant-admin --expires-in 30\` |
|
|
42658
42664
|
| \`{{cli}} mcp install --client claude-code|codex|cursor --rotate <old-token-id> (inherits the old token's scope; no --scope)\` | **Rotate** syntax. Mints a replacement, **inherits the old token's scope/seat** (so do not pass \`--scope\`), prints the new registration block, and revokes the old token. | Tenant | \`{{cli}} mcp install --client codex --rotate <old-token-id>\` |
|
|
42665
|
+
| \`{{cli}} mcp install ... --skip-permissions (or {{envPrefix}}_CLI_SKIP_PERMISSIONS=1 \u2014 auto-approves the token-mint confirmation in a non-interactive session)\` | **Skip-permissions** opt-in. In a headless/agent session, auto-approve the \`human_required\` token-mint (and rotate revoke) confirmation inline instead of surfacing it for a human (a deliberate loosening). An interactive operator never needs it. | Tenant | \`{{cli}} mcp install --client codex --scope seat --seat-id <seat-id> --skip-permissions\` |
|
|
42659
42666
|
| \`{{cli}} mcp install --client claude-code --scope tenant-admin\` | Mint a tenant-admin MCP token and print a Claude Code registration command. | Tenant | \`{{cli}} mcp install --client claude-code --scope tenant-admin\` |
|
|
42660
42667
|
| \`{{cli}} mcp install --client codex --scope tenant-admin\` | Mint a tenant-admin MCP token and print Codex TOML. | Tenant | \`{{cli}} mcp install --client codex --scope tenant-admin\` |
|
|
42661
42668
|
| \`{{cli}} mcp install --client cursor --scope tenant-admin\` | Mint a tenant-admin MCP token and print Cursor JSON. | Tenant | \`{{cli}} mcp install --client cursor --scope tenant-admin\` |
|
|
@@ -44268,9 +44275,14 @@ var mcpTokenListEntrySchema = external_exports.object({
|
|
|
44268
44275
|
var mcpTokenListOutputSchema = external_exports.object({
|
|
44269
44276
|
tokens: external_exports.array(mcpTokenListEntrySchema)
|
|
44270
44277
|
}).passthrough();
|
|
44278
|
+
var approveViaSchema = external_exports.object({
|
|
44279
|
+
webUrl: external_exports.string().min(1).optional(),
|
|
44280
|
+
cliCommand: external_exports.string().min(1).optional()
|
|
44281
|
+
}).passthrough();
|
|
44271
44282
|
var pendingConfirmationSchema = external_exports.object({
|
|
44272
44283
|
confirmationId: external_exports.string().min(1),
|
|
44273
|
-
commandId: external_exports.string().min(1)
|
|
44284
|
+
commandId: external_exports.string().min(1),
|
|
44285
|
+
approveVia: approveViaSchema.optional().catch(void 0)
|
|
44274
44286
|
}).passthrough();
|
|
44275
44287
|
var confirmationApprovalOutputSchema = external_exports.object({
|
|
44276
44288
|
confirmation_id: external_exports.string().min(1),
|
|
@@ -44286,6 +44298,7 @@ function parseMcpInstallOptions(args) {
|
|
|
44286
44298
|
let expiresInDays;
|
|
44287
44299
|
let noExpiry = false;
|
|
44288
44300
|
let rotateTokenId;
|
|
44301
|
+
let skipPermissions = false;
|
|
44289
44302
|
for (let index = 0; index < args.length; index += 1) {
|
|
44290
44303
|
const arg = args[index];
|
|
44291
44304
|
if (arg === "--client") {
|
|
@@ -44308,6 +44321,8 @@ function parseMcpInstallOptions(args) {
|
|
|
44308
44321
|
index += 1;
|
|
44309
44322
|
} else if (arg === "--json") {
|
|
44310
44323
|
json2 = true;
|
|
44324
|
+
} else if (arg === "--skip-permissions") {
|
|
44325
|
+
skipPermissions = true;
|
|
44311
44326
|
} else {
|
|
44312
44327
|
throw new Error(`Unknown mcp install option: ${arg}`);
|
|
44313
44328
|
}
|
|
@@ -44328,24 +44343,71 @@ function parseMcpInstallOptions(args) {
|
|
|
44328
44343
|
...seatId === void 0 ? {} : { seatId },
|
|
44329
44344
|
json: json2,
|
|
44330
44345
|
expiry,
|
|
44331
|
-
...rotateTokenId === void 0 ? {} : { rotateTokenId }
|
|
44346
|
+
...rotateTokenId === void 0 ? {} : { rotateTokenId },
|
|
44347
|
+
skipPermissions
|
|
44332
44348
|
};
|
|
44333
44349
|
}
|
|
44334
44350
|
var MISSING_SCOPE_MESSAGE = `${cliBrand.binName} mcp install requires an explicit --scope. Choose: --scope seat --seat-id <id> (narrower \u2014 limited to one seat's Charter and permission manifest; prefer this for day-to-day operation), or --scope tenant-admin (can administer the whole company \u2014 reserve it for initial setup). Find a seat id with: ${cliBrand.binName} command graph.get --json '{}'.`;
|
|
44335
44351
|
var MCP_TOKEN_CAUTION = "Security: this minted MCP token is a live credential that lands in the client's plaintext config \u2014 prefer the narrowest scope (--scope seat --seat-id <id>) and revoke it immediately if it leaks.";
|
|
44336
44352
|
var NO_EXPIRY_WARNING = "Warning: --no-expiry mints a token with no practical expiry (a ~100-year TTL). This is a long-lived credential by choice \u2014 rotate it deliberately and revoke immediately if it leaks.";
|
|
44353
|
+
var PendingConfirmationError = class extends Error {
|
|
44354
|
+
confirmationId;
|
|
44355
|
+
commandId;
|
|
44356
|
+
approveCommand;
|
|
44357
|
+
approveUrl;
|
|
44358
|
+
constructor(input) {
|
|
44359
|
+
super(`Pending human approval for ${input.commandId} (confirmation ${input.confirmationId}).`);
|
|
44360
|
+
this.name = "PendingConfirmationError";
|
|
44361
|
+
this.confirmationId = input.confirmationId;
|
|
44362
|
+
this.commandId = input.commandId;
|
|
44363
|
+
this.approveCommand = input.approveCommand;
|
|
44364
|
+
if (input.approveUrl !== void 0) {
|
|
44365
|
+
this.approveUrl = input.approveUrl;
|
|
44366
|
+
}
|
|
44367
|
+
}
|
|
44368
|
+
// The multi-line human-handoff message rendered on stderr by the caller. It
|
|
44369
|
+
// names the gated command, the confirmation id, the exact approve command, and
|
|
44370
|
+
// the approveVia URL when the server provided one.
|
|
44371
|
+
toHandoffMessage() {
|
|
44372
|
+
const isRevoke = this.commandId === "mcp_token.revoke";
|
|
44373
|
+
const lines = isRevoke ? [
|
|
44374
|
+
`Pending human approval: revoking the old token (${this.commandId}) requires a human to approve confirmation ${this.confirmationId}.`,
|
|
44375
|
+
"The new token was minted and registered, but the OLD token is still live until its revocation is approved.",
|
|
44376
|
+
`Approve the revocation: ${this.approveCommand}`
|
|
44377
|
+
] : [
|
|
44378
|
+
`Pending human approval: ${this.commandId} requires a human to approve confirmation ${this.confirmationId} before the MCP token is minted.`,
|
|
44379
|
+
"This is a non-interactive session and --skip-permissions is not set, so nothing was minted yet.",
|
|
44380
|
+
// confirmation.approve EXECUTES the deferred mint and returns the token in
|
|
44381
|
+
// its own output (shown once) — it does not just unlock a re-run. So the
|
|
44382
|
+
// approver registers the token from that output; re-running mcp install
|
|
44383
|
+
// would start a SECOND mint and orphan the first.
|
|
44384
|
+
`A human approves with: ${this.approveCommand} \u2014 this mints the token and returns it in that command's output (shown once). Register it with your client from there; do not re-run mcp install afterward (that starts a new mint).`
|
|
44385
|
+
];
|
|
44386
|
+
if (this.approveUrl !== void 0) {
|
|
44387
|
+
lines.push(`Or approve in a browser: ${this.approveUrl}`);
|
|
44388
|
+
}
|
|
44389
|
+
lines.push(
|
|
44390
|
+
`To auto-approve inline in a headless session instead, pass --skip-permissions or set ${brandEnvKey3("CLI_SKIP_PERMISSIONS")}=1 (a deliberate loosening).`
|
|
44391
|
+
);
|
|
44392
|
+
return lines.join("\n");
|
|
44393
|
+
}
|
|
44394
|
+
};
|
|
44395
|
+
function brandEnvKey3(suffix) {
|
|
44396
|
+
return `${cliBrand.envPrefix}_${suffix}`;
|
|
44397
|
+
}
|
|
44337
44398
|
async function renderMcpInstall(input) {
|
|
44338
44399
|
const stderrLines = [];
|
|
44400
|
+
const canAutoApprove = input.canAutoApprove ?? false;
|
|
44339
44401
|
if (input.options.rotateTokenId === void 0 && input.options.scope === void 0) {
|
|
44340
44402
|
throw new Error(MISSING_SCOPE_MESSAGE);
|
|
44341
44403
|
}
|
|
44342
|
-
const mintScope = input.options.rotateTokenId === void 0 ? { scope: input.options.scope, ...input.options.seatId === void 0 ? {} : { seatId: input.options.seatId } } : await resolveRotationScope(input.client, input.options);
|
|
44343
|
-
const token = await createMcpToken(input.client, mcpTokenCreateBody(mintScope, input.options.expiry));
|
|
44404
|
+
const mintScope = input.options.rotateTokenId === void 0 ? { scope: input.options.scope, ...input.options.seatId === void 0 ? {} : { seatId: input.options.seatId } } : await resolveRotationScope(input.client, input.options, canAutoApprove);
|
|
44405
|
+
const token = await createMcpToken(input.client, mcpTokenCreateBody(mintScope, input.options.expiry), canAutoApprove);
|
|
44344
44406
|
let rotationOldRevoked = null;
|
|
44345
44407
|
if (input.options.rotateTokenId !== void 0) {
|
|
44346
44408
|
const oldTokenId = input.options.rotateTokenId;
|
|
44347
44409
|
try {
|
|
44348
|
-
const output = await executeWithConfirmation(input.client, "mcp_token.revoke", { token_id: oldTokenId });
|
|
44410
|
+
const output = await executeWithConfirmation(input.client, "mcp_token.revoke", { token_id: oldTokenId }, canAutoApprove);
|
|
44349
44411
|
const revoke = mcpTokenRevokeOutputSchema.safeParse(output);
|
|
44350
44412
|
rotationOldRevoked = revoke.success && revoke.data.revoked === true;
|
|
44351
44413
|
if (!rotationOldRevoked) {
|
|
@@ -44355,6 +44417,9 @@ async function renderMcpInstall(input) {
|
|
|
44355
44417
|
);
|
|
44356
44418
|
}
|
|
44357
44419
|
} catch (error51) {
|
|
44420
|
+
if (error51 instanceof PendingConfirmationError) {
|
|
44421
|
+
throw error51;
|
|
44422
|
+
}
|
|
44358
44423
|
rotationOldRevoked = false;
|
|
44359
44424
|
stderrLines.push(
|
|
44360
44425
|
`Warning: the new token (${token.token_id}) was minted, but revoking the old token (${oldTokenId}) failed: ${revokeFailureReason(error51)}. It is still live. Revoke it by hand: ${cliBrand.binName} command mcp_token.revoke --json '{"token_id":"${oldTokenId}"}'`
|
|
@@ -44423,9 +44488,9 @@ function mcpTokenCreateBody(mint, expiry) {
|
|
|
44423
44488
|
}
|
|
44424
44489
|
return base;
|
|
44425
44490
|
}
|
|
44426
|
-
async function resolveRotationScope(client, options) {
|
|
44491
|
+
async function resolveRotationScope(client, options, canAutoApprove) {
|
|
44427
44492
|
const oldTokenId = options.rotateTokenId;
|
|
44428
|
-
const listOutput = await executeWithConfirmation(client, "mcp_token.list", { include_revoked: true });
|
|
44493
|
+
const listOutput = await executeWithConfirmation(client, "mcp_token.list", { include_revoked: true }, canAutoApprove);
|
|
44429
44494
|
const parsed = mcpTokenListOutputSchema.safeParse(listOutput);
|
|
44430
44495
|
if (!parsed.success) {
|
|
44431
44496
|
throw new Error("Could not read the token list to rotate \u2014 mcp_token.list returned an unexpected shape.");
|
|
@@ -44488,11 +44553,11 @@ function revokeFailureReason(error51) {
|
|
|
44488
44553
|
}
|
|
44489
44554
|
return "unknown error";
|
|
44490
44555
|
}
|
|
44491
|
-
async function createMcpToken(client, body) {
|
|
44492
|
-
const output = await executeWithConfirmation(client, "mcp_token.create", body);
|
|
44556
|
+
async function createMcpToken(client, body, canAutoApprove) {
|
|
44557
|
+
const output = await executeWithConfirmation(client, "mcp_token.create", body, canAutoApprove);
|
|
44493
44558
|
return mcpTokenOutputSchema.parse(output);
|
|
44494
44559
|
}
|
|
44495
|
-
async function executeWithConfirmation(client, commandId, body) {
|
|
44560
|
+
async function executeWithConfirmation(client, commandId, body, canAutoApprove) {
|
|
44496
44561
|
try {
|
|
44497
44562
|
const result = await client.execute(commandId, body);
|
|
44498
44563
|
return result.output;
|
|
@@ -44501,6 +44566,14 @@ async function executeWithConfirmation(client, commandId, body) {
|
|
|
44501
44566
|
if (!pending) {
|
|
44502
44567
|
throw error51;
|
|
44503
44568
|
}
|
|
44569
|
+
if (!canAutoApprove) {
|
|
44570
|
+
throw new PendingConfirmationError({
|
|
44571
|
+
confirmationId: pending.confirmationId,
|
|
44572
|
+
commandId: pending.commandId,
|
|
44573
|
+
approveCommand: `${cliBrand.binName} command confirmation.approve --json '{"confirmation_id":"${pending.confirmationId}"}'`,
|
|
44574
|
+
...pending.approveVia?.webUrl === void 0 ? {} : { approveUrl: pending.approveVia.webUrl }
|
|
44575
|
+
});
|
|
44576
|
+
}
|
|
44504
44577
|
const approved = await client.execute("confirmation.approve", {
|
|
44505
44578
|
confirmation_id: pending.confirmationId
|
|
44506
44579
|
});
|
|
@@ -45865,7 +45938,15 @@ function ensureTrailingSlash2(value) {
|
|
|
45865
45938
|
|
|
45866
45939
|
// src/index.ts
|
|
45867
45940
|
async function main(argv = process.argv.slice(2), options = {}) {
|
|
45868
|
-
const io = options.io ?? {
|
|
45941
|
+
const io = options.io ?? {
|
|
45942
|
+
stdout: process.stdout,
|
|
45943
|
+
stderr: process.stderr,
|
|
45944
|
+
// DER-832: an interactive session is a human at a real terminal — BOTH stdin
|
|
45945
|
+
// and stdout must be TTYs. A piped/headless/agent session fails this and so
|
|
45946
|
+
// will not auto-approve its own mint/revoke confirmation unless skip-
|
|
45947
|
+
// permissions is explicitly enabled.
|
|
45948
|
+
interactive: process.stdin.isTTY === true && process.stdout.isTTY === true
|
|
45949
|
+
};
|
|
45869
45950
|
const login = options.login ?? loginWithBrowser;
|
|
45870
45951
|
const deviceLogin = options.deviceLogin ?? loginWithDeviceCode;
|
|
45871
45952
|
const [rawCommand, ...args] = argv;
|
|
@@ -46152,23 +46233,28 @@ async function executeOnboard(io, client, args) {
|
|
|
46152
46233
|
`);
|
|
46153
46234
|
return 1;
|
|
46154
46235
|
}
|
|
46155
|
-
async function executeMcp(io, client, appUrl2, args) {
|
|
46236
|
+
async function executeMcp(io, client, appUrl2, args, env = process.env) {
|
|
46156
46237
|
if (args[0] !== "install") {
|
|
46157
46238
|
io.stderr.write(
|
|
46158
46239
|
`Usage:
|
|
46159
|
-
${cliBrand.binName} mcp install --client claude-code|codex|cursor --scope tenant-admin|seat [--seat-id <id>] [--expires-in <days>|--no-expiry]
|
|
46240
|
+
${cliBrand.binName} mcp install --client claude-code|codex|cursor --scope tenant-admin|seat [--seat-id <id>] [--expires-in <days>|--no-expiry] [--skip-permissions]
|
|
46160
46241
|
Direct install \u2014 --scope is required (seat is narrower; prefer it for day-to-day).
|
|
46161
|
-
${cliBrand.binName} mcp install --client claude-code|codex|cursor --rotate <old-token-id>
|
|
46242
|
+
${cliBrand.binName} mcp install --client claude-code|codex|cursor --rotate <old-token-id> [--skip-permissions]
|
|
46162
46243
|
Rotate in place \u2014 inherits the old token's scope, so do not pass --scope.
|
|
46244
|
+
--skip-permissions (or ${cliBrand.envPrefix}_CLI_SKIP_PERMISSIONS=1) auto-approves the token-mint confirmation in a non-interactive session.
|
|
46163
46245
|
`
|
|
46164
46246
|
);
|
|
46165
46247
|
return 1;
|
|
46166
46248
|
}
|
|
46167
46249
|
try {
|
|
46250
|
+
const options = parseMcpInstallOptions(args.slice(1));
|
|
46251
|
+
const envSkipPermissions = env[`${cliBrand.envPrefix}_CLI_SKIP_PERMISSIONS`] === "1";
|
|
46252
|
+
const canAutoApprove = io.interactive === true || options.skipPermissions || envSkipPermissions;
|
|
46168
46253
|
const rendered = await renderMcpInstall({
|
|
46169
46254
|
client,
|
|
46170
46255
|
appUrl: appUrl2,
|
|
46171
|
-
options
|
|
46256
|
+
options,
|
|
46257
|
+
canAutoApprove
|
|
46172
46258
|
});
|
|
46173
46259
|
io.stdout.write(rendered.stdout);
|
|
46174
46260
|
if (rendered.stderr) {
|
|
@@ -46176,6 +46262,11 @@ async function executeMcp(io, client, appUrl2, args) {
|
|
|
46176
46262
|
}
|
|
46177
46263
|
return 0;
|
|
46178
46264
|
} catch (error51) {
|
|
46265
|
+
if (error51 instanceof PendingConfirmationError) {
|
|
46266
|
+
io.stderr.write(`${redactForLog(error51.toHandoffMessage())}
|
|
46267
|
+
`);
|
|
46268
|
+
return 1;
|
|
46269
|
+
}
|
|
46179
46270
|
if (error51 instanceof CommandClientError) {
|
|
46180
46271
|
return printCommandError(io, error51);
|
|
46181
46272
|
}
|
|
@@ -46289,8 +46380,9 @@ function printUsage(io) {
|
|
|
46289
46380
|
...operationUsageLines(cliBrand.binName),
|
|
46290
46381
|
`${cliBrand.binName} onboard status`,
|
|
46291
46382
|
`${cliBrand.binName} onboard run`,
|
|
46292
|
-
`${cliBrand.binName} mcp install --client claude-code|codex|cursor --scope tenant-admin|seat [--seat-id <id>] [--expires-in <days>|--no-expiry]`,
|
|
46383
|
+
`${cliBrand.binName} mcp install --client claude-code|codex|cursor --scope tenant-admin|seat [--seat-id <id>] [--expires-in <days>|--no-expiry] [--skip-permissions]`,
|
|
46293
46384
|
`${cliBrand.binName} mcp install --client claude-code|codex|cursor --rotate <old-token-id> (inherits the old token's scope; no --scope)`,
|
|
46385
|
+
`${cliBrand.binName} mcp install ... --skip-permissions (or ${cliBrand.envPrefix}_CLI_SKIP_PERMISSIONS=1 \u2014 auto-approves the token-mint confirmation in a non-interactive session)`,
|
|
46294
46386
|
`${cliBrand.binName} init [--client claude-code|codex|cursor] (defaults --scope tenant-admin)`,
|
|
46295
46387
|
`${cliBrand.binName} docs`,
|
|
46296
46388
|
`${cliBrand.binName} reference <list|search|get> [options]`,
|