Stacked PRs for GitHub — agent-first CLI for parallel development
Project description
ez
Agent-first version control. Stacked PRs, worktree isolation, zero friction.
ez makes version control invisible for AI coding agents. Four commands cover the entire development lifecycle. Multiple agents work on the same repo without stepping on each other.
Install
pip install ez-stack
ez setup --yes
ez init
The 4 Commands
ez create feat/auth # Start: worktree + branch + cd
ez push -am "feat: add auth" # Ship: stage + commit + push + PR
ez sync --autostash # Sync: pull trunk, clean merged, restack
ez delete feat/auth --yes # Done: remove worktree + branch
That's it. No git add, no git commit, no gh pr create, no cd.
Why ez?
For agents: Each ez create gives the agent an isolated worktree. Multiple agents work in parallel on the same repo without merge conflicts. Structured JSON output, mutation receipts, and exit codes let agents verify every operation.
For humans: Stacked PRs become effortless. Auto-restacking, auto-cleanup of merged branches, and a dashboard that shows everything at a glance.
Dashboard
ez list
BRANCH PR CI AGE PORT STATUS
--------------------------------------------------------------------------------
main (trunk) - - 2m - -
* feat/auth #42 ✓ 5m 14832 clean
feat/api #43 ⏳ 15m 11247 2M 1U
feat/ui - - 1h 16503 no worktree
Shows all local branches with PR status, CI pass/fail, time since last commit, deterministic dev port per worktree, and working tree state. Branches not tracked by ez still appear and are labeled not tracked. ez list --json for machine output.
Multi-Agent Workflow
# Agent 1 (terminal 1)
ez create feat/auth --from main
# ... works in .worktrees/feat-auth ...
ez push -am "feat: auth system"
# Agent 2 (terminal 2, same repo)
ez create feat/api --from main
# ... works in .worktrees/feat-api ...
ez push -am "feat: API routes"
# No conflicts. Each agent has its own worktree.
Stacked PRs
# Build a stack of dependent changes
ez create feat/auth-types
ez commit -m "add auth types"
ez create feat/auth-api # stacks on auth-types
ez commit -m "add auth API"
ez submit # pushes all, creates PRs with correct bases
# After the first PR merges:
ez sync # cleans up, restacks remaining branches
Scope Guard
Keep an agent focused on the files a branch is supposed to touch:
ez create feat/auth --scope 'src/auth/**' --scope 'tests/auth/**'
ez scope show
ez scope add 'benches/auth/**'
ez scope set --mode strict 'src/auth/**' 'tests/auth/**'
With scope configured, ez commit and ez push -am check the staged file set before mutating git state. In warn mode they print drift and continue. In strict mode they stop.
Worktree Hooks
Create .ez/hooks/post-create/default.md to give agents setup instructions:
# Worktree Setup
1. `npm install`
2. `cp .env.example .env`
3. Start dev server on port $EZ_PORT
Hooks are markdown instructions, not scripts. ez prints them, the agent follows them.
Use --hook <name> for project-specific hooks, or --hook alone to list available hooks.
All Commands
Flagship
| Command | Description |
|---|---|
ez create <name> |
Create worktree + branch (default). --from main for independent work. --no-worktree for branch only. |
ez list |
Dashboard for all local branches: PRs, CI, age, ports, and working tree state. --json for machine output. |
ez delete [name] |
Delete branch + worktree. Auto-detects worktrees and best-effort stops listeners on the branch dev port. --yes for agents. |
ez push |
Push + create/update PR. -am "msg" to stage+commit+push in one step. |
Committing
| Command | Description |
|---|---|
ez commit -m "msg" |
Commit the current staged set + restack children |
ez commit -am "msg" |
Stage tracked files + commit |
ez commit -m "msg" -- path1 path2 |
Stage specific files + commit |
ez commit --if-changed |
No-op if nothing staged |
ez amend |
Amend last commit + restack |
Intended workflow:
- Focused commit:
ez commit -m "msg" -- path1 path2 - Bulk update:
ez commit -am "msg" - Partial hunks:
git add -pthenez commit -m "msg"
Scope
| Command | Description |
|---|---|
ez scope show |
Show the current branch's configured scope |
ez scope add <pattern...> |
Append patterns to the current branch's scope |
ez scope set <pattern...> |
Replace the current branch's scope |
ez scope clear |
Remove scope configuration from the current branch |
Syncing
| Command | Description |
|---|---|
ez sync |
Fetch trunk, clean merged branches, restack |
ez sync --autostash |
Stash before sync, restore after |
ez sync --dry-run |
Preview what sync would do |
ez restack |
Fetch trunk, refresh it locally, and rebase stale branches onto their latest parent tips |
Navigation
| Command | Description |
|---|---|
ez switch <name> |
Switch to branch (cd's to worktree if applicable) |
ez switch <pr-number> |
Switch by PR number |
ez up / ez down |
Navigate the stack |
ez top / ez bottom |
Jump to stack endpoints |
Inspection
| Command | Description |
|---|---|
ez log |
Visual stack tree with PR status |
ez log --json |
Stack as JSON |
ez status |
Branch info + working tree state |
ez status --json |
Branch info as JSON |
ez diff |
Diff vs parent (what the PR reviewer sees) |
ez diff --stat |
Diffstat summary |
ez diff --name-only |
Changed file names |
ez parent |
Print parent branch name to stdout |
PRs
| Command | Description |
|---|---|
ez submit |
Push entire stack + create/update all PRs |
ez pr-link |
Print PR URL to stdout |
ez pr-edit --title "..." --body "..." |
Edit PR metadata |
ez draft / ez ready |
Toggle PR draft status |
ez merge |
Merge bottom PR via GitHub |
ez merge --yes |
Merge non-interactively for agents/scripts |
ez merge --stack --yes |
Merge the current linear stack bottom-to-top |
Setup
| Command | Description |
|---|---|
ez setup --yes |
Configure shell integration |
ez skill install |
Install the ez-workflow skill for AI agents |
ez update |
Update to latest version |
Agent Integration
Install the skill so agents auto-discover ez:
ez skill install
This writes the canonical skill to .agents/skills/ez-workflow/SKILL.md, then creates compatibility symlinks for agent-specific skill roots such as .claude/skills/ez-workflow and .codex/skills/ez-workflow.
See SKILL.md for the full agent workflow, and reference.md for the complete command reference.
How It Works
- Worktrees give each agent an isolated copy of the repo with its own branch
- Stack metadata in
.git/ez/stack.jsontracks branch parents and PR numbers - Auto-restacking via
git rebase --ontokeeps children up to date when parents change - Mutation receipts (JSON on stderr) let agents verify every operation
- Progressive help —
ez,ez <cmd>,ez <cmd> --helpeach give more detail
Prerequisites
- git 2.38+
- gh (GitHub CLI), authenticated via
gh auth login - Python 3.8+ (for
pip install) or download binaries from Releases
License
MIT. See LICENSE for details.
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 Distributions
Built Distributions
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 ez_stack-0.2.22-py3-none-manylinux_2_17_x86_64.whl.
File metadata
- Download URL: ez_stack-0.2.22-py3-none-manylinux_2_17_x86_64.whl
- Upload date:
- Size: 806.7 kB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08f538ee2a48c560fd757c9a45261fe76d880f8aad86d0ca561b587fdf51be6a
|
|
| MD5 |
9e4ec65aa0c49e7ccf4def6887f18f43
|
|
| BLAKE2b-256 |
59be1aa797ef6513d38fbe49140a7b922c76448bbdd58897f9a08b3f08b28b91
|
Provenance
The following attestation bundles were made for ez_stack-0.2.22-py3-none-manylinux_2_17_x86_64.whl:
Publisher:
python-wheel.yml on rohoswagger/ez-stack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ez_stack-0.2.22-py3-none-manylinux_2_17_x86_64.whl -
Subject digest:
08f538ee2a48c560fd757c9a45261fe76d880f8aad86d0ca561b587fdf51be6a - Sigstore transparency entry: 1275750335
- Sigstore integration time:
-
Permalink:
rohoswagger/ez-stack@73a01326b11d60a976cf8b6a3099ed185bce5223 -
Branch / Tag:
refs/tags/v0.2.22 - Owner: https://github.com/rohoswagger
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-wheel.yml@73a01326b11d60a976cf8b6a3099ed185bce5223 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ez_stack-0.2.22-py3-none-manylinux_2_17_aarch64.whl.
File metadata
- Download URL: ez_stack-0.2.22-py3-none-manylinux_2_17_aarch64.whl
- Upload date:
- Size: 735.6 kB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12d6aabebd5523b7a63f0c2d24d97c0e452a0dabff9644e494262b031ba53a65
|
|
| MD5 |
e8e1a471873cb32215acd26cc9b2f96b
|
|
| BLAKE2b-256 |
11c65c8981d19fe05e2d2bdc0f7ad99b79d53971196c4590e240eaaa4e70025a
|
Provenance
The following attestation bundles were made for ez_stack-0.2.22-py3-none-manylinux_2_17_aarch64.whl:
Publisher:
python-wheel.yml on rohoswagger/ez-stack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ez_stack-0.2.22-py3-none-manylinux_2_17_aarch64.whl -
Subject digest:
12d6aabebd5523b7a63f0c2d24d97c0e452a0dabff9644e494262b031ba53a65 - Sigstore transparency entry: 1275750170
- Sigstore integration time:
-
Permalink:
rohoswagger/ez-stack@73a01326b11d60a976cf8b6a3099ed185bce5223 -
Branch / Tag:
refs/tags/v0.2.22 - Owner: https://github.com/rohoswagger
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-wheel.yml@73a01326b11d60a976cf8b6a3099ed185bce5223 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ez_stack-0.2.22-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: ez_stack-0.2.22-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 714.5 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d61c8be75dce4ebd44494148b93ea45a95cd0055d8b3a4cd564487ad54c5c24
|
|
| MD5 |
1f3cd023add19d3223ed43da5318fbc5
|
|
| BLAKE2b-256 |
02f3adf64b862406ed6ee1264f69173736ee47406d5c9ee94d8a80af5a2d3912
|
Provenance
The following attestation bundles were made for ez_stack-0.2.22-py3-none-macosx_11_0_arm64.whl:
Publisher:
python-wheel.yml on rohoswagger/ez-stack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ez_stack-0.2.22-py3-none-macosx_11_0_arm64.whl -
Subject digest:
2d61c8be75dce4ebd44494148b93ea45a95cd0055d8b3a4cd564487ad54c5c24 - Sigstore transparency entry: 1275750238
- Sigstore integration time:
-
Permalink:
rohoswagger/ez-stack@73a01326b11d60a976cf8b6a3099ed185bce5223 -
Branch / Tag:
refs/tags/v0.2.22 - Owner: https://github.com/rohoswagger
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-wheel.yml@73a01326b11d60a976cf8b6a3099ed185bce5223 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ez_stack-0.2.22-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: ez_stack-0.2.22-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 773.8 kB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0ef55a807fbc13b04cb230067312bf6683ceb3eec9eb880151cf5866c02103e
|
|
| MD5 |
9f87e12dfefefd463a6d8bd182ad8b59
|
|
| BLAKE2b-256 |
7a8d7dfd49f9d7c4126cb25cd20b0d26461402987a72ed805ee52f17c965ed36
|
Provenance
The following attestation bundles were made for ez_stack-0.2.22-py3-none-macosx_10_12_x86_64.whl:
Publisher:
python-wheel.yml on rohoswagger/ez-stack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ez_stack-0.2.22-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
e0ef55a807fbc13b04cb230067312bf6683ceb3eec9eb880151cf5866c02103e - Sigstore transparency entry: 1275750413
- Sigstore integration time:
-
Permalink:
rohoswagger/ez-stack@73a01326b11d60a976cf8b6a3099ed185bce5223 -
Branch / Tag:
refs/tags/v0.2.22 - Owner: https://github.com/rohoswagger
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-wheel.yml@73a01326b11d60a976cf8b6a3099ed185bce5223 -
Trigger Event:
push
-
Statement type: