# Nibble Studio CLI

Node.js 22 or newer. No npm account or Nibble repository checkout is required.

```sh
npm install -g https://nibble.lat/cli/nibble-studio-cli-0.2.0.tgz
nibble-studio browser install
```

Run `nibble-studio login`. Your browser opens Nibble, where you sign in with your existing account and choose **Connect CLI**. The CLI receives the connection automatically and saves a session on your computer. There are no keys to create, paste or add to environment variables. Commands open login automatically when no valid local session exists. No Pro subscription is required; the account still needs publishing access from the administrator.

Sessions last 30 days and are scoped to the server origin. `nibble-studio logout` revokes this session and removes the local credential. You can also disconnect sessions in Studio's **Agent CLI** section. Removing publisher access immediately blocks connected CLIs.

For SSH/headless agents use `nibble-studio login --no-browser` and open the emitted URL in a browser on the same computer, or forward the exact loopback callback port over SSH. The callback must reach the computer running the CLI. Login expires after five minutes. Use the browser's Cancel button or Ctrl+C to cancel.

Browser login uses a one-time authorization code, SHA-256 PKCE and a random state bound to a temporary loopback server. Credentials are never passed in the browser URL or printed in command output. They are stored under `~/.config/nibble-studio/`, with private directory/file modes on POSIX and inherited user-profile permissions on Windows. `NIBBLE_STUDIO_CONFIG_DIR` overrides the directory. Keep it outside your repository and do not share it with other users. Server storage contains only session token hashes, not browser cookies or passwords. Legacy 0.1 Studio keys are no longer accepted; install 0.2 and log in.

`NIBBLE_STUDIO_URL` or `--url` changes the server (default `https://nibble.lat`). HTTP is supported only for localhost development. The CLI does not load `.env` files automatically. PowerShell example for setting the non-secret URL:

```powershell
$env:NIBBLE_STUDIO_URL='http://127.0.0.1:3000'
```

## Workflow for agents

```sh
nibble-studio login
nibble-studio whoami
nibble-studio init
# Edit Component.jsx and nibble.component.json.
nibble-studio upload nibble.component.json
nibble-studio verify my-component --out ./nibble-check
# Inspect index.html and all PNGs. Fix problems and upload with --update.
nibble-studio publish my-component --report ./nibble-check/report.json
```

Upload saves a private draft and compiles it on the server. It does not publish. Existing IDs require `--update`. Edits preserve the currently published component. Concurrent changes are rejected. `publish` requires a passing report matching the current server, component and draft revision. This is a workflow check, not a security attestation: authorized publishers also have the website's Publish button.

`verify` runs Chromium with the website's iframe sandbox and CSP. It captures 1280×800 desktop and 390×844 mobile, in dark and light themes, checks runtime/console errors, visible DOM content, horizontal overflow and broken images, and saves `report.json`, PNGs and an `index.html` inspection page. The authenticated preview is fetched by Node and replayed locally; the Studio token and session cookies never enter the browser. The temporary preview server binds only to loopback and closes after verification. It uses the compiled, saved draft, not code from a different local build.

**Passing checks do not establish that a design looks good.** The agent must open the captures and inspect alignment, colors, clipping and typography. Test important interactions. Canvas/WebGL visual correctness, animation quality, external media availability and accessibility require additional inspection. This command checks Chromium only. `--wait-ms` adjusts capture delay (default 800, range 0–10000). On Linux CI, install Chromium system dependencies with your runner's usual Playwright setup.

## Manifest

All paths are relative to the manifest. One self-contained JSX/TSX module; React and `motion/react` imports are supported. Bundle local modules/assets before uploading. Optional CSS and preview props are supported. Source limit: 250 KB; CSS: 50 KB; props: 16 KB; complete request: 400 KB.

```json
{
  "id": "my-component",
  "name": "My component",
  "description": "An interactive counter.",
  "category": "Forms",
  "exportName": "default",
  "codeFile": "Component.jsx",
  "cssFile": "styles.css",
  "props": {}
}
```

Omit `cssFile` if unused. Categories are the same as Studio: Logo, Text, Glass, Morph, Cards, Backgrounds, Inputs, Buttons, Dropdowns, Dialogs, Galleries and Forms. Set `category` to the primary type and optionally add `categories` (for example `["Glass", "Morph"]`) for additional matching types or effects. Content previews automatically grow and shrink to fit their contents, with a comfortable minimum height for small controls. Backgrounds keep their canvas presentation. The optional `previewSize` values `compact` and `regular` remain accepted for existing manifests. Empty categories are hidden from Explore. Legacy broad categories remain accepted for older manifests; update them to specific types when editing. Validation errors are returned as JSON. Use `get` to inspect an existing draft's metadata, code, publication state and revision.

## Interaction steps

```json
[
  { "action": "click", "role": "button", "name": "Count 0" },
  { "action": "expect-text", "role": "button", "value": "Count 1" }
]
```

```sh
nibble-studio verify my-component --steps steps.json --out ./nibble-check
```

Each step uses exactly one locator: `role` with optional exact accessible `name`, exact `text`, or CSS `selector`. Actions: `click`, `fill` (string `value`), `press` (key in `value`), `expect-text` (substring in `value`), `expect-visible`. Steps run in every device/theme; captures are saved before and after interaction. An assertion/interaction failure fails verification. Maximum 50 steps; each action times out after 5 seconds.

## Commands and output

`login [--no-browser]`, `logout`, `init [manifest]`, `browser install`, `whoami`, `list`, `get <id>`, `upload <manifest> [--update]`, `verify <id> [--out dir] [--steps file] [--wait-ms n]`, `publish <id> --report file`, `unpublish <id>`.

Commands emit JSON, except `--help`. Login emits its browser URL and status events as JSON on stderr while it waits; its final result is JSON on stdout and contains no credential. Errors use stderr JSON and exit 1. Failed verification emits a report on stdout and exits 1. A report never includes credentials. Use `unpublish` to remove a component from the catalog while keeping its draft. The next component does not require a website deployment.

Preview automation uses the [official Playwright browser installation](https://playwright.dev/docs/browsers) and [page API](https://playwright.dev/docs/api/class-page).
