gh-dash

repository·main·Indexed 11 days ago

https://github.com/dlvhdr/gh-dash

A terminal user interface (TUI) for GitHub that enables developers to manage pull requests, issues, and other activities using vim-style keyboard shortcuts and custom workflows. Features include customizable views, YAML-based configuration, and integration with the GitHub CLI.

Tokens
25.4K
Snippets
71
Records
146
Agent score
95%

What's inside gh-dash

  1. Overview of DASH

    main

    DASH is a rich terminal user interface (TUI) designed for GitHub that allows developers to manage their workflow without leaving the terminal. It provides a keyboard-centric experience for navigating and interacting with GitHub repositories.

    Key Features

    • Customizable Views: Define per-repo sections for Pull Requests (PRs) and Issues.
    • Keyboard Navigation: Uses overridable vim-style hotkeys for fast navigation.
    • Workflow Integration: Perform standard GitHub actions like diffing, commenting, checking out code, pushing, and updating directly from the TUI.
    • Custom Actions: Define specific actions to suit your unique workflow.
    • Configuration: Full control over settings via a YAML configuration file.
  2. Explore gh-dash configuration options

    main

    The dash configuration is schematized and covers several functional areas. You can find detailed documentation for each of the following categories:

    • Schema: Use this to configure your IDE for autocomplete when editing the config file.
    • Defaults: Documentation for the default setting options.
    • Searching: How to search and filter issues and pull requests.
    • PR Section: Configuration for the PR sections of your dashboard.
    • Issue Section: Configuration for the issue sections of your dashboard.
    • Keybindings: Defining commands for your dashboard.
    • Layout: Configuring the dashboard's layout.
    • Theme: Configuring the dashboard's visual theme.
    • Reusing Settings: How to define global settings that are always applied.
  3. Project structure and content management

    main

    The documentation site follows the Starlight/Astro directory structure:

    • Documentation Content: Add .md or .mdx files to src/content/docs/. Each file name determines its route.
    • Images: Place images in src/assets/ and reference them in Markdown using relative links.
    • Static Assets: Place files like favicons in the public/ directory.
    • Configuration: Core configuration is handled via astro.config.mjs and src/content.config.ts.
    .
    ├── public/
    ├── src/
    │   ├── assets/
    │   ├── content/
    │   │   └── docs/
    │   └── content.config.ts
    ├── astro.config.mjs
    ├── package.json
    └── tsconfig.json
  4. Understand the DASH configuration hierarchy

    main

    DASH uses a layered configuration model where settings are applied in a specific order of precedence. This allows you to define common settings (like themes and keybindings) globally and override or extend them for specific repositories or one-time sessions.

    Precedence Order (Highest to Lowest):

    1. Ad-hoc/Per-repo overrides: Settings from a .gh-dash.yml file in a git repo root, or settings provided via the --config flag or GH_DASH_CONFIG environment variable.
    2. Included files: Files referenced via the include directive within a config file (merged in order, later files override earlier ones).
    3. Global config: The base configuration, typically located at $HOME/.config/gh-dash/config.yml (following XDG specs).

    When merging:

    • Most settings are overridden by higher-precedence files.
    • keybindings are unioned across all files.
    • sections are taken from the file that defines them (they are not unioned).
  5. Understand Notifications limitations

    main

    Users should be aware of the following constraints in the Notifications feature:

    • Mark as Unread: Not supported by GitHub's REST API; use Bookmarks as a workaround.
    • Discussion/Release Content: Detailed sidebar content is only available for PR and Issue notifications. Other types open in a browser.
    • Local State Persistence: Bookmarks and 'Done' status are stored locally in ~/.local/state/gh-dash/ and are not synced with GitHub or other machines.
    • Done Notifications: 'Marking as Done' is a local filter. These notifications still exist in the GitHub API. Local 'Done' entries older than 90 days are pruned on startup.
    • Server-Side Filtering: GitHub does not support filtering by reason on the server. All notifications are fetched before client-side filters are applied.
  6. Notification Command Architecture

    main

    Commands in the notifications section are split into two categories based on their scope:

    Section Methods

    These operate on the internal state of the notificationssection and are triggered by keybindings in the section's Update method. They include:

    • markAsDone(): Persists the current notification's ID and updated_at timestamp to the DoneStore.
    • markAllAsDone(): Marks all currently visible notifications as Done.
    • markAsRead(): Marks the current notification as read.
    • markAllAsRead(): Marks all notifications as read.
    • unsubscribe(): Unsubscribes from the current thread via the GitHub API.
    • openInBrowser(): Marks the notification as read and opens it in a browser.

    Standalone Functions

    These require enriched data (like full PR details) that only exists in the notificationView (sidebar). They are called from ui.go rather than the section itself:

    • DiffPR(ctx, prNumber, repoName): Opens a diff view for a specific PR.
    • CheckoutPR(ctx, prNumber, repoName): Checks out a PR branch locally.
  7. How the Bookmark and Done systems work

    main

    Since GitHub's API does not natively support 'bookmarks' or a persistent 'done' state that hides notifications from all views, gh-dash implements these locally.

    Bookmarks

    • Storage: Saved in ~/.local/state/gh-dash/bookmarks.json as a JSON array of IDs.
    • Behavior: Bookmarked items appear in the default inbox even if they are read. They are styled as read (faint text) but show a 🔖 icon.
    • Access: Managed via the data.GetBookmarkStore() singleton.

    Done Tracking

    • Storage: Saved in ~/.local/state/gh-dash/done.json as a JSON object mapping IDs to RFC 3339 timestamps (id -> updatedAt).
    • Resurfacing Logic: Unlike a simple ID list, the DoneStore tracks the updated_at timestamp. If a notification is updated (e.g., a new comment is added) after it was marked as 'Done', it will automatically resurface in the UI.
    • Pruning: Entries older than 90 days are automatically pruned to keep the local file size manageable.
    • Pagination: To ensure a full page of results is shown even when many items are marked 'Done', the fetch logic automatically requests additional pages from the GitHub API until the requested limit is met.
  8. Notification Row Layout and Visuals

    main

    Each notification row in the table uses a three-line layout to provide a visual hierarchy:

    1. Line 1 (SecondaryText): Repository name with issue/PR number. Includes a 🔖 icon (in WarningText color) if bookmarked.
    2. Line 2 (PrimaryText): Notification title. It is bold if the notification is unread.
    3. Line 3 (FaintText): Activity description (e.g., "@username commented on this pull request").

    Unread Indicator: Unread notifications are identified by a blue dot displayed below the notification type icon. Note that text is not dimmed for read notifications; only the blue dot indicates status.

  9. How notifications and their actions work

    main

    Notifications in gh-dash require an explicit action to view content to prevent accidental marking of items as 'read' (a side effect of the GitHub API).

    When a notification is selected but not yet viewed, an action prompt is displayed in the Preview pane. Users can then choose to:

    • View: Press [Enter] to view the PR/Issue (this marks it as read).
    • Mark as Done: Press [D] to hide the notification locally.
    • Mark as Read: Press [m] to mark it as read without opening it.
    • Unsubscribe: Press [u] to stop receiving notifications for the thread.
    • Toggle Bookmark: Press [b] to bookmark the item.
    • Toggle Filtering: Press [t] to toggle filters.
    • Sort by Repo: Press [S] to sort.
    • Open in Browser: Press [o] to open the notification in a web browser.

    For non-PR/Issue types (like Discussions or Releases), the [Enter] key defaults to 'open in browser' instead of 'view'.

          Press [Enter] to view the PR
          (Note: this will mark it as read)
    
          Other Actions
    
                [D]  mark as done
                [m]  mark as read
                [u]  unsubscribe
                [b]  toggle bookmark
                [t]  toggle filtering
                [S]  sort by repo
                [o]  open in browser
            [Enter]  view
  10. Understand and configure Smart Filtering

    main

    Smart Filtering automatically adds a repo:<RepoName> filter to your PR and issue sections if they do not have an explicit repo: field. The <RepoName> is determined by:

    1. The GH_REPO environment variable (if set).
    2. The remote repository tracked by your current working directory's git clone (checking upstream, then github, then origin).
    3. The first remote returned by git remote if none of the above match.

    Managing Smart Filtering:

    • Disable globally: Set smartFilteringAtLaunch: false in your configuration.
    • Toggle for current section: Press the t key (or your custom binding for togglesearch).
    • Manual edit: Press / to edit the search bar. Removing the repo: filter manually will turn off Smart Filtering for that section; adding it will turn it on.
    smartFilteringAtLaunch: false