A presentation app that loads structured asset directories as topics and panels, rendered in the terminal.
Requires Rust. Install via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shBuild the app:
make buildPass the path to your assets directory:
Build and install the application:
make installThen run it with the included demo assets:
present assets/demoRun a second, small window showing the current panel's speaker notes — open it in a second terminal window and drag that window to your other display:
present --notes assets/demoIt mirrors whatever topic/panel is live in the main window (updating
within a fraction of a second) and shows that panel's notes.md
content. Press q in the notes window to quit it independently of the
main presentation.
assets/
01-topic-name/ # Topics load in numeric order
01/ # Panels load in numeric order within a topic
text.md
02/
prompt.md
03/
diagram.md
02-another-topic/
...
Each panel directory (01, 02, …) may contain one or more asset files. A panel can mix types — e.g. a text.md and a prompt.md together.
Markdown rendered in the panel. Use for talking points, explanations, or any content you want visible on screen.
# Section Title
Key point one.
Key point two.The first heading becomes the panel label.
A prompt ready to fire at Claude during the presentation. Displayed in the lower portion of the screen. Move the cursor with j/k and toggle individual lines into a selection with c (each gets a green ✓ highlight). Press s to stage — if you've selected lines it sends all of them joined together, otherwise it sends just the line under the cursor. Staging starts a countdown, giving you time to switch to Claude, then the content is automatically typed into an iTerm2 session via AppleScript. If iTerm2 is not available it falls back to copying to the clipboard for manual paste (⌘V).
The first heading becomes the label shown in the UI; everything after it is the prompt text sent to Claude.
# Prompt label shown in UI
Actual prompt text sent to Claude.
Ask it something specific here.A Mermaid diagram rendered visually in the panel.
graph TD
A[Start] --> B[Process]
B --> C[End]A scattered word cloud rendered in the panel. When paired with a text.md in the same panel, the text is shown on top and the word cloud below.
---
size: large
---
# Rust Concepts
ownership
borrowing
lifetimesThe first heading becomes the cloud's title; each remaining non-blank line becomes one word. The optional ----delimited front matter accepts a size of small, medium (default), or large.
Speaker notes for this panel, shown only in the --notes second-monitor window (see Presenter notes on a second monitor) — never on the main audience-facing screen.
Slow down here. Make eye contact before advancing.| Key | Action |
|---|---|
l / Space / ↓ |
Next panel |
h / ↑ |
Previous panel |
→ / ← |
Next / previous topic |
j / k |
Move prompt cursor down / up |
c |
Toggle-select the prompt line under the cursor |
s |
Stage send — selected lines if any, else the cursor line — starts countdown, then auto-types into iTerm2 or copies to clipboard |
S |
Stage send — all lines in the prompt |
C |
Copy the panel's text file path to the clipboard |
R |
Reset to the start |
? |
Toggle help |
q |
Quit |
| Key | Action |
|---|---|
V |
Open the panel's markdown files in nvim, as horizontal splits (text.md on top, the rest alphabetically below), cwd'd into the assets dir |
H |
Move the current panel earlier — swaps its directory number with the previous panel's. No-op on the first panel |
L |
Move the current panel later — swaps its directory number with the next panel's. No-op on the last panel |
If the assets dir is inside a git repo, V, H, and L each commit their own change automatically once done — scoped to only the panel folder(s) involved, never the whole repo. V commits whatever nvim left changed in the panel's directory (a no-op if nothing changed). H/L commit the two swapped panel directories together; git's own rename detection will show these as renames as long as the two panels don't share an identical filename (e.g. both having their own text.md with different content shows as two modifications instead, which is a git limitation, not a bug).
