Imported from gencau/test-practices-agent-configurations (
dataset/repos/lablup§backend.ai-webui/AGENTS.md). Install upstream withnpx skills add gencau/test-practices-agent-configurations --skill lablup§backend.ai-webui. Copyright stays with the author.
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Essential Commands
Development
pnpm run dev- Start development environment (TypeScript watch + Relay watch + React dev server)pnpm run wsproxy- Start websocket proxy (required for local development)
Build and Production
pnpm run build- Full production build (cleansbuild/web/, copies resources, builds React via Craco with Workbox service worker generation, builds workspace packages)pnpm run build:react-only- Build only React app via Cracopnpm run relay- Compile GraphQL queries with Relay compiler
Quality Control
pnpm run lint- Run ESLint (exits with 0 to not break builds)pnpm run lint-fix- Auto-fix ESLint issuespnpm run format- Check code formatting with Prettierpnpm run format-fix- Auto-fix code formatting
Testing
pnpm run test- Run Jest tests (root:scripts/,src/)pnpm run test(in/reactdirectory) - Run React-specific Jest tests- E2E tests (
/e2e/) use Playwright; require full Backend.AI cluster running first
Electron App
pnpm run electron:d- Run Electron app in development modemake clean && make dep- Prepare dependencies for Electronmake mac/make win/make linux- Build platform-specific apps
Architecture Overview
Architecture
This is a React web application using React 19 + Ant Design 6 + Relay 20 (GraphQL).
Key Technologies
- React Build: Webpack via @craco/craco (Create React App with customizations)
- Component Library Build: Vite (
packages/backend.ai-ui/) - Service Worker: workbox-webpack-plugin (GenerateSW, integrated into Craco/Webpack build)
- Package Manager: pnpm with workspace monorepo
- Styling: Ant Design + antd-style
- State Management: Jotai (global UI state), Relay (server/GraphQL state)
- GraphQL: Relay compiler with projects for both
react/andpackages/backend.ai-ui/ - React Compiler: babel-plugin-react-compiler in annotation mode (
'use memo'directive) - Testing: Jest for unit tests, Playwright for E2E tests
- Linting: ESLint 9 (flat config) + Prettier, pre-commit hooks via Husky + lint-staged
- Electron: Desktop app wrapper with built-in websocket proxy
- Storybook: @storybook/react-vite for
backend.ai-uicomponent library
Project Structure
react/ # Main React application (Webpack/Craco)
src/ # Application source code
components/ # React UI components
pages/ # Page-level components
hooks/ # Custom React hooks
helper/ # Utility functions
__generated__/ # Relay compiler output
craco.config.cjs # Webpack customization via Craco
packages/ # Monorepo workspace packages
backend.ai-ui/ # Shared React component library (Vite build)
backend.ai-webui-docs/# User manual documentation
eslint-config-bai/ # Shared ESLint configuration
src/ # Utilities and websocket proxy
lib/ # Backend.AI client library (ESM/Node.js)
wsproxy/ # WebSocket proxy for desktop app
resources/ # Static assets, i18n files (22 languages), themes
data/ # GraphQL schema files (schema.graphql, client-directives.graphql)
e2e/ # Playwright E2E tests
electron-app/ # Electron desktop app source
configs/ # Environment-specific config files
scripts/ # Build and dev utility scripts
Build Pipeline
Production build (pnpm run build) runs these steps sequentially:
- Clean and create
build/web/output directory - Copy
index.html,resources/,manifest/, config files pnpm run -r --stream buildbuilds all workspace packages:- React app (Craco/Webpack) →
react/build/→ copied tobuild/web/ - Service worker (
sw.js) generated by workbox-webpack-plugin during React build - backend.ai-ui (Vite) →
packages/backend.ai-ui/dist/
- React app (Craco/Webpack) →
Development Workflow
- Dev Server: Run
pnpm run dev(TypeScript watch + Relay watch + React dev server) andpnpm run wsproxy(WebSocket proxy) for full development - Port Configuration: Managed by
scripts/dev-config.js(default React port: 9081) - Testing: Jest unit tests + Playwright E2E tests
- Linting: ESLint 9 (flat config) + Prettier with pre-commit hooks via Husky
Additional Workflow Description
-
All work items are created in Jira and serve as the starting point for understanding and resolving tasks.
-
Work items are cloned as GitHub issues in the corresponding repository.
-
GitHub PR titles follow this format:
- prefix
- feat: New features or feature improvements and changes
- fix: Bug fixes
- refactor: Refactoring
- style: Design changes without functional changes
- chore: Other small tasks
- Format:
prefix(JIRA-ISSUE-NUMBER): title - GitHub PR content starts with
Resolves #1234(FR-1234)where #1234 is the cloned issue number and FR-1234 is the Jira issue number
- prefix
-
Tool Requirements:
- Jira: Use
jira-workflowskill (fw plugin). Project config in.jira.config. - GitHub: Use
ghCLI (preferred) or GitHub MCP (mcp__github__*) - Git/PR: Use Graphite MCP (
mcp__graphite__run_gt_cmd) for branch/commit/push- Do NOT use
git commit,git push,git checkout -bdirectly - Allowed:
git status,git diff,git add,git log,git stash
- Do NOT use
- Jira: Use
-
Follow Graphite's Stacked PR strategy. Write work by appropriately stacking individual PRs.
-
When amending a PR with significant changes, update the PR description to reflect the new scope. Minor fixes don't need description updates, but new features, deleted files, or changed approach should be reflected.
Configuration
- Main config:
config.toml(copied fromconfig.toml.sample) - Multiple environments supported via
configs/directory - Electron app config:
build/electron-app/app/config.toml
Key Libraries
- react 19, react-dom 19 - UI framework
- antd 6 - Ant Design component library
- react-relay 20, relay-runtime 20 - GraphQL client
- jotai - Atomic state management
- i18next, react-i18next - Internationalization
- @craco/craco - CRA webpack customization
- electron 35 - Desktop app framework
GraphQL/Relay Setup
- Schema files in
/data/(schema.graphql,client-directives.graphql) - Relay compiler configured for two projects:
reactandbackend.ai-ui - Config:
/relay.config.js(extends/relay-base.config.js) - Generated types output to
react/src/__generated__/andpackages/backend.ai-ui/src/__generated__/ - Run
pnpm run relayto compile GraphQL queries - Run
pnpm run relay:watchfor watch mode during development
Internationalization
- JSON translation files in
resources/i18n/(22 languages supported) - React components use
useTranslation()hook fromreact-i18next - Backend.AI UI package has own locale files in
packages/backend.ai-ui/src/locale/ - Run
make i18nto extract translation strings
Build Output
- Production build:
build/web/(contains React build + service worker + static assets) - Electron app:
build/electron-app/(created bymake dep) - Component library:
packages/backend.ai-ui/dist/
Important Notes
- Always run websocket proxy (
pnpm run wsproxy) for local development - Pre-commit hooks (Husky + lint-staged) run linting and formatting automatically
- Use
make cleanbefore building if encountering issues - Electron app requires special build process with
make dep - React components use Relay; ensure GraphQL schema in
/data/is up to date - Backend.AI client library (
src/lib/backend.ai-client-esm.ts) is aliased in Craco config
Core Guidelines
React Essentials (detail: .github/instructions/react.instructions.md, auto-loaded via applyTo)
- Use
'use memo'directive at the top of component bodies for React Compiler optimization. Never remove existing'use memo'. - Use
BAIButtonactionprop for async operations (auto loading state). Prefer BAI components over Ant Design equivalents. - Follow Relay fragment architecture: query orchestrator (useLazyLoadQuery) + fragment component (useFragment).
- Fragment prop naming:
queryReffor Query types,{typeName}Frgmtfor others. - Use
useBAILoggerinstead ofconsole.log. Use pre-defined error boundaries (BAIErrorBoundary,ErrorBoundaryWithNullFallback). - Use Jotai for global state, Relay for GraphQL state.
On-Demand Skills (loaded only when needed)
- Storybook:
storybook-guideskill (CSF 3, meta config, story patterns, checklists) - i18n:
i18n-guideskill (translation keys, casing rules, language-specific guidelines) - Documentation:
docs-guideskill (user manual structure, terminology, multilingual rules) - Relay:
relay-patternsskill (fragment architecture, naming conventions, query optimization)
Auto-Applied Instructions (loaded when editing matching files)
react.instructions.md→react/**/*.tsx,react/**/*.tsstorybook.instructions.md→packages/backend.ai-ui/**/*.stories.tsx,packages/backend.ai-ui/**/*.stories.tsi18n.instructions.md→resources/i18n/**/*.json,packages/backend.ai-ui/src/locale/**/*.json(usei18n-guideskill for tsx/ts context)e2e.instructions.md→e2e/**/*.tsdocs.instructions.md→packages/backend.ai-webui-docs/**/*.md
Verification Harness
Run bash scripts/verify.sh from project root to check Relay, Lint, Format, and TypeScript. Output ends with === ALL PASS === on success. Agents should use this script instead of running checks individually.
PR Review Checklist
When reviewing PRs (especially agent-generated ones), check:
- Verification results (
scripts/verify.shoutput in PR description) - Semantic correctness: does the code do what the issue asks? (lint/tsc passing is not enough)
- i18n keys match actual UI text and follow naming conventions
- No unintended scope creep (files changed beyond what the issue requires)
TODO(needs-backend)markers are properly placed with issue references- No hardcoded strings, magic numbers, or debug artifacts left behind