@rosthq/cli
v0.7.183
Published
Command-line adapter for the server-side command surface.
Readme
CLI distribution package
This package ships the Node CLI adapter for the server-side command endpoint. The public npm package is @rosthq/cli; it installs the rost binary through the package bin entry.
Build
pnpm --filter cli build
node apps/cli/dist/index.js --help
pnpm --filter cli pack:dry-run
pnpm --filter cli publish:npm:dry-runpnpm --filter cli build emits dist/index.js with a Node shebang and executable mode for npm and npx. pnpm --filter cli build:binary uses bun build --compile for the no-Node release binary in dist-bin/; pkg is the documented fallback if Bun cannot compile a supported target.
Public Node install
After the company-owned npm org owns the @rost scope and this package is published publicly, these commands become the user-facing install path:
npx @rosthq/cli@latest login
npx @rosthq/cli@latest mcp install --client claude-code --scope tenant-admin
npx @rosthq/cli@latest mcp install --client codex --scope seat --seat-id <seat-id>
npm i -g @rosthq/cli
rost login
rost doctor
rost graph show
rost seat list
rost runner serve --onceNode does not have a separate registry to register with. npx and npm i -g resolve from registry.npmjs.org, so npm publish --access public is the public registration step.
Public implementation Skill (v0 preview)
The installer fetches a signed release from GitHub and turns a general-purpose agent into a mode-aware ROST implementer. Regular mode is available today.
rost skills install-implementation --client claude-code
rost skills install-implementation --client codex
rost skills install-implementation --client cursor
# Or without a prior install:
npx @rosthq/cli@latest skills install-implementation --client codexWhat the installer verifies before any file is used:
- The annotated release tag is signed against the CLI-held trust root.
- The manifest's repository owner matches the trusted source.
- The manifest checksum matches the pinned default release, when available.
- Every fetched file matches its manifest checksum.
- The release's skill protocol range is compatible with this CLI version.
v0 preview: Full Operator external-effect handoff is not yet available and activates only through live capability discovery.
Reference corpus
The CLI includes the public implementation reference corpus for local agents and operators:
rost reference list
rost reference search "agent tools"
rost reference get agent-reference-map
pnpm --filter @rosthq/cli dev -- reference get agent-reference-mapImplementation access (agent-led setup)
A local setup agent can run under a bounded, owner-approved implementation credential instead of the human operator's personal session. This is useful when an external agent (Claude Code, Codex, Cursor, or another headless shell) is driving onboarding on a separate machine.
There are two credential families:
- Human operator session — the ordinary Supabase session created by
rost loginorrost login --device. It is stored in the user credential slot (OS keychain or the owner-only file store withROST_CLI_ALLOW_FILE_TOKEN_STORE=1). An interactive human operator can approve their own confirmations in a TTY. - Implementation credential — a short-lived, run-bound
rost_impl_bearer minted only after a human owner approves the device-code flow at/auth/device. It is stored in a separate implementation-bootstrap slot (implementation-bootstrapaccount /implementation-bootstrap.json), never in the user session slot.
Start a bounded implementation run:
npx @rosthq/cli@latest implementation access start --source-client claude-code
npx @rosthq/cli@latest implementation access start --source-client codex
npx @rosthq/cli@latest implementation access start --source-client cursorCheck, complete, or abandon the run:
rost implementation access status
rost implementation access complete
rost implementation access abandonRead onboarding state and resume context:
rost onboard status
rost onboard resumeEvery tenant-scoped rost onboard verb (and rost seat create-complete) uses
an existing implementation-bootstrap credential first. An absent credential
leaves the ordinary owner-session path available; an expired, unreadable, or
refused credential stops the command without retrying under another principal.
Human decision commands are terminal in headless runs and remain available to
an explicit interactive TTY owner. This includes the registry's
human_required commands, all four credential_flow commands
(agent.configure_tools, credential.ingress, integration.connect_rest, and
tenant.anthropic_key.save), and the none-class human decisions for
escalations, onboarding path selection, task proposals, Signal readings, error
logs, and confirmation approve/reject/remint. (rost onboard run prints the
public onboarding prompt offline and needs no credential.)
Retain each allowed local business source before constructing the setup plan. The CLI reads the file and base64-encodes it client-side; the server computes the digest and canonical family manifest and rejects paths, URLs, and client-supplied digests:
rost onboard source-ingest \
--file ./org-chart.csv \
--source-key org-chart \
--kind org_chart \
--title "Org chart" \
--jsonThe JSON output contains the opaque source_upload_id and the exact
source_ref object to place in the setup plan's sources[].
Transport note: two ceilings apply, and the smaller one wins. The application
caps the command body at 1 MiB for most commands, but onboarding.source_ingest
gets a selectively raised cap (≈ 6.7 MB) sized for its base64 expansion (×4/3).
The hosting platform enforces a lower request-body ceiling in front of that —
measured at at least 4 MiB, the largest body proven to reach the function —
and rejects a larger body at the edge before the application sees it. Base64
expansion therefore puts the largest source file this command can carry at
roughly 3.1 MB, not the protocol's documented 5,000,000-byte bound. The CLI
derives its pre-check from the platform ceiling and names the exact fitting size
before sending; split or trim a larger export.
Stage the one-approval composite setup with the complete declarative plan
(--input '<json>' inline, or --input-file <path> for a large plan):
rost onboard setup --input-file ./setup-plan.json --jsonStaging succeeds with exit code 0: the server holds the one owner approval and
the CLI prints the pending confirmation id and the exact approval URL (with
--json, the full pending-confirmation object including
approveVia.webUrl). Hand the human that one URL.
Discover the setup state through the command's idempotent contract by re-submitting the identical plan:
rost onboard setup-status --input-file ./setup-plan.json --jsonAfter the owner approves, this returns the immutable applied receipt — the
application_id, receipt.receipt_revision, and receipt.digests.input are
exactly the --setup-application-id, --expected-receipt-revision, and
--expected-input-digest the rehearsal step needs. While approval is still
pending, re-submission returns the current approval card: an identical
still-valid card is reused with the same confirmation id and URL; only a
changed server-derived projection (live state moved) 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, never a mutation.
After the owner approves the atomic setup proposal, run the exact receipt-bound sandbox rehearsal:
rost onboard rehearse \
--setup-application-id <application-id> \
--expected-input-digest <digest> \
--expected-receipt-revision <revision> \
--idempotency-key <stable-key> \
--jsonThe command is ungated and run/tenant isolated. It rehearses only the agents in that setup receipt, after rechecking current Charter manifests, pinned published Skill versions/content hashes, schedules, execution lanes, and the canonical configuration digest. Success returns a complete immutable terminal batch receipt and one immutable receipt per agent, with nonzero checked counts and runtime run IDs. It never returns an approval URL, makes an agent live, arms a schedule, accesses credentials, mutates sources, sends externally, or stages a confirmation. A retry with the same key and configuration returns the same terminal evidence; changed configuration is a conflict. Keep that exact evidence for the separate activation step:
rost onboard activate \
--setup-application-id <application-id> \
--expected-input-digest <digest> \
--expected-receipt-revision <revision> \
--terminal-rehearsal-batch-receipt-id <batch-receipt-id> \
--rehearsal-runs '[{"agent_id":"<agent-id>","rehearsal_run_id":"<run-id>"}]' \
--configuration-digests '[{"agent_id":"<agent-id>","configuration_digest":"<digest>"}]' \
--idempotency-key <stable-key> \
--jsonrost onboard activate accepts only the exact all-passed terminal batch and
per-agent evidence returned by rehearsal. It stages one complete owner approval
showing every agent, Seat, Charter/configuration digest, rehearsal run, effective
lane/model, permissions, schedule, warnings, and the onboarding-completion
effect. Approval makes every receipt agent live, arms eligible schedules, and
completes onboarding in one transaction; any stale or failed agent rolls the
whole activation back. A same-key retry returns the original committed receipt.
Under a schema_version: 2 setup this step is optional. That setup already
recorded onboarding as finished when its own approval was consumed, so
onboard activate only takes live the agents the plan deliberately left in
draft — and a run that stops after setup leaves a complete, operating company
rather than an unfinished one. Under schema_version: 1 the activation is what
completes onboarding, and the paragraph above describes it exactly.
Register the same rost_impl_ bearer with an MCP client. This uses the bearer directly; there is no mcp_token.create step and no second token:
rost implementation access install-mcp --client claude-code
rost implementation access install-mcp --client codex
rost implementation access install-mcp --client cursorThe implementation credential is intentionally narrow and explicitly classified. It can run vetted reads (for example onboarding.status, graph.get, charter.get/list, compass.get_current, goal.list, agent.list_fleet, system.health), stage human-gated proposals (onboarding.setup, onboarding.activate, seat.create_complete, agent.create_custom, agent.create_from_template, compass.set, compass.approve_version, onboarding.finish, agent.run_now), execute only the receipt-bound sandbox exception onboarding.rehearse, and close its own run. seat.create_complete stages one atomic complete-Seat proposal for an owner to approve; it never makes an optional agent live. onboarding.activate stages the one post-rehearsal owner decision and cannot approve itself. agent.run_now stages one manual production run at a time, bounded to agents this same implementation run's own setup receipt created and re-checked when the approved run dispatches; it arms no schedule. The rehearsal exception grants no general agent execution authority and cannot reach unrelated agents. Everything outside the explicit class map, including other confirmation-free durable mutations and confirmation.approve, stays outside the bounded principal. The policy module is packages/commands/src/implementation-bootstrap-policy.ts and is enforced by both the runtime guard and a CI drift test.
With an implementation credential present, the CLI runs every classified command over that credential — on rost command <id> --json '<body>' and on the ergonomic verbs that resolve to a classified command (rost graph show, rost seat list, rost agent list-fleet, rost agent templates, rost goal list, rost system health, rost skills list, rost skills catalog, rost charter list, rost charter get, rost compass get-current) — even when a user session also exists. An expired, unreadable, unauthenticated, or refused implementation credential is terminal for that invocation; the CLI never silently replays the classified command as the owner. The ergonomic rost implementation access complete/abandon verbs are the one deliberate exception on an already-expired credential — see below. The complete human-only floor — human_required, credential_flow, and the explicit none-class decisions for escalations, onboarding path selection, task proposals, Signal readings, error logs, confirmation approve/reject/remint/dismiss/dismiss_stale/activation_set.list, agent_grant_intervention.resume, and coach.draft_guide — stops in a headless session while an explicit interactive TTY remains the deliberate owner path. A successful implementation_access.complete or .abandon clears the bearer and writes a local closed-run tombstone so headless bootstrap commands refuse owner fallthrough until a new implementation access start. That includes closing on an already-expired credential: rost implementation access complete/abandon now attempt a best-effort server-side close, then write the tombstone, clear the bearer, and exit 0 — a locally-expired bearer can still be live server-side because renewal extends expires_at without the CLI writing the new value back. Note that a Markdown-rendering show verb resolves to a *.show_markdown command outside the bounded surface (so rost compass show remains session-only; use rost compass get-current), and rost agent fleet-digest is likewise outside it (use rost agent list-fleet).
