This project is designed to be friendly for AI coding assistants and agents. The structure is modular, typed, and follows clear patterns that make it easy for LLMs to understand and modify.
Users can employ various AI tools to extend or modify this application:
- Google Gemini: Excellent for logic generation, refactoring, and explaining complex music theory concepts within the app's context.
- GitHub Copilot: Great for inline code completion and boilerplate reduction.
- Cursor / Windsurf: Ideal for full-project context-aware editing.
If you are using an AI agent to modify this codebase, please adhere to the following patterns:
- Context is Key: Always read
types.tsandconstants.tsfirst. These files define the domain model (Levels, Chords, GameState). - Type Safety: Ensure generated code adheres to the TypeScript definitions. Do not use
any. - Localization:
- Never hardcode UI text.
- Always add new strings to
i18n/locales/en.tsfirst. - If possible, add translations for
es.ts,pt.ts, andja.ts. - Use the
useTranslationhook to access strings.
- Audio Engine:
- Modifications to
audioService.tsmust respect the Tone.js lifecycle. - Audio context must only resume/start after a user interaction event (click/keydown).
- Modifications to
- Pattern Matching with ts-pattern:
- Prefer ts-pattern over switch statements and if-else chains when working with enums, union types, or complex conditional logic.
- Use
.exhaustive()whenever possible to ensure all cases are handled at compile time. - Pattern matching is especially useful for:
- LevelType enum handling (see
services/theoryService.ts) - Language type guards and validation
- State machine transitions (GameState status changes)
- Audio preset selection and configuration
- State Management:
- The app uses a centralized
GameStateobject inApp.tsx. - Avoid creating parallel state trees unless necessary for a specific isolated component.
- The app uses a centralized
- Context7 Integration: Always use Context7 when you need code generation, setup or configuration steps, or library/API documentation. This means you should automatically use the Context7 MCP tools to resolve library id and get library docs without me having to explicitly ask.
- Development Server Management: Always check if the development server is already running before starting it. If it's running, just access the website instead of starting a new server. Use
curl -s http://localhost:5173or similar to check if server is responsive. - Tailwind CSS Best Practices:
- Never use
!importantin Tailwind classes. The project usestailwind-mergewhich automatically handles class conflicts and precedence. - Use the
cn()utility fromlib/utils.tsfor combining classes, especially when dealing with conditional styling. - Prefer semantic Tailwind classes over arbitrary values when possible.
- Never use
A coding task is considered complete only when both of the following pass:
- Lint Check:
pnpm run lintmust pass with zero errors (warnings are acceptable) - Format Check:
pnpm run formatmust pass without any changes needed - Build Check:
pnpm run buildmust complete successfully without TypeScript errors
Declaration of Completion: Only declare a coding task "done" or "completed" after verifying all three checks above pass. Do not declare completion based on visual inspection or partial fixes.
The following Biome rules may generate false positives and can be safely ignored in specific contexts:
complexity/noExcessiveCognitiveComplexity: Some functions naturally have higher complexity and warnings are acceptable:- Keyboard event handlers (multiple key combinations)
- Feedback generation functions (multiple conditional branches) These warnings are acceptable if the function is well-structured and readable.
- Note: Progression generation should use ts-pattern to reduce complexity.
a11y/useAnchorContent: Links with properaria-labelandtitleattributes that contain SVG icons are already accessible. This rule may flag false positives when accessible content is provided via ARIA attributes.
complexity/useLiteralKeys: When working with dynamic object keys that come from string variables, bracket notation may be necessary even for literal-like access patterns.
The following warnings are considered acceptable and don't need to be fixed:
- Cognitive complexity warnings for the specific function types mentioned above
useLiteralKeyswarnings when dynamic object access is requireduseAnchorContentwarnings when proper ARIA attributes are present
When asking an AI to generate new levels, use this structure:
"Create a new Level 13 based on the 'Phrygian Mode'.
- Update
types.tsLevelType enum.- Update
constants.tswith the level configuration (available chords).- Update
services/theoryService.tswith the chord maps and generation logic.- Update
i18n/locales/*.tswith the level title, description, lesson content, and chord descriptions."