A lightweight, continuously-updating terminal dashboard for the GitHub pull requests you care about. Built to live in a terminal tab all day.
Dashboard recreation
PRD — lindy-ai/lindy refreshed 7s ago
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
▾ ACTIVE (3)
#28351 Integration account picker
✕ failing ✓ approved ✓ mergeable CI FAIL
#28372 Fix personal MCP migration
◷ running ✓ approved ✓ mergeable RUNNING
❯ #28391 Guardrail select not updating
✓ passing ✓ approved ✓ mergeable GREEN
▸ WAITING (1)
▾ PARKED (1)
#28114 Integration refactor
— no checks — no review — draft DRAFT
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
j/k move · 1-3 group · h/l shift group · C groups · enter open · c checks · v detail · r refresh · / filter ·…
prd uses the installed GitHub CLI (gh) as its only GitHub transport and
auth layer — it never touches credentials, OAuth, or the GitHub API directly. It
keeps your personal organization (which PR belongs to which group) in a small
local JSON file, keyed per repository.
-
Go 1.23+ (only to build)
-
GitHub CLI installed: https://cli.github.com
-
Authenticate once:
gh auth login
go install github.com/bgar324/prd/cmd/prd@latestOr build from a checkout:
git clone https://github.com/bgar324/prd
cd prd
go install ./cmd/prdprd is a single ~5 MB static binary with no runtime dependencies beyond gh.
prd # dashboard for the current repo, your open PRs
prd --repo owner/repo # choose a repository explicitly
prd --all # show all open PRs in the repo (not just yours)
prd --refresh 15s # set the background refresh interval (default 25s)Run prd from inside any git repository or worktree and it auto-detects the
GitHub repo (via gh repo view, falling back to the origin git remote). It
works correctly across multiple worktrees of the same repo.
| Key | Action |
|---|---|
j k / ↑ ↓ |
move selection |
1 2 3 |
assign the selected PR to the first / second / third group |
h l / ← → |
shift the selected PR to the previous/next group |
C |
assign and manage groups |
g G |
jump to top / bottom |
enter / o |
open the selected PR in your browser |
c |
detailed per-check view |
v |
PR detail panel |
y |
copy the selected PR's URL |
r |
refresh now |
/ |
filter by number / title / branch / label, or a quick view: all, failing, running, review, green, drafts |
m |
merge the selected PR (confirmation modal — squash / merge / rebase, optional branch delete) |
d |
toggle draft / ready for review (confirmation) |
u |
update the PR branch from base (confirmation) |
? |
help |
esc |
clear filter / close a modal |
q / ctrl+c |
quit |
Destructive GitHub actions (m, d, u) always require an explicit confirm.
They can't fire from a single stray keypress. enter/o open a browser tab; if
you'd rather nothing ever auto-launch a browser, just don't press them.
prd keeps GitHub state and your personal groups strictly separate.
Each refresh is a single batched gh pr list --json … call that pulls everything
(number, title, draft, review decision, mergeable, merge state, the full status
check rollup, labels, reviewers, …) — never one call per PR.
From that it derives, per PR:
-
CI column — rolled up from the status check rollup:
✓ passing,✕ failing,◷ running, or— no checks. A singleCANCELLED/STALEcheck does not flip a PR to failing (matchesgh pr checks). -
Review column —
✓ approved,✕ changes,◷ review, or— no review. -
Merge column —
✓ mergeable,✕ conflict,◷ merge?, or— draft. -
Badge — the dominant, most actionable state:
Badge Meaning CONFLICTmerge conflict CI FAILa required check is failing CHANGESchanges requested DRAFTdraft PR RUNNINGchecks still running REVIEWwaiting on review BLOCKEDapproved but blocked by another requirement GREENapproved + mergeable + checks passing
c opens an on-demand gh pr checks view per selected PR for individual checks.
Open PRs start in the first group. A repository begins with ACTIVE, WAITING, and PARKED, but those defaults are ordinary groups: they can be renamed, moved, collapsed, or deleted. At least one group must remain.
Press C to assign the selected PR or manage the group list:
j/kselects a group;enterassigns the selected PRspacecollapses or expands a groupJ/Kmoves a group down or uprrenames the focused groupncreates a groupxdeletes a group after confirmation; its PRs move to the first remaining group
Group manager recreation
╭─────────────────────────────────────────────────────────╮
│ GROUPS — ASSIGN #28391 │
│ │
│ ❯ ▾ NOW (3) (current) │
│ ▸ WAITING (1) │
│ ▾ PARKED (0) │
│ ▾ Project A (1) │
│ + new group │
│ │
│ j/k select · J/K move · space collapse · enter assign │
│ r rename · n new · x delete · esc close │
╰─────────────────────────────────────────────────────────╯
The manager still opens when every group is collapsed. Group order, names, and assignments persist per repository; collapse state lasts for the current session.
{
"version": 3,
"repos": {
"github.com/owner/repo": {
"prs": {
"28391": "active",
"28294": "waiting",
"28114": "project-a"
},
"customs": [
{ "key": "project-a", "title": "Project A" }
],
"order": ["active", "project-a", "waiting", "parked"],
"titles": { "active": "NOW" }
}
}
}State is keyed by host/owner/repo, so the same PR number in different repos
never collides, and a malformed state file never bricks the app — it falls back
to empty state with a warning.
- Fetches immediately on startup.
- Background refresh every 25s (configurable via
--refresh);rforces one now. - Old data stays visible until new data arrives — the screen never blanks.
- Overlapping refreshes are suppressed; a subtle
refreshing…indicator shows activity and the last successful refresh time. - Transient failures (network, rate limits) keep existing data and surface a non-destructive "last refresh failed" note.
cmd/prd/main.go flags, config dir, launches Bubble Tea
internal/ghclient/ gh CLI wrapper: repo/user detect, batched PR fetch,
checks, merge/draft/update, clipboard, OS-open
internal/model/ domain PullRequest, CI + badge derivation, sort, filter,
category
internal/store/ local JSON persistence (per-repo, atomic, stale cleanup)
internal/tui/ Bubble Tea program: model, update, view, styles, list/nav
GitHub fetching, status derivation, persistence, and rendering are kept
separate. All subprocesses use exec.CommandContext for cancellation — no
bash -c.
MIT