Your coding agent is blind to the most important thing: what you actually saw on screen.
When a human tester says "the button does nothing", my agent can't see it. A screenshot freezes one frame and loses the why. Writing a proper bug report takes 10 minutes — and by then I've context-switched away from what I was building.
So I built witness — an open-source (MIT) CLI that records you using your product, and hands your coding agent a causal evidence package it can fix from.
The idea
wit start https://localhost:3000 opens a managed browser. You use the product and just talk — "here the submit button should show a spinner but it doesn't". Every utterance is welded to the clicks, network requests, console errors, DOM state and rrweb replay of that exact second.
When you stop, witness writes a .witness/sessions/<id>/ evidence bundle: transcript anchored to events, timeline, screenshots, response bodies — and exposes the whole thing to your agent over 12 MCP tools (witness_get_session, witness_timeline, witness_request_detail...). Claude Code / Cursor / Codex can then investigate the recording instead of guessing.
Why not just a screen recording?
Video has no semantics. A screen recording shows a click; witness records the click, the fetch it fired, the 500 it got back, the console.error, the DOM diff, and what you said about it — indexed by timestamp so the agent can correlate "user said spinner missing at t=12s" with "POST /api/submit returned 200 in 41ms but emitted no submit:start event at t=12s".
That's the difference between "here's a video, figure it out" and "here is the causal chain, the evidence is in these files".
The dogfood moment
We literally found and fixed a bug on witness's own marketing site using a witness recording of the site — the recording caught a request failing that never surfaced in the UI. That's when I knew the workflow worked.
Local-first, because it's evidence
Everything lands in .witness/ on your disk. No account, no keys, nothing leaves your machine except the optional anonymous "someone ran wit start" ping. Password fields are masked across four capture channels, credential fields are redacted from POST bodies, WIT_NO_BODIES=1 disables body capture entirely, P freezes the recording instantly.
Try it
npm i -g witness-recorder wit start https://your-app.dev # talk, click, break things # then point your agent at .witness/sessions/latest Or as an MCP server: wit mcp registers 12 tools straight into your client.
Repo: https://github.com/wookat/witness — MIT, TypeScript, works on Windows/macOS/Linux. Issues and PRs welcome; I'm especially curious what other channels of evidence people want captured.


