Rill

CLI reference

Record browser work from your terminal.

Use the CLI to record a supported browser your agent controls, or submit a browser task for Rill to run in the cloud. Review the recording and captured diagnostics before sharing.

CLI0.1.21APIv1

What you can do

Make a browser run inspectable.

Record a bug reproduction, verify a fix, or hand a browser test to another person with the evidence attached. Rill runs a local Chromium recorder and gives your browser automation a CDP endpoint to control.

Reproduce a bug

Capture the steps, console errors, and failed requests together. Share the run so the next developer can see where it broke.

Verify a change

Drive the changed flow in Rill’s browser, stop the recording, and attach the ready link to your pull request.

Hand off to an agent

Give an agent the share URL and the task. rill inspect returns bounded JSON context without a Rill login.

Share an existing video

Upload an MP4 or WebM from a test run. Existing videos are shared as video-only evidence.

Cloud recording

Give Rill a URL and a task.

Use the homepage form without installing anything, or run the command below with Node.js 22 or newer. Cloud recording does not need local Chrome, ffmpeg, or an AI API key. The CLI opens sign-in the first time.

npx @runalabs/rill-cli record https://example.com -p "Explore the pricing page"

The command waits for the result by default. Add --no-wait to return after submission, then use rill run status <run-id>. Use rill run cancel <run-id> to cancel. Retry a submission with the same --id <uuid> and task to avoid creating another run.

Cloud recordings are private to your workspace. Create a share link separately if you want others to view the recording.

Websites that require login

Save a website test account in Rill Settings, then add --account <name>. Its HTTPS origin must match the target website. Website login is separate from signing into Rill. CAPTCHA, MFA, and external SSO are unsupported; login steps appear in the video.

For localhost or private networks, use the local recording workflow below.

Quick start

Install, authenticate, verify.

Browser recording runs on macOS, Linux, and Windows. Install Node.js 22 or newer and Google Chrome or Chromium. Since CLI 0.1.10, remote encoding is the default and requires no local FFmpeg. Chrome stays local, including access to localhost; raw frames upload after stop. For optional local encoding, install FFmpeg and use record start --encoding local and doctor --encoding local.

Before installing, run node -p "process.platform" and rill --version in the environment your agent actually uses. Reuse an installed compatible CLI. If it is missing, check npm with npm ping --fetch-timeout=5000 --fetch-retries=0. A sandbox can have different network and browser access from your desktop. Follow the skill’s pre-install checks for bounded connectivity checks and the Windows Terminal fallback. Doctor checks prerequisites; your agent must separately establish that it can attach over CDP.

npm install --global @runalabs/rill-clirill --versionrill loginrill doctor

Authenticate

Authorize a browser agent.

Interactive login

Run rill whoami for a short account summary, or rill whoami --json for agent-readable identity fields, including the verified email, workspace, scopes, and expiry. It reports connected, anonymous, or missing access without starting sign-in. Missing credentials still exit with status 1.

For renewable local-agent access, use rill connect --email you@example.com; this also claims unexpired anonymous recordings. See anonymous limits and connection permissions. Legacy device login remains available for existing workflows: run rill login, open the verification URL printed in your terminal, and enter the device code. Sign in and approve the request in your browser. The CLI waits for approval, then stores the credential in macOS Keychain, Linux Secret Service via secret-tool, or Windows current-user DPAPI.

On Linux, browser login needs secret-tool and an available Secret Service keyring. Use a token in headless environments without a keyring.

Unattended runs and CI

Create a scoped, expiring agent credential in Rill Settings and inject it as RILL_TOKEN through your environment’s secret manager. It takes precedence over the keychain credential. Run rill doctor in that environment to check API reachability, credential validity, CLI compatibility, Chrome, and remote encoding availability.

Agent credentials carry their own scopes and network-body capture policy. Manage and revoke them in Settings. The CLI defaults to https://userill.dev; credentials stored by login are associated with the selected API URL.

Set up your agent

Teach it the recording loop.

Use the agent quickstart to install the project skill and make a first recording without signing in. See /docs/agent-quickstart and /docs/install-skill. The commands below are also available directly.

Use Rill to record the browser flow you are verifying.
1. Run rill doctor and resolve failed checks.
2. Start with rill record start --url <target-url> --title "<claim to verify>".
3. Save recordingId and connect your browser tool to the returned cdpUrl.
4. Perform the authorized flow in the existing recorded page.
5. Run rill record stop <recording-id> to upload and wait for readiness.
6. Confirm status is ready and shareUrl is non-null, then inspect the link.
7. Return the share URL with what passed, failed, or could not be verified.

The browser tool must support connecting to an existing Chromium browser over CDP. Keep the recorded page open until Rill stops. For a bug fix, record the reproduction and verification as separate runs with clear titles.

Record a run

Start, connect, work, stop.

rill record start --url <target-url> --title "Agent reproduction"# connect your browser agent to the returned cdpUrlrill record stop <recording-id>
10 mindefault maximum
1280×720default viewport
JSONmachine-readable output

The start response contains a recordingId and cdpUrl. Preserve both. After the agent finishes, stop the same recording; Rill uploads frames and diagnostics, encodes remotely, and waits for a playable share URL. Success means status: "ready" with a non-null shareUrl. A locally finalized video alone is not a ready share.

Choose an existing Chromium tab

Your browser must already expose a CDP endpoint. List its pages, choose the intended tab ID, and start recording that page. Ambiguous or stale selections fail instead of silently choosing another page. Only the selected page and its navigations are recorded; stopping preserves its browser, other tabs, and cookies.

rill record tabs --cdp-url <endpoint>
rill record start --cdp-url <endpoint> --tab-id <tab-id> --title "Selected browser flow"

Use the returned tabId to identify the recorded target. If an older running recorder cannot honor selection, finish its active recordings and restart it before attaching.

Remote encoding

Keep Chrome local. Encode with Rill.

Remote encoding adds no fee or cloud-run credit usage; existing recording allowances apply. Recordings support up to ten minutes and 1 GiB of raw frames, with three pending jobs per workspace. Busy recordings may reach the byte limit sooner.

record stop ID --no-wait returns after upload acceptance. Processing continues if the terminal closes. Use record status ID for progress and the share link, or record retry ID to resume retained captures without repeating browser actions. Raw captures are deleted after publication or expire after 24 hours. Local retention starts at capture start; server retention starts at upload initialization. The job’s expiresAt reports the server deadline.

rill record stop <recording-id> --no-wait
rill record status <recording-id>
# Retry after an upload or encoding failure:
rill record retry <recording-id>

Progress moves through uploading, queued, encoding, processing, and ready. Long recordings can take several minutes to upload and encode. A queued job is waiting for capacity; it does not need a new browser run.

After upload acceptance, the server finishes independently. If the terminal closes before acceptance, retry from the original machine using the same credential and retained capture files.

Browser automation example

Connect Playwright to the recorded page.

In a project with playwright-core installed, save this as rill-run.mjs. Start the recording above, then run node rill-run.mjs "<cdpUrl>" using the exact URL from its JSON response. Run rill record stop after the script finishes, including when verification fails.

import { chromium } from 'playwright-core';

const browser = await chromium.connectOverCDP(process.argv[2]);
try {
  const page = browser.contexts()[0].pages()[0];
  if (!page) throw new Error('The recorded page is unavailable.');
  await page.waitForLoadState('domcontentloaded');
  // Add your flow and assertions here, using this page.
  console.log(await page.title());
} finally {
  // Disconnect this client; let rill record stop finalize the recording.
  await browser.close();
}

Capture follows the first page selected when recording starts. Keep verification in that page; new tabs and popups do not receive complete video and diagnostic coverage. A page title alone is not a verification of your app’s behavior.

Start optionBehavior
--url <url>Open the target URL in a managed browser.
--encoding remote | localRemote is the default. Local requires FFmpeg on your machine.
--title <title> / --description <text>Describe the run. A timestamped title is generated when omitted.
--headedShow the managed browser window. The default is headless.
--cdp-url <url>Attach to an existing Chromium browser; its first open page is recorded. Navigate that page with your browser tool.
--width <pixels> / --height <pixels>Managed browser viewport; defaults to 1280 × 720.
--max-duration <seconds>Automatically finalize local capture after this duration; defaults to 600. Still run record stop to upload.

Rill closes browsers it launches when finalizing. An attached browser remains open.

Upload a video

Bring an existing test artifact.

rill upload ./test-results/checkout.webm --title "Checkout test"

Upload an existing WebM or MP4. The command waits for readiness and returns the recording ID and share URL. The result reports diagnosticsAvailable: false: upload does not import Playwright traces or reconstruct console and network events.

Both upload and record stop accept --no-wait. Upload still completes, then remote recordings may be queued or encoding before playback is ready. Use record status ID to retrieve the eventual share link.

Command reference

Find the command you need.

Run rill --help or add --help to a subcommand for its supported arguments and flags.

