Skip to content

build(ui): migrate to React 19 and Primer React 38 - #3383

Merged
SamMorrowDrums merged 3 commits into
mainfrom
sammorrowdrums-react-19-primer-38-migration
Oct 2, 2026
Merged

SamMorrowDrums merged 3 commits into
mainfrom
sammorrowdrums-react-19-primer-38-migration

Conversation

@SamMorrowDrums

@SamMorrowDrums SamMorrowDrums commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Migrate the four MCP Apps views to React/React DOM 19.3.0, their 19.3.0 types, and Primer React 38.40.1. Replace removed styling APIs rather than adding the temporary styled-components compatibility package.

Why

Follow-up to #3370, which deferred these major upgrades for separate visual review. Based on latest main at cd50233; no issue closed.

What changed

  • Upgrade React, React DOM and their types to 19.3.0; upgrade Primer React to 38.40.1 and add the directly imported Primer primitives 11.10.0.
  • Replace every removed Box and sx/styled-system call site with native HTML/styles and CSS Modules for Markdown and nested selectors. Preserve layout scales, raw direct gap values, truncation, custom-label colors and Markdown interactions.
  • Load bundled primitive CSS and light/dark themes; use the CSS-based ThemeProvider from @primer/react/next instead of the deprecated JavaScript theme provider.
  • Replace deprecated Flash with accessible critical Banner components; augment react/jsx-runtime for the Markdown custom elements. Existing createRoot, refs and function defaults already meet React 19 requirements; no propTypes/legacy React DOM APIs were present.
  • Document the UI workflow in CONTRIBUTING.md. No changes to @modelcontextprotocol/ext-apps (1.7.5), TypeScript (5.9.3), @types/node (25.9.9), or their lock entries.

Visual review

Captured baseline and upgraded builds in Chrome with a local JSON-RPC MCP Apps host fixture, using the actual built single-file HTML. Compared all four views in light/dark themes at 720px and 360px, plus Markdown previews, metadata menus, submitted success/error states and narrow custom issue fields. No new horizontal overflow or browser errors/warnings in the exercised flows.

Expected differences: Primer 38's token colors/borders and label typography differ slightly, especially in dark mode. Error messages now use a critical Banner with an icon and accessible region instead of deprecated Flash. Layout, form data, editor behavior and submission payloads remain unchanged.

Each comparison has before on the left, after on the right; rows are labeled by view. Screenshot data is synthetic and all tool calls are mocked.

All four views — light, 720px

All four views in light mode, before and after

All four views — dark, 720px

All four views in dark mode, before and after

All four views — light, 360px

All four narrow views in light mode, before and after

All four views — dark, 360px

All four narrow views in dark mode, before and after

Markdown previews — all three form views, light and dark

Light Markdown previews, before and after

Dark Markdown previews, before and after

Error presentation — Flash to Banner

Error states in all three form views, before and after

Submitted success states — all three form views

Success states, before and after

Metadata menus and narrow custom issue fields

Label and reviewer menus, before and after

Narrow custom issue fields, before and after

Remaining risks

Draft intentionally pending human visual sign-off. Browser coverage used mocked tool responses in Chrome, not live authenticated VS Code/other MCP hosts or Firefox/Safari; host-specific rendering/focus should be checked before marking ready. The pre-existing Vite warning about a future native config loader and __dirname remains; Vite is not changed here. The UI package has no existing npm test script.

Upgrade references reviewed: React 19 upgrade guide, Primer 37/38 changelog.

MCP impact

  • No tool or API changes — UI dependencies, styles and error presentation only; Go tool schemas, resource URIs and protocol integration are unchanged.
  • Tool schema or behavior changed
  • New tool added

Prompts tested (tool changes only)

  • N/A: no tool changes. Browser fixtures exercised profile, issue create, PR create and PR edit views.

Security / limits

  • No security or limits impact — permissions, CSP and external resource policy unchanged; CSS/JS remain bundled in each HTML resource. npm audit reports zero vulnerabilities.
  • Auth / permissions considered
  • Data exposure, filtering, or token/size limits considered

Tool renaming

  • I am renaming tools as part of this PR (e.g. a part of a consolidation effort)
    • I have added the new tool aliases in deprecated_tool_aliases.go
  • I am not renaming tools as part of this PR — all names unchanged.

Note: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.

Lint & tests

  • Linted locally with ./script/lint — GOTOOLCHAIN=go1.26.8 script/lint passed with 0 issues (installed Go 1.27 is too new for the pinned linter).
  • Tested locally with ./script/test — GOTOOLCHAIN=go1.26.8 script/test passed, including the full Go race suite with the upgraded UI built.

