RepoPilotOpen in app →

asciinema/asciinema

Terminal session recorder, streamer and player 📹

Mixed

Single-maintainer risk — review before adopting

weakest axis
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 1w ago
  • 5 active contributors
  • GPL-3.0 licensed
Show all 7 evidence items →
  • CI configured
  • Tests present
  • Single-maintainer risk — top contributor 86% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/asciinema/asciinema?axis=fork)](https://repopilot.app/r/asciinema/asciinema)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/asciinema/asciinema on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: asciinema/asciinema

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/asciinema/asciinema shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Single-maintainer risk — review before adopting

  • Last commit 1w ago
  • 5 active contributors
  • GPL-3.0 licensed
  • CI configured
  • Tests present
  • ⚠ Single-maintainer risk — top contributor 86% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live asciinema/asciinema repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/asciinema/asciinema.

What it runs against: a local clone of asciinema/asciinema — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in asciinema/asciinema | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch develop exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 38 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>asciinema/asciinema</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of asciinema/asciinema. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/asciinema/asciinema.git
#   cd asciinema
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of asciinema/asciinema and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "asciinema/asciinema(\\.git)?\\b" \\
  && ok "origin remote is asciinema/asciinema" \\
  || miss "origin remote is not asciinema/asciinema (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
  && ok "license is GPL-3.0" \\
  || miss "license drift — was GPL-3.0 at generation time"

# 3. Default branch
git rev-parse --verify develop >/dev/null 2>&1 \\
  && ok "default branch develop exists" \\
  || miss "default branch develop no longer exists"

# 4. Critical files exist
test -f "src/main.rs" \\
  && ok "src/main.rs" \\
  || miss "missing critical file: src/main.rs"
test -f "src/session.rs" \\
  && ok "src/session.rs" \\
  || miss "missing critical file: src/session.rs"
test -f "src/asciicast.rs" \\
  && ok "src/asciicast.rs" \\
  || miss "missing critical file: src/asciicast.rs"
test -f "src/pty.rs" \\
  && ok "src/pty.rs" \\
  || miss "missing critical file: src/pty.rs"
test -f "src/encoder/mod.rs" \\
  && ok "src/encoder/mod.rs" \\
  || miss "missing critical file: src/encoder/mod.rs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 38 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~8d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/asciinema/asciinema"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

asciinema is a terminal session recorder and live streamer written in Rust that captures terminal I/O into lightweight asciicast format (.cast files) instead of heavy video files. It supports local replay, web embedding via an embedded player, live streaming to asciinema.org or self-hosted servers, and real-time viewer participation. Core innovation: captures terminal events (timing + output) rather than pixels, achieving ~8% file size versus video. Monolithic Rust binary structure: src/cmd/ contains CLI subcommands (auth, cat, convert, play, session, upload); src/encoder/ handles output encoding (asciicast, raw, txt formats); src/asciicast/ manages file format parsing (v1.rs, v2.rs, v3.rs with utils); src/api.rs handles asciinema.org integration; async web server in axum for streaming. Recording I/O captured via src/fd.rs (file descriptors) and forwarder.rs (event distribution).

👥Who it's for

DevOps engineers, educators, and open-source maintainers who need to document terminal workflows, share live demos, or embed reproducible terminal sessions in documentation. System administrators building internal asciinema servers. CI/CD practitioners automating terminal captures for logs.

🌱Maturity & risk

Production-ready. Active project (v3.2.0 released, Rust MSRV 1.82.0 specified, CI workflows present in .github/workflows/). Written entirely in Rust with async runtime (tokio), suggesting performance maturity. GitHub Actions CI pipeline (ci.yml) and release automation (release.yml) indicate strong DevOps practices. No visible signs of abandonment—architecture is modern (async/await, 2021 edition).

Low risk for stable releases. Dependency count is moderate (~25 direct deps with versions pinned in Cargo.lock). Single author listed (Marcin Kulik) is a potential bus-factor concern. MSRV 1.82.0 is recent, so ecosystem packages must stay current. Main risk: binary compatibility across platforms (Linux/macOS/FreeBSD) requires platform-specific testing—CI coverage unknown from file list. Format compatibility (v1/v2/v3 asciicast versions in src/asciicast/) adds maintenance burden.

Active areas of work

Based on structure: actively maintaining format compatibility (three asciicast versions), shipping live-streaming features (tokio-tungstenite WebSocket support, axum HTTP server), and supporting cloud integration (reqwest HTTP client to asciinema.org). Release automation present (release.yml). No visible PR data, but CHANGELOG.md likely tracks recent work.

🚀Get running

git clone https://github.com/asciinema/asciinema.git
cd asciinema
cargo build --release
./target/release/asciinema record my-session.cast
./target/release/asciinema play my-session.cast

Daily commands: Record a session: cargo run -- record my-session.cast (starts interactive recording, Ctrl+D or Ctrl+C stops). Play locally: cargo run -- play my-session.cast. Start live stream server: cargo run -- session --stream (built-in HTTP server on localhost:5000). Development: cargo test for unit tests, cargo check for lint, cargo clippy for style.

🗺️Map of the codebase

  • src/main.rs — Entry point for the CLI application; orchestrates command routing and initialization for all recording, playback, and streaming workflows.
  • src/session.rs — Core session management logic that handles PTY creation, event capture, and session lifecycle—essential for understanding how recordings are captured.
  • src/asciicast.rs — Asciicast file format parsing and serialization abstraction; supports v1, v2, v3 formats and determines how terminal data is persisted.
  • src/pty.rs — PTY abstraction layer wrapping OS-level terminal APIs; critical for capturing terminal I/O and handling platform-specific quirks.
  • src/encoder/mod.rs — Encoder interface and orchestration for converting raw PTY output into asciicast, raw, or txt formats during recording.
  • src/cmd/mod.rs — Command dispatcher module that routes CLI arguments to subcommands (record, play, convert, upload); primary abstraction for user-facing features.
  • Cargo.toml — Rust dependencies and project metadata; defines MSRV 1.82.0 and critical libs like nix for PTY, reqwest for API, and serde for serialization.

🛠️How to make changes

Add a new CLI command

  1. Define command arguments in the enum variant within src/cli.rs using #[command] attributes (src/cli.rs)
  2. Create a new handler module at src/cmd/yourcommand.rs with a public fn run() function (src/cmd/yourcommand.rs)
  3. Add a pub mod yourcommand; declaration and match arm in src/cmd/mod.rs dispatcher (src/cmd/mod.rs)
  4. Match the new command variant in src/main.rs and call cmd::yourcommand::run() (src/main.rs)

Support a new asciicast format version

  1. Create src/asciicast/v4.rs with Serialize/Deserialize impls for Header and Event structs (src/asciicast/v4.rs)
  2. Add parsing logic to detect version 4 and delegate in src/asciicast.rs read() method (src/asciicast.rs)
  3. Create an encoder variant in src/encoder/asciicast.rs if format is writable (src/encoder/asciicast.rs)
  4. Update Asciicast enum and version detection logic in src/asciicast.rs (src/asciicast.rs)

Add platform-specific PTY handling

  1. Create src/tty/yourplatform.rs with implementation of terminal control functions (src/tty/yourplatform.rs)
  2. Add cfg-gated module declaration in src/tty/mod.rs or src/tty/default.rs (src/tty/default.rs)
  3. Implement platform-specific logic in src/pty.rs by calling the new module conditionally (src/pty.rs)

Add a new file format encoder

  1. Create src/encoder/yourformat.rs with Encoder trait implementation (src/encoder/yourformat.rs)
  2. Add pub mod yourformat; and register in src/encoder/mod.rs factory (src/encoder/mod.rs)
  3. Add format variant to src/cmd/session.rs or src/cmd/convert.rs to support --format yourformat (src/cmd/session.rs)

🔧Why these technologies

  • Rust + nix crate — Provides zero-cost abstractions for PTY/terminal APIs; nix safely wraps platform-specific syscalls (openpty, ioctl) for macOS, Linux, etc.
  • serde + serde_json — Declarative (de)serialization of Asciicast JSON formats v1–v3; cleanly supports versioning and schema evolution without manual parsing.
  • reqwest (blocking + rustls-tls) — Synchronous HTTP client for API calls to asciinema.org; rustls provides TLS without system dependencies; multipart for file uploads.
  • clap (derive) — Type-safe CLI argument parsing; reduces boilerplate and auto-generates help text; aligns with modern Rust CLI conventions.
  • signal-hook — Safe signal handling (SIGWINCH for resize, SIGINT for interruption) without async; integrates with polling loop in session.rs.

⚖️Trade-offs already made

  • Synchronous event loop in session.rs using nix poll/select rather than async/tokio

    • Why: Simplifies PTY handling (PTY I/O is inherently blocking); avoids async runtime overhead; keeps code readable for shell integration.
    • Consequence: Single-threaded recording session; no concurrent command execution; adequate for typical use case (one shell per recording).
  • Three distinct asciicast format versions (v1 JSON, v2 NDJSON, v3 JSONL+binary) coexist in codebase

    • Why: Backward compatibility; gradual format evolution from text to compact binary; user choice for file size vs readability.
    • Consequence: More parser code; version detection logic; slight maintenance burden when adding features.
  • Encoder abstraction (trait) over format-specific writers

    • Why: Decouples recording session from output format; enables multiple formats (asciicast, raw, txt) without session changes.
    • Consequence: Indirection; potential for new format support via plugins (not yet implemented).
  • Split TTY platform overrides (default.rs

    • Why: undefined
    • Consequence: undefined

🪤Traps & gotchas

PTY/terminal integration: Recording relies on nix crate's PTY support—only works on supported platforms (Linux/macOS/FreeBSD). Test locally on your target OS. Signal handling: signal-hook and signal-hook-tokio manage Ctrl+C/SIGTERM during recording—custom logic in cmd/session.rs; don't assume standard Ctrl+C behavior. Format versioning: Three asciicast versions (v1/v2/v3) must coexist; conversion logic in cmd/convert.rs; changing v3 format is a breaking change. WebSocket streaming: Live streams use tokio-tungstenite; requires tokio runtime—standalone binaries won't work without #[tokio::main] wrapper. Config file parsing: config crate loads from ~/.config/asciinema/ or env vars (check src/config.rs for paths); missing config won't fail, but user flags override defaults unexpectedly. Embedded assets: Web player (asciinema-player.min.js) is vendored in assets/ and embedded at compile time—updates require recompilation.

🏗️Architecture

💡Concepts to learn

  • Asciicast Format (v1/v2/v3) — Understanding the core file format is essential for any recording/playback modification; v3 is current but v1/v2 compatibility code lives in src/asciicast/ and must be maintained
  • Pseudo-terminal (PTY) / PTY multiplexing — src/fd.rs and nix crate handle PTY allocation and I/O capture; understanding PTY semantics is critical for fixing recording/playback issues on different OSes
  • Tokio async runtime and event multiplexing — Core dependency for concurrent recording+streaming; forwarder.rs and cmd/session.rs use tokio channels for event distribution across multiple encoders
  • LEB128 variable-length integer encoding — src/leb128.rs implements compact encoding for timing deltas in asciicast files; key to achieving 8% file size compression versus raw format
  • WebSocket protocol (RFC 6455) — Live streaming feature uses tokio-tungstenite; required for real-time viewer participation in remote streams
  • ANSI escape sequences and terminal emulation — avt crate parses ANSI codes; understanding terminal color, cursor movement, and style sequences is needed for accurate replay and format conversion
  • Signal handling and process termination — signal-hook and signal-hook-tokio manage graceful shutdown during recording; critical for data integrity when user presses Ctrl+C or sends SIGTERM
  • asciinema/asciinema-player — Official web player JavaScript library that embeds asciinema recordings in HTML pages; consumed by assets/asciinema-player.min.js
  • asciinema/asciinema-server — Reference server implementation for hosting recordings; defines the API that src/api.rs communicates with
  • termtosvg/termtosvg — Alternative terminal recorder (Python) producing SVG instead of asciicast; competes on same use case with different output format
  • charmbracelet/vhs — Go-based terminal session recorder with GIF/MP4 output; overlapping problem domain but different execution model
  • rbspy/rbspy — Terminal recording tool for profiling; demonstrates Rust+nix+PTY pattern for system-level terminal introspection

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for asciicast format handlers (v1, v2, v3)

The repo has test data files (tests/casts/) but no visible unit tests for src/asciicast/v1.rs, src/asciicast/v2.rs, and src/asciicast/v3.rs. These are critical parsers for different asciicast versions. Adding tests would catch regressions in format compatibility, especially important given the migration from v1→v3.

  • [ ] Create tests/asciicast_v1.rs with tests for parsing tests/casts/full-v1.json
  • [ ] Create tests/asciicast_v2.rs with tests for parsing tests/casts/full-v2.cast
  • [ ] Create tests/asciicast_v3.rs with tests for parsing tests/casts/full-v3.cast
  • [ ] Add tests for version detection and format conversion in src/asciicast/util.rs
  • [ ] Verify all test data files parse correctly and validate schema compliance

Add GitHub Actions workflow for cross-platform build verification (macOS, Linux, Windows)

The repo has MSRV 1.82.0 and platform-specific code (src/tty/default.rs, src/tty/macos.rs, src/pty.rs using nix crate). Current CI (ci.yml) likely doesn't validate macOS and Windows builds. With Rust binary distribution needs, this is critical for catching platform-specific regressions.

  • [ ] Review existing .github/workflows/ci.yml for scope
  • [ ] Extend ci.yml to include matrix jobs for ubuntu-latest, macos-latest, windows-latest
  • [ ] Add cargo build --release for each platform
  • [ ] Add platform-specific feature tests (e.g., verify src/tty/macos.rs only compiles on macOS)
  • [ ] Test binary distribution targets (if applicable) like x86_64-unknown-linux-gnu, aarch64-apple-darwin, x86_64-pc-windows-msvc

Add integration tests for CLI commands with mock recordings

The repo has command modules (src/cmd/auth.rs, src/cmd/cat.rs, src/cmd/play.rs, src/cmd/upload.rs, src/cmd/session.rs) but no visible integration tests exercising the full CLI pipeline. This is essential for verifying end-to-end functionality like recording, playback, format conversion, and API interaction without breaking user workflows.

  • [ ] Create tests/integration_tests.rs with setup fixtures for temporary recordings
  • [ ] Add test for 'asciinema rec' command writing valid v3 cast file using src/encoder/asciicast.rs
  • [ ] Add test for 'asciinema play' command using src/player.rs with test cast files
  • [ ] Add test for 'asciinema convert' command testing src/encoder/raw.rs and src/encoder/txt.rs
  • [ ] Add test for 'asciinema cat' command with src/cmd/cat.rs against sample casts
  • [ ] Mock API calls in auth.rs and upload.rs to test server communication without network

🌿Good first issues

  • Add integration tests for asciicast v3 round-trip conversion (record → encode v3 → decode → verify frame-by-frame). Currently only src/asciicast/v3.rs exists with no test fixtures in tests/ directory.
  • Document the encoder trait and add examples in src/encoder/mod.rs showing how to implement a custom encoder (e.g., for SRT subtitles or CSV timeline export). Trait definition exists but no examples or RFC.
  • Add ANSI color palette preservation tests: verify that terminal color sequences in src/asciicast/v3.rs are correctly captured and replayed, especially for 256-color and truecolor modes (check against avt crate's capabilities).

Top contributors

Click to expand

📝Recent commits

Click to expand
  • ea64be7 — Temporarily disable autoplay in the README demo link (ku1ik)
  • d8bf39d — Improve features list in the README (ku1ik)
  • 5de65c0 — Replace qualified path with use (ku1ik)
  • 47565ba — Make const durations in forwarder actual Duration values (ku1ik)
  • 728a1fd — Add rustfmt to dev shell's cargo (ku1ik)
  • 202d5c5 — Update the changelog (ku1ik)
  • 1f970a3 — Upgrade player to the latest version (ku1ik)
  • 691fe89 — Bump version (ku1ik)
  • d278f44 — Update flake inputs (ku1ik)
  • 62e8e1e — Fix key binding parser (ku1ik)

🔒Security observations

The asciinema codebase demonstrates a generally sound security posture with appropriate use of secure dependencies (rustls-tls, no unsafe SQL patterns visible). Key strengths include use of Cargo.lock for reproducible builds, native TLS libraries, and a GPL-3.0 license indicating open-source transparency. Primary concerns are: (1) incomplete dependency list visibility preventing full vulnerability assessment, (2) reliance on system TLS certificate stores in containerized environments, and (3) potential security header gaps in web server functionality. The application handles user input (terminal sessions) which requires careful validation. No hardcoded secrets or obvious injection vulnerabilities were detected in the available code. Recommendations focus on running cargo audit, verifying TLS configuration in containers, and ensuring proper terminal input validation and security header implementation in web server code.

  • Medium · Incomplete Dependency List in Cargo.toml — Cargo.toml. The Cargo.toml file content provided is truncated at the signal-hook-tokio dependency. This makes it impossible to verify all dependencies for known vulnerabilities. The complete dependency list cannot be fully analyzed. Fix: Ensure the complete Cargo.toml is reviewed. Run 'cargo audit' to check for known vulnerabilities in all dependencies. Consider using cargo-deny for additional supply chain security.
  • Medium · Permissive TLS Configuration in Dependencies — Cargo.toml - reqwest and tokio-tungstenite dependencies. Multiple crates use 'native-roots' for TLS certificate verification (reqwest and tokio-tungstenite). While native-roots leverages system certificates, the reliance on system certificate stores could be a concern in containerized environments where the certificate store may be outdated or compromised. Fix: Verify that the Debian trixie-slim container includes up-to-date CA certificates. Consider using 'webpki-roots' as an alternative if predictable, vendored roots are preferred. Ensure regular container updates.
  • Low · Default Tokio Runtime Without Security Hardening — Cargo.toml - tokio dependency. The application uses tokio with multi-threaded runtime. While not inherently insecure, there are no visible security-focused runtime configurations (e.g., stack size limits, resource constraints) in the provided codebase. Fix: Review runtime initialization in src/main.rs to ensure appropriate resource limits are set. Consider configuring worker thread limits and memory constraints appropriate for the deployment environment.
  • Low · Missing SBOM/Dependency Lock Verification in Docker Build — Dockerfile. While Cargo.lock is present and used (--locked flag in build), the Docker build doesn't explicitly verify the integrity of the lock file or build artifacts. Fix: Consider implementing additional verification steps such as checksum validation or SBOM generation. Document the expected Cargo.lock hash in CI/CD pipelines.
  • Low · Broad File Mounting in Docker Build — Dockerfile - RUN mount directives. The Dockerfile mounts entire directories (src, assets) without restricting which files are accessible. This could potentially leak sensitive files if they were accidentally included in the source tree. Fix: Review .dockerignore to ensure sensitive files (private keys, tokens, etc.) are excluded. Consider using more restrictive mount paths if possible.
  • Low · No Explicit Security Headers Configuration Visible — src/server.rs (not fully reviewed). The application includes web server functionality (axum, tower-http) but no visible explicit security header configuration in the provided files. While tower-http includes trace and compression, other security headers may need configuration. Fix: Ensure all responses include appropriate security headers (X-Content-Type-Options, X-Frame-Options, Content-Security-Policy, etc.). Review server configuration code thoroughly.
  • Low · Terminal Input Handling Without Visible Sanitization — src/asciicast/, src/player.rs. The application records and replays terminal sessions. While the format is structured (asciicast v3), improper handling of terminal control sequences could potentially be exploited. Fix: Ensure all terminal input is properly validated and sanitized. Use the 'avt' library (already included) correctly to handle terminal sequences safely. Add unit tests for malformed input.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · asciinema/asciinema — RepoPilot