Add your description here
Project description
Turn big changes into pull requests reviewers can follow.
Shortcake helps you build a feature as a stack of small, review-sized branches, see the order at a glance, and submit matching GitHub PRs from your terminal.
The whole stack is reconstructed from your commits. Each branch records its parent in a git trailer — no state files, no metadata branch, no daemon. Rebase, push, checkout, and branch with the tools you already use; the stack travels with your Git history.
feat: add login form
Shortcake-Parent: main
That one marker is why Shortcake can recover the order after rebases, checkouts, and pushes without a separate state file to keep in sync.
Why stacked PRs?
Big pull requests are hard to review. Stacked branches let you send a large change in the order it should be read — foundation first, follow-ups after — so each PR stays focused on one idea instead of the whole feature. Shortcake keeps that order visible and submits PRs with bases that match it, so reviewers always know what builds on what.
Install
uv tool install shortcake
Requires Python 3.14+. The install exposes both shortcake and the short alias sc.
Other ways to install
# pipx
pipx install shortcake
Quick start
Build a two-branch stack, look at it, and open the PRs — start to finish.
1. Create a branch from your staged changes. sc create commits what's staged and records
main as the parent.
$ echo "def login(): ..." > login.py && git add login.py
$ sc create -m "Add login form"
Created branch 'add-login-form' from 'main'
2. Stack the next change on top. Run create again — the new branch's parent is the one
you're on.
$ echo "def reset(): ..." > reset.py && git add reset.py
$ sc create -m "Add password reset"
Created branch 'add-password-reset' from 'add-login-form'
3. See the stack with sc ls:
$ sc ls
◉ add-password-reset (current)
│
◯ add-login-form
│
◯ main
4. Submit the stack to GitHub. sc submit pushes every branch and opens (or updates) a PR
for each, with bases that match the stack. Add --draft/-d for drafts, --dry-run/-n
to preview first, or --stealth to push without creating or updating PRs.
$ sc submit
Pushing 'add-login-form'...
Creating PR for 'add-login-form'...
Created PR #1: https://github.com/you/repo/pull/1
Pushing 'add-password-reset'...
Creating PR for 'add-password-reset'...
Created PR #2: https://github.com/you/repo/pull/2
Created 2 PR(s)
Each PR description gets a stack map showing the order and which PR you're looking at, and
sc ls now shows the PR numbers:
$ sc ls
◉ add-password-reset #2 (current)
│
◯ add-login-form #1
│
◯ main
sc submitnormally needs a GitHub token (fromgh auth login, orGH_TOKEN/GITHUB_TOKEN) and anoriginremote pointing at GitHub.sc submit --stealthonly pushes branches, so it does not need the GitHub API token. Submit restacks branches before pushing and uses--force-with-leaseso it won't clobber others' work.
That's the core loop: create → ls → submit. The rest of the CLI is there when you
need to move, split, restack, or repair branches.
How it works
The stack is rebuilt entirely from the Shortcake-Parent trailer in each branch's first
commit. ls/log walk parent → children, and restack rebases descendants whenever a parent
moves. Because the relationship lives in the commit, the stack survives rebasing, pushing, and
branching with any Git tooling — there's nothing else to keep in sync.
Already started a branch the normal way? sc adopt brings an existing branch into a stack
instead of recreating it.
Commands
| Build the stack | create (new tracked branch; --before/--after to insert) · adopt (track an existing branch) |
| Edit the stack | modify · fold · reorder · move · split (move files into a new stacked branch) |
| Restack | restack (rebase children when a parent changes) · continue · abort (resume/abandon after a conflict) |
| Navigate & inspect | up · down · top · bottom · checkout (alias co) · ls · log |
| GitHub & remote | submit (open/update stacked PRs) · sync · pull · review |
| Web UI | ui |
Run sc <command> --help for the options on any command.
Review the stack in your browser
sc ui
Opens a local, GitHub-style view of every branch diff — file tree, inline comments, and AI review — reading straight from your repo. Nothing leaves your machine.
You can also review a branch from the terminal with sc review, which runs the change through
an installed AI CLI (claude or codex).
Working with coding agents
Shortcake is built to be driven by agents as well as humans: every core command takes
--json (exactly one JSON document on stdout — {"data": ...} or
{"error": {"code", "message", "hint"}}), sc sync never blocks on prompts in
non-interactive shells, and pre-commit formatter failures self-heal.
Shortcake ships a workflow skill that teaches an agent the stacked-PR model. Install it for Claude Code with:
mkdir -p .claude/skills/shortcake-stacked-prs
sc skill --print shortcake-stacked-prs > .claude/skills/shortcake-stacked-prs/SKILL.md
Or paste this into your project's CLAUDE.md / agent instructions:
This repo uses shortcake (`sc`) for stacked PRs. Read the workflow first:
run `sc skill --print shortcake-stacked-prs`. Key points: use `sc ls --json`
to read the stack, `sc create -m` / `sc modify` / `sc split` to shape it,
`sc restack` + `sc continue` for rebases, and `sc submit` for PRs. Pass
`--json` to any of these for machine-readable output.
Development
# Tests + coverage (must stay at 100%)
uv run pytest tests/ -v --cov=src/shortcake --cov-report=term
uv run coverage report --fail-under=100
# CLI end-to-end tests (executable markdown docs in e2e/docs/)
uv run python e2e/markdown_runner.py
# Browser e2e for the web UI (one-time: uv run playwright install --with-deps chromium)
uv run pytest tests/e2e/ -v
# Lint, format, and type-check
uv run --group linting ruff check src/ tests/
uv run --group linting ruff format --check src/ tests/
uv run --group typing ty check src/
See CLAUDE.md for the project layout and conventions.
License
MIT © Patrick Arminio. If Shortcake is useful to you, consider sponsoring. 🍰
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file shortcake-1.3.0.tar.gz.
File metadata
- Download URL: shortcake-1.3.0.tar.gz
- Upload date:
- Size: 227.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
073a7d357fce9330c48f3f48aaf3e1056cb4361811f2947c193c1f7507bd9626
|
|
| MD5 |
51703e79594322a7194cb751f89f1b2e
|
|
| BLAKE2b-256 |
80680de609e4dbfa27ff222d36f224ea9e934823a0f677adbe3cf9cadf5987f2
|
File details
Details for the file shortcake-1.3.0-py3-none-any.whl.
File metadata
- Download URL: shortcake-1.3.0-py3-none-any.whl
- Upload date:
- Size: 255.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3e18f6f763fbf899e684f070fab1b6396c80b5285fa551ab16895c02fe79975
|
|
| MD5 |
1fe503b6effcc3cc6bae13dc5bc8159f
|
|
| BLAKE2b-256 |
d156c42ef8fa18c50d170a1957d5317ffa1eee21866052d908391f29ff363410
|