StrideLabs/Writing/Reviewing agent diffs: the design behind Strix
Reviewing agent diffs: the design behind Strix
How a git-diff idea for Roost became a standalone TUI: I no longer need to open VS Code or Cursor just to view a diff. Side-by-side diffs, history, first-class mouse support, themes, and a Rust core built on ratatui and gitoxide.
Strix started as a feature I almost built into Roost. I wanted a quick git-diff view inside my terminal multiplexer and was about to add one, then figured a small standalone TUI would do the job just as well, and I could launch it from Roost when I wanted it. So it split off into its own tool.
What I wanted was specific. The main reason I still opened VS Code or Cursor was their diff view (the side-by-side, syntax-highlighted one) and I liked it enough to want it in the terminal. I also wanted genuine first-class mouse support, which the git TUIs I’d used and admired (LazyGit, tig) leaned on less, and theming so it matched the rest of my setup. Those three wants were the whole brief: enough to stage a commit with confidence, and nothing else competing for attention.
A narrow tool for a narrow job
The design I kept coming back to was the Unix shape: a focused tool that does one job well and fits cleanly into a larger workflow. Strix is not trying to be a full git client. It is the place I go to review what changed, understand the diff, and stage the files I mean to stage.
That keeps the main view simple: changes on the left, a diff on the right. Staged files sit at the top of the left pane, unstaged and untracked below; you move files between sections to stage, unstage, or reset to HEAD. The right pane shows a syntax-highlighted diff of whatever’s selected, unified or side-by-side. You can browse it with hotkeys or the mouse, and themes let it match the rest of your terminal instead of feeling like a different surface.
History is part of the same review loop. Press i and Strix becomes a branch-and-merge rail graph of the current branch, with commit details or per-file diffs (against the commit’s first parent) alongside. Esc or i returns you to staging. It is there when I need context, but the default view stays focused on the changed files in front of me.
The crates underneath
Strix is Rust, built on three crates that each do one thing well. ratatui draws the panes and handles layout. gitoxide reads git data. It’s a pure-Rust git implementation, which keeps the data layer fast and dependency-light. syntect does the syntax highlighting in the diff pane.
strix # open the repo in the current directory
strix path/to/repo # or a specific one
One deliberate choice: Strix shells out to git for the operations that mutate state, even though gitoxide could do more. I like the split: gitoxide gives Strix a fast, Rust-native way to read the repository, while staging and resetting go through the same git binary users already trust. gitoxide reads; git writes. It is a simple boundary, and it matches how I want the tool to behave.
Mouse and keyboard, both first-class
Mouse support is the thing I most wanted to get right. Plenty of terminal tools are keyboard-first, with the mouse a secondary path if it’s there at all; I wanted both to be real. Every action has a keybinding, and the same actions respond to clicks, drags, and scroll. The point isn’t to be clever about input; it’s that whichever hand you reach with, the tool answers the same way. Themeability is part of the same idea: Strix should adopt your terminal’s palette, not impose its own.
Watching the tree
One thing I didn’t plan but now lean on: Strix watches the working tree and refreshes itself. A background file watcher notices changes and updates the status and diff without a keystroke (toggle it off and you refresh with r). In practice that means I open Strix in a pane next to a coding agent and watch the diff take shape as it edits; staging becomes the last deliberate step, after the change is already in front of me.
Built faster than I expected
Strix came together faster than I expected. A lot of that is the Rust ecosystem: ratatui, gitoxide, and syntect gave me strong pieces to build on, and once I had talked through the use case and the shape I wanted with Claude Code, the first useful version landed quickly.
That does not make it a throwaway tool. It is small, but it solves a real problem in my workflow: I can watch an agent’s diff take shape, review it in a terminal UI that feels familiar, stage what I mean to stage, and move on. I enjoy using it, and I hope it is useful for other people working the same way.