feat: rewrite web UI with React + Tailwind + shadcn#44
Merged
Conversation
Replace the four hand-written HTML files with a modular React SPA built with TypeScript, Tailwind CSS v4, shadcn/ui primitives, TanStack Query, and i18next for localization (English). Key changes: - React 18 SPA with React Router v6 client-side routing - Bun-native build pipeline producing a single inlined HTML file - Collapsible tool cards with search across all MCP server tools - Hue-based color badges for servers and plugins with distinguishing icons - Plugin cards showing per-plugin skill/tool/server counts - Logo in navbar and favicon from capa-docs assets - Light/dark theme support with CSS variable tokens - Server wiring collapsed to a single handleSpa() route
Contributor
There was a problem hiding this comment.
Pull request overview
This PR replaces the legacy multi-page static HTML web UI with a bundled React + TypeScript SPA (Tailwind/shadcn, TanStack Query, i18next) and updates the server to serve a single inlined index.html for /, /ui, and /ui/* (closing #38).
Changes:
- Introduces a new React SPA web UI with modular pages/components, typed API models, and i18n resources.
- Adds a Bun-native
build:webpipeline to compile Tailwind + bundle the SPA and inline assets intoweb-ui/dist/index.html. - Simplifies server-side UI routing to a single
handleSpa()response.
Reviewed changes
Copilot reviewed 56 out of 58 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| web-ui/tsconfig.json | Adds a dedicated TS config for the web UI (paths/baseUrl, TSX includes). |
| web-ui/src/types/api.ts | Defines typed client-side API response/request models used by the SPA. |
| web-ui/src/pages/ProjectsListPage.tsx | Implements the SPA projects list page (loading/error/empty/search states). |
| web-ui/src/pages/ProjectDetailPage.tsx | Implements the SPA project detail/config page (capabilities, variables, OAuth). |
| web-ui/src/pages/NotFoundPage.tsx | Adds a SPA 404 page. |
| web-ui/src/pages/IntegrationsPage.tsx | Implements the SPA integrations page (OAuth + PAT flows). |
| web-ui/src/main.tsx | SPA entrypoint wiring i18n + TanStack Query + theme init. |
| web-ui/src/locales/en/projects.json | English strings for projects pages/sections. |
| web-ui/src/locales/en/integrations.json | English strings for integrations UI. |
| web-ui/src/locales/en/common.json | Shared English strings (nav/actions/status/errors/success). |
| web-ui/src/lib/utils.ts | Shared UI helpers (classnames, escaping/highlight/search, formatting, badge hues). |
| web-ui/src/lib/theme.ts | Theme storage + application via data-theme. |
| web-ui/src/lib/queryClient.ts | Central TanStack Query client defaults. |
| web-ui/src/lib/i18n.ts | i18next initialization and locale persistence. |
| web-ui/src/lib/api.ts | Fetch wrapper + ApiError for typed API calls. |
| web-ui/src/index.html | Dev/source HTML shell for the SPA. |
| web-ui/src/index.css | Tailwind v4 + CSS variables/theme tokens and shared styles. |
| web-ui/src/features/projects/hooks.ts | React Query hooks for projects/variables/OAuth/tools queries and mutations. |
| web-ui/src/features/projects/components/VariablesForm.tsx | UI for editing/saving required environment variables. |
| web-ui/src/features/projects/components/ToolsList.tsx | Tool list UI with search/highlighting and expandable details. |
| web-ui/src/features/projects/components/tokenStats.ts | Token-estimation logic and “token savings” computation. |
| web-ui/src/features/projects/components/TokenSavingsBar.tsx | Renders token savings summary UI. |
| web-ui/src/features/projects/components/SkillsList.tsx | Skill list UI with search/highlighting. |
| web-ui/src/features/projects/components/ServerToolsPanel.tsx | Expandable per-server tool schema panel with search-driven expansion. |
| web-ui/src/features/projects/components/ServersList.tsx | Server list UI with per-server tools expansion and search. |
| web-ui/src/features/projects/components/ProjectsTable.tsx | Projects table/list row rendering for the list page. |
| web-ui/src/features/projects/components/PluginsSection.tsx | Plugin cards + contribution counts for skills/tools/servers. |
| web-ui/src/features/projects/components/OAuth2Section.tsx | OAuth connection UI for per-project servers. |
| web-ui/src/features/projects/components/CapabilitiesSection.tsx | Capabilities overview section + deep search + token savings. |
| web-ui/src/features/projects/api.ts | Projects API client (list/get/variables/oauth/tools). |
| web-ui/src/features/integrations/hooks.ts | React Query hooks for integrations + disconnect mutation. |
| web-ui/src/features/integrations/components/GitLabSelfManagedCard.tsx | GitLab self-managed PAT connect/disconnect card UI. |
| web-ui/src/features/integrations/components/GitLabCard.tsx | GitLab OAuth connect/disconnect card UI. |
| web-ui/src/features/integrations/components/GitHubEnterpriseCard.tsx | GitHub Enterprise PAT connect/disconnect card UI. |
| web-ui/src/features/integrations/components/GitHubCard.tsx | GitHub OAuth connect/disconnect card UI. |
| web-ui/src/features/integrations/api.ts | Integrations API client (OAuth start, PAT connect, disconnect). |
| web-ui/src/components/layout/TopBar.tsx | Shared top navigation bar with logo, breadcrumbs, nav links, theme toggle. |
| web-ui/src/components/layout/ThemeToggle.tsx | Theme toggle control bound to persisted theme state. |
| web-ui/src/components/layout/Page.tsx | Shared page container/header layout component. |
| web-ui/src/components/layout/NavLinks.tsx | Nav links to integrations/docs/GitHub repo. |
| web-ui/src/components/common/StatusDot.tsx | Connection status indicator component. |
| web-ui/src/components/common/Spinner.tsx | Loading spinner component. |
| web-ui/src/components/common/ServerBadge.tsx | Hue-based badge component for servers/plugins (with highlighting support). |
| web-ui/src/components/common/SearchInput.tsx | Debounced search input with clear action. |
| web-ui/src/components/common/EmptyState.tsx | Shared empty state component. |
| web-ui/src/components/common/Alert.tsx | Shared alert component with optional auto-dismiss. |
| web-ui/src/App.tsx | SPA router configuration and route mapping. |
| web-ui/integrations.html | Removes legacy static integrations page. |
| web-ui/index.html | Removes legacy static project configuration page. |
| web-ui/home.html | Removes legacy static projects list page. |
| src/server/index.ts | Switches UI serving to a single bundled SPA HTML response (handleSpa). |
| scripts/build-web.ts | Adds build pipeline to compile Tailwind + bundle + inline SPA into one HTML file. |
| package.json | Adds build:web and runs it during prebuild; adds UI dependencies. |
| .gitignore | Ignores generated web UI build artifacts. |
| .github/workflows/test.yml | Builds the web UI before tests/typechecks; adds web UI TS typecheck. |
| .github/workflows/release.yml | Builds the web UI before the compile/release step. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…dule Consolidates six duplicate inline SVG definitions (GitHubIcon, GitLabIcon, GitLabColorIcon) into a single shared file at components/icons/BrandIcons.tsx.
- Prevent open redirect in VariablesForm by restricting returnUrl to relative paths (must start with / and not //) - URL-encode serverId in startOAuth query parameter - Remove unused imports: useQueryClient in IntegrationsPage, escapeHtml in ToolsList and ServersList - Replace hardcoded strings in NotFoundPage with i18n t() calls - Use React Router Link instead of <a> in ProjectsTable - Remove deprecated baseUrl/paths from web-ui/tsconfig.json (fixes CI lint failure with TypeScript 7.x) - Add TODO for i18n of OAuth2Section formatExpiry strings
- Guard projectId in useEffect before using it (no more non-null assertion) - Add safeDecode helper wrapping decodeURIComponent in try/catch - Use safeDecode in ProjectDetailPage and IntegrationsPage - Update disconnect flow to pass integration.host for self-managed integrations (GitHubEnterprise, GitLabSelfManaged cards) - Encode all dynamic path segments in projects API client - Clear debounce timer on unmount in SearchInput - Use getStoredTheme (pure getter) instead of initTheme in ThemeToggle
Extend the project detail API to return subagents, rules, providers, and options from the capabilities model. Add four new frontend components: - SubagentsList: collapsible cards showing agent skills, tools, and instructions - RulesList: collapsible cards with type badges, provider/glob filters, and always-apply flag - ProvidersSection: provider name badges with Cpu icon - OptionsSection: tool exposure mode, security config, and required commands table All sections are wired into the project detail page with search filtering and i18n support.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
home.html,index.html,project.html,integrations.html) with a modular React 18 SPA built with TypeScript, Tailwind CSS v4, shadcn/ui primitives, TanStack Query, and i18next (English)scripts/build-web.ts) that compiles Tailwind CSS, bundles the React app, and inlines everything into a singleindex.htmlembedded in the executablehandleSpa()method serving/,/ui, and/ui/*UI Improvements over the old frontend
capa-docs/publicCI
test.yml: addsbun run build:webbefore tests and type-checking for the web UIrelease.yml: addsbun run build:webbefore the compile stepCloses #38
Test plan
bun run build:weband verifyweb-ui/dist/index.htmlis generatedbun run buildand start the server; verify the SPA loads at/and/ui