From ac-git
Manages GitHub orphan 'assets' branch for persistent PR screenshot/video hosting. Uploads Playwright E2E outputs, generates raw URLs, bypasses transient CDN tokens.
npx claudepluginhub waterplanai/agentic-config --plugin ac-gitThis skill is limited to using the following tools:
Automates the "assets branch" strategy for persistent image hosting in GitHub PRs. Solves the problem of transient CDN tokens (`?jwt=...`) that expire on private repo images.
Records browser interactions as a video walkthrough of a feature, stitches screenshots into MP4 with ffmpeg, uploads to GitHub, and embeds in PR description. Useful for visual PR demos and reviewer walkthroughs.
Records browser interactions into MP4 feature demo video, uploads to GitHub, and embeds in PR description for reviewer walkthroughs.
Captures demo reels (GIFs, terminal recordings, screenshots) of UI changes, CLI features, or product behaviors for PR descriptions. Detects project type, handles secrets, uploads publicly, and provides markdown.
Share bugs, ideas, or general feedback.
Automates the "assets branch" strategy for persistent image hosting in GitHub PRs. Solves the problem of transient CDN tokens (?jwt=...) that expire on private repo images.
CRITICAL: When using playwright-cli for E2E testing, video recording is explicit.
Start and stop recording explicitly with playwright-cli:
playwright-cli video-start # Start recording
# ... perform browser actions ...
playwright-cli video-stop # Stop and save video file
outputs/e2e/ directory (or configured outputDir)playwright-cli.json saveVideo settings (default: 1920x1080)When adding visual evidence to PRs:
| Evidence Type | Source | Tool |
|---|---|---|
| Screenshots | playwright-cli screenshot | Direct capture via Bash |
| Video | outputs/e2e/*.webm | Use recorded file |
DO NOT re-record video when adding video evidence. Use the file from the E2E session.
playwright-cli screenshot during E2E validationvideo-stop), find the video in outputs/e2e/# Upload all evidence (screenshots + video)
/gh-assets-branch-mgmt upload outputs/screenshots/*.png outputs/e2e/*.webm --context pr-42
The video will be automatically converted to H.264 MP4 (8x speed) + GIF for PR embedding.
| Command | Description |
|---|---|
init | Create orphan assets branch if not exists |
upload <files/glob> --context <id> | Upload files to assets branch under context path |
list --context <id> | List all assets for a context |
cleanup --context <id> | Remove all assets for a context |
url <file> --context <id> | Get raw URL for a specific file |
convert-video <input> [options] | Convert video to optimized H.264 MP4 |
download-video <context> [options] | Download videos from assets branch |
/gh-assets-branch-mgmt init
Creates an orphan assets branch with no commit history using Git's well-known empty tree SHA.
/gh-assets-branch-mgmt upload outputs/screenshots/*.png --context pr-42
Uploads all matching files to assets branch under pr-42/ path.
/gh-assets-branch-mgmt url screenshot.png --context pr-42
Returns: https://raw.githubusercontent.com/OWNER/REPO/assets/pr-42/screenshot.png
Videos are automatically converted and uploaded as both GIF + MP4:
/gh-assets-branch-mgmt upload ./recording.mov --context pr-42
The tool:
Output format:

[Download Recording](https://github.com/.../recording_converted.mp4?raw=true)
Why both? GIF embeds inline, MP4 provides full quality download option.
Note: Videos are sped up 8x by default (144s input -> 18s output). Audio is dropped.
/gh-assets-branch-mgmt convert-video ./demo.mov --preset pr-medium
Video Options:
--preset <name> - Compression preset (see table below)--max-size <mb> - Target file size in MB (enables two-pass encoding)--output <path> - Custom output path--speed <factor> - Playback speed multiplier (default: 8 = 8x faster)GIF Options:
--gif - Also generate GIF from output MP4--gif-only - Generate only GIF, remove MP4 after--gif-fps <n> - GIF frame rate (default: 10)--gif-width <px> - GIF max width (default: 720)Examples:
# Default: 8x speed, pr-small preset (MP4 only)
./gh-video-convert.sh demo.mov
# Generate MP4 + GIF
./gh-video-convert.sh demo.mov --gif
# Generate only GIF (no MP4 kept)
./gh-video-convert.sh demo.mov --gif-only
# Custom GIF settings
./gh-video-convert.sh demo.mov --gif --gif-width 1080 --gif-fps 24
# Original speed (no speedup)
./gh-video-convert.sh demo.mov --speed 1
Processing Pipeline:
Input Video -> MP4 (scaled, sped up) -> GIF (from MP4)
The GIF is always generated from the output MP4, ensuring visual consistency.
| Preset | Target Size | Resolution | CRF | Use Case |
|---|---|---|---|---|
pr-small | ~8MB | 720p | 28 | GitHub free plan, short demos |
pr-medium | ~25MB | 720p | 24 | Longer demos |
pr-large | ~50MB | 1080p | 23 | High quality demos |
demo | ~80MB | 1080p | 20 | Maximum quality |
Download uploaded videos from the assets branch:
/gh-assets-branch-mgmt download-video pr-42
Downloads the latest video and opens it automatically.
Options:
--all - Download all videos (default: latest only)--list - List videos without downloading--no-open - Don't open video after download--output <dir> - Download directory (default: /tmp)--repo <owner/repo> - Repository (default: current repo)Examples:
# Download & open latest video
./gh-assets-download.sh pr-42
# Download all videos
./gh-assets-download.sh pr-42 --all
# List available videos
./gh-assets-download.sh pr-42 --list
# Download to specific directory
./gh-assets-download.sh pr-42 --output ./downloads
/gh-assets-branch-mgmt cleanup --context pr-42
Removes all files under pr-42/ from the assets branch.
Uses Git's well-known empty tree SHA to create a branch with no history:
EMPTY_TREE="4b825dc642cb6eb9a060e54bf8d69288fbee4904"
COMMIT=$(gh api repos/$OWNER/$REPO/git/commits -X POST \
-f message="chore: initialize assets branch" \
-f tree="$EMPTY_TREE" --jq '.sha')
gh api repos/$OWNER/$REPO/git/refs -X POST \
-f ref="refs/heads/assets" -f sha="$COMMIT"
CRITICAL: Files must be uploaded sequentially (not in parallel). Use the bash script:
./gh-assets-upload.sh <source-dir> <context> <owner/repo>
Each file is uploaded via GitHub Contents API with inline base64 encoding:
gh api repos/OWNER/REPO/contents/{context}/{filename} -X PUT \
-f message="assets({context}): add {filename}" \
-f content="$(base64 -i {filepath})" \
-f branch="assets" \
--jq '.content.sha'
Use blob URL with ?raw=true for embedding (works for both public and private repos):
https://github.com/{owner}/{repo}/blob/assets/{context}/{filename}?raw=true
Markdown syntax:

assets/
├── pr-1/
│ ├── screenshot1.png
│ └── screenshot2.png
├── pr-42/
│ └── demo.gif
└── README.md (optional)
Scripts are located in this skill directory:
gh-assets-upload.sh - Batch upload with auto video conversiongh-video-convert.sh - Standalone video conversion toolgh-assets-download.sh - Download videos from assets branchUsage (from skill directory):
./gh-assets-upload.sh ./screenshots pr-42
./gh-video-convert.sh demo.mov --gif
./gh-assets-download.sh pr-42
[a-z0-9-]+For private repos, use the blob URL with ?raw=true format:

URL Format Comparison:
| Format | Private Repo | Public Repo |
|---|---|---|
raw.githubusercontent.com/.../assets/... | 404 | Works |
github.com/.../blob/assets/...?raw=true | Works | Works |
Correct Pattern:
https://github.com/{owner}/{repo}/blob/assets/{context}/{filename}?raw=true
GitHub has different video size limits by plan:
| Plan | Max Video Size |
|---|---|
| Free | 10MB |
| Paid | 100MB |
Use --preset pr-small for free plan compatibility, or --max-size <mb> for precise control.
| Duration | Approx GIF Size (720px, 10fps) |
|---|---|
| 10s | ~5-8MB |
| 30s | ~15-25MB |
| 60s | ~25-40MB |
For large GIFs, try --gif-width 480 or --gif-fps 8.
--speed 1 to preserve audio)