feat(ui): migrate to Vite+ React Tailwind v4 shadcn/ui#127
feat(ui): migrate to Vite+ React Tailwind v4 shadcn/ui#127karthikmudunuri merged 11 commits intomainfrom
Conversation
Replace vanilla TypeScript/HTML/CSS SPA (tsdown + morphdom + IIFE scripts) with a modern React SPA using Vite+ toolchain, Tailwind CSS v4, and shadcn/ui component system. Migration scope: - Toolchain: tsdown → Vite+ (vite-plus) with @vitejs/plugin-react - Framework: vanilla DOM manipulation → React 19 + React Router v7 - Styling: 2,407-line styles.css → Tailwind CSS v4 (CSS-first config) - Components: raw HTML → shadcn/ui (base-nova style) + custom components - Build: IIFE scripts → ES module bundling with code splitting - Container: node:22-alpine → node:22-slim (Vite+ glibc requirement) New architecture: - src/pages/ — route-level components (chat, create, terminal) - src/components/acp/ — ACP chat UI (sidebar, messages, composer, thinking) - src/components/ui/ — shadcn/ui primitives (button, input, card, etc.) - src/lib/ — business logic (api, acp-client, config, transcripts, cache) - src/types/ — TypeScript type definitions Key features preserved: - ACP WebSocket chat with server-side bootstrap - Create form with preset system and localStorage persistence - Live spritz state polling (3s provisioning, 10s stable) - Runtime config injection via config.js + entrypoint.sh - Hash-based URL redirect for legacy links - Auth token management with refresh flow Deleted: - 9 legacy vanilla TS source files (~8,300 lines) - 13 test files (public/*.test.mjs) - morphdom, xterm vendor bundles - tsdown config, dev server, copy scripts
Add vitest setup and 102 tests covering all modules that lost test coverage during the Vite+ migration. Includes pure logic tests for acp-client, acp-transcript, acp-cache, presets, create-payload, and form-state, plus component tests for notice-banner, preset-panel, and App routing.
Replace toBeInTheDocument() with standard vitest assertions (toBeDefined/toBeNull) to avoid jest-dom type augmentation issues with vite-plus bundled vitest. Remove unused @testing-library/jest-dom dependency.
…P improvements Restore conversation title behavior from main branch (first message as title, session_info_update handling), fix slash command pill rendering, and improve ACP transcript state management for the Vite+ React migration.
Fix void-expression truthiness error in permission-dialog, update acp-client tests to handle initialize/session-load handshake, and align acp-transcript tests with thinking-chunks-based tool tracking.
Keep vanilla JS files deleted as they are replaced by the Vite+ React migration.
📋 GitRank PR AnalysisScore: 0 points (ineligible)
Eligibility Checks
Impact SummaryThis PR migrates the Spritz UI from vanilla TypeScript/HTML/CSS with tsdown bundling to a modern Vite+/React 19/Tailwind CSS v4/shadcn/ui stack. It includes 30+ new React components, new chat features (conversation titles, slash command pills, streaming/markdown/thinking blocks), redesigned create page, and harness-agnostic ACP rendering. The migration removes ~13,100 lines of legacy code and adds ~12,184 lines of new code across 93 files. Analysis DetailsComponent Classification: This PR is a comprehensive stack migration and architectural refactor affecting the entire UI layer, spanning toolchain, framework, styling, and component architecture. No single component category applies; this is a system-wide modernization classified as OTHER. Severity Justification: Classified as P1 (High) because this is a major architectural migration with significant impact on the entire UI system, introducing new dependencies, build processes, and component structures. While not a bug fix, the scope and risk of this refactor warrants high severity scoring due to potential for regressions across all UI functionality. Eligibility Notes: issue=false: This is a feature/refactor PR, not fixing a reported bug. fix_implementation=true: Code changes comprehensively implement the described stack migration and new features. pr_linked=true: PR has detailed description with architecture, design decisions, and test plan. tests=true: PR includes new test files (App.test.tsx, notice-banner.test.tsx, preset-panel.test.tsx) and removes legacy test files. tests_required=true: Major refactoring of business logic, new features, and API changes require comprehensive testing to prevent regressions. Analyzed by GitRank 🤖 |
TL;DR
Full migration of the Spritz UI from vanilla TypeScript/HTML/CSS to a modern Vite+ / React 19 / Tailwind CSS v4 / shadcn/ui stack, plus new chat features (conversation titles, slash command pills, streaming/markdown/thinking blocks), a redesigned create page, harness-agnostic ACP rendering, and API support for workspace service accounts.
Summary
Stack migration
tsdown(IIFE bundles) →vite-plus(ES modules with HMR)morphdom→ React 19 + React Router v7styles.css→ Tailwind CSS v4 (CSS-first config) + shadcn/ui components (base-nova)globals.d.ts→ Strict TS with proper module boundariesnode:22-alpine→node:22-slim(Vite+ requires glibc, not musl)New features & improvements
What's new (migration detail)
public/index.html+ 10<script>tagsindex.html+ single<script type="module">#chat/name)/chat/name) with legacy hash redirect.jsfilesindex-*.js+index-*.cssArchitecture
Key Design Decisions
Server-side ACP bootstrap:
POST /api/acp/conversations/:id/bootstraphandlesinitialize+session/load, then the browser connects toGET /api/acp/conversations/:id/connectas a raw WebSocket proxy.Runtime config injection:
config.jsloaded as a<script>tag before the app module.entrypoint.shusessedto templatewindow.SPRITZ_CONFIGfrom environment variables at container start.Live state polling: Spritz list polls at 3s during provisioning, 10s when stable, with phase-aware icons.
Legacy hash redirect:
HashRedirectcomponent intercepts#chat/nameURLs and navigates to/chat/name.Harness-agnostic rendering: Tool timeline and ACP components work across different harness implementations without coupling.
Deleted
app.ts,acp-page.ts,acp-render.ts, etc.)*.test.mjs)index.html,styles.csstsdown.config.ts,dev-server.mjs,copy-static.mjsTest Plan
pnpm buildsucceeds inui/with no TypeScript errorsdocker build -f ui/Dockerfile -t spritz-ui:latest uicompletes/create): form renders, preset selection works, spritz creation submits/chat/:name): sidebar shows agents, conversations load/connect/#chat/spritz-nameredirects to/chat/spritz-nameSPRITZ_API_BASE_URLenv var populateswindow.SPRITZ_CONFIGkind load docker-image+kubectl rollout restartpicks up new image