Skip to content

sessions: add rich GitHub reference previews - #335583

Draft
Cherry Wang (chryw) wants to merge 9 commits into
mainfrom
dev/cherwan/agents/popup-layout-design-issue-metadata
Draft

sessions: add rich GitHub reference previews#335583
Cherry Wang (chryw) wants to merge 9 commits into
mainfrom
dev/cherwan/agents/popup-layout-design-issue-metadata

Conversation

@chryw

@chryw Cherry Wang (chryw) commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Exploratory follow-up to #335448, building on the first-level title work from #335387.

This proposal adds a compact issue/PR preview to Agents Window reference pills so users can identify a GitHub object and decide whether to open it without leaving their current context.

Design rationale

  • Progressive disclosure: collections keep the existing scannable list; focusing a row reveals detail. A single reference shows the same detail directly.
  • Source-product hierarchy: GitHub's own hover cards inform the order of information, while VS Code continues to own typography, color, spacing, popup chrome, focus, and keyboard behavior. Collection rows lead with the lifecycle icon, followed by the canonical title and a muted trailing ID.
  • Bounded transient content: the card provides identity and enough context to make a decision, rather than becoming a full issue reader.
  • Consistent information budget: standalone and collection cards contain the same information; only their outer density differs.

The resulting card order is repository/date → title/ID → lifecycle state → bounded description → PR branches → author. Lifecycle state uses a compact native pill: neutral text and surface treatment keep it secondary, while the icon carries the restrained state color.

Descriptions are normalized from Markdown and bounded to 200 Unicode code points. Visible titles are bounded to 80 Unicode code points. The final visible title word and linked ID are grouped so the number cannot interrupt the sentence or become clipped at narrow widths.

#335448 also explores a full Markdown reader across broader GitHub-reference surfaces; this iteration focuses on the compact pill-hover treatment.

What inspired the design

  • GitHub hover cards: provenance first, title and ID as the lead, state next, then context, routing details, and authorship/viewer context.
  • GitLab and GitHub PR experiences: emphasize identity, state, and short context before secondary metadata.
  • Linear/Slack unfurls: keep transient previews concise and action-oriented instead of reproducing the full work item.
  • JetBrains and VS Code GitHub PR lists: reserve updated time, checks, review state, and dense metadata for persistent triage surfaces.
  • Existing VS Code patterns: reuse the issue/PR hover components, ActionList list/dialog semantics, SessionSummaryHover hierarchy, branch pills, popup chrome, focus indicators, and spacing tokens.

Those examples drove the current boundary: enough content to understand and route the reference, with labels, reactions, comments, assignees, checks, and full Markdown left to richer or persistent surfaces.

Collection item interactions

Pull request collection

github-hover-collection-pr.mp4

Starts on the focused Pull Requests parent pill, opens the first-level list, moves across PR states, then traverses Copy URL, repository, ID, base/head branches, reverse Tab, and Arrow navigation from the card.

Issue collection

github-hover-collection-issue.mp4

Starts on the focused Issues parent pill, opens the first-level list, covers long-title/closed/open rows, then traverses Copy URL, repository, ID, reverse Tab, and Arrow navigation from the card.

Single-reference interactions

A single reference skips the list but keeps the same information budget.

Single pull request

github-hover-single-pr.mp4

Uses Shift+Tab and ArrowRight to focus the direct PR chip, then opens its hover and moves through repository, linked ID, and base/head branch controls.

Single issue

github-hover-single-issue.mp4

Uses Shift+Tab and ArrowRight to focus the direct issue chip, then opens its hover and moves through repository and linked ID.

Keyboard and screen-reader behavior

  • Collections: Shift+Tab from the chat input focuses the first pill; Left/Right moves between pills.
  • Collections: Enter/Space opens the list, Up/Down moves through rows, and the metadata card follows the focused item.
  • Collections: Tab moves through Copy URL, repository, resource ID, and PR branch controls; Shift+Tab returns to Copy URL.
  • Single references: Enter/Space activates the reference directly; pointer hover exposes the same detail content and its links/branch controls.
  • The listbox retains keyboard focus while the named detail dialog remains available in screen-reader reading order.
  • Rows announce the full resource title. The detail card reads provenance → title/ID → state → description → branches → author.
  • Focusing a bounded title's ID reveals the full canonical title; blur restores the compact title.

