docs: add web frontend init design

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tao.chen
2026-07-02 16:33:59 +08:00
co-authored by Claude
parent 8f2f3cf271
commit 53e402e7cb
@@ -0,0 +1,216 @@
# 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:
```txt
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:
- `app` wires router and providers only.
- `pages/workspace` composes the workspace page and owns temporary mock data.
- `components/layout` owns panel geometry.
- `components/editor` wraps `@monaco-editor/react`.
- `components/terminal` wraps `xterm.js` and `xterm-addon-fit`.
- `components/workspace` contains file explorer and status UI.
- `lib/store` contains Zustand UI state only.
- `lib/api` is reserved for future TanStack Query-backed API work.
## Component Design
Initial route renders `WorkspacePage`, which renders `WorkspaceShell`.
```txt
WorkspaceShell
├─ Header / lightweight activity area
├─ ResizablePanelGroup horizontal
│ ├─ FileExplorerPanel
│ └─ ResizablePanelGroup vertical
│ ├─ EditorPanel
│ └─ TerminalPanel
└─ StatusBar
```
Responsibilities:
- `FileExplorerPanel` displays a static mock file tree and lets the user choose an active file path.
- `EditorPanel` renders Monaco with sample content for the active file.
- `TerminalPanel` renders xterm with a welcome message and mock command output.
- `WorkspaceShell` manages layout composition, not editor or terminal internals.
- `StatusBar` shows basic mock workspace/editor state.
## State and Data Flow
Use Zustand for UI state:
- `activeFilePath`
- `terminalVisible`
- `sidebarCollapsed`
- `setActiveFilePath(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 `tailwindcss` and `@tailwindcss/vite`.
- Configure `vite.config.ts` with `tailwindcss()` and `react()` plugins.
- Use `@import "tailwindcss";` in the main CSS file.
Use shadcn/ui with:
- style: `new-york`
- `tsx: true`
- `rsc: 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:
- `react`
- `react-dom`
- `react-router`
- `zustand`
- `@tanstack/react-query`
- `@monaco-editor/react`
- `xterm`
- `xterm-addon-fit`
- `react-resizable-panels`
- `lucide-react`
- `react-hook-form`
- `zod`
- `@hookform/resolvers`
- shadcn support packages such as `class-variance-authority`, `clsx`, and `tailwind-merge`
Expected dev dependencies:
- `vite`
- `typescript`
- `@vitejs/plugin-react`
- `tailwindcss`
- `@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/.gitkeep` with a real frontend project.
- Add `web/package.json`, `pnpm-lock.yaml`, Vite/TypeScript config, source files, and shadcn/Tailwind config files.
- Update `.gitignore` for frontend build artifacts and local brainstorming artifacts if needed.
No Go API signatures, config keys, or backend tests should change.
## Validation
Implementation should verify:
```sh
cd web
pnpm install
pnpm lint
pnpm build
```
Repository baseline should continue to pass:
```sh
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.