tui-cap
v0.5.3
Published
Capture terminal output as editable SVG, PNG, and MP4 assets
Maintainers
Readme
tui-cap
Turn GitHub Copilot CLI (or any terminal program) into a clean, editable, brand-correct image, video, or react component.
tui-cap records a terminal session and turns it into an SVG with real, editable text — the
exact GitHub colors, ready to drop straight into Figma or Illustrator for slides, docs, and
marketing shots. It can also export a PNG, timed MP4, or a React component animation of
the whole session.
Screenshots give you the look but flatten everything to pixels. Copy/paste gives you the text but
throws the colors away. tui-cap keeps both.
What you need
- macOS.
- Node.js 24 or newer. To check, open Terminal and run:
node --version
If you see v24 (or higher), you're set. If the command isn't found or the number is lower, install
the LTS version from nodejs.org — download the macOS installer and
double-click it, no terminal needed. 3. (Only to record the Copilot CLI) the copilot command,
installed and signed in. Everything else works without it.
That's the entire setup. There's nothing to compile and no other tools to install.
Install
Install it once so the tui-cap command is always available:
npm install -g tui-capCheck it worked:
tui-cap --helpStay current automatically. Every time you open the app,
tui-capchecks npm for a newer release. When one is available, a banner appears at the top with an Update now button — one click upgrades you in place and restarts the app on the new version. Prefer the terminal? Runtui-cap update. Either way, any app still running an older version is stopped so it can't open in place of the new one.
The rest of this guide writes commands as
tui-cap …. If you didn't install globally, just putnpxin front, e.g.npx tui-cap record ….
Quick start — capture the Copilot CLI
1. Record a session. This launches the Copilot CLI inside a recorder:
tui-cap record -- copilotEach recording is named automatically (copilot-capture_01.ans, copilot-capture_02.ans, …). Use
Copilot normally — type a prompt, let it answer. When you're happy, quit Copilot (e.g. /exit,
or press Ctrl+C) to stop recording.
2. The app opens automatically. When recording stops, tui-cap opens a small app in your
browser showing your recording.
3. Pick a frame and export. Scrub the timeline to the moment you want, tweak the look if you like (window title, size, spacing), then click:
- Save SVG… — editable text + colors, perfect for Figma/Illustrator.
- Save PNG… — a flat image at 1×–4× size.
- Export MP4… — a timed video of the whole session.
- Create shareable link… — publish an interactive player (real text that plays back and scrolls) to a private GitHub Pages site and get a link to share. It appears below the Transcript panel's Export React… button once sharing is set up — see Shareable links.
Your recording and exports are saved in a captures folder in your home directory
(~/captures). That's it.
While paused with Edit content off, drag across the preview's text and press ⌘C to copy it, preserving line breaks and spacing between text runs. Text selection is disabled during playback and content editing; exports are unchanged.
Want to record something other than Copilot? Put any command after
--, e.g.tui-cap record -- git log --oneline.
Commands
Run tui-cap --help (or tui-cap <command> --help) any time for the full list.
| Command | What it does |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| tui-cap record -- <command> | Record a live terminal session (e.g. copilot) to a capture file, then open the app to review and export it. Add -o <file> to choose the name. |
| tui-cap gui | Open the app to browse your captures, pick frames, tweak the look, and export SVG / PNG / MP4. |
| tui-cap render <file.ans> | Turn a capture into an editable SVG straight from the command line (no app). |
| tui-cap asciinema <file.cast> | Turn an existing asciinema recording into an SVG. |
| tui-cap transcript <file.ans> | Print the full, edited transcript of a Copilot session (--json for blocks, --svg -o out.svg for an image). |
| tui-cap export-react <file.ans> | Export the interactive React component (--inline for one file, -o <dir>, --theme, --title). |
| tui-cap update | Update to the latest version from the public npm registry. |
| tui-cap --version | Print the installed version. |
Handy options
record
-o <file>— name for the capture. Omit it and recordings are auto-numbered (copilot-capture_01.ans,_02, …) in your captures folder.--no-gui— don't auto-open the app when recording finishes.
gui
--port <n>— pick a port (default4787; it auto-picks the next free one).--no-open— start the server but don't open a browser; just print the URL.
render
-o <file.svg>— output path (defaults to your captures folder).--theme <name>—default,github,github-light,dim,high-contrast,colorblind,brand, orbrand-light(defaults to the recording's saved theme, thengithub).--title "<text>"— the window title bar text (default "GitHub Copilot CLI").--no-chrome— drop the window frame / title bar.--no-outline— drop the 1px border outline around the window (also onexport-react).--list-frames— list the frames in a capture so you can pick one with--frame <n>.--layout <name>— render at a saved size layout or anyCOLSxROWS(see Size layouts); also ontranscriptandexport-react.
asciinema
--at <seconds>— render the frame at that time (default: the end).
Using the app (GUI)
tui-cap gui opens a local app (it runs only on your machine) that turns your captures folder into
a visual library:
- Browse captures — every recording, newest first; it refreshes on its own when a new recording
lands. Long filenames stay on one line with an ellipsis; hover a title to see its full name.
Resize the library using its divider; in narrow panels, actions move below the title. Right-click
a recording for Duplicate (copies it with its edits and settings as
name-2,name-3, … so you can keep versions), Rename, Reveal in Finder, and Delete. - Scrub the timeline — drag through the session and watch the big preview update; play it back with the space bar. Select frames by clicking, shift-clicking, right-dragging a marquee, or ⌘A for all; the Speed slider then retimes just those frames (Esc clears the selection). Right-click a frame (or a selection) to delete or restore it. ⌘Z / ⇧⌘Z undo and redo.
- Tweak the look — switch the recorded Copilot content and window chrome between the Copilot CLI themes, GitHub light/dark, and OctoCap Brand light/dark; the selection is saved per recording and used by SVG, PNG, and MP4 exports. Window title, window style (macOS / Windows), show/hide the window frame, font size, and line spacing also update the preview live.
- Edit the content (non-destructively) — recolor, bold, or rewrite text right on the canvas, or add/remove blank lines for spacing. Your edits follow the text across every frame and never change the original recording. Playback waits for pending edits to save; accepting an edit refreshes canvas sizing without rebuilding the entire timeline. Stationary text edits also persist when a separate status field on the same row changes, provided the selected text and its adjacent context stay unchanged. Press Esc to exit edit mode and cancel any unaccepted text or styling changes.
- Edit the whole transcript — for Copilot CLI recordings, the Transcript panel lists every block of the session (your prompt, thinking, tool calls, Copilot's messages) exactly as the CLI drew it — glyphs, colors and all — rebuilt from the recording even though most of it scrolled out of view. Click a block to jump to it; as you scrub or play, the list follows along, centering the current block and outlining the ones on screen. Remove a block, or edit it (pencil or double-click) in a rich editor that opens on the block's recorded text and colors: select text to recolor, highlight, bold, italicize, or turn it into a code chip; insert the CLI's bullets, arrows, tree lines, and check marks; and swap the block's marker glyph and color — each from a compact dropdown that shows the current choice. Entrance sets how the new text arrives: stream it at the session's natural pace or your own speed (chars/s, with the resulting length shown), or make it appear instantly. That length holds at any playback speed or idle cap. A live preview shows exactly how it will render, and ▶ Play entrance plays the entrance once at the chosen timing. Everything after an edited block re-flows and scrolls like the CLI would, removed blocks take no screen time, and the rest of an edited block's original streaming time is trimmed. Undo/redo works as usual.
- Change the size after recording — see Size layouts below.
- Resize the panels — drag the gutters beside the library and the settings/transcript panel (double-click to reset) to give the transcript more room.
- Export — Save SVG, Save PNG (1×–4×), Export a timed MP4, save the whole edited transcript as one tall Transcript SVG, or Export React… (below).
Size layouts (desktop and mobile cuts)
A Copilot CLI recording can be laid out again at another terminal size after it was captured — for example a wide Desktop cut and a tall, narrow Mobile cut of the same session. In the sidebar's Layout section, + Add a layout (pick an aspect-ratio preset or type columns × rows, and name it), then switch between layouts and Recorded size from the menu; Edit renames, resizes, or deletes one. Every layout is drawn from the same capture, edits, and timing — nothing is re-recorded and the recording itself is never changed.
At a new size tui-cap redraws each frame the way the CLI would have drawn it in a terminal that size:
- transcript text re-wraps with the CLI's rules (code blocks, lists, and tool output keep their shape), and the transcript stays complete — everything that scrolled by is still there;
- the tab bar stays pinned at the top, the prompt box, status line, and footer at the bottom, and the scrollbar on the right, with its thumb recomputed for the new transcript length;
- open menus (slash commands,
@files, pickers, and dialogs) are laid out again above the prompt; - frames stay one-for-one with the recording, so frame speeds, skips, and holds still apply.
Exports — SVG, PNG, MP4, the transcript SVG, Export React…, and shareable links — use the layout picked in the sidebar (each layout gets its own share link). While you edit content, the preview shows the recorded size; your edits carry over to every layout. Frames whose layout tui-cap couldn't fully work out (an unfamiliar dialog, say) are laid out best-effort; the ≈ N frames laid out approximately badge lists them, and clicking it steps through them.
From the command line, render, transcript, and export-react use the recording's active layout,
or take --layout <name> (a saved layout's name, any COLSxROWS such as 50x40, or recorded):
tui-cap render shot.ans --layout 50x40 # writes shot-50x40.svg
tui-cap export-react shot.ans --layout mobile # writes shot-mobile-react/Resizing while you record. Recorded with --backend pty (see Tips), a
session also follows terminal resizes: the CLI redraws at each new size and tui-cap logs where, then
plays every stretch back at one size so the whole recording reads as a single session. (macOS's
built-in script recorder keeps the program at its starting size, so tui-cap tells you to use
--backend pty if you resize mid-recording.)
Good to know. A layout is a careful re-creation, not a re-recording, so a few things are approximate:
- Text the CLI cut short at record time (a long file path or menu description ending in
…) can't be restored at a wider size, and the CLI's own shortening of long@paths isn't copied. - Very narrow sizes can clip the exit summary and the status line; spacing edits in the header or footer don't carry over to other layouts.
- Full-screen dialogs (such as
/model) and other frames tui-cap can't fully interpret are laid out best-effort and counted in the approximate badge. - Recordings made with older versions of the CLI are laid out frame by frame, so they're always approximate.
Interactive React component (for web pages)
Export React… writes a small, self-contained React component to your Downloads folder
(<name>-react/; tui-cap export-react <capture.ans> writes it next to the capture, or to -o).
On a web page it plays the edited recording with your timeline's timing — as real, selectable text,
not video — and once it finishes, visitors can scroll back through the transcript just like a live
CLI session, line by line (no smooth scrolling between lines). Choose either a shared player plus a
lazily loaded data file (best for pages with several recordings) or a single .tsx file. The dialog
reports each file's size; Preview player shows exactly what the component will do. The component
uses the theme, title, cursor, and window style (macOS or Windows, active or inactive, or no chrome)
you picked in the editor, at the size layout picked in the sidebar — its scroll-back holds the whole
transcript re-wrapped at that layout's width.
The preview's Width slider and numeric pixel field let you try precise sizes. Rendered reports the player's actual width × height in CSS pixels, including available-width limits.
It's built for marketing pages: the player is about 5.5 KB (minified + gzipped), a multi-minute
session is typically 20–35 KB of gzipped data, playback pauses when off-screen, there's no layout
shift, and it respects reduced-motion settings. See the generated README.md for props.
MP4 export needs a modern browser with a built-in H.264 encoder — Chrome, Edge, or Safari 16.4+. (Firefox can't export MP4 yet.) SVG and PNG export work everywhere. The video is made entirely on your machine — nothing is uploaded.
Shareable links
Create shareable link… publishes the interactive player to the github/tui-cap repo's private
GitHub Pages site, so anyone with access to the repo can open the link. The button (and Shared
links in the top bar) only appears when tui-cap can confirm you have write access to that
repo. To set it up:
Ask for write access to
github/tui-capif you don't have it.Install the GitHub CLI (
brew install gh) and sign in:gh auth loginIf you're prompted to authorize the
githuborganization's SSO, accept. (Being signed in to Copilot or to github.com in your browser isn't enough — tui-cap reads its credentials from the GitHub CLI.)Restart the app (
tui-cap gui).
Prefer a token? Set GH_TOKEN (or GITHUB_TOKEN) to a personal access token with the repo scope,
SSO-authorized for the github organization. It's used instead of the GitHub CLI login.
Shared links lists every link on the site, not just yours — and each row can be renamed or deleted, so take care with links other people published.
Where your files are saved
Everything lands in one captures folder so shots don't scatter across whatever project you recorded from:
- By default that's
~/captures(created automatically). - Bare filenames (
-o my-shot.ans) and outputs go there. - Want a specific location? Pass a path with a slash (
-o ./shot.ansor-o /tmp/shot.ans) and it's written there instead. - Prefer a different default folder? Set the
GHCP_CAPTURE_DIRenvironment variable.
Exports from the app default to your Downloads folder: the save dialogs for SVG, PNG, MP4, and
the transcript SVG open there, and Export React… writes its <name>-react/ folder there (set
GHCP_EXPORT_DIR to use another folder).
render also looks in the captures folder, so record -o shot.ans -- copilot followed by
render shot.ans works from any directory.
Tips & troubleshooting
command not found: copilot— install and sign in to the Copilot CLI first, then try therecordcommand again.- My recording only shows the shell prompt. Full-screen tools (like Copilot) wipe their screen
when they exit.
tui-caphandles this for you — it keeps the live frame by default. Use the app's timeline, orrender … --list-framesand--frame <n>, to pick a different moment. - The "Do you trust this folder?" prompt. Answer it inside the recorded session (it's part of Copilot's startup), then continue.
- MP4 export is greyed out. Open the app in Chrome, Edge, or Safari 16.4+ (see above).
- A capture keystroke cursor / typing effect (advanced). The optional
--backend ptyrecords keystrokes for a typing-cursor effect. It needs the optional nativenode-ptypackage and is intended for people running from a source checkout; the default recorder already captures timing for MP4 export. It's also the backend that captures terminal resizes on macOS. If it fails withposix_spawnp failed, make node-pty's helper executable:chmod +x node_modules/node-pty/prebuilds/*/spawn-helper.
How it works (the short version)
The colors never actually leave the terminal — your clipboard strips them. The escape codes for
color, bold, italic, and underline are right there in the bytes the program prints. tui-cap:
- Records the raw output through a real terminal, so the program behaves exactly as it would for you.
- Replays it through the same engine that powers xterm.js, snapshotting the screen so it recovers real frames (important for full-screen tools that repaint constantly).
- Draws each frame as an SVG where every run of same-styled text is genuine, editable
<text>with an exact hex color.
For the full architecture, timing model, Figma details, and contributor docs, see DEVELOPMENT.md.
License
MIT © GitHub Brand & Marketing Design
Contributions and development setup: see DEVELOPMENT.md.