Implementation

  • reuses ChatDropdownPillActionViewItem, ActionListWidget, createIssueHoverElement, and createPullRequestHoverElement
  • keeps standalone and collection content identical
  • makes ActionList and managed-hover padding ownership explicit instead of using compensating offsets
  • uses standard ActionWidget border, radius, background, shadow, and spacing tokens
  • uses measured panel dimensions for viewport positioning

Validation

  • npm run compile
  • npm run typecheck-client
  • targeted ESLint and stylelint
  • focused ChatPills + Sessions toolbar tests: 25 passing
  • dark/light and keyboard-focus fixtures
  • standalone issue and PR paths
  • live Open, Draft, Closed, Merged, Completed, and Not planned resources
  • 567-character title and 300px-width stress cases
  • linked ID remains fully visible and focusing it does not scroll clipped content

Related

Reuse the existing issue and pull request hover components for dropdown details, with compact metadata, explicit spacing ownership, and bounded readable descriptions. Integrate the pill, row action, detail link, and branch-copy controls into one accessible keyboard flow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings September 10, 2026 22:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Several moderate review findings remain around focus behavior, event propagation, and regression coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This pull request adds rich GitHub issue and pull-request previews to Sessions pills, with keyboard-accessible detail cards.

Changes:

  • Adds lifecycle metadata, descriptions, links, and branch-copy controls.
  • Integrates ActionList focus traversal and padding ownership.
  • Adds styling, tests, accessibility guidance, and fixtures.
File summaries
File Description
src/vs/workbench/test/browser/componentFixtures/sessions/githubReferenceHoverLayouts.fixture.ts Adds themed GitHub hover layout fixtures.
src/vs/workbench/contrib/chat/browser/chatInputPills.ts Exposes chat pill focus behavior.
src/vs/workbench/browser/chatPills.ts Supports enriched entries and first-pill focusing.
src/vs/sessions/contrib/github/common/types.ts Extends GitHub models with closure metadata.
src/vs/sessions/contrib/github/browser/pullRequestHover.ts Renders PR details and branch-copy controls.
src/vs/sessions/contrib/github/browser/media/pullRequestHover.css Styles PR cards and branch pills.
src/vs/sessions/contrib/github/browser/media/issueHover.css Styles issue cards.
src/vs/sessions/contrib/github/browser/issueHover.ts Renders issue preview cards.
src/vs/sessions/contrib/github/browser/githubHover.ts Normalizes and bounds descriptions.
src/vs/sessions/contrib/github/browser/fetchers/githubPRFetcher.ts Maps GitHub closure dates.
src/vs/sessions/contrib/chat/test/browser/sessionChatInputToolbar.test.ts Tests rich preview behavior and controls.
src/vs/sessions/contrib/chat/browser/sessionsChatAccessibilityHelp.ts Documents pill keyboard navigation.
src/vs/sessions/contrib/chat/browser/sessionChatInputToolbar.ts Builds rich GitHub pill entries.
src/vs/sessions/contrib/chat/browser/chatView.ts Routes Shift+Tab to visible pills.
src/vs/platform/actionWidget/test/browser/actionList.test.ts Tests panel keyboard navigation.
src/vs/platform/actionWidget/browser/actionWidget.css Styles content-owned panel padding.
src/vs/platform/actionWidget/browser/actionList.ts Adds panel focus and padding contracts.
Review details

Suppressed comments (5)

