Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Projects View

A read-only board for the GitHub Projects (v2) linked to the current repository (gh repo view --json projectsV2), with the board itself fetched over GraphQL (a few points per board).

The board takes the full width and the first linked project shows up right away: one column per Status option in GitHub’s order, plus a No status column for items without one. Cards show the item type ( issue, pull request, draft), number, title and assignees; a card whose item lives in another repository carries a dimmed owner/repo prefix before its number.

Several linked projects, and pinning one

With several linked projects the header reads Board: <title> (i/n) and p / P cycle through them; with none the board explains how to link one (the repository’s Projects tab or gh project link). A top-level projects-board config node pins the page to one board, by title or project number — see projects-board in the Config Reference.

Table mode and the detail pane

t switches to a table with one row per item and the project’s fields (Status, Priority, Estimate, Iteration, dates, custom text / number fields) as sortable columns — h / l and s pick the sort column.

The detail pane lists every field value of the selected item, then the issue / PR body and comments as in the GitHub view (drafts show their body).

The optional projects list pane

A projects list pane also exists but is not placed by the built-in layout. Placing it in your config gets a selectable list of the linked projects back — see the recipe for the layout to paste.

Saved views

The project’s saved views (ProjectV2.views, fetched over GraphQL — gh project does not expose them) are read together with the board. The header shows the current view’s name and layout (Board: vig demo board · Sprint [board] (2/3)), and v / V cycle through them. A project without saved views — or a views fetch that fails — falls back to the fixed Status kanban. A Table view renders as the view defines it: its visible fields become the columns (in the view’s order, behind a # column), its sort is the initial sort — descending sorts marked — and its grouping renders one bold header row per group, No <field> last.

A Board view follows the view too: the columns come from its column field (verticalGroupByFields — any single-select or iteration field, in option order plus No <field>; Status when unset), its sort orders the cards inside each column, and its horizontal grouping renders swimlanes — one band per value with its own header line, Space collapses / expands the selected lane and j / k cross between lanes at a column’s edge. A Roadmap view renders a timeline: item rows on the left, a time scale on the right with one bar per item, a yellow today marker and shaded iteration bands. Spans come from the project’s date fields (a name containing start / begin is the span start, target / end / due / finish the end; a single date field is a point) or, for items without dates, from the iteration field’s start and duration. + / - zoom between month, week and day scales, h / l scroll the timeline, and t drops into the table and back. Items without a span are listed without a bar.

A view’s filter (status:Todo -label:bug assignee:@me is:issue no:milestone …) is evaluated locally against the items already fetched — no extra API call — before grouping and sorting, in every layout. Supported: free-text title words, field:value with , lists and quoted values, - negation, is:issue|pr|draft, no: / has:, assignee: (@me is the signed-in login), label:, milestone:, repo:. Ranges (>, ..), wildcards and is:open|closed cannot be evaluated: the status bar says ⚠ filter: unsupported "…" and those tokens are ignored. The status bar also counts what the filter hid ((3 filtered out)).

Key bindings

KeyAction
p / PNext / previous linked project
h / l, / (board)Previous / next column (table mode: sort column)
j / k (board)Move between cards in a column (table mode: rows)
t (board)Toggle table mode
s (board, table mode)Cycle the sort column
Enter / i (board)Focus the detail
v / VNext / previous saved view of the project
SpaceCollapse / expand the selected swimlane
+ / -Zoom the roadmap time scale in / out
oOpen the project / item in the browser
yCopy the project / item URL
j / k / Ctrl+d / Ctrl+u (detail)Scroll
h / Esc (detail)Back to the board
Tab / Shift+TabCycle panes: Board → Detail
/ n NSearch item titles / numbers across columns
rRe-read the linked projects, the board and the shown item

Auto-refresh

While the page is shown, vig asks GitHub every projects-poll-interval (30 seconds by default) whether the board changed. The probe reads only the project’s updatedAt — one GraphQL point; moving a card or editing a field bumps it — and re-fetches the board only when it moved, keeping the selection, the view and the sort. The status bar shows the board’s age (board 12s ago) and a brief ↻ updated after such a refresh. Coming back to the page after five minutes still re-fetches a stale board. Both follow github-auto-refresh, the idle slow-down and the low-quota throttle.

Constraints

  • gh project needs the project token scope. When it is missing the view shows a notice instead of the panes: run gh auth refresh -s project, then press r.
  • Boards are fetched with two GraphQL requests — the fields, saved views and item count, then the items in pages sized to that count — asking only for what the page renders, which costs about a point per hundred item × field pairs (a small board: ~2 points). Past 500 items the status bar says (truncated).
  • The header warns ⚠ api N left when fewer than 1,500 GraphQL points remain of the account’s 5,000/hour, and automatic re-fetches slow down or stop on their own — see Troubleshooting.
  • Nothing in this view adds, moves, edits or deletes anything.