| name | stacked-pr |
| description | Create and update stacked pull requests. Use this after completing an implementation phase to commit changed files. |
Stacked PR Workflow
This skill enables Claude to create stacked pull requests using git-town automation scripts. Each phase becomes an atomic PR that builds on previous phases.
When to Use This Skill
Invoke this skill after completing a phase from /implement_plan when:
- All automated verification has passed (
just check-test) - User has confirmed manual verification is complete
- There are uncommitted changes ready to be stacked
DO NOT use this skill:
- Before verification is complete
- When there are no changes to commit
- For non-plan-based work (use standard git workflow instead)
Pre-Flight Checks
Before creating the stack, verify:
- Current git status shows modified/new files
- All tests and checks have passed
- You know the phase number and plan context
Workflow Instructions
Step 1: Determine Phase Type
Check the current branch to determine if this is Phase 1 or Phase N:
git branch --show-current
Decision Logic:
- If on
main: This is Phase 1 → Usejust new-stack - If on
phase-X-*: This is Phase N (where N = X + 1) → Usejust append-stack
Step 2: Prepare Arguments
Both scripts require the same arguments (in order):
- phase-num: The phase number (e.g.,
1,2,3) - branch-name: Short descriptive name (e.g.,
websocket-foundation,message-parser) - commit-msg: Full commit message (multiline string)
- pr-title: PR title (e.g.,
Phase 1: WebSocket Connection Foundation) - pr-body: PR body/description (multiline string)
Branch Naming Convention
- Format:
phase-N-<short-description> - Examples:
phase-1-websocket-foundationphase-2-message-parserphase-3-orderbook-state
Commit Message Format
<type>: <phase-summary>
Phase N: <detailed-description>
Changes:
- <key change 1>
- <key change 2>
- <key change 3>
<any relevant context or notes>
Types: feat, fix, refactor, test, chore, docs
PR Body Format
## Phase N: <Title>
### Summary
<1-2 sentence overview of what this phase accomplishes>
### Changes
- <key change 1>
- <key change 2>
- <key change 3>
### Stack
<!-- branch-stack -->
### Verification
- [x] All automated tests passed (\`just check-test\`)
- [x] Manual verification completed
- [x] Code follows project patterns
### Related
Part of implementation plan: [link to plan if available]
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Step 3: Execute the Appropriate Script
For Phase 1 (on main branch):
just new-stack \
"<phase-num>" \
"<branch-name>" \
"<commit-msg>" \
"<pr-title>" \
"<pr-body>"
For Phase N > 1 (on phase-X-* branch):
just append-stack \
"<phase-num>" \
"<branch-name>" \
"<commit-msg>" \
"<pr-title>" \
"<pr-body>"
Example Workflows
Example 1: Phase 1 (Starting New Stack)
# Current state check
$ git branch --show-current
main
$ git status
# Shows: modified files in src/connection/ (uncommitted)
# Execute new-stack
just new-stack \
"1" \
"websocket-foundation" \
"feat: Add WebSocket connection foundation
Phase 1: Implement core WebSocket connection logic
Changes:
- Add WebsocketConnection class with lifecycle management
- Implement exponential backoff reconnection strategy
- Add connection health monitoring
- Create connection stats tracking
Establishes the foundation for real-time market data streaming." \
"Phase 1: WebSocket Connection Foundation" \
"## Phase 1: WebSocket Connection Foundation
### Summary
Implements the core WebSocket connection class with automatic reconnection, health monitoring, and stats tracking.
### Changes
- Add WebsocketConnection class with lifecycle management
- Implement exponential backoff reconnection strategy (1s → 30s)
- Add connection health monitoring (60s silence detection)
- Create connection stats tracking
### Stack
<!-- branch-stack -->
### Verification
- [x] All automated tests passed (\`just check-test\`)
- [x] Manual verification: Connected to Polymarket API successfully
- [x] Code follows project patterns
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)"
What the script does:
- ✓ Verifies you're on
mainbranch - ✓ Checks for uncommitted changes
- ✓ Creates branch
phase-1-websocket-foundationviagit town hack - ✓ Commits changes (excluding
thoughts/directory) - ✓ Creates PR with
--base main - ✓ Syncs the stack
Example 2: Phase 2 (Extending Stack)
# Current state check
$ git branch --show-current
phase-1-websocket-foundation
$ git status
# Shows: modified files (uncommitted)
# Execute append-stack
just append-stack \
"2" \
"message-parser" \
"feat: Add message parsing with msgspec
Phase 2: Implement zero-copy message parser
Changes:
- Add msgspec-based message parser
- Define protocol structures for BookSnapshot, PriceChange, LastTradePrice
- Implement generator-based parsing for streaming
- Handle integer scaling for prices/sizes
Enables efficient parsing of WebSocket messages with zero-copy optimization." \
"Phase 2: Message Parser with msgspec" \
"## Phase 2: Message Parser with msgspec
### Summary
Implements zero-copy message parsing using msgspec, enabling efficient processing of WebSocket events.
### Changes
- Add msgspec-based MessageParser class
- Define protocol structures (BookSnapshot, PriceChange, LastTradePrice)
- Implement generator-based parsing for streaming
- Handle integer scaling (PRICE_SCALE=1000, SIZE_SCALE=100)
### Stack
<!-- branch-stack -->
Merge order: This PR should be merged after Phase 1.
### Verification
- [x] All automated tests passed (\`just check-test\`)
- [x] Manual verification: Parsed live messages successfully
- [x] Code follows project patterns
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)"
What the script does:
- ✓ Verifies you're NOT on
main(you must be on previous phase branch) - ✓ Auto-detects previous phase branch (
phase-1-websocket-foundation) - ✓ Checks for uncommitted changes
- ✓ Creates branch
phase-2-message-parserviagit town append - ✓ Commits changes (excluding
thoughts/directory) - ✓ Creates PR with
--base phase-1-websocket-foundation - ✓ Syncs the stack
Script Features
Both scripts automatically:
- Validate pre-conditions (branch state, uncommitted changes)
- Create properly named branches with git-town
- Stage changes (excluding
thoughts/directory) - Commit with your provided message
- Create GitHub PR with proper base branch
- Sync the stack after PR creation
- Provide clear output with emoji indicators
Common Issues and Solutions
Issue: "No uncommitted changes detected"
The script checks git status --porcelain. Ensure:
- You have modified, added, or deleted files
- Changes are not in the
thoughts/directory (which is excluded)
Issue: "Previous phase branch does not exist"
For append-stack, ensure:
- You're on the correct previous phase branch before running
- The branch name follows the
phase-N-*pattern
Issue: Wrong base branch in PR
Use GitHub CLI to fix:
gh pr edit <pr-number> --base <correct-base-branch>
Issue: Need to update an earlier phase
# Checkout the phase that needs changes
git checkout phase-N-<name>
# Make changes and commit
# ...
# Sync stack to propagate changes forward
git town sync --stack
Key Principles
- One phase = One PR: Each phase should be atomic with passing CI
- Sequential dependencies: Phase N+1 builds on Phase N
- Clear commit messages: Reference phase number and provide context
- Automatic base branches: Scripts handle this (Phase 1 → main, Phase N → Phase N-1)
- Always sync: Scripts automatically sync the stack after PR creation
- Thoughts excluded: Both scripts exclude the
thoughts/directory from commits
Integration with /implement_plan
This skill integrates with the /implement_plan workflow:
/implement_planimplements a phase- Automated verification runs (
just check-test) - Claude pauses for manual verification
- User confirms: "Manual verification complete"
- Claude invokes stacked-pr skill
- Skill executes appropriate script (new-stack or append-stack)
- PR created and stack synced
- Ready for next phase
Notes
- Uses
git-townfor stack management - PRs created using GitHub CLI (
gh) - Main branch is
main(configured in git-town) - Stack branches should be merged in order (Phase 1, then 2, then 3, etc.)
- After all phases are merged, the stack is automatically cleaned up by git-town
- The
thoughts/directory is automatically excluded from all commits