Expand description
diffler binary internals, exposed as a library so the integration tests can drive the full app (event pump + MCP server) headlessly. The public surface is the binary’s: nothing here is a stable API.
Modules§
- app
- Application state and event handling.
App::handleis a pure-ish state transition (no terminal IO) so the whole shell is unit-testable; rendering reads the state inui::draw. Per-screen state and handlers live in thestatus,log, anddiffsubmodules. - clipboard
- System clipboard. Two mechanisms, used together for reach without native build deps (so the static musl binaries stay clean): an OSC52 escape sequence — written to the terminal by the main loop after a draw, never from rendering — which the terminal forwards even over ssh/tmux; and a best-effort pipe to the platform clipboard CLI, covering terminals that don’t honor OSC52.
- config
- Layered TOML configuration: defaults → global file → project file → CLI.
- editor
- $EDITOR integration. The TUI loop owns the terminal, so opening an
editor is a request:
Appqueues anEditorRequest, the main loop suspends the terminal, runs the subprocess, restores the screen, and hands the outcome back toApp::editor_finished. - event
- Terminal event pump: crossterm’s async stream plus a periodic tick,
multiplexed onto one channel. Kept thin — all decisions live in
App::handle, which is what the tests drive. - keymap
- Key bindings: neogit-style defaults per screen, overridable from
[keys.*]config sections, with multi-key sequence resolution. - mcp
- Embedded MCP server: agents read review comments, answer them in place,
and long-poll for the human’s feedback. Tool handlers never touch the
review directly — every call is sent through the app event channel as an
McpRequestand answered byApp::handle_mcpon the main loop, so the app stays the single owner of all state (no locks). - theme
- Color themes.
github-darkis the default;ui.themeselects a built-in, each pairing its palette with a matching syntax-highlight theme. - transient
- Magit/neogit-style transient menus: a top-level prefix key opens a transient whose own keys are pure leaves (immediate actions). The model is data, not closures, so resolution and the which-key panel layout stay pure and unit-testable; the app owns the live transient state and timer.
- tree
- Pure directory-trie flattening shared by the diff sidebar and the status sections. A file list (repo-relative paths, in input order) becomes a list of visible rows honoring fold state — directories before files at each level, input order preserved within a kind, folded directories hiding their subtree. No rendering and no app state, so the navigation math is fully unit-testable.
- ui
- Rendering.
drawnever computes review state; it readsApp(the diff view additionally fills its lazy highlight cache and follows the cursor with its scroll offset, which is why it takes&mut App). - watch
- Filesystem watcher: debounced notify events on the repo become
AppEvent::RepoChanged. Noise sources (the session store, lockfiles, git’s object database) are filtered out so staging or saving a comment does not echo back as a repo change.