一键导入
v1-prove-work
Use when explicitly recording browser proof or a demo GIF for a completed UI change. Triggers on "prove work", "record demo", or "visual proof".
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when explicitly recording browser proof or a demo GIF for a completed UI change. Triggers on "prove work", "record demo", or "visual proof".
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when explicitly choosing which v1tamins skill fits a task. Triggers on "which v1 skill", "v1 menu", or "/v1-menu".
Use when the user explicitly requests phone-a-friend, a counterpart review, steelman, or peer consult. Triggers on /v1-phone-a-friend or $v1-phone-a-friend only.
Use when explicitly convening several peer agents to review a PR or branch. Triggers on "review board", "multi-agent review", or "fan out a review".
Use when refining working code through a quality pass, deslop, or hindsight rewrite. Triggers on "make this diff simpler", "reduce complexity", or "deslop".
Use when diagnosing a throughput bottleneck in a process, funnel, queue, or WIP system. Triggers on "where is this process stuck?", "find the bottleneck", or "too much WIP".
Use when creating a self-contained HTML page, report, or interactive explainer. Triggers on "one-page dashboard", "shareable page", or "interactive report".
| name | v1-prove-work |
| description | Use when explicitly recording browser proof or a demo GIF for a completed UI change. Triggers on "prove work", "record demo", or "visual proof". |
| disable-model-invocation | true |
| allowed-tools | ["Bash","Read","Write","Grep","Glob"] |
Generate an animated GIF showing the result of work done during a session and embed it in a GitHub PR.
Typical invocations:
/v1-prove-work http://localhost:3000/settings --pr 42v1-prove-work from the skills menu or use $v1-prove-work http://localhost:3000/settings --pr 42This records a browser interaction with localhost:3000/settings, converts the recording to a GIF, uploads it to GitHub, and embeds it in PR #42's ## Demo section.
Without arguments, the skill infers the URL from the git diff and auto-detects the PR:
/v1-prove-work
In Codex, the slash examples below map directly to $v1-prove-work ....
Typical invocations:
Claude Code: /v1-prove-work [url] [--pr NUMBER] [--no-upload]
Codex: invoke v1-prove-work from the skills menu or use $v1-prove-work [url] [--pr NUMBER] [--no-upload]
url -- Override the target URL (default: inferred from context)
--pr NUMBER -- PR number to embed the GIF into (default: auto-detected)
--no-upload -- Save GIF locally without uploading to GitHub
Run these checks before proceeding. Stop and report if any fail.
# Check Python playwright
python3 -c "import playwright" 2>/dev/null || pip install playwright
# Check playwright browsers
python3 -c "from playwright.sync_api import sync_playwright; p=sync_playwright().start(); p.chromium.launch(headless=True).close(); p.stop()" 2>/dev/null || python3 -m playwright install chromium
# Check pyav and pillow (auto-installed by video_to_gif.py on first run)
python3 -c "import av; from PIL import Image" 2>/dev/null || echo "Dependencies will be auto-installed on first conversion."
# Check gifsicle (optional but recommended)
which gifsicle >/dev/null 2>&1 || echo "WARNING: gifsicle not found. Install with: brew install gifsicle"
Determine what to demonstrate. Read the recent git diff to identify changed files:
git diff --name-only HEAD~1..HEAD 2>/dev/null || git diff --name-only --cached
Decision tree:
.tsx, .jsx, .vue, .html, .css, templates) -> Infer the route/page affected, construct localhost URL.py, .rb, .go, API routes with no views) -> Tell the user: "This change has no visual component. Skipping proof-of-work." and exitWhen inferring the URL, look for:
Default base URL: http://localhost:3000 (override if project uses a different port).
Verify the URL is reachable before recording:
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/ROUTE
If the server is not running (connection refused), tell the user:
"Dev server is not running on localhost:3000. Start it and run the
v1-prove-workskill again."
Write a Python Playwright script to /tmp/prove-work/interact.py that demonstrates the feature.
Read references/recording-patterns.md for the script template, interaction patterns, and timing guidelines. Use the template from that file as the starting point -- fill in the interaction section based on context analysis.
mkdir -p /tmp/prove-work
# Clean old recordings
rm -f /tmp/prove-work/*.webm /tmp/prove-work/*.gif
# Run the interaction script
python3 /tmp/prove-work/interact.py
If the script fails, read the error output. Common issues:
wait_for_load_state timeout or check if the server is respondingRun the conversion script:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
RESOLVER=""
for candidate in \
"$REPO_ROOT/plugins/v1tamins/scripts/resolve-skill-root.sh" \
"${CLAUDE_PLUGIN_ROOT:-}/scripts/resolve-skill-root.sh" \
"$HOME/.claude/skills/v1-prove-work/../../scripts/resolve-skill-root.sh" \
"$HOME/.codex/skills/v1-prove-work/../../scripts/resolve-skill-root.sh" \
"$HOME/.claude/plugins/cache"/*/v1tamins/*/scripts/resolve-skill-root.sh \
"$HOME/.codex/plugins/cache/v1tamins/v1tamins"/*/scripts/resolve-skill-root.sh; do
[ -x "$candidate" ] && RESOLVER="$candidate" && break
done
if [ -z "${RESOLVER:-}" ]; then
echo "ERROR: Could not find resolve-skill-root.sh" >&2
exit 1
fi
SKILL_DIR="$("$RESOLVER" v1-prove-work scripts/video_to_gif.py)"
python3 "$SKILL_DIR/scripts/video_to_gif.py" \
--input /tmp/prove-work/ \
--output /tmp/prove-work/demo.gif \
--max-size-mb 10
The script:
If --no-upload was specified: Report the local path and stop.
Auto-detect PR number (if not provided):
gh pr view --json number --jq .number 2>/dev/null
If a PR exists, upload and embed:
# Reuse the $SKILL_DIR resolved in Step 5 (re-run that resolver block first if this is a fresh shell).
python3 "$SKILL_DIR/scripts/video_to_gif.py" \
--input /tmp/prove-work/ \
--output /tmp/prove-work/demo.gif \
--max-size-mb 10 \
--upload \
--pr PR_NUMBER
If no PR exists, save locally and report:
GIF saved to: /tmp/prove-work/demo.gif
No open PR found for this branch. Run the `v1-prove-work` skill again with `--pr NUMBER` after creating a PR, or use `--no-upload` to keep the GIF local.
After completion, report:
Proof of work recorded!
GIF: /tmp/prove-work/demo.gif (X.X MB)
URL: https://github.com/owner/repo/releases/download/media-assets/demo-pr42-20260224-143022.gif
PR: #42 -- ## Demo section updated
Recorded: [brief description of what was demonstrated]
Example 1: New settings page
Input: /v1-prove-work
Diff: app/pages/settings.tsx, app/api/settings.ts
Output:
Proof of work recorded!
GIF: /tmp/prove-work/demo.gif (1.8 MB)
URL: https://github.com/acme/app/releases/download/media-assets/demo-pr12-20260224-091500.gif
PR: #12 -- ## Demo section updated
Recorded: Navigated to /settings, filled display name, clicked Save, showed success toast
Example 2: Explicit URL with PR number
Input: /v1-prove-work http://localhost:5173/dashboard --pr 27
Output:
Proof of work recorded!
GIF: /tmp/prove-work/demo.gif (2.4 MB)
URL: https://github.com/acme/app/releases/download/media-assets/demo-pr27-20260224-143000.gif
PR: #27 -- ## Demo section updated
Recorded: Navigated to /dashboard, scrolled through widgets, toggled dark mode
Example 3: Backend-only change
Input: /v1-prove-work
Diff: app/services/billing.py, tests/test_billing.py
Output: This change has no visual component. Skipping proof-of-work.
Example 4: Local only
Input: /v1-prove-work --no-upload
Output:
GIF saved to: /tmp/prove-work/demo.gif (1.1 MB)
| Error | Action |
|---|---|
| Dev server not running | Report the error, suggest starting the server |
| Playwright not installed | Auto-install via pip + playwright install chromium |
| No .webm produced | Check interact.py output, report the error |
| GIF exceeds 10MB after all reductions | Report the size, suggest a shorter recording |
| gh CLI not authenticated | Report the error, suggest gh auth login |
| No visual changes detected | Tell the user, exit cleanly |