src/vs/platform/actionWidget/browser/actionList.ts:2286

  • When a row has both Copy URL and Remove (multi-entry pull-request pills append removeAction after toolbarActions), this always focuses the last toolbar action. Shift+Tab from the detail card therefore lands on Remove instead of Copy URL, contradicting the documented focus order. Please define the intended return action for this traversal (or reorder/exclude the removal action) and cover the multi-action case.
			if (inPanel) {
				if (controls.toolbar?.length()) {
					dom.EventHelper.stop(event, true);
					controls.toolbar.focus(controls.toolbar.length() - 1);

src/vs/sessions/contrib/chat/browser/chatView.ts:351

  • This handler routes only Shift+Tab from the chat input into the pills, but the existing sessionsChat.inputPills accessibility-help entry still tells users to press Tab to reach the pills above the input. Normal Tab is not intercepted here, so that instruction does not reach the intended control; update the help text to match this Shift+Tab behavior.
			if (event.keyCode === KeyCode.Tab && event.shiftKey && !event.ctrlKey && !event.metaKey && !event.altKey && this._chatPills.focusFirst()) {

src/vs/sessions/contrib/chat/browser/chatView.ts:354

  • This adds a new global Shift+Tab focus transition, but the Sessions ChatView tests do not dispatch this handler. A regression in the modifier filtering, focusFirst() result, or cancellation behavior could silently break keyboard access to the status pills; add a focused test for the matching and non-matching paths.
		this._register(this._widget.inputEditor.onKeyDown(event => {
			if (event.keyCode === KeyCode.Tab && event.shiftKey && !event.ctrlKey && !event.metaKey && !event.altKey && this._chatPills.focusFirst()) {
				event.preventDefault();
				event.stopPropagation();
			}

src/vs/sessions/contrib/github/browser/fetchers/githubPRFetcher.ts:352

  • The new closedAt mapping drives the card's closed-PR transition date, but the fetcher tests never include closed_at in makePRResponse or assert pr.data?.closedAt. A regression in this wire-to-domain mapping would therefore leave the UI showing the updated date while all current tests still pass; add a response fixture and assertion for the closed timestamp.
		...(data.closed_at ? { closedAt: data.closed_at } : {}),

src/vs/sessions/contrib/github/browser/pullRequestHover.ts:143

  • Activating either branch button bubbles a click to the ActionList root. Unlike the link handler above, this callback does not stop propagation, so List.onViewPointer sees a click outside a row and clears the focused row. After copying a branch, Up/Down and the panel Tab sequence lose their list context; stop propagation before invoking the copy callback.
	branch.onclick = onDidClick;
  • Files reviewed: 17/17 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

const branchRow = append(hoverElement, $('.sessions-pr-hover-branches'));
appendBranchPill(branchRow, data.pullRequest.baseRef || localize('agentSessions.pullRequestHover.baseFallback', "target"));
const baseBranch = appendBranchPill(branchRow, data.pullRequest.baseRef || localize('agentSessions.pullRequestHover.baseFallback', "target"), 'base', data.onDidClickBaseBranch);
append(branchRow, $('span.sessions-pr-hover-branch-arrow', undefined, '\u2190'));
const { container } = context;
container.style.padding = '24px';
container.style.backgroundColor = 'var(--vscode-sideBar-background)';
content.classList.add('action-list-submenu-hover-header');
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Screenshot Changes

Base: d20c17c0 Current: 154b552f

6 insignificant change(s) omitted (≤20 px, Δ≤2). See CI logs for details.

Added (12)

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_Issue/Dark

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_Issue/Light

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_PullRequest/Dark

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_PullRequest/Light

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_SingleIssue/Dark

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_SingleIssue/Light

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_SinglePullRequest/Dark

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_SinglePullRequest/Light

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_LongTitleCollectionIssue/Dark

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_LongTitleCollectionIssue/Light

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_LongTitleSingleIssue/Dark

current

sessions/githubReferenceHoverLayouts/GitHubReferenceHover_LongTitleSingleIssue/Light

current

Cherry Wang (chryw) and others added 3 commits September 10, 2026 17:06
Use existing relative-time, title, spacing, and popup patterns consistently across standalone and collection references. Bound long titles, keep transient content concise, and make HTML hover padding ownership explicit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the existing 8px SessionSummaryHover rhythm between the title and description in both standalone and collection cards.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Let the card root own a uniform 8px gap between metadata, title, description, and branch rows instead of splitting relationship spacing across child padding.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cherry Wang (chryw) and others added 5 commits September 10, 2026 17:57
Follow GitHub hover cards for provenance, title and ID, state, context, routing, and author order while preserving VS Code styling and the bounded transient content budget.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Group the final visible title word with the linked reference ID, bound pathological titles safely, and allow narrow cards to wrap without clipping focusable content.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use measured submenu height for positioning and reveal the full bounded GitHub title when keyboard focus reaches its linked reference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Render shared hover actions as centered inline flex rows so codicons and text use the same vertical center.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants