Skip to content

feat: add terminal session recording with asciinema v2 format#8

Open
pcgeek86 wants to merge 5 commits intomasterfrom
feat/session-recording
Open

feat: add terminal session recording with asciinema v2 format#8
pcgeek86 wants to merge 5 commits intomasterfrom
feat/session-recording

Conversation

@pcgeek86
Copy link
Copy Markdown

@pcgeek86 pcgeek86 commented Apr 8, 2026

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

pcgeek86 and others added 5 commits April 8, 2026 08:59
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>
@pcgeek86
Copy link
Copy Markdown
Author

pcgeek86 commented Apr 8, 2026

Here's a video of it working:

2026-04-wsh-feature-terminal-session-recording.mp4

@pcgeek86 pcgeek86 changed the title [Do not merge] feat: add terminal session recording with asciinema v2 format feat: add terminal session recording with asciinema v2 format Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant