Terminal UI for keeping up with your open GitHub pull requests across repositories.
ghui gives you one keyboard-driven place to review PR details, inspect diffs, leave diff comments, manage labels, toggle draft state, merge, open PRs in GitHub, and copy PR metadata without leaving the terminal.
PR descriptions and full comment/review threads render Markdown with OpenTUI's native renderer, the same component used by OpenCode. Headings, emphasis, lists, quotes, tables, and fenced code follow the active ghui theme.
Requirements: Bun and the GitHub CLI, authenticated with gh auth login.
git clone https://github.com/kkrausse/ghui.git
cd ghui
bun install
bun link
ghuiThis checkout now includes a native LINEAR tab containing the migrated
Linear TUI (inbox, My Issues, projects, search, details, editing, and comments).
It shares GHUI's renderer; it does not launch another CLI. The original app in
kevin-scripts remains untouched until migration audits are complete.
- Click LINEAR, or press
7from the home list (3in a repository). ctrl+left/ctrl+right(orctrl+tab/ctrl+shift+tabwhere supported) switch host tabs. Plaintabremains Linear's pane-navigation key.- Finish or cancel a Linear picker/search input/composer before leaving its tab.
- Linear credentials are resolved on the first visit, from
LINEAR_API_TOKENor the local macOS Keychain itemlinear-api-token. No credential is bundled. - Setup:
ghui --linear-login; removal:ghui --linear-logout. Source-mode equivalents arebun src/index.tsx --linear-login/--linear-logout. - GitHub PR links in Linear open in GHUI's PR view; other web links open in the browser, and non-web link schemes are refused.
See plans/linear-workspace-migration.md for the migration scope.
Run from source without the linked command: bun run dev. For offline UI work with generated data: bun run dev:mock.
With Nix flakes:
nix develop
bun install
bun run devGHUI_PR_FETCH_LIMIT: max PRs fetched, defaults to200GHUI_RUN_FETCH_LIMIT: max workflow runs fetched per PR, defaults to20
Example:
GHUI_PR_FETCH_LIMIT=100 ghuiYou can also copy .env.example to .env and edit the values locally.
ghui stores UI preferences in config.json under GHUI_CONFIG_DIR when set,
otherwise under the platform config directory. On Linux this is normally
~/.config/ghui/config.json.
Example:
{
"theme": "system",
"systemThemeAutoReload": true,
"showScrollbars": false
}systemThemeAutoReload defaults to false. Set it to true to let external
theme reload signals update the active system theme palette while ghui is
running.
Scrollable panes hide their scrollbar rails by default. Set showScrollbars
to true to display them while retaining the same keyboard and mouse scrolling
behavior.
When libdv is installed, the diff view (d) is drawn by
dv, a Rust diff viewer, loaded in-process
through bun:ffi. It brings a file tree, folding, hidden-context expansion,
/ search, and drag-to-copy. Review comments render inline under their lines.
enteron a line comments on it;vstarts a range, andentercomments on the range. Clicking a line number also starts a comment.enteron a thread replies to it;n/pmove between threads.escgoes back (after clearing any dv selection, search, or range);Rreviews the PR,Ycopies its link, andctrl-popens commands.
Comments are posted through ghui's own comment dialog. Hidden context comes from
the PR's local clone (see repoPaths below) when its objects are fetched.
Build and install the library from a dv checkout:
cargo build --release
install -m 755 target/release/libdv.dylib ~/.local/lib/ # libdv.so on LinuxGHUI_DV_LIB overrides the path. Without the library, ghui uses its built-in
diff pane.
Press e on a pull request (in the list, detail, or diff view) to hand it off
to your editor. ghui suspends the TUI, runs your command attached to the
terminal, and resumes when it exits.
Configure this in config.json:
{
"editorCommand": "tmux new-window -c {{repoPath}} 'gh pr checkout {{number}} && nvim -c \":DiffviewOpen {{baseRef}}...{{headRef}}\"'",
"repoPaths": {
"kkrausse/ghui": "~/Documents/kkrausse/ghui",
"kkrausse/*": "~/Documents/kkrausse/*",
":owner/:repo": "~/src/github.com/:owner/:repo"
}
}repoPaths maps a repository to a local clone, matched in order: an exact
owner/repo key, then an owner wildcard (owner/*, where * becomes the repo
name), then the generic :owner/:repo template. ~ expands to your home
directory.
editorCommand is a shell command template with these substitutions:
{{repo}}— fullowner/repo{{owner}},{{name}}{{number}}— PR number{{headRef}}— PR head branch{{baseRef}}— base branch{{author}}{{url}}{{repoPath}}— resolved local path (requires a matchingrepoPathsentry)
If editorCommand is omitted, ghui falls back to $VISUAL/$EDITOR opening
the resolved repoPath. Some common recipes:
Press a on a pull request to open its GitHub Actions runs full-screen,
scoped to the PR's head commit:
- The runs list shows each workflow run with status, conclusion, duration, and age.
enterdrills into a run to see its jobs and steps; failing steps are easy to spot.n/pjump between failures,enterexpands a step,oopens the run in your browser,rrefreshes, andescwalks back out.
Requires the GitHub CLI (gh) the same as the rest of ghui; nothing extra to configure.
The home tabs are Repos, My PRs, Review requested, Assigned PRs, Mentioned PRs, and Issues. PR queues span all repositories; Review requested shows open PRs requesting your review. Inside a repository, the tabs are Pull Requests and Issues. Click a tab or use the shortcuts below.
up/down: move selectionk/j: move selectionleft/right: navigate PR list ↔ PR details/description ↔ diff (no wrapping); inputs and modals keep their own arrow behaviorgg/G: jump to first or last pull requestctrl-u/ctrl-d: page up or downtab/shift-tab: switch top-level tabs1–6: select a home tab by position (1–2inside a repository)ctrl-p/cmd-k: open the command palette/: filterenter: expand details; normal PR actions still work while details are expanded- Expanded PR details show the description followed by the conversation in one scroll area. Use
↑/↓orj/kto select the description or a comment; page keys and the wheel scroll independently.ycopies the selected link, whileshift-yalways copies the PR link.enteron a comment opens the existing reply editor (also available as Reply to comment in the command palette).copens the dedicated comments view at the selected comment for additional actions. esc: return from expanded details, leave diff/comment mode, or close modalr: refreshd: view stacked diff for all changed filesa: view this PR's GitHub Actions runs (jobs, steps, and failing logs)shift-r: review or approve the selected pull requestup/down/pageup/pagedown: move comment target while viewing a diffenter: open a commented diff line, or start a comment on an uncommented linev: start or clear a multi-line diff comment rangey: copy a link to the selected diff line, or to the range selected withvand the movement keysn/p: jump between diff comment threadsf: open the changed-files navigator while viewing a diffh/l: choose the deleted or added side while in split diff comment mode[/]: switch files while viewing or commenting on a diffm: preview the selected.mdor.markdownfile in a nearly full-height rendered Markdown dialog; drag to select rendered text, then pressy/cmd-cto copy the selection (the complete source is copied when nothing is selected), and usem/escto closeshift-y: copy only the selected pull request's GitHub links: toggle draft or ready-for-review statem: mergex: close with confirmationt: choose a fixed theme, includingSystemto match your terminal colors; pressmin the theme picker to follow the OS light/dark appearance with separate theme choicesl: manage labelso: open PR in browsere: open PR in your editor (configurable; seeeditorCommand/repoPaths)y: copy PR metadata in the list; copy the selected link in description/comments. Copy pull request metadata remains available in the command palette.q: quit
Authored-only pull request views render compact one-line rows because the author identity is implied by the active view. Mixed-author views continue to show the author and branch metadata row.
Review submission:
- Press
shift-rto open the review modal. - Use
j/korup/downto choose Comment, Approve, or Request changes. - Press
enterto move to the optional summary area. - Press
enteragain to submit, orshift-enterto insert a newline. - Press
escfrom the summary to return to action selection; pressescfrom action selection to cancel.
