gitgui: a real git GUI inside cmux, next to Pi Developer Antonello F. released gitgui, a Rust binary that renders a full git GUI—commit graph, staged file list, inline diffs, and hunk buttons—inside terminal panes using the kitty graphics protocol, enabling mouse-driven git operations alongside AI agents like Pi in cmux. The tool, available on GitHub, supports macOS and Linux, sends frames via POSIX shared memory locally (rasterizing a 1600×1000 release build in about 6 ms on a Mac), and offers a JSON-lines socket for external tools to query status, stage paths, or capture screenshots. gitgui: a real git GUI inside cmux, next to Pi I wrote The Local Agent Trio: cmux + Pi + Unsloth Studio /2026/cmux-pi-unsloth-local-glm-setup/ about splitting your local stack into cmux, inference, and Pi. Git stayed in the shell. Pi runs git status and git diff fine. You still lose the commit graph, the staged file list, inline diffs, and hunk buttons when you review a refactor. I kept Alt-Tabbing to Fork or squinting at git diff output. I wanted Sourcetree in the same cmux grid as the agent. So I built gitgui https://github.com/antonellof/gitgui . One Rust binary paints a GUI into your terminal pane with the kitty graphics protocol https://sw.kovidgoyal.net/kitty/graphics-protocol/ . Pixels, not a TUI. Graph, sidebar, diff viewer, commit box. cmux, Ghostty, kitty, WezTerm. Over SSH it sends zlib plus base64 frames. This is my daily layout: Pi on the left edits the repo. gitgui on the right shows branch lanes, unstaged files, and hunk buttons. One workspace. One checkout. cmux + pi + gitgui = 😍 Why stay inside the terminal? cmux is a pane grid. You already split shell, Pi, and sometimes a browser. Fork or GitKraken pull you out: different font, different shortcuts, another app fighting for focus. lazygit and gitui help for quick commits. They fall short when you read a three-file refactor with colored hunks, click Stage hunk on one block, and scan merge lanes on a graph. I wanted mouse clicks and a graph without leaving the grid. terminal-browser https://github.com/zenbu-labs/terminal-browser and terminal-code https://github.com/zenbu-labs/terminal-code proved the pattern: render pixels in the terminal, read pixel mouse events back. gitgui uses egui https://github.com/emilk/egui instead of Chromium. Three steps: - Draw the UI into an RGBA framebuffer with egui - Send the framebuffer as a kitty graphics image each frame - Map kitty keyboard and SGR mouse events into egui input Your terminal never prints UI text. It shows a picture. Locally frames go through POSIX shared memory. On my Mac a 1600×1000 release build rasterizes in about 6 ms. You get a commit graph with branch lanes, a sidebar for branches/tags/stashes, unstaged and staged lists, per-hunk stage and unstage, fetch/pull/push through your existing git CLI, and a JSON-lines socket so Pi or Cursor queries status, selects commits, stages paths, or saves a PNG screenshot. Keys are single letters and Ctrl combinations terminals do not steal. cmux keeps Cmd+ . Quit with q or Ctrl+C. Install You need macOS or Linux and a kitty-graphics terminal. Quick start: curl -fsSL https://raw.githubusercontent.com/antonellof/gitgui/main/scripts/install.sh | bash That one-liner works on public repos. Private repo? Clone with gh and run the script locally: gh repo clone antonellof/gitgui cd gitgui bash scripts/install.sh The script pulls a release binary when GitHub has one. Otherwise it builds from source with cargo Rust 1.95+ . Success looks like: installed: ~/.local/bin/gitgui run in a kitty-graphics terminal cmux, Ghostty, kitty : gitgui open repo in current directory gitgui /path/to/repo open a specific repo gitgui --split right . open in a new terminal split quit with q or Ctrl+C Check terminal support: gitgui --probe cmux + Pi + gitgui Same workspace as the trio post. One extra split. Pane A, Pi: cd ~/Projects/my-app pi Pane B, gitgui, from the agent pane: gitgui --split right . cmux runs new-split right and send with the gitgui command. Or split by hand and type gitgui in the new pane. Give your agent the skill file: mkdir -p ~/.cursor/skills/gitgui ln -sf ~/path/to/gitgui/skill/SKILL.md ~/.cursor/skills/gitgui/SKILL.md Drive the GUI from the shell: gitgui ls gitgui action '{"cmd":"status"}' gitgui action '{"cmd":"stage","paths": "src/main.rs" }' gitgui action '{"cmd":"screenshot","path":"/tmp/frame.png"}' Run action from the pane where gitgui lives and it finds the instance via the controlling tty. Writes queue on a background git thread. Poll status until busy hits zero. A typical session: Pi edits and runs tests on the left. You stage hunks and commit with Ctrl+Enter on the right. Or Pi stages through gitgui action and you type the commit message yourself. Inside the binary One Rust process. Three threads. stdin reader blocks on terminal bytes and feeds a parser for kitty keys, SGR mouse, paste, resize. main loop runs egui, tessellates meshes, rasterizes triangles, encodes kitty graphics. git worker uses libgit2 for reads and index writes. fetch, pull, and push shell out to git so your credential helper and SSH agent stay untouched. The UI reads an immutable RepoSnapshot. The worker swaps in a new snapshot after each command. Rendering never calls git. egui 0.36, a custom rasterizer, git2, libc for termios and shm, serde for the agent API. No Electron. No GPU backend. No tokio. Spec and protocol bytes live in docs/SPEC.md https://github.com/antonellof/gitgui/blob/main/docs/SPEC.md and docs/PROTOCOLS.md https://github.com/antonellof/gitgui/blob/main/docs/PROTOCOLS.md . One refactor, start to finish Pi touches three files. You want the graph to update, one hunk staged and one left alone, and a commit message you wrote yourself. All inside cmux. Before gitgui: git diff in the shell for small diffs, Alt-Tab to Fork for a graph, lazygit when you want speed over pixels. Now: gitgui --split right . once per session. Tab between Pi and gitgui. cmux still rings when Pi waits on you. Mouse clicks hit the right widgets. SSH sessions use the direct transport and the same UI. What v1 skips cmux and Ghostty are the main targets. kitty works. tmux and Zellij need graphics passthrough and fail today. Ghostty on macOS has no stable split-from-child API. gitgui --split prints a keybind hint and runs in the current pane when needed. Merge conflict UI is out of scope for v1. Use git on the CLI or your desktop client for conflicts. If you already run cmux and Pi, gitgui is the git pane I wished existed. Install it, split right, keep the graph beside the harness. gitgui: github.com/antonellof/gitgui https://github.com/antonellof/gitgui . cmux: cmux.dev https://cmux.dev . Pi: pi.dev https://pi.dev . Related: The Local Agent Trio: cmux + Pi + Unsloth Studio /2026/cmux-pi-unsloth-local-glm-setup/ .