CommandBehavior
rill connect --email you@example.comConnect and claim anonymous recordings with renewable read/create access.
rill whoamiVerify the current account, anonymous access, workspace, scopes, and expiry without starting sign-in.
rill loginApprove a device code and store an agent credential.
rill doctorCheck prerequisites, API compatibility, and authentication.
rill record tabs --cdp-url <endpoint>List existing Chromium page target IDs without Rill authentication.
rill record start [options]Start a managed or attached browser recording; return recordingId, cdpUrl, remainingSeconds and, when attached, tabId. Supports --tab-id with --cdp-url.
rill record stop <recording-id>Finalize, upload frames and diagnostics, and wait for readiness. Supports --no-wait and --no-feedback.
rill record status <recording-id>Read the remote encoding job first; otherwise check local capture state with a remote fallback.
rill record retry <recording-id>Resume retained frame uploads or retry a failed encode with the original credential. Supports --no-wait.
rill record cancel <recording-id>Abandon a recording owned by this credential and release its remote quota reservation.
rill upload <video-file>Upload video-only evidence. Supports --title and --no-wait.
rill inspect <share-url>Read bounded context from an active share URL, without login.
rill drafts listList directory names under the local draft root.
rill drafts purgeDelete draft directories whose modification time is older than 24 hours.
rill feedback submit <recording-id>Send optional Rill feedback; requires --outcome and at least one text answer.

Output and errors

Use JSON in scripts and agents.

whoami shows a short human summary by default; agents should request rill whoami --json. Doctor and local recording commands retain JSON by default. Use --human for readable doctor, login, recording start/stop/status/retry summaries and recovery guidance. Explicit --json or --pretty takes precedence; --pretty indents JSON. Human errors go to stderr and structured errors remain on stdout. Terminal color is optional and respects NO_COLOR. Workspace feedback and browser attachment metadata remain available in JSON. Help and version commands print plain text.

rill whoamirill whoami --jsonrill --human doctorrill --human record status <recording-id>
rill --pretty record status <recording-id>rill inspect https://userill.dev/s/<share-secret> > context.json
{
  "schemaVersion": 1,
  "recordingId": "<recording-id>",
  "status": "ready",
  "shareUrl": "https://userill.dev/s/<share-secret>"
}

This example shows selected fields. Stop also returns duration, stop reason, diagnostic summary, and feedback instructions when applicable.

Success exits 0. Command failures exit 1; runtime failures return an error object on stdout with code, message, and optional recovery and details. Argument parsing errors may print plain text to stderr. Doctor exits 1 with its JSON check report when a check fails.

Check the exit status first, then inspect structured fields. Useful error codes include authentication_required, scope_denied, quota_exceeded, browser_unavailable, local_capture_failed, processing_failed, and internal_error.

Environment variables

Configure the CLI and recorder.

VariablePurpose
RILL_TOKENAgent credential. Overrides the OS keychain; supply through a secret manager.
RILL_API_URLAPI origin. Defaults to https://userill.dev; global --api-url overrides it.
RILL_CHROME_PATHPath to the Chrome or Chromium executable.
RILL_FFMPEGFFmpeg executable for --encoding local; defaults to ffmpeg on PATH.
RILL_HOMERecorder state directory; defaults to ~/.rill.
RILL_SOCKETRecorder socket path; defaults to recorder.sock inside RILL_HOME.
RILL_TEMPRecording artifact root; defaults to rill-recordings inside the system temporary directory.

Set recorder variables before starting the background recorder. An already running recorder retains the environment it started with. Keep the same configuration when recording, stopping, and recovering drafts.

Recover a run

Interrupted does not mean lost.

If local capture fails before producing an uploadable artifact, stop attempts to release its unused server reservation. A subsequent start can recover a confirmed blocking local failure and retry creation once. The local_capture_failed error reports reservationReleased. Active or unknown local state, retained uploadable captures, and server encoding jobs are preserved; follow the returned recovery guidance when automatic cleanup cannot complete.

Frame uploads use at most three concurrent parts. Progress counts acknowledged bytes; after interruption, retry uploads only missing parts and retains the original capture.

rill record status <recording-id>

Checks remote encoding first, then remote recording state. Remote processing or completion takes precedence over retained local files. For a capture awaiting upload, checks the local recorder; local completion is reported as captured, not ready.

rill record retry <recording-id>

Resumes retained captures without repeating browser actions. Use the original credential before expiry.

rill record cancel <recording-id>

Releases an abandoned run and its quota slot.

rill drafts list

Lists local draft directory names; some may be incomplete.

rill drafts purge

Deletes draft directories last modified more than 24 hours ago. Check them before purging.

Troubleshooting

Keep the recording ID when something fails.

