persiyanov/herdr-reviewr

A code review + file viewer sidebar for herdr. Comment on a diff and send back to agent. Inspect diffs, files, and a PR state.

676

stars

270

commits

Rust

primary language

Sep 5, 2026

updated

code-review
herdr
herdr-plugin
rust
tui

README

herdr-reviewr

CI Release License

install · quick start · controls · scopes · configuration · limitations · changelog

A code-review pane for herdr. Your agent writes the code. You read its diff in a pane beside the chat, comment on the lines, and send the notes back. You never leave the terminal.

demo

One persistent pane, pointed at a git worktree:

  • Diff review — the agent's changed files, syntax-highlighted.
  • Four diff scopes — uncommitted, branch, last turn, commits.
  • Last-turn diff — what the worktree's latest turn changed, on its own.
  • Line comments — comment on a line or a range. Then send it to the agent.
  • Text selection — drag over any text to copy it, like an editor.
  • File viewer — any file's current content from the whole worktree.
  • Search — fuzzy file names and live code grep across the worktree, powered by fff.
  • Find in file — search the open file and step between every match.
  • PR view — the branch's pull request in the pane, read-only.
  • Markdown preview — flip a .md file between source and rendered view.
  • Themes — 18 palettes in dark and light.

It never edits your worktree and sends nothing on its own. The PR tab reads GitHub, GitLab, or Azure DevOps and never posts.

Requirements

  • herdr ≥ 0.7.5 (the plugin system).
  • git on PATH.
  • A truecolor terminal with Unicode box-drawing.
  • macOS or Linux.
  • gh (GitHub), glab (GitLab), or az (Azure DevOps, with the azure-devops extension), authenticated. Only the PR tab needs one.

Install

Prebuilt binaries, no Rust toolchain needed:

herdr plugin install persiyanov/herdr-reviewr

Open it in the current workspace:

herdr plugin action invoke open --plugin persiyanov.reviewr

reviewr auto-opens when herdr creates a workspace for a worktree, whether the checkout is new or opened from disk. auto_open = false keeps it hidden until you ask (Configuration).

To update, reinstall. Your config is keyed by plugin id and survives:

herdr plugin uninstall persiyanov.reviewr && herdr plugin install persiyanov/herdr-reviewr

Without herdr, reviewr runs as a plain terminal app. Grab a release binary and point it at a repo:

herdr-reviewr ~/some/repo

Everything works except Send and the last turn scope. Those need herdr around.

Quick start

Open reviewr next to your agent:

  1. Pick a file. Changed files are in the navigator. j / k moves, the diff follows. Or ] walks the changes hunk by hunk, file after file.
  2. Focus the diff. Tab switches panes.
  3. Select lines. v, then j / k to extend (or click or drag the gutter).
  4. Comment. c, type, Enter.
  5. Send. s sends every comment to the agent's input.

The footer shows the next step. Press ? for every key that works right now.

For a shortcut, bind a key to the toggle in your herdr config (user config, not the plugin manifest):

[[keys.command]]
key = "cmd+r"
type = "plugin_action"
command = "persiyanov.reviewr.toggle"   # <plugin_id>.<action_id> — note the id, not the name

cmd+… chords reach herdr. Many macOS terminals swallow alt+… themselves.

Controls

The keys below are defaults. You can rebind every action, even to several keys at once (Keybindings).

Getting around

