Skip to content

Enhanced PR Checks Monitor with Runtime and Latency Tracking #25

@chicks-net

Description

@chicks-net

Problem

The GitHub CLI's gh pr checks --watch command is functional but frustrating in practice. When you push code and want to monitor your CI pipeline, you're stuck watching a command that doesn't handle reality well:

  • Startup delay blindness: Actions can take 30-90 seconds to even start after you create a PR. During this time, --watch just shows nothing or stale data, leaving you wondering if something broke or if GitHub is just being slow.

  • No runtime visibility: Once checks are running, you can't see how long they've been running. Is that test suite taking its usual 3 minutes or has it been stuck for 15? You have no idea without opening a browser.

  • Missing latency data: You can't tell the difference between "job started immediately" vs "job waited in queue for 5 minutes." This is valuable context when deciding whether to wait or go get coffee.

The web UI has some of this information, but buried in multiple clicks. You started with the terminal, you want to stay in the terminal. This tool would bridge that gap with a better CLI experience.

Technical Requirements

Core Functionality

  • Monitor PR check runs in real-time via GitHub API
  • Display check status with:
    • Current state (queued, in_progress, completed, etc.)
    • Queue/latency time (time between PR creation and job start)
    • Elapsed runtime (time since job started)
    • Final duration (when complete)
    • Outcome (success, failure, cancelled, skipped)
  • Handle the startup delay gracefully with useful feedback
  • Update display in-place (not scrolling spam)
  • Color-coded output for quick visual scanning
  • Exit with appropriate status code (0 for all passed, 1 for any failure)

Example Output

PR #123: Add new feature
Branch: chicks/2026-02-08-new-feature

Startup Phase (37s elapsed):
  ⏳ Waiting for Actions to start...
  💡 GitHub typically takes 30-90s to queue jobs after PR creation

Running Checks:
  ✓ markdownlint          [completed in 12s]        (queued: 41s)
  ✓ shellcheck            [completed in 8s]         (queued: 41s)
  ⏳ go-test              [running: 2m 34s]         (queued: 45s)
  ⏳ integration-tests    [running: 1m 12s]         (queued: 52s)
  ⏸️  deploy-preview      [queued: 3m 15s]          (waiting for tests)

Last updated: 2s ago

Configuration

  • Auto-detect current PR from branch (like gh pr checks does)
  • Accept PR number as argument: gh-pr-watch 123
  • Accept PR URL as argument
  • Support configuration file (~/.config/gh-pr-watch/config.yaml or similar):
    • Refresh interval (default: 3-5 seconds)
    • Color scheme preferences
    • Notification preferences (alert on completion, failure, etc.)
    • Expected/baseline durations for common jobs (to highlight anomalies)
    • Output format (compact, detailed, JSON)

Notifications (optional but valuable)

  • Desktop notification when all checks complete
  • Optional sound/bell on completion
  • Webhook support for posting to Slack/Discord/etc.
  • Different notification based on outcome (success vs. failure)

Implementation Considerations

GitHub API Usage

  • Use GitHub REST API or GraphQL API for check runs
  • Respect rate limits (authenticated requests get 5000/hour)
  • Cache results to minimize API calls
  • Use conditional requests (ETag/If-Modified-Since) where possible
  • Handle API errors gracefully (rate limit, network issues, etc.)

Terminal UI

  • Use ANSI escape codes for color and cursor positioning
  • Support both fancy mode (cursor positioning, colors) and plain mode (for CI logs)
  • Detect terminal capabilities (detect if stdout is a TTY)
  • Handle terminal resize gracefully
  • Consider using a TUI library for robustness:
    • Go: bubbletea, termui, or simple fmt with ANSI codes
    • Rust: crossterm, tui-rs, indicatif
    • Bash: just ANSI codes (tput, printf)

State Management

  • Track state changes to avoid unnecessary redraws
  • Calculate deltas: queued time = start_time - created_time, runtime = now - start_time
  • Handle out-of-order updates (API might return stale data)
  • Remember first-seen time to track "startup phase"

Timing Considerations

  • Clock skew: GitHub timestamps are server-side, local clock might differ
  • Timezone handling: convert GitHub UTC times to local time if displaying absolute times
  • Poll interval: balance between freshness and API rate limits (3-5s seems reasonable)

Edge Cases

  • PR with no checks configured (helpful error message)
  • Checks that get re-run (show both attempts?)
  • Checks that are cancelled or skipped
  • Required vs. optional checks (differentiate visually?)
  • Multiple concurrent PRs (support watching multiple PRs at once?)

Possible Tech Stack

