reshoot 0.3.0__py3-none-any.whl

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.
Files changed (50) hide show
  1. reshoot/__init__.py +1 -0
  2. reshoot/artifacts.py +55 -0
  3. reshoot/browser.py +280 -0
  4. reshoot/bundled_skills/README.md +98 -0
  5. reshoot/bundled_skills/check-privacy/SKILL.md +72 -0
  6. reshoot/bundled_skills/cut-video/SKILL.md +77 -0
  7. reshoot/bundled_skills/keep-current/SKILL.md +41 -0
  8. reshoot/bundled_skills/plan-demo/SKILL.md +66 -0
  9. reshoot/bundled_skills/record-terminal/SKILL.md +50 -0
  10. reshoot/bundled_skills/record-terminal/template.tape +25 -0
  11. reshoot/bundled_skills/record-web/SKILL.md +159 -0
  12. reshoot/bundled_skills/record-window/SKILL.md +45 -0
  13. reshoot/bundled_skills/reshoot-demo/SKILL.md +28 -0
  14. reshoot/bundled_skills/reshoot-demo/agents/openai.yaml +4 -0
  15. reshoot/bundled_skills/reshoot-refresh/SKILL.md +22 -0
  16. reshoot/bundled_skills/reshoot-refresh/agents/openai.yaml +4 -0
  17. reshoot/bundled_skills/reshoot-review/SKILL.md +25 -0
  18. reshoot/bundled_skills/reshoot-review/agents/openai.yaml +4 -0
  19. reshoot/check.py +326 -0
  20. reshoot/cli.py +127 -0
  21. reshoot/config.py +83 -0
  22. reshoot/cut.py +371 -0
  23. reshoot/overlay.js +247 -0
  24. reshoot/project.py +92 -0
  25. reshoot/rec.js +88 -0
  26. reshoot/rec.py +181 -0
  27. reshoot/review.py +223 -0
  28. reshoot/run.py +286 -0
  29. reshoot/safety.py +28 -0
  30. reshoot/scan.py +133 -0
  31. reshoot/skills.py +26 -0
  32. reshoot/story.py +86 -0
  33. reshoot/templates/BRIEF.md +22 -0
  34. reshoot/templates/about.html +23 -0
  35. reshoot/templates/edit.py +9 -0
  36. reshoot/templates/edit.toml +13 -0
  37. reshoot/templates/index.html +61 -0
  38. reshoot/templates/reshoot.toml +15 -0
  39. reshoot/templates/storyboard.py +9 -0
  40. reshoot/templates/storyboard.toml +49 -0
  41. reshoot/timeline.py +244 -0
  42. reshoot/voice.py +70 -0
  43. reshoot/web.py +359 -0
  44. reshoot/window.py +57 -0
  45. reshoot/zoom.py +292 -0
  46. reshoot-0.3.0.dist-info/METADATA +268 -0
  47. reshoot-0.3.0.dist-info/RECORD +50 -0
  48. reshoot-0.3.0.dist-info/WHEEL +4 -0
  49. reshoot-0.3.0.dist-info/entry_points.txt +2 -0
  50. reshoot-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: plan-demo