Additional evidence:

  • cd ui && npm ci && npm run typecheck && npm run build && npm audit — passed; all four self-contained HTML resources emitted, zero vulnerabilities.
  • cd ui && npm ls --all — passed; no invalid peer dependencies.
  • GOTOOLCHAIN=go1.26.8 go test ./pkg/github -run 'TestRegisterUIResources_ReadableViaClient|TestNewMCPServer_RegistersUIResources' -v — passed without skips; all four upgraded UI resources are embedded and readable through the Go MCP server.
  • Session-local Playwright capture.mjs before/after — passed: 16 view/theme/width combinations and 12 preview screenshots per build.
  • Session-local Playwright interactions.mjs before/after — passed: all three forms in both themes, exact bold-toolbar output, list continuation/exit, preview, metadata selections, submitted title/body/reviewer/label payloads, success/error states and narrow custom fields. Upgraded inactive-tab hover and Banner region assertions also passed.
  • git diff --check — passed.
  • Live PAT-dependent e2e tests were not run. No tool/toolset definitions changed, so toolsnap/doc generation is not applicable.

Docs

  • Not needed
  • Updated (README / docs / examples) — CONTRIBUTING.md documents React 19/Primer 38 styling, build and visual-review requirements.

Replace removed Box and sx APIs with native styles and CSS Modules, load Primer CSS tokens, use the CSS-based theme provider and Banner, and scope custom-element JSX types to the React runtime.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@SamMorrowDrums
SamMorrowDrums marked this pull request as ready for review October 2, 2026 09:51
@SamMorrowDrums
SamMorrowDrums requested a review from a team as a code owner October 2, 2026 09:51
Copilot AI balanced review requested due to automatic review settings October 2, 2026 09:51

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.

Copilot review overview

🟡 Changes recommended

Native numeric gaps incorrectly collapse Primer spacing, and reviewer-label backgrounds use an invalid CSS color token.

Review effort: Balanced
Findings: 5 Medium severity

Open (5)
What changed in this PR

Migrates all four MCP Apps views to React 19 and Primer React 38 without retaining styled-components compatibility.

Changes:

  • Upgrades React, Primer, types, and lockfile dependencies.
  • Replaces Box/sx styling with native styles and CSS Modules.
  • Adopts CSS themes and accessible critical banners.
File Description
CONTRIBUTING.md Documents UI development and visual-review workflow.
ui/​package.json Upgrades React and Primer dependencies.
ui/​package-lock.json Locks the upgraded dependency graph.
ui/​src/​styles.module.css Adds Markdown and truncation styles.
ui/​src/​components/​AppProvider.tsx Loads CSS themes and the new provider.
ui/​src/​components/​FeedbackFooter.tsx Replaces Box styling.
ui/​src/​components/​MarkdownEditor.tsx Migrates editor styling and JSX types.
ui/​src/​apps/​get-me/​App.tsx Migrates profile-view styling.
ui/​src/​apps/​issue-write/​App.tsx Migrates issue form and banners.
ui/​src/​apps/​pr-write/​App.tsx Migrates PR creation UI.
ui/​src/​apps/​pr-edit/​App.tsx Migrates PR editing UI.
Files not reviewed (1)
  • ui/package-lock.json: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread ui/src/apps/get-me/App.tsx
Comment thread ui/src/apps/issue-write/App.tsx
Comment thread ui/src/apps/pr-edit/App.tsx
Comment thread ui/src/apps/pr-write/App.tsx
Comment thread ui/src/components/MarkdownEditor.tsx
Replace leftover canvas.inset theme paths with the CSS custom property in PR creation and editing. Keep the reviewed native gaps unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@SamMorrowDrums

Copy link
Copy Markdown
Collaborator Author

Review follow-up: fixed the valid reviewer-label background issue mentioned in the review overview in ad936a1. Both PR forms now use var(--bgColor-inset) rather than the invalid inline CSS value canvas.inset. Browser checks confirmed the intended backgrounds in both themes at 360px and 720px, with no horizontal overflow.

The five gap threads have been replied to and resolved: their premise that bare Box gap props were theme-scaled is incorrect for Primer 36. The newly effective small native gaps are intentionally retained following visual review; the temporary local removals were fully undone and never committed.

Validation passed: cd ui && npm ci, npm run typecheck, npm run build, npm audit (zero vulnerabilities), GOTOOLCHAIN=go1.26.8 script/lint, GOTOOLCHAIN=go1.26.8 script/test, and the targeted embedded-resource tests.

Preserve main's MCP Apps SDK v2, TypeScript 7 and Node 26 updates alongside React 19 and Primer 38. Regenerate the lockfile with npm on Node 26.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@SamMorrowDrums
SamMorrowDrums merged commit f10e4e1 into main Oct 2, 2026
19 checks passed
@SamMorrowDrums
SamMorrowDrums deleted the sammorrowdrums-react-19-primer-38-migration branch October 2, 2026 14:31
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