← Back to posts

Automated release notes with 'demo' skill

Yesterday, I added scheduled posts to firehose. I let my coding agent write the release notes. It is fun to read the release notes like this, and see the screenshots. Do note that a coding agent might not care there is no navigation - it happily will remember the urls and navigate to them, so that is something you might want to double check with exploratory testing :-).

I’ve included the full skill below. It is not in the repository, it went straight to my home directory so I can use it in other porjects. This is the second project I have used it in. It helped me earlier do a fairly large archiectural spike for an RFP response, and include screenshots of a working application in the response document. Working software is still a great measure of progress.

Demo skill - let your agent generate demos with screenshots for you


name: demo description: >- Generate a living demo document proving a feature works. Uses showboat for Markdown assembly with captured command output and rodney for Chrome browser screenshots. Use when the user says “demo this”, “show me it works”, “create a demo”, or after /build completes. argument-hint: “<feature-name> [–scenario <description>] [–plan <path>]” user-invocable: true allowed-tools: Read, Write, Glob, Grep, Bash


Demo

Role: worker. This command generates a standalone Markdown demo document that proves a feature works, using showboat for document assembly and rodney for browser automation.

You have been invoked with the /demo command.

Parse Arguments

Arguments: $ARGUMENTS

  • Positional: <feature-name> (required) — short name or description of the feature to demo
  • --scenario <description>: Explicit demo scenario describing what to show. If omitted, infer from the plan and recent commits.
  • --plan <path>: Path to the plan file. If omitted, search plans/ for the most recently modified .md file with status implemented or approved.

Steps

1. Check tool availability

Verify showboat and rodney are installed:

showboat --help 2>/dev/null && echo "showboat: ok" || echo "showboat: missing"
rodney --help 2>/dev/null && echo "rodney: ok" || echo "rodney: missing"

If either tool is missing, tell the user:

One or more demo tools are missing. Install them with:

go install github.com/simonw/showboat@latest
go install github.com/simonw/rodney@latest

Do not proceed until both tools are confirmed available.

2. Gather feature context

Build an understanding of what to demo from these sources (in priority order):

  1. Explicit scenario (--scenario): If provided, use as primary guide.
  2. Plan file: Read the plan’s Goal, Acceptance Criteria, and completed Steps.
  3. Recent commits: Run git log --oneline -15 and git diff main...HEAD --stat to identify changed files and commit messages.
  4. Route map: Cross-reference changed files against known LiveView routes in the router (lib/hub_web/router.ex).

From these sources, produce a demo outline:

  • Narrative: 2-3 sentence description of what the feature does
  • Backend evidence: mix commands, test output, or database queries to run
  • UI pages: which routes to visit and what to look for
  • Interactions: any clicks, form fills, or navigation sequences to perform

If no plan exists and commits are ambiguous, ask the user for a brief description of what to demo.

3. Check dev server

curl -s -o /dev/null -w "%{http_code}" http://localhost:4000/ 2>/dev/null

If the server is not reachable:

The Phoenix dev server is not running. Start it now?

mix phx.server &

After starting, wait up to 10 seconds and verify connectivity. If it still fails, proceed with backend-only evidence (skip all browser screenshots) and note the limitation in the demo document.

4. Handle authentication

