Clean up project documentation and constitution for post-MVP maturity
- CLAUDE.md: replace 32-line per-feature tech changelog with consolidated tech stack, add project structure and data/storage sections, remove stale Recent Changes - README.md: rewrite for current feature set, fix bestiary description (import-based, not bundled), remove placeholder license section - Constitution v2.2.0: remove unused Agent Boundary principle (MAJOR), add README and CLAUDE.md sync rules to Development Workflow (MINOR) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
<!--
|
||||
Sync Impact Report
|
||||
───────────────────
|
||||
Version change: 1.0.2 → 1.0.3 (PATCH — add merge-gate rule)
|
||||
Version change: 1.0.3 → 2.2.0 (MAJOR+MINOR — remove Agent Boundary, add README/CLAUDE.md sync rules)
|
||||
Modified sections:
|
||||
- Development Workflow: added automated-checks merge gate
|
||||
- Core Principles: removed III (Agent Boundary), renumbered IV→III, V→IV, VI→V, VII→VI
|
||||
- Layered Architecture: removed Agent layer (4→3 layers)
|
||||
- Clarification-First: reworded "the agent" → "Claude Code"
|
||||
- Development Workflow: removed agent-assisted reference
|
||||
Templates requiring updates:
|
||||
- .specify/templates/plan-template.md ✅ no update needed
|
||||
- .specify/templates/spec-template.md ✅ no update needed
|
||||
- .specify/templates/plan-template.md ⚠️ update Constitution Check if it references Agent Boundary
|
||||
- .specify/templates/spec-template.md ⚠️ update Constitution Check if it references Agent Boundary
|
||||
- .specify/templates/tasks-template.md ✅ no update needed
|
||||
Follow-up TODOs: none
|
||||
Follow-up TODOs: review templates for stale Agent Boundary references
|
||||
-->
|
||||
# Encounter Console Constitution
|
||||
|
||||
@@ -29,7 +32,7 @@ be injected at the boundary, never sourced inside the domain layer.
|
||||
|
||||
### II. Layered Architecture
|
||||
|
||||
The codebase MUST be organized into four layers with strict
|
||||
The codebase MUST be organized into three layers with strict
|
||||
dependency direction:
|
||||
|
||||
1. **Domain** — pure types, state transitions, validation rules.
|
||||
@@ -39,34 +42,21 @@ dependency direction:
|
||||
interfaces that Adapters implement. May import Domain only.
|
||||
3. **Adapters** — I/O, persistence, UI rendering, external APIs.
|
||||
May import Application and Domain.
|
||||
4. **Agent** — AI-assisted features (suggestions, analysis).
|
||||
May import Application and Domain as read-only consumers.
|
||||
|
||||
A module in an inner layer MUST NOT import from an outer layer.
|
||||
|
||||
### III. Agent Boundary
|
||||
|
||||
The agent layer MAY read domain events and current state. The agent
|
||||
MAY produce suggestions, annotations, or recommendations. The agent
|
||||
MUST NOT mutate domain state directly. All agent-originated changes
|
||||
MUST flow through the Application layer as explicit user-confirmed
|
||||
commands.
|
||||
|
||||
- Agent output MUST be clearly labeled as suggestions.
|
||||
- No silent or automatic application of agent recommendations.
|
||||
|
||||
### IV. Clarification-First
|
||||
### III. Clarification-First
|
||||
|
||||
Before making any non-trivial assumption during specification,
|
||||
planning, or implementation, the agent MUST surface a clarification
|
||||
planning, or implementation, Claude Code MUST surface a clarification
|
||||
question to the user. "Non-trivial" means any decision that would
|
||||
alter observable behavior, data model shape, or public API surface.
|
||||
The agent MUST also ask when multiple valid interpretations exist,
|
||||
Claude Code MUST also ask when multiple valid interpretations exist,
|
||||
when a choice would affect architectural layering, or when scope
|
||||
would expand beyond the current spec. The agent MUST NOT silently
|
||||
would expand beyond the current spec. Claude Code MUST NOT silently
|
||||
choose among valid alternatives.
|
||||
|
||||
### V. Escalation Gates
|
||||
### IV. Escalation Gates
|
||||
|
||||
Any feature, requirement, or scope change not present in the current
|
||||
spec MUST be rejected at implementation time until the spec is
|
||||
@@ -77,7 +67,7 @@ explicitly updated. The workflow is:
|
||||
3. Update the spec via `/speckit.specify` or `/speckit.clarify`.
|
||||
4. Only then proceed with implementation.
|
||||
|
||||
### VI. MVP Baseline Language
|
||||
### V. MVP Baseline Language
|
||||
|
||||
Constraints in this constitution and in specs MUST use MVP baseline
|
||||
language ("MVP baseline does not include X") rather than permanent
|
||||
@@ -86,7 +76,7 @@ add capabilities in future iterations without constitutional
|
||||
amendment. The current MVP baseline is local-first and single-user;
|
||||
this is a starting scope, not a permanent restriction.
|
||||
|
||||
### VII. No Gameplay Rules in Constitution
|
||||
### VI. No Gameplay Rules in Constitution
|
||||
|
||||
This constitution MUST NOT contain concrete gameplay mechanics,
|
||||
rule-system specifics, or encounter resolution logic. Such details
|
||||
@@ -96,9 +86,9 @@ architecture, and quality — not product behavior.
|
||||
## Scope Constraints
|
||||
|
||||
- The Encounter Console's primary focus is initiative tracking and
|
||||
encounter state management. Adjacent capabilities (e.g., richer
|
||||
game-engine features) are not in the MVP baseline but may be
|
||||
added via spec updates in future iterations.
|
||||
encounter state management. Adjacent capabilities (e.g., bestiary
|
||||
integration, richer game-engine features) may be added via spec
|
||||
updates.
|
||||
- Technology choices, UI framework, and storage mechanism are
|
||||
spec-level decisions, not constitutional mandates.
|
||||
- Testing strategy (unit, integration, contract) is determined per
|
||||
@@ -117,8 +107,14 @@ architecture, and quality — not product behavior.
|
||||
- Commits SHOULD be atomic and map to individual tasks where
|
||||
practical.
|
||||
- Layer boundary compliance MUST be verified by automated import
|
||||
rules or architectural tests. Agent-assisted or manual review MAY
|
||||
supplement but not replace automated checks.
|
||||
rules or architectural tests.
|
||||
- When a feature adds, removes, or changes user-facing capabilities
|
||||
described in README.md, the README MUST be updated in the same
|
||||
change. Features that materially alter what the product does or
|
||||
how it is set up SHOULD also be reflected in the README.
|
||||
- When a feature changes the tech stack, project structure, or
|
||||
architectural patterns documented in CLAUDE.md, the CLAUDE.md
|
||||
MUST be updated in the same change.
|
||||
|
||||
## Governance
|
||||
|
||||
@@ -142,4 +138,4 @@ MUST comply with its principles.
|
||||
**Compliance review**: Every spec and plan MUST include a
|
||||
Constitution Check section validating adherence to all principles.
|
||||
|
||||
**Version**: 1.0.3 | **Ratified**: 2026-03-03 | **Last Amended**: 2026-03-03
|
||||
**Version**: 2.2.0 | **Ratified**: 2026-03-03 | **Last Amended**: 2026-03-10
|
||||
|
||||
70
CLAUDE.md
70
CLAUDE.md
@@ -5,7 +5,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
pnpm check # Merge gate — must pass before every commit (knip + format + lint + typecheck + test)
|
||||
pnpm check # Merge gate — must pass before every commit (knip + biome + typecheck + test + jscpd)
|
||||
pnpm knip # Unused code detection (Knip)
|
||||
pnpm test # Run all tests (Vitest)
|
||||
pnpm test:watch # Tests in watch mode
|
||||
@@ -27,11 +27,38 @@ apps/web (React 19 + Vite) → packages/application (use cases) → packages
|
||||
```
|
||||
|
||||
- **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.
|
||||
- **Application** — Orchestrates domain calls via port interfaces (`EncounterStore`, `BestiarySourceCache`). No business logic here.
|
||||
- **Web** — React adapter. Implements ports using hooks/state. All UI components, routing, and user interaction live here.
|
||||
|
||||
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.
|
||||
|
||||
### Data & Storage
|
||||
|
||||
- **localStorage** — encounter persistence (adapter layer, JSON serialization)
|
||||
- **IndexedDB** — bestiary source cache (`apps/web/src/adapters/bestiary-cache.ts`, via `idb` wrapper)
|
||||
- **`data/bestiary/index.json`** — pre-built search index for creature lookup, generated by `scripts/generate-bestiary-index.mjs`
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
apps/web/ React app — components, hooks, adapters
|
||||
packages/domain/src/ Pure state transitions, types, validation
|
||||
packages/application/src/ Use cases, port interfaces
|
||||
data/bestiary/ Bestiary search index
|
||||
scripts/ Build tooling (layer checks, index generation)
|
||||
specs/<feature>/ Feature specs (spec.md, plan.md, tasks.md)
|
||||
.specify/memory/ Project constitution
|
||||
```
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- TypeScript 5.8 (strict mode, `verbatimModuleSyntax`)
|
||||
- React 19, Vite 6, Tailwind CSS v4
|
||||
- Lucide React (icons)
|
||||
- `idb` (IndexedDB wrapper for bestiary cache)
|
||||
- Biome 2.0 (formatting + linting), Knip (unused code), jscpd (copy-paste detection)
|
||||
- Vitest (testing), Lefthook (pre-commit hooks)
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Biome 2.0** for formatting and linting (no Prettier, no ESLint). Tab indentation, 80-char lines. Imports are auto-organized alphabetically.
|
||||
@@ -50,40 +77,3 @@ The constitution (`.specify/memory/constitution.md`) governs all feature work:
|
||||
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)
|
||||
- TypeScript 5.x (strict mode, verbatimModuleSyntax) + React 19, Vite 6, Biome 2.0, existing domain/application packages (008-persist-encounter)
|
||||
- Browser localStorage (adapter layer only) (008-persist-encounter)
|
||||
- TypeScript 5.x (strict mode, verbatimModuleSyntax) + React 19, Vite 6, Biome 2.0, Vites (009-combatant-hp)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + React 19, Vite 6, Tailwind CSS v4, shadcn/ui, Lucide React (icons) (010-ui-baseline)
|
||||
- N/A (no storage changes — localStorage persistence unchanged) (010-ui-baseline)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + React 19, Vite 6, Tailwind CSS v4, shadcn/ui-style components, Lucide React (icons) (011-quick-hp-input)
|
||||
- N/A (no storage changes -- existing localStorage persistence handles HP via `adjustHpUseCase`) (011-quick-hp-input)
|
||||
- N/A (no storage changes -- existing localStorage persistence unchanged) (012-turn-navigation)
|
||||
- N/A (no storage changes -- purely derived state, existing localStorage persistence unchanged) (013-hp-status-indicators)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + jscpd (new dev dependency), Lefthook (existing), Biome 2.0 (existing), Knip (existing) (015-add-jscpd-gate)
|
||||
- N/A (no storage changes) (015-add-jscpd-gate)
|
||||
- Browser localStorage (existing adapter, transparent JSON serialization) (016-combatant-ac)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + React 19, Vite 6, Tailwind CSS v4, Lucide React (icons) (017-combat-conditions)
|
||||
- N/A (no storage changes — existing localStorage persistence unchanged) (019-combatant-row-declutter)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + React 19, Tailwind CSS v4, Lucide React (icons) (020-fix-zero-hp-opacity)
|
||||
- Browser localStorage (existing adapter, extended for creatureId) (021-bestiary-statblock)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + React 19, Tailwind CSS v4 + React 19, Tailwind CSS v4, Vite 6 (022-fixed-layout-bars)
|
||||
- N/A (no storage changes -- purely presentational) (022-fixed-layout-bars)
|
||||
- Browser localStorage (existing adapter, updated to handle empty encounters) (023-clear-encounter)
|
||||
- N/A (no storage changes — purely presentational fix) (024-fix-hp-popover-overflow)
|
||||
- N/A (no storage changes — purely derived from existing bestiary data) (025-display-initiative)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + React 19, Tailwind CSS v4, Lucide React (icons), Vite 6 (026-roll-initiative)
|
||||
- N/A (no storage changes — existing localStorage persistence handles initiative via `setInitiativeUseCase`) (026-roll-initiative)
|
||||
- N/A (no storage changes — purely presentational) (027-ui-polish)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + React 19, Tailwind CSS v4, Vite 6 + Tailwind CSS v4 (CSS-native `@theme` theming), Lucide React (icons) (028-semantic-hover-tokens)
|
||||
- TypeScript 5.8 (strict mode, verbatimModuleSyntax) + React 19, Vite 6, Tailwind CSS v4, Lucide React (icons), idb (IndexedDB wrapper) (029-on-demand-bestiary)
|
||||
- IndexedDB for cached source data (new); localStorage for encounter persistence (existing, unchanged) (029-on-demand-bestiary)
|
||||
- IndexedDB for cached source data (existing via `bestiary-cache.ts`); localStorage for encounter persistence (existing, unchanged) (030-bulk-import-sources)
|
||||
|
||||
## Recent Changes
|
||||
- 003-remove-combatant: Added TypeScript 5.x (strict mode, verbatimModuleSyntax) + React 19, Vite
|
||||
|
||||
43
README.md
43
README.md
@@ -1,10 +1,17 @@
|
||||
# Initiative Tracker
|
||||
# Encounter Console
|
||||
|
||||
A turn-based initiative tracker for tabletop RPG encounters. Click "Next Turn" to cycle through combatants and advance rounds.
|
||||
A local-first initiative tracker and encounter manager for tabletop RPGs (D&D 5e / 2024). Runs entirely in the browser — no server, no account, no data leaves your machine.
|
||||
|
||||
## What it does
|
||||
|
||||
- **Initiative tracking** — add combatants, roll initiative (manual or d20), cycle turns and rounds
|
||||
- **Encounter state** — HP, AC, conditions, concentration tracking with visual status indicators
|
||||
- **Bestiary integration** — import bestiary JSON sources, search creatures, and view full stat blocks
|
||||
- **Persistent** — encounters survive page reloads via localStorage; bestiary data cached in IndexedDB
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js 22
|
||||
- Node.js 22+
|
||||
- pnpm 10.6+
|
||||
|
||||
## Getting Started
|
||||
@@ -14,9 +21,7 @@ pnpm install
|
||||
pnpm --filter web dev
|
||||
```
|
||||
|
||||
Open the URL printed in your terminal (typically `http://localhost:5173`).
|
||||
|
||||
The app starts with a 3-combatant demo encounter (Aria, Brak, Cael). Click **Next Turn** to advance through the initiative order. When the last combatant finishes their turn, the round number increments and the cycle restarts.
|
||||
Open `http://localhost:5173`.
|
||||
|
||||
## Scripts
|
||||
|
||||
@@ -24,5 +29,27 @@ The app starts with a 3-combatant demo encounter (Aria, Brak, Cael). Click **Nex
|
||||
|---------|-------------|
|
||||
| `pnpm --filter web dev` | Start the dev server |
|
||||
| `pnpm --filter web build` | Production build |
|
||||
| `pnpm test` | Run all tests |
|
||||
| `pnpm check` | Full merge gate (format, lint, typecheck, test) |
|
||||
| `pnpm test` | Run all tests (Vitest) |
|
||||
| `pnpm check` | Full merge gate (knip, biome, typecheck, test, jscpd) |
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
apps/web/ React 19 + Vite — UI components, hooks, adapters
|
||||
packages/domain/ Pure functions — state transitions, types, validation
|
||||
packages/app/ Use cases — orchestrates domain via port interfaces
|
||||
data/bestiary/ Bestiary index for creature search
|
||||
scripts/ Build tooling (layer boundary checks, index generation)
|
||||
specs/ Feature specifications (spec → plan → tasks)
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
Strict layered architecture with enforced dependency direction:
|
||||
|
||||
```
|
||||
apps/web (adapters) → packages/application (use cases) → packages/domain (pure logic)
|
||||
```
|
||||
|
||||
Domain is pure — no I/O, no randomness, no framework imports. Layer boundaries are enforced by automated import checks that run as part of the test suite. See [CLAUDE.md](./CLAUDE.md) for full conventions.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user