This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
pnpm run dev- Start development environment (TypeScript watch + Relay watch + React dev server under Portless on*.localhost:1355)
pnpm run build- Full production build (cleansbuild/web/, copies resources, builds React via Vite withvite-plugin-pwaservice worker generation, builds workspace packages)pnpm run build:react-only- Build only React app via Vitepnpm run relay- Compile GraphQL queries with Relay compiler
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
pnpm run test- Run Vitest tests (root:scripts/,src/)pnpm run test(in/reactdirectory) - Run React-specific Vitest tests (pnpm run vitest:watchfor watch mode)- E2E tests (
/e2e/) use Playwright; require full Backend.AI cluster running first
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
This is a React web application using React 19 + Ant Design 6 + Relay 20 (GraphQL).
- React Build: Vite 6 (
@vitejs/plugin-react) withvite-plugin-pwa,vite-plugin-svgr,vite-plugin-node-polyfills - Component Library Build: Vite (
packages/backend.ai-ui/) - Service Worker:
vite-plugin-pwa(Workbox under the hood), integrated into the Vite 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: Vitest for unit tests (jsdom env), 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
react/ # Main React application (Vite)
src/ # Application source code
components/ # React UI components
pages/ # Page-level components
hooks/ # Custom React hooks
helper/ # Utility functions
__generated__/ # Relay compiler output
vite.config.ts # Vite + plugins (PWA / svgr / node-polyfills) configuration
vitest.config.ts # Vitest configuration (unit tests)
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
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 (Vite) →
react/build/→ copied tobuild/web/ - Service worker (
sw.js) generated byvite-plugin-pwaduring the React build - backend.ai-ui (Vite) →
packages/backend.ai-ui/dist/
- React app (Vite) →
- Dev Server: Run
pnpm run dev(TypeScript watch + Relay watch + React dev server under Portless). Portless is adevDependency, no global install needed;dev.mjsauto-starts the daemon on port 1355 (HTTPS by default). - URL: For branches matching
FR-XXXXthe dev URL ishttps://fr-XXXX.localhost:1355; otherwise Portless derives a branch-based subdomain (printed on startup). SeeDEV_ENVIRONMENT.mdfor theme color and troubleshooting. - Testing: Vitest unit tests + Playwright E2E tests
- Linting: ESLint 9 (flat config) + Prettier with pre-commit hooks via Husky
-
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.
- Main config:
config.toml(copied fromconfig.toml.sample) - Multiple environments supported via
configs/directory - Electron app config:
build/electron-app/app/config.toml
- 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
- vite 6 + @vitejs/plugin-react - React app bundler and dev server
- vitest 4 - Unit test runner (jsdom env)
- electron 35 - Desktop app framework
- 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
- 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
- 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/
- 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 is a workspace package at
packages/backend.ai-client/(built with tsup)
- 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.
- 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)
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
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.
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