Files
initiative/CLAUDE.md

3.4 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

pnpm check              # Merge gate — must pass before every commit (knip + format + lint + typecheck + test)
pnpm knip               # Unused code detection (Knip)
pnpm test               # Run all tests (Vitest)
pnpm test:watch         # Tests in watch mode
pnpm typecheck          # tsc --build (project references)
pnpm lint               # Biome lint
pnpm format             # Biome format (writes)
pnpm --filter web dev   # Vite dev server (localhost:5173)
pnpm --filter web build # Production build

Run a single test file: pnpm vitest run packages/domain/src/__tests__/advance-turn.test.ts

Architecture

Strict layered architecture with ports/adapters and enforced dependency direction:

apps/web (React 19 + Vite)  →  packages/application (use cases)  →  packages/domain (pure logic)
  • Domain — Pure functions, no I/O, no framework imports. All state transitions are deterministic. Errors returned as values (DomainError), never thrown. Adapters may throw only for programmer errors.
  • Application — Orchestrates domain calls via port interfaces (e.g., EncounterStore). No business logic here.
  • Web — React adapter. Implements ports using hooks/state.

Layer boundaries are enforced by scripts/check-layer-boundaries.mjs, which runs as a Vitest test. Domain and application must never import from React, Vite, or upper layers.

Conventions

  • Biome 2.0 for formatting and linting (no Prettier, no ESLint). Tab indentation, 80-char lines. Imports are auto-organized alphabetically.
  • TypeScript strict mode with verbatimModuleSyntax. Use .js extensions in relative imports when required by the repo's ESM settings (e.g., ./types.js).
  • Branded types for identity values (e.g., CombatantId). Prefer immutability/readonly where practical.
  • Domain events are plain data objects with a type discriminant — no classes.
  • Tests live in packages/*/src/__tests__/*.test.ts. Test pure functions directly; map acceptance scenarios and invariants from specs to individual it() blocks.
  • Feature specs live in specs/<feature>/ with spec.md, plan.md, tasks.md. The project constitution is at .specify/memory/constitution.md.

Constitution (key principles)

The constitution (.specify/memory/constitution.md) governs all feature work:

  1. Deterministic Domain Core — Pure state transitions only; no I/O, randomness, or clocks in domain.
  2. Layered Architecture — Domain → Application → Adapters. Never skip layers or reverse dependencies.
  3. Clarification-First — Ask before making non-trivial assumptions.
  4. MVP Baseline — Say "MVP baseline does not include X", never permanent bans.
  5. Every feature begins with a spec — Spec → Plan → Tasks → Implementation.

Active Technologies

  • TypeScript 5.x (strict mode, verbatimModuleSyntax) + React 19, Vite (003-remove-combatant)
  • In-memory React state (local-first, single-user MVP) (003-remove-combatant)
  • TypeScript 5.x (project), Go binary via npm (Lefthook) + lefthook (npm devDependency) (006-pre-commit-gate)
  • TypeScript 5.x (strict mode, verbatimModuleSyntax) + Knip v5 (new), Biome 2.0, Vitest, Vite 6, React 19 (007-add-knip)

Recent Changes

  • 003-remove-combatant: Added TypeScript 5.x (strict mode, verbatimModuleSyntax) + React 19, Vite