Documentation

Keep up with what your agents ship

Spool turns a merged pull request into a short narrated recap you watch instead of read. These docs cover the CLI behind it: point it at your running app, drive the change once, and it records, narrates, and publishes the recap.

Quick start

One prompt for your coding agent. It installs Spool, you approve a login, and it records your first spool. Change the URL to where your app runs.

Paste this into Claude Code, Codex or Cursor
Set up Spool on this machine and record my first spool.

1. Run `npm i -g @spoolkit/cli && spool init` inside my project and follow what it prints. It installs anything missing and installs the spool skill for you.
2. When it prints a login link and a code, send me both and keep waiting until it says Connected.
3. Then use the spool skill to record a walkthrough of my app at http://localhost:3000 and send me the watch link.

Behind the prompt is one command, spool init. It checks the environment and installs what is missing (Chromium through the CLI's own Playwright, ffmpeg through Homebrew when there is one), installs the spool skill into ~/.claude/skills and ~/.codex/skills, runs the login, writes defaults, and prints the record command. Off a terminal it still runs the login: it prints a link and a code for the agent to relay, and waits for you to type the code. Node 20 or newer is the one thing it cannot install.

By hand

# the CLI, published as @spoolkit/cli npm i -g @spoolkit/cli spool init

The Chromium download takes a few minutes and only happens once. Without Homebrew, install ffmpeg yourself and run spool init again.

Verify the environment

Run spool doctor anytime to check deps, config, host, and token. It prints an actionable fix for anything missing, and --json makes it machine-readable for an agent.

spool doctor

Preferences

spool setup writes your defaults to ~/.spool.json: which browser records (bundled Chromium, your real Chrome, or Edge), the default recording target, and the voice engine. Publishing always targets spoolkit.dev unless you point SPOOL_HOST at your own deployment (see self-host below). Interactive on a terminal; agents pass flags with --yes. Precedence everywhere: explicit flag, then env, then preferences.

spool setup --browser chrome --engine hosted --yes spool setup --show

Setup

Install, connect, record. spool login authorizes the CLI from your browser and writes the config for you, so there is nothing to copy by hand.

Run spool login. It opens spoolkit.dev/cli-auth in your browser; sign in, approve the request, and the CLI writes your host and token to ~/.spool.json. That one token covers both publishing and hosted voice. Done.

spool login
Hosted voice needs no key of your own. The voice engine auto-resolves in order: OPENROUTER_API_KEY, then OPENAI_API_KEY (each read from env, project .env, or openrouterKey/openaiKey in ~/.spool.json); with neither, voice runs on the hosted app through the same token, subject to a fair-use daily cap. Force one with spool setup --engine openrouter|openai|hosted|local, or with the SPOOL_ENGINE environment variable for a single run. Run spool voice clone once and the hosted voice becomes yours: read a short script, and every spool from then on narrates in your voice.

Headless, CI, or self-host

On a machine with no browser, mint a raw token and hand it to the CLI directly. The API keys page lets you create a named key for each machine or workflow. The key is shown once; creating another keeps existing keys active. Revoke individual keys from the same page. Then either paste it into spool login --paste, write the config file yourself, or set the SPOOL_HOST and SPOOL_PUBLISH_TOKEN environment variables in your CI job.

# paste a dashboard token, no browser needed spool login --paste # or the raw config / CI envs { "host": "https://spoolkit.dev", "token": "spk_..." } export SPOOL_HOST=https://spoolkit.dev SPOOL_PUBLISH_TOKEN=spk_...

Record a walkthrough

Live mode is the drive-once path. You just verified a feature in a browser, so drive it one more time and spool records as you go. No steps.mjs to author or debug.

Start a session against your running app. Spool boots a headless recording browser and an HTTP control server on 127.0.0.1:<port>, then prints one line of stdout with the port.

spool live spool/my-feature --url http://localhost:3000

The control server

You drive the take by posting to the control port:

  • POST /step: { name, narration, zoom }. Narration is required; the renderer sizes each step window to it.
  • POST /js: runs the body of async (page, h) => { … }. Use the h.* helpers (click, move, type, scroll, pause) for anything visible.
  • GET /status: progress so far.
  • POST /end: finalizes video.webm, timeline.json, keyframes, and a generated steps.mjs snapshot.

Drive it in one continuous script

Write every step as a single shell script and run it in one command. Thinking time between separate tool calls is recorded as dead air in the take. End each step settled, with about two seconds of h.pause, so the freeze-hold lands on a finished state. Aim for four to eight steps, one idea each.

# each step is one /step then one /js curl -sX POST 127.0.0.1:$PORT/step -d '{"name":"open","narration":"The dashboard loads the new flow."}' curl -sX POST 127.0.0.1:$PORT/js -d '{"code":"await h.click(\"#open\"); await page.waitForSelector(\".result\")"}' curl -sX POST 127.0.0.1:$PORT/end
Failure forensics. A failed /js returns { ok: false } without killing the session, and it comes back with a screenshot path, the recent console telemetry, and selector candidates when the error looks locator-shaped. Fix and retry inline; those seconds are recorded, so keep fumbles short.

Finish and publish

spool finish runs voice, render, and share on the recorded session without re-recording, then publishes and prints your watch link. Pass --no-publish to keep it local.

spool finish spool/my-feature

Prefer a reproducible driver? The scripted path is spool init my-feature to scaffold a steps.mjs, spool dry to debug it cheaply, then spool build. To leave the browser (native apps, the terminal) capture the whole macOS desktop with spool live --target os.

PR guides

Turn a pull request into a narrated, navigable reading of the change. A guide is a comprehension tool, not a review: no verdicts, no bug hunting.

Scaffold the workdir from the PR number or URL. It fetches the metadata and diff via gh and writes tour.json, context.json, and a context.md brief.

spool pr 128

Rewrite tour.json into four to eight stops in narrative reading order (why the change exists, the entrypoint, the core change, the ripples, the tests). Each stop is { id, heading, prose, files }.

  • UI-surface change: live-record the running feature, naming each /step after the tour stop id it illustrates. Stop ids are the only link between the tour and the video.
  • Non-UI change (refactor, backend, infra): author a self-contained explainer.html in the workdir and record that page, one section reveal per step.

Run spool lint to catch structural breaks and unmatched tour stops, then publish with --pr. Publishing comments the guide, a stop table timestamped to the video, on the pull request.

spool lint spool/pr-128 spool publish spool/pr-128 --pr 128

Projects

Seed a repo's shared knowledge once so future guides and recordings start warm instead of re-deriving the app every time.

Bare spool init (no slug) detects the repo owner and name via gh, fetches the current project store into spool/project/knowledge.json, and writes an empty ops file for you to author. Record the overview, the subsystems a reader needs, the domain vocabulary, and, after booting the app, the recording topics: how to run it, the dev-login shape, and any flaky spots.

spool init # scaffold the seed ops spool init --apply # apply them to the project store

Once seeded, every spool pr and spool live session on the repo starts from those recording topics, and each published guide grounds its watch-page chat in the accumulated project knowledge.

CLI reference

Every command, with its most common flags. Run spool <command> --help for the full option list.

CommandWhat it does
spool loginAuthorize the CLI from your browser: opens /cli-auth, you approve, and the token is written to ~/.spool.json. --paste takes a token on the terminal for headless machines, --host points at another deployment.
spool init [slug]With a slug, scaffold spool/<slug>/steps.mjs. Bare, seed this repo's shared project knowledge (--apply writes it).
spool live <dir>Drive the app once over an HTTP control server and derive the steps. --url, --title, --target browser|os, --format wide|vertical, --auth <file> (a Playwright storageState JSON, so the take starts signed in).
spool record <dir>Record a scripted steps.mjs at natural speed. The renderer retimes it, so VO is not required first.
spool dry <dir>Drive the steps in a visible browser with no recording or VO, to debug selectors and timing.
spool recut <dir>Re-derive the step boundaries from the take's signal log, with no re-record. --merge, --split, --drop, --trim-start, --trim-end, --name, --narrate, --dry-run, --json.
spool build <dir>End to end: (vo ‖ record) then render, share, and publish. --no-publish, --cloud renders on spoolkit.dev instead of this machine.
spool finish <dir>vo then render, share, and publish on an existing session, no re-record. --no-publish, --cloud.
spool render <dir>Normalize and render the final mp4. --preview writes a fast half-scale draft to share/preview.mp4 and leaves final.mp4 alone. --cloud renders on spoolkit.dev.
spool bg <dir> <bg>Swap a rendered spool's canvas from layers/fg.webm, with no re-render. --publish mints a new watch link for the swapped take.
spool vo <dir>Generate voiceover segments and word timestamps. The engine and voice come from your preferences, not from flags.
spool voiceYour own voice for narration. clone records about a minute from the mic (or takes a file) and every spool speaks in it; remove goes back to the house voice.
spool share <dir>Write the agent-consumable share/ bundle (spool.json, transcript, keyframes, console log).
spool read <target>Print an agent-oriented digest of a spool (a workdir or its share/ dir). --plan reads a plan packet and its decision instead, and takes a watch URL or spool id. --json, --offline, --transcript.
spool listYour recently published spools: title, PR, views, watch link. --json, --host, --token.
spool publish <dir>Upload the spool and get one watch link. Pre-lints and blocks on errors. --pr [n] comments the link on the PR, --host, --token, --force.
spool pr <n|url>Scaffold a PR guide workdir (fetches PR metadata and diff via gh).
spool lint [dir]Fast static checks on a workdir (steps, timeline, tour, vo), no browser. --json.
spool doctorCheck the environment (deps, config, host, token) with actionable fixes. --json.
spool setupSet preferences: --browser, --target, --engine, --host. --yes writes them without prompting, for agents. --show prints the profile.
spool open [dir]Open the published watch link, or the dashboard when there is none.

For agents

Spool is built for agents to consume, not just produce. Every build emits a machine-readable bundle so another agent can review a demo without watching video.

  • share/spool.json: steps, narration, timings, click coordinates, and keyframe paths, with transcript.txt and one keyframe PNG per step alongside it.
  • console.jsonl: browser console, page errors, and failed requests captured during recording. File bugs straight from it or verify a claimed fix renders clean.
  • spool read <dir>: an instant digest of a spool (steps, narration, timings, console errors, keyframe paths). Read only the frames you care about after that.
  • --json: both spool lint --json and spool doctor --json emit structured output for programmatic checks.
Connect your agent. The API keys page provides CLI setup commands and named keys for agents and CI. A platform key is required before recording or building, even with local voice or no publishing.

Pricing

Free to start, hosted and managed when you need more.

The free plan publishes 3 spools a month with every feature included, and the links stay live forever. Only live spools count against it: a draft you abandon and a cloud render that failed cost you nothing, the slot is spent when a spool actually becomes watchable, and the allowance refills on the 1st. Pro is $15/mo per seat for unlimited published spools, PR guides, shared projects, hosted voice, and per-user CI tokens. It includes 20 recaps per seat per month, pooled across the workspace, and every recap past the pool is $1. The other fair-use caps scale with the seats you buy (hosted voice per day, cloud renders per month) and the dashboard shows your usage against them. Every spool is a self-contained final.mp4 plus an agent-readable bundle, so the output is yours either way. See the pricing section.