{"id":34966338,"url":"https://github.com/cesarferreira/stax","last_synced_at":"2026-05-22T01:04:22.390Z","repository":{"id":330229454,"uuid":"1122030229","full_name":"cesarferreira/stax","owner":"cesarferreira","description":"The fastest stacked-branch workflow for Git. Interactive TUI, smart PRs, safe undo. Written in Rust.","archived":false,"fork":false,"pushed_at":"2026-04-27T18:05:42.000Z","size":5888,"stargazers_count":85,"open_issues_count":12,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-27T20:29:18.250Z","etag":null,"topics":["freephite","git","graphite","prs","stack","stacked","stacks"],"latest_commit_sha":null,"homepage":"https://cesarferreira.com/stax/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cesarferreira.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-12-24T01:43:15.000Z","updated_at":"2026-04-27T18:05:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"268a194d-419b-47c7-beb3-82a9dfe3a9c8","html_url":"https://github.com/cesarferreira/stax","commit_stats":null,"previous_names":["cesarferreira/stax"],"tags_count":88,"template":false,"template_full_name":null,"purl":"pkg:github/cesarferreira/stax","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cesarferreira%2Fstax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cesarferreira%2Fstax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cesarferreira%2Fstax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cesarferreira%2Fstax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cesarferreira","download_url":"https://codeload.github.com/cesarferreira/stax/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cesarferreira%2Fstax/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32495949,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["freephite","git","graphite","prs","stack","stacked","stacks"],"created_at":"2025-12-26T23:08:34.310Z","updated_at":"2026-05-22T01:04:22.377Z","avatar_url":"https://github.com/cesarferreira.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003estax\u003c/h1\u003e\n\n  \u003cp\u003e\u003cstrong\u003eStacked Git branches and PRs — fast, safe, and built for humans and AI agents.\u003c/strong\u003e\u003c/p\u003e\n\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/cesarferreira/stax/actions/workflows/rust-tests.yml\"\u003e\u003cimg alt=\"CI\" src=\"https://github.com/cesarferreira/stax/actions/workflows/rust-tests.yml/badge.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://crates.io/crates/stax\"\u003e\u003cimg alt=\"Crates.io\" src=\"https://img.shields.io/crates/v/stax\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/cesarferreira/stax/releases\"\u003e\u003cimg alt=\"Release\" src=\"https://img.shields.io/github/v/release/cesarferreira/stax?color=blue\"\u003e\u003c/a\u003e\n    \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-green\"\u003e\n  \u003c/p\u003e\n\n  \u003cp\u003e\n    \u003ca href=\"#install\"\u003eInstall\u003c/a\u003e\n    \u0026nbsp;·\u0026nbsp;\n    \u003ca href=\"#quickstart\"\u003eQuickstart\u003c/a\u003e\n    \u0026nbsp;·\u0026nbsp;\n    \u003ca href=\"#commands\"\u003eCommands\u003c/a\u003e\n    \u0026nbsp;·\u0026nbsp;\n    \u003ca href=\"https://cesarferreira.github.io/stax/\"\u003eDocs\u003c/a\u003e\n  \u003c/p\u003e\n\n  \u003cbr\u003e\n\n  \u003cimg src=\"assets/screenshot.png\" width=\"880\" alt=\"stax in action\"\u003e\n\u003c/div\u003e\n\n---\n\n## Why stax\n\nOne giant PR is slow to review and risky to merge. A stack of small PRs is the answer — but managing stacks by hand with `git rebase --onto` is a footgun. **stax** makes stacks a first-class Git primitive.\n\n- **Stack, don't wait.** Keep shipping on top of in-review PRs. `st create`, `st ss`, done.\n- **Native-fast.** A single Rust binary that starts in ~25ms. `st ls` benches ~70× faster than Graphite and ~215× faster than Freephite on this repo.\n- **Agent-native.** Run parallel AI agents on isolated branches (`st lane`), auto-resolve rebase conflicts (`st resolve`), and generate branch names, commit messages, and PR details from real diffs.\n- **Undo-first.** Every destructive op snapshots state. `st undo` / `st redo` rescue risky rebases instantly.\n- **Batteries-included TUI.** Run bare `st` to browse the stack, inspect diffs, and watch CI hydrate live.\n\n\u003e `stax` installs two binaries: `stax` and the short alias `st`. This README uses `st`.\n\n## Install\n\nThe shortest path on macOS and Linux:\n\n```bash\nbrew install cesarferreira/tap/stax\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eOther installation methods\u003c/strong\u003e — cargo-binstall, prebuilt binaries, Windows, from source\u003c/summary\u003e\n\n### cargo-binstall\n\n```bash\ncargo binstall stax\n```\n\n### Prebuilt binaries\n\nDownload the latest binary from [GitHub Releases](https://github.com/cesarferreira/stax/releases):\n\n```bash\n# macOS (Apple Silicon)\ncurl -fsSL https://github.com/cesarferreira/stax/releases/latest/download/stax-aarch64-apple-darwin.tar.gz | tar xz\n# macOS (Intel)\ncurl -fsSL https://github.com/cesarferreira/stax/releases/latest/download/stax-x86_64-apple-darwin.tar.gz | tar xz\n# Linux (x86_64)\ncurl -fsSL https://github.com/cesarferreira/stax/releases/latest/download/stax-x86_64-unknown-linux-gnu.tar.gz | tar xz\n# Linux (arm64)\ncurl -fsSL https://github.com/cesarferreira/stax/releases/latest/download/stax-aarch64-unknown-linux-gnu.tar.gz | tar xz\n\nmkdir -p ~/.local/bin\nmv stax st ~/.local/bin/\n# Ensure ~/.local/bin is on your PATH:\n# echo 'export PATH=\"$HOME/.local/bin:$PATH\"' \u003e\u003e ~/.zshrc\n```\n\n**Windows (x86_64):** download `stax-x86_64-pc-windows-msvc.zip` from [Releases](https://github.com/cesarferreira/stax/releases), extract `stax.exe` and `st.exe`, and place them on your `PATH`. See [Windows notes](#windows-notes).\n\n### Build from source\n\nPrereqs:\n- Debian/Ubuntu: `sudo apt-get install libssl-dev pkg-config`\n- Fedora/RHEL: `sudo dnf install openssl-devel`\n- Arch: `sudo pacman -S openssl pkg-config`\n- macOS: OpenSSL included\n\nThen:\n\n```bash\ncargo install --path . --locked\n# or\nmake install\n# or\ntask install\n```\n\nNo system OpenSSL? Use the vendored feature:\n\n```bash\ncargo install --path . --locked --features vendored-openssl\n```\n\n\u003c/details\u003e\n\nVerify the install:\n\n```bash\nst --version\n```\n\n\u003ca id=\"quickstart\"\u003e\u003c/a\u003e\n## Quickstart\n\n`st setup` handles shell integration, AI agent skills, and GitHub auth in a single step:\n\n```bash\nst setup --yes\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eAlternative auth options\u003c/summary\u003e\n\n```bash\n# Import from GitHub CLI\ngh auth login \u0026\u0026 st auth --from-gh\n\n# Enter a token interactively\nst auth\n\n# Or via env var\nexport STAX_GITHUB_TOKEN=\"ghp_xxxx\"\n```\n\nBy default stax ignores ambient `GITHUB_TOKEN`. Opt in with `auth.allow_github_token_env = true`.\n\n\u003c/details\u003e\n\nNow ship a two-branch stack end-to-end:\n\n```bash\n# 1. Stack two branches on trunk\nst create auth-api\nst create auth-ui\n\n# 2. See the stack\nst ls\n# ◉  auth-ui        1↑\n# ○  auth-api       1↑\n# ○  main\n\n# 3. Submit the whole stack as linked PRs\nst ss\n\n# 4. After the bottom PR merges on GitHub…\nst update          # sync trunk, restack this stack, update PRs\n```\n\nPicked the wrong trunk? Run `st trunk main` or `st init --trunk \u003cbranch\u003e` to reconfigure.\n\nNext: [Quick Start guide](docs/getting-started/quick-start.md) · [Merge \u0026 cascade workflow](docs/workflows/merge-and-cascade.md)\n\n## Highlights\n\n### Parallel AI lanes\n\nSpin up multiple AI agents on isolated branches, all tracked as normal stax branches:\n\n```bash\nst lane fix-auth-refresh \"Fix the token refresh edge case from #142\"\nst lane stabilize-ci     \"Stabilize the 3 flaky tests in the checkout flow\"\nst lane api-docs         \"Update API docs for the /users endpoint\"\n```\n\nEach lane is a real Git worktree with normal stax metadata — it appears in `st ls`, participates in restack/sync/undo, and re-attaches via tmux any time. No hidden scratch directories, no lost work.\n\n```bash\nst wt         # open the worktree dashboard\nst wt rs      # restack every lane at once when trunk moves\nst ss         # submit PRs for the ones that are ready\n```\n\n→ [Agent worktrees](docs/workflows/agent-worktrees.md) · [Multi-worktree workflow](docs/workflows/multi-worktree.md)\n\n### Cascade stack merge\n\nMerge from the bottom of the stack up to your current branch, with CI and readiness checks:\n\n```bash\nst merge                  # local cascade merge\nst merge --when-ready     # wait/poll until PRs are mergeable\nst merge --ds             # merge ancestors, rebase current branch\nst merge --remote         # merge remotely on GitHub while you keep working\nst merge --all            # merge the whole stack regardless of position\n```\n\n→ [Merge and cascade](docs/workflows/merge-and-cascade.md)\n\n### AI conflict resolution\n\nWhen a rebase stops on a conflict, `st resolve` sends only the conflicted text files to your configured AI agent, applies the result, and resumes the rebase automatically. If the AI returns invalid output, touches a non-conflicted file, or leaves extra conflicts behind, stax bails out and preserves the in-progress rebase so you can inspect or continue manually.\n\n```bash\nst resolve\nst resolve --agent codex --model gpt-5.3-codex\n```\n\nBefore each rebase, stax also runs a **preflight repair** that compares the\nstored parent boundary against `merge-base(parent, branch)`. When they diverge\nsharply — the “my restack hit conflicts on files I never touched” case — stax\nautomatically uses the merge-base boundary for that rebase and prints a\none-line notice. Silence the notice with `[restack] preflight_warn = false` or\n`--quiet`; disable the automatic correction with\n`[restack] preflight_auto_repair = false`.\n\n### Undo / redo\n\n`restack`, `submit`, and `reorder` each snapshot branch state before they touch anything. Recovery is one command away.\n\n```bash\nst restack\nst undo\nst redo\n```\n\n→ [Undo/redo safety](docs/safety/undo-redo.md)\n\n### Interactive TUI\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"stax TUI\" src=\"assets/tui.png\" width=\"760\"\u003e\n\u003c/p\u003e\n\nBare `st` launches a full-screen TUI for browsing stacks, inspecting branch summaries and cached patches, watching live CI hydrate, and running common ops without leaving the terminal.\n\n→ [TUI guide](docs/interface/tui.md)\n\n### AI branch names, PR details, and standups\n\n```bash\nst create --ai -a --yes   # generate branch name + first commit message\nst ss --ai --yes          # generate PR titles/bodies during submit\nst gen                    # interactive: PR body, PR title, or commit message (AI)\nst generate --pr-body     # non-interactive: refresh PR body from branch diff + context\nst generate --pr-title    # non-interactive: refresh PR title from branch diff\nst generate --commit-msg  # non-interactive: amend HEAD commit message with AI\nst standup --ai           # spoken-style daily engineering summary\nst standup --ai --style slack  # Slack-ready Yesterday/Today bullets\n```\n\nEach AI feature (`generate`, `standup`, `resolve`, `lane`) can use a different agent/model. `st create --ai`, `st submit --ai`, and `st generate` / `st gen` (PR body/title, commit message) share the `generate` setting. Configure with:\n\n```bash\nst config --set-ai\n```\n\n→ [PR templates \u0026 AI](docs/integrations/pr-templates-and-ai.md) · [Reporting](docs/workflows/reporting.md)\n\n\u003ca id=\"commands\"\u003e\u003c/a\u003e\n## Commands\n\n| Command | What it does |\n|---|---|\n| `st` | Launch interactive TUI |\n| `st ls` / `st ll` | Show stack health and PR status (`st ll` adds PR URLs/details) |\n| `st watch` | Live auto-refreshing stack status with CI and PR state (adaptive polling: 15s active CI → 60s open PRs → 120s idle) |\n| `st watch --current` | Watch only the current stack |\n| `st create \u003cname\u003e` / `st add \u003cname\u003e` | Create a branch stacked on current |\n| `st create --ai -a --yes` | Generate branch name + first commit message |\n| `st create \u003cname\u003e --below` | Insert a new branch below current, carrying tracked/untracked prepared changes with it |\n| `st ss` | Submit the full stack, open/update linked PRs |\n| `st merge` | Cascade-merge from bottom to current (`--when-ready`, `--downstack-only`/`--ds`, `--remote`, `--all`) |\n| `st ci -w --alert` | Watch CI until all checks finish, then play success/error sounds |\n| `st ci -w --strict` | Watch CI but exit as soon as any check fails |\n| `st rs` / `st rs --restack` | Sync trunk, clean merged branches, optionally rebase |\n| `st update` | Sync trunk without merged-branch cleanup, restack current stack, then push/update PRs |\n| `st update --force --yes --no-prompt` | Run update without sync or submit prompts |\n| `st update --verbose` | Include detailed sync/restack/submit timing |\n| `st restack` | Rebase current stack onto parents locally |\n| `st cascade` | Restack + push + open/update PRs |\n| `st split` | Split a branch into stacked branches (by commit or `--hunk`) |\n| `st lane \u003cname\u003e \"\u003ctask\u003e\"` | Spawn an AI agent on a new lane |\n| `st wt` | Open the worktree dashboard |\n| `st resolve` | AI-resolve an in-progress rebase conflict |\n| `st create --ai` | Generate a branch name from local changes |\n| `st gen` / `st generate` | AI: interactive picker, or `--pr-body` / `--pr-title` / `--commit-msg` |\n| `st ss --ai` | Submit with AI-generated PR title/body suggestions |\n| `st standup` | Summarize recent engineering activity |\n| `st tmux status` | Print a tmux-formatted status string (branch, stack position, PR, CI) for `status-right` |\n| `st tmux popup` | Open `stax watch --current` in a floating tmux panel |\n| `st undo` / `st redo` | Recover / reapply risky operations |\n| `st run \u003ccmd\u003e` | Run a command on each branch in the stack |\n| `st draft [branch]` / `st undraft [branch]` | Toggle a PR between draft and ready-for-review |\n| `st pr` / `st pr body` / `st pr list` / `st issue list` | Open current PR · view/edit PR body · list PRs · list issues |\n\nFull reference: [docs/commands/core.md](docs/commands/core.md) · [docs/commands/reference.md](docs/commands/reference.md)\n\n## Performance\n\nBenchmarked with `hyperfine` on this repo. Absolute times vary by repo and machine; the ratios do not.\n\n| Benchmark      | stax     | vs [Freephite](https://github.com/bradymadden97/freephite) | vs [Graphite](https://github.com/withgraphite/graphite-cli) |\n|----------------|----------|-----------------|----------------|\n| `st ls`        | baseline | **214.76×** faster | **69.72×** faster |\n| `st rs` (sync) | baseline | **2.41×** faster  | —              |\n\nstax is wire-compatible with Freephite/Graphite for common stacked-branch workflows.\n\n→ [Full benchmarks](docs/reference/benchmarks.md) · [Compatibility notes](docs/compatibility/freephite-graphite.md)\n\n## Configuration\n\n```bash\nst config                  # open the config editor\nst config --set-ai         # pick AI agent + model\nst config --reset-ai       # clear saved AI pairing and re-prompt\n```\n\nConfig lives at `~/.config/stax/config.toml`:\n\n```toml\n[submit]\nstack_links = \"body\"   # \"comment\" | \"body\" | \"both\" | \"off\"\nsingle_stack = \"on\"    # \"on\" | \"off\" — when \"off\", skip stack-link sync while only one PR exists\n```\n\n→ [Full config reference](docs/configuration/index.md)\n\n## Integrations\n\n### tmux\n\n[**stax.tmux**](https://github.com/cesarferreira/stax.tmux) is a TPM-compatible plugin that puts your stack in the tmux status bar and adds keybindings for common actions:\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/tmux.png\" width=\"880\" alt=\"stax.tmux status bar\"\u003e\n\u003c/p\u003e\n\n- Live status bar — branch, stack position, PR state, CI state; auto-refreshes in the background\n- Keybindings — `prefix + S` popup, `prefix + ]`/`[` up/down, `prefix + M-s` sync\n- Window auto-rename — tmux window title follows the current branch\n\nInstall via TPM:\n\n```tmux\nset -g @plugin 'cesarferreira/stax.tmux'\n```\n\nSee the [stax.tmux README](https://github.com/cesarferreira/stax.tmux) for full setup and configuration options.\n\n---\n\nAI and editor integration guides:\n\n- [Claude Code](docs/integrations/claude-code.md)\n- [Codex](docs/integrations/codex.md)\n- [Gemini CLI](docs/integrations/gemini-cli.md)\n- [OpenCode](docs/integrations/opencode.md)\n- [PR templates + AI generation](docs/integrations/pr-templates-and-ai.md)\n\nShared skill/instruction file used across agents: [skills.md](skills.md)\n\n`st changelog` can generate notes between refs, and `st changelog find [query]`\nor `st changelog --find [query]` fuzzy-finds entries in `CHANGELOG.md` while\nshowing the release and section that contain each match.\n\n\u003ca id=\"windows-notes\"\u003e\u003c/a\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eWindows notes\u003c/strong\u003e — shell integration, worktrees, tmux\u003c/summary\u003e\n\nstax runs on Windows (x86_64) with prebuilt binaries on [Releases](https://github.com/cesarferreira/stax/releases). Most commands work identically, with these limitations:\n\n- **Shell integration is not available.** `st setup` supports bash/zsh/fish only. On Windows:\n  - `st wt c` / `st wt go` create and navigate worktrees but cannot auto-`cd` the parent shell. Manually `cd` to the printed path.\n  - The `sw` quick alias is not available.\n  - `st wt rm` (bare) cannot relocate the shell. Specify: `st wt rm \u003cname\u003e`.\n- **Worktree commands still work.** `st wt c/go/ls/ll/cleanup/rm/prune/restack` all function — only the shell-level `cd` is missing.\n- **tmux integration requires WSL** or a Unix-like environment. The [stax.tmux](https://github.com/cesarferreira/stax.tmux) plugin is Unix-only.\n\nEverything else — stacked branches, PRs, restack, sync, undo/redo, TUI, AI generation — works on Windows without limitation.\n\n\u003c/details\u003e\n\n## Contributing\n\nBefore opening a PR, run:\n\n```bash\nmake test\n```\n\nTo cut a release, run:\n\n```bash\nmake release                  # default minor bump\nmake release LEVEL=patch      # patch bump\nmake release LEVEL=major      # major bump\n```\n\nRelease automation now finalizes the next versioned entry in `CHANGELOG.md` from commits since the latest `v*` tag inside `cargo release`'s pre-release hook, refreshes the compare links, and leaves a fresh `Unreleased` header for follow-up work. If there are no commits since the last tag, the release exits early instead of creating an empty changelog entry.\n\nProject docs and architecture: [docs/index.md](docs/index.md). Contributor guidelines: [AGENTS.md](AGENTS.md).\n\n## License\n\nMIT \u0026copy; Cesar Ferreira\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcesarferreira%2Fstax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcesarferreira%2Fstax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcesarferreira%2Fstax/lists"}