mergr adds GitHub pull request status to Herdr's Space sidebar. It refreshes
through one background service, reports status through Herdr metadata tokens,
and does not open panes or change focus.
- Herdr 0.7.5 or newer
- macOS on Apple silicon or Intel for prebuilt installation
- Git
- GitHub CLI authenticated with
gh auth login
The Space must use a local checkout of a GitHub repository that the authenticated GitHub account can access.
Linux remains supported through a source build and currently requires Rust 1.88 or newer, including Cargo. Rust is not required for ordinary installation or runtime on macOS.
Install directly from GitHub:
herdr plugin install jsmenzies/mergrOn macOS, Herdr runs the bundled installer, which downloads the prebuilt binary
matching the plugin version and Mac architecture. The download must pass its
published SHA-256 checksum before it is installed. Apple silicon (arm64) and
Intel (x86_64) Macs are supported.
mergr publishes metadata tokens for Herdr's configurable Space rows. Merge
the following settings into ~/.config/herdr/config.toml. The layout supports
up to five pull request rows; maxRows controls how many the plugin populates.
[ui]
sidebar_max_width = 60
[ui.sidebar.spaces]
rows = [
["state_icon", "workspace", { token = "$pr_count", fg = "#92fef7", bold = true }],
[{ token = "branch", fg = "#92fef7" }, "git_status"],
[{ token = "$pr_1_bad_title", fg = "#ff4144" }, { token = "$pr_1_bad_status", fg = "#ff4144", bold = true }, { token = "$pr_1_wait_title", fg = "#ffdc63" }, { token = "$pr_1_wait_status", fg = "#ffdc63", bold = true }, { token = "$pr_1_good_title", fg = "#b0f72e" }, { token = "$pr_1_good_status", fg = "#b0f72e", bold = true }, { token = "$pr_1_open_title", fg = "#777777" }, { token = "$pr_1_open_status", fg = "#777777" }],
[{ token = "$pr_2_bad_title", fg = "#ff4144" }, { token = "$pr_2_bad_status", fg = "#ff4144", bold = true }, { token = "$pr_2_wait_title", fg = "#ffdc63" }, { token = "$pr_2_wait_status", fg = "#ffdc63", bold = true }, { token = "$pr_2_good_title", fg = "#b0f72e" }, { token = "$pr_2_good_status", fg = "#b0f72e", bold = true }, { token = "$pr_2_open_title", fg = "#777777" }, { token = "$pr_2_open_status", fg = "#777777" }],
[{ token = "$pr_3_bad_title", fg = "#ff4144" }, { token = "$pr_3_bad_status", fg = "#ff4144", bold = true }, { token = "$pr_3_wait_title", fg = "#ffdc63" }, { token = "$pr_3_wait_status", fg = "#ffdc63", bold = true }, { token = "$pr_3_good_title", fg = "#b0f72e" }, { token = "$pr_3_good_status", fg = "#b0f72e", bold = true }, { token = "$pr_3_open_title", fg = "#777777" }, { token = "$pr_3_open_status", fg = "#777777" }],
[{ token = "$pr_4_bad_title", fg = "#ff4144" }, { token = "$pr_4_bad_status", fg = "#ff4144", bold = true }, { token = "$pr_4_wait_title", fg = "#ffdc63" }, { token = "$pr_4_wait_status", fg = "#ffdc63", bold = true }, { token = "$pr_4_good_title", fg = "#b0f72e" }, { token = "$pr_4_good_status", fg = "#b0f72e", bold = true }, { token = "$pr_4_open_title", fg = "#777777" }, { token = "$pr_4_open_status", fg = "#777777" }],
[{ token = "$pr_5_bad_title", fg = "#ff4144" }, { token = "$pr_5_bad_status", fg = "#ff4144", bold = true }, { token = "$pr_5_wait_title", fg = "#ffdc63" }, { token = "$pr_5_wait_status", fg = "#ffdc63", bold = true }, { token = "$pr_5_good_title", fg = "#b0f72e" }, { token = "$pr_5_good_status", fg = "#b0f72e", bold = true }, { token = "$pr_5_open_title", fg = "#777777" }, { token = "$pr_5_open_status", fg = "#777777" }],
]The colors can be changed locally. If the tables already exist, add or replace their keys rather than declaring duplicate TOML tables. Validate and reload the configuration:
herdr config check
herdr server reload-configThe plugin works without a config file. Its defaults are:
{
"maxRows": 3,
"refreshIntervalSeconds": 60,
"filters": {
"author": "@me",
"branch": "all"
}
}To customize them, create config.json in the directory printed by:
herdr plugin config-dir mergrYou can add the bundled JSON Schema for editor validation:
{
"$schema": "https://raw.githubusercontent.com/jsmenzies/mergr/main/config.schema.json",
"maxRows": 3,
"refreshIntervalSeconds": 60,
"filters": {
"author": "@me",
"branch": "all"
}
}maxRows accepts 1 through 5. filters.author accepts "any", "@me", or
a GitHub username. filters.branch accepts "all" or "current".
refreshIntervalSeconds accepts 1 through 86400. Its default of 60 refreshes
every minute. Periodic refresh is always enabled.
The only supported top-level settings are $schema, maxRows,
refreshIntervalSeconds, and filters. The runtime rejects unknown or invalid
settings. It checks for configuration changes within 30 seconds and applies
them on the next scheduled refresh.
- Red
✕: failed checks, merge conflicts, or requested changes - Yellow
◷: pending checks or required review - Green
✓: passing checks - Gray
•: no checks
Pull requests that need attention appear first, followed by the most recently updated pull requests within each status. Titles and trailing status glyphs adapt to the current sidebar width.
The plugin service refreshes on server startup, at the configured periodic interval, and after the filter action is invoked. It does not refresh when workspaces or panes gain focus. Bulk refreshes process up to five repositories concurrently and share identical GitHub queries between Spaces. Refresh requests are serialized, duplicate pending requests are coalesced, and metadata is reported only when the displayed pull request tokens change.
Herdr exposes plugin actions through custom command bindings. These bindings are optional examples and do not replace Herdr's default keys:
[[keys.command]]
key = "prefix+m"
type = "plugin_action"
command = "mergr.filter-cycle"
description = "cycle mergr PR filter"filter-cycle rotates through all pull requests, pull requests authored by the
authenticated user, and pull requests for the current branch across all
repositories.
mergr runs as the current user and inherits the existing GitHub CLI
authentication. It runs read-only git and gh queries, writes its own
config.json when filters change, and reports display metadata directly to
Herdr's local socket. It does not store GitHub credentials or send telemetry.
As with any Herdr plugin, review the manifest and source before installation. Herdr plugins are executable programs and are not sandboxed.
The macOS installer downloads only the version declared in
herdr-plugin.toml, verifies its published SHA-256 checksum, and then replaces
the installed binary atomically. Release binaries are ad-hoc signed. They are
not Developer ID signed or notarized.
Check authentication, the installed plugin version and state, and recent command logs:
gh auth status
herdr plugin list --plugin mergr --json
herdr plugin log list --plugin mergr --limit 20No pull request rows are shown for directories outside a Git repository, local
repositories without a remote, repositories without matching open pull
requests, or detached HEADs when the branch filter is set to "current".
mergr daemon is not running indicates that the background service has not
started yet. Restart Herdr after initially linking or installing this version.
Refresh failed indicates that a GitHub or Git query failed. The underlying
error is available in the plugin log.
Release versions in Cargo.toml, Cargo.lock, and herdr-plugin.toml must
match. To publish version 0.3.2, update and validate those files, merge the
release commit, then create and push the matching signed tag:
git tag -s v0.3.2 -m "mergr v0.3.2"
git push origin v0.3.2The tag starts the release workflow. It validates the project with Rust 1.88, builds native Apple silicon and Intel binaries, applies ad-hoc signatures, generates SHA-256 checksums, and publishes the assets to the matching GitHub Release. Do not create a version tag until the corresponding version is present in both manifests.
Developer ID signing and Apple notarization require Apple credentials stored as repository secrets and are intentionally outside the current release process.
Current Herdr releases update GitHub-managed plugins by reinstalling them:
herdr plugin install jsmenzies/mergr
herdr server stop
herdrVersion 0.3.2 makes periodic refresh and sidebar metadata always active. If
you already have a Mergr config file, update it before restarting Herdr:
${EDITOR:-vi} "$(herdr plugin config-dir mergr)/config.json"- Remove
enabled. - Remove
repositories. Move any override you still want into the globalmaxRowsorfilterssettings first. - Replace
refreshIntervalMinuteswithrefreshIntervalSecondswhen upgrading from0.3.0or earlier, multiplying the old value by 60. - Ensure
refreshIntervalSecondsis between 1 and 86400.
The refresh, refresh-all, and sidebar-toggle actions were also removed.
Delete any custom Herdr keybindings that invoke mergr.refresh,
mergr.refresh-all, or mergr.sidebar-toggle. The mergr.filter-cycle action
remains available.
After restarting, confirm the installed version and daemon state:
herdr plugin list --plugin mergr --jsonherdr plugin uninstall mergrUninstalling a plugin does not edit ~/.config/herdr/config.toml. Remove the
$pr_* sidebar tokens there if they are no longer needed.
Rust 1.88 or newer, including Cargo, is required for development and source builds.
cargo fmt --all -- --check
cargo clippy --locked -- -D warnings
cargo build --release --locked
MERGR_BUILD_FROM_SOURCE=1 herdr plugin link /path/to/mergr