postrundocs Back to siteGet early accessAccess
Browse docsReviewing sessions

Reviewing sessions

The review app is a local web page served by the Postrun server. It reads the store, lists every recorded session, and shows one session at a time as a report: the files it touched, the commands it ran, and a timeline of every step. It updates live while agents are working.

Open it

pnpm serve

pnpm serve builds the review app, then serves it with the store at http://127.0.0.1:1234/. On start it prints the store path, the sessions in it, and the address:

postrun store /home/you/.postrun/postrun.db: 3 session(s)
  ...
serving UI from /path/to/postrun/apps/ui/out
ingest: POST http://127.0.0.1:1234/api/ingest  (bearer token in /home/you/.postrun/ingest-token)
listening on http://127.0.0.1:1234/  (127.0.0.1 only; ctrl-c to stop)

Options:

pnpm serve --port 4321              # or PORT=4321; the flag wins, then PORT, then 1234
pnpm serve --db /some/other/postrun.db

The server only reads the store; it never runs adapters. Sessions arrive from pnpm capture, pnpm ingest or the ingest API, and appear without a restart. All of these can run at the same time: they share the SQLite file.

The session list

The home page lists every stored session, newest first. Each row shows:

  • The agent badge and version.
  • The session title (the first line of the first prompt) and the start of the session id.
  • The workspace folder name.
  • When it started, as a date and a relative time.
  • The step count, broken down by type, with failed and reference-only counts.
  • The cost the agent reported.
  • The number of flags.

Above the list, the agent chips filter by agent kind (the address becomes /?agent=<kind>), and the total shows the number of sessions and their combined cost. Click a row to open the session.

The session view

A session opens at /session?id=<id>.

Summary

The top card shows the agent, the title and version, and:

ItemWhat it is
costReported API cost and number of API requests
steps, turnsTotals for the session
failedSteps whose outcome is failed
reference-onlySteps whose content was not available inline
workspaceThe working directory
whenStart and end time, or open while the session has no end, plus the number of segments
ownerThe owner id and the machine it was captured on
tokensInput and output tokens

Files touched

Every file the session created, edited or read, with a count of each and how many of those steps failed.

Commands run

Every distinct command, with how many times it ran and the exit codes seen. Commands whose output is not inline are tagged output not inline.

Timeline

The timeline groups steps by turn. Each turn shows its number, the prompt that started it, and its mode (for Cline, plan or act; otherwise no mode). Each step shows its seq, its type, a one-line summary, and a status:

  • ok
  • failed, followed by the error type when the agent reported one
  • reference-only, when the content is a pointer rather than inline

Click a step, or focus it and press Enter, to open everything it recorded:

StepWhat opens
commandThe command, its working directory and exit code, then stdout and stderr
editThe file and the change as a diff: removed lines in red, added lines in green
readThe file and the line range read
messageThe full prompt or reply
otherThe tool name and everything recorded for it

Each step also shows when it happened, the permission decision when one was recorded, and any error or flag. Output longer than 100,000 characters is cut, with a button to show all of it. Expand all and Collapse all sit next to the timeline heading. To link to one step, add #step-<seq> to the address: that step opens and scrolls into view. An open step stays open while the session updates live.

Long sessions stay quick to open and to watch:

  • The timeline shows the 30 most recent turns. Show earlier turns above them adds 50 at a time. A link to a step shows every turn.
  • The session arrives with each step's first 2 KB of output; opening a step loads the rest.
  • A live update fetches only the steps that changed since the last one, at most once every two seconds, and redraws only the turns that changed.

A Claude Code session recorded while pnpm capture was stopped shows not recorded for cost: see Troubleshooting.

Live updates

The app keeps one connection per browser tab to the live events stream. When a session is written, the list and the open session refetch in place. The pill in the top bar shows the connection state:

PillMeaning
liveConnected. Changes appear as they are written.
connectingOpening or reopening the connection.
server offlineThe server cannot be reached. What is on screen stays, and the app catches up when the server is back.

A Claude Code session updates at the end of each assistant turn. A Cline session updates shortly after Cline saves its messages file.

Export

The Export report button on a session opens the export panel. It lists every value redaction will mask before you download. See Exporting and redaction.

Deleting a session

The Delete button on a session removes it from Postrun on this computer. A short panel asks you to confirm first, with Cancel selected, and says how many steps will go.

Deleting removes:

  • the session's steps, turns and summary from the store, with SQLite's secure delete on, so the content is overwritten rather than left in free pages, and the write-ahead log is cleared;
  • its raw capture files, for a Claude Code session.

Postrun then remembers only the session id, so the recorder will not record that session again, even if the agent keeps writing to it. Pushes for it get 410. Any other tab showing the session says it is no longer in Postrun.

Deleting does not touch the agent's own copy. Claude Code keeps its transcripts under ~/.claude/projects and Cline keeps tasks in ~/.cline/data/sessions; delete them there if you want them gone everywhere.

The same works from a terminal with pnpm delete. The button is not shown in the demo.

Read routes

The review app uses these routes, which you can also call from scripts on the same machine. They need no token.

RouteReturns
GET /api/sessions{ sessions, agents }, newest first. Add ?agent=<kind> to filter.
GET /api/sessions/<id>The full session (summary, segments, actors, turns, steps) plus report (files touched, commands run). 404 if not found.
GET /api/sessions/<id>/exportThe redacted HTML report, as a download.
GET /api/sessions/<id>/export/reviewWhat the export would mask, as JSON.
GET /api/eventsThe live events stream.
DELETE /api/sessions/<id>Deletes the session (see above). Only accepted from the review app itself: requests from another site get 403. 404 if not found.

Every response carries x-content-type-options: nosniff, referrer-policy: no-referrer and cache-control: no-store, and no CORS headers.

Working on the review app

To run the app with hot reload, start the core server and the Next dev server in two terminals:

pnpm dev:core    # API and the last built UI on 127.0.0.1:1234
pnpm dev:ui      # Next dev server on 127.0.0.1:3000, with /api proxied to 127.0.0.1:1234

Set UI_PORT to move the dev server, and POSTRUN_CORE_URL to proxy to a core server on another address.

Found something wrong? These docs live in apps/docs of the postrun repo. Privacy · Security