Language (per project preferences)

  • Go: Excellent choice - single binary, good GitHub API libraries (go-github), decent TUI libraries, fast startup
  • Rust: Also good - great performance, type safety, excellent error handling; octocrab for GitHub API, crossterm/indicatif for UI
  • Bash: Could work for simple version, but complex for good TUI; would need jq for JSON parsing and curl for API calls
  • Perl: Could work but not ideal for modern API consumption and TUI

Recommendation: Go - best balance of project preference, ecosystem maturity, and deployment simplicity

GitHub API Client Libraries

  • Go: google/go-github (mature, well-maintained)
  • Rust: octocrab (actively developed, good API coverage)
  • Bash: curl + jq (manual but flexible)

TUI/Terminal Libraries

  • Go: charmbracelet/bubbletea (modern, elegant), gizak/termui (dashboard-style), or raw ANSI
  • Rust: crossterm (low-level), tui-rs (higher-level), indicatif (progress bars)
  • Bash: tput, printf with ANSI escape codes

Notifications

  • Cross-platform: gen2brain/beeep (Go), notify-rust (Rust)
  • macOS: osascript / terminal-notifier
  • Linux: notify-send (via D-Bus)
  • Windows: Windows Toast notifications

Integration with gh CLI

Option 1: Standalone Binary

  • Ship as gh-pr-watch (GitHub CLI automatically recognizes gh-* executables as extensions)
  • Users install by putting binary in PATH
  • Invoke as gh pr watch (space, not dash) or gh-pr-watch directly

Option 2: gh Extension

  • Package as official gh extension
  • Install via gh extension install user/gh-pr-watch
  • Better discovery, automatic updates
  • More setup overhead (manifest, documentation)

Recommendation: Start with Option 1 (standalone), migrate to Option 2 once stable

Future Enhancements

  • Historical comparison: "This run is 2x slower than average"
  • Flamegraph/timeline view: Visual representation of job parallelism and dependencies
  • Log streaming: Show live logs from failing jobs without leaving terminal
  • Job step breakdown: Show individual steps within a job with their timing
  • Retry failed jobs: Integrate with gh to trigger re-runs
  • Custom alerting rules: "Alert me if runtime > 10 minutes" or "Alert only on failure"
  • Multi-PR dashboard: Watch multiple PRs simultaneously in split view
  • Export to formats: JSON, CSV, or markdown summary for pasting in PR comments
  • Baseline learning: Automatically learn typical job durations and alert on anomalies
  • Cost tracking: Estimate Actions minutes consumed (for usage monitoring)
  • Workflow visualization: Show dependency graph of jobs
  • Integration with Waybar/Polybar: Status bar widget showing current PR check status

Nice-to-Haves

  • Man page documentation
  • Shell completion (bash, zsh, fish)
  • Update checker (notify when new version available)
  • Verbose/debug mode for troubleshooting API issues
  • Dry-run mode to test configuration without watching
  • Configuration wizard for first-time setup
  • Pre-built binaries for major platforms (Linux, macOS, Windows)
  • Homebrew formula for easy installation on macOS
  • Docker container for running in CI or constrained environments

Success Criteria

  • Handles "waiting for Actions to start" with clear user feedback
  • Shows elapsed runtime for all running checks
  • Shows queue latency for all jobs (time from PR to job start)
  • Updates smoothly without terminal flicker or spam
  • Exits with correct status code for CI integration
  • Works with public and private repositories (authenticated)
  • Gracefully handles API errors and rate limits
  • Performant enough to check every 3-5 seconds without lag
  • Clear documentation and installation instructions
  • Single binary with no runtime dependencies (for Go/Rust)

Prior Art / Related Tools

  • gh pr checks --watch: The baseline we're improving on
  • hub ci-status: Similar functionality for older hub CLI
  • GitHub Actions web UI: Full-featured but requires browser
  • Various CI dashboard tools (Jenkins BlueOcean, CircleCI, etc.): Inspiration for UX patterns

Notes

This is fundamentally a UX improvement over existing tooling. The data is all available via GitHub API, but the presentation in gh pr checks --watch leaves much to be desired. The most valuable additions are:

  1. Startup delay handling: Just acknowledging "yes, it's normal for this to take a minute" reduces anxiety
  2. Runtime display: Being able to see "this is taking longer than usual" helps decide whether to wait or investigate
  3. Latency visibility: Helps understand whether slowness is your code or GitHub's infrastructure

The tool should feel calm and informative rather than anxious and noisy. Good terminal UI is about providing the right information at the right time without overwhelming the user.

This also serves as a good template for other "watch GitHub thing" tools - releases, deployments, issue updates, etc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestin-progressSomebody else has already started on this.
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions