rect.sh

CLI

Publish templates, issue rects, and drive their state from your terminal or a script.

@rectsh/cli is the terminal surface for rect.sh — the same loop agents run over MCP, speakable from any shell, script, or CI job. It covers publishing templates (reusable views), issuing rects (live instances), injecting and reading back state — and driving the view you're still developing.

npm install -g @rectsh/cli
rect login        # authorize this machine via your browser (once)

Account plumbing: rect accounts lists the teams you can publish to, rect members --account <slug> lists one team's members for shaping into Rect state, rect whoami shows who this machine is logged in as, and rect logout removes stored credentials. rect host prints the effective default host, and rect host set <url> stores a new default.

Apps — compose and run jobs

rect app publish app.json --account acme # Markdown job + ordered Screens
rect app list --account acme             # visible Apps
rect app spec <app-id>                   # instructions and pinned Screens
rect app launch <app-id> --account acme --open
rect app launch <shared-app-id> --account acme --confirm-third-party --open
rect app read <run-id>                    # job + ordered Screen handles
rect app select-screen <run-id> --screen request --expected-revision 2

An App specification may use instructionsMd directly or instructionsFile relative to the JSON file. Each ordered Screen accepts a screen slug/id plus initialViewModel; the CLI resolves and pins its stable Screen id and immutable version id during publication. See Apps and Screens for the complete format and external-agent loop.

rect app read intentionally keeps child ViewModels out of the aggregate response. Use rect read <instance-id> for the Screen you are about to work on, then rect dispatch its named actions.

rect members --account acme --json \
  | jq '{members: .members}' \
  | rect issue team-directory --account acme --state - --read-access workspace

Member output includes names, emails, roles, and profile image URLs. Prefer workspace access for Rects containing member email addresses unless broader access is explicitly intended.

Templates — publish & explore

rect publish             # build, bundle, and deploy the view in this directory
rect check               # build + actionable project audit [--json]
rect publish --issue     # publish, then issue one live instance
rect search "project planning dashboard" # find matching templates [--account <slug>] [--limit <n>] [--json]
rect list                # visible templates [--account <slug>] [--limit <n>|--all] [--cursor <cursor>] [--json]
rect spec <ref>          # one template's spec — always JSON
rect remix <ref>         # download a template's source into a new folder
  • rect publish is keyed by the project's slug (rect.json), so republishing updates the same template in place. See Compile & publish.
  • Teams: everything belongs to a team. With nothing pinned, a single team resolves itself and multiple teams are prompted for; --account <slug> targets one explicitly (rect accounts lists them). Publishing remembers the choice in rect.json.
  • <ref> is a template slug or id. Without an account pin, rect list shows visible templates from your teams first, then official and other public templates. It returns 20 by default; increase --limit or pass --all for the complete catalog. rect list --account <slug> lists only templates owned by that account. JSON output includes nextCursor, which can be passed back with --cursor to resume. Template references resolve across the visible catalog; use an id when public templates share a slug. For rect issue, --account selects the destination workspace, not the template owner.

Audit before publishing

Run rect check from a bundle-based Rect project before handing it back or publishing it:

rect check
rect check --json
rect check --no-build --dir dist

The audit checks the build, stable project slug, source and embedded specs, the required stateSchema, schema validity and example conformance, rect.agent.md, Codex/Claude Code instruction files, action metadata and handler block, example size, entry file, and the 20 MB bundle limit. Problems are written for a coding agent to act on:

WARN  Action "approve" has no inputSchema.
      How to fix: Add an inputSchema for "approve" so agents can construct
      valid arguments and the host can reject malformed input before the
      handler runs.

--json returns stable check codes, statuses, messages, and fixes. Warnings do not fail the command; errors exit non-zero.

Rects — issue & drive

rect issue <ref>                             # issue a rect from a template
rect issue <ref> --state '{"title":"A"}'     # …with an initial view model
rect issue <ref> --state input.json --open   # …from a file, then open it
rect issue <ref> --read-access anonymous --write-access owner

