What it does
[Coda](https://coda.io) blends a doc, spreadsheet, and database in one canvas — teams use it for project trackers, OKRs, content pipelines, and lightweight CRMs. This sink writes every peepshow run as one row in a chosen doc + table via `POST /apis/v1/docs/<docId>/tables/<tableId>/rows` with the standard `{rows: [{cells: [{column, value}, ...]}]}` shape. Columns must exist on the table (Coda's API doesn't auto-create schema). Once wired up the rows flow into any Coda automation, pack, or dashboard you've built — a queryable log that non-engineer stakeholders can shape into views without leaving the doc they already live in.
When to reach for it
- Maintain a stakeholder-friendly log of every video an agent processed — Coda views beat SQL for non-engineers
- Trigger Coda automations (Slack post, email, pack action) on each new peepshow run
- Drop runs into a Coda dashboard alongside your project tracker — no extra UI needed
Install
npm i -g peepshowUse it
CODA_API_KEY="codaKEYxxxxxxxxxxxxxxxxxxxxxxxx" \
CODA_DOC_ID="abc123XYZ" \
CODA_TABLE_ID="grid-xxxxxxxx" \
peepshow ./demo.mp4 --sink codaMake it automatic
Register the sink once — every run fires it afterward. Scope by --when so it only runs for matching videos.
peepshow sinks add coda
peepshow sinks add coda --when extension=mp4,mov
peepshow sinks add coda --when path=/Volumes/Work/Configuration
CODA_API_KEYCoda API token (Bearer auth). Generate at [coda.io/account](https://coda.io/account). requiredCODA_DOC_IDDoc id — the segment after `_d` in the doc URL (e.g. `https://coda.io/d/My-Doc_dXYZ123` → `XYZ123`). requiredCODA_TABLE_IDTable id (preferred — survives renames). Find via `GET /docs/<doc>/tables`.CODA_TABLE_NAMEHuman-readable table name. Used when `CODA_TABLE_ID` is unset.CODA_API_URLOverride the base URL — useful for proxies.PEEPSHOW_FRAME_BASE_URLWhen set, the first frame URL is written to the `Thumbnail URL` column.
Use with an LLM agent
Every peepshow sink reads its config from env vars and receives a single JSON payload on stdin. An LLM agent (Claude Code, Cursor, Windsurf, Gemini, Codex) can drive the Coda sink automatically when three things are true:
- the env vars below are exported in the agent's shell (or a project
.envit can load), - the
peepshowCLI is onPATH— install withnpm i -g peepshow, - a peepshow auto-sink is registered for the run (optional but recommended — makes invocation zero-argument).
1. Set the environment
# Add to ~/.zshrc, ~/.bashrc, or a project .env the agent can load
export CODA_API_KEY="..."
export CODA_DOC_ID="..."2. Register as an auto-sink
peepshow sinks add coda
peepshow sinks add coda --when extension=mp4,mov3. Example LLM session
You → drop a
.movinto Claude Code.Claude → auto-invokes
/peepshow:slides ./clip.mov. peepshow extracts frames + audio, theCodasink forwards the run to a new page in your knowledge base. Claude replies with a summary and a link to the created record.
The transcript text is embedded alongside the frame gallery on the created page.
Write your own
A sink is any executable that reads the --emit json payload on stdin. Shell, Node, Python, Go — the spec's in docs/PLUGINS.md. Register persistent ones with peepshow sinks add-cmd 'your-command'.