The app requires authentication for LiveView routes. Before capturing UI screenshots:

  1. Ensure a demo user exists:

    mix run -e "
      alias Hub.Accounts
      case Accounts.get_user_by_email(\"demo@example.com\") do
        nil -> Accounts.register_user(%{email: \"demo@example.com\", password: \"demodemo1234\"})
        user -> {:ok, user}
      end
    "
  2. Log in via rodney:

    rodney start
    rodney open http://localhost:4000/users/log-in
    rodney wait "input[name='user[email]']"
    rodney input "input[name='user[email]']" "demo@example.com"
    rodney input "input[name='user[password]']" "demodemo1234"
    rodney click "button[type='submit']"
    rodney waitidle

If login fails, warn and proceed with backend-only evidence.

5. Initialize the demo document

Slugify the feature name (lowercase, hyphens, no special chars). Then:

showboat init "demos/demo-$(date +%Y%m%d-%H%M%S)-<slug>.md" "Demo: <Feature Name>"

Store the demo file path for use in all subsequent steps.

6. Narrative introduction

showboat note <demo-file> "## Feature Overview

<2-3 sentence description derived from the plan or commits.>

**Branch**: $(git branch --show-current)
**Commits**: <N> commits ahead of main
**Plan**: <plan file path or 'none'>
"

7. Backend evidence

Capture backend proof via showboat exec. Always include relevant tests. Add narrative notes between evidence blocks explaining what each proves.

Test output (always include):

showboat note <demo-file> "## Test Suite"
showboat exec <demo-file> bash "mix test <relevant-test-files> --color"
showboat note <demo-file> "All <N> tests pass, confirming <specific criterion>."

Compilation check:

showboat note <demo-file> "## Compilation Check"
showboat exec <demo-file> bash "mix compile --warnings-as-errors"

Database state (if relevant to the feature):

showboat note <demo-file> "## Database State"
showboat exec <demo-file> bash "mix run -e '<query expression>'"

8. UI screenshots

For each UI page identified in step 2, navigate with rodney, screenshot, and embed via showboat.

Static page capture:

rodney open http://localhost:4000/<route>
rodney waitidle
rodney screenshot demos/screenshots/<feature>-<page-name>.png

showboat note <demo-file> "### <Page Name>

<What this page shows and why it proves the feature works.>"

showboat image <demo-file> '![<What the screenshot demonstrates>](demos/screenshots/<feature>-<page-name>.png)'

Interactive flow (form submissions, navigation):

showboat note <demo-file> "### Interactive Flow: <Flow Name>"

# Before state
rodney screenshot demos/screenshots/<feature>-before.png
showboat image <demo-file> '![Before: <initial state>](demos/screenshots/<feature>-before.png)'

# Perform interaction
rodney click "<selector>"
rodney input "<selector>" "<value>"
rodney click "<submit-selector>"
rodney waitidle

# After state
rodney screenshot demos/screenshots/<feature>-after.png
showboat image <demo-file> '![After: <resulting state>](demos/screenshots/<feature>-after.png)'

9. Acceptance criteria checklist

If a plan file exists, map each acceptance criterion to evidence:

showboat note <demo-file> "## Acceptance Criteria Verification

- [x] <Criterion 1> -- see Test Suite output above
- [x] <Criterion 2> -- see <Page Name> screenshot
- [x] <Criterion 3> -- see Database State output
"

If no plan, summarize what was demonstrated and what it proves.

10. Clean up

rodney stop 2>/dev/null || true

11. Report results

Display:

## Demo Complete

- **Document**: demos/<filename>.md
- **Screenshots**: <N> captured in demos/screenshots/
- **Evidence**: <N> backend commands, <N> UI screenshots
- **Acceptance criteria**: <N>/<M> demonstrated

Error Handling

  • Tools not installed: Show go install commands. Do not proceed without them.
  • Dev server not running: Offer to start. If startup fails, produce backend-only demo and note the limitation.
  • Authentication failure: Proceed with backend-only evidence. Note skipped UI screenshots in the document.
  • Screenshot failure: Log the error as a note in the demo document, continue with remaining screenshots.
  • No plan found: Infer from git commits and changed files. Ask the user for a description if commits are ambiguous.
  • Rodney/Chrome crash: Run rodney stop then rodney start to reset. Retry once. If it fails again, degrade to backend-only.

Integration

  • /build can suggest running /demo after a successful build
  • /pr can invoke /demo to generate evidence before or after PR creation
  • /plan produces the acceptance criteria this command verifies visually
  • Beads (bd) can reference demo documents as task completion evidence
  • Reads plan files from plans/ directory (same format as /build)