rect find                                    # issued rects, newest issued first
rect find --account <slug> --template <ref> --status open
rect find --sort updated                     # most recently updated first
rect find --all                              # every accessible issued rect

rect read <rect-id>                          # full state + revision — always JSON
rect patch <rect-id> '{"done":true}'         # RFC 7386 merge patch
rect patch <rect-id> --file patch.json --expected-revision 4
rect dispatch <rect-id> addTodo '{"title":"Ship it"}'  # run a named action
rect open <rect-id>                          # open in the browser
rect delete <rect-id>                        # permanently delete a Rect

rect attachment upload <rect-id> ./report.pdf  # signed upload into $attachments
rect app attachment link <run-id> <attachment-id> --screen <key>
  • read, open, patch, dispatch, and attachment mutations all follow the instance's independent read and write scopes. The CLI sends your configured login or RECT_API_TOKEN when available; protected access returns 401 when sign-in is required and 403 when that identity lacks permission.
  • Authenticated issuance defaults both scopes to workspace. Use --read-access and --write-access to choose a different audience.
  • Without an account pin, rect find searches issued Rects across every account you can access. --account <slug> narrows the results to that account. The CLI follows pagination automatically up to --limit (default 20); pass --all for every result. JSON output includes nextCursor, which can be passed back with --cursor to resume. Results default to newest issued; pass --sort updated for most recently updated.
  • When the view declares actions, prefer dispatch over patch: the view's handler runs host-side and a rule violation comes back as its code (✖ Rejected (TODOS_OPEN): …) instead of corrupted state.
  • --expected-revision gives optimistic concurrency: a stale patch fails with the current revision so you can re-read and retry.
  • --state and patches accept inline JSON, a file path, or - (stdin).
  • rect delete asks for confirmation and defaults to “No.” Scripts and other non-interactive sessions must pass --yes.

The agent loop

rect search "sales report"                 # what best fits?
rect spec <template-id>                    # what shape does it want?
rect issue <template-id> --state '{...}'   # issue + inject
# … the human works in the view …
rect read <rect-id>                        # read their edits back
rect patch <rect-id> '{"note":"reviewed"}' # respond

Use rect list when you want to browse the catalog, or when keyword-based search is unavailable or does not return a useful candidate. Without an account pin, both commands include public templates; rect list --account <slug> narrows the listing to templates owned by that account. Listing defaults to 20 results; increase --limit or pass --all to retrieve the complete catalog.

This is the same loop agents run over MCP (rect_issue / rect_patch / rect_dispatch / rect_get_result) and any program can run over the HTTP API — the CLI speaks it from any terminal or script.

Drive the view you're developing

While npm run dev is running, the @rectsh/rect/vite plugin plays the Rect host locally. The reserved id dev targets it — the CLI finds the dev server on its own (ports 5173–5180; --dev <port> for anything else):

rect spec dev                          # the spec of the view being developed
rect read dev                          # the dev store's current state
rect patch dev '{"title":"draft"}'     # applies live in the open /dev.html
rect dispatch dev stamp '{"text":"x"}' # runs src/actions.ts (hot-reloaded)

Changes land in the browser over Vite's HMR socket — no reload — and edits made in the page flow back, so rect read dev always sees the latest. It's a full rehearsal of the agent loop against your work-in-progress view, before any publish.

CI

Create an account API token in account settings and set RECT_API_TOKEN instead of rect login, then pass --account <slug> (or commit it in rect.json).

export RECT_API_TOKEN=rect_api_...
rect publish --account acme

In GitHub Actions, store the token as a repository secret and expose it only to the publish step:

- run: rect publish --account acme
  env:
    RECT_API_TOKEN: ${{ secrets.RECT_API_TOKEN }}

Host precedence is --host > RECT_HOST > rect host set <url> > https://rect.sh.

On this page