9.2 KiB
Claude Code Instructions for apps/web
MANDATORY: Quality Checks for ALL Work
BEFORE declaring ANY work complete, fixed, or working, you MUST run and pass these checks:
When This Applies
- Before every commit
- Before saying "it's done" or "it's fixed"
- Before marking a task as complete
- Before telling the user something is working
- After any code changes, no matter how small
npm run pre-commit
This single command runs all quality checks in the correct order:
npm run type-check- TypeScript type checking (must have 0 errors)npm run format- Auto-format all code with Biomenpm run lint:fix- Auto-fix linting issues with Biome + ESLintnpm run lint- Verify 0 errors, 0 warnings
DO NOT COMMIT until all checks pass with zero errors and zero warnings.
Available Scripts
npm run type-check # TypeScript: tsc --noEmit
npm run format # Biome: format all files
npm run format:check # Biome: check formatting without fixing
npm run lint # Biome + ESLint: check for errors/warnings
npm run lint:fix # Biome + ESLint: auto-fix issues
npm run check # Biome: full check (format + lint + imports)
npm run pre-commit # Run all checks (type + format + lint)
Workflow
When asked to make ANY changes:
- Make your code changes
- Run
npm run pre-commit - If it fails, fix the issues and run again
- STOP - Tell user changes are ready for testing
- WAIT for user to manually test and approve
- Only commit/push when user explicitly approves or requests it
CRITICAL: Passing npm run pre-commit only verifies code quality (TypeScript, linting, formatting). It does NOT verify that features work correctly. Manual testing by the user is REQUIRED before committing.
Never auto-commit or auto-push after making changes.
Details
See .claude/CODE_QUALITY_REGIME.md for complete documentation.
No Pre-Commit Hooks
This project does not use git pre-commit hooks for religious reasons. You (Claude Code) are responsible for enforcing code quality before commits.
Quick Reference: package.json Scripts
Primary workflow:
npm run pre-commit # ← Use this before every commit
Individual checks (if needed):
npm run type-check # TypeScript: tsc --noEmit
npm run format # Biome: format code (--write)
npm run lint # Biome + ESLint: check only
npm run lint:fix # Biome + ESLint: auto-fix
Additional tools:
npm run format:check # Check formatting without changing files
npm run check # Biome check (format + lint + organize imports)
Remember: Always run npm run pre-commit before creating commits.
Styling Framework
CRITICAL: This project uses Panda CSS, NOT Tailwind CSS.
- All styling is done with Panda CSS (
@pandacss/dev) - Configuration:
/panda.config.ts - Generated system:
/styled-system/ - Import styles using:
import { css } from '../../styled-system/css' - Token syntax:
color: 'blue.200',borderColor: 'gray.300', etc.
Common Mistakes to Avoid:
- ❌ Don't reference "Tailwind" in code, comments, or documentation
- ❌ Don't use Tailwind utility classes (e.g.,
className="bg-blue-500") - ✅ Use Panda CSS
css()function for all styling - ✅ Use Panda's token system (defined in
panda.config.ts)
Color Tokens:
// Correct (Panda CSS)
css({
bg: 'blue.200',
borderColor: 'gray.300',
color: 'brand.600'
})
// Incorrect (Tailwind)
className="bg-blue-200 border-gray-300 text-brand-600"
See .claude/GAME_THEMES.md for standardized color theme usage in arcade games.
Abacus Visualizations
CRITICAL: This project uses @soroban/abacus-react for all abacus visualizations.
- All abacus displays MUST use components from
@soroban/abacus-react - Package location:
packages/abacus-react - Main components:
AbacusReact,useAbacusConfig,useAbacusDisplay - DO NOT create custom abacus visualizations
- DO NOT manually draw abacus columns, beads, or bars
Common Mistakes to Avoid:
- ❌ Don't create custom abacus components or SVGs
- ❌ Don't manually render abacus beads or columns
- ✅ Always use
AbacusReactfrom@soroban/abacus-react - ✅ Use
useAbacusConfigfor abacus configuration - ✅ Use
useAbacusDisplayfor reading abacus state
MANDATORY: Read the Docs Before Customizing
ALWAYS read the full README documentation before customizing or styling AbacusReact:
- Location:
packages/abacus-react/README.md - Check homepage implementation:
src/app/page.tsx(MiniAbacus component) - Check storybook examples:
src/stories/AbacusReact.*.stories.tsx
Key Documentation Points:
- Custom Styles: Use
fill(not juststroke) for columnPosts and reckoningBar - Props: Use direct props like
value,columns,scaleFactor(not config objects) - Example from Homepage:
const darkStyles = { columnPosts: { fill: 'rgba(255, 255, 255, 0.3)', stroke: 'rgba(255, 255, 255, 0.2)', strokeWidth: 2, }, reckoningBar: { fill: 'rgba(255, 255, 255, 0.4)', stroke: 'rgba(255, 255, 255, 0.25)', strokeWidth: 3, }, } <AbacusReact value={123} columns={3} customStyles={darkStyles} />
Example Usage:
import { AbacusReact } from '@soroban/abacus-react'
<AbacusReact value={123} columns={5} scaleFactor={1.5} showNumbers={true} />
Known Issues
@soroban/abacus-react TypeScript Module Resolution
Issue: TypeScript reports that AbacusReact, useAbacusConfig, and other exports do not exist from the @soroban/abacus-react package, even though:
- The package builds successfully
- The exports are correctly defined in
dist/index.d.ts - The imports work at runtime
- 20+ files across the codebase use these same imports without issue
Impact: npm run type-check will report errors for any files importing from @soroban/abacus-react.
Workaround: This is a known pre-existing issue. When running pre-commit checks, TypeScript errors related to @soroban/abacus-react imports can be ignored. Focus on:
- New TypeScript errors in your changed files (excluding @soroban/abacus-react imports)
- Format checks
- Lint checks
Status: Known issue, does not block development or deployment.
Game Settings Persistence
When working on arcade room game settings, refer to:
-
.claude/GAME_SETTINGS_PERSISTENCE.md- Complete architecture documentation- How settings are stored (nested by game name)
- Three critical systems that must stay in sync
- Common bugs and their solutions
- Debugging checklist
- Step-by-step guide for adding new settings
-
.claude/GAME_SETTINGS_REFACTORING.md- Recommended improvements- Shared config types to prevent inconsistencies
- Helper functions to reduce duplication
- Type-safe validation
- Migration strategy
Quick Reference:
Settings are stored as: gameConfig[gameName][setting]
Three places must handle settings correctly:
- Provider (
Room{Game}Provider.tsx) - Merges saved config with defaults - Socket Server (
socket-server.ts) - Creates session from saved config - Validator (
{Game}Validator.ts) -getInitialState()must accept ALL settings
If a setting doesn't persist, check all three locations.
Z-Index and Stacking Context Management
When working with z-index values or encountering layering issues, refer to:
.claude/Z_INDEX_MANAGEMENT.md- Complete z-index documentation- Z-index layering hierarchy (0-20000+)
- Stacking context rules and gotchas
- Current z-index audit of all components
- Guidelines for choosing z-index values
- Migration plan to use constants file
- Debugging checklist for layering issues
Quick Reference:
ALWAYS use the constants file:
import { Z_INDEX } from '@/constants/zIndex'
// ✅ Good
zIndex: Z_INDEX.NAV_BAR
zIndex: Z_INDEX.MODAL
zIndex: Z_INDEX.TOOLTIP
// ❌ Bad - magic numbers!
zIndex: 100
zIndex: 10000
zIndex: 500
Layering hierarchy:
- Base content: 0-99
- Navigation/UI chrome: 100-999
- Overlays/dropdowns/tooltips: 1000-9999
- Modals/dialogs: 10000-19999
- Toasts: 20000+
Critical reminder about stacking contexts:
Z-index values are only compared within the same stacking context! Elements with position + zIndex, opacity < 1, transform, or filter create new stacking contexts where child z-indexes are relative, not global.
Before setting a z-index, always check:
- What stacking context is this element in?
- Am I comparing against siblings or global elements?
- Does my parent create a stacking context?
Database Access
This project uses SQLite with Drizzle ORM. Database location: ./data/sqlite.db
ALWAYS use MCP SQLite tools for database operations:
mcp__sqlite__list_tables- List all tablesmcp__sqlite__describe_table- Get table schemamcp__sqlite__read_query- Run SELECT queriesmcp__sqlite__write_query- Run INSERT/UPDATE/DELETE queriesmcp__sqlite__create_table- Create new tables- DO NOT use bash
sqlite3commands - use the MCP tools instead
Database Schema:
- Schema definitions:
src/db/schema/ - Drizzle config:
drizzle.config.ts - Migrations:
drizzle/directory