feat(desktop): peek an issue beside the Issues board instead of leaving it
Part of the "Improve Issues board" plan, item "Peek, don't leave": open an issue beside the board or list instead of in its place, so triage keeps its place.
Behavior change
A press or Return on a card or list row now opens a peek of the issue. It no longer replaces the board with the issue's page. The issue's page is still a ⌘ away:
| Gesture | Before | Now |
|---|---|---|
| Press / Return on a card or row | Opens the issue's page | Opens the peek beside the board or list |
| ⌘-press / ⌘Return | (same as press) | Opens the issue's page |
| Peek's "Open as page" button | — | Opens the issue's page |
| Escape | Leaves Issues (on the board) / back to board (on a page) | Closes the peek first. The next Escape works as before. |
| Luke link, ⌘K, Back/Forward | Opens the issue's page | Unchanged |
In a window too narrow for the peek at its minimum width beside one board column, a press opens the issue's page as it always did.
What it does
- A pane of the Issues page, not a side-panel tab. The window's side panel holds a task's tabs: they are kept, ordered and pinned per task. An issue has no task. The automation's Runs pane is the precedent this follows. The peek docks at the page's right on
usePaneSlide. Its left edge is the side panel's resize edge (useResizableEdge): it resizes between 360 and 720px, the width is kept on this Mac, and dragging past the minimum closes the peek. The page'sPaneGlidemoves the toolbar and the list as the pane takes or gives back its room. No width is ever animated. - The peek follows the keyboard. While a peek is open, ↑ ↓ ← → (and Tab or a press) move through the cards and the peek shows whichever card has focus. That card is marked with the sidebar's open-row fill, and in the list the row is
current. - Moving reads nothing. The peek shows the issue as the list holds it. The list re-reads every minute and after every write, so holding an arrow key sends no
ISSUES_READ. There is no debounce. Changes made from the peek go through the list's ownchange, so the card moves the moment the answer lands. An issue that leaves the list (for example, archived) closes the peek. - One copy of the issue's content.
issue-detail.tsxis split intoIssueDocument(title, byline, Status/Priority chips, description) andIssueMenu(⋯: Copy link, Archive and its confirm). The page drawsDetailPagewith crumbs plus those two pieces. The peek draws a head (identifier, Open as page, ⋯, Close) over the sameIssueDocument. #3648 (merged first) is folded in: its Tasks row is part ofIssueDocumentand its Start task… is part ofIssueMenu, so both the page and the peek show them. @luke/uiListRow:onPressnow receives the click event, so a row can read ⌘. Existing callers are unaffected, since it was already wired toonClick.
Not in this PR: Space to peek and ⌥⌘B, a peek floating over the board in windows too narrow to dock it, and peeks in history or links.
Screenshots
Rendered from the real components in a Playwright harness (IssuesPage over a stubbed bridge, 1280×760, sidebar folded).
Before: pressing ACME-1 replaced the board with the issue's page.

After: the same press opens the peek, the board stays in place, and ACME-1's card is marked.

Mid-peek, about halfway through the slide-in: the board took its new width at once, the pane slides in on transform, and the toolbar's buttons glide.


Tests
New in issues-page.test.ts. Each fails without the change except the narrow-window one, which pins the fallback:
- A press on a card opens a peek: the board stays, the card is marked, no page opens, nothing is read.
- While a peek is open, ↓ and → move it from card to card without a read. Escape closes it and leaves the card focused, and a second Escape leaves Issues.
- Close puts the peek away and returns focus to its card.
- ⌘-press, ⌘Return, and Open as page open the issue's page.
- In a window with no room, a press opens the page (the fallback).
- A status picked in the peek is sent through the list, the card moves column, and the peek stays on the issue.
- Archive from the peek's ⋯ removes the card and closes the peek.
- In the List layout, a press on a row opens a peek and the row is current.
- A peek whose window narrows below that room closes, and its card gets the keyboard back (Devin's review).
- Archive's question asked in a peek goes away as soon as the peek starts sliding out, and listing another workspace opens no peek from the last one (Devin's review).
- The peek lists the tasks started from its issue and offers Start task… from its ⋯, as the issue's page does (#3648).
- An issue that a View options filter (#3667) leaves off the page closes its peek (Devin's review).
- The board's columns glide, rather than jump, as the peek opens and closes (Devin's review). The recording motion engine moved to
#testing/pane-motion, now that two suites use it.
Rewritten to the new paths because they pinned "Return/press opens the page":
- "↓ and Return open the issue reached…" is now "↓ and ⌘Return open the issue reached…"
- "on the board ↓ and ↑ move … and Return opens the card reached" now uses ⌘Return.
- "on a board wider than the window … on the way back from its issue" now uses ⌘Return.
- "View options lays the page out as the list … an issue opened from either goes back to it" now uses a ⌘-press.
- "a card let go over its own column sends nothing, and a press that does not move still opens it" now uses a ⌘-press that opens the page.
- The
openIssuehelper (used by the issue-page tests) and the "C … a c typed into … an issue's title" test now open the page with a ⌘-press.
pnpm check:affected: typecheck passed. lint, knip and discarded-effect were rerun one at a time after the parallel run ran out of memory, and all passed. Desktop, ui and web vitest suites pass.
Made with Luke