showrun-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- showrun_cli-0.1.0/.gitignore +8 -0
- showrun_cli-0.1.0/LICENSE +9 -0
- showrun_cli-0.1.0/PKG-INFO +247 -0
- showrun_cli-0.1.0/README.md +212 -0
- showrun_cli-0.1.0/docs/README.md +207 -0
- showrun_cli-0.1.0/examples/recorded.yaml +22 -0
- showrun_cli-0.1.0/examples/tour.yaml +66 -0
- showrun_cli-0.1.0/pyproject.toml +60 -0
- showrun_cli-0.1.0/src/showrun/__init__.py +6 -0
- showrun_cli-0.1.0/src/showrun/cast.py +86 -0
- showrun_cli-0.1.0/src/showrun/check.py +95 -0
- showrun_cli-0.1.0/src/showrun/cli.py +236 -0
- showrun_cli-0.1.0/src/showrun/export.py +50 -0
- showrun_cli-0.1.0/src/showrun/keys.py +149 -0
- showrun_cli-0.1.0/src/showrun/mcp_server.py +205 -0
- showrun_cli-0.1.0/src/showrun/model.py +203 -0
- showrun_cli-0.1.0/src/showrun/notes.py +96 -0
- showrun_cli-0.1.0/src/showrun/player.py +467 -0
- showrun_cli-0.1.0/src/showrun/record.py +163 -0
- showrun_cli-0.1.0/src/showrun/render.py +51 -0
- showrun_cli-0.1.0/src/showrun/shell.py +238 -0
- showrun_cli-0.1.0/src/showrun/starter.yaml +65 -0
- showrun_cli-0.1.0/tests/test_showrun.py +227 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anand Rao
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: showrun-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Scripted, keypress-driven terminal demos: record once, present with Enter, replay offline.
|
|
5
|
+
Project-URL: Homepage, https://showrun.clues.apps.clue2.app
|
|
6
|
+
Project-URL: Repository, https://github.com/honnuanand/showrun
|
|
7
|
+
Project-URL: Issues, https://github.com/honnuanand/showrun/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/honnuanand/showrun/tree/main/docs
|
|
9
|
+
Author-email: Anand Rao <anand@clue2solve.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: asciinema,cli,demo,demo-magic,live-coding,mcp,presentation,terminal
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
21
|
+
Classifier: Topic :: Terminals
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Requires-Dist: pexpect>=4.8
|
|
24
|
+
Requires-Dist: pydantic>=2
|
|
25
|
+
Requires-Dist: pyyaml>=6
|
|
26
|
+
Requires-Dist: rich>=13
|
|
27
|
+
Requires-Dist: typer>=0.9
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
31
|
+
Requires-Dist: twine; extra == 'dev'
|
|
32
|
+
Provides-Extra: mcp
|
|
33
|
+
Requires-Dist: mcp>=1.2; (python_version >= '3.10') and extra == 'mcp'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# showrun
|
|
37
|
+
|
|
38
|
+
[](https://github.com/honnuanand/showrun/actions/workflows/ci.yml)
|
|
39
|
+
[](https://github.com/honnuanand/showrun/actions/workflows/publish.yml)
|
|
40
|
+
[](https://pypi.org/p/showrun-cli)
|
|
41
|
+
[](https://pypi.org/p/showrun-cli)
|
|
42
|
+
[](https://github.com/honnuanand/showrun/blob/main/LICENSE)
|
|
43
|
+
|
|
44
|
+
Scripted, keypress-driven terminal demos. You write (or **record**) the demo once, then
|
|
45
|
+
present it by just hitting **Enter**: commands are typed out like a human would, run in a
|
|
46
|
+
real shell, and stream live output. Hidden setup, canned output, presenter notes, rehearsal,
|
|
47
|
+
offline playback and recordings are built in.
|
|
48
|
+
|
|
49
|
+
It's made for anyone who shows a command line to other people: conference talks, team demos,
|
|
50
|
+
and especially **how-tos for CLI tools**. Write the steps once, rehearse them in CI, present
|
|
51
|
+
them live, and publish the same file as a replay and a Markdown runbook.
|
|
52
|
+
|
|
53
|
+
**Website and live replays: [showrun.clues.apps.clue2.app](https://showrun.clues.apps.clue2.app)**
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install showrun-cli # the command is `showrun`
|
|
59
|
+
showrun init demo.yaml # starter demo that shows off every feature
|
|
60
|
+
showrun check demo.yaml # rehearse unattended
|
|
61
|
+
showrun play demo.yaml # present it
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Sample replays
|
|
65
|
+
|
|
66
|
+
Each of these is a YAML file in this repo, rendered with `showrun render`. The `.cast` files
|
|
67
|
+
play in [asciinema-player](https://github.com/asciinema/asciinema-player) or with
|
|
68
|
+
`showrun replay docs/casts/<name>.cast`.
|
|
69
|
+
|
|
70
|
+
| Demo | Replay |
|
|
71
|
+
|---|---|
|
|
72
|
+
| **How-to: undo your last git commit** ([`docs/demos/git-undo.yaml`](https://github.com/honnuanand/showrun/blob/main/docs/demos/git-undo.yaml)): narration, highlights, a real git repo set up silently | [GIF](https://raw.githubusercontent.com/honnuanand/showrun/main/docs/media/git-undo.gif) · [cast](https://github.com/honnuanand/showrun/blob/main/docs/casts/git-undo.cast) |
|
|
73
|
+
| **The feature tour** ([`examples/tour.yaml`](https://github.com/honnuanand/showrun/blob/main/examples/tour.yaml)): shared shell state, hidden steps, a background server with `wait_for`, canned output |  |
|
|
74
|
+
| **showrun rehearsing itself** ([`docs/demos/showrun-cli.yaml`](https://github.com/honnuanand/showrun/blob/main/docs/demos/showrun-cli.yaml)): `validate`, `check` and `export` |  |
|
|
75
|
+
| **Offline playback** ([`examples/recorded.yaml`](https://github.com/honnuanand/showrun/blob/main/examples/recorded.yaml) with `--offline`): recorded output, nothing executed |  |
|
|
76
|
+
|
|
77
|
+
The full guide, with every option and workflow, is in [docs/](https://github.com/honnuanand/showrun/blob/main/docs/README.md).
|
|
78
|
+
|
|
79
|
+
## Commands
|
|
80
|
+
|
|
81
|
+
| Command | What it does |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `showrun play demo.yaml` | Present. `--offline` replays recorded output, `--fallback` runs live but swaps in the recording if a step fails, `--auto 3` advances by itself, `--start 7`, `--speed 2`, `--cast talk.cast`, `-v port=9000` |
|
|
84
|
+
| `showrun record demo.yaml` | Do the demo once in a shell; every command and its output becomes a step |
|
|
85
|
+
| `showrun check demo.yaml` | Rehearsal: runs every step, checks exit codes and expected output, flags slow steps. Exit code 1 on failure, so it works in CI |
|
|
86
|
+
| `showrun notes demo.yaml` | Presenter view for a second terminal: current step, talking points, what's next, timer |
|
|
87
|
+
| `showrun render demo.yaml -o demo.cast` | Present unattended and save an asciinema cast, no terminal needed (`--offline`, `--delay 1.5`, `--width`, `--height`). Good for docs and CI |
|
|
88
|
+
| `showrun replay talk.cast` | Play back a recording (`--speed 2 --max-idle 1`). Casts also work with asciinema / asciinema-player |
|
|
89
|
+
| `showrun export demo.yaml -f md` | Markdown runbook (`-f sh` for a plain bash script) |
|
|
90
|
+
| `showrun validate demo.yaml` | Parse and list steps |
|
|
91
|
+
| `showrun mcp` | MCP server for AI agents (see below) |
|
|
92
|
+
|
|
93
|
+
## Keys while presenting
|
|
94
|
+
|
|
95
|
+
| Key | Action |
|
|
96
|
+
|---|---|
|
|
97
|
+
| Enter / Space / → | run the typed command, or continue |
|
|
98
|
+
| any key while typing | finish typing instantly |
|
|
99
|
+
| `s` | skip this step |
|
|
100
|
+
| `b` / ← | back one step |
|
|
101
|
+
| `r` | retype the command |
|
|
102
|
+
| `g` + number + Enter | jump to step N |
|
|
103
|
+
| `l` | list all steps |
|
|
104
|
+
| `i` | live shell in the same session (Ctrl-] returns to the demo) |
|
|
105
|
+
| `?` | help |
|
|
106
|
+
| `q` / Ctrl-C | quit (cleanup still runs) |
|
|
107
|
+
|
|
108
|
+
## Recording
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
showrun record kafka-demo.yaml
|
|
112
|
+
● rec ~/work $ #title Producing events
|
|
113
|
+
● rec ~/work $ #say Let's start the broker first
|
|
114
|
+
● rec ~/work $ #bg docker compose up kafka
|
|
115
|
+
● rec ~/work $ #wait nc -z localhost 9092
|
|
116
|
+
● rec ~/work $ kcat -b localhost:9092 -L
|
|
117
|
+
● rec ~/work $ #note mention partitions here
|
|
118
|
+
● rec ~/work $ ./produce.sh 100
|
|
119
|
+
● rec ~/work $ #done
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Directives: `#say`, `#title`, `#note` (attach to the next command), `#hide cmd`, `#bg cmd`,
|
|
123
|
+
`#wait cmd`, `#fake` (turn the last step into canned output), `#pause`, `#undo`, `#list`,
|
|
124
|
+
`#done`. The file is saved after every step, so nothing is lost if something crashes.
|
|
125
|
+
|
|
126
|
+
Each recorded step keeps its output in `recorded_output`, which gives you three ways to
|
|
127
|
+
present:
|
|
128
|
+
|
|
129
|
+
- `showrun play demo.yaml` runs everything live.
|
|
130
|
+
- `showrun play demo.yaml --offline` shows the recordings and runs nothing that has one
|
|
131
|
+
(background services and `wait_for` are skipped). It's for bad wifi or no cluster.
|
|
132
|
+
- `showrun play demo.yaml --fallback` runs live, but if a step fails, times out or misses
|
|
133
|
+
`expect_output`, it says so and shows the recorded run instead.
|
|
134
|
+
|
|
135
|
+
## Demo file reference
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
title: My demo
|
|
139
|
+
settings:
|
|
140
|
+
prompt: "[bold green]me@demo[/] [blue]{cwd}[/] $ " # Rich markup; {cwd} is live
|
|
141
|
+
typing_speed: 0.04 # s per char
|
|
142
|
+
jitter: 0.5 # timing randomness
|
|
143
|
+
typo_rate: 0.01 # occasional fake typo, corrected on screen
|
|
144
|
+
wait_before_typing: false
|
|
145
|
+
theme: monokai # syntax highlighting theme
|
|
146
|
+
timeout: 60 # default per-step timeout
|
|
147
|
+
shell: bash # or zsh
|
|
148
|
+
cwd: ./project # relative to the YAML file
|
|
149
|
+
env: {KUBECONFIG: ./kc}
|
|
150
|
+
vars: # {{name}}; override with -v name=x or SHOWRUN_VAR_NAME
|
|
151
|
+
ns: demo
|
|
152
|
+
setup: [kubectl create ns {{ns}}] # silent, before step 1
|
|
153
|
+
cleanup: [kubectl delete ns {{ns}}] # always runs
|
|
154
|
+
steps:
|
|
155
|
+
- kubectl get pods -n {{ns}} # plain string = run it
|
|
156
|
+
- run: export TOKEN=$(./get-token)
|
|
157
|
+
hidden: true # runs silently
|
|
158
|
+
- title: Deploying # section rule
|
|
159
|
+
say: Now we roll out v2 # narration shown as a comment
|
|
160
|
+
notes: Stress zero downtime # presenter view only
|
|
161
|
+
run: kubectl apply -f v2.yaml
|
|
162
|
+
highlight: ["configured", "created"] # regexes highlighted in output
|
|
163
|
+
expect_output: configured # checked by `check`, warned live
|
|
164
|
+
expect_exit: 0 # or "any"
|
|
165
|
+
timeout: 30
|
|
166
|
+
- run: ./server --port 8080
|
|
167
|
+
background: true
|
|
168
|
+
wait_for: curl -sf localhost:8080/health
|
|
169
|
+
wait_timeout: 30
|
|
170
|
+
- run: terraform apply # too slow to run on stage?
|
|
171
|
+
execute: false
|
|
172
|
+
output: "Apply complete! Resources: 3 added"
|
|
173
|
+
- run: cat big.json
|
|
174
|
+
type: false # appears instantly
|
|
175
|
+
speed: 0.01 # per-step typing speed
|
|
176
|
+
typos: false
|
|
177
|
+
clear: true # clear screen first
|
|
178
|
+
- pause: true # wait for Enter
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## How it works
|
|
182
|
+
|
|
183
|
+
- **One persistent shell** (`pexpect` on a pty) runs every step, so `cd`, `export` and
|
|
184
|
+
functions carry over. A unique marker after each command gives the exit code and tells
|
|
185
|
+
showrun when the command has finished, without guessing at prompts.
|
|
186
|
+
- **Rich** draws the prompt, the syntax-highlighted typing, highlights and the notes view.
|
|
187
|
+
- **Recordings** are plain asciinema v2 files with a marker at each step, written by
|
|
188
|
+
showrun itself, so asciinema doesn't need to be installed.
|
|
189
|
+
- **Background jobs** run inside the session, and their process trees are killed at the end.
|
|
190
|
+
|
|
191
|
+
## Limits
|
|
192
|
+
|
|
193
|
+
Full-screen apps (vim, top, k9s) don't stream well inside a step. Use `i` to drop into the
|
|
194
|
+
live shell for those. Commands that read from stdin need their input piped in.
|
|
195
|
+
|
|
196
|
+
## Use it from AI agents (MCP)
|
|
197
|
+
|
|
198
|
+
`showrun mcp` runs a [Model Context Protocol](https://modelcontextprotocol.io) server over
|
|
199
|
+
stdio, so an agent such as Claude Code, Claude Desktop or Cursor can write, rehearse and
|
|
200
|
+
render demos for you.
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
pip install 'showrun-cli[mcp]' # needs Python 3.10+
|
|
204
|
+
claude mcp add showrun -- showrun mcp # Claude Code
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
There's also a hosted, read-only server at `https://showrun.clues.apps.clue2.app/mcp`. It can explain the format, validate
|
|
208
|
+
and export demos, and never runs commands. Use it when you don't want to install anything:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
claude mcp add --transport http showrun https://showrun.clues.apps.clue2.app/mcp
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
For other clients, add the local server to the client's MCP config:
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{ "mcpServers": { "showrun": { "command": "showrun", "args": ["mcp"] } } }
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
| Tool | What it does |
|
|
221
|
+
|---|---|
|
|
222
|
+
| `demo_format`, `starter_demo` | The YAML format reference and a starter file to edit |
|
|
223
|
+
| `validate_demo` | Parse a demo (file or inline YAML) and list its steps |
|
|
224
|
+
| `write_demo` | Validate and save a demo; won't overwrite unless asked |
|
|
225
|
+
| `check_demo` | Rehearse: **runs** every command and reports failures |
|
|
226
|
+
| `export_demo` | Markdown runbook or bash script |
|
|
227
|
+
| `render_demo` | Present unattended into a `.cast` (**runs** commands unless `offline`) |
|
|
228
|
+
| `read_cast` | A `.cast` as plain text with step markers, so the agent can see the result |
|
|
229
|
+
|
|
230
|
+
The server also publishes the one-page guide as the resource `showrun://guide`. Ask your
|
|
231
|
+
agent something like *"write a showrun demo that shows how to use `jq` to filter JSON,
|
|
232
|
+
check it, and render it"*. `check_demo` and `render_demo` run shell commands on your
|
|
233
|
+
machine, so leave your client's tool approval on.
|
|
234
|
+
|
|
235
|
+
## Credits
|
|
236
|
+
|
|
237
|
+
showrun is inspired by [demo-magic](https://github.com/paxtonhare/demo-magic) by Paxton
|
|
238
|
+
Hare, the little bash script that types your commands for you while you talk. I've used
|
|
239
|
+
demo-magic for my own talks and demos for more than a decade, and showrun is my attempt at
|
|
240
|
+
the same idea with rehearsal, recording, offline playback and presenter notes built in.
|
|
241
|
+
Thank you, Paxton.
|
|
242
|
+
|
|
243
|
+
## Development
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
pip install -e '.[dev]' && pytest
|
|
247
|
+
```
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# showrun
|
|
2
|
+
|
|
3
|
+
[](https://github.com/honnuanand/showrun/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/honnuanand/showrun/actions/workflows/publish.yml)
|
|
5
|
+
[](https://pypi.org/p/showrun-cli)
|
|
6
|
+
[](https://pypi.org/p/showrun-cli)
|
|
7
|
+
[](https://github.com/honnuanand/showrun/blob/main/LICENSE)
|
|
8
|
+
|
|
9
|
+
Scripted, keypress-driven terminal demos. You write (or **record**) the demo once, then
|
|
10
|
+
present it by just hitting **Enter**: commands are typed out like a human would, run in a
|
|
11
|
+
real shell, and stream live output. Hidden setup, canned output, presenter notes, rehearsal,
|
|
12
|
+
offline playback and recordings are built in.
|
|
13
|
+
|
|
14
|
+
It's made for anyone who shows a command line to other people: conference talks, team demos,
|
|
15
|
+
and especially **how-tos for CLI tools**. Write the steps once, rehearse them in CI, present
|
|
16
|
+
them live, and publish the same file as a replay and a Markdown runbook.
|
|
17
|
+
|
|
18
|
+
**Website and live replays: [showrun.clues.apps.clue2.app](https://showrun.clues.apps.clue2.app)**
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install showrun-cli # the command is `showrun`
|
|
24
|
+
showrun init demo.yaml # starter demo that shows off every feature
|
|
25
|
+
showrun check demo.yaml # rehearse unattended
|
|
26
|
+
showrun play demo.yaml # present it
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Sample replays
|
|
30
|
+
|
|
31
|
+
Each of these is a YAML file in this repo, rendered with `showrun render`. The `.cast` files
|
|
32
|
+
play in [asciinema-player](https://github.com/asciinema/asciinema-player) or with
|
|
33
|
+
`showrun replay docs/casts/<name>.cast`.
|
|
34
|
+
|
|
35
|
+
| Demo | Replay |
|
|
36
|
+
|---|---|
|
|
37
|
+
| **How-to: undo your last git commit** ([`docs/demos/git-undo.yaml`](https://github.com/honnuanand/showrun/blob/main/docs/demos/git-undo.yaml)): narration, highlights, a real git repo set up silently | [GIF](https://raw.githubusercontent.com/honnuanand/showrun/main/docs/media/git-undo.gif) · [cast](https://github.com/honnuanand/showrun/blob/main/docs/casts/git-undo.cast) |
|
|
38
|
+
| **The feature tour** ([`examples/tour.yaml`](https://github.com/honnuanand/showrun/blob/main/examples/tour.yaml)): shared shell state, hidden steps, a background server with `wait_for`, canned output |  |
|
|
39
|
+
| **showrun rehearsing itself** ([`docs/demos/showrun-cli.yaml`](https://github.com/honnuanand/showrun/blob/main/docs/demos/showrun-cli.yaml)): `validate`, `check` and `export` |  |
|
|
40
|
+
| **Offline playback** ([`examples/recorded.yaml`](https://github.com/honnuanand/showrun/blob/main/examples/recorded.yaml) with `--offline`): recorded output, nothing executed |  |
|
|
41
|
+
|
|
42
|
+
The full guide, with every option and workflow, is in [docs/](https://github.com/honnuanand/showrun/blob/main/docs/README.md).
|
|
43
|
+
|
|
44
|
+
## Commands
|
|
45
|
+
|
|
46
|
+
| Command | What it does |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `showrun play demo.yaml` | Present. `--offline` replays recorded output, `--fallback` runs live but swaps in the recording if a step fails, `--auto 3` advances by itself, `--start 7`, `--speed 2`, `--cast talk.cast`, `-v port=9000` |
|
|
49
|
+
| `showrun record demo.yaml` | Do the demo once in a shell; every command and its output becomes a step |
|
|
50
|
+
| `showrun check demo.yaml` | Rehearsal: runs every step, checks exit codes and expected output, flags slow steps. Exit code 1 on failure, so it works in CI |
|
|
51
|
+
| `showrun notes demo.yaml` | Presenter view for a second terminal: current step, talking points, what's next, timer |
|
|
52
|
+
| `showrun render demo.yaml -o demo.cast` | Present unattended and save an asciinema cast, no terminal needed (`--offline`, `--delay 1.5`, `--width`, `--height`). Good for docs and CI |
|
|
53
|
+
| `showrun replay talk.cast` | Play back a recording (`--speed 2 --max-idle 1`). Casts also work with asciinema / asciinema-player |
|
|
54
|
+
| `showrun export demo.yaml -f md` | Markdown runbook (`-f sh` for a plain bash script) |
|
|
55
|
+
| `showrun validate demo.yaml` | Parse and list steps |
|
|
56
|
+
| `showrun mcp` | MCP server for AI agents (see below) |
|
|
57
|
+
|
|
58
|
+
## Keys while presenting
|
|
59
|
+
|
|
60
|
+
| Key | Action |
|
|
61
|
+
|---|---|
|
|
62
|
+
| Enter / Space / → | run the typed command, or continue |
|
|
63
|
+
| any key while typing | finish typing instantly |
|
|
64
|
+
| `s` | skip this step |
|
|
65
|
+
| `b` / ← | back one step |
|
|
66
|
+
| `r` | retype the command |
|
|
67
|
+
| `g` + number + Enter | jump to step N |
|
|
68
|
+
| `l` | list all steps |
|
|
69
|
+
| `i` | live shell in the same session (Ctrl-] returns to the demo) |
|
|
70
|
+
| `?` | help |
|
|
71
|
+
| `q` / Ctrl-C | quit (cleanup still runs) |
|
|
72
|
+
|
|
73
|
+
## Recording
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
showrun record kafka-demo.yaml
|
|
77
|
+
● rec ~/work $ #title Producing events
|
|
78
|
+
● rec ~/work $ #say Let's start the broker first
|
|
79
|
+
● rec ~/work $ #bg docker compose up kafka
|
|
80
|
+
● rec ~/work $ #wait nc -z localhost 9092
|
|
81
|
+
● rec ~/work $ kcat -b localhost:9092 -L
|
|
82
|
+
● rec ~/work $ #note mention partitions here
|
|
83
|
+
● rec ~/work $ ./produce.sh 100
|
|
84
|
+
● rec ~/work $ #done
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Directives: `#say`, `#title`, `#note` (attach to the next command), `#hide cmd`, `#bg cmd`,
|
|
88
|
+
`#wait cmd`, `#fake` (turn the last step into canned output), `#pause`, `#undo`, `#list`,
|
|
89
|
+
`#done`. The file is saved after every step, so nothing is lost if something crashes.
|
|
90
|
+
|
|
91
|
+
Each recorded step keeps its output in `recorded_output`, which gives you three ways to
|
|
92
|
+
present:
|
|
93
|
+
|
|
94
|
+
- `showrun play demo.yaml` runs everything live.
|
|
95
|
+
- `showrun play demo.yaml --offline` shows the recordings and runs nothing that has one
|
|
96
|
+
(background services and `wait_for` are skipped). It's for bad wifi or no cluster.
|
|
97
|
+
- `showrun play demo.yaml --fallback` runs live, but if a step fails, times out or misses
|
|
98
|
+
`expect_output`, it says so and shows the recorded run instead.
|
|
99
|
+
|
|
100
|
+
## Demo file reference
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
title: My demo
|
|
104
|
+
settings:
|
|
105
|
+
prompt: "[bold green]me@demo[/] [blue]{cwd}[/] $ " # Rich markup; {cwd} is live
|
|
106
|
+
typing_speed: 0.04 # s per char
|
|
107
|
+
jitter: 0.5 # timing randomness
|
|
108
|
+
typo_rate: 0.01 # occasional fake typo, corrected on screen
|
|
109
|
+
wait_before_typing: false
|
|
110
|
+
theme: monokai # syntax highlighting theme
|
|
111
|
+
timeout: 60 # default per-step timeout
|
|
112
|
+
shell: bash # or zsh
|
|
113
|
+
cwd: ./project # relative to the YAML file
|
|
114
|
+
env: {KUBECONFIG: ./kc}
|
|
115
|
+
vars: # {{name}}; override with -v name=x or SHOWRUN_VAR_NAME
|
|
116
|
+
ns: demo
|
|
117
|
+
setup: [kubectl create ns {{ns}}] # silent, before step 1
|
|
118
|
+
cleanup: [kubectl delete ns {{ns}}] # always runs
|
|
119
|
+
steps:
|
|
120
|
+
- kubectl get pods -n {{ns}} # plain string = run it
|
|
121
|
+
- run: export TOKEN=$(./get-token)
|
|
122
|
+
hidden: true # runs silently
|
|
123
|
+
- title: Deploying # section rule
|
|
124
|
+
say: Now we roll out v2 # narration shown as a comment
|
|
125
|
+
notes: Stress zero downtime # presenter view only
|
|
126
|
+
run: kubectl apply -f v2.yaml
|
|
127
|
+
highlight: ["configured", "created"] # regexes highlighted in output
|
|
128
|
+
expect_output: configured # checked by `check`, warned live
|
|
129
|
+
expect_exit: 0 # or "any"
|
|
130
|
+
timeout: 30
|
|
131
|
+
- run: ./server --port 8080
|
|
132
|
+
background: true
|
|
133
|
+
wait_for: curl -sf localhost:8080/health
|
|
134
|
+
wait_timeout: 30
|
|
135
|
+
- run: terraform apply # too slow to run on stage?
|
|
136
|
+
execute: false
|
|
137
|
+
output: "Apply complete! Resources: 3 added"
|
|
138
|
+
- run: cat big.json
|
|
139
|
+
type: false # appears instantly
|
|
140
|
+
speed: 0.01 # per-step typing speed
|
|
141
|
+
typos: false
|
|
142
|
+
clear: true # clear screen first
|
|
143
|
+
- pause: true # wait for Enter
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## How it works
|
|
147
|
+
|
|
148
|
+
- **One persistent shell** (`pexpect` on a pty) runs every step, so `cd`, `export` and
|
|
149
|
+
functions carry over. A unique marker after each command gives the exit code and tells
|
|
150
|
+
showrun when the command has finished, without guessing at prompts.
|
|
151
|
+
- **Rich** draws the prompt, the syntax-highlighted typing, highlights and the notes view.
|
|
152
|
+
- **Recordings** are plain asciinema v2 files with a marker at each step, written by
|
|
153
|
+
showrun itself, so asciinema doesn't need to be installed.
|
|
154
|
+
- **Background jobs** run inside the session, and their process trees are killed at the end.
|
|
155
|
+
|
|
156
|
+
## Limits
|
|
157
|
+
|
|
158
|
+
Full-screen apps (vim, top, k9s) don't stream well inside a step. Use `i` to drop into the
|
|
159
|
+
live shell for those. Commands that read from stdin need their input piped in.
|
|
160
|
+
|
|
161
|
+
## Use it from AI agents (MCP)
|
|
162
|
+
|
|
163
|
+
`showrun mcp` runs a [Model Context Protocol](https://modelcontextprotocol.io) server over
|
|
164
|
+
stdio, so an agent such as Claude Code, Claude Desktop or Cursor can write, rehearse and
|
|
165
|
+
render demos for you.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
pip install 'showrun-cli[mcp]' # needs Python 3.10+
|
|
169
|
+
claude mcp add showrun -- showrun mcp # Claude Code
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
There's also a hosted, read-only server at `https://showrun.clues.apps.clue2.app/mcp`. It can explain the format, validate
|
|
173
|
+
and export demos, and never runs commands. Use it when you don't want to install anything:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
claude mcp add --transport http showrun https://showrun.clues.apps.clue2.app/mcp
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
For other clients, add the local server to the client's MCP config:
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{ "mcpServers": { "showrun": { "command": "showrun", "args": ["mcp"] } } }
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
| Tool | What it does |
|
|
186
|
+
|---|---|
|
|
187
|
+
| `demo_format`, `starter_demo` | The YAML format reference and a starter file to edit |
|
|
188
|
+
| `validate_demo` | Parse a demo (file or inline YAML) and list its steps |
|
|
189
|
+
| `write_demo` | Validate and save a demo; won't overwrite unless asked |
|
|
190
|
+
| `check_demo` | Rehearse: **runs** every command and reports failures |
|
|
191
|
+
| `export_demo` | Markdown runbook or bash script |
|
|
192
|
+
| `render_demo` | Present unattended into a `.cast` (**runs** commands unless `offline`) |
|
|
193
|
+
| `read_cast` | A `.cast` as plain text with step markers, so the agent can see the result |
|
|
194
|
+
|
|
195
|
+
The server also publishes the one-page guide as the resource `showrun://guide`. Ask your
|
|
196
|
+
agent something like *"write a showrun demo that shows how to use `jq` to filter JSON,
|
|
197
|
+
check it, and render it"*. `check_demo` and `render_demo` run shell commands on your
|
|
198
|
+
machine, so leave your client's tool approval on.
|
|
199
|
+
|
|
200
|
+
## Credits
|
|
201
|
+
|
|
202
|
+
showrun is inspired by [demo-magic](https://github.com/paxtonhare/demo-magic) by Paxton
|
|
203
|
+
Hare, the little bash script that types your commands for you while you talk. I've used
|
|
204
|
+
demo-magic for my own talks and demos for more than a decade, and showrun is my attempt at
|
|
205
|
+
the same idea with rehearsal, recording, offline playback and presenter notes built in.
|
|
206
|
+
Thank you, Paxton.
|
|
207
|
+
|
|
208
|
+
## Development
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
pip install -e '.[dev]' && pytest
|
|
212
|
+
```
|