ghzinga is a small terminal UI for keeping GitHub pull requests and issues
open on the side while you work.
It is not trying to be a full GitHub client. It is for maintainers who want a
faster-than-the-web-UI view of the current status, comments, checks, files, and
links for a PR or issue, with automatic refresh. It is similar in spirit to
gh dash, but focused on a single item
first instead of a dashboard list.
ghzinga is inspired by Herdr and built with
Ratatui and
Crossterm, so the terminal UI is
interactive: click tabs and links, expand rows, scroll with the mouse wheel,
drag the scrollbar, or use keyboard shortcuts.
ghzinga.mp4
Install from crates.io:
cargo install ghzingaInstall from a local checkout:
cargo install --path .This installs two equivalent commands:
gzgghzinga
Open a pull request or issue:
gzg openclaw/openclaw#81834
gzg https://github.com/openclaw/openclaw/pull/81834
gzg https://github.com/openclaw/openclaw/issues/88499Run gzg again from the same terminal context to restore the last ghzinga
dashboard for that pane, tmux pane, Herdr pane, working tree, or named session.
Use --new to start a separate saved session, --no-restore to ignore saved
state for one run, or --session <name> to pick a specific saved session.
ghzinga reuses your existing GitHub CLI login through gh auth token. You can
also set GH_TOKEN or GITHUB_TOKEN to override that token. Public repositories
can fall back to unauthenticated GitHub data when credentials are unavailable.
Useful launch options:
gzg --tab files openclaw/openclaw#81834
gzg --theme solarized --spacing compact openclaw/openclaw#81834
gzg --width-mode full --scrollbar always openclaw/openclaw#81834
gzg --api-depth full openclaw/openclaw#81834
gzg --refresh-seconds 0 openclaw/openclaw#81834For pull requests, ghzinga shows:
- overview and conversation
- author, labels, branches, review state, and merge/check status
- activity, reviews, review comments, and linked issues or PRs
- commits
- checks and status contexts
- changed files with expandable patch context
For issues, ghzinga shows:
- overview and conversation
- author, labels, assignees, state, milestones, and projects
- timeline activity and comments
- linked issues or PRs
Resources load progressively. The TUI shell appears immediately, core PR/issue data replaces the loading placeholder as soon as GitHub returns it, and slower details such as timeline pages, checks, review threads, and file patches fill in afterward. File diffs are fetched lazily when the Files tab needs them.
The UI is built for active terminal use:
- click tabs to switch views
- click the top-right plus button, or press
n, to open another PR or issue in a new tab - when multiple resources are open, click the resource tabs to switch or close them
- click GitHub issue/PR links to choose between opening here or in a new tab
- click same-resource comment links to focus the matching Activity entry
- click rows and
[more]controls to expand details - click footer actions for refresh, expand/collapse, settings, help, and quit
- scroll with the mouse wheel or keyboard
- drag the scrollbar when content is long
- press
?in the app for the full keyboard help
Common keys:
q: close the active modal/help/settings layer, then ask before quittingCtrl-C: quit immediatelyr: refreshn: open another PR or issue in a resource tabo: open a PR or issue in the current tabx: close the current resource tabCtrl-Cin the open-resource modal: clear input, then close when emptyLeft,Right,h,l: switch Overview, Activity, and other content tabsTab,Shift+Tab,Shift+Left,Shift+Right: switch PR/issue tabsUp,Down,j,k,PageUp,PageDown,Home,End: scrollEnter: activate the first visible link or actiony: copy the first visible GitHub URLs: settings?: help
The config file is:
~/.config/ghzinga/config.toml
Default config:
[ui]
theme = "default"
symbols = "emoji"
spacing = "comfortable"
width_mode = "fixed"
fixed_width = 118
scrollbar = "on-scroll"You can change theme, symbols, spacing, width, and scrollbar behavior from the settings view inside the app.
Supported themes:
default, catppuccin, catppuccin-latte, terminal, tokyo-night,
tokyo-night-day, dracula, nord, gruvbox, gruvbox-light, one-dark,
one-light, solarized, solarized-light, kanagawa, kanagawa-lotus,
rose-pine, rose-pine-dawn, vesper
Supported setting values:
symbols:emoji,asciispacing:comfortable,compactwidth_mode:fixed,fullfixed_width: clamped between72and180scrollbar:always,on-scroll,hidden
ghzinga saves open PR/issue tabs and UI state under:
~/.local/state/ghzinga
Cached GitHub resource snapshots are stored separately under:
~/.cache/ghzinga
Environment overrides:
GZG_STATE_HOME: alternate session state directoryGZG_CACHE_HOME: alternate resource cache directoryGZG_RUNTIME_HOME: alternate runtime socket directory for live session controlGZG_SESSION: default named session
Session commands:
gzg sessions
gzg session show <id-or-name>
gzg session rename <id-or-name> <name>
gzg session delete <id-or-name>Control a running session from another shell:
gzg open dutifuldev/ghzinga#29
gzg open --session <id-or-name> dutifuldev/ghzinga#29
gzg open --session <id-or-name> dutifuldev/ghzinga#29 dutifuldev/ghzinga#32
gzg set --session <id-or-name> theme solarized
gzg set --session <id-or-name> symbols emoji
gzg set --session <id-or-name> spacing comfortable
gzg set --session <id-or-name> width-mode fixed
gzg set --session <id-or-name> fixed-width 118
gzg set --session <id-or-name> scrollbar on-scrollgzg sessions includes each session's running/saved status, active resource,
and resource count. If the session is running, control commands update the live
TUI without stealing terminal focus. gzg open adds or focuses resource tabs in
that session, including while another resource is still loading. If the target
session is not running, gzg open updates the saved session so the resources
appear on the next restore.
ghzinga refreshes automatically every 300 seconds by default. Use
--refresh-seconds 0 to disable automatic refresh, or press r to refresh
manually.
When a resource has more data than the normal GitHub API depth loads, ghzinga shows a full-depth action so you can fetch the rest without restarting the app. Normal successful refreshes stay quiet; status messages are reserved for active loading, changed sections, warnings, and errors.