KeyAction
1 2 3Switch tab — Changes / All files / PR
u b t gSwitch scope — uncommitted / branch / last turn / commits
BPick the base branch
GPick the commits to review
j k · Move cursor
] [Jump to next / previous hunk
f FJump to next / previous file
PageUp PageDownMove a page
Ctrl+U Ctrl+DMove a half-page
TabSwitch focus
Expand / collapse, or scroll sideways
/Search files and code
Ctrl+FFind in file
wToggle line wrap
mPreview markdown file
pRotate navigator
zHide / show navigator
< >Grow / shrink navigator
rRefresh
?Open shortcuts helper
qQuit

Reviewing (in the diff)

KeyAction
vSelect lines
cComment on line or selection
eEdit the comment under the cursor, or open the file in your editor
dDelete comment
n NJump to next / previous comment
lList all comments
sSend comments to agent
yCopy comments to clipboard
escClear selection

In the comment box

KeyAction
EnterSave comment
EscCancel
Shift+Enter · Alt+Enter · Ctrl+JInsert newline

Plus the usual caret moves: arrows, Home / End, Ctrl+A / Ctrl+E, Alt+b / Alt+f word jumps, and Ctrl+W / Ctrl+U / Ctrl+K deletes.

PR tab (read-only)

KeyAction
j kMove through description and comments
PageUp PageDownScroll focused pane
oOpen PR in browser
rRefresh

The mouse works too. Drag over any text to select and copy it, double-click a word, triple-click a line. Click or drag the line-number gutter to comment. Click files, tabs, and links, and scroll with the wheel.

The three tabs

  • Changes — the active scope's changed files with +/- stats and totals in the header.
  • All files — any file's current content from the whole worktree, comments too. Ignored paths show dimmed.
  • PR — a read-only mirror of the branch's pull request (GitHub, Azure DevOps) or merge request (GitLab): state, checks, description, and comments, rendered as markdown. reviewr never writes to the forge.

Diff scopes

  • uncommitted — the working tree vs HEAD (staged, unstaged, and untracked).
  • branch — the working tree vs the merge-base with the base branch: uncommitted plus the branch's commits. The base is your repo's default branch until you pick another with B (Base branch).
  • last turn — everything that changed in this worktree since its most recent turn started (Limitations).
  • commits — one commit, or several in a row, picked with G. Read what the agent committed one step at a time, without its unsaved edits mixed in.

reviewr starts in uncommitted. default_scope changes that. Switching with u/b/t/g wins for the rest of the session. g without a pick opens the picker.

Every scope respects .gitignore, so build output never clutters Changes. To review a file, track it. All files still browses any ignored path.

Configuration

CLI flags on the pane command:

FlagDefaultMeaning
--poll <ms>2000worktree poll interval (min 200)
--base <ref>autobase for branch scope, any rev, overrides the pick
--theme <name>catppuccinUI + syntax theme (see below)
--wrap <on|off>onsoft-wrap long diff lines (w toggles at runtime)

Everything else lives in reviewr's config file:

~/.config/herdr/plugins/config/persiyanov.reviewr/config.toml

Create it if missing. It is reviewr's file. Settings in herdr's ~/.config/herdr/config.toml never reach it. reviewr re-reads it on every refresh and toggle, so edits apply without a relaunch.

The file accepts these keys:

theme = "tokyo-night"
default_scope = "branch"
navigator_position = "right"
toggle_placement = "overlay"
toggle_direction = "down"
auto_open = false
github_host = "github.example.com"
editor = "code -g {file}:{line}"

[keybindings]
comment = ["c", "ㅊ"]
select  = ["v", "ㅍ"]

A missing file or omitted key uses its default. An invalid file is rejected whole — the pane shows the error and recovers on the next refresh after you fix it.

Theme

One theme colors the whole UI, chrome and syntax together:

theme = "tokyo-night"

--theme overrides the file. Match your terminal's light or dark background. Available:

  • Dark: catppuccin, catppuccin-frappe, catppuccin-macchiato, dracula, nord, gruvbox, one-dark, solarized, monokai, tokyo-night, rose-pine.
  • Light: catppuccin-latte, gruvbox-light, one-light, solarized-light, github-light, tokyo-night-day, rose-pine-dawn.

Names match herdr's where both ship a palette.

The navigator starts on the right. Set navigator_position to right, bottom, left, or top, or press p to cycle clockwise:

navigator_position = "bottom"

< grows, > shrinks, or drag the divider. z hides the navigator altogether and brings it back.

Base branch

The branch scope diffs against the merge-base with your repo's default branch, the one origin/HEAD names. The header shows the resolved base, vs main.

When the trunk is something else, or you review a stacked branch, press B (or click the base name) and pick the branch. The pick is stored for this worktree and holds until you pick again. Other worktrees on the same clone keep their own pick. Choosing the default branch records that name.

You can also type any revision, like HEAD~2, a tag, or a SHA prefix. The header shows what resolved: vs HEAD~2 (a1b2c3d).

--base <ref> sets the base for this pane. It wins over the pick and disables the picker.

Editor

e opens the file at the line you're on, or the navigator's selected file. On a line you have already commented, e edits the comment instead.

Set $EDITOR (or $VISUAL) and reviewr opens it at the right line. It knows vim, neovim, helix, emacs, nano, VS Code and its forks, Zed, Sublime Text, JetBrains, and the rest of the usual set.

A terminal editor takes the pane, and reviewr refreshes when you quit it. A window editor opens its own window, so the diff stays up and your save turns up in it on the next poll.

Write the command yourself when you need to. {file} and {line} are reviewr's, everything else is your editor's:

editor = "code -g {file}:{line}"

Keybindings

[keybindings] maps an action name to an array of keys. The array replaces that action's defaults, actions you don't mention keep theirs, and hints show the first key:

[keybindings]
comment = ["c", "ㅊ"]
select  = ["v", "ㅍ"]

Several keys per action serves CJK input sources — bind the character your layout produces on the same physical key.

The action names and their defaults:

ActionDefault
down / upj / k
next-hunk / prev-hunk] / [
next-file / prev-filef / F
scope-uncommitted / scope-branch / scope-last-turn / scope-commitsu / b / t / g
base-pick / commit-pickB / G
tab-changes / tab-all-files / tab-pr1 / 2 / 3
wrapw
previewm
navigator-positionp
navigator-hidez
navigator-grow / navigator-shrink< / >
selectv
commentc
edit / deletee / d
next-comment / prev-commentn / N
commentsl
search/
findctrl+f
keys?
sends, S
copyy, Y
open-pro
refreshr
quitq

A key is one printable character, or a ctrl+/alt+ chord like ctrl+f. Tab, Esc, and Enter are fixed. Keys still type normally in the comment box.

Forge repositories and hosts

The PR tab reads upstream when you have one, otherwise origin. A standard fork clone works without setup.

GitHub.com, GitLab.com, dev.azure.com, and the *.visualstudio.com organization hosts work without configuration. For one self-hosted instance per forge, set its bare hostname:

github_host = "github.example.com"
gitlab_host = "git.corp.example"
azure_devops_host = "tfs.corp.example"

Matching is exact. reviewr does not infer SSH aliases like github.com-work — use a canonical-host remote or an insteadOf rewrite. Authenticate with gh auth login --hostname github.example.com, glab auth login --hostname git.corp.example, or az login.

Pane placement

The toggle opens reviewr as a split to the right of your agent. toggle_placement changes the shape:

toggle_placement = "overlay"   # split | overlay | zoomed | tab   (default: split)
toggle_direction = "down"      # right | down — split only        (default: right)
  • split sits next to your agent. toggle_direction puts reviewr on the right (default) or below.
  • overlay covers the tab. Toggle again to drop back.
  • zoomed fills the tab.
  • tab opens its own tab.

Every placement takes the keyboard on toggle. New worktree workspaces auto-open only split and tab, and never steal focus.

Auto-open and layout plugins

reviewr auto-opens when herdr creates a workspace for a new or existing worktree checkout. Opening an already-live workspace does not resurrect a reviewr pane you closed there. auto_open = false makes it wait for the toggle:

auto_open = false   # default: true

A layout places reviewr like any other program. Give one pane the command:

command = "herdr-reviewr"

That pane is a full reviewr pane. The install links the binary at ~/.local/bin/herdr-reviewr and at ~/.local/state/herdr/plugins/persiyanov.reviewr/bin/herdr-reviewr. Use the long path if ~/.local/bin is not on your PATH.

A layout hook can also invoke the actions, once its panes are in place:

herdr plugin action invoke open --plugin persiyanov.reviewr

open ignores auto_open, and both actions are safe to repeat. They target the focused workspace. Put herdr-reviewr itself in a layout pane, never the invoke.

Limitations

The known constraints:

Terminal & theme

  • Truecolor required — colors are 24-bit RGB with no 256/8-color fallback. Basic terminals render wrong colors.
  • Theme must match the terminal — the pane keeps the terminal's background, and there is no auto light/dark detection yet. You match the theme by hand.
  • Add / remove are red / green — no secondary cue for colorblind users yet.
  • Box-drawing glyphs required, but no Nerd Font.

Platform

  • macOS and Linux only — no Windows.
  • Clipboard export uses pbcopy, wl-copy, xclip, or xsel. With none installed it says so, and Send still works.

herdr coupling

  • Send needs an agent in the workspace — one agent takes the comments straight away, and several open a picker so you choose. With no agent, Send says so and keeps your comments.
  • last turn relies on polling (2 s default) — a turn that starts and finishes inside one poll is missed, and the scope shows everything since the last observed turn start, your own edits included.

PR tab (GitHub, GitLab, and Azure DevOps)

  • Read-only — needs the forge's authenticated CLI (gh, glab, or az) and a recognized upstream or origin. Without either it tells you what to fix, and the other tabs keep working. Other forges are not supported.
  • One repository, never a cross-repository search — a readable, recognized upstream is authoritative, otherwise origin. Clones that target different parent repositories stay separate.
  • Mirrors the branch's open PR or MR — merged or closed shows as history. Each comment surface caps at its newest 100 rows, with a +more marker naming the forge when there is more.

Review model

  • Comments are in-memory and single-session — closing the pane loses any you haven't sent or copied out.
  • Sending is all-or-nothing — Send (or copy) delivers the whole set and clears it. A failure leaves everything in place.
  • No line-number rebasing — a comment stays locatable by its diff snippet, not its line number. reviewr flags a stale comment instead of dropping it.

Budgets

  • Files over 2 MB or 50,000 lines show a "too large" notice. Binary files get no diff.

Building from source

For the dev setup, tests, and benchmarks, see CONTRIBUTING.md. To run your own build inside herdr panes, link the checkout. herdr plugin link runs the binary you build at bin/herdr-reviewr:

git clone https://github.com/persiyanov/herdr-reviewr
cd herdr-reviewr
just install   # build release → bin/herdr-reviewr, ad-hoc re-signed on macOS
herdr plugin link .

After every just install, toggle the reviewr pane off and on. An open pane keeps running the old process. The loop only works while the plugin is linked: a github:… source in herdr plugin list runs a downloaded binary that local rebuilds never touch. Switch with:

herdr plugin uninstall persiyanov.reviewr   # config is keyed by id and survives
herdr plugin link .

Roadmap

Structured (JSON) export, a side-by-side split view, mark-file-reviewed, named-key notation for keybindings, OSC light/dark theme autodetect, more themes (kanagawa, vesper, everforest, ayu, a dark github), a terminal-following palette, and OSC 52 clipboard.

Design

Change specs live in docs/specs/, one folder per change.

License

MIT. Syntax highlighting comes from syntect and two-face. Most themes' syntax colors come from two-face's bundled set.

Bundled .tmTheme syntax files in assets/, each under its own license:

Contributors

persiyanov

261 commits

tomotochi

2 commits

dferland1

1 commits

persiyanov/herdr-reviewr

A code review + file viewer sidebar for herdr. Comment on a diff and send back to agent. Inspect diffs, files, and a PR state.

676

stars

270

commits

Rust

primary language

Sep 5, 2026

updated

code-review
herdr
herdr-plugin
rust
tui

README

herdr-reviewr

CI Release License

install · quick start · controls · scopes · configuration · limitations · changelog

A code-review pane for herdr. Your agent writes the code. You read its diff in a pane beside the chat, comment on the lines, and send the notes back. You never leave the terminal.

demo

One persistent pane, pointed at a git worktree:

  • Diff review — the agent's changed files, syntax-highlighted.
  • Four diff scopes — uncommitted, branch, last turn, commits.
  • Last-turn diff — what the worktree's latest turn changed, on its own.
  • Line comments — comment on a line or a range. Then send it to the agent.
  • Text selection — drag over any text to copy it, like an editor.
  • File viewer — any file's current content from the whole worktree.
  • Search — fuzzy file names and live code grep across the worktree, powered by fff.
  • Find in file — search the open file and step between every match.
  • PR view — the branch's pull request in the pane, read-only.
  • Markdown preview — flip a .md file between source and rendered view.
  • Themes — 18 palettes in dark and light.

It never edits your worktree and sends nothing on its own. The PR tab reads GitHub, GitLab, or Azure DevOps and never posts.

Requirements

  • herdr ≥ 0.7.5 (the plugin system).
  • git on PATH.
  • A truecolor terminal with Unicode box-drawing.
  • macOS or Linux.
  • gh (GitHub), glab (GitLab), or az (Azure DevOps, with the azure-devops extension), authenticated. Only the PR tab needs one.

Install

Prebuilt binaries, no Rust toolchain needed:

herdr plugin install persiyanov/herdr-reviewr

Open it in the current workspace:

herdr plugin action invoke open --plugin persiyanov.reviewr

reviewr auto-opens when herdr creates a workspace for a worktree, whether the checkout is new or opened from disk. auto_open = false keeps it hidden until you ask (Configuration).

To update, reinstall. Your config is keyed by plugin id and survives:

herdr plugin uninstall persiyanov.reviewr && herdr plugin install persiyanov/herdr-reviewr

Without herdr, reviewr runs as a plain terminal app. Grab a release binary and point it at a repo:

herdr-reviewr ~/some/repo

Everything works except Send and the last turn scope. Those need herdr around.

Quick start

Open reviewr next to your agent:

  1. Pick a file. Changed files are in the navigator. j / k moves, the diff follows. Or ] walks the changes hunk by hunk, file after file.
  2. Focus the diff. Tab switches panes.
  3. Select lines. v, then j / k to extend (or click or drag the gutter).
  4. Comment. c, type, Enter.
  5. Send. s sends every comment to the agent's input.

