feat: add terminal session recording with asciinema v2 format#8
Open
feat: add terminal session recording with asciinema v2 format#8
Conversation
Sessions can now be recorded to .cast files, served over the API, and played back in any browser without additional tooling — the primary use case being CI pipelines where sessions run headlessly and someone needs to review what happened after the fact. ## New API endpoints Session-scoped (nested under /sessions/:name): POST /recording start recording GET /recording get active recording status DELETE /recording stop active recording Global recording management: GET /recordings list all recordings GET /recordings/:id get one recording DELETE /recordings/:id delete a recording GET /recordings/:id/cast serve the raw .cast file GET /recordings/:id/player self-contained HTML player page GET /recordings/:id/embed copy-pasteable HTML embed snippet ## Format asciinema v2: newline-delimited JSON, append-only so partial recordings from unclean shutdowns remain playable. ## Web embeddability - /player: full HTML page with asciinema-player loaded from CDN; works in any browser, no installation required - /embed: HTML snippet with absolute cast URL for pasting into GitHub issues, Confluence pages, CI dashboards, etc. - CORS header on /cast allows cross-origin player embeds ## Auto-record on session create POST /sessions accepts a `recording` field to start recording from the first PTY byte, capturing session output before any API client connects. ## Implementation notes - Recording taps the broker broadcast channel (same source as WS clients) - Writer runs in a separate async task; cancellation token stops it cleanly - Session cancellation token propagated so recordings stop when sessions die - SessionInfo now includes active recording_id when present Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Covers the full recording API (start/stop/status, list, cast/player/embed), auto-record on session create, CI/GitHub Actions example, storage paths, and options for sharing recordings publicly. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
wsh record start <session> [--title "..."]
Start recording an existing session.
wsh record stop <session>
Finalize the recording and print IDs + URLs.
wsh record status <session>
Show whether a session has an active recording.
wsh record list [--session <name>] [--status recording|stopped|failed]
Columnar table of all recordings, filterable by session or status.
wsh record get <id>
Show full details for a single recording.
wsh record delete <id>
Delete the recording and its .cast file from disk.
wsh record download <id> [--output <path>]
Write the .cast file to a local path or stdout ("-").
Works for both active (partial) and completed recordings.
Suitable for piping: wsh record download <id> | asciinema play /dev/stdin
--record / --record-title flags on the default wsh command:
wsh --record --record-title "Build" starts recording from the
first PTY byte. The recording ID is printed to stderr after
session creation.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Author
|
Here's a video of it working: 2026-04-wsh-feature-terminal-session-recording.mp4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sessions can now be recorded to .cast files, served over the API, and played back in any browser without additional tooling — the primary use case being CI pipelines where sessions run headlessly and someone needs to review what happened after the fact.
New API endpoints
Session-scoped (nested under /sessions/:name):
POST /recording start recording
GET /recording get active recording status
DELETE /recording stop active recording
Global recording management:
GET /recordings list all recordings
GET /recordings/:id get one recording
DELETE /recordings/:id delete a recording
GET /recordings/:id/cast serve the raw .cast file
GET /recordings/:id/player self-contained HTML player page
GET /recordings/:id/embed copy-pasteable HTML embed snippet
Format
asciinema v2: newline-delimited JSON, append-only so partial recordings from unclean shutdowns remain playable.
Web embeddability
Auto-record on session create
POST /sessions accepts a
recordingfield to start recording from the first PTY byte, capturing session output before any API client connects.Implementation notes