Files
claude-engineering-plugin/plugins/compound-engineering/skills/ce-demo-reel/references/tier-browser-reel.md
Trevin Chow 9ddcd22aee
Some checks failed
CI / pr-title (push) Has been cancelled
CI / test (push) Has been cancelled
Release PR / release-pr (push) Has been cancelled
Release PR / publish-cli (push) Has been cancelled
fix(ce-demo-reel): prevent secrets in recorded demos (#664)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 21:52:52 -07:00

5.1 KiB

Tier: Browser Reel

Capture 3-5 browser screenshots at key UI states and stitch into an animated GIF.

Best for: Web apps, desktop apps accessible via localhost or CDP. Output: GIF (PNG screenshots stitched via ffmpeg two-pass palette) Label: "Demo" Required tools: agent-browser, ffmpeg

If agent-browser is not installed, inform the user: "agent-browser is not installed. Run /ce-setup to install required dependencies." Then fall back to a lower tier (static screenshots or skip).

Step 1: Connect to the Application

For web apps -- verify the dev server is accessible:

  • Read package.json scripts for dev, start, serve commands
  • Check Procfile, Procfile.dev, or bin/dev if they exist
  • Check Gemfile for Rails (bin/rails server) or Sinatra
  • Check for running processes on common ports (3000, 5000, 8080)

If the server is not running, tell the user what start command was detected and ask them to start it. Do not start it automatically (it may require environment variables, database setup, etc.).

If the server cannot be reached after the user confirms it should be running, fall back to static screenshots tier.

Once accessible, note the base URL (e.g., http://localhost:3000).

For Electron/desktop apps -- connect via Chrome DevTools Protocol (CDP):

  1. Check if the app is already running with CDP enabled by probing common ports:

    curl -s http://localhost:9222/json/version
    

    If that returns a JSON response, the app is ready -- connect agent-browser to it:

    agent-browser connect 9222
    
  2. If not running, the app needs to be launched with --remote-debugging-port. Detect the entry point from package.json (look for the main field or electron in scripts), then ask the user to launch it with:

    your-electron-app --remote-debugging-port=9222
    

    If port 9222 is busy, try 9223-9230.

  3. Poll until CDP is ready (timeout after 30 seconds):

    curl -s http://localhost:9222/json/version
    
  4. Connect agent-browser:

    agent-browser connect 9222
    

CDP advantages: Screenshots come from the renderer's frame buffer, not macOS screen capture -- no Accessibility or Screen Recording permissions needed.

If CDP connection fails: Fall back to static screenshots tier. Tell the user: "Could not connect to the app via CDP. Falling back to static screenshots."

Step 2: Capture Screenshots

Navigate to the relevant pages and capture 3-5 screenshots at key UI states:

  1. Initial/empty state -- Before the feature is used
  2. Navigation -- How the user reaches the feature (if not the landing page)
  3. Feature in action -- The hero shot showing the feature working
  4. Result state -- After interaction (data present, items created, success message)
  5. Detail view (optional) -- Expanded item, settings panel, modal

For each screenshot, write to the concrete RUN_DIR created by the parent skill:

agent-browser open [URL]
agent-browser wait 2000
agent-browser screenshot [RUN_DIR]/frame-01-initial.png

Capture tips:

  • Use URL navigation (agent-browser open URL) rather than clicking SPA elements (clicks often fail on React/Vue/Svelte SPAs)
  • Wait 2-3 seconds after navigation for the page to settle
  • Capture the full viewport (sidebar, header give reviewers context)

Keep secrets out of frame:

  • Do not open DevTools, the Network panel, or Application/Storage -- these expose auth headers, cookies, session storage, and tokens in plain view
  • Skip pages that display raw credentials (unmasked API-key settings, OAuth consent screens, .env viewers, billing/payment detail)
  • Check the URL bar before each screenshot -- if it carries a session token or credential query param (?access_token=, ?api_key=, #id_token=), navigate to the clean canonical URL first
  • Prefer a demo account or seeded fixture data over a real logged-in account when the screenshot will include account identifiers that are themselves sensitive

Step 3: Stitch into GIF

Use the capture pipeline script to normalize frame dimensions, stitch with two-pass palette, and auto-reduce if over 10 MB:

python3 scripts/capture-demo.py stitch [RUN_DIR]/demo.gif [RUN_DIR]/frame-*.png

The script handles dimension normalization (via ffprobe + ffmpeg padding), concat demuxer stitching, palette generation, and automatic frame reduction if the GIF exceeds GitHub's 10 MB inline limit. Default is 3 seconds per frame. To adjust:

python3 scripts/capture-demo.py stitch --duration 2.0 [RUN_DIR]/demo.gif [RUN_DIR]/frame-*.png

If stitching fails: Fall back to static screenshots tier using the individual PNGs already captured. If no PNGs were captured, report the failure.

Step 4: Secrets Scan and Cleanup

Before uploading, inspect the final GIF for any credential material visible on-screen. If any appears, discard the GIF and recapture with the offending page or state routed out of frame. Do not upload, do not blur.

After a clean GIF is confirmed, remove individual PNG frames. Keep only the final GIF for upload.

Proceed to references/upload-and-approval.md.