Skip to content

Latest commit

 

History

History
74 lines (58 loc) · 8.9 KB

File metadata and controls

74 lines (58 loc) · 8.9 KB

CLAUDE.md

Project context. Read first in every new chat. Written in English to save context; all chat prose, UI text, commits, changelog and PR reviews stay Russian.

Session protocol (token economy)

  • Cost scales with turns, not words: batch independent reads/searches/edits into one message; run long commands in the background instead of polling.
  • Show diffs or changed fragments, never reprint a file. Don't re-read what is already in context. Don't re-run a check that passed until code changed.
  • Unknown path → Grep, not a question. Ask only when the answer changes the whole approach.
  • Big files (spells.js, data.js, character-builds.js, build-notes-data.js, index.html) — Grep plus Read with offset/limit, never whole. One full read of those stays in context for the rest of the session and is billed on every later request.
  • Session cap: 150 model requests or 200k context. At the cap — /carry, then /clear, even mid-task. Measured on this repo: sessions over 300 requests burned 72% of all tokens ever spent; context grows ~0.7k per request, so one 600-request session costs four 150-request ones. The Stop hook warns at 120 requests / 150k.
  • Never read the same file twice in one session — measured 32% of all read volume was re-reads (style.css alone: 266). What was read is still in context; scroll back instead. If a file changed since, read only the changed range.
  • Before touching style.css, index.html or a big JS module: Read docs/map.md limit 20 (its TOC), then a ranged read of the section you need, then the ranged read of the file itself. Regenerate with node tools/gen-map.js after large structural edits.
  • Any UI/CSS/preview check goes to the verifier subagent, always — screenshots and browser dumps must never land in the main context (measured 459 images and ~130M carried tokens).
  • Subagents only for wide repo search, browser verification (verifier) or mechanical routine on a cheap model. Never spawn one for a single command — it starts cold and re-reads everything.
  • Routine (boilerplate, renames, small fixes) — no extended reasoning.
  • Report: what changed / what to check. No task restatement, no unrequested docs or refactors. Task closed → 2-line handoff summary, then suggest /clear.

Stack

  • Vanilla JS + HTML + CSS, no bundler, no npm runtime deps (npm is for tools only).
  • PWA: sw.js (CACHE_NAME shaped dnd-sheet-vN + FILES_TO_CACHE) + manifest.json.
  • Vendored: vendor/dice-box/ (3D dice, WebGL), vendor/jspdf/ (PDF).

File map

Full structure, key functions, character schema and migrations — docs/ARCHITECTURE.md. Line-level map for ranged reads (CSS sections, markup blocks, function and data-constant indexes) — docs/map.md, generated by node tools/gen-map.js.

  • index.html — the only page: markup, script order, lazy loader.
  • Core: rules.js (pure rules math, no DOM — AC, saves, slots, rest, concentration), app-core.js (state, navigation, characters) + app-migrate.js, app-builds.js, app-io.js.
  • Tabs: app-combat.js + app-conditions.js / app-cast-effects.js / app-proficiencies.js, app-hp.js, app-inventory.js, app-spells.js, app-party.js, app-notes.js, app-ui.js + app-dice.js / app-settings.js / app-asi.js, app-desktop.js, app-help.js, history-stack.js, app-backup.js, app-log.js, app-pdf.js, app-home.js.
  • Data: data.js (classes/races/feats + APP_VERSION/APP_VERSION_DATE/APP_CHANGELOG), data-2024.js, spells.js, spell-effects.js, character-builds.js + build-notes-data.js, class-choices.js + subclass-choices-data.js, magic-items.js, gear-catalog.js, glossary-data.js, monsters-srd.js + npc-srd.js.
  • Misc: icons.js, bg-space.js + dice-arena-bg.js, dev-verify-builds.js (verifyAllBuilds()).
  • tools/ — version, changelog and check scripts + phb-search.py (search local rulebook PDFs) + gen-map.js (regenerates docs/map.md). tests/headless-node.js, runner.html + headless.js, fixtures.js, rules-cases.js. CI — .github/workflows/: tests.yml (tests + invariant + themes), pages.yml (deploy), claude-code-review.yml (PR review in Russian, review only).

