rect.sh

Compile & publish

Build a view to a bundle and ship it with the rect CLI.

The Vite plugin

@rectsh/rect/vite's rect() turns a normal Vite project into a view compiler.

// vite.config.ts
import { defineConfig } from 'vite';
import { rect } from '@rectsh/rect/vite';

export default defineConfig({
  esbuild: { jsx: 'automatic', jsxImportSource: 'react' },
  plugins: [rect()],
});

No @vitejs/plugin-react is needed for a build-only view — Vite's built-in esbuild handles JSX. (Add it only if you want React Fast Refresh in the dev harness.)

At vite build the plugin:

  1. Sets base: './' so every asset URL is relative — the bundle works from whatever path the host serves it at.
  2. Injects the spec block from rect.view.json (or the spec option).
  3. Validates the output: spec present and valid, exactly one HTML entry, no unsupported URL forms (http:// or //), and under the 20 MB cap. Runtime https:// loads are governed by the host CSP/sandbox.

The output is a dist/ bundleindex.html plus an assets/ folder. Pass rect({ singleFile: true }) to inline everything into one dist/index.html instead.

The spec

// rect.view.json
{
  "name": "Note",
  "description": "Use when an agent and a person need to draft a shared note.",
  "example": { "title": "Untitled", "body": "" }
}

description is discovery guidance: keep it short and say when this Rect is the right choice. Put operating instructions in a sibling rect.agent.md:

# Shared note agent guide

Draft the note from the source material the user provides. When updating an
existing note, preserve human edits unless the user explicitly replaces them.

The Vite plugin reads rect.agent.md automatically and publishes it as the spec's agent instructions. example is the initial view model an instance starts from. Make it a realistic, complete shape — it's both the default state and the documentation an agent reads before issuing the view.

Publish with the CLI

@rectsh/cli publishes the view in the current directory in one command. A project scaffolded with npm create rect already wires it up as npm run publish.

rect login       # authorize this machine via your browser (once)
rect publish     # build, bundle, upload, and register the view
rect publish --issue  # also issue one live instance and print its URL

rect login opens your browser, you approve, and the session is stored in ~/.rect/credentials.json (and refreshed automatically). rect publish then:

  1. runs your build script (skip with --no-build),
  2. zips the dist/ bundle (--dir to change the directory),
  3. uploads and registers it.

Run rect issue <slug> when you want a live instance to open or share, or pass --issue to create one immediately after publishing.

Useful flags: --host <url> to target a different host (default https://rect.sh, or $RECT_HOST), and --name <name> to override the view name. In CI, create an account API token in account settings and set RECT_API_TOKEN instead of running rect login.

Project identity & accounts

Every publish is keyed by a slug, so republishing the same project updates its existing rect in place — its id and live instances survive, they just pick up the new build — instead of piling up duplicates. A scaffolded project pins this in a committed rect.json:

{ "slug": "sales-dashboard", "account": "acme" }
  • slug — the project's identity within an account (defaults to the package name; override with --slug). Agents see it in both search and catalog discovery results.
  • account — the team (org) slug to publish to. With nothing pinned, a single team resolves itself and multiple teams are prompted for; override per-publish with --account <slug>. Run rect accounts to list your teams.

Because rect.json is committed, your whole team publishes to the same rect and the same account.

By hand

Prefer the browser? npm run build, then upload the dist/ folder (or the single index.html) on the Views page. Both routes create the same view source.

Registering & issuing

Publishing uploads the bundle as a view source and registers it as a rect. An agent then issues instances of the rect — each with its own store and capability URL. The same bundle backs thousands of independent instances.

Once an instance is open, an agent drives it with the rect_dispatch and rect_patch MCP tools and your view updates live; the human's edits flow back the same way. That's the loop you rehearsed locally with the dev harness — now against the real host.

On this page