stacked-prs
A tool for managing stacked branches and pull requests. Available as a
standalone CLI (via Homebrew or JSR) and as a Claude Code plugin that works
through Claude: you issue natural language requests or
/stacked-prs <subcommand>, and Claude orchestrates git, gh, and Deno helper
scripts on your behalf.
Installation
Homebrew (standalone CLI)
Install the stacked-prs binary for direct terminal use (no Deno required):
brew tap wyattjoh/stable
brew install stacked-prs
After install, stacked-prs is in your PATH. Run the interactive TUI with:
stacked-prs status --interactive
JSR (standalone CLI)
Install the Deno-based CLI from JSR:
deno install --global --allow-run=git,gh,pbcopy,xclip,wl-copy --allow-env --allow-read -n stacked-prs jsr:@wyattjoh/stacked-prs
This installs the same command name:
stacked-prs status --interactive
The Homebrew binary gives you direct CLI access. For the AI-orchestrated
workflow (Claude plans and confirms every write operation), use the Claude
Code plugin path below.
Claude Code plugin
This is a Claude Code plugin distributed through the
wyattjoh/claude-code-marketplace.
From inside Claude Code, add the marketplace and then install the plugin:
/plugin marketplace add wyattjoh/claude-code-marketplace
/plugin install wyattjoh/stacked-prs
After install, the stacked-prs skill auto-loads on relevant prompts and is
also user-invocable as /stacked-prs <subcommand>.
Prerequisites
- git 2.38+ (required for
--update-refs during rebase)
- gh CLI (authenticated, for PR operations)
- Deno (runs the helper scripts bundled with the skill)
How it works
Storage model
Stack metadata lives entirely in local git config:
branch.<name>.stack-name = my-stack
branch.<name>.stack-parent = main
stack.<stack-name>.merge-strategy = squash
stack.<stack-name>.base-branch = main
No files are added to the working tree. Metadata is per-repo and survives branch
switches, stashes, and worktree changes.
Tree model
Stacks are tree-shaped, not strictly linear. Multiple branches can share the
same parent, creating a fork:
main
└── feature/auth
├── feature/auth-api
│ └── feature/auth-api-v2
└── feature/auth-tests
└── feature/auth-ui
You can start a second branch off any point in the stack without disrupting
existing branches. When the bottom PR lands, if the remaining branches have
different parents (the stack forks), they are automatically split into separate
stacks. Sibling order is alphabetical by branch name; topology is derived from
stack-parent relationships, no ordering metadata is stored.
Execution model
Claude reads the SKILL.md runbook and acts as the orchestrator:
- Reads state by running Deno scripts (
cli.ts status,
cli.ts restack --json, etc.)
- Presents a plan describing every write operation (rebase, push, PR
create)
- Waits for your confirmation before executing anything destructive
- Executes git and gh commands, then reports results
If a rebase hits conflicts mid-execution, Claude pauses and re-presents the
remaining plan before continuing.
Safety guarantees
All write operations require explicit confirmation:
| Always requires confirmation | Always allowed (read-only) |
|---|
git push, git rebase | git status, git log, git fetch |
git branch -d | gh pr list, gh pr view, gh repo view |
gh pr create, gh pr edit | cli.ts status, cli.ts verify-refs |
gh pr comment, gh api PATCH | cli.ts nav --dry-run |
Commands
/stacked-prs init
Register the current branch as a new stack. Prompts for a stack name and merge
strategy (merge or squash), then writes git config metadata. The current branch
becomes the root with main as its parent.
/stacked-prs import
Discover and register an existing tree of branches as a stack. Walks the git
graph between your current branch and main, detects PR base mismatches, and
warns you. After confirmation, writes config for all discovered branches at
once.
/stacked-prs create
Add a new child branch off the current branch. The new branch becomes a child of
the current branch in the stack tree. If you have staged changes, Claude offers
to commit them.
When run from the repo's default branch (e.g. main), create auto-inits a new
stack so you do not need to run init first.
Pass --create-worktree <dir> to eject the new branch into a git worktree at
the given directory, keeping your current working tree clean.
/stacked-prs insert