DOCS

You talk. Your agent runs the commands.

The reference manual — the story lives on the homepage. Install, configure, use, and what's in the evidence package.

docs
01 · Install

You don't install it. Your agent does.

The intended flow: you give the instruction, the agent types the commands. Witness is a CLI (wit) that drives your installed Edge/Chrome (bundled Chromium only as fallback) — no cloud account, no keys.

say this to your agent
Install witness: `npm i -g github:wookat/witness`,
verify with `wit --version`. Requires Node 18+.

What lands on your machine

the wit CLI — recorder, session renderer, transcriber, MCP server in one binary. Config persists to the project's .witness/config.json; the doubao-ime engine caches its token at ~/.witness/doubao-creds.json. Evidence always lands in the current project's .witness/sessions/.

Teach an agent that doesn't know it

The repo ships skills/witness/SKILL.md — a ready-made skill file. Drop it into CLAUDE.md / .cursor/rules/ / AGENTS.md and phrases like "record a session for me" trigger the whole workflow. View it ↗
what the agent actually runs
# for transparency — under the hood your agent does:
npm i -g github:wookat/witness
wit --version
config
02 · Configure

Zero-config by default; switches when you want them.

Live ASR engine

wit config asr persists to the project's .witness/config.json; --asr / WIT_ASR override per run. Agents can flip it live via the set_asr MCP tool.
auto         doubao-web → doubao-ime → sr
doubao-web   best punctuation (default pick)
doubao-ime   per-sentence timestamps, ITN digits
sr           browser SpeechRecognition (offline)
off          no live subtitles (final transcript only)

Optional keys & env

Everything works with none of these — they're upgrades, not requirements:
OPENAI_API_KEY   whisper-1 word timestamps
ZHIPU_API_KEY    GLM-4 say-correction + associate
WIT_ASR          engine override for one run
WIT_NO_BODIES=1  skip response-body capture
WIT_CDP=<port>   expose CDP so an agent can drive
                 the recorded browser as the tester
record● REC
03 · Use it

Three sentences. That's the whole loop.

the conversation
you → "record http://localhost:5173 for me"
agent → runs `wit start`, managed browser opens you → use the product, talk out loud, mark problems you → press ■ (or tell the agent "stop") you → "fix the issues from that recording"
agent → reads session.md, fixes from the evidence
YOUR PART — inside the browser

Talk & point

speak        every observation → timestamped SAY
Ctrl+Click   mark an element (selector + shot + DOM)
M            inspect mode — hover-pick or drag a region
N            new issue boundary (optional)
P            pause/resume — freezes evidence AND mic
■ / Alt+Shift+R   stop
AGENT'S PART — commands it may run

The CLI surface

wit start <url>        record (agent launches it)
wit list / open        browse sessions
wit transcribe <dir>   re-run transcription
wit correct <dir>      LLM polish (verbatim kept)
wit associate <dir>    LLM picks evidence per SAY
wit recover <dir>      rebuild after a crash
wit mcp [dir]          serve evidence over MCP
wit config asr …       engine: auto|doubao-web|doubao-ime|sr|off
package
04 · What you get

One package, two audiences.

For you: a visual replay. For your agent: a structured handoff it can fix from.

.witness/sessions/<ts>/
├─ review.html → FOR HUMANS — timeline replay: audio + shots + events, click anything to seek
├─ SEGMENTS.md → FOR AGENTS — speech segments: verbatim + suspects + shot refs (read first)
├─ keyframes/ → rrweb-rendered replay frames per segment (wit keyframes)
├─ segments/NN.md → FOR AGENTS — per-segment bundle: frags + dead clicks + errors + shots
├─ PROMPT.md → FOR AGENTS — handoff doc: how to read this evidence
├─ session.md → FOR AGENTS — full timeline archive (drill-down)
├─ events.jsonl → raw event stream (1189 events in a real run)
├─ transcript.json → final speech transcript, segment timestamps
├─ audio.webm → the recording, seekable
├─ shots/ → screenshots — marks get red boxes, regions are crops
├─ bodies/ → request/response payloads
├─ dom/ → DOM snapshots at key moments
├─ rrweb.jsonl → full replay stream
└─ session.json → meta: url, duration, asr engine, counts

PROMPT.md

The paste-this-to-your-agent doc. Teaches it the format: causal-burst indentation, "no aftermath = evidence", component chains, never infer intent without a SAY.

session.md

The evidence timeline. Each SAY block carries your verbatim words plus what the page did at that second.

wit mcp

Serves the session over stdio MCP — 12 tools: list_segments · segment_detail · session_overview · list_says · session_md · events_around · get_errors · get_shot · get_dom_state · get_body · get_asr · set_asr.
handoff
05 · Tell your agent

Three ways to hand over evidence.

EASIEST

Point at the directory

"I recorded a session —
evidence is in .witness/sessions/<ts>.
Read session.md and fix the issues."
FOR ANY AGENT

Paste PROMPT.md

The file teaches an unfamiliar agent how to read the package. Copy its contents plus the directory path — works with agents that don't know Witness.
PERMANENT

Wire the MCP

{ "mcpServers": { "witness": {
  "command": "wit", "args": ["mcp"]
} } }
Agent pulls evidence on demand — and can flip the ASR engine itself.

And to make an agent record: "use witness to record http://localhost:5173 — I'll talk through the issues". With WIT_CDP set, an agent can even be the tester inside the recorded browser.

demo■ STOP
06 · Try it in two minutes

Record the demo page.

A tiny broken product ships with the site — it has a dead button, a console error and a bad API response waiting to be caught:

terminal
wit start https://witness.zalize.com/demo-app.html --duration 60
# click the Pay button, say "it does nothing", stop → open review.html