ProblemNext step
Doctor reports an errorRead the failed check and its recovery field. Fix authentication, API connectivity, or missing executables before recording.
quota_exceededRead error.details.quota.type and blockingRecordingId when present. Cancel only an abandoned recording; check Billing for storage and daily limits.
Upload interrupted or processing timed outKeep the recording ID and local artifacts. Run record status: it checks remote encoding and recording state before local capture. If it reports captured, follow the returned stop command to upload. Only ready confirms playback is available; review the recording before sharing.
Browser reached the duration limitLocal capture finalizes automatically. Run record stop with the same ID to upload the result.
Local recorder or session is missingRun record status to check remote progress even when the local session is missing. Remote authorization or network errors are reported, not hidden by local state. drafts list can locate retained artifacts, but there is no drafts resume command.
Share link cannot be inspectedOpen the complete link in a browser. Ask the owner for a current link if it expired, was replaced, or was revoked.

When finalized artifacts survive, retain both recording.webm and diagnostics-v1.ndjson.gz in the recording’s draft directory. As a video-only fallback, use rill upload on the WebM; this creates a new recording and does not restore the original diagnostics.

record cancel changes remote state; it does not stop the local browser. Finish local capture before abandoning its remote reservation. Purging drafts deletes local files immediately, so recover needed evidence first.

60-second inspection

Give the next agent facts, not a retelling.

rill inspect https://userill.dev/s/<share-secret>
  1. 1

    Copy the unlisted Rill share URL from the handoff.

  2. 2

    Run rill inspect with the complete share URL.

  3. 3

    Give the bounded JSON context to the next agent alongside the task.

A ready share combines the browser video with synchronized console messages, exceptions, network metadata, navigation, and interaction events. Existing video uploads remain video-only and do not claim diagnostic coverage.

Manage evidence

Share deliberately. Delete completely.

Sharing defaults depend on how you record:

  • Anonymous local CLI recordings: receive an unlisted link when ready. The recording and link expire seven days after creation.
  • Connected-local CLI recordings: also receive an unlisted link when ready, normally valid for seven days. Account connection does not make the link private.
  • Cloud recordings: signed-in runs start private to your workspace; create a share link separately. Guest results are available in the originating browser and through a secure emailed link for seven days.

Saved screen recordings also start with workspace access. Anyone holding an active unlisted link can view the recording and included diagnostics. From the recording page, create or copy a share link, replace it with a new seven-day link, or stop sharing. Replaced, stopped, and expired links cannot be reopened. An existing private recording stays private unless you choose to share it.

Delete a finished recording from the same page. After a five-second undo window, the recording and diagnostics disappear from your workspace and active share links stop working.

10 / Unlimiteddaily recordings · Free / Pro
Keep more with Promore room for your recordings · compare plans
3 / 10active recordings · Free / Pro

Privacy boundary

Capture is constrained by the credential.

Diagnostic redaction targets cookies, credential headers, URL query values, fragments, embedded credentials, and secret-shaped values. Network-body capture is controlled by the human-issued credential and defaults off; an agent cannot enable it for itself.

Redaction is best-effort and does not mask the recorded video. Avoid displaying secrets or sensitive personal data in the browser, and review evidence before sharing.

Treat unlisted share URLs as sensitive. Share expiry, revocation, and deletion apply to both the video and its diagnostic evidence.

Optional feedback

Help improve Rill after the handoff.

When a workspace owner opts in, a stop result may include feedbackRequested: true and a structured suggestedAction. Compatible agents should submit a short Rill-specific review when practical; the workspace opt-in pre-authorizes it. Feedback is optional and must never block or delay returning the recording.

rill feedback submit <recording-id> --outcome succeeded --improvement "Make processing progress clearer"

--outcome accepts succeeded, failed, or abandoned. Include at least one of --helped, --friction, or --improvement. Keep it about Rill and omit credentials, personal data, and copied page content.

Skip feedback when it is not requested. Use rill record stop <recording-id> --no-feedback to opt out for a run. Feedback is for Rill’s operators and does not appear on the public evidence page.

Update

Keep the Rill CLI current.

Install the latest published version, then verify the update:

npm install --global @runalabs/rill-cli@latestrill --versionrill doctor

Uninstall

Remove the Rill CLI.

Uninstall the globally installed npm package:

npm uninstall --global @runalabs/rill-cli

Uninstalling the package leaves keychain credentials, recorder state, local drafts, and remote recordings in place. Revoke the agent credential in Settings if it should no longer have access, and remove any RILL_TOKEN from your environment or secret manager.

To remove the local credential for the default API, use the command for your operating system. Substitute your API URL if you configured another environment.

# macOSsecurity delete-generic-password -a https://userill.dev -s rill# Linuxsecret-tool clear service rill api-url https://userill.dev