Commit Graph
100 Commits
Author SHA1 Message Date
Lukas 934d98025e chore(deps): suppress two new unreachable undici advisories
GHSA-vxpw-j846-p89q (WebSocket DoS via fragment count bypass) and
GHSA-hm92-r4w5-c3mj (SOCKS5 proxy pool cross-origin reuse) just
landed in the registry. Both are fixed in undici>=7.28.0 and both
sit in code paths we don't exercise from tests (no WebSocket
client, no SOCKS5 proxy). Same blocker as GHSA-vmh5-mc38-953g:
jsdom@29.1.1 reaches into undici 7's private module layout, so
we can't move the pin to 7.28+. Added them to the existing
ignoreGhsas list and consolidated the per-entry notes.
2026-06-19 16:51:56 +02:00
Lukas 3b2fb99b37 Fix duplicate player character ids after page reload
The PC id counter lived in a module-level let that reset to 0 on
every page load. After rehydrating PCs from localStorage, the next
create would hand out pc-1 again, colliding with an existing id.
That broke React's keyed reconciliation and caused the wrong PC
to be deleted (deletePlayerCharacter matches the first occurrence
of the id, so deleting the new pc-1 would remove the rehydrated
one instead).

Derive the next id from the max numeric suffix of existing
characters at the moment of creation. No more shared counter, so
no more reset on reload and no collision after import.
2026-06-19 16:36:20 +02:00
Lukas 111b464da5 Add Centaur Youth to bundled bestiary under Homebrew source
CR 1/4 Medium Fey with Gallop (advantage-cancelling skirmisher
trait) and Charge (bonus 1d6 on a 15 ft. straight-line melee),
matching the centaur PC traits players already have access to.
2026-06-19 16:30:01 +02:00
Lukas a97ffe5ed1 chore(deps): bump vite, jsdom; pin undici and suppress unreachable advisory
Bumps vite ^8.0.5 → ^8.0.16 (GHSA-fx2h-pf6j-xcff, server.fs.deny
bypass on Windows) and jsdom ^29.0.1 → ^29.1.1 to unblock the
pre-commit audit gate.

