6.0 KiB
Web Frontend Initialization Design
Date: 2026-07-02 Branch: feat/web
Goal
Initialize web/ as an independent Vite + React 19 + TypeScript frontend project and build the first runnable codespace IDE shell: file explorer on the left, Monaco editor in the center, and xterm terminal at the bottom.
This design deliberately stops before backend integration. The current Go backend already exposes workspace, file, and process APIs, but the first frontend step should prove the UI structure and technology boundaries without mixing server data, editor state, and terminal state too early.
Decisions
- Package manager:
pnpm. - Scope: IDE shell skeleton, not a full API-connected MVP.
- Layout: VS Code-style shell with left file explorer, center editor, bottom terminal.
- Internationalization: not included in the initial scaffold.
- Backend API: provider/client placeholders only; no real API calls in the first implementation.
- Tests: use build/lint/type validation first; do not add a test framework until real business logic appears.
Architecture
web/ is a standalone frontend project. It should not modify the Go module or force the backend lifecycle to depend on Node tooling.
Proposed structure:
web/
src/
app/
App.tsx
router.tsx
providers.tsx
pages/
workspace/
WorkspacePage.tsx
mock-data.ts
components/
layout/
WorkspaceShell.tsx
editor/
EditorPanel.tsx
terminal/
TerminalPanel.tsx
workspace/
FileExplorerPanel.tsx
StatusBar.tsx
ui/
# shadcn/ui generated components
hooks/
lib/
api/
client.ts
store/
workspace-ui-store.ts
utils.ts
styles/
index.css
Boundaries:
appwires router and providers only.pages/workspacecomposes the workspace page and owns temporary mock data.components/layoutowns panel geometry.components/editorwraps@monaco-editor/react.components/terminalwrapsxterm.jsandxterm-addon-fit.components/workspacecontains file explorer and status UI.lib/storecontains Zustand UI state only.lib/apiis reserved for future TanStack Query-backed API work.
Component Design
Initial route renders WorkspacePage, which renders WorkspaceShell.
WorkspaceShell
├─ Header / lightweight activity area
├─ ResizablePanelGroup horizontal
│ ├─ FileExplorerPanel
│ └─ ResizablePanelGroup vertical
│ ├─ EditorPanel
│ └─ TerminalPanel
└─ StatusBar
Responsibilities:
FileExplorerPaneldisplays a static mock file tree and lets the user choose an active file path.EditorPanelrenders Monaco with sample content for the active file.TerminalPanelrenders xterm with a welcome message and mock command output.WorkspaceShellmanages layout composition, not editor or terminal internals.StatusBarshows basic mock workspace/editor state.
State and Data Flow
Use Zustand for UI state:
activeFilePathterminalVisiblesidebarCollapsedsetActiveFilePath(path)toggleTerminal()toggleSidebar()
Use TanStack Query only as infrastructure in this phase by installing and wiring QueryClientProvider. Do not create real query hooks yet.
Reason: UI state and server state are different data. Mixing them during scaffolding creates special cases later when real backend data arrives.
Mock file data belongs in pages/workspace/mock-data.ts. Future API integration can replace this with query hooks without rewriting Monaco, xterm, or panel layout components.
Styling and UI System
Use Tailwind CSS v4 with the Vite plugin:
- Install
tailwindcssand@tailwindcss/vite. - Configure
vite.config.tswithtailwindcss()andreact()plugins. - Use
@import "tailwindcss";in the main CSS file.
Use shadcn/ui with:
- style:
new-york tsx: truersc: false- base color:
neutral - CSS variables enabled
- aliases:
@/components@/components/ui@/lib@/hooks
Only add necessary shadcn components for the shell, such as button, separator, and scroll-area. Do not bulk-install components.
Dependencies
Expected runtime dependencies:
reactreact-domreact-routerzustand@tanstack/react-query@monaco-editor/reactxtermxterm-addon-fitreact-resizable-panelslucide-reactreact-hook-formzod@hookform/resolvers- shadcn support packages such as
class-variance-authority,clsx, andtailwind-merge
Expected dev dependencies:
vitetypescript@vitejs/plugin-reacttailwindcss@tailwindcss/vite- ESLint/TypeScript ESLint packages from the Vite React TypeScript template
Do not add react-i18next in this phase.
Error Handling
Keep error handling simple:
- If Monaco fails to load, show an editor fallback panel.
- If xterm initialization fails, show a terminal fallback panel.
- Use a small app-level error boundary only if it stays generic and does not introduce logging/reporting infrastructure.
- Do not add toast-driven retry behavior before real API calls exist.
Compatibility and Breakage
This change should not alter existing backend behavior.
Expected repository effects:
- Replace
web/.gitkeepwith a real frontend project. - Add
web/package.json,pnpm-lock.yaml, Vite/TypeScript config, source files, and shadcn/Tailwind config files. - Update
.gitignorefor frontend build artifacts and local brainstorming artifacts if needed.
No Go API signatures, config keys, or backend tests should change.
Validation
Implementation should verify:
cd web
pnpm install
pnpm lint
pnpm build
Repository baseline should continue to pass:
go test ./...
If the Vite template does not provide a test runner, do not add Vitest during this phase.
Out of Scope
- Real workspace creation/listing UI.
- File read/write API integration.
- Process start/stop/restart integration.
- WebSocket streaming.
- Authentication.
- Docker.
- Git integration.
- LSP integration.
- AI agent orchestration UI.
- Internationalization.