[2.16.0] Consolidate DHH styles and add /feature-video command
- Merge dhh-ruby-style into dhh-rails-style for comprehensive Rails conventions - Add testing.md reference covering Rails testing patterns - Add /feature-video command for recording PR demo videos - Update docs and component counts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
342
plugins/compound-engineering/commands/feature-video.md
Normal file
342
plugins/compound-engineering/commands/feature-video.md
Normal file
@@ -0,0 +1,342 @@
|
||||
---
|
||||
name: feature-video
|
||||
description: Record a video walkthrough of a feature and add it to the PR description
|
||||
argument-hint: "[PR number or 'current'] [optional: base URL, default localhost:3000]"
|
||||
---
|
||||
|
||||
# Feature Video Walkthrough
|
||||
|
||||
<command_purpose>Record a video walkthrough demonstrating a feature, upload it, and add it to the PR description.</command_purpose>
|
||||
|
||||
## Introduction
|
||||
|
||||
<role>Developer Relations Engineer creating feature demo videos</role>
|
||||
|
||||
This command creates professional video walkthroughs of features for PR documentation:
|
||||
- Records browser interactions using Playwright video capture
|
||||
- Demonstrates the complete user flow
|
||||
- Uploads the video for easy sharing
|
||||
- Updates the PR description with an embedded video
|
||||
|
||||
## Prerequisites
|
||||
|
||||
<requirements>
|
||||
- Local development server running (e.g., `bin/dev`, `rails server`)
|
||||
- Playwright MCP server connected
|
||||
- Git repository with a PR to document
|
||||
- `ffmpeg` installed (for video conversion if needed)
|
||||
</requirements>
|
||||
|
||||
## Main Tasks
|
||||
|
||||
### 1. Parse Arguments
|
||||
|
||||
<parse_args>
|
||||
|
||||
**Arguments:** $ARGUMENTS
|
||||
|
||||
Parse the input:
|
||||
- First argument: PR number or "current" (defaults to current branch's PR)
|
||||
- Second argument: Base URL (defaults to `http://localhost:3000`)
|
||||
|
||||
```bash
|
||||
# Get PR number for current branch if needed
|
||||
gh pr view --json number -q '.number'
|
||||
```
|
||||
|
||||
</parse_args>
|
||||
|
||||
### 2. Gather Feature Context
|
||||
|
||||
<gather_context>
|
||||
|
||||
**Get PR details:**
|
||||
```bash
|
||||
gh pr view [number] --json title,body,files,headRefName -q '.'
|
||||
```
|
||||
|
||||
**Get changed files:**
|
||||
```bash
|
||||
gh pr view [number] --json files -q '.files[].path'
|
||||
```
|
||||
|
||||
**Map files to testable routes** (same as playwright-test):
|
||||
|
||||
| File Pattern | Route(s) |
|
||||
|-------------|----------|
|
||||
| `app/views/users/*` | `/users`, `/users/:id`, `/users/new` |
|
||||
| `app/controllers/settings_controller.rb` | `/settings` |
|
||||
| `app/javascript/controllers/*_controller.js` | Pages using that Stimulus controller |
|
||||
| `app/components/*_component.rb` | Pages rendering that component |
|
||||
|
||||
</gather_context>
|
||||
|
||||
### 3. Plan the Video Flow
|
||||
|
||||
<plan_flow>
|
||||
|
||||
Before recording, create a shot list:
|
||||
|
||||
1. **Opening shot**: Homepage or starting point (2-3 seconds)
|
||||
2. **Navigation**: How user gets to the feature
|
||||
3. **Feature demonstration**: Core functionality (main focus)
|
||||
4. **Edge cases**: Error states, validation, etc. (if applicable)
|
||||
5. **Success state**: Completed action/result
|
||||
|
||||
Ask user to confirm or adjust the flow:
|
||||
|
||||
```markdown
|
||||
**Proposed Video Flow**
|
||||
|
||||
Based on PR #[number]: [title]
|
||||
|
||||
1. Start at: /[starting-route]
|
||||
2. Navigate to: /[feature-route]
|
||||
3. Demonstrate:
|
||||
- [Action 1]
|
||||
- [Action 2]
|
||||
- [Action 3]
|
||||
4. Show result: [success state]
|
||||
|
||||
Estimated duration: ~[X] seconds
|
||||
|
||||
Does this look right?
|
||||
1. Yes, start recording
|
||||
2. Modify the flow (describe changes)
|
||||
3. Add specific interactions to demonstrate
|
||||
```
|
||||
|
||||
</plan_flow>
|
||||
|
||||
### 4. Setup Video Recording
|
||||
|
||||
<setup_recording>
|
||||
|
||||
**Create videos directory:**
|
||||
```bash
|
||||
mkdir -p tmp/videos
|
||||
```
|
||||
|
||||
**Start browser with video recording using Playwright MCP:**
|
||||
|
||||
Note: Playwright MCP's browser_navigate will be used, and we'll use browser_run_code to enable video recording:
|
||||
|
||||
```javascript
|
||||
// Enable video recording context
|
||||
mcp__plugin_compound-engineering_pw__browser_run_code({
|
||||
code: `async (page) => {
|
||||
// Video recording is enabled at context level
|
||||
// The MCP server handles this automatically
|
||||
return 'Video recording active';
|
||||
}`
|
||||
})
|
||||
```
|
||||
|
||||
**Alternative: Use browser screenshots as frames**
|
||||
|
||||
If video recording isn't available via MCP, fall back to:
|
||||
1. Take screenshots at key moments
|
||||
2. Combine into a GIF using ffmpeg
|
||||
|
||||
```bash
|
||||
ffmpeg -framerate 2 -pattern_type glob -i 'tmp/screenshots/*.png' -vf "scale=1280:-1" tmp/videos/feature-demo.gif
|
||||
```
|
||||
|
||||
</setup_recording>
|
||||
|
||||
### 5. Record the Walkthrough
|
||||
|
||||
<record_walkthrough>
|
||||
|
||||
Execute the planned flow, capturing each step:
|
||||
|
||||
**Step 1: Navigate to starting point**
|
||||
```
|
||||
mcp__plugin_compound-engineering_pw__browser_navigate({ url: "[base-url]/[start-route]" })
|
||||
mcp__plugin_compound-engineering_pw__browser_wait_for({ time: 2 })
|
||||
mcp__plugin_compound-engineering_pw__browser_take_screenshot({ filename: "tmp/screenshots/01-start.png" })
|
||||
```
|
||||
|
||||
**Step 2: Perform navigation/interactions**
|
||||
```
|
||||
mcp__plugin_compound-engineering_pw__browser_click({ element: "[description]", ref: "[ref]" })
|
||||
mcp__plugin_compound-engineering_pw__browser_wait_for({ time: 1 })
|
||||
mcp__plugin_compound-engineering_pw__browser_take_screenshot({ filename: "tmp/screenshots/02-navigate.png" })
|
||||
```
|
||||
|
||||
**Step 3: Demonstrate feature**
|
||||
```
|
||||
mcp__plugin_compound-engineering_pw__browser_snapshot({})
|
||||
// Identify interactive elements
|
||||
mcp__plugin_compound-engineering_pw__browser_click({ element: "[feature element]", ref: "[ref]" })
|
||||
mcp__plugin_compound-engineering_pw__browser_wait_for({ time: 1 })
|
||||
mcp__plugin_compound-engineering_pw__browser_take_screenshot({ filename: "tmp/screenshots/03-feature.png" })
|
||||
```
|
||||
|
||||
**Step 4: Capture result**
|
||||
```
|
||||
mcp__plugin_compound-engineering_pw__browser_wait_for({ time: 2 })
|
||||
mcp__plugin_compound-engineering_pw__browser_take_screenshot({ filename: "tmp/screenshots/04-result.png" })
|
||||
```
|
||||
|
||||
**Create video/GIF from screenshots:**
|
||||
```bash
|
||||
# Create GIF from screenshots
|
||||
ffmpeg -framerate 1 -pattern_type glob -i 'tmp/screenshots/*.png' \
|
||||
-vf "scale=1280:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
|
||||
-loop 0 tmp/videos/feature-demo.gif
|
||||
|
||||
# Or create MP4 for better quality
|
||||
ffmpeg -framerate 1 -pattern_type glob -i 'tmp/screenshots/*.png' \
|
||||
-c:v libx264 -pix_fmt yuv420p -vf "scale=1280:-1" \
|
||||
tmp/videos/feature-demo.mp4
|
||||
```
|
||||
|
||||
</record_walkthrough>
|
||||
|
||||
### 6. Upload the Video
|
||||
|
||||
<upload_video>
|
||||
|
||||
**Option A: Upload to GitHub (via PR comment with attachment)**
|
||||
|
||||
GitHub doesn't support direct video uploads via API, but you can:
|
||||
1. Drag-drop in browser, or
|
||||
2. Use a hosting service
|
||||
|
||||
**Option B: Upload to transfer.sh (temporary, 14 days)**
|
||||
```bash
|
||||
curl --upload-file tmp/videos/feature-demo.gif https://transfer.sh/feature-demo.gif
|
||||
```
|
||||
|
||||
**Option C: Upload to Cloudflare R2/S3 (if configured)**
|
||||
```bash
|
||||
# If AWS CLI is configured
|
||||
aws s3 cp tmp/videos/feature-demo.gif s3://your-bucket/pr-videos/pr-[number]-demo.gif --acl public-read
|
||||
```
|
||||
|
||||
**Option D: Keep local and provide path**
|
||||
```bash
|
||||
# Just provide the local path for manual upload
|
||||
echo "Video saved to: $(pwd)/tmp/videos/feature-demo.gif"
|
||||
```
|
||||
|
||||
Ask user for upload preference:
|
||||
```markdown
|
||||
**Video Ready**
|
||||
|
||||
Video saved to: `tmp/videos/feature-demo.gif`
|
||||
Size: [size]
|
||||
|
||||
How would you like to share it?
|
||||
1. Upload to transfer.sh (temporary link, 14 days)
|
||||
2. Keep local - I'll upload manually
|
||||
3. Upload to S3/R2 (requires config)
|
||||
```
|
||||
|
||||
</upload_video>
|
||||
|
||||
### 7. Update PR Description
|
||||
|
||||
<update_pr>
|
||||
|
||||
**Get current PR body:**
|
||||
```bash
|
||||
gh pr view [number] --json body -q '.body'
|
||||
```
|
||||
|
||||
**Add video section to PR description:**
|
||||
|
||||
If the PR already has a video section, replace it. Otherwise, append:
|
||||
|
||||
```markdown
|
||||
## Demo Video
|
||||
|
||||

|
||||
|
||||
_Walkthrough recorded with Playwright_
|
||||
```
|
||||
|
||||
**Update the PR:**
|
||||
```bash
|
||||
gh pr edit [number] --body "[updated body with video section]"
|
||||
```
|
||||
|
||||
**Or add as a comment if preferred:**
|
||||
```bash
|
||||
gh pr comment [number] --body "## Feature Demo
|
||||
|
||||

|
||||
|
||||
_Automated walkthrough of the changes in this PR_"
|
||||
```
|
||||
|
||||
</update_pr>
|
||||
|
||||
### 8. Cleanup
|
||||
|
||||
<cleanup>
|
||||
|
||||
```bash
|
||||
# Optional: Clean up screenshots
|
||||
rm -rf tmp/screenshots
|
||||
|
||||
# Keep videos for reference
|
||||
echo "Video retained at: tmp/videos/feature-demo.gif"
|
||||
```
|
||||
|
||||
</cleanup>
|
||||
|
||||
### 9. Summary
|
||||
|
||||
<summary>
|
||||
|
||||
Present completion summary:
|
||||
|
||||
```markdown
|
||||
## Feature Video Complete
|
||||
|
||||
**PR:** #[number] - [title]
|
||||
**Video:** [url or local path]
|
||||
**Duration:** ~[X] seconds
|
||||
**Format:** [GIF/MP4]
|
||||
|
||||
### Shots Captured
|
||||
1. [Starting point] - [description]
|
||||
2. [Navigation] - [description]
|
||||
3. [Feature demo] - [description]
|
||||
4. [Result] - [description]
|
||||
|
||||
### PR Updated
|
||||
- [x] Video section added to PR description
|
||||
- [ ] Ready for review
|
||||
|
||||
**Next steps:**
|
||||
- Review the video to ensure it accurately demonstrates the feature
|
||||
- Share with reviewers for context
|
||||
```
|
||||
|
||||
</summary>
|
||||
|
||||
## Quick Usage Examples
|
||||
|
||||
```bash
|
||||
# Record video for current branch's PR
|
||||
/feature-video
|
||||
|
||||
# Record video for specific PR
|
||||
/feature-video 847
|
||||
|
||||
# Record with custom base URL
|
||||
/feature-video 847 http://localhost:5000
|
||||
|
||||
# Record for staging environment
|
||||
/feature-video current https://staging.example.com
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- **Keep it short**: 10-30 seconds is ideal for PR demos
|
||||
- **Focus on the change**: Don't include unrelated UI
|
||||
- **Show before/after**: If fixing a bug, show the broken state first (if possible)
|
||||
- **Annotate if needed**: Add text overlays for complex features
|
||||
Reference in New Issue
Block a user