When to invoke (auto-trigger)
Invoke automatically whenever:
- A new component, store, API route, or type file is about to be created
- The user asks how to structure, design, or plan a feature in this repo
- A refactor touches domain boundaries or moves code between domains
Do NOT invoke for: small bug fixes, copy changes, config tweaks, or test-only changes.
Narraitor Architecture
Migration in progress: Component organization and styling patterns are actively migrating to a design system. Verify component structure and styling conventions against current code rather than relying solely on this skill.
Place code in the right module
- Put routes and API handlers in
src/app/andsrc/app/api/(Next.js 15 App Router). - Put UI in
src/components/, grouped by domain/feature; usesrc/components/uifor shared primitives andsrc/components/sharedfor cross-domain UI. - Put state in
src/state/with domain stores; use persistence helpers insrc/state/persistence.tswhen needed. - Put types in
src/types/*.types.ts; keepsrc/types/index.tstype-only (no runtime imports). - Put hooks in
src/hooks/and services insrc/services/unless an existingsrc/lib/*module already owns the behavior. - Put shared logic and domain services in
src/lib/(AI, services, generators, utils, and domain-specific modules likenarrative/,lore/,inventory/,world/,journal/,tutorial/). Usesrc/utils/for general helpers already used there.
Enforce domain boundaries
- Keep domain logic inside its domain folders and store; coordinate cross-domain behavior at pages or feature orchestrators.
- Share data across domains via typed IDs/DTOs instead of direct store or component imports.
- Follow the domain names in
src/types/and existingsrc/state/*Store.tsfiles.
Follow state patterns
- Use the
CrudStoretype when building standard CRUD stores. - Use
persist+createIndexedDBStoragefor stores that must survive reloads. - Store only source-of-truth data; compute derived values in selectors.
Keep AI server-side
- Route AI calls through API routes and
src/lib/ai(uses@google/genai). - Never expose API keys or AI clients in client components.
Use design tokens
- Avoid hardcoded colors; use
var(--color-*)design tokens directly (already complete colors, never wrap inhsl()). Status/domain tokens (--success,--warning,--ending-*,--alignment-*, etc.) are raw HSL channels and DO needhsl(var(--success))— seepublic_docs/design-system/design-tokens.mdfor the full split. - Style components with plain CSS + design tokens (removed: Tailwind, shadcn/ui, cva); use
clsxfor conditional classes.
Validate with tests and dev harnesses
- Add tests in
__tests__/or*.test.ts(x); add stories insrc/stories/. - Use
/dev/*routes for interactive feature verification when relevant.
Target the right branch
- Branch off
developand targetdevelopin PRs. Never push tomainor open a PR against it. mainholds tagged releases only; the maintainer fast-forwards it manually following public_docs/development/release-process.md.- Release notes live in
RELEASES.mdat the repo root.
References
resources/domain-boundaries.mdresources/state-management-patterns.mdresources/component-patterns.md