The existing >=7.24.0 undici override was floating to 8.x, which
broke jsdom (it reaches into undici 7's private module layout).
Tightened to ~7.24.0 to keep jsdom working. That leaves
GHSA-vmh5-mc38-953g (undici SOCKS5 ProxyAgent TLS bypass) open —
patched in 7.28+ but we can't move there until jsdom updates its
pin. We never use a SOCKS5 proxy in tests, so the vulnerable code
path is unreachable. Added an auditConfig.ignoreGhsas entry with
a note explaining the rationale and the condition for removing it.
2026-06-19 16:29:42 +02:00
LukasandClaude Opus 4.7 1930473753 Bundle The Great Labors bestiary (27 creatures)
CI / check (push) Successful in 2m54s
CI / build-image (push) Successful in 36s
Adds the monsters from appendix B (pages 163-199) of The Great Labors:
Anarch Boar, Blemys, Bronze Automaton/Strategos, Cerberus/Young Cerberus,
Empusa, Goatling/Trickster, Gygan, Keledone, Maenad, Thylean Manticore,
Marble Golem, Minotaur Berserker/Warrior, the three mythic beasts
(White Stag, Golden Lion, Golden Ram), the five nymph lineages
(Aurae, Naiad, Nereid, Oceanid, Oread), Satyr Minstrel, and
Soldier/Soldier Captain.

Generated by scripts/extract-great-labors.py from the source PDF.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 15:50:15 +02:00
LukasandClaude Opus 4.7 c343fd3cd0 Add bundled-bestiary mechanism for shipping creatures with the app
D&D creatures listed in data/bestiary/dnd-bundled.json are now merged into
the search index and pre-loaded into creatureMap, so they appear alongside
5etools creatures with no "Load source" step. Source codes are derived from
the JSON itself (each creature carries source + sourceDisplayName), so adding
a new book is a pure data change. Bundled sources are excluded from
getAllSourceCodes() so bulk-import skips them, and they never appear in the
source manager (which only lists cached sources).

Includes a reference extractor (scripts/extract-great-labors.py) for the
5.5e revised stat-block format and a /bundle-bestiary skill that future
agents can follow to add monsters from other PDF books.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 15:49:34 +02:00
LukasandClaude Opus 4.6 d9fb271607 Add PF2e encounter difficulty calculation with 5-tier budget system
CI / check (push) Successful in 2m39s
CI / build-image (push) Successful in 18s
Implements PF2e encounter difficulty alongside the existing D&D system.
PF2e uses creature level vs party level to derive XP, compares against
5-tier budgets (Trivial/Low/Moderate/Severe/Extreme), and adjusts
thresholds for party size. The indicator shows 4 bars in PF2e mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 15:24:18 +02:00
LukasandClaude Opus 4.6 064af16f95 Fix persistent damage tag ordering and differentiate condition icons
CI / check (push) Successful in 2m39s
CI / build-image (push) Successful in 18s
- Render persistent damage tags before the "+" button, not after
- Use insertion order for conditions on the row instead of definition order
- Differentiate Undetected condition (EyeClosed/slate) from Invisible (Ghost/violet)
- Use purple for void persistent damage to distinguish from violet conditions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 13:06:31 +02:00
LukasandClaude Opus 4.6 0f640601b6 Add force, void, spirit, vitality, and piercing persistent damage types
CI / check (push) Successful in 2m39s
CI / build-image (push) Successful in 19s
Expands persistent damage from 7 to 12 types to cover all PF2e damage
types that have verified persistent damage sources in published content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 12:44:03 +02:00
LukasandClaude Opus 4.6 4b1c1deda2 Add PF2e persistent damage condition tags
CI / check (push) Successful in 2m39s
CI / build-image (push) Successful in 19s
Persistent damage displayed as compact tags with damage type icon and
formula (e.g., Flame + "2d6"). Supports fire, bleed, acid, cold,
electricity, poison, and mental types. One instance per type, added via
sub-picker in the condition picker. PF2e only, persists across reload.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 12:09:31 +02:00
LukasandClaude Opus 4.6 09a801487d Add PF2e weak/elite creature adjustments with stat block toggle
CI / check (push) Successful in 2m32s
CI / build-image (push) Successful in 19s
Weak/Normal/Elite toggle in PF2e stat block header applies standard
adjustments (level, AC, HP, saves, Perception, attacks, damage) to
individual combatants. Adjusted stats are highlighted blue (elite) or
red (weak). Persisted via creatureAdjustment field on Combatant.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 02:24:30 +02:00
LukasandClaude Opus 4.6 a44f82127e Add PF2e attack effects, ability frequency, and perception details
CI / check (push) Successful in 2m31s
CI / build-image (push) Successful in 17s
Show inline on-hit effects on attack lines (e.g., "plus Grab"), frequency
limits on abilities (e.g., "(1/day)"), and perception details text alongside
senses. Strip redundant frequency lines from Foundry descriptions.

Also add resilient PF2e source fetching: batched requests with retry,
graceful handling of ad-blocker-blocked creature files (partial success
with toast warning and re-fetch prompt for missing creatures).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 23:37:30 +02:00
LukasandClaude Opus 4.6 c3707cf0b6 Add PF2e attack effects, ability frequency, and perception details
Show inline on-hit effects on attack lines (e.g., "plus Grab"), frequency
limits on abilities (e.g., "(1/day)"), and perception details text alongside
senses. Strip redundant frequency lines from Foundry descriptions.

Also add resilient PF2e source fetching: batched requests with retry,
graceful handling of ad-blocker-blocked creature files (partial success
with toast warning and re-fetch prompt for missing creatures).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 23:37:03 +02:00
LukasandClaude Opus 4.6 1eaeecad32 Add PF2e equipment display with detail popovers in stat blocks
CI / check (push) Successful in 2m31s
CI / build-image (push) Successful in 17s
Extract shared DetailPopover shell from spell popovers. Normalize
weapon/consumable/equipment/armor items from Foundry data into
mundane (Items line) and detailed (Equipment section with clickable
popovers). Scrolls/wands show embedded spell info. Bump IDB cache v7.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 21:11:54 +02:00
LukasandClaude Opus 4.6 e2e8297c95 Add Recall Knowledge DC and skill to PF2e stat blocks
CI / check (push) Successful in 2m29s
CI / build-image (push) Successful in 19s
Display Recall Knowledge line below trait tags showing DC (from level
via standard DC-by-level table, adjusted for rarity) and associated
skill derived from creature type trait. Omitted for D&D creatures and
creatures with no recognized type trait.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:43:49 +02:00
LukasandClaude Opus 4.6 e161645228 Add PF2e spell description popovers in stat blocks
CI / check (push) Successful in 2m31s
CI / build-image (push) Successful in 26s
Clicking a spell name in a PF2e creature's stat block now opens a
popover (desktop) or bottom sheet (mobile) showing full spell details:
description, traits, rank, range, target, area, duration, defense,
action cost icons, and heightening rules. All data is sourced from
the embedded Foundry VTT spell items already in the bestiary cache.

- Add SpellReference type replacing bare string spell arrays
- Extract full spell data in pf2e-bestiary-adapter (description,
  traits, traditions, range, target, area, duration, defense,
  action cost, heightening, overlays)
- Strip inline heightening text from descriptions to avoid duplication
- Bold save outcome labels (Critical Success/Failure) in descriptions
- Bump DB_VERSION to 6 for cache invalidation
- Add useSwipeToDismissDown hook for mobile bottom sheet
- Portal popover to document.body to escape transformed ancestors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:18:08 +02:00
LukasandClaude Opus 4.6 9b0cb38897 Fix oxlint --deny-warnings and eliminate all biome-ignores
--deny warnings was a no-op (not a valid category); the correct flag
is --deny-warnings. Fixed all 8 pre-existing warnings and removed
every biome-ignore from source and test files. Simplified the check
script to zero-tolerance: any biome-ignore now fails the build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:17:30 +02:00
LukasandClaude Opus 4.6 5cb5721a6f Redesign PF2e action icons with diamond-parallel geometry
CI / check (push) Successful in 2m27s
CI / build-image (push) Successful in 18s
Align cutout edges to 45° angles parallel to outer diamond shape.
Multi-action icons use outlined diamonds with matched border width.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 01:07:45 +02:00
LukasandClaude Opus 4.6 48795071f7 Hide concentration UI in PF2e mode
CI / check (push) Successful in 2m26s
CI / build-image (push) Successful in 18s
PF2e uses action-based spell sustaining, not damage-triggered
concentration checks. The Brain icon, purple border accent, and
damage pulse animation are now hidden when PF2e is active, and
the freed gutter column is reclaimed for row content. Concentration
state is preserved so switching back to D&D restores it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 00:25:54 +02:00
LukasandClaude Opus 4.6 f721d7e5da Allow /commit skill to be invoked by other skills
CI / check (push) Successful in 2m26s
CI / build-image (push) Successful in 5s
Remove disable-model-invocation so /ship can delegate to /commit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 00:13:59 +02:00
LukasandClaude Opus 4.6 e7930a1431 Add /ship skill for commit, tag, and push workflow
CI / check (push) Successful in 2m27s
CI / build-image (push) Successful in 18s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 00:09:03 +02:00
LukasandClaude Opus 4.6 553e09f280 Enforce maximum values for PF2e numbered conditions
Cap dying (4), doomed (3), wounded (3), and slowed (3) at their
rule-defined maximums. The domain clamps values in setConditionValue
and the condition picker disables the [+] button at the cap.

Closes #31

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 00:04:47 +02:00
LukasandClaude Opus 4.6 1c107a500b Switch PF2e data source from Pf2eTools to Foundry VTT PF2e
CI / check (push) Successful in 2m25s
CI / build-image (push) Successful in 23s
Replace the stagnant Pf2eTools bestiary with Foundry VTT PF2e system
data (github.com/foundryvtt/pf2e, v13-dev branch). This gives us 4,355
remaster-era creatures across 49 sources including Monster Core 1+2 and
all adventure paths.

Changes:
- Rewrite index generation script to walk Foundry pack directories
- Rewrite PF2e normalization adapter for Foundry JSON shape (system.*
  fields, items[] for attacks/abilities/spells)
- Add stripFoundryTags utility for Foundry HTML + enrichment syntax
- Implement multi-file source fetching (one request per creature file)
- Add spellcasting section to PF2e stat block (ranked spells + cantrips)
- Add saveConditional and hpDetails to PF2e domain type and stat block
- Add size and rarity to PF2e trait tags
- Filter redundant glossary abilities (healing when in hp.details,
  spell mechanic reminders, allSaves duplicates)
- Add PF2e stat block component tests (22 tests)
- Bump IndexedDB cache version to 5 for clean migration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 21:05:00 +02:00
LukasandClaude Opus 4.6 0c235112ee Improve PF2e stat block action icons, triggers, and tag handling
- Replace unicode action cost chars with custom SVG icons (diamond
  with chevron for actions, outlined diamond for free, curved arrow
  for reaction) rendered inline via ActivityCost on TraitBlock
- Add activity icons to attacks (all Strikes default to single action)
- Add trigger/effect rendering for reaction abilities (bold labels)
- Fix nested tag stripping ({@b ...{@spell ...}...}) by looping
- Move icon after ability name to match AoN format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 10:36:30 +02:00
LukasandClaude Opus 4.6 57278e0c82 Add PF2e action cost icons to ability names
CI / check (push) Successful in 2m21s
CI / build-image (push) Successful in 17s
Show Unicode action icons (◆/◆◆/◆◆◆ for actions, ◇ for free,
↺ for reaction) in ability names from the activity field.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 16:31:24 +02:00
LukasandClaude Opus 4.6 f9cfaa2570 Include traits on PF2e ability blocks
Parse and display traits (concentrate, divine, polymorph, etc.)
on ability entries, matching how attack traits are already shown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 16:29:08 +02:00
LukasandClaude Opus 4.6 3e62e54274 Strip all angle brackets in PF2e attack traits and damage
CI / check (push) Successful in 2m23s
CI / build-image (push) Successful in 17s
Broaden stripDiceBrackets to stripAngleBrackets to handle all
PF2e tools angle-bracket formatting (e.g. <10 feet>, <15 feet>),
not just dice notation. Also strip in damage text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:34:28 +02:00
LukasandClaude Opus 4.6 12a089dfd7 Fix PF2e condition tooltip descriptions and sort picker alphabetically
Correct inaccurate PF2e condition descriptions against official AoN
rules (blinded, deafened, confused, grabbed, hidden, paralyzed,
unconscious, drained, fascinated, enfeebled, stunned). Sort condition
picker alphabetically per game system.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:29:49 +02:00
LukasandClaude Opus 4.6 65e4db153b Fix PF2e stat block senses and attack trait rendering
CI / check (push) Successful in 2m20s
CI / build-image (push) Successful in 17s
- Format senses with type (imprecise/precise) and range in feet,
  and strip {@ability} tags (e.g. tremorsense)
- Strip angle-bracket dice notation in attack traits (<d8> → d8)
- Fix existing weakness/resistance tests to nest under defenses
- Fix non-null assertions in 5e bestiary adapter tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:23:08 +02:00
LukasandClaude Opus 4.6 8dbff66ce1 Fix "undefined" in PF2e stat block weaknesses/resistances
CI / check (push) Successful in 2m23s
CI / build-image (push) Successful in 30s
Some PF2e creatures (e.g. Giant Mining Bee) have qualitative
weaknesses without a numeric amount, causing "undefined" to
render in the stat block. Handle missing amounts gracefully.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:06:22 +02:00
LukasandClaude Opus 4.6 e62c49434c Add Pathfinder 2e game system mode
CI / check (push) Successful in 2m21s
CI / build-image (push) Successful in 24s
Implements PF2e as an alternative game system alongside D&D 5e/5.5e.
Settings modal "Game System" selector switches conditions, bestiary,
stat block layout, and initiative calculation between systems.

- Valued conditions with increment/decrement UX (Clumsy 2, Frightened 3)
- 2,502 PF2e creatures from bundled search index (77 sources)
- PF2e stat block: level, traits, Perception, Fort/Ref/Will, ability mods
- Perception-based initiative rolling
- System-scoped source cache (D&D and PF2e sources don't collide)
- Backwards-compatible condition rehydration (ConditionId[] → ConditionEntry[])
- Difficulty indicator hidden in PF2e mode (excluded from MVP)

Closes dostulata/initiative#19

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 01:26:22 +02:00
LukasandClaude Opus 4.6 8f6eebc43b Render structured list and table entries in stat block traits
CI / check (push) Successful in 2m21s
CI / build-image (push) Successful in 17s
Stat block traits containing 5etools list (e.g. Confusing Burble d4
effects) or table entries were silently dropped. The adapter now
produces structured TraitSegment[] instead of flat text, preserving
lists and tables as first-class data. The stat block component renders
labeled list items inline (bold label + flowing text) matching the
5etools layout. Also fixes support for the singular "entry" field on
list items and bumps the bestiary cache version to force re-normalize.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:09:11 +02:00
LukasandClaude Opus 4.6 817cfddabc Add 2014 DMG encounter difficulty calculation
CI / check (push) Successful in 2m18s
CI / build-image (push) Successful in 17s
Support the 2014 DMG encounter difficulty as an alternative to the 5.5e
system behind the existing Rules Edition toggle. The 2014 system uses
Easy/Medium/Hard/Deadly thresholds, an encounter multiplier based on
monster count, and party size adjustment (×0.5–×5 range).

- Extract RulesEdition to its own domain module
- Refactor DifficultyTier to abstract numeric values (0–3)
- Restructure DifficultyResult with thresholds array
- Add 2014 XP thresholds table and encounter multiplier logic
- Wire edition from context into difficulty hooks
- Edition-aware labels in indicator and breakdown panel
- Show multiplier, adjusted XP, and party size note for 2014
- Rename settings label from "Conditions" to "Rules Edition"
- Update spec 008 with issue #23 requirements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 14:52:23 +02:00
LukasandClaude Opus 4.6 94e1806112 Add combatant side assignment for encounter difficulty
CI / check (push) Successful in 2m18s
CI / build-image (push) Successful in 17s
Combatants can now be assigned to party or enemy side via a toggle
in the difficulty breakdown panel. Party-side NPCs subtract their XP
from the encounter total, letting allied NPCs reduce difficulty.
PCs default to party, non-PCs to enemy — users who don't use sides
see no change. Side persists across reload and export/import.

Closes #22

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:15:12 +02:00
LukasandClaude Opus 4.6 30e7ed4121 Stabilize turn navigation bar layout with CSS grid
CI / check (push) Successful in 2m18s
CI / build-image (push) Successful in 17s
Use a three-column grid (1fr / auto / 1fr) so the active combatant
name stays centered while round badge and difficulty indicator are
anchored in the left and right zones. Prevents layout jumps when
the name changes between turns.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 02:15:16 +02:00
LukasandClaude Opus 4.6 5540baf14c Show concentration icon on mobile as grey affordance
On touch devices, the Brain icon was fully hidden (opacity-0) unlike
the edit and condition buttons. Add pointer-coarse:opacity-50 so it
appears as a discoverable grey icon, matching the other action buttons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 01:02:16 +02:00
LukasandClaude Opus 4.6 1ae9e12cff Add manual CR assignment and difficulty breakdown panel
CI / check (push) Successful in 2m20s
CI / build-image (push) Successful in 17s
Implement issue #21: custom combatants can now have a challenge rating
assigned via a new breakdown panel, opened by tapping the difficulty
indicator. Bestiary-linked combatants show read-only CR with source name;
custom combatants get a CR picker with all standard 5e values. CR persists
across reloads and round-trips through JSON export/import.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 17:03:33 +02:00
LukasandClaude Opus 4.6 2c643cc98b Introduce adapter injection and migrate test suite
CI / check (push) Successful in 2m13s
CI / build-image (push) Has been skipped
Replace direct adapter/persistence imports with context-based injection
(AdapterContext + useAdapters) so tests use in-memory implementations
instead of vi.mock. Migrate component tests from context mocking to
AllProviders with real hooks. Extract export/import logic from ActionBar
into useEncounterExportImport hook. Add bestiary-cache and
bestiary-index-adapter test suites. Raise adapter coverage thresholds
(68→80 lines, 56→62 branches).

77 test files, 891 tests, all passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 23:55:45 +02:00
LukasandClaude Opus 4.6 228c1c667f Fix bestiary creatures with zero HP silently failing to add
CI / check (push) Successful in 2m7s
CI / build-image (push) Successful in 23s
Bestiary sources like AWM store 0 for unknown HP. Passing maxHp: 0
into addCombatant triggered domain validation rejection, silently
dropping the creature. Treat hp: 0 as undefined, matching existing
ac: 0 handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:15:38 +02:00
LukasandClaude Opus 4.6 300d4b1f73 Convert /commit command to skill
Adds disable-model-invocation and allowed-tools restrictions
that structurally enforce commit safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:32:19 +02:00
LukasandClaude Opus 4.6 43546aaa7b Add artifact lifecycle guidance to constitution (v3.2.0)
CI / check (push) Successful in 2m8s
CI / build-image (push) Has been skipped
Clarify that spec.md is a living capability document, plan.md/tasks.md
are bounded work packages, and tests are the executable ground truth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 01:06:35 +02:00
LukasandClaude Opus 4.6 09da9a8dfc Reduce pre-commit context noise, gitignore agent artifacts
Slim Vitest pre-commit output with dot reporter and coverage summary.
Ignore .agent-tests/ and docs/agents/research/ in git.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:57:01 +02:00
LukasandClaude Opus 4.6 b229a0dac7 Add missing component and hook tests, raise coverage thresholds
13 new test files for untested components (color-palette, player-management,
stat-block, settings-modal, export/import dialogs, bulk-import-prompt,
source-fetch-prompt, player-character-section) and hooks (use-long-press,
use-swipe-to-dismiss, use-bulk-import, use-initiative-rolls). Expand
combatant-row tests with inline editing, HP popover, and condition picker.

Component coverage: 59% → 80% lines, 55% → 71% branches
Hook coverage: 72% → 83% lines, 55% → 66% branches

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:55:21 +02:00
LukasandClaude Opus 4.6 08b5db81ad Add /commit skill to bypass sandbox for Lefthook hooks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:18:27 +02:00
LukasandClaude Opus 4.6 a89fac5c23 Slim CLAUDE.md with progressive disclosure, add project purpose
Move niche conventions (component props, export compat) to
docs/conventions.md, trim Speckit/Constitution sections to link to
source files, and add a one-line project description.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:07:18 +02:00
LukasandClaude Opus 4.6 b6ee4c8c86 Fix oxlint warnings, extract dialog polyfill, deny warnings in gate
CI / check (push) Successful in 1m38s
CI / build-image (push) Has been skipped
Adds void to floating promise in bestiary-cache.ts, extracts shared
polyfillDialog() helper to eliminate unbound-method warnings in 3 test
files. Adds --deny warnings to oxlint so future warnings fail the
build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:38:57 +02:00
LukasandClaude Opus 4.6 c295840b7b Update CLAUDE.md for jsinspect, TS compiler props, parallel lefthook
CI / check (push) Successful in 1m39s
CI / build-image (push) Has been skipped
Adds jsinspect to check description and tech stack, removes incorrect
routing mention, notes prop checker uses TS compiler API, updates
quality gates to reflect parallel lefthook jobs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:29:48 +02:00
LukasandClaude Opus 4.6 d13641152f Update README with setup guide, contributing workflow, and bestiary docs
Fixes packages/app → packages/application path, expands scripts table,
documents the parallel merge gate, adds contributing workflow with
spec-driven process and Claude Code skills, and documents bestiary
index regeneration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:48:11 +02:00
LukasandClaude Opus 4.6 110f4726ae Add tests for Dialog and Tooltip, raise components/ui threshold to 93%
Dialog: open/close lifecycle, cancel event handling, DialogHeader.
Tooltip: show on pointer enter, hide on pointer leave. Raises
components/ui coverage threshold to enforce testing of future
primitives.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 17:22:17 +02:00
LukasandClaude Opus 4.6 2bc22369ce Add tests for ConditionTags and CreatePlayerModal
ConditionTags: rendering, remove callback, add picker callback.
CreatePlayerModal: create/edit modes, form validation (name, AC, HP,
level), error display and clearing, onSave/onClose callbacks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:36:07 +02:00
LukasandClaude Opus 4.6 2971d32f45 Add action-bar tests for overflow menu, dialogs, and custom stats
Tests browse mode toggle, export/import dialog opening, overflow menu
callbacks (manage players, settings), and custom stat field submission.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 03:26:57 +02:00
LukasandClaude Opus 4.6 a97044ec3e Add tests for useActionBarState hook
Tests search/suggestion filtering, queued creature counting, form
submission with custom stats, browse mode, and dismiss/clear behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 00:16:54 +01:00
LukasandClaude Opus 4.6 a77db0eeee Add quick-win tests for components and hooks
Adds tests for DifficultyIndicator, Toast, RollModeMenu, OverflowMenu,
useTheme, and useRulesEdition. Covers rendering, user interactions,
auto-dismiss timers, external store sync, and localStorage persistence.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:32:15 +01:00
LukasandClaude Opus 4.6 d8c8a0c44d Add direct reducer tests for encounterReducer
Exports encounterReducer and EncounterState for testing. Adds 26
pure-function tests covering all action types: CRUD, turn navigation,
HP/AC/conditions, undo/redo, bestiary add with auto-numbering,
player character add, import, and event accumulation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:50:45 +01:00
LukasandClaude Opus 4.6 80dd68752e Refactor useEncounter from useState to useReducer
Replaces 18 useCallback wrappers with a typed action union and
encounterReducer. Undo/redo wrapping is now systematic per-case in
the reducer instead of ad-hoc per operation. Complex cases (undo/redo,
bestiary add, player character add) are extracted into helper functions.

The stat block auto-show on bestiary add now uses lastCreatureId from
reducer state instead of the synchronous return value, with a useEffect
in use-action-bar-state to react to changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:41:40 +01:00
LukasandClaude Opus 4.6 896fd427ed Add tests for undo/redo/setTempHp use cases, fix coverage thresholds
Adds missing tests for undoUseCase, redoUseCase, and setTempHpUseCase,
bringing application layer coverage from ~81% to 97%. Removes
autoUpdate from coverage thresholds and sets floors to actual values
so they enforce a real minimum.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:19:15 +01:00
LukasandClaude Opus 4.6 01b1bba6d6 Replace regex prop counter with TypeScript compiler API
Uses ts.createProgram to parse real AST instead of regex + brace-depth
state machine. Immune to comments, strings, and complex type syntax.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:11:34 +01:00
LukasandClaude Opus 4.6 b7a97c3d88 Parallelize pre-commit checks via lefthook jobs
Independent checks (audit, knip, biome, jscpd, jsinspect, custom
scripts) now run in parallel. Type-dependent checks (oxlint, vitest)
remain sequential after tsc --build via a piped group. Also reorder
pnpm check for fast-fail on cheap checks first.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:07:38 +01:00
LukasandClaude Opus 4.6 1de00e3d8e Move entity rehydration to domain layer, fix tempHp gap
CI / check (push) Successful in 1m16s
CI / build-image (push) Has been skipped
Rehydration functions (reconstructing typed domain objects from untyped
JSON) lived in persistence adapters, duplicating domain validation.
Adding a field required updating both the domain type and a separate
adapter function — the adapter was missed for `level`, silently dropping
it on reload. Now adding a field only requires updating the domain type
and its co-located rehydration function.

- Add `rehydratePlayerCharacter` and `rehydrateCombatant` to domain
- Persistence adapters delegate to domain instead of reimplementing
- Add `tempHp` validation (was silently dropped during rehydration)
- Tighten initiative validation to integer-only
- Exhaustive domain tests (53 cases); adapter tests slimmed to round-trip
- Remove stale `jsinspect-plus` Knip ignoreDependencies entry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:12:41 +01:00
LukasandClaude Opus 4.6 f4fb69dbc7 Add jsinspect-plus structural duplication gate, extract shared helpers
CI / check (push) Successful in 1m13s
CI / build-image (push) Has been skipped
Add jsinspect-plus (AST-based structural duplication detector) to pnpm
check with threshold 50 / min 3 instances. Fix all findings:

- Extract condition icon/color maps to shared condition-styles.ts
- Extract useClickOutside hook (5 components)
- Extract dispatchAction + resolveAndRename in use-encounter
- Extract runEncounterAction in application layer (13 use cases)
- Extract findCombatant helper in domain (9 functions)
- Extract TraitSection in stat-block (4 trait rendering blocks)
- Extract DialogHeader in dialog.tsx (4 dialogs)

Net result: -263 lines across 40 files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 02:16:54 +01:00
LukasandClaude Opus 4.6 ef76b9c90b Add encounter difficulty indicator (5.5e XP budget)
CI / check (push) Successful in 1m13s
CI / build-image (push) Successful in 16s
Live 3-bar difficulty indicator in the top bar showing encounter
difficulty (Trivial/Low/Moderate/High) based on the 2024 5.5e XP
budget system. Automatically derived from PC levels and bestiary
creature CRs.

- Add optional level field (1-20) to PlayerCharacter
- Add CR-to-XP and XP Budget per Character lookup tables in domain
- Add calculateEncounterDifficulty pure function
- Add DifficultyIndicator component with color-coded bars and tooltip
- Add useDifficulty hook composing encounter, PC, and bestiary contexts
- Indicator hidden when no PCs with levels or no bestiary-linked monsters
- Level field in PC create/edit forms, persisted in storage

Closes #18

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:55:48 +01:00
LukasandClaude Opus 4.6 36122b500b Add import/export to README, research scope guidance to CLAUDE.md
CI / check (push) Successful in 1m11s
CI / build-image (push) Successful in 16s
Add import/export feature bullet to README.md (constitution requires
README updates when user-facing capabilities change). Add research
scope note to CLAUDE.md RPI section: research phases should scan for
existing patterns and consolidation opportunities, not just what the
feature needs. Remove auto-generated Active Technologies / Recent
Changes sections that duplicated Tech Stack.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:04:32 +01:00
LukasandClaude Opus 4.6 f4355a8675 Add optional export filename, tests for post-implement features
Add optional filename field to export dialog with automatic .json
extension handling. Extract resolveFilename() for testability. Add
tests for includeHistory flag, bundleToJson, and filename resolution.
Add export format compatibility note to CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:42:50 +01:00
LukasandClaude Opus 4.6 209df13c32 Add export method dialog, extract shared Dialog primitive
Add export dialog with download/clipboard options and optional
undo/redo history inclusion (default off). Extract shared Dialog
component to ui/dialog.tsx, consolidating open/close lifecycle,
backdrop click, and escape key handling from all 6 dialog components.
Update spec to reflect export method dialog and optional history.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:57:31 +01:00
LukasandClaude Opus 4.6 4969ed069b Add import method dialog with file upload and paste options
Replace direct file picker trigger with a modal offering two import
methods: file upload and paste JSON content. Uses a textarea instead
of navigator.clipboard.readText() to avoid browser permission prompts.
Also centers both import dialogs and updates spec for clipboard import.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:43:22 +01:00
LukasandClaude Opus 4.6 fba83bebd6 Add JSON import/export for full encounter state
Export and import encounter, undo/redo history, and player characters
as a downloadable .json file. Export/import actions are in the action
bar overflow menu. Import validates using existing rehydration functions
and shows a confirmation dialog when replacing a non-empty encounter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:28:39 +01:00
LukasandClaude Opus 4.6 f6766b729d Rename spec 037-undo-redo to 006-undo-redo for sequential numbering
Delete merged feature branches (005–037) that inflated the auto-increment
counter in create-new-feature.sh, and renumber the undo-redo spec to
follow the existing 001–005 sequence.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:32:29 +01:00
LukasandClaude Opus 4.6 f10c67a5ba Dismiss side panel when encounter becomes empty
CI / check (push) Successful in 1m7s
CI / build-image (push) Successful in 15s
Closes the stat block / source manager panel when the last combatant
is removed or the encounter is cleared, giving a fully clean state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:16:32 +01:00
LukasandClaude Opus 4.6 9437272fe0 Batch bestiary add produces a single undo entry
CI / check (push) Successful in 1m10s
CI / build-image (push) Successful in 15s
Extract addOneFromBestiary (no undo) and build addMultipleFromBestiary
on top so confirming N creatures from the bestiary panel creates one
undo entry that restores the entire batch, not N individual entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:07:25 +01:00
LukasandClaude Opus 4.6 541e04b732 Wrap initiative rolls with undo so they produce undo entries
Initiative rolls (single and bulk) called makeStore() directly from
useInitiativeRolls, bypassing the withUndo wrapper. Expose withUndo
from the encounter context and wrap both roll paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:06:50 +01:00
LukasandClaude Opus 4.6 e9fd896934 Clean up gitignore and CLAUDE.md
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 30s
Add .rodney/ to gitignore. Remove redundant Active Technologies and
Recent Changes sections from CLAUDE.md — info already covered by
Tech Stack and Data & Storage sections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:36:52 +01:00
LukasandClaude Opus 4.6 29cdd19cab Roll back renames on failed compound add operations
addFromBestiary and addFromPlayerCharacter rename existing combatants
before adding the new one. If the add fails, the renames were applied
without an undo entry. Restore the pre-operation snapshot on failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:31:11 +01:00
LukasandClaude Opus 4.6 17cc6ed72c Add undo/redo for all encounter actions
Memento-based undo/redo with full encounter snapshots. Undo stack
capped at 50 entries, persisted to localStorage. Triggered via
buttons in the top bar (inboard of turn navigation) and keyboard
shortcuts (Ctrl+Z / Ctrl+Shift+Z, Cmd on Mac, case-insensitive key
matching). Clear encounter resets both stacks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:30:33 +01:00
LukasandClaude Opus 4.6 9d81c8ad27 Atomic addCombatant with optional CombatantInit bag
addCombatant now accepts an optional init parameter for pre-filled stats
(HP, AC, initiative, creatureId, color, icon, playerCharacterId), making
combatant creation a single atomic operation with domain validation.

This eliminates the multi-step store.save() bypass in addFromBestiary and
addFromPlayerCharacter, and removes the CombatantOpts/applyCombatantOpts
helpers. Also extracts shared initiative sort logic into initiative-sort.ts
used by both addCombatant and setInitiative.

Closes #15

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:13:20 +01:00
LukasandClaude Opus 4.6 7199b9d2d9 Add browser-interactive-testing skill and fix Biome/audit config
Integrate the rodney/showboat browser automation skill for headless
Chrome screenshots and testing. Exclude .rodney and .agent-tests
from Biome file scanning. Add picomatch override to resolve
high-severity ReDoS vulnerability in knip/jscpd transitive deps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:10:57 +01:00
LukasandClaude Opus 4.6 158bcf1468 Add ADRs for branded types, bestiary loading, and pre-commit gates
ADR-003: Branded types for compile-time identity safety at zero
runtime cost.
ADR-004: On-demand bestiary via compact index + IndexedDB cache,
avoiding distribution of copyrighted content.
ADR-005: All quality gates at pre-commit for tight agent feedback
loops, with analysis of per-change hooks as a future option.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:02:48 +01:00
LukasandClaude Opus 4.6 fab9301b20 Decompose ActionBar into hook and focused sub-components
CI / check (push) Successful in 1m7s
CI / build-image (push) Has been skipped
Extract useActionBarState hook with all search/queue/mode state and
handlers. Extract RollAllButton (context-consuming, zero props),
BrowseSuggestions, CustomStatFields, and refactor AddModeSuggestions
to use grouped SuggestionActions interface (11 props → 6).

ActionBar is now a ~120-line layout shell.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:41:35 +01:00
LukasandClaude Opus 4.6 d653cfe489 Add ADR template and first two architecture decision records
Document the errors-as-values pattern (ADR-001) and domain events
as plain data objects (ADR-002) to capture the reasoning behind
these foundational design choices.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:19:54 +01:00
LukasandClaude Opus 4.6 228a2603e8 Add Sapped and Slowed conditions for 5.5e weapon mastery
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 15s
These D&D 2024 weapon mastery conditions are edition-gated: they only
appear in the condition picker when 5.5e rules are selected. Applied
conditions still render correctly regardless of edition setting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:31:41 +01:00
LukasandClaude Opus 4.6 27ff8ba1ad Collapse hover-only buttons to zero width when hidden
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 16s
Edit and add-condition buttons now take no space when not hovered,
eliminating the gap between name and condition icons. They slide in
smoothly on hover with a 150ms transition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:19:47 +01:00
LukasandClaude Opus 4.6 4cfcefe6c3 Hide custom stat fields on mobile, fix action bar gap consistency
CI / check (push) Successful in 1m7s
CI / build-image (push) Successful in 16s
Init/AC/MaxHP inputs are hidden on phones — users set these values
directly in the combatant row after adding. Fixes uneven spacing
between action bar elements by using consistent gap-3.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:41:18 +01:00
Lukas 8baccf3cd3 Merge 006-mobile-touch-targets: mobile foundation and bug fixes
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 16s
- iOS zoom fix (16px input font)
- Safe area insets for notched phones
- viewport-fit=cover
- Action bar flex-wrap for narrow screens
- Slightly increased row padding on mobile
- Fix stat block panel showing wrong creature on first open
- Skip auto-opening stat block when adding on mobile
2026-03-24 23:26:33 +01:00
LukasandClaude Opus 4.6 a9ca31e9bc Skip auto-opening stat block panel when adding creatures on mobile
On desktop the panel has room alongside the combatant list, but on
mobile it covers the screen and disrupts the add-combatant flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:22:54 +01:00
LukasandClaude Opus 4.6 64a1f0b8db Add mobile foundation: iOS zoom fix, safe area insets, row padding
- Input base font 16px on mobile to prevent iOS Safari auto-zoom
- Safe area insets for notched phones (top/bottom bars)
- viewport-fit=cover to enable safe area env() values
- Action bar flex-wrap for custom stat field overflow
- Slightly increased row padding on mobile (py-3 sm:py-2)
- Removed redundant font-size classes from Input usages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:19:10 +01:00
LukasandClaude Opus 4.6 5e5812bcaa Fix stat block panel showing wrong creature on first open
useAutoStatBlock was overriding the user's creature selection when
the panel transitioned from closed to open. Now only auto-updates
when the active turn index changes (advance/retreat), not when the
panel mode changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:18:49 +01:00
LukasandClaude Opus 4.6 9e09c8ae2a Sync theme-color meta tag with active light/dark theme
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:59:13 +01:00
LukasandClaude Opus 4.6 4d0ec0c7b2 Add Open Graph meta tags for link previews in messengers
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 15s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:54:05 +01:00
LukasandClaude Opus 4.6 fe62f2eb2f Add PWA manifest, app icons, and favicon
D20-themed icon in app color scheme for home screen installation,
favicon, and apple-touch-icon. Standalone display mode makes the
app feel native when launched from home screen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:51:28 +01:00
LukasandClaude Opus 4.6 7092677273 Make layout full-width on mobile with docked top/bottom bars
Remove max-width constraint and horizontal padding on small screens
so content goes edge-to-edge. Turn navigation and action bar lose
rounded corners on mobile and dock flush to top/bottom edges.
Desktop layout (sm: and up) is unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:36:01 +01:00
LukasandClaude Opus 4.6 e1a06c9d59 Tighten combatant row grid on mobile for better name visibility
Reduce grid gap and initiative column width on small screens,
restoring full layout at the sm breakpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:35:42 +01:00
LukasandClaude Opus 4.6 4043612ccf Add rules edition setting for condition tooltips (5e/5.5e)
CI / check (push) Successful in 1m8s
CI / build-image (push) Successful in 16s
Introduce a settings modal (opened from the kebab menu) with a rules
edition selector for condition tooltip descriptions and a theme picker
replacing the inline cycle button. About half the conditions have
meaningful mechanical differences between editions.

- Add description5e field to ConditionDefinition with 5e (2014) text
- Add RulesEditionProvider context with localStorage persistence
- Create SettingsModal with Conditions and Theme sections
- Wire condition tooltips to edition-aware descriptions
- Fix 6 inaccurate 5.5e condition descriptions
- Update spec 003 with stories CC-3, CC-8 and FR-095–FR-102

Closes #12

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:08:41 +01:00
LukasandClaude Opus 4.6 cfd4aef724 Expand pre-2024 {@atk} tags to full attack type labels in stat blocks
Old 5etools data uses {@atk mw} instead of {@atkr m}, which the generic
tag handler was reducing to bare "mw" text. Adds dedicated handling for
all {@atk} variants and bumps the bestiary cache version to clear stale
processed data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:11:54 +01:00
LukasandClaude Opus 4.6 968cc7239b Downgrade Knip 6 to 5 for CI compatibility
CI / check (push) Successful in 1m6s
CI / build-image (push) Successful in 22s
Knip 6 uses oxc-parser which attempts a 6GB ArrayBuffer allocation
that fails on the CI runner (3.7GB RAM, no swap). This is a known
oxc allocator issue (oxc-project/oxc#20513) with no fix yet.
Revert to Knip 5 which uses TypeScript's parser. Also revert the
NODE_OPTIONS workaround since it's no longer needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:31:58 +01:00
LukasandClaude Opus 4.6 d9562f850c Inline NODE_OPTIONS for CI check step
CI / check (push) Failing after 18s
CI / build-image (push) Has been skipped
Step-level env may not propagate to pnpm subprocesses in Gitea
Actions. Inline the variable directly in the command instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:48:33 +01:00
LukasandClaude Opus 4.6 ec9f2e7877 Increase Node heap limit for CI check step
CI / check (push) Failing after 16s
CI / build-image (push) Has been skipped
oxc-parser (used by Knip) fails with ArrayBuffer allocation
error on the CI runner's default heap size. Set max-old-space-size
to 2048MB to accommodate the buffer allocation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:40:33 +01:00
LukasandClaude Opus 4.6 c4079c384b Fix initiative input clipping inside container
CI / check (push) Failing after 17s
CI / build-image (push) Has been skipped
Widen initiative grid column from 3rem to 3.5rem and use w-full
on the editing input so it fits within the rounded background
container without overflowing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:26:39 +01:00
LukasandClaude Opus 4.6 a4285fc415 Polish stat containers and optical alignment
Refine AC shield to use filled shape with border color instead of
stroke outline. Add subtle muted background to initiative container.
Apply optical vertical centering to round badge text (-3px) and
AC shield number (-2px). Unify round badge corners to rounded-md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:23:22 +01:00
LukasandClaude Opus 4.6 9c0e3398f1 Move AC shield next to initiative and refine shield style
Place AC between initiative and name to group static reference
stats on the left, leaving HP as the sole dynamic element on
the right. Dim the shield outline to 40% opacity so it recedes
visually, and nudge the number up 2px toward the visual center.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:54:20 +01:00
LukasandClaude Opus 4.6 9cdf004c15 Restyle HP display as compact rounded pill
Group current HP, temp HP, and max HP into a single bordered
pill container with a subtle slash separator. Removes the
scattered layout with separate elements and gaps. Temp HP +N
only renders when present (no invisible spacer).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:11:28 +01:00
LukasandClaude Opus 4.6 8bf69fd47d Add temporary hit points as a separate damage buffer
Temp HP absorbs damage before current HP, cannot be healed, and
does not stack (higher value wins). Displayed as cyan +N after
current HP with a Shield button in the HP adjustment popover.
Column space is reserved across all rows only when any combatant
has temp HP. Concentration pulse fires on any damage, including
damage fully absorbed by temp HP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 11:39:47 +01:00