- Level-up build-route advisor (src/features/characters/sheet/LevelUpAdvisor.tsx +
useLevelUpAdvisor): ~4 system-aware routes plus a custom one; choosing a route
expands it into concrete next-level steps. AI when configured, deterministic
fallback (src/lib/assistant/levelup.ts) otherwise. Embedded in the existing
HP-only LevelUpModal, which stays primary.
- Level-up prompts/schemas added to prompts.ts (buildRoutes/buildSteps), each
leading with the system constraint + class + next level.
- Campaign Insights section on the Assistant page renders deterministic themes,
with an optional 'ask the assistant to expand' affordance when AI is on.
levelup + prompt unit tests (4 routes both systems, system vocabulary, custom
route); e2e for the deterministic route→steps flow and the insights section.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- src/lib/assistant/prompts.ts: balanceSuggestionSchema + buildBalancePrompt
(system message leads with the grounding constraint; restricts choices to the
provided compendium candidates).
- useEncounterAdvisor hook: builds context → picks system-correct candidates →
asks the LLM (when configured) for a structured pick, validates + filters names
to the candidate set, else falls back to the deterministic buildSuggestedEncounter.
Apply adds the creatures transactionally via encountersRepo.mutate.
- EncounterTipCard in the combat tracker: leads with the detected difficulty
tendency (or the current difficulty), offers a one-click grounded suggestion
(AI or deterministic) with propose→confirm Apply.
prompts unit tests + e2e for both the deterministic apply flow and the AI path
(stubbed provider); the AI test also confirms candidate-grounding (only
shortlisted creatures survive).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- src/lib/assistant/context.ts: buildCampaignContext() assembles a system-aware
snapshot led by an explicit systemConstraint (anti cross-system hallucination),
party, recent encounters with computed difficulty, quest/note summaries.
pickCreatureCandidates() pulls level/CR-appropriate creatures from the correct
bestiary so LLM tips are grounded in real data.
- src/lib/assistant/patterns.ts: difficultyTendency() + detectThemes() classify
whether the DM's encounters skew too easy/hard, rating each fight against its
party-level snapshot.
- Encounter schema gains optional partyLevelsSnapshot + outcome (Dexie v7, additive).
Combat tracker snapshots PC levels at start and rates difficulty against them.
17 assistant unit tests (context + patterns).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Bring-your-own-key assistant config in a dedicated persisted store
(src/stores/assistantStore.ts); partialize drops the key from localStorage
when 'remember' is off. Key lives in localStorage only, so it's auto-excluded
from Dexie backups.
- Provider-agnostic LLM client (src/lib/llm) over fetch, no SDK: Anthropic
Messages + OpenAI-compatible Chat Completions (covers OpenAI/OpenRouter/
Ollama/LM Studio via custom base URL). Structured JSON output parsed +
Zod-validated; timeouts; typed error kinds; key never leaked in errors.
- Settings 'Assistant (AI)' section with provider/model/baseUrl/key, remember
+ enabled toggles, and Test connection.
- CSP connect-src widened to any https + localhost for the BYO endpoint.
10 client unit tests; settings e2e asserts config persists and the key is
never present in an exported backup.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Deterministic advisors (src/lib/assistant): party resources (downed/bloodied/
spent slots/rest nudges), session prep (dangling [[wiki links]], active quests,
empty journal), live combat hints (turn, downed combatants) — pure + tested
- Data-driven encounter builder: greedily assembles level/CR-appropriate monsters
to a target difficulty via the Phase-3 budget; one click builds + opens combat
- Assistant page: suggestion cards with one-click actions (goto, long rest,
create note); wired into routes, dashboard, command palette
- 8 advisor/builder unit tests + assistant e2e
Conversational LLM layer intentionally deferred (no provider/key in this env);
the deterministic advisor is the offline default per the plan.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Homebrew entity (monster/spell/item/feat/condition) — Dexie v6, repo, hook,
cascade-deleted with campaign
- Homebrew editor page: per-kind fields + description, create/edit/delete
- Compendium merges campaign homebrew of the matching kind (HB badge, generic
HomebrewDetail) with the same cross-links (add monster->combat, spell/item->character)
- Content packs: export/import homebrew as JSON (validated, ids reassigned)
- System extensibility documented via the existing RulesSystem registry seam
- Fix: card editors (homebrew/npc/quest/note) debounce-save the FULL snapshot, not
partial patches — editing two fields fast no longer drops an edit
New homebrew e2e + cascade test coverage.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Player View (/play): read-only projector screen — party HP bars + conditions,
active-encounter initiative with current turn; enemy HP hidden behind a
Healthy/Bloodied/Down status band; Fullscreen button
- SyncAdapter seam (src/lib/sync): local-first default via Dexie liveQuery;
documents where a future networked (WebSocket/CRDT) backend plugs in
- Dashboard + routes get a Player View entry
- Robustness: encountersRepo.mutate() does transactional read-modify-write so
rapid combat mutations can't overwrite each other (old C19 race); tracker uses it
New player-view e2e. Networked multiplayer backend intentionally deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Ability generation: standard array, point buy (27-pt, validated), 4d6kh3 roll;
AbilityGenModal with assign-from-pool + steppers (pure abilityGen lib + tests)
- Level-up flow: increment level, HP gain (average or roll hit die + CON)
- Print / save-to-PDF: print button + @media print hides app chrome and roll tray
- Plan: added Phase 11 (data-driven Assistant) to the roadmap
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Advantage/Disadvantage are now toggle modes (rollStore.mode) applied to d20
rolls everywhere (dice page, sheet skills/saves/attacks), preserving modifiers;
applyRollMode() rewrites the first d20 -> 2d20kh1/kl1
- addCombatant auto-numbers duplicate names (Goblin 1, Goblin 2, …); the first
duplicate also renames the original. Quantity add relies on this.
- Tests for applyRollMode + duplicate numbering
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Dice notation: exploding (Nd6!) and reroll-below (Nd6r2), capped + tested
- Degrees of success / roll-vs-DC (PF2e ±10 + nat 20/1 steps; 5e crit on nat 20/1)
- Global roll tray (shared store + RollTray in layout) with animated result + degree
- Roll from the character sheet: skills, saves, and attack to-hit/damage are
clickable and post to the tray + history (rollAndShow/rollCheck helpers)
- Saved roll macros per campaign (persisted) on the Dice page
10 new unit tests (notation explode/reroll, degrees), interactive-dice e2e.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Condition durations + auto-expiry: timed conditions tick down on the affected
combatant's turn and drop at 0 (engine tickConditions; UI rounds field + (Nr) chip)
- Initiative: Roll-all (d20 + per-combatant bonus, re-sort anchored) + group/quantity add
- Combat log: per-round event feed (turns, round changes, damage/heal, expiries,
removals) + in-memory Undo of the last change
- Encounter difficulty budget: 5e XP thresholds + PF2e level budget (pure lib +
tests); live difficulty/XP-award readout from monster combatants vs the party
- Combatants carry initBonus + cr/level; compendium add-to-combat passes them
18 new unit tests (durations, applyInitiatives, budget), new combat-depth e2e.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Scraped PF2e reference from Archives of Nethys ES into public/data/pf2e/
(spells, creatures, feats, equipment, weapons, armor, ancestries, heritages,
backgrounds, archetypes, actions, conditions, deities) via scripts/fetch_pf2e.ts
- Registry-driven compendium: system toggle + per-category nav + generic filters
- 5e expanded: weapons, armor, feats, conditions added alongside spells/monsters/items
- PF2e data served as static assets (fetched, not bundled) for fast native parse
- Cross-links: add spell->spellbook / item->inventory to a campaign character;
add monster/creature -> open encounter
- Condition tooltips in combat sourced from the conditions glossary
- Tests: registry filter unit tests, compendium e2e (browse + cross-link)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- System-aware condition list (5e PHB / pf2e) in src/lib/rules/conditions.ts
- Dropdown replaces free-text input; non-valued conditions add instantly,
valued ones (Exhaustion, Frightened N, etc.) show a value field, plus Custom
- Already-applied conditions disabled in the list; chips remain click-to-remove
- New e2e covering preset + valued add and tag removal
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Inventory + currency + encumbrance vs carrying capacity
- Class resources with correct short/long/daily rest recovery (applyRest)
- Spellcasting: slots (+pact), known/prepared spells, derived DC + attack
- Defenses: 5e death saves/inspiration/exhaustion, pf2e dying/wounded/hero points
- Derived weapon attacks + passive perception via extended RulesSystem
- Dexie v2 migration backfills new fields; debounced save flushes on pagehide
- 9 new unit tests, new character-depth e2e; all green
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>