| name | show-me |
| description | Use after implementing a change or opening a PR — proves the change works end-to-end by running the app, driving it in the browser, and recording an MP4 video as proof. The reviewer watches the recording and merges without pulling the branch. |
Show Me
Overview
A post-implementation proof protocol. Instead of telling the reviewer "it works," show them: run the app, exercise exactly what changed, and capture a short recording (or terminal transcript for non-UI changes) that a reviewer watches and immediately thinks "yep, it works."
Inspired by Devin's testing-and-recordings workflow: Setup → Plan → Record → Deliver.
The proof is scoped to the diff. This is not a full regression pass — the test suite does that. This is a focused demonstration of the changed behavior.
When to Use
- After completing a feature or bug fix, before or right after opening the PR
- User says "prove it works", "show me", "send me a recording", or "verify X works"
- As the final step of
powerups:plan-driven-development or powerups:bug-fix, when the change is user-facing
- Any time a reviewer would otherwise have to pull the branch to verify behavior
Not for: pure refactors, dependency bumps, or changes with no observable behavior. Say so and skip instead of recording nothing meaningful.
The Protocol
Phase 1: Setup
Get the app running before any recording starts.
- Read the diff to understand what needs demonstrating:
git diff main...HEAD (or the PR diff via gh pr diff)
- Start the app locally the way the project normally does (check README,
package.json scripts, Makefile, docker-compose). Run it in the background and confirm it's serving before proceeding
- If the flow needs credentials, seed data, or services that aren't available, ask the user for them now — never fake, stub, or screenshot around a login you can't complete
- For UI proof, load the Chrome tools if deferred — one ToolSearch call for the full set including
gif_creator, javascript_tool, and resize_window — then call tabs_context_mcp and create a new tab
Success criteria: The app is running and you can reach the entry point of the changed behavior.
Phase 2: Plan
Write a minimal test plan derived from the diff — 3–7 steps, one flow, only what changed.
- Each step is a concrete action with an expected observable result ("click Save → toast appears, row updates")
- Include the one edge case the diff exists to handle (the bug input, the new validation), not every edge case
- If the diff touches multiple independent flows, plan one recording per flow rather than one long meandering recording
State the plan in one short list before executing. Don't ask for approval — just record it so the deliverable can be checked against it.
Success criteria: A step list where every step maps to a line in the diff, and nothing in it is "general app smoke testing."
Phase 3: Record
UI changes — deliver as MP4.
Stage the scene before capturing (both paths):
- Load the
frontend-design:frontend-design skill (if available) before styling the overlays below — the cursor and caption are designed UI and should read as intentional, not thrown-together defaults
- Inject an animated cursor. Automation clicks dispatch synthetic events — the real pointer never moves, so an unstaged recording shows the page reacting to nothing. Inject a small fixed-position cursor element with a CSS transition on
transform (~300ms, ease-out) via javascript_tool; before every click, animate it to the target, let the transition finish, then click. Playback shows the pointer traveling, never teleporting
- Inject a caption bar. A fixed lower-third for one-line step annotations ("Submitting empty form — expect inline error"). Update the text as each step starts; clear it during the pause on the proof moment so the caption never covers the evidence
Two capture paths, in order of preference:
- Preferred (macOS): normalize the window size, then record only the page viewport natively with
screencapture — real video, no GIF intermediate, no browser chrome:
osascript -e 'tell application "Google Chrome" to get bounds of front window'
osascript -e 'tell application "Google Chrome" to set bounds of front window to {100, 100, 1380, 900}'
Then cut the tab strip, omnibox, and bookmarks bar out of the region — they're noise, not proof. With DevTools closed, measure the browser-chrome height from inside the page (window.outerHeight - window.innerHeight via javascript_tool) and record just the content:
screencapture -x -v -R 100,<100+chromeH>,<innerW>,<innerH> flow.mov &
pkill -INT screencapture
ffmpeg -i flow.mov -c copy -movflags +faststart flow.mp4
(The resize_window browser tool also works for the resize step.) Requires screen-recording permission for the terminal, and the window must stay unobstructed at those coordinates for the whole recording. If permission is denied or you're not on macOS, use the fallback
- Fallback: capture with
gif_creator (it captures only the tab content, so no cropping needed), then convert to MP4 — far smaller and scrubs properly:
ffmpeg -i flow.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" flow.mp4
If ffmpeg isn't installed, deliver the GIF and say so — don't block the proof on a codec
Either way:
- Start capture before navigating to the flow so playback has context on both sides of each action
- Execute the plan exactly. Pause briefly on the "proof moment" (the fixed output, the new element) so it's legible in playback
- Name the file after the behavior, not the task:
login_error_message.mp4, not test.mp4
- If a step fails, stop recording and fix the app, not the plan. Re-record from the top once fixed — a recording that skips the broken part is not proof
Non-UI changes (API, CLI, background job) — capture a terminal transcript instead:
- Run the demonstrating commands (
curl the endpoint, invoke the CLI) and save the real input/output to a file
- Show the before-state where feasible (e.g. the error response on
main, then the fix on the branch)
Success criteria: A recording or transcript where every planned step visibly succeeds.
Phase 4: Deliver
- Send the recording (or transcript) to the user with
SendUserFile, captioned with a one-line pass/fail summary
- Report the plan-vs-result: each step, what was expected, what the recording shows
- If a PR exists, post the test plan and result as a PR comment (
gh pr comment) so the reviewer has the summary next to the code
- Stop the app, close the tab you created, and restore the browser window to the bounds you saved before resizing
Success criteria: The user has the file, and the summary honestly reflects what was and wasn't demonstrated.
Rules
- The diff defines the plan. No drive-by exploration, no testing unrelated screens.
- Never deliver a recording of a failure as if it passed. If it fails, that's a finding — report it, fix it (via
powerups:bug-fix if it's a real bug), then re-record.
- Never fake the environment. No hardcoded data, mocked endpoints, or commented-out auth to make the demo work. If the demo needs something you don't have, ask.
- Keep it short. A reviewer should get to "yep, it works" in under 30 seconds of playback. Cut setup and navigation dead time by starting recording close to the flow.
- One flow per recording. Multiple independent changes get multiple short recordings.
Anti-Patterns
| Don't | Do |
|---|
| Record the whole app "while you're at it" | Record only the flow the diff changed |
| Record the tab strip and bookmarks bar along with the page | Crop the capture region to the page viewport |
| Let clicks land with no visible pointer | Animate the injected cursor to each target before clicking |
| Re-plan around a broken step mid-recording | Stop, fix the app, re-record from the top |
| Ship a recording where the key moment flashes by | Pause on the proof moment so it reads in playback |
| Mock the backend to make the UI demo work | Run the real stack; ask for missing credentials |
| Claim "verified" from a transcript that only shows the happy path you didn't change | Demonstrate the specific changed behavior, including its edge case |
| Skip proof on a non-UI change | Deliver a terminal transcript instead of a video |