This repository has been archived on 2026-07-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
codespace/docs/superpowers/plans/2026-07-02-web-frontend-init.md
2026-07-02 16:40:40 +08:00

24 KiB

Web Frontend Initialization Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking. This repository also has a stricter project rule: all code generation/refactoring must be delegated to Codex MCP unless the change is trivial documentation/config. Every Codex MCP call must include model: "kimi/kimi-k2.7-code", sandbox: "danger-full-access", and approval-policy: "on-failure".

Goal: Initialize web/ as an independent pnpm Vite + React 19 + TypeScript frontend and deliver the first runnable codespace IDE shell with a left file explorer, center Monaco editor, and bottom xterm terminal.

Architecture: The frontend is a standalone project under web/. app wires providers and routing, pages/workspace owns mock workspace data, layout components own resizable panel geometry, editor/terminal wrappers isolate third-party lifecycle code, Zustand stores only UI state, and TanStack Query is wired as infrastructure without real backend hooks.

Tech Stack: pnpm, Vite, React 19, TypeScript, React Router v7, Zustand, TanStack Query, Tailwind CSS v4, shadcn/ui-style components, Radix UI primitives, Monaco, xterm.js, react-resizable-panels, lucide-react, react-hook-form, zod.

Global Constraints

  • 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 reserved files 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.
  • Do not alter existing Go API signatures, config keys, or backend behavior.
  • Replace web/.gitkeep with the frontend project.
  • Update .gitignore for frontend build artifacts and local brainstorming artifacts.
  • Code implementation must be performed through Codex MCP using model: "kimi/kimi-k2.7-code", sandbox: "danger-full-access", and approval-policy: "on-failure".
  • If using xterm.js current packages, prefer @xterm/xterm and @xterm/addon-fit; this satisfies the xterm.js requirement while avoiding stale package names.

File Structure Map

Root files

  • Modify .gitignore: ignore .superpowers/, web/node_modules/, web/dist/, and Vite local env files.
  • Keep Go files unchanged.

Frontend project files

  • Create web/package.json: pnpm scripts and dependencies.
  • Create web/pnpm-lock.yaml: generated by pnpm install.
  • Create web/index.html: Vite entry document.
  • Create web/vite.config.ts: React + Tailwind v4 Vite plugins and @ alias.
  • Create web/tsconfig.json, web/tsconfig.app.json, web/tsconfig.node.json: TypeScript project config.
  • Create web/eslint.config.js: ESLint config from Vite React TS baseline.
  • Create web/components.json: shadcn/ui-compatible configuration.
  • Create web/src/main.tsx: React root bootstrap.
  • Create web/src/styles/index.css: Tailwind v4 import, theme variables, shell base styles, xterm CSS import if needed.
  • Create web/src/app/App.tsx: top-level app component.
  • Create web/src/app/router.tsx: React Router route definitions.
  • Create web/src/app/providers.tsx: QueryClientProvider and router provider composition.
  • Create web/src/app/AppErrorBoundary.tsx: small generic app boundary.
  • Create web/src/pages/workspace/WorkspacePage.tsx: page-level composition.
  • Create web/src/pages/workspace/mock-data.ts: mock files and helper lookup.
  • Create web/src/components/layout/WorkspaceShell.tsx: resizable shell layout.
  • Create web/src/components/editor/EditorPanel.tsx: Monaco wrapper.
  • Create web/src/components/terminal/TerminalPanel.tsx: xterm wrapper.
  • Create web/src/components/workspace/FileExplorerPanel.tsx: static file tree UI.
  • Create web/src/components/workspace/StatusBar.tsx: bottom status display.
  • Create web/src/components/ui/button.tsx: minimal shadcn-style button.
  • Create web/src/components/ui/separator.tsx: Radix separator wrapper.
  • Create web/src/components/ui/scroll-area.tsx: Radix scroll area wrapper.
  • Create web/src/hooks/use-mobile.ts: optional shadcn-compatible hook if generated by the CLI.
  • Create web/src/lib/api/client.ts: base API URL and typed fetch helper reserved for future calls.
  • Create web/src/lib/store/workspace-ui-store.ts: Zustand UI state.
  • Create web/src/lib/utils.ts: cn() helper.
  • Create web/README.md: frontend commands and scope.

