npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@runalabs/rill-cli

v0.1.13

Published

Record, inspect, and share agent-controlled browser runs with Rill.

Readme

@runalabs/rill-cli

Record a browser flow, keep its video and runtime evidence together, and return an inspectable share link. Use Rill to reproduce a bug, verify a change, or hand a browser run to another developer or agent.

Rill starts a local Chromium recorder. Your browser tool drives the returned CDP endpoint; Rill captures the selected page and uploads the result when you stop.

Getting started · Website CLI reference · Agent instructions

Cloud agent runs

Invited workspaces can supply a URL and prompt. Cloud runs need Node.js 22+ and a Rill login; Chrome and ffmpeg run on Rill's server.

rill record https://example.com -p "Open pricing and describe the plans."
rill record https://example.com/dashboard -p "Describe the dashboard." --account staging
rill run status <run-id>
rill run cancel <run-id>

The first run opens Rill authorization if needed. Save optional website test accounts in Rill Settings using an account name, exact HTTPS origin, username, password, and optional login URL. Login appears in the private video, with masked password inputs; login diagnostics are omitted. MFA, CAPTCHA, external SSO, and unsupported login forms return a blocker.

Cloud recordings are private by default. Closing the terminal disconnects without cancelling. Use --no-wait to return after submission, and --id <same-run-id> with identical arguments to retry an uncertain submission. Cloud runs use run credits: Free includes 3 per calendar month and Pro includes 20. Buy additional credits from Billing.

The following local-recording instructions remain available through record start and record stop.

Install and verify

Browser recording runs on macOS and Linux. Install Node.js 22+ and Google Chrome or Chromium. Rill encodes recordings remotely by default; local FFmpeg is optional. Chrome stays on your machine and can access localhost. Raw frames upload after recording stops.

Then install the scoped package:

npm install --global @runalabs/rill-cli
rill --version
rill login
rill doctor

Do not use npx rill: the unscoped package belongs to a different product. Doctor checks Node, API reachability, CLI compatibility, authentication, Chrome, and remote encoding availability. Resolve failed checks before starting a run.

Authenticate

Connect with pollable approval

rill whoami verifies the current account without starting sign-in. rill connect --email [email protected] waits for human approval by default. For agents that cannot hold a foreground command open:

rill connect --email [email protected] --no-wait
rill connect status <authorization-id>

The first response contains authorizationId, verificationUri, userCode, expiresAt, retryAfterSeconds, and the exact nextCommand. The human opens the URL and approves their own request. Poll no faster than retryAfterSeconds; each status command returns once. States are pending, authenticated (approved and credentials saved), expired, or denied (including revoked claims). Expired and denied status commands exit 1. Pending state and polling backoff survive process exit in the OS credential store; claim/access tokens are never returned. Repeating connect with the same email resumes an unexpired pending request. Only the latest authorization ID for that API URL can be polled.

Interactive login

rill login prints a verification URL and device code. Open the URL, sign in, and approve the request. The CLI waits for approval and stores the credential in macOS Keychain or Linux Secret Service using secret-tool. Linux needs an available Secret Service keyring; use token authentication on headless machines without one.

CI and unattended agents

Create a scoped, expiring agent credential in Rill Settings. Inject it as RILL_TOKEN through your environment's secret manager, then run rill doctor. This token takes precedence over the OS keychain. Do not put real tokens in source files or command examples.

The default API is https://userill.dev. RILL_API_URL changes it; the global --api-url <url> flag takes precedence. Login stores credentials per API URL. Manage and revoke credentials in Settings.

First recording

rill record start --url https://example.com --title "Checkout verification"
# Save recordingId and connect your browser tool to the returned cdpUrl.
# Perform the flow in the existing recorded page.
rill record stop <recording-id>
rill inspect https://userill.dev/s/<share-secret>

Start returns recordingId, cdpUrl, status, bodyCaptureEnabled, and maxDurationSeconds. Stop finalizes capture, uploads frames and diagnostics for remote encoding, and waits for playback. Confirm status: "ready" and a non-null shareUrl before returning the evidence link. Local capture finishing does not establish remote readiness.

New browser recordings include a visible cursor and click pulses by default. In Rill Settings → Cursor appearance, workspace members can turn them off or choose an accent color. The CLI reads this preference when starting a recording; it is baked into the video and does not change existing recordings. Use an updated CLI and recorder daemon to capture the overlay.

Connect Playwright

Start also returns browserAttachment with the CDP endpoint, protocol, Playwright method, and attachment instructions. Browser tools must explicitly support attaching to that endpoint; Rill does not automatically expose its browser to every tool.

In a project with playwright-core installed, save this as rill-run.mjs:

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();
}