The footer shows the next step. Press ? for every key that works right now.

For a shortcut, bind a key to the toggle in your herdr config (user config, not the plugin manifest):

[[keys.command]]
key = "cmd+r"
type = "plugin_action"
command = "persiyanov.reviewr.toggle"   # <plugin_id>.<action_id> — note the id, not the name

cmd+… chords reach herdr. Many macOS terminals swallow alt+… themselves.

Controls

The keys below are defaults. You can rebind every action, even to several keys at once (Keybindings).

Getting around

KeyAction
1 2 3Switch tab — Changes / All files / PR
u b t gSwitch scope — uncommitted / branch / last turn / commits
BPick the base branch
GPick the commits to review
j k · Move cursor
] [Jump to next / previous hunk
f FJump to next / previous file
PageUp PageDownMove a page
Ctrl+U Ctrl+DMove a half-page
TabSwitch focus
Expand / collapse, or scroll sideways
/Search files and code
Ctrl+FFind in file
wToggle line wrap
mPreview markdown file
pRotate navigator
zHide / show navigator
< >Grow / shrink navigator
rRefresh
?Open shortcuts helper
qQuit

Reviewing (in the diff)

KeyAction
vSelect lines
cComment on line or selection
eEdit the comment under the cursor, or open the file in your editor
dDelete comment
n NJump to next / previous comment
lList all comments
sSend comments to agent
yCopy comments to clipboard
escClear selection

In the comment box

KeyAction
EnterSave comment
EscCancel
Shift+Enter · Alt+Enter · Ctrl+JInsert newline

Plus the usual caret moves: arrows, Home / End, Ctrl+A / Ctrl+E, Alt+b / Alt+f word jumps, and Ctrl+W / Ctrl+U / Ctrl+K deletes.

PR tab (read-only)

KeyAction
j kMove through description and comments
PageUp PageDownScroll focused pane
oOpen PR in browser
rRefresh

The mouse works too. Drag over any text to select and copy it, double-click a word, triple-click a line. Click or drag the line-number gutter to comment. Click files, tabs, and links, and scroll with the wheel.

The three tabs

  • Changes — the active scope's changed files with +/- stats and totals in the header.
  • All files — any file's current content from the whole worktree, comments too. Ignored paths show dimmed.
  • PR — a read-only mirror of the branch's pull request (GitHub, Azure DevOps) or merge request (GitLab): state, checks, description, and comments, rendered as markdown. reviewr never writes to the forge.

Diff scopes

  • uncommitted — the working tree vs HEAD (staged, unstaged, and untracked).
  • branch — the working tree vs the merge-base with the base branch: uncommitted plus the branch's commits. The base is your repo's default branch until you pick another with B (Base branch).
  • last turn — everything that changed in this worktree since its most recent turn started (Limitations).
  • commits — one commit, or several in a row, picked with G. Read what the agent committed one step at a time, without its unsaved edits mixed in.

reviewr starts in uncommitted. default_scope changes that. Switching with u/b/t/g wins for the rest of the session. g without a pick opens the picker.

Every scope respects .gitignore, so build output never clutters Changes. To review a file, track it. All files still browses any ignored path.

Configuration

CLI flags on the pane command:

FlagDefaultMeaning
--poll <ms>2000worktree poll interval (min 200)
--base <ref>autobase for branch scope, any rev, overrides the pick
--theme <name>catppuccinUI + syntax theme (see below)
--wrap <on|off>onsoft-wrap long diff lines (w toggles at runtime)

Everything else lives in reviewr's config file:

~/.config/herdr/plugins/config/persiyanov.reviewr/config.toml

Create it if missing. It is reviewr's file. Settings in herdr's ~/.config/herdr/config.toml never reach it. reviewr re-reads it on every refresh and toggle, so edits apply without a relaunch.

The file accepts these keys:

theme = "tokyo-night"
default_scope = "branch"
navigator_position = "right"
toggle_placement = "overlay"
toggle_direction = "down"
auto_open = false
github_host = "github.example.com"
editor = "code -g {file}:{line}"

[keybindings]
comment = ["c", "ㅊ"]
select  = ["v", "ㅍ"]

A missing file or omitted key uses its default. An invalid file is rejected whole — the pane shows the error and recovers on the next refresh after you fix it.

Theme

One theme colors the whole UI, chrome and syntax together:

theme = "tokyo-night"

--theme overrides the file. Match your terminal's light or dark background. Available:

  • Dark: catppuccin, catppuccin-frappe, catppuccin-macchiato, dracula, nord, gruvbox, one-dark, solarized, monokai, tokyo-night, rose-pine.
  • Light: catppuccin-latte, gruvbox-light, one-light, solarized-light, github-light, tokyo-night-day, rose-pine-dawn.

Names match herdr's where both ship a palette.

The navigator starts on the right. Set navigator_position to right, bottom, left, or top, or press p to cycle clockwise:

navigator_position = "bottom"

< grows, > shrinks, or drag the divider. z hides the navigator altogether and brings it back.

Base branch

The branch scope diffs against the merge-base with your repo's default branch, the one origin/HEAD names. The header shows the resolved base, vs main.

When the trunk is something else, or you review a stacked branch, press B (or click the base name) and pick the branch. The pick is stored for this worktree and holds until you pick again. Other worktrees on the same clone keep their own pick. Choosing the default branch records that name.

You can also type any revision, like HEAD~2, a tag, or a SHA prefix. The header shows what resolved: vs HEAD~2 (a1b2c3d).

--base <ref> sets the base for this pane. It wins over the pick and disables the picker.

Editor

e opens the file at the line you're on, or the navigator's selected file. On a line you have already commented, e edits the comment instead.

Set $EDITOR (or $VISUAL) and reviewr opens it at the right line. It knows vim, neovim, helix, emacs, nano, VS Code and its forks, Zed, Sublime Text, JetBrains, and the rest of the usual set.

A terminal editor takes the pane, and reviewr refreshes when you quit it. A window editor opens its own window, so the diff stays up and your save turns up in it on the next poll.

Write the command yourself when you need to. {file} and {line} are reviewr's, everything else is your editor's:

editor = "code -g {file}:{line}"

Keybindings

[keybindings] maps an action name to an array of keys. The array replaces that action's defaults, actions you don't mention keep theirs, and hints show the first key:

[keybindings]
comment = ["c", "ㅊ"]
select  = ["v", "ㅍ"]

Several keys per action serves CJK input sources — bind the character your layout produces on the same physical key.

The action names and their defaults:

ActionDefault
down / upj / k
next-hunk / prev-hunk] / [
next-file / prev-filef / F
scope-uncommitted / scope-branch / scope-last-turn / scope-commitsu / b / t / g
base-pick / commit-pickB / G
tab-changes / tab-all-files / tab-pr1 / 2 / 3
wrapw
previewm
navigator-positionp
navigator-hidez
navigator-grow / navigator-shrink< / >
selectv
commentc
edit / deletee / d
next-comment / prev-commentn / N
commentsl
search/
findctrl+f
keys?
sends, S
copyy, Y
open-pro
refreshr
quitq

A key is one printable character, or a ctrl+/alt+ chord like ctrl+f. Tab, Esc, and Enter are fixed. Keys still type normally in the comment box.

Forge repositories and hosts

The PR tab reads upstream when you have one, otherwise origin. A standard fork clone works without setup.

GitHub.com, GitLab.com, dev.azure.com, and the *.visualstudio.com organization hosts work without configuration. For one self-hosted instance per forge, set its bare hostname:

github_host = "github.example.com"
gitlab_host = "git.corp.example"
azure_devops_host = "tfs.corp.example"

Matching is exact. reviewr does not infer SSH aliases like github.com-work — use a canonical-host remote or an insteadOf rewrite. Authenticate with gh auth login --hostname github.example.com, glab auth login --hostname git.corp.example, or az login.

Pane placement

The toggle opens reviewr as a split to the right of your agent. toggle_placement changes the shape:

toggle_placement = "overlay"   # split | overlay | zoomed | tab   (default: split)
toggle_direction = "down"      # right | down — split only        (default: right)
  • split sits next to your agent. toggle_direction puts reviewr on the right (default) or below.
  • overlay covers the tab. Toggle again to drop back.
  • zoomed fills the tab.
  • tab opens its own tab.

Every placement takes the keyboard on toggle. New worktree workspaces auto-open only split and tab, and never steal focus.

Auto-open and layout plugins

reviewr auto-opens when herdr creates a workspace for a new or existing worktree checkout. Opening an already-live workspace does not resurrect a reviewr pane you closed there. auto_open = false makes it wait for the toggle:

auto_open = false   # default: true

A layout places reviewr like any other program. Give one pane the command:

command = "herdr-reviewr"

That pane is a full reviewr pane. The install links the binary at ~/.local/bin/herdr-reviewr and at ~/.local/state/herdr/plugins/persiyanov.reviewr/bin/herdr-reviewr. Use the long path if ~/.local/bin is not on your PATH.

A layout hook can also invoke the actions, once its panes are in place:

herdr plugin action invoke open --plugin persiyanov.reviewr

open ignores auto_open, and both actions are safe to repeat. They target the focused workspace. Put herdr-reviewr itself in a layout pane, never the invoke.

Limitations

The known constraints:

Terminal & theme

  • Truecolor required — colors are 24-bit RGB with no 256/8-color fallback. Basic terminals render wrong colors.
  • Theme must match the terminal — the pane keeps the terminal's background, and there is no auto light/dark detection yet. You match the theme by hand.
  • Add / remove are red / green — no secondary cue for colorblind users yet.
  • Box-drawing glyphs required, but no Nerd Font.

Platform

  • macOS and Linux only — no Windows.
  • Clipboard export uses pbcopy, wl-copy, xclip, or xsel. With none installed it says so, and Send still works.

herdr coupling

  • Send needs an agent in the workspace — one agent takes the comments straight away, and several open a picker so you choose. With no agent, Send says so and keeps your comments.
  • last turn relies on polling (2 s default) — a turn that starts and finishes inside one poll is missed, and the scope shows everything since the last observed turn start, your own edits included.

PR tab (GitHub, GitLab, and Azure DevOps)

  • Read-only — needs the forge's authenticated CLI (gh, glab, or az) and a recognized upstream or origin. Without either it tells you what to fix, and the other tabs keep working. Other forges are not supported.
  • One repository, never a cross-repository search — a readable, recognized upstream is authoritative, otherwise origin. Clones that target different parent repositories stay separate.
  • Mirrors the branch's open PR or MR — merged or closed shows as history. Each comment surface caps at its newest 100 rows, with a +more marker naming the forge when there is more.

Review model

  • Comments are in-memory and single-session — closing the pane loses any you haven't sent or copied out.
  • Sending is all-or-nothing — Send (or copy) delivers the whole set and clears it. A failure leaves everything in place.
  • No line-number rebasing — a comment stays locatable by its diff snippet, not its line number. reviewr flags a stale comment instead of dropping it.

Budgets

  • Files over 2 MB or 50,000 lines show a "too large" notice. Binary files get no diff.

Building from source

For the dev setup, tests, and benchmarks, see CONTRIBUTING.md. To run your own build inside herdr panes, link the checkout. herdr plugin link runs the binary you build at bin/herdr-reviewr:

git clone https://github.com/persiyanov/herdr-reviewr
cd herdr-reviewr
just install   # build release → bin/herdr-reviewr, ad-hoc re-signed on macOS
herdr plugin link .

After every just install, toggle the reviewr pane off and on. An open pane keeps running the old process. The loop only works while the plugin is linked: a github:… source in herdr plugin list runs a downloaded binary that local rebuilds never touch. Switch with:

herdr plugin uninstall persiyanov.reviewr   # config is keyed by id and survives
herdr plugin link .

Roadmap

Structured (JSON) export, a side-by-side split view, mark-file-reviewed, named-key notation for keybindings, OSC light/dark theme autodetect, more themes (kanagawa, vesper, everforest, ayu, a dark github), a terminal-following palette, and OSC 52 clipboard.

Design

Change specs live in docs/specs/, one folder per change.

License

MIT. Syntax highlighting comes from syntect and two-face. Most themes' syntax colors come from two-face's bundled set.

Bundled .tmTheme syntax files in assets/, each under its own license:

Contributors

persiyanov

261 commits

tomotochi

2 commits

dferland1

1 commits

Languages

Rust

96.9%

Python

1.7%

Shell

1.2%