Read the issues of the repo you are working in, in a herdr pane, without opening a browser tab.
The pane shows the open issues of the repo behind the current workspace; enter
opens one and renders its body and comment thread as terminal text. It is
read-only — it never comments, labels, assigns or closes anything, and it
issues no mutating GitHub request at all.
It costs nothing while idle: no browser, no polling, no timers, no background
process. Data comes from one small GraphQL query, is cached in SQLite, and
refreshes only when you press r. Opening the pane on a repo you have already
read is instant and needs no network.
herdr plugin install nyanyaon/github-issue-herdr-pluginHerdr shows an install preview listing the commands that will run, and installs nothing until you confirm.
What that install does:
- Reads the
versionfromherdr-plugin.tomland detects your target fromuname. - Downloads
herdr-issues-<target>.tar.gzfrom the matching GitHub Release. - Verifies it against
checksums.txtbefore unpacking it. An archive whose SHA-256 does not match is deleted unread and never placed or run. - Unpacks the binary to
bin/herdr-issuesinside the plugin directory, which is where the manifest's pane entrypoint expects it.
On any failure — no release for your platform, no network, a checksum
mismatch, an unrecognised target — it falls back to cargo build --release, so
an unpublished platform still ends up with a working plugin. The only way an
install can fail outright is a fallback with no Rust toolchain installed, and it
says so.
The script is scripts/fetch-or-build.sh; it runs
on herdr plugin install only, never on herdr plugin link.
Open it once:
herdr plugin pane open --plugin nyanyaon.herdr-issues --entrypoint issuesTo bind a key, add this to ~/.config/herdr/config.toml:
[[keys.command]]
key = "prefix+i"
type = "plugin_action"
command = "nyanyaon.herdr-issues.open"
description = "GitHub issues"Then herdr server reload-config, and ctrl+b i opens the pane.
A plugin_action binding resolves an action id, not a pane id, so the
manifest declares one action, open, whose only job is to ask herdr to open the
pane above. nyanyaon.herdr-issues.open is <plugin id>.<action id>.
The pane opens as a split. Every key it binds is a plain key — herdr keeps its
own bindings behind ctrl+b, and this plugin binds neither ctrl+b nor
ctrl+v.
List
| key | does |
|---|---|
j / k, arrows |
move |
g / G |
top / bottom |
enter |
open the issue |
/ |
filter as you type — number, title, label and author. No network. |
o |
cycle open → closed → all |
r |
refresh the list |
q |
close the pane |
Detail
| key | does |
|---|---|
esc |
back to the list, position intact |
j / k |
scroll |
n / p |
next / previous issue without going back |
m |
load more comments |
r |
re-fetch this issue |
q |
close the pane |
A ● on a list row means the issue has changed since the copy in the cache; it
re-fetches when you open it, not before.
GitHub's GraphQL API requires authentication — there is no anonymous mode — so the pane needs a token. It reads one from the first of these that yields anything, in this order:
$GITHUB_TOKEN$GH_TOKENgh auth token— if you already use theghCLI, this is zero setup.token_fileinconfig.toml— a path to a file whose first line is the token, trimmed.- Otherwise the pane says so on its status line and shows nothing else.
The plugin never writes a credential. It has no OAuth app, no token of its
own, and nothing for you to rotate — every token above is one you already own and
manage elsewhere. token_file is read, never written.
The token is resolved once, at startup. If it expires mid-session you will see
token rejected; reopen the pane after fixing it.
A read-only viewer should never hold write access. Use a fine-grained personal access token with, on the repositories you want to read:
| permission | access |
|---|---|
| Issues | Read-only |
| Metadata | Read-only (required alongside Issues) |
Nothing else. No contents, no pull requests, no write anywhere.
Fallback, for organisations that have not enabled fine-grained tokens, or if
you just ran gh auth login: a classic PAT with public_repo for public
repositories, or repo for private ones. repo is read and write on
everything, which is far more than this plugin uses — prefer the fine-grained
token where you can.
Optional. A fresh install needs none. If you want it, create
config.toml in the plugin's config directory:
herdr plugin config-dir nyanyaon.herdr-issueslist_page_size = 50 # issues fetched per list query
detail_comment_page_size = 100 # comments per detail page (GraphQL max)
prune_details_after_days = 30
prune_repos_after_days = 90
token_file = "/home/me/.secrets/gh-issues"
# Override the repo for one checkout, keyed by its repo root exactly. For a fork
# whose `origin` is not the repo whose issues you want to read, or a checkout
# with no remote at all.
[repo."/home/me/work/fork"]
slug = "upstream-org/project"Every key is optional. An unknown key warns and is ignored; a malformed file falls back to the defaults rather than refusing to start.
Without an override, the repo is resolved from the workspace's repo root:
origin first, then the sole remote if there is exactly one, otherwise the pane
lists the candidates and asks you to set slug. Only github.com is supported.
Every worktree of a repo shows the same list.
| platform | how you get the binary |
|---|---|
| Linux x86-64 | prebuilt, x86_64-unknown-linux-musl |
| Linux arm64 | prebuilt, aarch64-unknown-linux-musl |
| macOS Intel | prebuilt, x86_64-apple-darwin |
| macOS Apple silicon | prebuilt, aarch64-apple-darwin |
| Windows, anything else | source build, untested |
The Linux builds are static musl binaries, so they do not care what libc your distribution ships, and they work under WSL.
Why prebuilt binaries rather than just building on install: the cache is
SQLite, and rusqlite is vendored with the bundled feature — it compiles
SQLite from C. A source build therefore needs a C compiler as well as a Rust
toolchain, and herdr installs neither. Downloading a verified prebuilt is what
keeps that off your machine and the install down to seconds.
Windows is not a declared platform. herdr-plugin.toml says
platforms = ["linux", "macos"], which is honest rather than silent: a Windows
install falls through to cargo build --release and gets a TUI nobody has tested
there.
- Write anything. No comments, labels, assignees or state changes.
- Poll. Nothing fetches unless you press
r. Nothing retries by itself. - Render images, or align tables — those degrade to their markdown source.
- Pull requests, a cross-repo inbox, or GitHub Enterprise.
herdr plugin link never runs the install script, so the dev loop builds the
binary itself:
cargo build --release
install -D target/release/herdr-issues bin/herdr-issues
herdr plugin link .cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --all --checkReleasing is one command — push a v<version> tag matching the manifest.
.github/workflows/release.yml builds all
four targets, writes checksums.txt and creates the release, and fails before
building anything if the tag and herdr-plugin.toml disagree about the version.
The design lives in CONTEXT.md, docs/SPEC.md
and docs/adr/.
MIT.