@rosthq/cli 0.7.27 → 0.7.29
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-manifest.d.ts","sourceRoot":"","sources":["../../src/generated/command-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,gBAAgB,EAAE,SAAS,oBAAoB,
|
|
1
|
+
{"version":3,"file":"command-manifest.d.ts","sourceRoot":"","sources":["../../src/generated/command-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,gBAAgB,EAAE,SAAS,oBAAoB,EAmO3D,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -37346,15 +37346,25 @@ ${secret}
|
|
|
37346
37346
|
}
|
|
37347
37347
|
};
|
|
37348
37348
|
var DarwinTokenStore = class extends KeychainTokenStore {
|
|
37349
|
-
constructor(run2 = runExecFile, filePath) {
|
|
37349
|
+
constructor(run2 = runExecFile, filePath, stderr = process.stderr) {
|
|
37350
37350
|
super(run2);
|
|
37351
37351
|
this.filePath = filePath;
|
|
37352
|
+
this.stderr = stderr;
|
|
37352
37353
|
}
|
|
37353
37354
|
filePath;
|
|
37355
|
+
stderr;
|
|
37354
37356
|
backend = null;
|
|
37357
|
+
fileBackendReason = null;
|
|
37355
37358
|
fileStore = null;
|
|
37356
37359
|
async read() {
|
|
37357
|
-
|
|
37360
|
+
if (await this.selectBackend() === "file") {
|
|
37361
|
+
return this.file().read();
|
|
37362
|
+
}
|
|
37363
|
+
const keychainSession = await super.read();
|
|
37364
|
+
if (keychainSession) {
|
|
37365
|
+
return keychainSession;
|
|
37366
|
+
}
|
|
37367
|
+
return this.readFileStoreBestEffort();
|
|
37358
37368
|
}
|
|
37359
37369
|
async write(session) {
|
|
37360
37370
|
if (await this.selectBackend() === "file") {
|
|
@@ -37362,20 +37372,49 @@ var DarwinTokenStore = class extends KeychainTokenStore {
|
|
|
37362
37372
|
return;
|
|
37363
37373
|
}
|
|
37364
37374
|
await super.write(session);
|
|
37375
|
+
if (await this.keychainReadBackFailed(session)) {
|
|
37376
|
+
this.backend = "file";
|
|
37377
|
+
this.fileBackendReason = "unreadable";
|
|
37378
|
+
await this.file().write(session);
|
|
37379
|
+
await super.clear();
|
|
37380
|
+
this.warnKeychainNotReadableBack();
|
|
37381
|
+
}
|
|
37365
37382
|
}
|
|
37366
37383
|
async clear() {
|
|
37367
|
-
if (await this.selectBackend() === "file") {
|
|
37368
|
-
await this.file().clear();
|
|
37369
|
-
return;
|
|
37370
|
-
}
|
|
37371
37384
|
await super.clear();
|
|
37385
|
+
await this.file().clear();
|
|
37372
37386
|
}
|
|
37373
37387
|
describe() {
|
|
37374
|
-
|
|
37388
|
+
if (this.backend !== "file") {
|
|
37389
|
+
return super.describe();
|
|
37390
|
+
}
|
|
37391
|
+
return this.fileBackendReason === "unreadable" ? "owner-only file store (macOS keychain not readable back cross-process)" : "owner-only file store (no usable macOS keychain)";
|
|
37375
37392
|
}
|
|
37376
37393
|
file() {
|
|
37377
37394
|
return this.fileStore ??= new FileTokenStore(this.filePath);
|
|
37378
37395
|
}
|
|
37396
|
+
async readFileStoreBestEffort() {
|
|
37397
|
+
try {
|
|
37398
|
+
return await this.file().read();
|
|
37399
|
+
} catch {
|
|
37400
|
+
return null;
|
|
37401
|
+
}
|
|
37402
|
+
}
|
|
37403
|
+
async keychainReadBackFailed(session) {
|
|
37404
|
+
try {
|
|
37405
|
+
const readBack = await super.read();
|
|
37406
|
+
return readBack?.accessToken !== session.accessToken;
|
|
37407
|
+
} catch {
|
|
37408
|
+
return true;
|
|
37409
|
+
}
|
|
37410
|
+
}
|
|
37411
|
+
warnKeychainNotReadableBack() {
|
|
37412
|
+
const envKey = brandEnvKey2("CLI_ALLOW_FILE_TOKEN_STORE");
|
|
37413
|
+
this.stderr.write(
|
|
37414
|
+
`NOTICE: the macOS Keychain accepted the session but it was not readable back (cross-process keychain read failed). Wrote the session to the ${this.file().describe()} instead. For headless / non-interactive use, export ${envKey}=1 so later commands read it directly.
|
|
37415
|
+
`
|
|
37416
|
+
);
|
|
37417
|
+
}
|
|
37379
37418
|
async selectBackend() {
|
|
37380
37419
|
if (this.backend) {
|
|
37381
37420
|
return this.backend;
|
|
@@ -37384,7 +37423,12 @@ var DarwinTokenStore = class extends KeychainTokenStore {
|
|
|
37384
37423
|
await this.run("security", ["find-generic-password", "-s", serviceName, "-a", accountName, "-w"]);
|
|
37385
37424
|
this.backend = "keychain";
|
|
37386
37425
|
} catch (error51) {
|
|
37387
|
-
|
|
37426
|
+
if (isKeychainUnusableError(error51)) {
|
|
37427
|
+
this.backend = "file";
|
|
37428
|
+
this.fileBackendReason = "unusable";
|
|
37429
|
+
} else {
|
|
37430
|
+
this.backend = "keychain";
|
|
37431
|
+
}
|
|
37388
37432
|
}
|
|
37389
37433
|
return this.backend;
|
|
37390
37434
|
}
|
|
@@ -37513,7 +37557,7 @@ function createTokenStore(options = {}) {
|
|
|
37513
37557
|
}
|
|
37514
37558
|
const platform2 = options.platform ?? process.platform;
|
|
37515
37559
|
if (platform2 === "darwin") {
|
|
37516
|
-
return new DarwinTokenStore(options.execFile, tokenPath);
|
|
37560
|
+
return new DarwinTokenStore(options.execFile, tokenPath, options.stderr ?? process.stderr);
|
|
37517
37561
|
}
|
|
37518
37562
|
if (platform2 === "win32") {
|
|
37519
37563
|
return new WindowsCredentialTokenStore(options.execFile);
|
|
@@ -43268,6 +43312,82 @@ var softwareGithubIssueIntakeMetadataSchema = external_exports.object({
|
|
|
43268
43312
|
labels: external_exports.array(external_exports.string().trim().min(1).max(80)).max(50).default([]),
|
|
43269
43313
|
requested_automation_mode: softwareAutomationModeSchema.optional()
|
|
43270
43314
|
}).strict();
|
|
43315
|
+
var softwareVercelDeploymentStatusSchema = external_exports.enum(["queued", "initializing", "building", "ready", "error", "canceled", "unknown"]);
|
|
43316
|
+
var softwareVercelConnectionConnectInputSchema = external_exports.object({
|
|
43317
|
+
account_id: external_exports.string().trim().min(1).max(200),
|
|
43318
|
+
account_name: external_exports.string().trim().min(1).max(255).nullable().optional(),
|
|
43319
|
+
team_id: external_exports.string().trim().min(1).max(200).nullable().optional(),
|
|
43320
|
+
team_slug: external_exports.string().trim().min(1).max(255).nullable().optional(),
|
|
43321
|
+
user_id: external_exports.string().trim().min(1).max(200).nullable().optional(),
|
|
43322
|
+
configuration_id: external_exports.string().trim().min(1).max(200).nullable().optional(),
|
|
43323
|
+
access_token_vault_ref: external_exports.string().trim().min(12).max(700),
|
|
43324
|
+
scopes: external_exports.array(external_exports.string().trim().min(1).max(120)).max(40).default([])
|
|
43325
|
+
}).strict();
|
|
43326
|
+
var softwareVercelConnectionConnectOutputSchema = external_exports.object({
|
|
43327
|
+
vercel_connection_id: uuid10,
|
|
43328
|
+
account_id: external_exports.string(),
|
|
43329
|
+
team_id: external_exports.string().nullable()
|
|
43330
|
+
});
|
|
43331
|
+
var softwareVercelProjectLinkInputSchema = external_exports.object({
|
|
43332
|
+
software_project_id: uuid10,
|
|
43333
|
+
vercel_connection_id: uuid10,
|
|
43334
|
+
vercel_project_id: external_exports.string().trim().min(1).max(200),
|
|
43335
|
+
vercel_project_name: external_exports.string().trim().min(1).max(255),
|
|
43336
|
+
framework: external_exports.string().trim().min(1).max(120).nullable().optional(),
|
|
43337
|
+
root_directory: external_exports.string().trim().min(1).max(500).nullable().optional(),
|
|
43338
|
+
production_branch: external_exports.string().trim().min(1).max(255).nullable().optional(),
|
|
43339
|
+
git_repository: external_exports.record(external_exports.string().min(1), external_exports.unknown()).default({})
|
|
43340
|
+
}).strict();
|
|
43341
|
+
var softwareVercelProjectLinkOutputSchema = external_exports.object({
|
|
43342
|
+
vercel_project_link_id: uuid10,
|
|
43343
|
+
software_project_id: uuid10,
|
|
43344
|
+
vercel_project_id: external_exports.string()
|
|
43345
|
+
});
|
|
43346
|
+
var softwareVercelConnectionViewSchema = external_exports.object({
|
|
43347
|
+
id: uuid10,
|
|
43348
|
+
account_id: external_exports.string(),
|
|
43349
|
+
account_name: external_exports.string().nullable(),
|
|
43350
|
+
team_id: external_exports.string().nullable(),
|
|
43351
|
+
team_slug: external_exports.string().nullable(),
|
|
43352
|
+
user_id: external_exports.string().nullable(),
|
|
43353
|
+
configuration_id: external_exports.string().nullable(),
|
|
43354
|
+
status: external_exports.enum(["active", "revoked"]),
|
|
43355
|
+
connected_at: external_exports.string()
|
|
43356
|
+
});
|
|
43357
|
+
var softwareVercelProjectLinkViewSchema = external_exports.object({
|
|
43358
|
+
id: uuid10,
|
|
43359
|
+
software_project_id: uuid10,
|
|
43360
|
+
software_project_name: external_exports.string(),
|
|
43361
|
+
software_project_slug: external_exports.string(),
|
|
43362
|
+
vercel_connection_id: uuid10,
|
|
43363
|
+
vercel_project_id: external_exports.string(),
|
|
43364
|
+
vercel_project_name: external_exports.string(),
|
|
43365
|
+
framework: external_exports.string().nullable(),
|
|
43366
|
+
root_directory: external_exports.string().nullable(),
|
|
43367
|
+
production_branch: external_exports.string().nullable(),
|
|
43368
|
+
status: external_exports.enum(["active", "revoked"])
|
|
43369
|
+
});
|
|
43370
|
+
var softwareVercelProjectListInputSchema = external_exports.object({}).strict();
|
|
43371
|
+
var softwareVercelProjectListOutputSchema = external_exports.object({
|
|
43372
|
+
connections: external_exports.array(softwareVercelConnectionViewSchema),
|
|
43373
|
+
project_links: external_exports.array(softwareVercelProjectLinkViewSchema)
|
|
43374
|
+
});
|
|
43375
|
+
var softwareVercelDeployPreviewInputSchema = external_exports.object({
|
|
43376
|
+
software_project_id: uuid10,
|
|
43377
|
+
commit_sha: external_exports.string().trim().regex(/^[A-Fa-f0-9]{7,64}$/),
|
|
43378
|
+
git_ref: external_exports.string().trim().min(1).max(255),
|
|
43379
|
+
build_request_id: uuid10.optional(),
|
|
43380
|
+
phase_run_id: uuid10.optional(),
|
|
43381
|
+
seat_id: uuid10.optional(),
|
|
43382
|
+
required_secret_keys: external_exports.array(external_exports.string().trim().min(1).max(200)).max(25).default([])
|
|
43383
|
+
}).strict();
|
|
43384
|
+
var softwareVercelDeployPreviewOutputSchema = external_exports.object({
|
|
43385
|
+
vercel_deployment_record_id: uuid10,
|
|
43386
|
+
deployment_id: external_exports.string(),
|
|
43387
|
+
deployment_url: external_exports.string().nullable(),
|
|
43388
|
+
commit_sha: external_exports.string(),
|
|
43389
|
+
status: softwareVercelDeploymentStatusSchema
|
|
43390
|
+
});
|
|
43271
43391
|
|
|
43272
43392
|
// ../../packages/protocol/src/sync-brief.ts
|
|
43273
43393
|
var uuidSchema14 = external_exports.string().uuid();
|
|
@@ -44512,7 +44632,7 @@ No orphan agents. No raw secrets in prompts, logs, or tool arguments. No durable
|
|
|
44512
44632
|
order: 41,
|
|
44513
44633
|
title: "Add agents to your Responsibility Graph",
|
|
44514
44634
|
summary: "The visual journey for adding an agent seat: where to start, choosing a mode, placing the seat, naming a Steward, setup, the safety gates, and go-live.",
|
|
44515
|
-
version: "2026-07-04.
|
|
44635
|
+
version: "2026-07-04.2",
|
|
44516
44636
|
public: true,
|
|
44517
44637
|
audiences: ["human", "in_app_agent"],
|
|
44518
44638
|
stages: ["staffing"],
|
|
@@ -44534,7 +44654,7 @@ A seat is a function, not a person. Adding an agent means staffing a seat with a
|
|
|
44534
44654
|
You can open agent creation from three places:
|
|
44535
44655
|
|
|
44536
44656
|
- **Responsibility Graph.** Hover or focus a seat node and use its **Add agent** action to add an agent seat under that seat. The graph toolbar's **Add agent** action adds an agent and then asks where it should report. On an empty or small graph, **Add first agent** starts the same flow with the founder or owner seat as the default Steward.
|
|
44537
|
-
- **Left sidebar.** The **Agents** item
|
|
44657
|
+
- **Left sidebar.** The **Agents** item opens the agents surface. **Add agent** at the top of that surface is the primary action.
|
|
44538
44658
|
- **Agents surface.** The unified agents page has **Templates**, **Custom**, and **Existing** modes. A template's **Use template** action enters the same wizard with that template selected.
|
|
44539
44659
|
|
|
44540
44660
|
Starting from a selected graph seat carries the parent seat and a default Steward candidate into the wizard so you do not re-pick them.
|
|
@@ -45005,7 +45125,7 @@ External connectors are being rolled out provider by provider, conservatively (r
|
|
|
45005
45125
|
order: 48,
|
|
45006
45126
|
title: "CLI and MCP installation guide",
|
|
45007
45127
|
summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
|
|
45008
|
-
version: "2026-07-04.
|
|
45128
|
+
version: "2026-07-04.21",
|
|
45009
45129
|
public: true,
|
|
45010
45130
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
45011
45131
|
stages: ["company_setup", "staffing"],
|
|
@@ -45193,6 +45313,8 @@ Notes:
|
|
|
45193
45313
|
|
|
45194
45314
|
By default the CLI stores the session in the **macOS Keychain** (on darwin). There is no built-in Windows or Linux keychain integration today \u2014 on any non-macOS host, or any machine without a keychain, the CLI errors with "No OS credential store is available" unless you opt into the file store.
|
|
45195
45315
|
|
|
45316
|
+
On macOS, the CLI now **verifies the keychain write is readable back** right after \`login\`. On some headless/service hosts the keychain accepts the write but a later command's process cannot read it back (an ACL scoped to the writing binary, a re-locked login keychain, or a launchd/SSH session with no keychain), so \`login\` reports success yet the next command prints "Not logged in". When that readback fails, the CLI **automatically** writes the session to the same owner-only file store (directory \`0700\`, file \`0600\`), prints a one-line stderr notice, and later commands read it back transparently \u2014 so a headless macOS agent "just works" with no flag. For a fully unattended macOS host, export \`{{envPrefix}}_CLI_ALLOW_FILE_TOKEN_STORE=1\` anyway so every command uses the file store directly.
|
|
45317
|
+
|
|
45196
45318
|
For headless Linux, CI runners, or any no-keychain environment, set \`{{envPrefix}}_CLI_ALLOW_FILE_TOKEN_STORE=1\` to opt into the **development-only plain-file token store**. It is **not encrypted** \u2014 it writes the file with owner-only permissions (directory \`0700\`, file \`0600\`) and prints a stderr warning. It stores **only CLI session tokens** (access + refresh token), never tenant secrets, API keys, or vault refs. Treat that file as a credential: do not bake it into a shared image and do not commit it.
|
|
45197
45319
|
|
|
45198
45320
|
The CLI checks this flag on **every** invocation, not just \`login\`. Export it for the whole shell or CI job (so \`{{cli}} whoami\`, \`{{cli}} onboard status\`, and the rest also find the file store), not only on the login line:
|
|
@@ -45451,7 +45573,7 @@ These ergonomic wrappers (including the \`{{cli}} agent\` group) require **{{cli
|
|
|
45451
45573
|
|
|
45452
45574
|
**Generated verbs (0.6.0+).** Every registry command now has a first-class \`{{cli}} <namespace> <action>\` verb, projected directly from the command's input schema \u2014 so namespaces that previously had no ergonomic wrapper (for example \`{{cli}} measurable create\`, \`{{cli}} work_order enqueue\`, \`{{cli}} mcp_token create\`) are usable without dropping to the raw \`command <id>\` path. Flags follow the schema field names (\`--seat-id\`, \`--name\`, \u2026); read a command's exact input offline with \`{{cli}} <namespace> <action> --schema\` before calling it, and pass a nested payload with \`--input '<json>'\` when a field is a complex object. \`--json\` still selects machine output, \`--seat <id>\` still sets seat scope, and \`{{cli}} command <id> --json '<body>'\` remains the universal fallback.
|
|
45453
45575
|
|
|
45454
|
-
The signed-in app exposes the same Skill command surface
|
|
45576
|
+
The signed-in app exposes the same Skill command surface at **Skills**, linked from the Agents page (the nav collapse moved it out of the primary sidebar). Use \`/skills\` to filter the tenant library, \`/skills/new\` to build canonical \`SKILL.md\` frontmatter with \`tool.catalog\` dependencies, \`/skills/import\` for bounded GitHub or upload imports, and each Skill detail page to review validation, publish, check Seat dependencies, and assign a published version. During \`/agents/new\`, \`agent_setup.get\` can return \`next_action: "choose_skills"\`; selected Skills are proposed immutable-version assignments and required Skill tools block sign-off/go-live until tool configuration is ready.
|
|
45455
45577
|
|
|
45456
45578
|
| Command | Command ids | Purpose | Scope | Safe example |
|
|
45457
45579
|
|---|---|---|---|---|
|
|
@@ -45749,6 +45871,8 @@ Several rows here are seat-operating commands (\`task.create\`, the \`signal.*\`
|
|
|
45749
45871
|
| \`rost_set_a_forge_github_automation_policy\` | \`software_factory.github.policy.upsert\` | Set the server-side GitHub automation policy: allowed actions, automation-mode ceiling, and operations requiring humans. The allowed-actions and human-gated-actions lists are stored server-side as structured JSON arrays. Owner-only and human-gated. | Tenant-admin | Call with \`{"software_project_id":"<project-id>","automation_mode_ceiling":"pr_only","allowed_actions":["webhook_intake","installation_token"],"requires_human_for":["deploy_production"]}\`. |
|
|
45750
45872
|
| \`rost_create_a_forge_github_installation_token\` | \`software_factory.github.installation_token.create\` | Mint a short-lived GitHub App installation token for one bound repository after policy evaluation. The token is returned once and never stored. | Tenant | Call with \`{"software_project_id":"<project-id>","repository_id":789,"requested_actions":["read"],"requested_automation_mode":"plan_only"}\`. |
|
|
45751
45873
|
| \`rost_list_forge_github_installations\` | \`software_factory.github.installation.list\` | List connected GitHub App installations and each repository's bind state (connected or active) with the Forge project it maps to. Read-only. | Tenant | Call with \`{}\`; a \`connected\` repository is verified but not yet bound to a project. |
|
|
45874
|
+
| \`rost_list_forge_vercel_links\` | \`software_factory.vercel.project.list\` | List connected Vercel accounts/teams and linked existing Vercel projects. Read-only; no OAuth tokens or vault refs are returned. | Tenant | Call with \`{}\`; tenant admins connect/link from \`/forge/settings/vercel\`. |
|
|
45875
|
+
| \`rost_create_a_forge_vercel_preview_deployment\` | \`software_factory.vercel.deploy_preview\` | Create a Vercel preview deployment for a linked project after Forge deploy-preview authority, the Vercel OAuth vault-ref connection, and required preview secret/config grants are verified. | Tenant | Call with \`{"software_project_id":"<project-id>","commit_sha":"<sha>","git_ref":"feature/example","seat_id":"<seat-id>"}\`; returns deployment metadata, not tokens. |
|
|
45752
45876
|
| \`rost_list_forge_runner_capacity\` | \`software_factory.capacity.list\` | List Forge runner capacity observations (advisory scheduling input only, never an authority input). Read-only; requires the Forge add-on. | Tenant | Call with \`{}\` or \`{"runner_id":"<runner-id>"}\`. |
|
|
45753
45877
|
|
|
45754
45878
|
The web Forge control room at \`/forge\` uses the same command path for project selection, build request creation/list/detail reads, request pause/cancel/resume controls, runner capacity, configuration status, and Developer Team install. A request detail page shows phase history, open gates, plan progress, loop/time/cost ceilings, and latest plan-review questions from \`software_factory.request.show\`; answering a clarification, approving a plan, rejecting it, pausing, canceling, or resuming calls the same Forge commands exposed over CLI/MCP. Lifecycle controls deliberately stage pending confirmations before changing runner state. The install button also stages a pending confirmation before durable seats, Skills, authority grants, or live agent activation are applied; the install page states plainly that approving activates the 6 agents at a pull-request-only, observe-first posture and surfaces the company autonomy ceiling.
|
|
@@ -45763,6 +45887,12 @@ Tenant GitHub App connect and bind are intentionally not CLI or MCP mutation too
|
|
|
45763
45887
|
|
|
45764
45888
|
The Forge GitHub App itself is org-owned. App private key, webhook secret, and client secret values are platform-owned ROST operator credentials stored through the vault's reserved ROST system namespace, not through a customer tenant namespace or a tenant UUID deployment variable. Manifest conversion and manual secret storage also require the app-level \`GITHUB_APP_OPERATOR_EMAILS\` allowlist, which should contain only approved ROST platform operator emails. Deployment config carries only refs (\`GITHUB_APP_PRIVATE_KEY_REF\`, \`GITHUB_APP_WEBHOOK_SECRET_REF\`, \`GITHUB_APP_CLIENT_SECRET_REF\`); raw secret env vars are local/legacy compatibility only. The dogfood app is \`ROST Forge\` under \`agenticoperatingsystem\` with App ID \`4208495\` and Client ID \`Iv23liImH7qlBvXYQ0Wx\`. The base app omits \`administration\` and \`workflows\`; elevated repo creation or workflow mutation needs a separate human-approved power path.
|
|
45765
45889
|
|
|
45890
|
+
#### Forge Vercel access
|
|
45891
|
+
|
|
45892
|
+
Forge Vercel access is through a tenant-bound OAuth connection, never a browser-visible token. Tenant admins start at \`/forge/settings/vercel\`; the callback exchanges the short-lived Vercel code server-side, stores the access token in the vault, and records only account/team metadata plus the vault-ref pointer via \`software_factory.vercel.connection.connect\`. Existing Vercel projects are linked through \`software_factory.vercel.project.link\`; greenfield project creation is intentionally absent from this slice and requires a future explicit authority flag.
|
|
45893
|
+
|
|
45894
|
+
Preview deployment creation is a governed command. \`software_factory.vercel.deploy_preview\` requires an active Vercel project link, a Vercel OAuth vault-ref connection, active \`deploy_preview\` Forge authority for the requesting seat when a seat is supplied, and any requested preview secret/config grants. It writes the deployment id, URL, commit SHA, checks, status, and error metadata into \`software_vercel_deployments\`; build-request deployments also write a Forge artifact and event. Raw OAuth tokens and vault refs are never returned.
|
|
45895
|
+
|
|
45766
45896
|
### Seat-scoped operating tools
|
|
45767
45897
|
|
|
45768
45898
|
Seat-scoped MCP tokens expose the operating protocol below. The server still checks the seat's permission manifest, Charter, task ownership, and tenant boundary. These are the **seat-token equivalents** of the CLI \`{{cli}} task\` / \`{{cli}} signal\` / \`{{cli}} friction\` wrappers and the tenant-admin task tools above: \`rost_get_tasks\`, \`{{cli}} task list\`, and \`task.list\` are the same operation reached three different ways. The command-id column makes the mapping explicit.
|
|
@@ -46767,7 +46897,7 @@ Do not claim that a live charge happened unless Stripe test/live evidence proves
|
|
|
46767
46897
|
order: 72,
|
|
46768
46898
|
title: "Settings guide",
|
|
46769
46899
|
summary: "How to use Settings as the control plane for company access, channels, providers, tokens, and operating defaults.",
|
|
46770
|
-
version: "2026-07-04.
|
|
46900
|
+
version: "2026-07-04.3",
|
|
46771
46901
|
public: true,
|
|
46772
46902
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
46773
46903
|
stages: ["company_setup", "staffing"],
|
|
@@ -46790,9 +46920,9 @@ Start with members and invites, then provider and channel connections, then MCP
|
|
|
46790
46920
|
|
|
46791
46921
|
## Navigating Settings
|
|
46792
46922
|
|
|
46793
|
-
Settings is a left-rail master\u2013detail layout: a grouped rail (General, Team & Access, Billing, AI & Agents, Connections) selects one section at a time, shown in the detail pane. The active section is a URL search param, so \`/settings?section=<id>\` is linkable and survives a refresh. The Connections section is the workspace-level provider surface: Google, Slack, QuickBooks, local runners, seat-scoped agent tokens, and stored secrets appear as provider cards with status, used-for chips, actions, and the shared Access language (**Off / Read / Draft / Act with approval**). Detailed management forms for tokens, channels, runners, provider links, and stored vault entries remain reachable from those cards.
|
|
46923
|
+
Settings is reached from the footer gear in the left sidebar (the nav collapse moved it out of the primary item list). It is a left-rail master\u2013detail layout: a grouped rail (General, Team & Access, Billing, AI & Agents, Connections, Advanced) selects one section at a time, shown in the detail pane. The active section is a URL search param, so \`/settings?section=<id>\` is linkable and survives a refresh. The Connections section is the workspace-level provider surface: Google, Slack, QuickBooks, local runners, seat-scoped agent tokens, and stored secrets appear as provider cards with status, used-for chips, actions, and the shared Access language (**Off / Read / Draft / Act with approval**). Detailed management forms for tokens, channels, runners, provider links, and stored vault entries remain reachable from those cards.
|
|
46794
46924
|
|
|
46795
|
-
Legacy hash deep-links still resolve \u2014 \`/settings#integrations\`, \`#channels\`, and \`#vault\` redirect to \`?section=connections\`; other hashes such as \`#members\` and \`#guardrails\` redirect to their matching section. \`#runners\` is the one exception: it keeps resolving to the dedicated Connected machines management table (not the Connections overview), since System Health and seat pages deep-link there expecting the per-runner revoke actions. Documented shortcut links resolve to the right section instead of a dead end: \`/settings/integrations\` and \`/readiness\` open the Connections section (connector readiness lives inside it, not on a standalone page),
|
|
46925
|
+
Legacy hash deep-links still resolve \u2014 \`/settings#integrations\`, \`#channels\`, and \`#vault\` redirect to \`?section=connections\`; other hashes such as \`#members\` and \`#guardrails\` redirect to their matching section. \`#runners\` is the one exception: it keeps resolving to the dedicated Connected machines management table (not the Connections overview), since System Health and seat pages deep-link there expecting the per-runner revoke actions. Documented shortcut links resolve to the right section instead of a dead end: \`/settings/integrations\` and \`/readiness\` open the Connections section (connector readiness lives inside it, not on a standalone page), \`/settings/policy\` opens the Product learning section, and MCP/CLI access tokens live in the Agent access tokens section (not a separate \`/mcp\` page \u2014 \`/mcp\` is the MCP protocol endpoint itself, not a browsable settings screen). The Advanced group links out to \`/migration/ninety\`, the one settings-adjacent page with no home in the grouped rail. After you save a change, the app keeps you on the section you edited rather than returning to the top.
|
|
46796
46926
|
|
|
46797
46927
|
## What belongs in Settings
|
|
46798
46928
|
|
|
@@ -47046,7 +47176,7 @@ The runner should not store raw credentials in local notes, prompts, or logs. It
|
|
|
47046
47176
|
order: 76,
|
|
47047
47177
|
title: "Stock agents guide",
|
|
47048
47178
|
summary: "How to use stock agent templates as starting points while preserving seat-specific Charters and human approval.",
|
|
47049
|
-
version: "2026-07-
|
|
47179
|
+
version: "2026-07-04.1",
|
|
47050
47180
|
public: true,
|
|
47051
47181
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
47052
47182
|
stages: ["staffing"],
|
|
@@ -47065,7 +47195,7 @@ Stock agents are templates, not finished employees. Use them to accelerate setup
|
|
|
47065
47195
|
|
|
47066
47196
|
## Where to create agents
|
|
47067
47197
|
|
|
47068
|
-
Add agents from the unified agents surface. In the app, open it from the **Agents** item in the left sidebar
|
|
47198
|
+
Add agents from the unified agents surface. In the app, open it from the **Agents** item in the left sidebar, or from an **Add agent** action on the Responsibility Graph. The first screen asks for a creation mode \u2014 use a template, design a custom agent, or connect an existing agent \u2014 then walks the same conservative path for every mode: seat placement, Steward, draft Charter, manifest sign-off, sandbox dry run, and human go-live. Each step is command-backed, so the same workflow runs from the app, the CLI, and MCP.
|
|
47069
47199
|
|
|
47070
47200
|
## Template review
|
|
47071
47201
|
|
|
@@ -48969,6 +49099,10 @@ var COMMAND_MANIFEST = [
|
|
|
48969
49099
|
{ "id": "software_factory.secret.request", "namespace": "software_factory", "action": "secret.request", "title": "Request a Forge secret grant", "description": "An agent or user REQUESTS access to a project secret by key (draft-and-confirm \u2014 no value, no grant). Records the ask as a durable event for a human to grant. Never accepts a secret value (invariant #5). Entitlement-gated.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": true }, { "name": "environment", "flag": "environment", "type": "enum", "required": true, "enumValues": ["development", "preview", "production"] }, { "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "action", "flag": "action", "type": "string", "required": true }, { "name": "key_name", "flag": "key-name", "type": "string", "required": true }, { "name": "reason", "flag": "reason", "type": "string", "required": false }], "hasComplexInput": false, "help": "Request access to a project secret by key; persists the request and creates a human approval task. Never accepts a secret value." },
|
|
48970
49100
|
{ "id": "software_factory.secret.revoke", "namespace": "software_factory", "action": "secret.revoke", "title": "Revoke a Forge secret grant", "description": "Revoke a Forge secret grant (teardown \u2014 a compromised seat's access can be cut immediately, ADR-0018 \xA76). Owner-only, human-gated. Entitlement-gated.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "grant_id", "flag": "grant-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Revoke a Forge secret grant (teardown \u2014 cut a compromised seat's access immediately). Owner-only and human-gated." },
|
|
48971
49101
|
{ "id": "software_factory.secret.use", "namespace": "software_factory", "action": "secret.use", "title": "Verify Forge secret broker access", "description": "Verify a scoped secret broker grant without returning or opening the raw value. Runtime vault access happens only in the runner-side broker helper; this command writes a redacted authorization log and creates a request task for missing grants.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": true }, { "name": "environment", "flag": "environment", "type": "enum", "required": true, "enumValues": ["development", "preview", "production"] }, { "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "action", "flag": "action", "type": "string", "required": true }, { "name": "key_name", "flag": "key-name", "type": "string", "required": true }, { "name": "operation", "flag": "operation", "type": "enum", "required": false, "enumValues": ["use", "vercel_env_sync", "test_execution"] }], "hasComplexInput": false, "help": "Verify scoped broker access without returning or opening the raw value; missing grants create or reuse a request task and all attempts write redacted access logs." },
|
|
49102
|
+
{ "id": "software_factory.vercel.connection.connect", "namespace": "software_factory", "action": "vercel.connection.connect", "title": "Connect a Forge Vercel account", "description": "Record a Vercel OAuth account/team connection. The access token is stored only as a vault ref; this command persists bounded account metadata. Owner-only and human-gated.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": false, "fields": [{ "name": "account_id", "flag": "account-id", "type": "string", "required": true }, { "name": "account_name", "flag": "account-name", "type": "string", "required": false }, { "name": "team_id", "flag": "team-id", "type": "string", "required": false }, { "name": "team_slug", "flag": "team-slug", "type": "string", "required": false }, { "name": "user_id", "flag": "user-id", "type": "string", "required": false }, { "name": "configuration_id", "flag": "configuration-id", "type": "string", "required": false }, { "name": "access_token_vault_ref", "flag": "access-token-vault-ref", "type": "string", "required": true }, { "name": "scopes", "flag": "scopes", "type": "array", "required": false, "itemType": "string" }], "hasComplexInput": false, "help": "Record a Vercel OAuth account/team connection from the Forge Vercel settings flow. Stores only a vault-ref pointer to the token. Owner-only and human-gated." },
|
|
49103
|
+
{ "id": "software_factory.vercel.deploy_preview", "namespace": "software_factory", "action": "vercel.deploy_preview", "title": "Create a Forge Vercel preview deployment", "description": "Create a Vercel preview deployment for a linked existing project after Forge authority, Vercel connection, and required secret/config grants are verified. Records deployment metadata as artifacts and audit rows.", "requiredScope": "tenant", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": true }, { "name": "commit_sha", "flag": "commit-sha", "type": "string", "required": true }, { "name": "git_ref", "flag": "git-ref", "type": "string", "required": true }, { "name": "build_request_id", "flag": "build-request-id", "type": "string", "required": false }, { "name": "phase_run_id", "flag": "phase-run-id", "type": "string", "required": false }, { "name": "seat_id", "flag": "seat-id", "type": "string", "required": false }, { "name": "required_secret_keys", "flag": "required-secret-keys", "type": "array", "required": false, "itemType": "string" }], "hasComplexInput": false, "help": "Create a Vercel preview deployment for a linked project after Forge authority, Vercel connection, and required secret/config grants are verified." },
|
|
49104
|
+
{ "id": "software_factory.vercel.project.link", "namespace": "software_factory", "action": "vercel.project.link", "title": "Link a Forge project to Vercel", "description": "Link a Forge project to an existing Vercel project. Greenfield Vercel project creation is intentionally out of scope and remains behind a future authority flag.", "requiredScope": "tenant_admin", "confirmation": "human_required", "exposeOverMcp": false, "fields": [{ "name": "software_project_id", "flag": "software-project-id", "type": "string", "required": true }, { "name": "vercel_connection_id", "flag": "vercel-connection-id", "type": "string", "required": true }, { "name": "vercel_project_id", "flag": "vercel-project-id", "type": "string", "required": true }, { "name": "vercel_project_name", "flag": "vercel-project-name", "type": "string", "required": true }, { "name": "framework", "flag": "framework", "type": "string", "required": false }, { "name": "root_directory", "flag": "root-directory", "type": "string", "required": false }, { "name": "production_branch", "flag": "production-branch", "type": "string", "required": false }], "hasComplexInput": true, "help": "Link an existing Vercel project to a Forge software project. Owner-only and human-gated; greenfield project creation remains a future explicit authority." },
|
|
49105
|
+
{ "id": "software_factory.vercel.project.list", "namespace": "software_factory", "action": "vercel.project.list", "title": "List Forge Vercel links", "description": "List Vercel account/team connections and existing Vercel project links for this tenant. Read-only; token vault refs are never returned.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [], "hasComplexInput": false, "help": "List Vercel account/team connections and linked Vercel projects. Read-only; no OAuth tokens or vault refs are returned." },
|
|
48972
49106
|
{ "id": "staffing.assign", "namespace": "staffing", "action": "assign", "title": "Staff seat", "description": "Compatibility command for the DER-626 MCP staffing tool.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }], "hasComplexInput": true, "help": "Staff a seat only after the function, Charter, and human accountability are clear." },
|
|
48973
49107
|
{ "id": "staffing.assign_agent_dry_run", "namespace": "staffing", "action": "assign_agent_dry_run", "title": "Assign dry-run agent to seat", "description": "Assign an agent occupancy while the agent remains in dry-run.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "agent_id", "flag": "agent-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Start agent staffing with dry runs and a named human Steward." },
|
|
48974
49108
|
{ "id": "staffing.assign_user", "namespace": "staffing", "action": "assign_user", "title": "Assign user to seat", "description": "Assign a human user occupancy to a seat.", "requiredScope": "seat", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "user_id", "flag": "user-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Assign humans to seats after the seat accountability is clear." },
|