refactor(desktop): migrate integration tool details onto the design system

Merged
CH
5d ago
+71-104

D25 of the design-system migration (Desktop stack, base feature/desktop-d24-integration-directory, #3403).

What

The integration tool list and tool page (apps/desktop/src/renderer/integration-tool-list.tsx) are shared by Settings › Integrations, the MCP popover and a server's hover card. This PR moves them onto @luke/ui:

  • Row badge (Read-only / Destructive): the bespoke .integration-tool-badge span is now Badge. Read-only uses the neutral tone and Destructive uses danger.
  • Tool-page hints: each hint is a Badge inside its list item. Destructive uses danger; every other hint uses neutral.
  • "No description.": now Text (caption, subtle) instead of .integration-tool-silent.
  • Type and colour tokens:
    • Row title: body size and leading.
    • Row summary: caption size and leading, subtle ink.
    • Page title: section role (13/18, 600).
    • Page description: caption size, muted ink.
    • The Settings tools panel (settings.css) uses --luke-space-*, --luke-color-border, --luke-color-fill-strong and --luke-color-text instead of the legacy aliases.
  • Container layout only: .integration-tool-name > .luke-badge keeps the badge from shrinking and centres it on the title.

No caller here imported @luke/ui/compat.

Left for D79 (agent server picker): the tool page's back button only appears in the MCP popover. It uses onMouseDown + preventDefault to keep focus in the popover's filter. IconButton only forwards onPointerDown, which can't stop that focus change, so moving the button would mean changing a shared API. D79 owns that navigation.

Selectors removed (no callers left)

.integration-tool-badge, .integration-tool-badge[data-destructive], .integration-tool-hint (and its data-tone danger/quiet variants), .integration-tool-silent.

Visible changes

  • The row badge and the hints are the shared Badge: a full-radius capsule, 12/16 caption type, weight 500, tone tint. Before they were 10.5px, 4px-radius chips.
  • The open-world and closed-world hints ("Reaches outside Vercel", "Only Vercel's own data") were hairline-outlined. They are now neutral like the other non-destructive hints, because Badge has no outlined tone. Their words still say what they mean.
  • Row titles are 13px on a 20px line (were 12.5px). Every row is the same height whether or not it has a badge.
  • Row summaries are 12/16 (were 12px/1.35).

Tests

  • Existing behaviour tests still pass: integrations-page.test.ts, agent-servers.test.ts and server-card.test.ts (59 tests). They cover tool selection, expansion, arrows/Home/End/Enter/Escape and Tab stops.
  • Their locators moved from .integration-tool-badge and .integration-tool-hint to .luke-badge and .integration-tool-hints li. The silent page is now read through the body's text.
  • No new tests, because no user-visible behaviour changed.
  • pnpm check:affected exits 0.

Evidence

Captured on Linux with headless Chrome at 1280Ɨ840, animations held still, using the same method as #3403:

  • A throwaway, uncommitted copy of the page's test rendered the real IntegrationsSection in jsdom with synthetic tools.
  • That output was framed in SettingsPage markup with the built desktop stylesheet.
  • The ⌘ in the chord shows as a missing glyph only because Linux has no font for it.
LightDark
Read-only tool held: hints, markdown, parameters
Destructive tool held
A tool its server said nothing of

Not verified on a Mac

  • SF Pro rendering of the badges and rows.
  • The MCP popover and the server hover card in the real window. They share this component, but they weren't captured.
  • Scrolling and focus of the tool page in the real window. Only the jsdom tests cover these.

šŸ¤– Generated with Claude Code