Install
Node 20 or newer, ffmpeg on PATH, and a headless Chromium. The global npm package is the fastest path.
# the CLI, published as @spoolkit/cli
npm i -g @spoolkit/cli
npx playwright install chromiumFirst-time setup can be slow either way; the Chromium download takes a few minutes and only happens once.
Prefer a single command? The installer clones the repo, links spool onto your PATH, and fetches Chromium for you.
curl -fsSL https://raw.githubusercontent.com/aaarnv/spool/master/install.sh | bashPrerequisites
- Node 20+ and ffmpeg on PATH (on macOS,
brew install ffmpeg). - Chromium from Playwright's cache:
npx playwright install chromium.
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 doctorPreferences
spool setup writes your defaults to ~/.spool.json: which browser records (bundled Chromium, your real Chrome, or Edge), the default recording target, the voice engine, and the render background. 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 --bg paper --yes
spool setup --showSetup
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 loginOPENAI_API_KEY (env, project .env, or openaiKey in ~/.spool.json) is used when present, otherwise voice runs on the hosted app through the same token, subject to a fair-use daily cap. Force one with --engine openai|hosted|local.Headless, CI, or self-host
On a machine with no browser, mint a raw token and hand it to the CLI directly. The dashboard is the source of raw tokens: its agent prompt embeds a fresh one, and Revoke all & regenerate issues a new token (invalidating every previous one, CLI logins included). 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:3000The 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 ofasync (page, h) => { … }. Use theh.*helpers (click,move,type,scroll,pause) for anything visible.GET /status: progress so far.POST /end: finalizesvideo.webm,timeline.json, keyframes, and a generatedsteps.mjssnapshot.
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/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-featurePrefer 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 128Rewrite 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
/stepafter 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.htmlin 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 128Projects
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 storeOnce 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.
| Command | What it does |
|---|---|
| spool login | Authorize 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. |
| 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, --headed. |
| spool record <dir> | Record a scripted steps.mjs at natural speed. --headed. |
| spool dry <dir> | Drive the steps with no VO or video to debug selectors and timing. --headed. |
| spool build <dir> | End to end: (vo ‖ record) then render, share, and publish. Detects a live/recorded session and finishes it. --no-publish, --engine, --voice, --speed, --rate, --bg, --headed. |
| spool finish <dir> | vo then render, share, and publish on an existing session, no re-record. --no-publish, --engine, --voice, --speed, --rate, --bg, --preview. |
| spool render <dir> | Normalize and Remotion-render the final mp4. --rate, --bg, --preview (fast half-scale draft). |
| spool vo <dir> | Generate voiceover segments and word timestamps. --engine, --voice, --speed. |
| spool share <dir> | Write the agent-consumable share/ bundle (spool.json, transcript, keyframes, console log). |
| spool read <dir> | Print an agent-oriented digest of a spool (accepts a workdir or its share/ dir). |
| spool list | Your recently published spools: title, PR, views, watch link. --limit, --json. |
| 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 doctor | Check the environment (deps, config, host, token) with actionable fixes. --json. |
| spool setup | Set preferences: browser, recording target, voice engine, background. --yes for agents, --show prints the profile. |
| spool open [dir] | Open the published watch link, or the dashboard when there is none. |
| spool backgrounds | List the render backgrounds: repo presets plus this machine's macOS wallpapers. |
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, withtranscript.txtand 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: bothspool lint --jsonandspool doctor --jsonemit structured output for programmatic checks.
Pricing & self-host
Open source at the core, hosted when you want it managed.
The free plan publishes 3 spools with every feature included, and the links stay live forever. Pro is $8/mo for unlimited published spools, PR guides, shared projects, hosted voice, and per-user CI tokens. Fair-use caps scale with the plan (hosted voice per day, edit re-renders per month) and the dashboard shows your usage against them. Self-hosting the pipeline is free forever: the CLI and render pipeline are MIT licensed, so you can record, narrate, and render locally with no lock-in; every spool is a self-contained final.mp4 plus an agent-readable bundle. See the pricing section or the repository.