scenetake 1.4.0
dotnet tool install --global scenetake --version 1.4.0
dotnet new tool-manifest
dotnet tool install --local scenetake --version 1.4.0
#tool dotnet:?package=scenetake&version=1.4.0
nuke :add-package scenetake --version 1.4.0
scenetake
English | 日本語
Run a YAML scenario and record a terminal scene take asciinema v3 .cast, animated .svg. You do not need to install or launch asciinema to record. Write a YAML scenario with steps, and this tool executes those steps and records the output as .cast (and optionally .svg)—ordinary steps get simulated typing; steps with pty: true capture the terminal stream in real time.
Sample scenario samples/basic.yaml generates .cast and .svg output like below. You don't have to struggle with typing, and since the commands are actually executed, you can easily create realistic terminal recordings.
title: "Basic Demo"
width: 80
height: 24
shell: bash
settings:
prompt: "$ "
typing-speed: 0.02 # average seconds per keystroke
typing-jitter: 0.01 # random variance (±) per keystroke
pre-delay: 0.4 # pause before typing starts
post-delay: 1.0 # pause after output before next step
steps:
- echo "Hello, World!"
- name: Name of the step
run: echo "Current directory:"
- name: Coloring stdout
run: curl -I https://google.com
highlight:
- color: green
at:
- "1"
- color: gray
at:
- "2-12"
- echo "Wait for 2 seconds..."
- run: sleep 2
execution-duration: 1.0
- echo "stderr output is red by default" 1>&2
- echo "Done!"
| GIF | SVG |
|---|---|
SVG output supports custom font, light/dark theme, and optional window chrome (macos / windows).
| macOS | Windows |
|---|---|
What you can do
| I want to… | How |
|---|---|
| Record a terminal demo from a list of commands (no live typing) | Write a YAML scenario, then scenetake scenario.yaml |
| Get an animated SVG for a README or docs | scenetake --format svg scenario.yaml |
Convert an existing asciinema .cast to SVG |
scenetake svg recording.cast |
| Tune font, theme, or window chrome | Set render in YAML, or pass --font-size, --font-family, --theme, --window |
| Color output when CLI tools stay plain without a TTY | Use highlight, run-highlight, or stderr-color on steps — see samples/highlight.yaml |
Record TTY-dependent commands (matrix, terminal animations, etc.) |
pty: true on a step — see samples/pty.yaml or Limitations (scenario recording) |
Record fully interactive sessions (vim, REPLs, user input) |
pty: true + interactive: true on a step — see samples/interactive-pty.yaml (requires a real host terminal) |
| Scaffold a starter scenario | scenetake init |
| Browse examples and previews | samples/README.md |
| Read full behavior specs | .github/docs/spec_index.md |
Motivation
I want terminal demos without the hassle of typing commands into asciinema. That is the motivation behind scenetake. There are various tools in the asciinema ecosystem, but none quite fit: some lean heavily on shell scripts, some require asciinema itself as a dependency, some leak execution paths into the cast output, and some only fake the output rather than running real commands. What I want is something where I can write a scenario plainly, have the listed commands actually executed, and get a cast file generated directly from the real output.
scenetake is a cross-platform tool that records those scenarios as .cast files, optionally with .svg, without going through asciinema at all.
- Write the commands to run in the scenario.
- For ordinary steps, generate cast events as if the commands were typed at a steady pace; for
pty: truesteps, record the terminal byte stream as it runs. - Execute the commands for real and write their output into the cast.
Quick Start
Download the asset for your OS from GitHub Releases, then place scenetake (or scenetake.exe on Windows) where you want.
# .NET global tool (.NET 10 SDK required; .NET 10 runtime required to run)
dotnet tool install -g scenetake
# npm
npm install -g scenetake
# Windows (Scoop)
scoop bucket add guitarrapc https://github.com/guitarrapc/scoop-bucket
scoop install scenetake
# On macOS/Linux, add execute permission if needed.
chmod +x ./scenetake
# Create a starter scenario file in the current directory
scenetake init
# Run the scenario to generate a cast file
scenetake scenario.yaml
# Generate cast and animated SVG in one command
scenetake --format svg scenario.yaml
# SVG styling: font, theme, window chrome, frame cap
scenetake --format svg scenario.yaml --font-size 20 --font-family "'Noto Sans Mono', ui-monospace" --theme light --window macos
# Convert an existing cast file to SVG (v2 or v3)
scenetake svg scenario.cast
# Same styling flags work on the svg subcommand
scenetake svg scenario.cast --theme light --window windows --max-fps 30
# Show normal pre/post execution logs while generating a cast file
scenetake --verbose scenario.yaml
# Play with asciinema
asciinema play scenario.cast
# Convert to gif with agg (Linux/macOS) — requires agg 1.6.0+ for v3 cast files
docker run --rm -v "${PWD}:/data" ghcr.io/asciinema/agg /data/scenario.cast /data/scenario.gif --font-size 20 --last-frame-duration 0
# Convert to gif with agg (Windows PowerShell)
docker run --rm -v "$($PWD.Path):/data" ghcr.io/asciinema/agg /data/scenario.cast /data/scenario.gif --font-size 20 --last-frame-duration 0
Usage
# Initialize a new scenario file
scenetake init [scenario.yaml]
# Run scenario to generate cast (default) or cast + SVG
scenetake [--verbose] [--format cast|svg]
[--font-size N] [--font-family FAMILIES] [--theme dark|light]
[--window none|macos|windows] [--max-fps N]
scenario.yaml [output]
# Convert an existing cast file to SVG
scenetake svg [--font-size N] [--font-family FAMILIES] [--theme dark|light]
[--window none|macos|windows] [--max-fps N]
<input.cast> [output.svg]
--max-fps caps SVG animation frame rate (0 = off, use full cast timing). It applies when --format svg is set or on the svg subcommand.
Notes
shell:- Linux/macOS default shell is
$SHELL, withbashas fallback. - Windows default shell is
pwsh, withpowershellas fallback. On Windows,shell: bashuses Git Bash / MSYSbashwhen available.
- Linux/macOS default shell is
settingsprovides defaults for prompt and timing.rendercontrols cast header display metadata (st:font-sizetag,term.theme) and SVG output. See .github/docs/spec_cast.md and .github/docs/spec_svg.md.pre/postrun setup and teardown commands outside the recording flow. Their stdout/stderr are printed to the CLI, but are never written to the cast file.steps:- Steps are executed for real, so use caution with commands that modify files or affect external systems.
- Commands that need a terminal can opt into pseudo-terminal capture with
pty: true. See Limitations (scenario recording). - For long-running commands, use
execution-durationto keep playback readable. - For natural replay of long output (
docker build, stagedsleep, …), setstream-output: trueand optionallymax-durationon that step. Default pipe emit stays instant for typing and short demos.
Limitations (scenario recording)
Scenario recording normally runs commands without a PTY and captures each command's output in one batch after it finishes. For terminal-aware commands, use map-form steps with pty: true; the PTY size comes from scenario width / height.
steps:
- run: matrix --duration 5
pty: true
pty: true is intended for terminal UI commands and real-time terminal animations. It records the terminal stream directly, so stdout and stderr are not separated and stderr-color does not apply to that step. For interactive sessions where you operate the TUI on the host terminal (for example vim or a banner demo), add interactive: true on the same step — see samples/interactive-pty.yaml and spec_pty.md → Interactive PTY.
Scenario Format
Only steps is required; all other top-level keys are optional. The example below is a runnable scenario — source of truth: samples/scenario_format.yaml. For full field definitions see .github/docs/spec_scenario.md. Coloring and style syntax: spec_highlight.md. Pre/post behavior: spec_pre_post.md. More color examples: samples/highlight.yaml.
# Scenario format reference — runnable demo (samples/scenario_format.yaml).
# Required: steps only. Everything else is optional.
title: "Scenario Format Demo" # Optional cast title
width: 80 # Default: 120
height: 24 # Default: 24
# cwd: /your/project # Optional working directory for all commands
shell: bash # bash | pwsh | powershell | path. Windows: Git Bash when bash
render: # Optional display metadata for cast header and SVG
font-size: 16
font-family: ui-monospace, monospace
theme:
preset: dark # dark | light; optional fg / bg / palette overrides
window: macos # none | macos | windows
settings: # Defaults for all steps; map-form steps can override per key
prompt: "$ "
typing-speed: 0.04 # Average seconds per typed character
typing-jitter: 0.01 # Random variance (+/- seconds) per character
pre-delay: 0.5 # Pause before typing each step
post-delay: 1.0 # Pause after output before the next step
execution-duration: 0.1 # Cast wait after command execution
stderr-color: red # When stderr has no ANSI SGR sequences
# stream-output: false # When true, replay captured chunk times in the cast
# max-duration: 15 # Cap step output timeline; also enables stream emit
# silence-threshold: 2.0 # Stream mode: collapse idle gaps longer than this (seconds)
# max-idle: 0.2 # Stream mode: collapsed idle gap duration (seconds)
# Optional setup; runs before steps, not recorded in cast
pre:
- echo "environment check (not recorded)"
steps:
# String form - uses settings defaults
- echo "Hello, World!"
# Map form - comment line, per-step timing
- name: "[cyan]Project status"
run: printf 'name\tversion\nscenetake\t1.0\n'
post-delay: 1.5
- name: "Per-step timing overrides"
run: printf 'typing slowly...\n'
typing-speed: 0.12
pre-delay: 0.8
post-delay: 1.2
- name: "execution-duration"
run: sleep 1
execution-duration: 0.5
- name: "instant emit (ping, one blob)"
run: bash -c 'case "$(uname -s)" in MINGW*|MSYS*|CYGWIN*) ping -n 4 127.0.0.1 ;; *) ping -c 4 127.0.0.1 ;; esac'
execution-duration: 0.2
- name: "stream-output (ping, staggered replay)"
run: bash -c 'case "$(uname -s)" in MINGW*|MSYS*|CYGWIN*) ping -n 4 127.0.0.1 ;; *) ping -c 4 127.0.0.1 ;; esac'
stream-output: true
silence-threshold: 2.0
max-idle: 0.2
- name: "pty demo"
run: echo "This command runs in a PTY, so output appears immediately and can include interactive features like colors and progress bars."
pty: true
- name: "run-highlight colors the typed command"
run: printf 'done\n'
run-highlight: bright-cyan
- name: "stdout highlight"
run: printf 'line1 alpha\nline2 beta gamma\nline3\n'
highlight:
- color: yellow
at: "1"
- color: red
at: "2:7-10"
- color: bright-cyan
at: "2:12-"
- color: underline fg:bright-white bg:blue
at: "3"
- name: "stderr (default red)"
run: echo "plain stderr" 1>&2
- name: "stderr-color override"
run: echo "bright yellow stderr" 1>&2
stderr-color: bright-yellow
- echo "Done!"
# Optional teardown; runs after cast is written, not recorded
post:
- echo "demo complete (not recorded)"
Development
Use dotnet for local development, debugging, or publishing.
- .NET 10 SDK (file-based C# app)
# Local run
dotnet run scenetake.cs -- <scenario.yaml> [output.cast]
dotnet run scenetake.cs -- svg <scenario.cast> [output.svg]
# build
dotnet publish scenetake.cs --self-contained true -p:PublishAot=true -p:StripSymbols=true -p:DebugType=None
See samples/README.md for each scenario’s purpose and preview (GIF / SVG).
Regenerate samples cast/svg files:
dotnet run samples/regenerate.cs
foreach ($file in Get-ChildItem samples/*.cast) {
docker run --rm -v "$($PWD.Path):/data" ghcr.io/asciinema/agg /data/samples/$($file.BaseName).cast /data/samples/$($file.BaseName).gif --last-frame-duration 0
}
Release
Before tagging, bump Directory.Build.props and all npm packages under npm/packages/ together. The script uses the latest v* git tag as the base version (falls back to the current files when no tags exist).
dotnet run scripts/set_version.cs -- patch # e.g. v1.3.0 -> 1.3.1
dotnet run scripts/set_version.cs -- minor # e.g. v1.3.0 -> 1.4.0
dotnet run scripts/set_version.cs -- major # e.g. v1.3.0 -> 2.0.0
Commit the version bump, then create and push a tag matching the new version (for example v1.4.0). Pushing the tag starts the release workflow, which builds native binaries, creates a GitHub Release, and stages npm packages (scenetake plus @scenetake/* platform binaries).
After the workflow finishes, approve the staged npm packages locally with 2FA:
npm stage list @scenetake
npm stage list scenetake
npm stage approve <stage-id>
The first npm release must be published manually (npm publish), because staged publishing requires the package to already exist on the registry. Platform packages (@scenetake/linux-x64, etc.) must be approved before the main scenetake package.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.4.0 | 82 | 7/6/2026 |