3
+ description: Start here to make a demo video of software (a web app, a CLI, an AI agent such as Claude Code, a desktop app). Plans the takes and writes the storyboard, then hands off to record-web, record-terminal, record-window, check-privacy, cut-video and keep-current. Use when someone asks for a demo video, launch video, screencast, product tour or GIF of their app.
4
+ ---
5
+
6
+ # Plan a demo video
7
+
8
+ Keep a recipe for every take so the video can be shot again when the app changes.
9
+ Use browser storyboards, VHS tapes or app-specific native automation. For a
10
+ native app without automation, coordinate manual interaction during one-window
11
+ capture and save the steps; disclose that replay is manual.
12
+
13
+ ## Rules
14
+
15
+ - Never record the whole screen. Record a headless browser page, a VHS terminal, or one window by its id.
16
+ - Use demo data only, never the person's real data. If there is no demo data yet, making it is the first job.
17
+ - Nothing is posted, pushed or shared without the person's yes. The finished files stay local.
18
+
19
+ ## Steps
20
+
21
+ 1. **Ask what the video is for** if it isn't clear: where it will be posted (X, LinkedIn, a README, a talk), how
22
+ long (30 to 60 seconds suits social posts), and the 3 to 6 things it should show.
23
+ 2. **Pick a take for each part:**
24
+
25
+ | What's shown | Take | Skill |
26
+ |---|---|---|
27
+ | A web page or web app | headless Chrome from a storyboard | record-web |
28
+ | A terminal, a CLI, an AI agent | a VHS tape | record-terminal |
29
+ | A desktop app | one window, by its id (macOS) | record-window |
30
+
31
+ Match the take to the actual target. Use a browser for a web app, VHS for a
32
+ CLI, and one-window capture for a native app. Do not substitute a mock web
33
+ page for the native app the owner asked to show.
34
+ 3. **Set up demo data.** A separate database, data folder or account with only things anyone may see. Check that the
35
+ app can point at it (an environment variable, a flag) and that it can't touch real data during a take. Good demo
36
+ data has made-up people (emails at `example.com`), no real customers or colleagues, test keys only, photos
37
+ without people, and enough varied items to look real. If the app needs a login, make a demo account.
38
+ 4. **Write the storyboard** as beats. Each beat is one action and a hold. For each section of the video:
39
+ - a caption that says what the app does, in plain words, at most about 8 words, with an optional small line;
40
+ - the action (type, click, open a view);
41
+ - for a web take, what has to happen before recording (logging in, clearing old state) and which views load
42
+ slowly (maps, charts, big images);
43
+ - a hold long enough to read: about 1.5 s for a short caption, 2.5 s or more for a result.
44
+ Name the beats. The cut uses beat names to trim and to make one GIF per section.
45
+ 5. **Record each take** with its skill, then **check it** with check-privacy, then **cut** with cut-video.
46
+ 6. **Show the person the finished files** and the list of what was checked. They watch it all before it goes
47
+ anywhere.
48
+ 7. **Offer to keep it current** with the keep-current skill for browser/VHS projects: a `reshoot.toml` for `reshoot run`, and a workflow
49
+ that reshoots on each release. Keep native capture/edit scripts separately and compare recordings manually.
50
+
51
+ ## Files to keep in the project
52
+
53
+ Put the storyboards, tapes and edit script in the project (for example `tools/demo/`), and the takes and cuts in a
54
+ git-ignored folder (for example `takes/`). Write a short README there with the commands in order, so the next
55
+ reshoot is quick. This plugin's guide (`../../guide/` from this skill's folder) explains each step and lists the
56
+ pitfalls, and `../../examples/notes/` has a full example to copy from.
57
+
58
+ ## Install
59
+
60
+ The skills run the `reshoot` command. If it's missing: `uv tool install 'reshoot[browser]'`. It
61
+ also needs ffmpeg, VHS for terminal takes, and Chrome or Chromium for web takes. On macOS: `brew install ffmpeg vhs`.
62
+ On Linux, use the package manager.
63
+
64
+ ## Project setup
65
+
66
+ For browser/VHS projects, run `reshoot doctor --config reshoot.toml` when a project exists. For a new browser project, `reshoot init demo --url URL` supplies packaged templates without a source checkout. Fill in `BRIEF.md`, replace the placeholder action, then use `reshoot preview demo/reshoot.toml` before a full `run`. Versioned project outputs are isolated per run. Use standalone capture and editing for native windows.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: record-terminal
3
+ description: Record a terminal take with VHS, such as a CLI or an AI agent like Claude Code doing a task, with a clean shell that shows nothing private. Use for the terminal part of a demo video.
4
+ ---
5
+
6
+ # Record a terminal take
7
+
8
+ VHS (`brew install vhs`) plays a tape file in its own terminal and writes a video. Nothing outside that terminal can
9
+ show. `template.tape` next to this file is a starting point; `../../examples/notes/terminal.tape` is a full example.
10
+
11
+ ## Steps
12
+
13
+ 1. Copy `template.tape` into the project and set `Output`, the size and the commands.
14
+ 2. Do the setup inside `Hide` ... `Show`: start a clean shell, `cd` to a demo folder, remove what the last take left
15
+ behind, `clear`.
16
+ 3. Record: `vhs tools/demo/cli.tape`.
17
+ 4. Find where it finished: `reshoot last-change takes/cli.mp4` prints the time of the last real change. Cut there.
18
+ 5. Look at the last frame and a few in the middle before going on.
19
+
20
+ ## A clean shell
21
+
22
+ The shell must not show the person's name, machine, folders, history, prompt theme or any key:
23
+
24
+ ```
25
+ Type "env -i HOME=/tmp/demo PATH=/usr/bin:/bin:/opt/homebrew/bin TERM=xterm-256color LANG=en_US.UTF-8 PS1='~/demo $ ' bash --noprofile --norc" Enter
26
+ ```
27
+
28
+ Add only the variables the command needs. Never pass an API key on a typed line: it shows in the video.
29
+
30
+ ## AI agent takes
31
+
32
+ These notes are for Claude Code. Other agents need the same care: their own config, a demo folder, few tools.
33
+
34
+ - Run Claude from its own config folder, so the banner and settings show nothing of the person's: log in once with
35
+ `CLAUDE_CONFIG_DIR=~/.claude-demo claude`, with the account that should appear.
36
+ - Start it in a demo folder under `/tmp`: the banner shows the folder.
37
+ - Give it only the tools the take needs: `--mcp-config demo.json --strict-mcp-config --allowedTools ...`.
38
+ - Claude's time varies from run to run. Use a long fixed `Sleep` (longer than its slowest run) and cut at
39
+ `reshoot last-change`. Speed the working part up in the cut, with a label like "8x speed".
40
+ - Read the agent's answer in the take. It may describe or name things that need checking too.
41
+
42
+ ## Pitfalls
43
+
44
+ - **Never use `Wait`.** When a `Wait` times out, VHS throws away the whole recording. Use `Sleep` and cut afterwards.
45
+ - **Quotes in typed text.** Wrap a `Type` string that has double quotes in backticks: ``Type `say "hi"` ``.
46
+ - **Leftovers from the last take** change what the next one shows. Clean up in the hidden setup.
47
+ - **Typing time.** The typed part lasts about the number of characters times `TypingSpeed`. Use that to find where
48
+ the typing ends, if the cut needs it.
49
+ - **Two things driving the same app.** If the take drives an app (a desktop app, a database), don't touch that app
50
+ from anywhere else while it runs. Some apps stall when two scripts drive them at once.
@@ -0,0 +1,25 @@
1
+ # A VHS tape. Record it with: vhs this.tape
2
+ Output "takes/cli.mp4"
3
+ Set Shell "bash"
4
+ Set FontSize 22
5
+ Set Width 1280
6
+ Set Height 720
7
+ Set Padding 28
8
+ Set TypingSpeed 55ms
9
+ Set Theme "Catppuccin Mocha"
10
+
11
+ # Setup, not recorded: a clean shell with nothing private in it, in a demo folder, with the last take's files gone.
12
+ Hide
13
+ Type "env -i HOME=/tmp/demo PATH=/usr/bin:/bin:/opt/homebrew/bin TERM=xterm-256color LANG=en_US.UTF-8 PS1='~/demo $ ' bash --noprofile --norc" Enter
14
+ Type "mkdir -p ~ && cd ~ && clear" Enter
15
+ Sleep 500ms
16
+ Show
17
+
18
+ Sleep 1s
19
+ Type "echo hello"
20
+ Sleep 400ms
21
+ Enter
22
+
23
+ # A fixed Sleep, never a Wait: when a Wait times out, VHS throws away the whole recording.
24
+ # Make it longer than the slowest run, then cut at `reshoot last-change takes/cli.mp4`.
25
+ Sleep 3s
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: record-web
3
+ description: Record a web page or web app acting out a storyboard in headless Chrome, with a moving cursor, typing and captions, using `reshoot web`. Use for the browser part of a demo video, including phone-sized layouts.
4
+ ---
5
+
6
+ # Record a web take
7
+
8
+ The overlay keeps the current caption and cursor position across full page loads on the same origin. Inspect the saved result frames after navigation as well as the action frames.
9
+
10
+ `reshoot web STORYBOARD.py OUT.mp4` opens the page in headless Chrome, plays the beats, and writes:
11
+
12
+ - `OUT.mp4`: 60 fps, at the page size times the pixel ratio (1280x720@1.5 gives 1920x1080);
13
+ - `OUT.beats.json`: when each beat starts, for cutting;
14
+ - `OUT.assets.json`: every image and media URL the page loaded, for check-privacy;
15
+ - `OUT.events.json`: each action and caption, with where and when.
16
+
17
+ Only the page is captured, so nothing else on the screen can show.
18
+
19
+ ## The storyboard
20
+
21
+ A Python file. `../../examples/notes/storyboard.py` from this skill's folder is a full one.
22
+
23
+ ```python
24
+ URL = "http://localhost:8000/"
25
+ SIZE = "1280x720@1.5" # CSS width x height @ pixel ratio
26
+ THEME = "dark" # prefers-color-scheme
27
+ SETUP = [ # run before recording: log in, clear what the last take left
28
+ ("login", "await __demo.type('#email', 'demo@example.com'); await __demo.type('#password', 'demo'); __demo.key('Enter')", 1),
29
+ ]
30
+ WARM = ["#map"] # views to open before recording, so their data is loaded
31
+ ASSETS = ["/uploads/"] # optional: only list URLs containing these
32
+ ZOOM = True # zoom in on clicks and typing; or {"scale": 1.8, "quiet": 4.0, ...} (see below)
33
+ BLUR = [".avatar"] # blurred on every page for the whole take
34
+ VOICE = {"home": "Notes keeps your lists in one place."} # a voiceover: a line as each named beat starts
35
+ BEATS = [
36
+ ("home", "__demo.caption('Find any note', 'works offline')", 2.0),
37
+ ("type", "__demo.caption(null); await __demo.type('#q', 'bikes')", 0.4),
38
+ ("search", "await __demo.click('#go'); await __demo.waitFor('#results li')", 2.5),
39
+ ("end", "__demo.caption('Notes', 'open source'); __demo.hide()", 2.5),
40
+ ]
41
+ ```
42
+
43
+ Each beat is (name, JavaScript, seconds to hold after it). The JavaScript runs in the page inside an async function.
44
+ `__demo` has:
45
+
46
+ | Call | Does |
47
+ |---|---|
48
+ | `await __demo.click(sel)` | glides the cursor there and clicks, with a ripple |
49
+ | `await __demo.type(sel, text, {clear: true})` | clicks the field and types at a person's pace |
50
+ | `__demo.key("Enter")` | presses a key; Enter submits the form |
51
+ | `await __demo.waitFor(sel or fn, ms)` | waits until something appears |
52
+ | `await __demo.scroll(dy, {sel})` | scrolls smoothly |
53
+ | `await __demo.to(sel)` / `moveTo(x, y)` | moves the cursor without clicking |
54
+ | `__demo.caption(text, small)` / `caption(null)` | shows or hides a caption |
55
+ | `__demo.hide()` / `show()` | hides or shows the cursor |
56
+ | `__demo.blur(sel, {px})` / `unblur(sel)` | blurs everything matching sel (12 px), including what the page adds later |
57
+ | `__demo.byText(tag, text)` | the element whose words are text, such as `byText("button", "Save")`; pass it to `click` |
58
+ | `__demo.zoom(sel, {scale})` / `zoomOut()` | with `ZOOM` on: zooms in on sel until `zoomOut()`, over the automatic zoom |
59
+
60
+ A beat may also call the app's own functions, or set `location.hash`, when that's simpler than clicking.
61
+
62
+ ## Zoom on clicks
63
+
64
+ With `ZOOM = True` (or `--zoom`), the view moves in on what's being clicked or typed. It's worked out after
65
+ recording, from where each action happened and from the frames, so it starts just before a click and lands as the
66
+ click happens. The view moves only when it has to, since zooming out and back in for nothing is distracting:
67
+
68
+ | Next thing | What the view does |
69
+ |---|---|
70
+ | An action already in view, after any pause (up to `quiet`) | stays |
71
+ | An action just out of view, if a wider view still enlarges 1.2x or more | widens to take it in |
72
+ | An action far away | moves out, then in on the new place |
73
+ | Nothing for `quiet` seconds, or a new caption | moves out |
74
+ | Something sizeable changes outside the view (a new list item, a new page) | moves out once the action under way is done (just before, for a new page) and stays out for `show` seconds |
75
+
76
+ Small changes, like the text caret, the cursor and a click's ripple, don't count as changes. A target already as
77
+ wide as the page isn't zoomed, so phone layouts mostly stay as they are.
78
+
79
+ - Settings: `scale` (1.8) is the most it enlarges, `lead` (0.7 s) how early it starts, `hold` (1.0 s) how long it
80
+ stays after the last action, `quiet` (4 s) how long a pause ends a zoom, `show` (1 s) how long it stays out to
81
+ show a change, and `watch` (on) whether it looks at the frames for changes.
82
+ - The page is recorded at up to twice its pixel ratio, so zoomed text stays sharp.
83
+ - Captions are drawn after the zoom, so they stay put. They're plain text there: tags such as `<i>` are dropped.
84
+ - It takes longer: about 2.5 times the length of the take, against about 1.5 without zoom.
85
+
86
+ ## Voiceover
87
+
88
+ `VOICE = {beat name: words}` adds a voiceover. Each line is spoken before recording, so reshoot knows how long it
89
+ takes, and its beat waits until the line is done: a voiceover never runs into the next beat. The clips go in
90
+ `OUT.voice/`, and `OUT.voice.json` says when each starts in the take. The cut adds them (cut-video).
91
+
92
+ - The voice is macOS's `say` by default, or `espeak-ng` on Linux. `VOICE_ENGINE = "say -v Samantha"` picks a macOS
93
+ voice. Any other text-to-speech is a command with `{out}` for the sound file and the text on stdin, such as
94
+ `VOICE_ENGINE = "python3 tools/demo/tts.py {out}"`; that command handles any service key itself.
95
+ - Lines are spoken again only when their words or the engine change.
96
+ - Keep lines short and plain, one per beat that needs it. The captions still say the main point on screen, since
97
+ most people watch muted.
98
+ - `../../examples/notes/voiced.py` is the notes example with a voiceover.
99
+
100
+ A beat can follow a link to a new page. The overlay is added to every page, the cursor keeps its place, and the hold
101
+ starts once the new page has loaded. Code after the click in the same beat doesn't run, since its page is gone, so
102
+ put it in the next beat.
103
+
104
+ ## Steps
105
+
106
+ 1. Start the app on demo data, on its own port.
107
+ 2. Get a first storyboard, one of two ways:
108
+ - **The person clicks through it:** `reshoot rec http://localhost:8000/ tools/demo/storyboard.py` opens Chrome
109
+ with a fresh profile. They click and type through what the video should show and close the window, and it
110
+ writes the beats. Ask them to do this when the flow is long or the selectors are hard to find.
111
+ - **You write it:** read the app's HTML for the selectors. Prefer test ids, ids and names.
112
+ 3. Finish the storyboard: add captions, check the holds, and give the beats names the cut can use. Try a beat at a
113
+ time: put the beats so far in the file and record a short take.
114
+ 4. Record: `reshoot web tools/demo/storyboard.py takes/web.mp4`. Each beat prints how long it took. A beat that
115
+ fails stops the take and names the beat.
116
+ 5. Look at frames, not only the log: `ffmpeg -ss 5 -i takes/web.mp4 -frames:v 1 frame.png`, at several times.
117
+ 6. For phones: `--size 390x844@3 --mobile`, or `SIZE` and `MOBILE = True` in a second storyboard.
118
+
119
+ ## Pitfalls
120
+
121
+ - **Waiting for results.** A fixed hold that's fine on one run is too short on the next. After a click that loads
122
+ something, `await __demo.waitFor(...)` before the hold.
123
+ - **Blank maps and images when first shown.** Each take starts with a fresh browser profile, so nothing is cached.
124
+ List those views in `WARM`.
125
+ - **Something private on every page,** like the account name in a header: put it in `BLUR`, rather than hoping
126
+ each take avoids it.
127
+ - **Logged out.** The fresh profile has no cookies. Log in with a demo account in `SETUP`. Never point reshoot at
128
+ someone's own browser profile.
129
+ - **Phone sizes.** Headless Chrome won't make a window under 500 px. reshoot sets the size with device metrics
130
+ instead, and prints a note if the page's `innerWidth` isn't the width asked for.
131
+ - **Frameworks ignore typed text.** React and others watch the field's value setter. `__demo.type` uses it; setting
132
+ `el.value` yourself in a beat may not update the app.
133
+ - **Random content.** A view that picks items at random shows different things in each take. Every take needs its own
134
+ check, not just the first.
135
+ - **The last frame.** Chrome sends no frames while the page is still. reshoot holds each frame until the next, and
136
+ the last until recording stops, so the end card gets its full time.
137
+ - **Zooming hides a result.** A result that appears outside the view is normally caught by watching the frames.
138
+ One that's small (a short line of text, a little icon) may not count as a change. Call `__demo.zoomOut()` in the
139
+ beat that shows it.
140
+ - **Zooming in and out too often.** Usually a long hold in a recorded storyboard: a pause spent finding the next
141
+ button. If the next action is far away, shorten that hold. Or raise `quiet`.
142
+ - **A recorded storyboard is a draft.** `reshoot rec` turns a password into a placeholder, skips ids that look made
143
+ up by a framework, and finds a button by its words when it can. Read the selectors anyway: one that matches only
144
+ by its place in the page breaks first when the page changes.
145
+ - **Page errors** are printed at the end. Fix them: they often mean a beat ran before the page was ready.
146
+
147
+ Browser commands, navigation, beats, and the recording have timeouts. Unexpected page errors fail the take. A new take without `VOICE` removes the old narration metadata.
148
+
149
+ For a quick whole-project take use `reshoot preview reshoot.toml`; it uses a smaller output and faster encoding. Captured JPEGs are spooled to temporary disk files. Versioned projects keep each run separate, including its narration metadata.
150
+
151
+ ## Native input and TOML stories
152
+
153
+ For new takes, use a schema-version-1 TOML storyboard with named `[[beat]]` entries, `[[beat.action]]` operations and `[[beat.expect]]` results. `reshoot init DIR` supplies a complete notes example. Install the `browser` extra. TOML targets use `css`, `test_id`, or `role` with an optional `name` and `frame`. Actions use native input and fail on covered, disabled, missing, or ambiguous controls. Never force a click to bypass a broken demo. A `.take.json` records each expected result and screenshot. Python storyboards still use the legacy overlay input and cannot claim the same native-input checks.
154
+
155
+ `reshoot preview CONFIG --from BEAT` replays earlier actions without capture, then records the selected part. Partial previews skip editing and checking and never replace a final run. Captions wrap to fit the frame; keep copy short enough to read. Narration cache files are keyed by text and engine command and can be reused across isolated runs.
156
+
157
+ TOML stories can set `[caption]` position, safe margin, minimum seconds, font,
158
+ background, and foreground. Inspect a recorded frame near the bottom as well as a
159
+ browser screenshot; they use different capture paths.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: record-window
3
+ description: Record one window of a macOS desktop app (never the whole screen) with `reshoot window`, for the parts of a demo video that only a native app can show.
4
+ ---
5
+
6
+ # Record one app window
7
+
8
+ Use this for a native macOS app, with or without its source code. Capture one
9
+ demo window and keep the recipe for the next take.
10
+
11
+ ## Rules
12
+
13
+ - **Never capture the whole screen.** A full-screen capture shows mail, messages, calendars and notifications. Always
14
+ record one window by its id. `reshoot window` does nothing else.
15
+ - The app must show demo data only. Open the demo account, folder or document first.
16
+
17
+ ## Steps
18
+
19
+ 1. The app running the command needs Screen Recording permission once: System Settings, Privacy & Security, Screen
20
+ Recording. Add the terminal or editor, then restart it.
21
+ 2. Open the app on demo data, with the window on screen and not minimized. Get it to the state to show.
22
+ 3. `reshoot window --list` shows the windows: id, app, title. Check the right one is there.
23
+ 4. Record: `reshoot window TextEdit takes/app.mov --id ID -s 8`. Replace `ID` with the selected numeric ID and use a new output path for each take.
24
+ 5. Look at a frame: `ffmpeg -ss 3 -i takes/app.mov -frames:v 1 frame.png`. Check the sidebar and title bar too:
25
+ they often show names.
26
+
27
+ The command captures the window; it does not drive the app or add browser typing,
28
+ cursor effects, captions or assertions. Use app-specific automation or coordinate
29
+ manual input during capture. Save that script or procedure with the edit.
30
+ Export standalone media using numeric cuts; versioned web/VHS projects do not
31
+ support native takes. Compare native recordings manually.
32
+
33
+ ## In the cut
34
+
35
+ The recording includes the window's shadow on a dark background. `cut.window_clip(mov, bg_png, x, y, out,
36
+ width=1200)` crops it to the window, rounds the corners to match the window's own, and places it on a card. A square
37
+ crop alone shows the dark background at each corner, which stands out on a light card. `cut.window_box(mov)` and
38
+ `cut.corner_radius(mov)` give the measurements, if you need them for something else.
39
+
40
+ ## Pitfalls
41
+
42
+ - "could not create image from window" means the permission is missing, or the window isn't on screen.
43
+ - An app driven by a script (AppleScript, a take running at the same time) can stall. Let the other script finish
44
+ before recording.
45
+ - Windows move between runs. The id changes each time the app restarts, so look it up each take.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: reshoot-demo
3
+ description: Create a repeatable software demo with reshoot from an app and demo data. Use for product demos, release videos, README clips, and launch recordings.
4
+ ---
5
+
6
+ # Create a demo
7
+
8
+ Requires reshoot CLI 0.2 or newer. Run `reshoot --version` and `reshoot doctor --config CONFIG` for an existing project. If the CLI is missing, use the repository's documented installation; do not invent commands for a different version.
9
+
10
+ Resolve missing required tools before recording. If `RESHOOT_CHROME` is set, it must name an executable browser; correct or unset a stale path. A successful doctor check does not probe capture or the final scan.
11
+
12
+ Identify the target: app source, a running web URL, or an installed native macOS app. Source code is optional. Inspect code and demo fixtures when available; otherwise inspect the actual page or window. Choose one useful task with a visible result, audience and destination. Ask only for missing details that materially affect the story.
13
+
14
+ For a new browser project, use `reshoot init DIR --url DEMO_URL`; omit `--url` to try the packaged notes example. Fill in `BRIEF.md`. Replace the placeholder with actual actions and result checks, keeping an `end` beat if the edit uses it. Inspect the page's DOM or use `reshoot rec URL DRAFT.toml` when no source is available. Recorder drafts still need captions and assertions. An external URL project has no managed server unless `[app]` is added. Resolve login with an isolated demo account in a fresh profile. The generated files are in the project, not in this skill folder. Read `reshoot web --help` for storyboard settings and `reshoot run --help` for configuration.
15
+
16
+ For a native macOS app, save a brief, capture recipe and edit script in a demo folder. Use `reshoot window --list` to select the exact demo window, then `reshoot window APP NEW_TAKE.mov --id ID -s SECONDS`. Check Screen Recording permission for the command's host. Drive the app through app-specific automation or coordinate the owner's interaction during capture; the window command does not operate controls. Look up the ID each take and choose unused output paths. Versioned projects support web and VHS, not native window takes. Do not invent a native run manifest, browser overlay or result assertions. Export with `reshoot edit EDIT.toml NEW_TAKE.mov`, using numeric cuts, and a GIF export profile, or a Python edit. The primary skill can follow this route without supporting plugin skills.
17
+
18
+ Use made-up data in a separate account, folder, or database. Document and run its reset before each take. Record only a headless browser page, VHS terminal, or one macOS window by ID. Never capture the whole screen or reuse a person's browser profile.
19
+
20
+ For browser/VHS projects, run `reshoot preview CONFIG`, inspect frames and expected results, then `reshoot run CONFIG`. Read the printed run report. For native apps, inspect a standalone test take, then capture and edit a fresh final in a new folder. Generate check sheets for source and final media with `reshoot check SOURCES --full --review NEW_REVIEW_DIR`. Inspect actual outputs on either route. Execution success does not mean a scan passed or a person reviewed the video. When the owner wants a quicker refresh of checked data, follow the trade-offs in the guide's `speed.md` and say which checks were reduced; agent-written terminal text always needs reading. Fix failed inputs and actions rather than suppressing checks. Give the owner the final files and pending review items.
21
+
22
+ For combined web and VHS edits, configure matching take dimensions. Mixed previews retain the browser's configured dimensions because VHS keeps its tape dimensions.
23
+
24
+ Keep captions short and explain the result, not the click. Leave time to read. Identify mocked responses or shortened waits. Do not change the product claim merely to make a recording finish.
25
+
26
+ Inspect captions after page navigation. The overlay restores the current caption on same-origin page loads; zoomed or styled captions are drawn after recording.
27
+
28
+ Commit, push, or publish only within the owner's existing authorization. Creating local files is not publishing.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Create a demo"
3
+ short_description: "Create a repeatable demo with checked results"
4
+ default_prompt: "Use $reshoot-demo to create a repeatable software demo from one useful task and a checked result."
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: reshoot-refresh
3
+ description: Update an existing reshoot demo after an app or release changes. Use when a saved storyboard, video, or README clip needs recording again.
4
+ ---
5
+
6
+ # Refresh a demo
7
+
8
+ For combined web and VHS edits, keep take dimensions matched. Mixed previews retain the configured browser dimensions to match the unchanged VHS output size.
9
+
10
+ Requires reshoot CLI 0.2 or newer. Run `reshoot --version`. For a versioned browser/VHS project, read its brief, config, storyboard and previous run before changing anything, then run `reshoot doctor --config CONFIG`.
11
+
12
+ For a standalone native recording, read the brief, capture/edit scripts and exact previous media instead of expecting a versioned config or run report. Look up the current demo window ID, reset synthetic data, and use `reshoot window APP NEW_TAKE.mov --id ID -s SECONDS` with app-specific automation or coordinated manual interaction. Keep test and fresh final takes in new folders; edit and scan final exports. Compare the old/new MP4s and animated GIFs manually. Disclose that browser assertions, versioned `preview`/`run`, and automated beat comparison do not apply. Follow the versioned flow below only for browser/VHS projects.
13
+
14
+ Reset the made-up demo data and record the current app using `reshoot preview CONFIG`. Retain stable beat names. Diagnose failures using the beat, screenshot, and expected result. A selector repair should still perform the same task; it must not delete a failed assertion or replace the intended result with whatever the app happens to show.
15
+
16
+ When authorized to make local fixes, update the smallest necessary part, then rerun the affected flow. Use a full fresh `reshoot run CONFIG` for the final take. Keep the previous run. Read the report for execution errors, scan coverage, and pending human review.
17
+
18
+ A failed or missing browser take leaves the overall expectations unverified unless an assertion explicitly failed. Earlier passed assertions do not establish the result of an incomplete flow.
19
+
20
+ If this CLI version provides `reshoot compare`, compare the previous and new runs by beat and inspect the actual frames. Otherwise, show the old and new recordings and disclose that comparison is manual. A successful run must not silently replace the chosen comparison baseline or inherit approval from it.
21
+
22
+ Use only made-up data and page, terminal, or single-window capture. Call out changes to the story's claim, fixture meaning, speed, or narration. Present the new files and unresolved items. Publishing and repository changes follow the owner's existing authorization.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Update a demo"
3
+ short_description: "Update a demo and compare the results"
4
+ default_prompt: "Use $reshoot-refresh to update an existing reshoot demo, check its expected results, and compare it with the previous run."
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: reshoot-review
3
+ description: Inspect a reshoot recording and its check report for failed actions, privacy findings, coverage gaps, and readability before sharing.
4
+ ---
5
+
6
+ # Review a recording
7
+
8
+ Requires reshoot CLI 0.2 or newer. Read the project's brief and, for a versioned project, its current run report. Confirm which attempt produced the files, and distinguish execution, expected results, automatic scanning and human review.
9
+
10
+ For standalone native media, read its capture/edit recipe and exact source/export paths instead of requiring or inventing a run report. Compare old and new recordings manually and identify the result visually; do not claim browser assertions or automated beat comparison. Use a video player and check sheets rather than `reshoot review RUN`, which requires a versioned run manifest. Preserve existing reviews; generate any new scan in a separate directory.
11
+
12
+ Use `reshoot check SOURCES --review REVIEW_DIR` to generate a check report and sheets. Include final exports as well as available source images. Use `--full` for final exports when feasible. The default video scan samples every three seconds and can miss brief content. Read the reported coverage and unavailable detectors. A clean scan does not prove a recording contains no private content.
13
+
14
+ Check exits 0 for accepted supplied items, 1 for human review pending, and 2 for an error. Missing or unreadable sources must be fixed before accepting the review. `--no-scan` explicitly skips detectors; it is not a scan pass.
15
+
16
+ Inspect sheets and original frames, then watch the final video, with sound when present. Check the stated result, text size, caption wrapping, timing, audio, end card, and any mock or speed labels. Use only made-up data. Fail private names, accounts, files, tokens, or unintended people shown in the recording.
17
+
18
+ For a versioned run, if this CLI provides `reshoot review`, use its local page to inspect timestamps and comparisons. Otherwise use the sheets and a video player. Report that limitation.
19
+ Previous and current GIFs display as images in the comparison page; inspect their
20
+ animation and loop as well as the MP4 playback.
21
+
22
+ The owner decides whether a recording is accepted. Do not run `check --ok`, import approval, or promote a baseline merely because your inspection found nothing. Carry out those actions when the owner explicitly authorizes the decision. Give the owner the files, evidence, and unresolved findings; do not publish without authorization.
23
+
24
+ `check --text-file FINAL.srt` scans exact caption text. Runs also check generated
25
+ subtitle and narration sidecars. Inspect text findings at their recorded cue times.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Review a demo"
3
+ short_description: "Inspect recordings, changes, and privacy findings"
4
+ default_prompt: "Use $reshoot-review to review a reshoot run and its findings without treating execution success as approval."