Code conventions

  • Modules are plain <script src> at the bottom of index.html in a hard order: app-logicons → backgrounds → data → app-core → tabs → app-ui/app-notes/app-desktop/app-help. The only type="module" is the dice-box wrapper.
  • Everything is exchanged through globals: top-level function f(), no exports. index.html holds ~460 inline handlers (onclick=, oninput=) calling them by name — wrapping such a file in an IIFE breaks the tab. IIFE only in the self-contained app-log.js / icons.js / history-stack.js / bg-space.js / dice-arena-bg.js, which publish via window.X.
  • ES5 style: var, almost no arrows or template strings. Match the surrounding code.
  • Heavy files load lazily via loadScript() at the bottom of index.html: app-pdf + vendor/jspdf, build-notes-data, monsters-srd + npc-srd, magic-items, gear-catalog, data-2024. Their ?v= tokens live there too.
  • New js/css file → wire it in index.html (<script src> or loadScript) + ?v= token + a line in FILES_TO_CACHE (sw.js). All three are enforced by tools/check-invariant.js in CI; missing any one turns the tests job red.
  • UI and terminology are Russian, canon is the 5e 2014 books; the 2024 edition lives behind char.edition (EDITION_DATA/edData).

Run and test

  • Preview — the dnd-app config in .claude/launch.json (preview_start, port 3017), or any static server from the repo root; the PWA needs https or localhost. Browser verification goes through the verifier subagent (skill verify-ui).
  • /test (= node tests/headless-node.js) — logic; tests/runner.html — same in a browser; tests.html in the root — rules.js cases only; verifyAllBuilds() in the DevTools console — builds, currently 36/36 fullPass.

Versioning

Release invariant — five values change together in one command:

APP_VERSION ↔ APP_CHANGELOG[0].version ↔ CACHE_NAME (dnd-sheet-vN) ↔ every ?v=vN token in index.html ↔ CHANGELOG.md

/bump <patch|minor|major> "<changelog>" [--type chore|feat|fix] edits them, then /preflight. Mechanics and failure modes — skill release.

/ship runs the whole cycle: it reads the diff, decides whether a bump is needed (changes only under .claude/, tools/, docs/ go as a plain commit without a version), writes the level and changelog text, then the releaser subagent does tests → bump → invariant → commit → push → CI wait, and relpost returns the announcement. Commit and push happen only on this command.

Releases are described on three levels, all generated from APP_CHANGELOG + git: short — CHANGELOG.md and the in-app history window; detailed — docs/RELEASES.md; full patch — the GitHub compare/ link. Both generators run from /bump; /relpost builds the announcement.

Hooks (.claude/settings.json, the source of truth)

PostToolUse on Edit|Write|MultiEdit — five. Blocking (exit 2): sw.js edited without a CACHE_NAME bump; APP_VERSIONAPP_CHANGELOG[0].version mismatch; node --check on any *.js outside vendor/. Warning only: tests on *.js edits, check-theme.js --hook on style.css. Stop — two, both warning only: uncommitted changes and session size (check-session-size-hook.js, warns at 120 requests / 150k context, hard at 150 / 200k). Mute both with DND_NO_STOP_HINT=1.

Procedures

  • Slash commands — .claude/commands/*.md, skills — .claude/skills/*/SKILL.md. Read the skill before the task, not after. Content work (class, spell, build, magic item, feat, weapon) — skill add-content, which also covers files and schemaVersion migrations.
  • Plans: phases live in ~/.claude/projects/.../memory/project_*_plan.md, index in MEMORY.md; a new chat starts with «начать фазу X-N», a closed phase is marked **done**.
  • Rules math changed (rules.js, AC/saves/slots/rest/concentration, data.js tables) → subagent dnd-rules: checks against the Player's Handbook via local PDFs (tools/phb-search.py), returns a verdict, edits nothing. Manual call — /rules [function|file].
  • Delegate mechanical routine to cheaper models: releaser (sonnet), relpost (haiku), content (sonnet), verifier (sonnet), repo search via Explore with model: "sonnet". Planning, architecture, bug analysis and content decisions stay in the main chat.

Commit conventions

тип(scope): описание in Russian, types feat / fix / chore, releases prefixed vX.Y.Z:. Create commits only when the user asks.

Never

  • No bundler, no npm runtime dependencies — everything stays vanilla.
  • No changes to assets/ or static files without bumping CACHE_NAME in sw.js.
  • No commits without an explicit request.