Task 1: Scaffold the pnpm Vite React TypeScript project

Files:

  • Delete: web/.gitkeep
  • Create: web/package.json
  • Create: web/index.html
  • Create: web/vite.config.ts
  • Create: web/tsconfig.json
  • Create: web/tsconfig.app.json
  • Create: web/tsconfig.node.json
  • Create: web/eslint.config.js
  • Create: web/src/main.tsx
  • Create: web/src/styles/index.css
  • Modify: .gitignore

Interfaces:

  • Produces scripts: pnpm dev, pnpm lint, pnpm build, pnpm preview.

  • Produces alias: @/* maps to web/src/*.

  • Produces CSS entry: src/styles/index.css imported by src/main.tsx.

  • Step 1: Verify starting state

Run:

git status --short
find web -maxdepth 2 -type f -print | sort

Expected:

web/.gitkeep

git status --short may show the committed plan only if this plan has not been committed. There must be no existing frontend project files in web/.

  • Step 2: Run Codex to scaffold the frontend project

Call Codex MCP with these exact parameters:

{
  "model": "kimi/kimi-k2.7-code",
  "sandbox": "danger-full-access",
  "approval-policy": "on-failure",
  "cwd": "/Users/taochen/llm/codespace/.claude/worktrees/feat+web",
  "prompt": "## Context\n- Repository: Go backend with empty web/.gitkeep.\n- Design spec: docs/superpowers/specs/2026-07-02-web-frontend-init-design.md.\n- Plan: docs/superpowers/plans/2026-07-02-web-frontend-init.md.\n- Tech Stack: pnpm, Vite, React 19, TypeScript, Tailwind CSS v4.\n\n## Task\nScaffold web/ as a standalone Vite React TypeScript project.\nSteps:\n1. Remove web/.gitkeep.\n2. Create the Vite React TS project files directly under web/.\n3. Use React 19 and React DOM 19.\n4. Add Tailwind CSS v4 via @tailwindcss/vite.\n5. Configure @ alias to web/src.\n6. Import src/styles/index.css from src/main.tsx.\n7. Update .gitignore to ignore .superpowers/, web/node_modules/, web/dist/, and web/.env*.local.\n\n## Constraints\n- Do not modify Go backend files.\n- Do not add react-i18next.\n- Do not add test frameworks.\n- Keep the initial app minimal; later tasks build the IDE shell.\n- No new root package.json. web/ is the only Node project.\n\n## Acceptance\n- cd web && pnpm install succeeds.\n- cd web && pnpm lint succeeds.\n- cd web && pnpm build succeeds.\n- go test ./... still succeeds from repository root."
}
  • Step 3: Install dependencies

Run:

cd web && pnpm install

Expected: pnpm-lock.yaml is created and install exits with status 0.

  • Step 4: Validate scaffold

Run:

cd web && pnpm lint
cd web && pnpm build
go test ./...

Expected:

pnpm lint exits 0
pnpm build exits 0
go test ./... exits 0
  • Step 5: Commit scaffold

Run:

git status --short
git add .gitignore web
git commit -m "feat: scaffold web frontend" -m "Co-Authored-By: Claude <noreply@anthropic.com>"

Expected: one commit containing only frontend scaffold files and .gitignore changes.


Task 2: Add frontend dependencies and shadcn-style UI foundation

Files:

  • Modify: web/package.json
  • Modify: web/pnpm-lock.yaml
  • Create: web/components.json
  • Modify: web/src/styles/index.css
  • Create: web/src/lib/utils.ts
  • Create: web/src/components/ui/button.tsx
  • Create: web/src/components/ui/separator.tsx
  • Create: web/src/components/ui/scroll-area.tsx

Interfaces:

  • Produces cn(...inputs: ClassValue[]): string from @/lib/utils.

  • Produces Button, buttonVariants from @/components/ui/button.

  • Produces Separator from @/components/ui/separator.

  • Produces ScrollArea, ScrollBar from @/components/ui/scroll-area.

  • Step 1: Run Codex to add dependencies and UI foundation

Call Codex MCP with these exact parameters:

{
  "model": "kimi/kimi-k2.7-code",
  "sandbox": "danger-full-access",
  "approval-policy": "on-failure",
  "cwd": "/Users/taochen/llm/codespace/.claude/worktrees/feat+web",
  "prompt": "## Context\n- web/ is a Vite React 19 TypeScript project from Task 1.\n- Design requires React Router v7, Zustand, TanStack Query, shadcn/ui-style primitives, Monaco, xterm.js, resizable panels, lucide-react, react-hook-form, zod.\n\n## Task\nAdd runtime dependencies and minimal shadcn/ui-compatible foundation.\nSteps:\n1. Add dependencies: react-router, zustand, @tanstack/react-query, @monaco-editor/react, @xterm/xterm, @xterm/addon-fit, react-resizable-panels, lucide-react, react-hook-form, zod, @hookform/resolvers, class-variance-authority, clsx, tailwind-merge, @radix-ui/react-separator, @radix-ui/react-scroll-area.\n2. Create components.json with style new-york, rsc false, tsx true, Tailwind CSS path src/styles/index.css, baseColor neutral, cssVariables true, iconLibrary lucide, and aliases components/utils/ui/lib/hooks.\n3. Create src/lib/utils.ts exporting cn().\n4. Create minimal shadcn-style button, separator, and scroll-area components.\n5. Ensure src/styles/index.css has Tailwind v4 import, CSS variables for dark IDE shell, and base body/root sizing.\n\n## Constraints\n- Do not add react-i18next.\n- Do not add a test framework.\n- Do not bulk-add shadcn components beyond button, separator, scroll-area.\n- Keep component APIs conventional for shadcn so future CLI-generated components fit.\n\n## Acceptance\n- cd web && pnpm install succeeds if package.json changed.\n- cd web && pnpm lint succeeds.\n- cd web && pnpm build succeeds."
}
  • Step 2: Validate dependency foundation

Run:

cd web && pnpm install
cd web && pnpm lint
cd web && pnpm build

Expected: all commands exit 0.

  • Step 3: Inspect dependency scope

Run:

cd web && pnpm list --depth 0

Expected: the output includes the libraries listed in Step 1 and does not include react-i18next.

  • Step 4: Commit UI foundation

Run:

git status --short
git add web/package.json web/pnpm-lock.yaml web/components.json web/src/styles/index.css web/src/lib/utils.ts web/src/components/ui
git commit -m "feat: add web ui foundation" -m "Co-Authored-By: Claude <noreply@anthropic.com>"

Expected: one commit containing dependency, Tailwind, shadcn-compatible UI, and utility changes.


Task 3: Wire app providers, router, mock data, and UI store

Files:

  • Modify: web/src/main.tsx
  • Create: web/src/app/App.tsx
  • Create: web/src/app/AppErrorBoundary.tsx
  • Create: web/src/app/providers.tsx
  • Create: web/src/app/router.tsx
  • Create: web/src/pages/workspace/WorkspacePage.tsx
  • Create: web/src/pages/workspace/mock-data.ts
  • Create: web/src/lib/api/client.ts
  • Create: web/src/lib/store/workspace-ui-store.ts

Interfaces:

  • Produces App(): JSX.Element.

  • Produces AppProviders(): JSX.Element.

  • Produces router from @/app/router.

  • Produces type MockFileNode with fields name, path, kind, optional language, optional content, optional children.

  • Produces mockWorkspaceFiles: MockFileNode[].

  • Produces findFileByPath(files: MockFileNode[], path: string): MockFileNode | undefined.

  • Produces useWorkspaceUiStore with activeFilePath, terminalVisible, sidebarCollapsed, setActiveFilePath, toggleTerminal, and toggleSidebar.

  • Produces apiClient(path: string, init?: RequestInit): Promise<Response> for future backend calls; it must not be used for real calls in this task.

  • Step 1: Run Codex to add app infrastructure

Call Codex MCP with these exact parameters:

{
  "model": "kimi/kimi-k2.7-code",
  "sandbox": "danger-full-access",
  "approval-policy": "on-failure",
  "cwd": "/Users/taochen/llm/codespace/.claude/worktrees/feat+web",
  "prompt": "## Context\n- web/ has Vite React TS, Tailwind v4, shadcn-style UI primitives, and dependencies installed.\n- The design requires app/providers/router separation, mock workspace data, Zustand UI state, and TanStack Query infrastructure only.\n\n## Task\nCreate app infrastructure without implementing the full IDE shell yet.\nSteps:\n1. Create AppErrorBoundary as a small class error boundary rendering a dark fallback panel.\n2. Create providers.tsx with a QueryClient and RouterProvider.\n3. Create router.tsx with a single route `/` rendering WorkspacePage.\n4. Create App.tsx returning AppProviders.\n5. Update main.tsx to render App inside React.StrictMode and import styles.\n6. Create WorkspacePage with a simple semantic shell that displays the page title and confirms the mock active file path.\n7. Create mock-data.ts with a small nested file tree and findFileByPath(). Include at least package.json, src/main.tsx, internal/api/router.go, and README.md as mock files.\n8. Create workspace-ui-store.ts using Zustand with activeFilePath defaulting to src/main.tsx, terminalVisible true, sidebarCollapsed false, and the required actions.\n9. Create lib/api/client.ts with a VITE_API_BASE_URL fallback of empty string and apiClient() returning fetch(`${baseUrl}${path}`, init).\n\n## Constraints\n- Do not call the real backend.\n- Do not add API query hooks.\n- Do not implement Monaco or xterm in this task.\n- Keep UI state separate from mock server data.\n\n## Acceptance\n- cd web && pnpm lint succeeds.\n- cd web && pnpm build succeeds.\n- Running the app renders the WorkspacePage without runtime import errors."
}
  • Step 2: Validate app infrastructure

Run:

cd web && pnpm lint
cd web && pnpm build

Expected: both commands exit 0.

  • Step 3: Commit app infrastructure

Run:

git status --short
git add web/src/main.tsx web/src/app web/src/pages/workspace web/src/lib/api web/src/lib/store
git commit -m "feat: wire web app infrastructure" -m "Co-Authored-By: Claude <noreply@anthropic.com>"

Expected: one commit containing app wiring, mock data, API reserved file, and store.


Task 4: Build the resizable workspace shell with file explorer and status bar

Files:

  • Modify: web/src/pages/workspace/WorkspacePage.tsx
  • Create: web/src/components/layout/WorkspaceShell.tsx
  • Create: web/src/components/workspace/FileExplorerPanel.tsx
  • Create: web/src/components/workspace/StatusBar.tsx

Interfaces:

  • Consumes MockFileNode, mockWorkspaceFiles, and findFileByPath() from @/pages/workspace/mock-data.

  • Consumes useWorkspaceUiStore from @/lib/store/workspace-ui-store.

  • Produces WorkspaceShell({ files }: { files: MockFileNode[] }): JSX.Element.

  • Produces FileExplorerPanel({ files }: { files: MockFileNode[] }): JSX.Element.

  • Produces StatusBar({ activeFilePath }: { activeFilePath: string }): JSX.Element.

  • Step 1: Run Codex to implement shell layout

Call Codex MCP with these exact parameters:

{
  "model": "kimi/kimi-k2.7-code",
  "sandbox": "danger-full-access",
  "approval-policy": "on-failure",
  "cwd": "/Users/taochen/llm/codespace/.claude/worktrees/feat+web",
  "prompt": "## Context\n- App infrastructure and mock data exist from Task 3.\n- Layout choice is A: left file explorer, center editor area, bottom terminal area.\n- Editor and terminal are not implemented yet; use local visual panels in this task that will be replaced by Task 5.\n\n## Task\nBuild the resizable workspace shell with file explorer and status bar.\nSteps:\n1. Create WorkspaceShell using react-resizable-panels. Use a horizontal group: left file explorer panel, right main panel. Use a nested vertical group inside the right main panel: editor region above terminal region.\n2. Create FileExplorerPanel that renders the nested MockFileNode tree, highlights the active file, and calls setActiveFilePath(path) when a file is selected. Directories are display-only in this task.\n3. Create StatusBar showing active file path, mock workspace name `codespace`, and terminal visibility.\n4. Update WorkspacePage to render WorkspaceShell with mockWorkspaceFiles.\n5. Add simple header controls using existing Button and lucide-react icons: collapse sidebar and toggle terminal.\n\n## Constraints\n- Do not implement Monaco or xterm yet.\n- Do not call backend APIs.\n- Keep panel state in Zustand.\n- Keep layout readable; avoid nested conditional rendering deeper than necessary.\n\n## Acceptance\n- The page visually has left explorer, main editor region, bottom terminal region, and status bar.\n- Selecting a mock file updates active file state and status bar.\n- cd web && pnpm lint succeeds.\n- cd web && pnpm build succeeds."
}
  • Step 2: Validate shell layout

Run:

cd web && pnpm lint
cd web && pnpm build

Expected: both commands exit 0.

  • Step 3: Commit shell layout

Run:

git status --short
git add web/src/pages/workspace/WorkspacePage.tsx web/src/components/layout web/src/components/workspace
git commit -m "feat: add resizable workspace shell" -m "Co-Authored-By: Claude <noreply@anthropic.com>"

Expected: one commit containing layout, explorer, and status UI.


Task 5: Add Monaco editor and xterm terminal wrappers

Files:

  • Modify: web/src/components/layout/WorkspaceShell.tsx
  • Create: web/src/components/editor/EditorPanel.tsx
  • Create: web/src/components/terminal/TerminalPanel.tsx
  • Modify: web/src/styles/index.css

Interfaces:

  • Consumes MockFileNode from @/pages/workspace/mock-data.

  • Produces EditorPanel({ file }: { file?: MockFileNode }): JSX.Element.

  • Produces TerminalPanel(): JSX.Element.

  • WorkspaceShell must pass the active file node into EditorPanel and render TerminalPanel only when terminalVisible is true.

  • Step 1: Run Codex to add Monaco and xterm wrappers

Call Codex MCP with these exact parameters:

{
  "model": "kimi/kimi-k2.7-code",
  "sandbox": "danger-full-access",
  "approval-policy": "on-failure",
  "cwd": "/Users/taochen/llm/codespace/.claude/worktrees/feat+web",
  "prompt": "## Context\n- WorkspaceShell exists with visual editor and terminal regions from Task 4.\n- Dependencies include @monaco-editor/react, @xterm/xterm, and @xterm/addon-fit.\n\n## Task\nReplace visual regions with isolated Monaco and xterm wrappers.\nSteps:\n1. Create EditorPanel.tsx using @monaco-editor/react. It receives file?: MockFileNode. If no file or file.kind is not `file`, render a simple empty-state panel. If Monaco reports onValidate markers, keep the data local and do not add global state. Use theme `vs-dark`, automatic layout, readOnly false, minimap disabled, and language from file.language with fallback `typescript`.\n2. Create TerminalPanel.tsx using @xterm/xterm and @xterm/addon-fit. Initialize once in useEffect, write a welcome banner and mock command output, fit on mount and window resize, and dispose terminal/addon/listener on unmount. If initialization throws, render a fallback panel saying terminal failed to initialize.\n3. Import xterm CSS from @xterm/xterm/css/xterm.css in styles or the terminal component, choosing the approach that keeps bundling clean.\n4. Update WorkspaceShell to find the active MockFileNode by path and pass it to EditorPanel. Render TerminalPanel in the bottom panel only when terminalVisible is true.\n\n## Constraints\n- Do not connect to real processes.\n- Do not write terminal output to Zustand.\n- Do not call backend APIs.\n- Do not make editor content persistent.\n- Keep wrappers responsible for third-party lifecycle only.\n\n## Acceptance\n- Monaco renders the active mock file content.\n- xterm renders a banner and mock command output.\n- Toggling terminal hides/shows the terminal panel without runtime errors.\n- cd web && pnpm lint succeeds.\n- cd web && pnpm build succeeds."
}
  • Step 2: Validate editor and terminal wrappers

Run:

cd web && pnpm lint
cd web && pnpm build

Expected: both commands exit 0.

  • Step 3: Commit editor and terminal wrappers

Run:

git status --short
git add web/src/components/layout/WorkspaceShell.tsx web/src/components/editor web/src/components/terminal web/src/styles/index.css
git commit -m "feat: add web editor and terminal panels" -m "Co-Authored-By: Claude <noreply@anthropic.com>"

Expected: one commit containing Monaco/xterm wrappers and shell integration.


Task 6: Add frontend README and run final verification

Files:

  • Create: web/README.md
  • Optionally modify: README.md only if adding a short pointer to web/README.md; do not rewrite backend docs.

Interfaces:

  • Produces documented commands: pnpm install, pnpm dev, pnpm lint, pnpm build.

  • Documents initial scope: IDE shell only, no backend API integration, no i18n.

  • Step 1: Run Codex to add concise frontend docs

Call Codex MCP with these exact parameters:

{
  "model": "kimi/kimi-k2.7-code",
  "sandbox": "danger-full-access",
  "approval-policy": "on-failure",
  "cwd": "/Users/taochen/llm/codespace/.claude/worktrees/feat+web",
  "prompt": "## Context\n- web/ is now a runnable frontend project with a mock IDE shell.\n- Root README documents the Go backend.\n\n## Task\nAdd concise frontend documentation.\nSteps:\n1. Create web/README.md with purpose, scope, commands, and non-goals.\n2. If useful, add a short root README pointer to web/README.md without changing existing backend instructions.\n\n## Constraints\n- Do not claim backend API integration exists.\n- Do not mention i18n as implemented.\n- Keep docs short and factual.\n\n## Acceptance\n- web/README.md explains how to run and build the frontend.\n- cd web && pnpm lint succeeds.\n- cd web && pnpm build succeeds.\n- go test ./... succeeds."
}
  • Step 2: Run final verification

Run:

cd web && pnpm lint
cd web && pnpm build
go test ./...
git status --short

Expected:

pnpm lint exits 0
pnpm build exits 0
go test ./... exits 0
git status --short shows only intended documentation changes before the final commit
  • Step 3: Commit docs and final cleanup

Run:

git status --short
git add web/README.md README.md
git commit -m "docs: add web frontend usage" -m "Co-Authored-By: Claude <noreply@anthropic.com>"

If README.md was not modified, run:

git add web/README.md
git commit -m "docs: add web frontend usage" -m "Co-Authored-By: Claude <noreply@anthropic.com>"

Expected: one documentation commit.

  • Step 4: Summarize implementation state

Run:

git log --oneline --decorate -6
git status --short

Expected: recent commits include the spec, scaffold, UI foundation, app infrastructure, shell layout, editor/terminal panels, and docs. Working tree should be clean.


Self-Review Notes

Spec coverage

  • Standalone web/ project: Task 1.
  • pnpm: Task 1 and all validation commands.
  • Vite + React 19 + TypeScript: Task 1.
  • Tailwind CSS v4 + shadcn/ui style: Task 2.
  • React Router v7: Task 3.
  • Zustand UI state: Task 3.
  • TanStack Query provider only: Task 3.
  • Layout A: Task 4.
  • Monaco wrapper: Task 5.
  • xterm wrapper: Task 5.
  • react-resizable-panels: Task 4.
  • lucide-react controls: Task 4.
  • react-hook-form + zod dependencies: Task 2.
  • No i18n: Global constraints and Task 2 dependency check.
  • No backend API integration: Global constraints and Tasks 3-5.
  • Validation: every task has lint/build checks; Task 1 and Task 6 include Go backend tests.

Type consistency

  • MockFileNode is produced in Task 3 and consumed in Tasks 4-5.
  • useWorkspaceUiStore fields match the design: activeFilePath, terminalVisible, sidebarCollapsed, setActiveFilePath, toggleTerminal, toggleSidebar.
  • WorkspaceShell, FileExplorerPanel, StatusBar, EditorPanel, and TerminalPanel signatures are defined before downstream use.

Scope check

This plan is one coherent implementation unit: a runnable frontend shell. It does not include backend integration, WebSockets, auth, Git, LSP, Docker, or i18n.