A terminal user interface (TUI) for viewing and managing GitHub pull requests.
-
Three PR Views:
- My PRs: Pull requests you've authored
- Review Requested: PRs where your review is requested
- Labels: PRs matching configured labels
-
CI Integration:
- View CI status (pass/fail/pending) at a glance
- Workflows view showing all CI checks (GitHub Actions, CircleCI, etc.)
- Job logs with foldable steps
- Test failure extraction and copy-to-clipboard
- Annotations view for reviewdog and similar tools
-
PR Preview: View PR description, comments, and reviews in-terminal with markdown rendering
-
Fuzzy Search: Quickly filter PRs using fuzzy matching
-
Branch Checkout: Checkout PR branches directly (supports both git and jujutsu)
-
Labels Management: Configure repo-specific or global label filters
-
Caching: SQLite-based caching for fast startup with auto-refresh every 30 seconds
- GitHub CLI (
gh) installed and authenticated - Git (or jujutsu for jj-based repos)
| Variable | Required | Description |
|---|---|---|
GH_TOKEN |
No | GitHub personal access token. If not set, falls back to gh auth token (requires GitHub CLI to be authenticated) |
CIRCLECI_TOKEN |
No | CircleCI API token for viewing CircleCI job logs. Required only if your project uses CircleCI |
EDITOR |
No | Preferred text editor for viewing job logs (e.g., vim, nvim, code). Falls back to VISUAL, then vim |
VISUAL |
No | Alternative to EDITOR for graphical editors |
For GitHub authentication, you have two options:
- Use GitHub CLI (recommended): Simply run
gh auth loginand ghui will automatically use your token - Use GH_TOKEN: Set the environment variable with a personal access token
# Option 1: Use GitHub CLI (no env var needed)
gh auth login
# Option 2: Set GH_TOKEN in your shell profile
export GH_TOKEN="ghp_your_token_here"For CircleCI integration (optional):
# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.)
export CIRCLECI_TOKEN="your_circleci_token_here"To generate a CircleCI token:
- Go to CircleCI Personal API Tokens
- Click "Create New Token"
- Give it a name and copy the token
Install the latest release with a single command (works with bash, zsh, fish, and other shells):
curl -fsSL https://raw.githubusercontent.com/abeljim8am/ghui/main/install.sh | shOr with wget:
wget -qO- https://raw.githubusercontent.com/abeljim8am/ghui/main/install.sh | shTo install to a custom directory (e.g., /usr/local/bin):
curl -fsSL https://raw.githubusercontent.com/abeljim8am/ghui/main/install.sh | INSTALL_DIR=/usr/local/bin shcargo install --path .Download from the Releases page.
Supported platforms:
- macOS ARM64 (Apple Silicon)
- Linux x64
- Linux ARM64
Run ghui from within a Git repository:
cd your-repo
ghui| Option | Description |
|---|---|
-v, --version |
Print version |
--clear-cache |
Clear the local cache and exit |
| Key | Action |
|---|---|
1 |
Switch to My PRs tab |
2 |
Switch to Review Requested tab |
3 |
Switch to Labels tab |
j / ↓ |
Move down |
k / ↑ |
Move up |
g |
Go to top |
G |
Go to bottom |
/ |
Start fuzzy search |
Enter |
Open PR preview |
o |
Open PR in browser |
c |
Checkout branch |
w |
Open workflows/CI view |
p |
Open PR preview |
r |
Refresh current view |
l |
Manage labels |
? |
Show help |
q |
Quit |
| Key | Action |
|---|---|
| Type | Filter PRs |
Enter |
Accept search, exit search mode |
Esc |
Clear search and exit |
↓ / Tab |
Move to next result |
↑ / Shift+Tab |
Move to previous result |
| Key | Action |
|---|---|
j / ↓ |
Scroll down |
k / ↑ |
Scroll up |
Ctrl+d |
Half-page down |
Ctrl+u |
Half-page up |
g |
Go to top |
G |
Go to bottom |
o |
Open PR in browser |
q / Esc |
Close preview |
| Key | Action |
|---|---|
j / ↓ |
Next job |
k / ↑ |
Previous job |
Enter |
Open job logs |
r |
Refresh CI status |
o |
Open in browser |
q / Esc |
Close workflows view |
| Key | Action |
|---|---|
j / ↓ |
Next step / scroll down |
k / ↑ |
Previous step / scroll up |
Space |
Toggle step expansion |
Enter |
Open step in external editor |
y |
Copy test failures |
x |
Copy full step output |
o |
Open in browser |
q / Esc |
Close job logs |
| Key | Action |
|---|---|
j / ↓ |
Next annotation |
k / ↑ |
Previous annotation |
v / Space |
Toggle annotation selection |
y |
Copy selected annotations |
o |
Open in browser |
q / Esc |
Close annotations |
Press l to open the labels popup:
| Key | Action |
|---|---|
a |
Add new label |
d |
Delete selected label |
j / ↓ |
Move down |
k / ↑ |
Move up |
Esc |
Close popup |
When adding a label, press Tab to toggle between repo-specific and global scope.
ghui stores its cache and configuration in:
- macOS:
~/Library/Application Support/ghui/ - Linux:
~/.config/ghui/ - Windows:
%APPDATA%\ghui\
The cache is stored in a SQLite database (cache.db) and includes:
- Cached PR data for fast startup
- Configured label filters (repo-specific and global)
Use ghui --clear-cache to reset the cache if needed.
# Clone the repository
git clone https://github.com/abeljim8am/ghui.git
cd ghui
# Build release binary
cargo build --release
# The binary will be at ./target/release/ghui# Run with cargo
cargo run
# Run clippy
cargo clippy -- -D warnings
# Format code
cargo fmtghui uses a Model-View-Update (MVU/Elm) architecture:
- Model (
src/app/model.rs): Application state - Message (
src/app/message.rs): All possible events/actions - Update (
src/app/update.rs): State transitions based on messages - View (
src/view/): UI rendering components
src/services/github.rs: GitHub API integration (PRs, Actions, job logs)src/services/circleci.rs: CircleCI API integrationsrc/services/cache.rs: SQLite caching layersrc/services/search.rs: Fuzzy search implementation
ghui automatically detects whether you're in a git or jujutsu repository by checking for a .jj directory.
Repository detection:
- Git repos: Reads remote URL via
git remote get-url origin - Jujutsu repos: Reads remote URL via
jj git remote list
Branch checkout behavior:
| VCS | Command | Fallback |
|---|---|---|
| Git | git switch <branch> |
- |
| Jujutsu | jj edit <branch>@origin |
jj new <branch>@origin |
For jujutsu, edit is attempted first to move the working copy to the commit. If that fails (e.g., the commit is immutable), it falls back to new which creates a new mutable working copy change on top of the remote branch.
MIT