Run node rill-run.mjs "<cdpUrl>" with the exact endpoint from start. Then run rill record stop <recording-id>, including when your verification fails. A page title alone does not verify your app's behavior.

For a shell-only macOS/Linux agent with no project Playwright dependency, use a temporary directory. This installs the automation client without changing the project's manifest or launching another browser:

rill_automation_dir=$(mktemp -d)
npm install --prefix "$rill_automation_dir" --no-save --package-lock=false playwright-core
cat > "$rill_automation_dir/run.mjs" <<'JS'
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 the agreed interactions and assertions on this page.
  console.log(await page.title());
} finally {
  await browser.close(); // Disconnect this CDP client; preserve the recorded browser.
}
JS
node "$rill_automation_dir/run.mjs" "<cdpUrl>"
rill record stop <recording-id> --no-wait
rill record status <recording-id>

Replace the placeholders with start's actual values. This snippet verifies attachment only until you add your flow assertions. Keep the directory for retries and remove it when finished. Playwright documents the connected-browser disconnect behavior.

Capture follows the first page selected at recording start. Keep the flow in that page: new tabs and popups do not receive complete video and diagnostic coverage. Keep the recorded page open until Rill stops.

Recording options

| Option | Behavior | | --- | --- | | --url <url> | Open the target in a managed browser. | | --encoding remote / --encoding local | Remote is the default; local requires FFmpeg. | | --title <title> | Name the run; defaults to a timestamped title. | | --description <text> | Describe what the run demonstrates. | | --headed | Show the managed browser; default is headless. | | --cdp-url <url> | Attach to an existing Chromium browser and record its first open page. Navigate that page with your browser tool. | | --width <pixels> / --height <pixels> | Managed viewport; defaults to 1280 × 720. | | --max-duration <seconds> | Automatically finalize local capture; defaults to 600. Still call record stop to upload. |

Rill closes browsers it launches during finalization. Attached browsers remain open.

Set up a coding agent

Install and authenticate the CLI where the agent runs. No separate skill installation is required. Optionally save the following workflow in your agent's project instructions or skill setup; it is also available in the public agent instructions:

  1. Run rill doctor and resolve failed checks.
  2. Start a run titled with the claim to verify.
  3. Preserve recordingId; connect to cdpUrl using a browser tool that supports CDP.
  4. Perform the authorized flow in the existing recorded page.
  5. Stop the same recording and wait for readiness.
  6. Inspect the returned share URL.
  7. Return the link with what passed, failed, or could not be verified.

For a bug fix, record the reproduction and verification as separate runs. Attach the ready link to the handoff or pull request.

Inspect a shared run

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

Inspect returns bounded JSON context for another agent without requiring login. Browser recordings carry video and synchronized console messages, exceptions, network metadata, navigation, and interaction events. Treat this as bounded evidence, not a guarantee of complete capture. Use the share page to watch the run and examine its diagnostics.

An active share URL is required. Expired, replaced, revoked, or deleted shares cannot be inspected; ask the owner for a current link.

Upload an existing video

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

Upload WebM or MP4 evidence. The command waits for readiness and returns the recording ID and share URL. Existing uploads report diagnosticsAvailable: false; they do not import Playwright traces or reconstruct diagnostic events.

Both upload and record stop accept --no-wait. This waits for upload acceptance, then returns while processing continues. Remote recordings may report queued or encoding before processing and ready. Use rill record status <recording-id> to retrieve progress and the eventual share link.

Command reference

Use rill --help or <command> --help for supported flags.

| Command | Behavior | | --- | --- | | rill login | Authorize a device code and store a credential. | | rill whoami | Verify the saved identity and account email. | | rill connect --email <email> [--no-wait] | Start or resume account approval. | | rill connect status <authorization-id> | Poll a saved approval once; obey retryAfterSeconds. | | rill doctor | Check prerequisites, API compatibility, and authentication. | | rill record start [options] | Start a managed or attached browser recording. | | rill record stop <recording-id> | Finalize and upload; supports --no-wait and --no-feedback. | | rill record status <recording-id> | Read remote state first, then local capture for unsubmitted recordings; local completion is captured. | | rill record retry <recording-id> | Resume a retained remote capture or retry a failed encode; supports --no-wait. | | rill record cancel <recording-id> | Abandon a run created 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 without login. | | rill drafts list | List directory names under the local draft root. | | rill drafts purge | Delete draft directories last modified more than 24 hours ago. | | rill feedback submit <recording-id> | Submit optional Rill-specific feedback. |

Output and errors

Data commands emit JSON on stdout and human progress on stderr. Use global --pretty for indented JSON. Help and version commands print plain text.

rill --pretty record status <recording-id>

Selected fields from a successful stop result:

{
  "schemaVersion": 1,
  "recordingId": "<recording-id>",
  "status": "ready",
  "shareUrl": "https://userill.dev/s/<share-secret>"
}

Stop also returns duration, stop reason, diagnostic summary, and feedback instructions when applicable.

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

Check the exit status first, then structured fields. Known codes include authentication_required, scope_denied, quota_exceeded, browser_unavailable, recording_not_found, upload_interrupted, processing_failed, share_revoked, validation_failed, and the fallback internal_error. Not every failure has a specific code; avoid branching on message text.

Lifecycle recovery also distinguishes unsupported_platform, processing_pending, authorization_not_found, expired_token, and access_denied. An elapsed playback wait is pending, while a confirmed remote failure remains processing_failed.

Recovery and troubleshooting

  • Doctor fails: read the failed check's recovery field. Correct the credential, API connectivity, or executable path before recording.
  • Quota exceeded: inspect error.details.quota.type and blockingRecordingId when present. Uploading and processing recordings still hold the concurrency slot. Run the returned status command and wait for ready; if it reports captured, run its stop command to upload. Cancel only an abandoned run. Review storage and daily allowance in Billing.
  • Remote upload interrupted or encoding failed: keep the recording ID and local capture files. Run rill record status <recording-id>, then rill record retry <recording-id> with the original credential before capture expiry. Retry resumes accepted chunks or requeues the encode without repeating browser actions. A ready result needs a share URL before you return it as evidence.
  • Duration limit reached: local capture finalizes automatically. Status reports captured, source: "local", and the exact nextCommand to upload. It is not a playable share. Run record stop <recording-id> --no-wait, then poll status.
  • Upload reached 100%: transfer has finished; encoding/playback processing may continue. --no-wait returns after submission with a status command. A polling timeout reports processing_pending, not a confirmed processing failure.
  • Windows: doctor reports recorder_transport failure, and local record start rejects before reserving a recording. Use macOS/Linux for browser recording. Windows can use RILL_TOKEN with video-only upload; setting RILL_SOCKET does not add named-pipe/TCP support.
  • Terminal closed: after upload acceptance, the server finishes independently; retrieve the result with record status. Before acceptance, retry from the original machine while its captured frames remain available.
  • Local session missing: record status checks remote encoding and recording state. Remote processing/completion takes precedence over retained local artifacts. For captures not submitted, it checks the local recorder. Remote authorization/network errors are surfaced rather than being masked by local readiness. drafts list locates local directories, which may be incomplete. There is no drafts resume command.
  • Share cannot be inspected: open the complete URL in a browser; ask the owner for a current link if needed.

A failed local startup automatically attempts to cancel the remote reservation it just created. record cancel changes remote state and does not stop the local browser; finish local capture before abandoning the remote reservation.

For --encoding local, when finalized artifacts survive, retain recording.webm and diagnostics-v1.ndjson.gz in the recording's draft directory. rill upload <path-to-recording.webm> is a video-only fallback: it creates a new recording and does not restore the original diagnostics. Successful stop with readiness removes that run's local artifact directory.

drafts purge deletes local draft directories older than 24 hours by modification time, without a confirmation prompt. Recover needed evidence before purging.

Environment variables

| Variable | Purpose | | --- | --- | | RILL_TOKEN | Agent credential; overrides the keychain. | | RILL_API_URL | API origin; defaults to https://userill.dev. Global --api-url takes precedence. | | RILL_CHROME_PATH | Chrome or Chromium executable path. | | RILL_FFMPEG | FFmpeg executable for --encoding local; defaults to ffmpeg on PATH. | | RILL_HOME | Recorder state directory; defaults to ~/.rill. | | RILL_SOCKET | Recorder socket; defaults to recorder.sock inside RILL_HOME. | | RILL_TEMP | Artifact root; defaults to rill-recordings inside the system temporary directory. |

Set recorder variables before starting the background recorder; an existing recorder retains its original environment. Use the same configuration for recording, stopping, and draft recovery.

Sharing and privacy

Ready recordings get an unlisted share link that expires after seven days. In the recording page, copy it, replace it with a fresh link, or stop sharing. Finished recordings can be deleted after a five-second undo window.

Diagnostic redaction targets cookies, credential headers, URL query values, fragments, embedded credentials, and secret-shaped values. Network-body capture defaults off and is controlled by the human-issued credential; the agent cannot enable it for itself. Redaction is best-effort and does not mask the video. Avoid displaying secrets, review evidence before sharing, and treat share URLs as sensitive.

Optional agent feedback

Feedback begins with rill doctor and rill record start. When the workspace enables it, their JSON includes feedbackRequested: true and a feedbackBrief asking the agent to observe what went well, confusion or friction, and possible improvements throughout setup and the run. Review only Rill and report observed experience, not invented praise or issues.

At completion or abandonment, record stop still returns the recommended, pre-authorized suggestedAction. Submit a short review if practical:

rill feedback submit <recording-id> --outcome succeeded --helped "The CDP URL was easy to connect to" --friction "Upload progress was unclear" --improvement "Explain upload and processing stages"

Startup errors retain the brief under error.details, with the recording ID when one was reserved. If no recording exists, submit setup feedback without an ID using --outcome failed or --outcome abandoned. Successful submission returns feedbackStatus: "submitted" and the recording ID (null for setup-only feedback).

Only use --no-feedback when the user explicitly requests it, including in demos and tests. Respect the workspace preference. Feedback is optional, pre-authorized, and must not delay or affect the recording result. Authentication or connectivity failures may prevent feedback; preserve the original task result.

Setup-only feedback requires the API endpoint POST /api/feedback and migration 0012_setup_feedback.sql. Deploy the migration and API before distributing this CLI change. Existing recording feedback remains compatible.

Update and uninstall

npm install --global @runalabs/rill-cli@latest
rill --version
rill doctor

Remove the package:

npm uninstall --global @runalabs/rill-cli

This leaves keychain credentials, recorder state, local drafts, and remote recordings in place. Revoke the credential in Settings if access should end, and remove RILL_TOKEN from the environment or secret manager. To remove a stored local credential for the default API:

# macOS
security delete-generic-password -a https://userill.dev -s rill
# Linux
secret-tool clear service rill api-url https://userill.dev

Substitute your API URL if you configured another environment. These commands clear the local credential; server-side revocation is managed in Settings.

Cloud run output

rill record <url> -p "<prompt>" prints the outcome, summary, and recording URL. Use --json for a machine-readable result (--pretty also enables JSON formatting). Provider token usage is retained internally and omitted from customer output. rill run status <run-id> and rill run cancel <run-id> support the same output options.

Remote encoding

Since 0.1.10, record start uses remote encoding by default. Chrome stays local, including access to localhost; FFmpeg is required only for record start --encoding local. For local encoding, install FFmpeg with brew install ffmpeg on macOS or sudo apt install ffmpeg on Debian/Ubuntu, then run doctor --encoding local. Remote encoding adds no charge and consumes no cloud-run credits; existing recording allowances still apply. Captures are limited to ten minutes and 1 GiB of raw frames, with three pending jobs per workspace. Busy recordings can reach the byte limit sooner.

record stop uploads frames and waits for playback. record stop ID --no-wait returns after upload acceptance; processing continues if the terminal closes. Use record status ID to retrieve progress and the share link, or record retry ID to resume an interrupted upload or retry encoding without repeating browser actions. Raw captures are removed after successful publication. Recoverable captures expire after 24 hours: local retention starts at capture start, server retention at upload initialization. Keep the original credential and local files until upload acceptance; expiresAt reports the server deadline once a job exists.

rill record stop <recording-id> --no-wait
rill record status <recording-id>
# If upload or encoding failed, retry the same recording:
rill record retry <recording-id>

Progress runs through uploading → queued → encoding → processing → ready. Waiting for capacity is normal; do not repeat the browser journey merely because a job is queued. Long or busy recordings can take several minutes to upload and encode.

Anonymous local recordings and account connection

rill record start can begin without sign-in when the server supports anonymous access. The CLI stores the identity in the OS credential store and uses local encoding. Anonymous access includes three successful recordings, at most five minutes and 250 MB each; each recording and its unlisted share link expires seven days after creation. Failed uploads do not consume the successful-recording allowance. Source and service rate limits also apply.

Run rill connect --email [email protected] to authorize account access or keep your anonymous recordings. Open the displayed link, sign in, and enter the code yourself. Approval allows creation and reading of your existing and new recordings for 90 days, with automatic renewal of one-hour access tokens. Revoke the connection in Rill's Credentials page to stop access and renewal. Deletion and changes to existing sharing settings are not included.

Use rill record list to list accessible recordings and rill inspect <recording-id> for private recording details. rill inspect <share-url> continues to work without account access. The existing rill login and RILL_TOKEN flows remain supported. Local credential storage requires macOS Keychain or Linux Secret Service.

Check the connected account

Run rill whoami (or rill --pretty whoami) to verify your current identity. JSON output includes status, account email when available, workspace, scopes, and access expiry. It uses RILL_TOKEN when set, otherwise the saved OS credential. Existing access can renew automatically; it never creates an identity or opens an approval flow. Missing credentials return not_connected and exit 1. Invalid or revoked credentials return an error.