@rosthq/cli 0.7.123 → 0.7.124

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.js CHANGED
@@ -52051,7 +52051,7 @@ var referenceDocuments = [
52051
52051
  order: 10,
52052
52052
  title: "{{brand}} implementation method",
52053
52053
  summary: "The staged operating-system setup path used by humans, CLI sessions, MCP clients, and in-app agents.",
52054
- version: "2026-07-29.4",
52054
+ version: "2026-07-30.1",
52055
52055
  public: true,
52056
52056
  audiences: ["human", "cli", "mcp", "in_app_agent"],
52057
52057
  stages: ["company_setup", "graph_design", "charter_design", "staffing", "operating_rhythm"],
@@ -52180,6 +52180,8 @@ The Compass is drafted, then activated by a human through supersession.
52180
52180
 
52181
52181
  \`onboarding.setup\`, \`onboarding.finish\`, \`compass.approve_version\`, \`compass.reject_draft\`, and \`compass.set\` are \`human_required\`. \`onboarding.source_ingest\` is a bootstrap-safe \`none\` prerequisite that retains bounded source bytes encrypted under the exact tenant/run, computes its digest and canonical parser manifest server-side, and remains permanently outside Trusted and Full Operator. \`onboarding.setup\` is the one-approval composite apply: it freezes the complete plan and live proof at staging, then rechecks them and applies Compass, cycle, Responsibility Graph, Charters, staffing, goals, Signals/readings, Frictions, tasks, and Sync scope in one transaction. A failure rolls back the entire application and leaves the confirmation pending.
52182
52182
 
52183
+ The whole composite flow has first-class CLI verbs: \`{{cli}} onboard source-ingest --file <path> ...\` for each allowed local source, \`{{cli}} onboard setup --input-file <plan.json>\` to stage the one owner approval (it prints the confirmation id and exact approval URL), \`{{cli}} onboard setup-status --input-file <plan.json>\` to discover the applied receipt by idempotent re-submission of the identical plan, then \`{{cli}} onboard rehearse\` and \`{{cli}} onboard activate\`. Each authenticates with the implementation-bootstrap credential first and falls back to the user session; the generic \`{{cli}} command <id> --json\` path and the generated MCP tools expose the same schemas.
52184
+
52183
52185
  After setup succeeds, call \`onboarding.rehearse\` with the exact setup application, expected setup digest/revision, and a caller idempotency key. This is the implementation principal's one bounded \`execute\` exception: it is ungated because it can run only the setup receipt's exact agents in the sandbox, with no schedule arming, go-live transition, credential access, source mutation, or external communication. It rechecks the current Charter manifest, pinned published Skill versions and content hashes, schedule, execution lane, and canonical configuration digest under the same tenant/run boundary. A complete batch returns an immutable terminal batch receipt plus one immutable per-agent receipt with nonzero checked counts, runtime run ids, bounded tool previews/manifest holds/errors, and \`passed\` or \`failed\` status. Same-key/same-configuration retry returns that terminal evidence; a changed configuration conflicts instead of silently reusing it. The rehearsal never returns an approval URL and never stages activation. The later, separate \`onboarding.activate\` command consumes that exact terminal batch and the unique run/configuration evidence for the setup receipt's complete agent set. It stages one owner approval whose durable card shows every agent, Seat, Charter/configuration digest, rehearsal run, effective lane/model, permissions, schedule, warnings, and the onboarding-completion effect. Approval rechecks the full projection, records one composite human decision, makes every agent live, arms eligible schedules, and completes onboarding atomically. Any stale or failed member rolls the transaction back; same-key retry returns the committed receipt without duplicating effects.
52184
52186
 
52185
52187
  \`onboarding.advance_step\`, \`onboarding.create_invite\`, \`onboarding.attach_reference\`, \`compass.answer_gap\`, and drafting a Compass are \`none\` \u2014 none of them returns a pending confirmation. \`none\` is not the same as "agent-callable", though: \`onboarding.create_invite\` and \`compass.answer_gap\` record the human who ran them, so they run as a person, not from an agent session, while advancing a step, attaching a reference, drafting a Compass, and exact-run source ingestion are safe for the bootstrap agent. Approving a version (a supersession) is a human act. The agent drafts and surfaces the approve link. See the confirmations guide.
@@ -53320,7 +53322,7 @@ External connectors are being rolled out provider by provider, conservatively (r
53320
53322
  order: 48,
53321
53323
  title: "CLI and MCP installation guide",
53322
53324
  summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
53323
- version: "2026-07-29.2",
53325
+ version: "2026-07-30.1",
53324
53326
  public: true,
53325
53327
  audiences: ["human", "cli", "mcp", "in_app_agent"],
53326
53328
  stages: ["company_setup", "staffing"],
@@ -53844,11 +53846,28 @@ These are the security posture rules for operating after install \u2014 a checkl
53844
53846
 
53845
53847
  ### Onboarding
53846
53848
 
53849
+ \`\`\`text
53850
+ {{cli}} onboard status
53851
+ {{cli}} onboard resume
53852
+ {{cli}} onboard run
53853
+ {{cli}} onboard source-ingest --file <path> --source-key <key> --kind <kind> --title <title> [--json]
53854
+ {{cli}} onboard setup --input '<json-plan>' | --input-file <path> [--json]
53855
+ {{cli}} onboard setup-status --input '<json-plan>' | --input-file <path> [--json]
53856
+ {{cli}} onboard rehearse|activate --setup-application-id <uuid> ... [--json]
53857
+ \`\`\`
53858
+
53859
+ Every tenant-scoped \`onboard\` verb (\`status\`, \`resume\`, \`source-ingest\`, \`setup\`, \`setup-status\`, \`rehearse\`, \`activate\` \u2014 \`onboard run\` is an offline public print) authenticates with an existing implementation-bootstrap credential first and falls back to the user session, so the agent-led composite flow works without a personal login. \`onboard source-ingest\` reads one local business file client-side, base64-encodes it, and calls \`onboarding.source_ingest\`; the server computes the digest and family manifest and returns the opaque \`source_ref\` to reference from the setup plan's \`sources[]\` (paths and client digests are rejected). The server's 1 MiB command-body cap is authoritative, and base64 expands content by 4/3, so the largest file reachable through this command today is about 780 KB \u2014 the CLI pre-checks and names the exact fitting size; split a larger export. \`onboard setup\` submits the complete declarative plan to \`onboarding.setup\`: staging succeeds with exit code 0 and prints the pending confirmation id plus the exact approval URL (with \`--json\`, the full pending-confirmation object). \`onboard setup-status\` re-submits the identical plan to discover state through the command's idempotent contract: after approval it returns the immutable applied receipt (application id, receipt revision, input digest) without staging anything; while approval is still pending it returns the current approval card \u2014 an identical still-valid card is reused with the same confirmation id and URL, and only a changed server-derived projection supersedes the stale card and mints a fresh one. After application, a same-key re-submission with a different plan digest is a typed conflict.
53860
+
53847
53861
  | Command | Purpose | Scope | Safe example |
53848
53862
  |---|---|---|---|
53849
53863
  | \`{{cli}} onboard status\` | Return onboarding progress, graph summary, and next actions. | Tenant | \`{{cli}} onboard status\` |
53850
53864
  | \`{{cli}} onboard resume\` | Resume the guided onboarding flow where it left off. | Tenant | \`{{cli}} onboard resume\` |
53851
53865
  | \`{{cli}} onboard run\` | Print the deterministic agent onboarding prompt. | Public reference | \`{{cli}} onboard run\` |
53866
+ | \`{{cli}} onboard source-ingest\` | Retain one bounded local business source (encrypted, tenant/run-bound) via \`onboarding.source_ingest\` and print the opaque \`source_ref\` for the setup plan. | Tenant (implementation bootstrap or owner) | \`{{cli}} onboard source-ingest --file org-chart.csv --source-key org-chart --kind org_chart --title "Org chart" --json\` |
53867
+ | \`{{cli}} onboard setup\` | Stage the one-approval composite onboarding setup via \`onboarding.setup\`; prints the pending confirmation id and exact approval URL, or the applied receipt on an identical re-submission. | Tenant (implementation bootstrap or owner) | \`{{cli}} onboard setup --input-file setup-plan.json --json\` |
53868
+ | \`{{cli}} onboard setup-status\` | Discover the setup application state by idempotent re-submission of the identical plan: applied receipt after approval; while pending, the current approval card (an identical card is reused, same id and URL). | Tenant (implementation bootstrap or owner) | \`{{cli}} onboard setup-status --input-file setup-plan.json --json\` |
53869
+ | \`{{cli}} onboard rehearse\` | Run the applied setup receipt's agents through the resumable sandbox-only rehearsal batch via \`onboarding.rehearse\`; returns immutable terminal evidence, never an activation approval URL. | Tenant (implementation bootstrap or owner) | \`{{cli}} onboard rehearse --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision 1 --idempotency-key rehearse-1 --json\` |
53870
+ | \`{{cli}} onboard activate\` | Stage the one post-rehearsal owner approval via \`onboarding.activate\` with the exact unique-agent-ID rehearsal and configuration evidence arrays; it alone stages the activation URL. | Tenant (implementation bootstrap or owner) | \`{{cli}} onboard activate --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision 1 --terminal-rehearsal-batch-receipt-id <uuid> --rehearsal-runs '[...]' --configuration-digests '[...]' --idempotency-key activate-1 --json\` |
53852
53871
  | \`{{cli}} init [--client claude-code|codex|cursor] (defaults --scope tenant-admin)\` | Log in when needed, install MCP, and print the onboarding prompt. As the first-run helper it defaults to a tenant-admin token (no seats exist yet); pass \`--scope seat --seat-id <id>\` to scope it narrower. | User plus tenant | \`{{cli}} init --client codex\` |
53853
53872
  | \`{{cli}} init --tenant <tenant> --client <client>\` | Select a tenant before MCP install. | User plus tenant | \`{{cli}} init --tenant acme-ops --client cursor\` |
53854
53873
 
@@ -53890,7 +53909,7 @@ These ergonomic wrappers (including the \`{{cli}} agent\` group) require **{{cli
53890
53909
 
53891
53910
  **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.
53892
53911
 
53893
- For a complete Seat, inspect \`{{cli}} seat create-complete --schema\`, then pass the strict nested request with \`{{cli}} seat create-complete --input '<json>' --json\`. The generic \`{{cli}} command seat.create_complete --json '<json>'\` path and the generated MCP tool \`rost_create_complete_seat\` expose the same registry schema and server-side command. A successful staging response contains the pending confirmation id and exact approval URL. The human owner reviews one card covering the Seat, canonical Charter and permission manifest, disclosed staffing, effective agent lane/readiness, exact pinned Skill versions and dependency state, and schedule. Approval applies the proposal in one transaction and returns its application and receipt ids. Any failure rolls back the whole proposal. An optional agent remains in \`dry_run\`; this command never approves go-live. Direct calls use existing parent and Steward Seat ids\u2014logical references are reserved for the later composite onboarding flow. Retained source ingestion is not available on this direct command yet, so \`sources\` and every \`source_uses\` collection must be empty and planned staffing must omit \`source_ref\`; the command rejects source-backed provenance instead of accepting an unverified upload id or caller-supplied digest.
53912
+ For a complete Seat, inspect \`{{cli}} seat create-complete --schema\`, then pass the strict nested request with \`{{cli}} seat create-complete --input '<json>' --json\`. The generic \`{{cli}} command seat.create_complete --json '<json>'\` path and the generated MCP tool \`rost_create_complete_seat\` expose the same registry schema and server-side command. \`seat create-complete\` authenticates with an existing implementation-bootstrap credential first (it is one of the vetted bootstrap staging primitives) and falls back to the user session. Staging surfaces as the CLI's confirmation-required envelope: a \`COMMAND_CONFIRMATION_REQUIRED\` JSON object on stderr, exit code 3, whose \`details\` carry the pending confirmation id and the exact approval URL (\`details.approveVia.webUrl\`) \u2014 read the URL from there; the command has done its job at that point. The human owner reviews one card covering the Seat, canonical Charter and permission manifest, disclosed staffing, effective agent lane/readiness, exact pinned Skill versions and dependency state, and schedule. Approval applies the proposal in one transaction and returns its application and receipt ids. Any failure rolls back the whole proposal. An optional agent remains in \`dry_run\`; this command never approves go-live. Direct calls use existing parent and Steward Seat ids\u2014logical references are reserved for the later composite onboarding flow. Retained source ingestion is not available on this direct command yet, so \`sources\` and every \`source_uses\` collection must be empty and planned staffing must omit \`source_ref\`; the command rejects source-backed provenance instead of accepting an unverified upload id or caller-supplied digest.
53894
53913
 
53895
53914
  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.
53896
53915
 
@@ -57245,6 +57264,19 @@ function renderImplementationAccessNote() {
57245
57264
  `${cliBrand.binName} onboard resume`,
57246
57265
  "```",
57247
57266
  "",
57267
+ "The agent-led composite setup flow has first-class verbs that authenticate with this credential first and fall back to the user session:",
57268
+ "",
57269
+ "```bash",
57270
+ `${cliBrand.binName} onboard source-ingest --file <path> --source-key <key> --kind <kind> --title <title> --json`,
57271
+ `${cliBrand.binName} onboard setup --input-file <plan.json> --json`,
57272
+ `${cliBrand.binName} onboard setup-status --input-file <plan.json> --json`,
57273
+ `${cliBrand.binName} onboard rehearse --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision <n> --idempotency-key <key> --json`,
57274
+ `${cliBrand.binName} onboard activate --setup-application-id <uuid> ... --json`,
57275
+ `${cliBrand.binName} seat create-complete --input '<json>' --json`,
57276
+ "```",
57277
+ "",
57278
+ "`onboard setup` staging succeeds with exit code 0 and prints the pending confirmation id plus the exact approval URL; `onboard setup-status` re-submits the identical plan and returns the immutable applied receipt once the owner has approved.",
57279
+ "",
57248
57280
  "Register the same bearer with an MCP client through `implementation access install-mcp`:",
57249
57281
  "",
57250
57282
  "```bash",
@@ -57989,508 +58021,7 @@ function parseSemver(value) {
57989
58021
  }
57990
58022
 
57991
58023
  // src/commands/onboarding.ts
57992
- var REHEARSE_USAGE = `${cliBrand.binName} onboard rehearse --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision <integer> --idempotency-key <key> [--json]`;
57993
- var ACTIVATE_USAGE = `${cliBrand.binName} onboard activate --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision <integer> --terminal-rehearsal-batch-receipt-id <uuid> --rehearsal-runs '<json-array>' --configuration-digests '<json-array>' --idempotency-key <key> [--json]`;
57994
- var OnboardingUsageError = class extends Error {
57995
- constructor(message) {
57996
- super(message);
57997
- this.name = "OnboardingUsageError";
57998
- }
57999
- };
58000
- async function runOnboarding(args, io, deps) {
58001
- let invocation;
58002
- try {
58003
- invocation = parseOnboardingInvocation(args);
58004
- } catch (error51) {
58005
- if (!(error51 instanceof OnboardingUsageError)) {
58006
- throw error51;
58007
- }
58008
- io.stderr.write(`${error51.message}
58009
- ${onboardingUsage()}
58010
- `);
58011
- return 1;
58012
- }
58013
- const client = await deps.makeClient();
58014
- try {
58015
- const result = await client.execute(invocation.commandId, invocation.body);
58016
- const rendered = invocation.json ? JSON.stringify(result.output, null, 2) : formatOnboardingOutput(invocation.action, result.output);
58017
- io.stdout.write(`${rendered}
58018
- `);
58019
- return 0;
58020
- } catch (error51) {
58021
- return printCommandError(io, error51);
58022
- }
58023
- }
58024
- function parseOnboardingInvocation(args) {
58025
- const action = args[0];
58026
- if (action === "status" || action === "resume") {
58027
- return {
58028
- commandId: action === "status" ? "onboarding.status" : "onboarding.resume",
58029
- body: {},
58030
- json: args.includes("--json"),
58031
- action
58032
- };
58033
- }
58034
- if (action !== "rehearse" && action !== "activate") {
58035
- throw new OnboardingUsageError(`Unknown onboard action: ${action ?? "(missing)"}`);
58036
- }
58037
- const allowed = /* @__PURE__ */ new Set([
58038
- "setup-application-id",
58039
- "expected-input-digest",
58040
- "expected-receipt-revision",
58041
- "idempotency-key",
58042
- ...action === "activate" ? [
58043
- "terminal-rehearsal-batch-receipt-id",
58044
- "rehearsal-runs",
58045
- "configuration-digests"
58046
- ] : []
58047
- ]);
58048
- const values = /* @__PURE__ */ new Map();
58049
- let json2 = false;
58050
- for (let index = 1; index < args.length; index += 1) {
58051
- const argument = args[index];
58052
- if (argument === "--json") {
58053
- if (json2) {
58054
- throw new OnboardingUsageError("Duplicate --json flag.");
58055
- }
58056
- json2 = true;
58057
- continue;
58058
- }
58059
- if (argument === void 0 || !argument.startsWith("--")) {
58060
- throw new OnboardingUsageError(`Unexpected argument: ${argument ?? "(missing)"}`);
58061
- }
58062
- const key = argument.slice(2);
58063
- if (!allowed.has(key)) {
58064
- throw new OnboardingUsageError(`Unknown flag: --${key}`);
58065
- }
58066
- if (values.has(key)) {
58067
- throw new OnboardingUsageError(`Duplicate --${key} flag.`);
58068
- }
58069
- const value = args[index + 1];
58070
- if (value === void 0 || value.startsWith("--")) {
58071
- throw new OnboardingUsageError(`Missing required --${key} value.`);
58072
- }
58073
- values.set(key, value);
58074
- index += 1;
58075
- }
58076
- const requiredValue2 = (key) => {
58077
- const value = values.get(key);
58078
- if (value === void 0 || value.length === 0) {
58079
- throw new OnboardingUsageError(`Missing required --${key} value.`);
58080
- }
58081
- return value;
58082
- };
58083
- const setupApplicationId = requiredValue2("setup-application-id");
58084
- const expectedInputDigest = requiredValue2("expected-input-digest");
58085
- const revisionRaw = requiredValue2("expected-receipt-revision");
58086
- const idempotencyKey = requiredValue2("idempotency-key");
58087
- const expectedReceiptRevision = Number(revisionRaw);
58088
- if (!Number.isSafeInteger(expectedReceiptRevision) || expectedReceiptRevision <= 0) {
58089
- throw new OnboardingUsageError("--expected-receipt-revision must be a positive integer.");
58090
- }
58091
- const sharedBody = {
58092
- setup_application_id: setupApplicationId,
58093
- expected_input_digest: expectedInputDigest,
58094
- expected_receipt_revision: expectedReceiptRevision,
58095
- idempotency_key: idempotencyKey
58096
- };
58097
- if (action === "activate") {
58098
- return {
58099
- commandId: "onboarding.activate",
58100
- body: {
58101
- ...sharedBody,
58102
- terminal_rehearsal_batch_receipt_id: requiredValue2(
58103
- "terminal-rehearsal-batch-receipt-id"
58104
- ),
58105
- rehearsal_runs: parseJsonArrayFlag(
58106
- "rehearsal-runs",
58107
- requiredValue2("rehearsal-runs")
58108
- ),
58109
- configuration_digests: parseJsonArrayFlag(
58110
- "configuration-digests",
58111
- requiredValue2("configuration-digests")
58112
- )
58113
- },
58114
- json: json2,
58115
- action
58116
- };
58117
- }
58118
- return {
58119
- commandId: "onboarding.rehearse",
58120
- body: sharedBody,
58121
- json: json2,
58122
- action
58123
- };
58124
- }
58125
- function onboardingUsage() {
58126
- return [
58127
- `Usage: ${cliBrand.binName} onboard status|resume [--json]`,
58128
- ` ${REHEARSE_USAGE}`,
58129
- ` ${ACTIVATE_USAGE}`
58130
- ].join("\n");
58131
- }
58132
- function formatOnboardingOutput(action, output) {
58133
- if (action === "rehearse") {
58134
- return formatRehearsalOutput(output);
58135
- }
58136
- if (action === "activate") {
58137
- return formatActivationOutput(output);
58138
- }
58139
- const record2 = typeof output === "object" && output !== null ? output : {};
58140
- if (typeof record2.summary === "string") {
58141
- return record2.summary;
58142
- }
58143
- return JSON.stringify(output, null, 2);
58144
- }
58145
- function parseJsonArrayFlag(flag, value) {
58146
- try {
58147
- const parsed = JSON.parse(value);
58148
- if (!Array.isArray(parsed)) {
58149
- throw new Error("not an array");
58150
- }
58151
- return parsed;
58152
- } catch {
58153
- throw new OnboardingUsageError(`--${flag} must be a valid JSON array.`);
58154
- }
58155
- }
58156
- function formatActivationOutput(output) {
58157
- const record2 = asRecord(output);
58158
- const approveVia = asRecord(record2.approveVia);
58159
- if (typeof approveVia.webUrl === "string") {
58160
- return [
58161
- "Onboarding activation approval is ready.",
58162
- `Approve once: ${approveVia.webUrl}`
58163
- ].join("\n");
58164
- }
58165
- const receipt = asRecord(record2.receipt);
58166
- const agents = Array.isArray(receipt.agents) ? receipt.agents : [];
58167
- if (record2.status === "activated") {
58168
- return [
58169
- "Onboarding activation completed.",
58170
- `Activation receipt: ${field(receipt, "activation_receipt_id")}`,
58171
- `Agents live: ${agents.length} of ${agents.length}`,
58172
- `Onboarding completed: ${field(receipt, "onboarding_completed_at")}`
58173
- ].join("\n");
58174
- }
58175
- return JSON.stringify(output, null, 2);
58176
- }
58177
- function formatRehearsalOutput(output) {
58178
- const record2 = asRecord(output);
58179
- if (record2.status === "in_progress") {
58180
- const batch = asRecord(record2.batch);
58181
- const checkpoints = Array.isArray(record2.checkpoints) ? record2.checkpoints : [];
58182
- const completed = checkpoints.filter((checkpoint) => {
58183
- const status = asRecord(checkpoint).status;
58184
- return status === "passed" || status === "failed";
58185
- }).length;
58186
- return [
58187
- "Onboarding rehearsal is in progress.",
58188
- `Batch: ${field(batch, "batch_id")}`,
58189
- `Checkpoints complete: ${completed} of ${checkpoints.length}`,
58190
- ...checkpoints.map((checkpoint) => {
58191
- const item = asRecord(checkpoint);
58192
- return `- Agent ${field(item, "agent_id")} / Seat ${field(item, "seat_id")}: ${field(item, "status")}`;
58193
- }),
58194
- "Retry with the same idempotency key to continue this batch."
58195
- ].join("\n");
58196
- }
58197
- if (record2.status === "passed" || record2.status === "failed") {
58198
- return [
58199
- `Onboarding rehearsal ${record2.status}.`,
58200
- "Immutable batch receipt:",
58201
- JSON.stringify(record2.batch_receipt, null, 2),
58202
- "Immutable agent receipts:",
58203
- JSON.stringify(record2.agent_receipts, null, 2)
58204
- ].join("\n");
58205
- }
58206
- return JSON.stringify(output, null, 2);
58207
- }
58208
- function asRecord(value) {
58209
- return typeof value === "object" && value !== null ? value : {};
58210
- }
58211
- function field(record2, key) {
58212
- const value = record2[key];
58213
- return typeof value === "string" || typeof value === "number" ? String(value) : "\u2014";
58214
- }
58215
- function printCommandError(io, error51) {
58216
- if (error51 instanceof CommandClientError && error51.response && !error51.response.ok) {
58217
- const help = error51.response.error.help;
58218
- const requestId = error51.response.requestId;
58219
- io.stderr.write(redactForLog({
58220
- code: error51.response.error.code,
58221
- message: error51.response.error.message,
58222
- ...error51.response.error.details === void 0 ? {} : { details: error51.response.error.details },
58223
- ...help === void 0 ? {} : { help },
58224
- ...requestId === void 0 ? {} : { requestId }
58225
- }));
58226
- io.stderr.write("\n");
58227
- if (help !== void 0) {
58228
- io.stderr.write(`\u2192 try: ${redactForLog(help)}
58229
- `);
58230
- }
58231
- if (error51.status === 409) {
58232
- return 3;
58233
- }
58234
- return error51.status >= 400 && error51.status < 500 ? 1 : 2;
58235
- }
58236
- throw error51;
58237
- }
58238
-
58239
- // src/commands/implementation-access.ts
58240
- var implementationCredentialSchema = external_exports.object({
58241
- token: external_exports.string().regex(/^rost_impl_[A-Za-z0-9_-]+$/),
58242
- token_id: external_exports.string().uuid(),
58243
- tenant_id: external_exports.string().uuid(),
58244
- implementation_run_id: external_exports.string().uuid(),
58245
- scope: external_exports.literal("implementation_bootstrap"),
58246
- expires_at: external_exports.string().datetime({ offset: true })
58247
- }).strict();
58248
- var ImplementationAccessError = class extends Error {
58249
- constructor(message) {
58250
- super(message);
58251
- this.name = "ImplementationAccessError";
58252
- }
58253
- };
58254
- var DEFAULT_SOURCE_CLIENT = "external-agent";
58255
- var SOURCE_CLIENT_MAX_LENGTH = 80;
58256
- async function runImplementationAccess(args, io, deps) {
58257
- const json2 = args.includes("--json");
58258
- const action = parseAction(args[0]);
58259
- if (action === null) {
58260
- io.stderr.write(
58261
- `Usage: ${cliBrand.binName} implementation access start|status|complete|abandon [--json]
58262
- `
58263
- );
58264
- return 1;
58265
- }
58266
- if (action === "start") {
58267
- const sourceClient = parseSourceClient(args.slice(1), DEFAULT_SOURCE_CLIENT);
58268
- return runStart(io, deps, sourceClient, json2);
58269
- }
58270
- const store = deps.createImplementationStore();
58271
- const credential = await store.read();
58272
- if (!credential) {
58273
- io.stderr.write("No implementation credential. Run rost implementation access start.\n");
58274
- return 1;
58275
- }
58276
- if (action === "status") {
58277
- return runStatus(io, deps, credential, json2);
58278
- }
58279
- if (action === "complete") {
58280
- return runComplete(io, deps, credential, store, json2);
58281
- }
58282
- return runAbandon(io, deps, credential, store, json2);
58283
- }
58284
- function parseAction(value) {
58285
- if (value === "start" || value === "status" || value === "complete" || value === "abandon") {
58286
- return value;
58287
- }
58288
- return null;
58289
- }
58290
- function parseSourceClient(args, defaultValue) {
58291
- let sourceClient;
58292
- for (let index = 0; index < args.length; index += 1) {
58293
- const arg = args[index];
58294
- if (arg === "--source-client") {
58295
- sourceClient = args[index + 1];
58296
- if (sourceClient === void 0) {
58297
- throw new ImplementationAccessError("--source-client requires a value.");
58298
- }
58299
- index += 1;
58300
- }
58301
- }
58302
- const value = (sourceClient ?? defaultValue).trim();
58303
- if (value.length === 0) {
58304
- throw new ImplementationAccessError("--source-client cannot be blank.");
58305
- }
58306
- if (value.length > SOURCE_CLIENT_MAX_LENGTH) {
58307
- throw new ImplementationAccessError(`--source-client must be ${SOURCE_CLIENT_MAX_LENGTH} characters or fewer.`);
58308
- }
58309
- return value;
58310
- }
58311
- function minimalConfig(appUrl2) {
58312
- return {
58313
- appUrl: appUrl2,
58314
- supabaseUrl: "https://unused.example.test",
58315
- supabaseAnonKey: "unused"
58316
- };
58317
- }
58318
- async function runStart(io, deps, sourceClient, json2) {
58319
- const store = deps.createImplementationStore();
58320
- const credential = await deps.pollDeviceAuthorizationHandoff(
58321
- minimalConfig(deps.appUrl),
58322
- io,
58323
- {
58324
- purpose: "implementation_bootstrap",
58325
- sourceClient,
58326
- // DER-2158 (U3b) C3: `silent: json` still suppresses the poller's own
58327
- // stdout print + browser open in --json mode, so stdout stays pure JSON
58328
- // for a machine caller. But without a replacement, --json mode never
58329
- // shows the verification URL/code at all — the command blocks until
58330
- // approval and nobody ever saw the code to approve it, so it always
58331
- // times out. `onStart` fires unconditionally (even when silent), so use
58332
- // it to surface the same URL/code on STDERR instead. Never write the
58333
- // bearer token here — the pre-approval StartSession doesn't carry one.
58334
- silent: json2,
58335
- ...json2 ? { onStart: (session) => writeJsonStartPrompt(io, session) } : {}
58336
- },
58337
- {},
58338
- (approved) => mapApprovedToCredential(approved)
58339
- );
58340
- await store.write(credential);
58341
- if (json2) {
58342
- io.stdout.write(
58343
- `${JSON.stringify({
58344
- status: "started",
58345
- run_id: credential.implementation_run_id,
58346
- tenant_id: credential.tenant_id,
58347
- scope: credential.scope,
58348
- expires_at: credential.expires_at,
58349
- stored_in: store.describe()
58350
- })}
58351
- `
58352
- );
58353
- } else {
58354
- io.stdout.write(
58355
- `The implementation credential is stored in ${store.describe()} and expires at ${credential.expires_at}.
58356
- `
58357
- );
58358
- }
58359
- return 0;
58360
- }
58361
- function writeJsonStartPrompt(io, session) {
58362
- io.stderr.write(
58363
- [
58364
- "To sign in, open this URL in any browser and approve the code:",
58365
- ` ${session.verification_uri}`,
58366
- "",
58367
- ` Code: ${session.user_code}`,
58368
- "",
58369
- "Waiting for approval\u2026",
58370
- ""
58371
- ].join("\n")
58372
- );
58373
- }
58374
- function mapApprovedToCredential(approved) {
58375
- const raw = approved;
58376
- const parsed = implementationCredentialSchema.safeParse({
58377
- token: raw.token,
58378
- token_id: raw.token_id,
58379
- tenant_id: raw.tenant_id,
58380
- implementation_run_id: raw.implementation_run_id,
58381
- scope: raw.scope,
58382
- expires_at: raw.expires_at
58383
- });
58384
- if (!parsed.success) {
58385
- return null;
58386
- }
58387
- return parsed.data;
58388
- }
58389
- function createImplementationClient(deps, credential) {
58390
- return new deps.CommandClient({
58391
- appUrl: deps.appUrl,
58392
- token: credential.token,
58393
- credentialKind: "implementation_bootstrap"
58394
- });
58395
- }
58396
- function isDeadRunError(error51) {
58397
- if (!(error51 instanceof CommandClientError) || !error51.response || error51.response.ok) {
58398
- return false;
58399
- }
58400
- if (error51.status === 401) {
58401
- return true;
58402
- }
58403
- const code = error51.response.error.code;
58404
- return code === "COMMAND_AUTHORIZATION" || code === "COMMAND_UNAUTHENTICATED" || /expired/i.test(error51.response.error.message);
58405
- }
58406
- async function runStatus(io, deps, credential, json2) {
58407
- const client = createImplementationClient(deps, credential);
58408
- try {
58409
- const result = await client.execute("implementation_access.status", {});
58410
- if (json2) {
58411
- io.stdout.write(`${JSON.stringify(result.output)}
58412
- `);
58413
- } else {
58414
- io.stdout.write(`${redactForLog(formatStatusSummary(result.output))}
58415
- `);
58416
- }
58417
- return 0;
58418
- } catch (error51) {
58419
- if (isDeadRunError(error51)) {
58420
- io.stderr.write(
58421
- "The implementation run is no longer active. Start a new one: rost implementation access start\n"
58422
- );
58423
- return 1;
58424
- }
58425
- io.stderr.write(`${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
58426
- `);
58427
- return 1;
58428
- }
58429
- }
58430
- function formatStatusSummary(output) {
58431
- const record2 = typeof output === "object" && output !== null ? output : {};
58432
- const status = typeof record2.status === "string" ? record2.status : "unknown";
58433
- const runId = typeof record2.run_id === "string" ? record2.run_id : "unknown";
58434
- return `Implementation run ${runId} status: ${status}.`;
58435
- }
58436
- async function runComplete(io, deps, credential, store, json2) {
58437
- const client = createImplementationClient(deps, credential);
58438
- try {
58439
- const result = await client.execute("implementation_access.complete", {});
58440
- await store.clear();
58441
- if (json2) {
58442
- io.stdout.write(
58443
- `${JSON.stringify({
58444
- status: "completed",
58445
- run_id: credential.implementation_run_id,
58446
- already_closed: result.output?.already_closed ?? false
58447
- })}
58448
- `
58449
- );
58450
- } else {
58451
- io.stdout.write("Implementation run completed and the local credential was cleared.\n");
58452
- }
58453
- return 0;
58454
- } catch (error51) {
58455
- io.stderr.write(`${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
58456
- `);
58457
- io.stderr.write("The credential was kept. Retry with: rost implementation access complete\n");
58458
- return 1;
58459
- }
58460
- }
58461
- async function runAbandon(io, deps, credential, store, json2) {
58462
- const client = createImplementationClient(deps, credential);
58463
- try {
58464
- const result = await client.execute("implementation_access.abandon", {});
58465
- await store.clear();
58466
- if (json2) {
58467
- io.stdout.write(
58468
- `${JSON.stringify({
58469
- status: "abandoned",
58470
- run_id: credential.implementation_run_id,
58471
- already_closed: result.output?.already_closed ?? false
58472
- })}
58473
- `
58474
- );
58475
- } else {
58476
- io.stdout.write("Implementation run abandoned and the local credential was cleared.\n");
58477
- }
58478
- return 0;
58479
- } catch (error51) {
58480
- io.stderr.write(`${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
58481
- `);
58482
- io.stderr.write("The credential was kept. Retry with: rost implementation access abandon\n");
58483
- return 1;
58484
- }
58485
- }
58486
- function defaultImplementationAccessDeps(appUrl2) {
58487
- return {
58488
- appUrl: appUrl2,
58489
- createImplementationStore: createImplementationCredentialStore,
58490
- pollDeviceAuthorizationHandoff,
58491
- CommandClient
58492
- };
58493
- }
58024
+ import { readFile as readFile5 } from "node:fs/promises";
58494
58025
 
58495
58026
  // src/generated/command-manifest.ts
58496
58027
  var COMMAND_MANIFEST = [
@@ -58791,6 +58322,738 @@ var COMMAND_MANIFEST = [
58791
58322
  { "id": "work.record", "namespace": "work", "action": "record", "title": "Record work", "description": "Append one or more structured business-activity records to the agent work ledger for the acting seat. Batch-accepting, append-only, secret-redacted, and idempotent on dedup_key. Corrections are superseding records.", "requiredScope": "seat", "confirmation": "none", "exposeOverMcp": true, "fields": [], "hasComplexInput": true, "help": "Append structured business-activity records (verb + entity refs + outcome + evidence) to the seat's work ledger, in a batch, right after each action succeeds." }
58792
58323
  ];
58793
58324
 
58325
+ // src/commands/onboarding.ts
58326
+ var REHEARSE_USAGE = `${cliBrand.binName} onboard rehearse --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision <integer> --idempotency-key <key> [--json]`;
58327
+ var ACTIVATE_USAGE = `${cliBrand.binName} onboard activate --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision <integer> --terminal-rehearsal-batch-receipt-id <uuid> --rehearsal-runs '<json-array>' --configuration-digests '<json-array>' --idempotency-key <key> [--json]`;
58328
+ var SOURCE_INGEST_USAGE = `${cliBrand.binName} onboard source-ingest --file <path> --source-key <key> --kind <kind> --title <title> [--json]`;
58329
+ var SERVER_COMMAND_BODY_CAP_BYTES = 1048576;
58330
+ var COMMAND_BODY_SAFETY_MARGIN_BYTES = 4096;
58331
+ var SETUP_USAGE = `${cliBrand.binName} onboard setup --input '<json-plan>' | --input-file <path> [--json]`;
58332
+ var SETUP_STATUS_USAGE = `${cliBrand.binName} onboard setup-status --input '<json-plan>' | --input-file <path> [--json]`;
58333
+ function sourceIngestKinds() {
58334
+ const entry = COMMAND_MANIFEST.find((candidate) => candidate.id === "onboarding.source_ingest");
58335
+ const kinds = entry?.fields.find((field4) => field4.name === "kind")?.enumValues;
58336
+ if (!kinds || kinds.length === 0) {
58337
+ throw new Error("The command manifest is missing onboarding.source_ingest kind values.");
58338
+ }
58339
+ return kinds;
58340
+ }
58341
+ var OnboardingUsageError = class extends Error {
58342
+ constructor(message) {
58343
+ super(message);
58344
+ this.name = "OnboardingUsageError";
58345
+ }
58346
+ };
58347
+ async function runOnboarding(args, io, deps) {
58348
+ let invocation;
58349
+ try {
58350
+ invocation = parseOnboardingInvocation(args);
58351
+ await resolveOnboardingInvocationFiles(invocation, deps.readFile ?? readFile5);
58352
+ } catch (error51) {
58353
+ if (!(error51 instanceof OnboardingUsageError)) {
58354
+ throw error51;
58355
+ }
58356
+ io.stderr.write(`${error51.message}
58357
+ ${onboardingUsage()}
58358
+ `);
58359
+ return 1;
58360
+ }
58361
+ const client = await deps.makeClient();
58362
+ return executeOnboardingInvocation(invocation, io, client);
58363
+ }
58364
+ async function executeOnboardingInvocation(invocation, io, client, options = {}) {
58365
+ try {
58366
+ const result = await client.execute(invocation.commandId, invocation.body);
58367
+ const rendered = invocation.json ? JSON.stringify(result.output, null, 2) : formatOnboardingOutput(invocation.action, result.output);
58368
+ io.stdout.write(`${rendered}
58369
+ `);
58370
+ return 0;
58371
+ } catch (error51) {
58372
+ const staged = stagedSetupConfirmationFromError(invocation, error51);
58373
+ if (staged !== null) {
58374
+ io.stdout.write(`${invocation.json ? JSON.stringify(staged, null, 2) : formatStagedSetupConfirmation(invocation.action, staged)}
58375
+ `);
58376
+ return 0;
58377
+ }
58378
+ if (options.onError && options.onError(error51) === "handled") {
58379
+ return "fall-through";
58380
+ }
58381
+ return printCommandError(io, error51);
58382
+ }
58383
+ }
58384
+ async function resolveOnboardingInvocationFiles(invocation, readFileImpl = readFile5) {
58385
+ if (invocation.sourceFile !== void 0) {
58386
+ let bytes;
58387
+ try {
58388
+ bytes = await readFileImpl(invocation.sourceFile);
58389
+ } catch (error51) {
58390
+ throw new OnboardingUsageError(
58391
+ `Could not read --file ${invocation.sourceFile}: ${error51 instanceof Error ? error51.message : String(error51)}`
58392
+ );
58393
+ }
58394
+ if (bytes.length === 0) {
58395
+ throw new OnboardingUsageError(`--file ${invocation.sourceFile} is empty.`);
58396
+ }
58397
+ const contentBase64 = bytes.toString("base64");
58398
+ invocation.body.content_base64 = contentBase64;
58399
+ const bodyBytes = Buffer.byteLength(JSON.stringify(invocation.body), "utf8");
58400
+ const preflightCap = SERVER_COMMAND_BODY_CAP_BYTES - COMMAND_BODY_SAFETY_MARGIN_BYTES;
58401
+ if (bodyBytes > preflightCap) {
58402
+ const overheadBytes = bodyBytes - contentBase64.length;
58403
+ const effectiveMaxFileBytes = Math.floor((preflightCap - overheadBytes) / 4) * 3;
58404
+ throw new OnboardingUsageError(
58405
+ `--file ${invocation.sourceFile} is ${bytes.length} bytes; base64-encoded it makes a ${bodyBytes}-byte command body, over the server's authoritative ${SERVER_COMMAND_BODY_CAP_BYTES}-byte command-transport cap (this check stops ${COMMAND_BODY_SAFETY_MARGIN_BYTES} bytes early on purpose). The largest file this invocation can send is about ${effectiveMaxFileBytes} bytes. The onboarding.source_ingest protocol documents sources up to 5,000,000 bytes; reaching that range needs the server-side transport follow-up. Split the export or trim rows/columns to fit.`
58406
+ );
58407
+ }
58408
+ delete invocation.sourceFile;
58409
+ }
58410
+ if (invocation.inputFile !== void 0) {
58411
+ let text;
58412
+ try {
58413
+ text = (await readFileImpl(invocation.inputFile)).toString("utf8");
58414
+ } catch (error51) {
58415
+ throw new OnboardingUsageError(
58416
+ `Could not read --input-file ${invocation.inputFile}: ${error51 instanceof Error ? error51.message : String(error51)}`
58417
+ );
58418
+ }
58419
+ invocation.body = parseSetupPlanJson(text, "--input-file");
58420
+ delete invocation.inputFile;
58421
+ }
58422
+ }
58423
+ function stagedSetupConfirmationFromError(invocation, error51) {
58424
+ if (invocation.action !== "setup" && invocation.action !== "setup-status") {
58425
+ return null;
58426
+ }
58427
+ if (!(error51 instanceof CommandClientError) || !error51.response || error51.response.ok || error51.response.error.code !== "COMMAND_CONFIRMATION_REQUIRED") {
58428
+ return null;
58429
+ }
58430
+ const details = error51.response.error.details;
58431
+ if (typeof details !== "object" || details === null) {
58432
+ return null;
58433
+ }
58434
+ const record2 = details;
58435
+ return record2.commandId === invocation.commandId ? record2 : null;
58436
+ }
58437
+ function formatStagedSetupConfirmation(action, details) {
58438
+ const approveVia = asRecord(details.approveVia);
58439
+ const lines = [
58440
+ action === "setup-status" ? "Onboarding setup approval is pending. The URL below is the current card: an identical still-valid card is reused as-is; if live state moved, the stale card was superseded and this fresh one minted." : "Onboarding setup approval is ready.",
58441
+ `Confirmation: ${field(details, "confirmationId")}`
58442
+ ];
58443
+ if (typeof approveVia.webUrl === "string") {
58444
+ lines.push(`Approve once: ${approveVia.webUrl}`);
58445
+ }
58446
+ lines.push(
58447
+ "After the owner approves, re-run this command with the identical plan to read the immutable setup receipt."
58448
+ );
58449
+ return lines.join("\n");
58450
+ }
58451
+ function parseSetupPlanJson(text, flag) {
58452
+ let parsed;
58453
+ try {
58454
+ parsed = JSON.parse(text);
58455
+ } catch {
58456
+ throw new OnboardingUsageError(`${flag} must be valid JSON.`);
58457
+ }
58458
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
58459
+ throw new OnboardingUsageError(`${flag} must be a JSON object (the complete onboarding setup plan).`);
58460
+ }
58461
+ return parsed;
58462
+ }
58463
+ function parseOnboardingInvocation(args) {
58464
+ const action = args[0];
58465
+ if (action === "status" || action === "resume") {
58466
+ return {
58467
+ commandId: action === "status" ? "onboarding.status" : "onboarding.resume",
58468
+ body: {},
58469
+ json: args.includes("--json"),
58470
+ action
58471
+ };
58472
+ }
58473
+ if (action === "source-ingest") {
58474
+ return parseSourceIngestInvocation(args.slice(1));
58475
+ }
58476
+ if (action === "setup" || action === "setup-status") {
58477
+ return parseSetupInvocation(action, args.slice(1));
58478
+ }
58479
+ if (action !== "rehearse" && action !== "activate") {
58480
+ throw new OnboardingUsageError(`Unknown onboard action: ${action ?? "(missing)"}`);
58481
+ }
58482
+ const allowed = /* @__PURE__ */ new Set([
58483
+ "setup-application-id",
58484
+ "expected-input-digest",
58485
+ "expected-receipt-revision",
58486
+ "idempotency-key",
58487
+ ...action === "activate" ? [
58488
+ "terminal-rehearsal-batch-receipt-id",
58489
+ "rehearsal-runs",
58490
+ "configuration-digests"
58491
+ ] : []
58492
+ ]);
58493
+ const values = /* @__PURE__ */ new Map();
58494
+ let json2 = false;
58495
+ for (let index = 1; index < args.length; index += 1) {
58496
+ const argument = args[index];
58497
+ if (argument === "--json") {
58498
+ if (json2) {
58499
+ throw new OnboardingUsageError("Duplicate --json flag.");
58500
+ }
58501
+ json2 = true;
58502
+ continue;
58503
+ }
58504
+ if (argument === void 0 || !argument.startsWith("--")) {
58505
+ throw new OnboardingUsageError(`Unexpected argument: ${argument ?? "(missing)"}`);
58506
+ }
58507
+ const key = argument.slice(2);
58508
+ if (!allowed.has(key)) {
58509
+ throw new OnboardingUsageError(`Unknown flag: --${key}`);
58510
+ }
58511
+ if (values.has(key)) {
58512
+ throw new OnboardingUsageError(`Duplicate --${key} flag.`);
58513
+ }
58514
+ const value = args[index + 1];
58515
+ if (value === void 0 || value.startsWith("--")) {
58516
+ throw new OnboardingUsageError(`Missing required --${key} value.`);
58517
+ }
58518
+ values.set(key, value);
58519
+ index += 1;
58520
+ }
58521
+ const requiredValue2 = (key) => {
58522
+ const value = values.get(key);
58523
+ if (value === void 0 || value.length === 0) {
58524
+ throw new OnboardingUsageError(`Missing required --${key} value.`);
58525
+ }
58526
+ return value;
58527
+ };
58528
+ const setupApplicationId = requiredValue2("setup-application-id");
58529
+ const expectedInputDigest = requiredValue2("expected-input-digest");
58530
+ const revisionRaw = requiredValue2("expected-receipt-revision");
58531
+ const idempotencyKey = requiredValue2("idempotency-key");
58532
+ const expectedReceiptRevision = Number(revisionRaw);
58533
+ if (!Number.isSafeInteger(expectedReceiptRevision) || expectedReceiptRevision <= 0) {
58534
+ throw new OnboardingUsageError("--expected-receipt-revision must be a positive integer.");
58535
+ }
58536
+ const sharedBody = {
58537
+ setup_application_id: setupApplicationId,
58538
+ expected_input_digest: expectedInputDigest,
58539
+ expected_receipt_revision: expectedReceiptRevision,
58540
+ idempotency_key: idempotencyKey
58541
+ };
58542
+ if (action === "activate") {
58543
+ return {
58544
+ commandId: "onboarding.activate",
58545
+ body: {
58546
+ ...sharedBody,
58547
+ terminal_rehearsal_batch_receipt_id: requiredValue2(
58548
+ "terminal-rehearsal-batch-receipt-id"
58549
+ ),
58550
+ rehearsal_runs: parseJsonArrayFlag(
58551
+ "rehearsal-runs",
58552
+ requiredValue2("rehearsal-runs")
58553
+ ),
58554
+ configuration_digests: parseJsonArrayFlag(
58555
+ "configuration-digests",
58556
+ requiredValue2("configuration-digests")
58557
+ )
58558
+ },
58559
+ json: json2,
58560
+ action
58561
+ };
58562
+ }
58563
+ return {
58564
+ commandId: "onboarding.rehearse",
58565
+ body: sharedBody,
58566
+ json: json2,
58567
+ action
58568
+ };
58569
+ }
58570
+ function collectFlagValues(args, allowed) {
58571
+ const values = /* @__PURE__ */ new Map();
58572
+ let json2 = false;
58573
+ for (let index = 0; index < args.length; index += 1) {
58574
+ const argument = args[index];
58575
+ if (argument === "--json") {
58576
+ if (json2) {
58577
+ throw new OnboardingUsageError("Duplicate --json flag.");
58578
+ }
58579
+ json2 = true;
58580
+ continue;
58581
+ }
58582
+ if (argument === void 0 || !argument.startsWith("--")) {
58583
+ throw new OnboardingUsageError(`Unexpected argument: ${argument ?? "(missing)"}`);
58584
+ }
58585
+ const key = argument.slice(2);
58586
+ if (!allowed.has(key)) {
58587
+ throw new OnboardingUsageError(`Unknown flag: --${key}`);
58588
+ }
58589
+ if (values.has(key)) {
58590
+ throw new OnboardingUsageError(`Duplicate --${key} flag.`);
58591
+ }
58592
+ const value = args[index + 1];
58593
+ if (value === void 0 || value.startsWith("--")) {
58594
+ throw new OnboardingUsageError(`Missing required --${key} value.`);
58595
+ }
58596
+ values.set(key, value);
58597
+ index += 1;
58598
+ }
58599
+ return { values, json: json2 };
58600
+ }
58601
+ function parseSourceIngestInvocation(args) {
58602
+ const { values, json: json2 } = collectFlagValues(
58603
+ args,
58604
+ /* @__PURE__ */ new Set(["file", "source-key", "kind", "title"])
58605
+ );
58606
+ const required2 = (key) => {
58607
+ const value = values.get(key);
58608
+ if (value === void 0 || value.length === 0) {
58609
+ throw new OnboardingUsageError(`Missing required --${key} value.`);
58610
+ }
58611
+ return value;
58612
+ };
58613
+ const kind = required2("kind");
58614
+ const kinds = sourceIngestKinds();
58615
+ if (!kinds.includes(kind)) {
58616
+ throw new OnboardingUsageError(`--kind must be one of: ${kinds.join(", ")}`);
58617
+ }
58618
+ return {
58619
+ commandId: "onboarding.source_ingest",
58620
+ body: {
58621
+ source_key: required2("source-key"),
58622
+ kind,
58623
+ title: required2("title")
58624
+ },
58625
+ json: json2,
58626
+ action: "source-ingest",
58627
+ sourceFile: required2("file")
58628
+ };
58629
+ }
58630
+ function parseSetupInvocation(action, args) {
58631
+ const { values, json: json2 } = collectFlagValues(args, /* @__PURE__ */ new Set(["input", "input-file"]));
58632
+ const input = values.get("input");
58633
+ const inputFile = values.get("input-file");
58634
+ if (input === void 0 === (inputFile === void 0)) {
58635
+ throw new OnboardingUsageError(
58636
+ `onboard ${action} requires exactly one of --input '<json-plan>' or --input-file <path>.`
58637
+ );
58638
+ }
58639
+ return {
58640
+ commandId: "onboarding.setup",
58641
+ body: input === void 0 ? {} : parseSetupPlanJson(input, "--input"),
58642
+ json: json2,
58643
+ action,
58644
+ ...inputFile === void 0 ? {} : { inputFile }
58645
+ };
58646
+ }
58647
+ function onboardingUsage() {
58648
+ return [
58649
+ `Usage: ${cliBrand.binName} onboard status|resume [--json]`,
58650
+ ` ${SOURCE_INGEST_USAGE}`,
58651
+ ` ${SETUP_USAGE}`,
58652
+ ` ${SETUP_STATUS_USAGE}`,
58653
+ ` ${REHEARSE_USAGE}`,
58654
+ ` ${ACTIVATE_USAGE}`
58655
+ ].join("\n");
58656
+ }
58657
+ function formatOnboardingOutput(action, output) {
58658
+ if (action === "rehearse") {
58659
+ return formatRehearsalOutput(output);
58660
+ }
58661
+ if (action === "activate") {
58662
+ return formatActivationOutput(output);
58663
+ }
58664
+ if (action === "source-ingest") {
58665
+ return formatSourceIngestOutput(output);
58666
+ }
58667
+ if (action === "setup" || action === "setup-status") {
58668
+ return formatAppliedSetupOutput(output);
58669
+ }
58670
+ const record2 = typeof output === "object" && output !== null ? output : {};
58671
+ if (typeof record2.summary === "string") {
58672
+ return record2.summary;
58673
+ }
58674
+ return JSON.stringify(output, null, 2);
58675
+ }
58676
+ function parseJsonArrayFlag(flag, value) {
58677
+ try {
58678
+ const parsed = JSON.parse(value);
58679
+ if (!Array.isArray(parsed)) {
58680
+ throw new Error("not an array");
58681
+ }
58682
+ return parsed;
58683
+ } catch {
58684
+ throw new OnboardingUsageError(`--${flag} must be a valid JSON array.`);
58685
+ }
58686
+ }
58687
+ function formatActivationOutput(output) {
58688
+ const record2 = asRecord(output);
58689
+ const approveVia = asRecord(record2.approveVia);
58690
+ if (typeof approveVia.webUrl === "string") {
58691
+ return [
58692
+ "Onboarding activation approval is ready.",
58693
+ `Approve once: ${approveVia.webUrl}`
58694
+ ].join("\n");
58695
+ }
58696
+ const receipt = asRecord(record2.receipt);
58697
+ const agents = Array.isArray(receipt.agents) ? receipt.agents : [];
58698
+ if (record2.status === "activated") {
58699
+ return [
58700
+ "Onboarding activation completed.",
58701
+ `Activation receipt: ${field(receipt, "activation_receipt_id")}`,
58702
+ `Agents live: ${agents.length} of ${agents.length}`,
58703
+ `Onboarding completed: ${field(receipt, "onboarding_completed_at")}`
58704
+ ].join("\n");
58705
+ }
58706
+ return JSON.stringify(output, null, 2);
58707
+ }
58708
+ function formatSourceIngestOutput(output) {
58709
+ const record2 = asRecord(output);
58710
+ const descriptor = asRecord(record2.descriptor);
58711
+ const families = Array.isArray(descriptor.family_manifest) ? descriptor.family_manifest : [];
58712
+ return [
58713
+ "Source retained for this run.",
58714
+ `Upload: ${field(record2, "source_upload_id")}`,
58715
+ `SHA-256: ${field(descriptor, "sha256")}`,
58716
+ `Bytes: ${field(descriptor, "byte_count")}`,
58717
+ ...families.map((entry) => {
58718
+ const item = asRecord(entry);
58719
+ return `- ${field(item, "family")}: ${field(item, "input_count")} rows`;
58720
+ }),
58721
+ "Reference it from the setup plan's sources[] via the returned source_ref (run with --json to capture it verbatim)."
58722
+ ].join("\n");
58723
+ }
58724
+ function formatAppliedSetupOutput(output) {
58725
+ const record2 = asRecord(output);
58726
+ if (typeof record2.application_id !== "string") {
58727
+ return JSON.stringify(output, null, 2);
58728
+ }
58729
+ const receipt = asRecord(record2.receipt);
58730
+ const digests = asRecord(receipt.digests);
58731
+ return [
58732
+ "Onboarding setup is applied.",
58733
+ `Setup application: ${field(record2, "application_id")}`,
58734
+ `Receipt revision: ${field(receipt, "receipt_revision")}`,
58735
+ `Input digest: ${field(digests, "input")}`,
58736
+ `Next: ${cliBrand.binName} onboard rehearse --setup-application-id ${field(record2, "application_id")} --expected-input-digest ${field(digests, "input")} --expected-receipt-revision ${field(receipt, "receipt_revision")} --idempotency-key <stable-key> --json`
58737
+ ].join("\n");
58738
+ }
58739
+ function formatRehearsalOutput(output) {
58740
+ const record2 = asRecord(output);
58741
+ if (record2.status === "in_progress") {
58742
+ const batch = asRecord(record2.batch);
58743
+ const checkpoints = Array.isArray(record2.checkpoints) ? record2.checkpoints : [];
58744
+ const completed = checkpoints.filter((checkpoint) => {
58745
+ const status = asRecord(checkpoint).status;
58746
+ return status === "passed" || status === "failed";
58747
+ }).length;
58748
+ return [
58749
+ "Onboarding rehearsal is in progress.",
58750
+ `Batch: ${field(batch, "batch_id")}`,
58751
+ `Checkpoints complete: ${completed} of ${checkpoints.length}`,
58752
+ ...checkpoints.map((checkpoint) => {
58753
+ const item = asRecord(checkpoint);
58754
+ return `- Agent ${field(item, "agent_id")} / Seat ${field(item, "seat_id")}: ${field(item, "status")}`;
58755
+ }),
58756
+ "Retry with the same idempotency key to continue this batch."
58757
+ ].join("\n");
58758
+ }
58759
+ if (record2.status === "passed" || record2.status === "failed") {
58760
+ return [
58761
+ `Onboarding rehearsal ${record2.status}.`,
58762
+ "Immutable batch receipt:",
58763
+ JSON.stringify(record2.batch_receipt, null, 2),
58764
+ "Immutable agent receipts:",
58765
+ JSON.stringify(record2.agent_receipts, null, 2)
58766
+ ].join("\n");
58767
+ }
58768
+ return JSON.stringify(output, null, 2);
58769
+ }
58770
+ function asRecord(value) {
58771
+ return typeof value === "object" && value !== null ? value : {};
58772
+ }
58773
+ function field(record2, key) {
58774
+ const value = record2[key];
58775
+ return typeof value === "string" || typeof value === "number" ? String(value) : "\u2014";
58776
+ }
58777
+ function printCommandError(io, error51) {
58778
+ if (error51 instanceof CommandClientError && error51.response && !error51.response.ok) {
58779
+ const help = error51.response.error.help;
58780
+ const requestId = error51.response.requestId;
58781
+ io.stderr.write(redactForLog({
58782
+ code: error51.response.error.code,
58783
+ message: error51.response.error.message,
58784
+ ...error51.response.error.details === void 0 ? {} : { details: error51.response.error.details },
58785
+ ...help === void 0 ? {} : { help },
58786
+ ...requestId === void 0 ? {} : { requestId }
58787
+ }));
58788
+ io.stderr.write("\n");
58789
+ if (help !== void 0) {
58790
+ io.stderr.write(`\u2192 try: ${redactForLog(help)}
58791
+ `);
58792
+ }
58793
+ if (error51.status === 409) {
58794
+ return 3;
58795
+ }
58796
+ return error51.status >= 400 && error51.status < 500 ? 1 : 2;
58797
+ }
58798
+ throw error51;
58799
+ }
58800
+
58801
+ // src/commands/implementation-access.ts
58802
+ var implementationCredentialSchema = external_exports.object({
58803
+ token: external_exports.string().regex(/^rost_impl_[A-Za-z0-9_-]+$/),
58804
+ token_id: external_exports.string().uuid(),
58805
+ tenant_id: external_exports.string().uuid(),
58806
+ implementation_run_id: external_exports.string().uuid(),
58807
+ scope: external_exports.literal("implementation_bootstrap"),
58808
+ expires_at: external_exports.string().datetime({ offset: true })
58809
+ }).strict();
58810
+ var ImplementationAccessError = class extends Error {
58811
+ constructor(message) {
58812
+ super(message);
58813
+ this.name = "ImplementationAccessError";
58814
+ }
58815
+ };
58816
+ var DEFAULT_SOURCE_CLIENT = "external-agent";
58817
+ var SOURCE_CLIENT_MAX_LENGTH = 80;
58818
+ async function runImplementationAccess(args, io, deps) {
58819
+ const json2 = args.includes("--json");
58820
+ const action = parseAction(args[0]);
58821
+ if (action === null) {
58822
+ io.stderr.write(
58823
+ `Usage: ${cliBrand.binName} implementation access start|status|complete|abandon [--json]
58824
+ `
58825
+ );
58826
+ return 1;
58827
+ }
58828
+ if (action === "start") {
58829
+ const sourceClient = parseSourceClient(args.slice(1), DEFAULT_SOURCE_CLIENT);
58830
+ return runStart(io, deps, sourceClient, json2);
58831
+ }
58832
+ const store = deps.createImplementationStore();
58833
+ const credential = await store.read();
58834
+ if (!credential) {
58835
+ io.stderr.write("No implementation credential. Run rost implementation access start.\n");
58836
+ return 1;
58837
+ }
58838
+ if (action === "status") {
58839
+ return runStatus(io, deps, credential, json2);
58840
+ }
58841
+ if (action === "complete") {
58842
+ return runComplete(io, deps, credential, store, json2);
58843
+ }
58844
+ return runAbandon(io, deps, credential, store, json2);
58845
+ }
58846
+ function parseAction(value) {
58847
+ if (value === "start" || value === "status" || value === "complete" || value === "abandon") {
58848
+ return value;
58849
+ }
58850
+ return null;
58851
+ }
58852
+ function parseSourceClient(args, defaultValue) {
58853
+ let sourceClient;
58854
+ for (let index = 0; index < args.length; index += 1) {
58855
+ const arg = args[index];
58856
+ if (arg === "--source-client") {
58857
+ sourceClient = args[index + 1];
58858
+ if (sourceClient === void 0) {
58859
+ throw new ImplementationAccessError("--source-client requires a value.");
58860
+ }
58861
+ index += 1;
58862
+ }
58863
+ }
58864
+ const value = (sourceClient ?? defaultValue).trim();
58865
+ if (value.length === 0) {
58866
+ throw new ImplementationAccessError("--source-client cannot be blank.");
58867
+ }
58868
+ if (value.length > SOURCE_CLIENT_MAX_LENGTH) {
58869
+ throw new ImplementationAccessError(`--source-client must be ${SOURCE_CLIENT_MAX_LENGTH} characters or fewer.`);
58870
+ }
58871
+ return value;
58872
+ }
58873
+ function minimalConfig(appUrl2) {
58874
+ return {
58875
+ appUrl: appUrl2,
58876
+ supabaseUrl: "https://unused.example.test",
58877
+ supabaseAnonKey: "unused"
58878
+ };
58879
+ }
58880
+ async function runStart(io, deps, sourceClient, json2) {
58881
+ const store = deps.createImplementationStore();
58882
+ const credential = await deps.pollDeviceAuthorizationHandoff(
58883
+ minimalConfig(deps.appUrl),
58884
+ io,
58885
+ {
58886
+ purpose: "implementation_bootstrap",
58887
+ sourceClient,
58888
+ // DER-2158 (U3b) C3: `silent: json` still suppresses the poller's own
58889
+ // stdout print + browser open in --json mode, so stdout stays pure JSON
58890
+ // for a machine caller. But without a replacement, --json mode never
58891
+ // shows the verification URL/code at all — the command blocks until
58892
+ // approval and nobody ever saw the code to approve it, so it always
58893
+ // times out. `onStart` fires unconditionally (even when silent), so use
58894
+ // it to surface the same URL/code on STDERR instead. Never write the
58895
+ // bearer token here — the pre-approval StartSession doesn't carry one.
58896
+ silent: json2,
58897
+ ...json2 ? { onStart: (session) => writeJsonStartPrompt(io, session) } : {}
58898
+ },
58899
+ {},
58900
+ (approved) => mapApprovedToCredential(approved)
58901
+ );
58902
+ await store.write(credential);
58903
+ if (json2) {
58904
+ io.stdout.write(
58905
+ `${JSON.stringify({
58906
+ status: "started",
58907
+ run_id: credential.implementation_run_id,
58908
+ tenant_id: credential.tenant_id,
58909
+ scope: credential.scope,
58910
+ expires_at: credential.expires_at,
58911
+ stored_in: store.describe()
58912
+ })}
58913
+ `
58914
+ );
58915
+ } else {
58916
+ io.stdout.write(
58917
+ `The implementation credential is stored in ${store.describe()} and expires at ${credential.expires_at}.
58918
+ `
58919
+ );
58920
+ }
58921
+ return 0;
58922
+ }
58923
+ function writeJsonStartPrompt(io, session) {
58924
+ io.stderr.write(
58925
+ [
58926
+ "To sign in, open this URL in any browser and approve the code:",
58927
+ ` ${session.verification_uri}`,
58928
+ "",
58929
+ ` Code: ${session.user_code}`,
58930
+ "",
58931
+ "Waiting for approval\u2026",
58932
+ ""
58933
+ ].join("\n")
58934
+ );
58935
+ }
58936
+ function mapApprovedToCredential(approved) {
58937
+ const raw = approved;
58938
+ const parsed = implementationCredentialSchema.safeParse({
58939
+ token: raw.token,
58940
+ token_id: raw.token_id,
58941
+ tenant_id: raw.tenant_id,
58942
+ implementation_run_id: raw.implementation_run_id,
58943
+ scope: raw.scope,
58944
+ expires_at: raw.expires_at
58945
+ });
58946
+ if (!parsed.success) {
58947
+ return null;
58948
+ }
58949
+ return parsed.data;
58950
+ }
58951
+ function createImplementationClient(deps, credential) {
58952
+ return new deps.CommandClient({
58953
+ appUrl: deps.appUrl,
58954
+ token: credential.token,
58955
+ credentialKind: "implementation_bootstrap"
58956
+ });
58957
+ }
58958
+ function isDeadRunError(error51) {
58959
+ if (!(error51 instanceof CommandClientError) || !error51.response || error51.response.ok) {
58960
+ return false;
58961
+ }
58962
+ if (error51.status === 401) {
58963
+ return true;
58964
+ }
58965
+ const code = error51.response.error.code;
58966
+ return code === "COMMAND_AUTHORIZATION" || code === "COMMAND_UNAUTHENTICATED" || /expired/i.test(error51.response.error.message);
58967
+ }
58968
+ async function runStatus(io, deps, credential, json2) {
58969
+ const client = createImplementationClient(deps, credential);
58970
+ try {
58971
+ const result = await client.execute("implementation_access.status", {});
58972
+ if (json2) {
58973
+ io.stdout.write(`${JSON.stringify(result.output)}
58974
+ `);
58975
+ } else {
58976
+ io.stdout.write(`${redactForLog(formatStatusSummary(result.output))}
58977
+ `);
58978
+ }
58979
+ return 0;
58980
+ } catch (error51) {
58981
+ if (isDeadRunError(error51)) {
58982
+ io.stderr.write(
58983
+ "The implementation run is no longer active. Start a new one: rost implementation access start\n"
58984
+ );
58985
+ return 1;
58986
+ }
58987
+ io.stderr.write(`${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
58988
+ `);
58989
+ return 1;
58990
+ }
58991
+ }
58992
+ function formatStatusSummary(output) {
58993
+ const record2 = typeof output === "object" && output !== null ? output : {};
58994
+ const status = typeof record2.status === "string" ? record2.status : "unknown";
58995
+ const runId = typeof record2.run_id === "string" ? record2.run_id : "unknown";
58996
+ return `Implementation run ${runId} status: ${status}.`;
58997
+ }
58998
+ async function runComplete(io, deps, credential, store, json2) {
58999
+ const client = createImplementationClient(deps, credential);
59000
+ try {
59001
+ const result = await client.execute("implementation_access.complete", {});
59002
+ await store.clear();
59003
+ if (json2) {
59004
+ io.stdout.write(
59005
+ `${JSON.stringify({
59006
+ status: "completed",
59007
+ run_id: credential.implementation_run_id,
59008
+ already_closed: result.output?.already_closed ?? false
59009
+ })}
59010
+ `
59011
+ );
59012
+ } else {
59013
+ io.stdout.write("Implementation run completed and the local credential was cleared.\n");
59014
+ }
59015
+ return 0;
59016
+ } catch (error51) {
59017
+ io.stderr.write(`${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
59018
+ `);
59019
+ io.stderr.write("The credential was kept. Retry with: rost implementation access complete\n");
59020
+ return 1;
59021
+ }
59022
+ }
59023
+ async function runAbandon(io, deps, credential, store, json2) {
59024
+ const client = createImplementationClient(deps, credential);
59025
+ try {
59026
+ const result = await client.execute("implementation_access.abandon", {});
59027
+ await store.clear();
59028
+ if (json2) {
59029
+ io.stdout.write(
59030
+ `${JSON.stringify({
59031
+ status: "abandoned",
59032
+ run_id: credential.implementation_run_id,
59033
+ already_closed: result.output?.already_closed ?? false
59034
+ })}
59035
+ `
59036
+ );
59037
+ } else {
59038
+ io.stdout.write("Implementation run abandoned and the local credential was cleared.\n");
59039
+ }
59040
+ return 0;
59041
+ } catch (error51) {
59042
+ io.stderr.write(`${redactForLog(error51 instanceof Error ? error51.message : String(error51))}
59043
+ `);
59044
+ io.stderr.write("The credential was kept. Retry with: rost implementation access abandon\n");
59045
+ return 1;
59046
+ }
59047
+ }
59048
+ function defaultImplementationAccessDeps(appUrl2) {
59049
+ return {
59050
+ appUrl: appUrl2,
59051
+ createImplementationStore: createImplementationCredentialStore,
59052
+ pollDeviceAuthorizationHandoff,
59053
+ CommandClient
59054
+ };
59055
+ }
59056
+
58794
59057
  // src/generator/groups.ts
58795
59058
  import { readFileSync as readFileSync2 } from "node:fs";
58796
59059
 
@@ -62676,7 +62939,7 @@ async function sweepStaleRunnerTempFiles(dir, options = {}) {
62676
62939
  // src/runner-service.ts
62677
62940
  import { execFile as execFileCallback2 } from "node:child_process";
62678
62941
  import { realpathSync as realpathSync2 } from "node:fs";
62679
- import { access, mkdir as mkdir4, readFile as readFile5, readdir as readdir2, rm as rm4, writeFile as writeFile4 } from "node:fs/promises";
62942
+ import { access, mkdir as mkdir4, readFile as readFile6, readdir as readdir2, rm as rm4, writeFile as writeFile4 } from "node:fs/promises";
62680
62943
  import { homedir as homedir4 } from "node:os";
62681
62944
  import path7 from "node:path";
62682
62945
  import { promisify as promisify2 } from "node:util";
@@ -63090,7 +63353,7 @@ async function inspectRunnerService(options) {
63090
63353
  const paths = runnerServicePaths(options.homeDir, safeName);
63091
63354
  const label = serviceLabel(safeName);
63092
63355
  const installed = await fileExists(paths.launchAgentPath);
63093
- const plist = installed ? await readFile5(paths.launchAgentPath, "utf8").catch(() => null) : null;
63356
+ const plist = installed ? await readFile6(paths.launchAgentPath, "utf8").catch(() => null) : null;
63094
63357
  const programArgs = plist ? extractProgramArguments(plist) : [];
63095
63358
  const appUrl2 = plist ? extractPlistEnvironmentValue(plist, `${cliBrand.envPrefix}_APP_URL`) : null;
63096
63359
  const urlPolicyEnv = extractPlistEnvironmentValue(plist ?? "", allowInsecureAppUrlEnv) === "1" ? "set" : "unset";
@@ -63358,7 +63621,7 @@ async function fileExists(file2) {
63358
63621
  }
63359
63622
  async function readTail(file2, maxBytes) {
63360
63623
  try {
63361
- const content = await readFile5(file2, "utf8");
63624
+ const content = await readFile6(file2, "utf8");
63362
63625
  return content.length > maxBytes ? content.slice(content.length - maxBytes) : content;
63363
63626
  } catch {
63364
63627
  return null;
@@ -63506,7 +63769,7 @@ function parseSemver2(value) {
63506
63769
  import { execFile as execFileCallback5, spawn } from "node:child_process";
63507
63770
  import { createHash as createHash4, randomUUID } from "node:crypto";
63508
63771
  import { constants as fsConstants4 } from "node:fs";
63509
- import { access as access3, chmod as chmod2, lstat as lstat2, mkdir as mkdir6, open as open2, readFile as readFile7, rename as rename2, rm as rm6, statfs, writeFile as writeFile6 } from "node:fs/promises";
63772
+ import { access as access3, chmod as chmod2, lstat as lstat2, mkdir as mkdir6, open as open2, readFile as readFile8, rename as rename2, rm as rm6, statfs, writeFile as writeFile6 } from "node:fs/promises";
63510
63773
  import { cpus, homedir as homedir5, hostname as hostname3, platform, totalmem, tmpdir as tmpdir2 } from "node:os";
63511
63774
  import path10 from "node:path";
63512
63775
  import { setTimeout as sleep3 } from "node:timers/promises";
@@ -63516,7 +63779,7 @@ import { promisify as promisify5 } from "node:util";
63516
63779
  import { execFile as execFileCallback4 } from "node:child_process";
63517
63780
  import { createHash as createHash3, randomBytes } from "node:crypto";
63518
63781
  import { constants as fsConstants3 } from "node:fs";
63519
- import { chmod, link, lstat, mkdir as mkdir5, mkdtemp, open, readdir as readdir3, readFile as readFile6, realpath, rename, rm as rm5, stat as stat4, writeFile as writeFile5 } from "node:fs/promises";
63782
+ import { chmod, link, lstat, mkdir as mkdir5, mkdtemp, open, readdir as readdir3, readFile as readFile7, realpath, rename, rm as rm5, stat as stat4, writeFile as writeFile5 } from "node:fs/promises";
63520
63783
  import os3 from "node:os";
63521
63784
  import path8 from "node:path";
63522
63785
  import { setTimeout as sleep2 } from "node:timers/promises";
@@ -63628,7 +63891,7 @@ async function provisionIsolatedClaudeConfigDir(base, configDir, onRepair) {
63628
63891
  const source = resolveSourceClaudeConfigDir(base);
63629
63892
  for (const file2 of CLAUDE_CONFIG_AUTH_FILES) {
63630
63893
  try {
63631
- const data = await readFile6(path8.join(source, file2));
63894
+ const data = await readFile7(path8.join(source, file2));
63632
63895
  await writeFileAtomicNoFollow(path8.join(configDir, file2), data, { mode: 384 });
63633
63896
  } catch {
63634
63897
  }
@@ -63831,7 +64094,7 @@ trust_level = "untrusted"
63831
64094
  await rm5(dest, { recursive: true, force: true });
63832
64095
  }
63833
64096
  const source = resolveSourceCodexHomeDir(base);
63834
- const data = await readFile6(path8.join(source, CODEX_HOME_AUTH_FILE)).catch(() => null);
64097
+ const data = await readFile7(path8.join(source, CODEX_HOME_AUTH_FILE)).catch(() => null);
63835
64098
  if (data === null) {
63836
64099
  return homeDir;
63837
64100
  }
@@ -63914,7 +64177,7 @@ async function acquireCodexHomeLock(homeDir, options = {}) {
63914
64177
  ino = String((await handle.stat()).ino);
63915
64178
  } catch (error51) {
63916
64179
  await handle.close().catch(() => void 0);
63917
- const stillOurs = await readFile6(lockPath, "utf8").then((raw) => JSON.parse(raw).nonce === nonce).catch(() => false);
64180
+ const stillOurs = await readFile7(lockPath, "utf8").then((raw) => JSON.parse(raw).nonce === nonce).catch(() => false);
63918
64181
  if (stillOurs) {
63919
64182
  await rm5(lockPath, { force: true }).catch(() => void 0);
63920
64183
  }
@@ -63957,7 +64220,7 @@ async function breakCodexHomeLock(lockPath, expected) {
63957
64220
  }
63958
64221
  let raw;
63959
64222
  try {
63960
- raw = await readFile6(lockPath, "utf8");
64223
+ raw = await readFile7(lockPath, "utf8");
63961
64224
  } catch {
63962
64225
  return;
63963
64226
  }
@@ -63974,7 +64237,7 @@ async function judgeCodexHomeLock(lockPath, staleMs) {
63974
64237
  }
63975
64238
  let raw;
63976
64239
  try {
63977
- raw = await readFile6(lockPath, "utf8");
64240
+ raw = await readFile7(lockPath, "utf8");
63978
64241
  } catch (error51) {
63979
64242
  if (error51.code === "ENOENT") {
63980
64243
  return { stale: false, identity: null };
@@ -65537,7 +65800,7 @@ async function migrateOneLegacyCodexHome(legacyHome, newHome, io) {
65537
65800
  }
65538
65801
  async function loadState(filePath, expectedTenantId) {
65539
65802
  try {
65540
- const parsed = JSON.parse(await readFile7(filePath, "utf8"));
65803
+ const parsed = JSON.parse(await readFile8(filePath, "utf8"));
65541
65804
  if (typeof parsed.runner_id === "string" && typeof parsed.runner_secret === "string") {
65542
65805
  if (expectedTenantId && parsed.tenant_id !== expectedTenantId) {
65543
65806
  return null;
@@ -67335,7 +67598,7 @@ async function reconcileOrphanedInFlightWorkOrders(deps) {
67335
67598
  const transcriptPath = await findClaudeTranscriptPath(entry.claude_config_dir, entry.claude_session_id);
67336
67599
  if (transcriptPath) {
67337
67600
  try {
67338
- const content = await readFile7(transcriptPath, "utf8");
67601
+ const content = await readFile8(transcriptPath, "utf8");
67339
67602
  verdict = classifyClaudeTranscript(content);
67340
67603
  } catch {
67341
67604
  verdict = { kind: "missing" };
@@ -67734,7 +67997,7 @@ async function main(argv = process.argv.slice(2), options = {}) {
67734
67997
  allowDevelopmentAppUrl: process.env[allowInsecureAppUrlEnv] === "1"
67735
67998
  });
67736
67999
  }
67737
- if (command === "onboard" && (args[0] === "status" || args[0] === "resume" || args[0] === "rehearse" || args[0] === "activate")) {
68000
+ if (command === "onboard" && (args[0] === "status" || args[0] === "resume" || args[0] === "rehearse" || args[0] === "activate" || args[0] === "source-ingest" || args[0] === "setup" || args[0] === "setup-status")) {
67738
68001
  let implCredential = null;
67739
68002
  try {
67740
68003
  implCredential = await createImplementationCredentialStore().read();
@@ -67745,6 +68008,7 @@ async function main(argv = process.argv.slice(2), options = {}) {
67745
68008
  let invocation;
67746
68009
  try {
67747
68010
  invocation = parseOnboardingInvocation(args);
68011
+ await resolveOnboardingInvocationFiles(invocation);
67748
68012
  } catch (error51) {
67749
68013
  if (!(error51 instanceof OnboardingUsageError)) {
67750
68014
  throw error51;
@@ -67760,15 +68024,51 @@ ${onboardingUsage()}
67760
68024
  token: implCredential.token,
67761
68025
  credentialKind: "implementation_bootstrap"
67762
68026
  });
67763
- try {
67764
- const result = await implClient.execute(invocation.commandId, invocation.body);
67765
- io.stdout.write(`${invocation.json ? JSON.stringify(result.output, null, 2) : formatOnboardingOutput(invocation.action, result.output)}
68027
+ const exit = await executeOnboardingInvocation(invocation, io, implClient, {
68028
+ onError: (error51) => isDeadRunError(error51) ? "handled" : "print"
68029
+ });
68030
+ if (exit !== "fall-through") {
68031
+ return exit;
68032
+ }
68033
+ }
68034
+ }
68035
+ if (command === "seat" && args[0] === "create-complete") {
68036
+ let implCredential = null;
68037
+ try {
68038
+ implCredential = await createImplementationCredentialStore().read();
68039
+ } catch {
68040
+ implCredential = null;
68041
+ }
68042
+ if (implCredential) {
68043
+ const CommandClientCtor2 = options.commandClient ?? CommandClient;
68044
+ const implClient = new CommandClientCtor2({
68045
+ appUrl: config2.appUrl,
68046
+ token: implCredential.token,
68047
+ credentialKind: "implementation_bootstrap"
68048
+ });
68049
+ let deadRun = false;
68050
+ const exit = await runOperation("seat", args, {
68051
+ io,
68052
+ client: implClient,
68053
+ binName: cliBrand.binName,
68054
+ run: async (wrapperClient, commandId, body, format, runOptions) => {
68055
+ try {
68056
+ const result = await wrapperClient.execute(commandId, body, runOptions ?? {});
68057
+ const rendered = format ? format(result.output) : JSON.stringify(result.output, null, 2);
68058
+ io.stdout.write(`${rendered}
67766
68059
  `);
67767
- return 0;
67768
- } catch (error51) {
67769
- if (!isDeadRunError(error51)) {
67770
- return printCommandError3(io, error51);
68060
+ return 0;
68061
+ } catch (error51) {
68062
+ if (isDeadRunError(error51)) {
68063
+ deadRun = true;
68064
+ return 1;
68065
+ }
68066
+ return printCommandError3(io, error51);
68067
+ }
67771
68068
  }
68069
+ });
68070
+ if (!deadRun) {
68071
+ return exit;
67772
68072
  }
67773
68073
  }
67774
68074
  }
@@ -68268,6 +68568,10 @@ function printUsage(io) {
68268
68568
  `${cliBrand.binName} onboard status`,
68269
68569
  `${cliBrand.binName} onboard resume`,
68270
68570
  `${cliBrand.binName} onboard run`,
68571
+ `${cliBrand.binName} onboard source-ingest --file <path> --source-key <key> --kind <kind> --title <title> [--json]`,
68572
+ `${cliBrand.binName} onboard setup --input '<json-plan>' | --input-file <path> [--json]`,
68573
+ `${cliBrand.binName} onboard setup-status --input '<json-plan>' | --input-file <path> [--json]`,
68574
+ `${cliBrand.binName} onboard rehearse|activate --setup-application-id <uuid> ... [--json]`,
68271
68575
  `${cliBrand.binName} mcp install --client claude-code|codex|cursor --scope tenant-admin|seat [--seat-id <id>] [--expires-in <days>|--no-expiry]`,
68272
68576
  `${cliBrand.binName} mcp install --client claude-code|codex|cursor --rotate <old-token-id> (inherits the old token's scope; no --scope)`,
68273
68577
  `${cliBrand.binName} implementation access start|status|complete|abandon [--json]`,