# Mana Loop โ€” Project Architecture Guide for AI Agents This document provides everything an AI agent needs to work on this codebase safely and effectively. **Read it in full before writing a single line of code.** ## โš ๏ธ TERMINAL TOOL PROTOCOL After calling `run_command`, you MUST immediately call `get_process_status` with `wait: 30` in the SAME response. Never stop generating after a `status: "running"` result โ€” always follow up immediately. After ANY Edit tool call, immediately call read_file to verify the change is present. If it's not, use write_file instead. --- ## ๐Ÿ”‘ Git Credentials (SAVE THESE) **Repository:** `git@gitea.tailf367e3.ts.net:Anexim/Mana-Loop.git` **HTTPS URL with credentials:** ``` https://n8n-gitea:tkF9HFgxL2k4cmT@gitea.tailf367e3.ts.net/Anexim/Mana-Loop.git ``` **Credentials:** - **User:** n8n-gitea - **Email:** n8n-gitea@anexim.local - **Password:** tkF9HFgxL2k4cmT **To configure git:** ```bash git config --global user.name "n8n-gitea" git config --global user.email "n8n-gitea@anexim.local" ``` --- ## โš ๏ธ MANDATORY GIT WORKFLOW โ€” MUST BE FOLLOWED **Before starting ANY work, you MUST:** 1. **Pull the latest changes:** ```bash cd /home/user/repos/Mana-Loop && git pull origin master ``` 2. **Do your task** โ€” Make all necessary code changes 3. **Before finishing, commit and push:** ```bash cd /home/user/repos/Mana-Loop git add -A git commit -m "descriptive message about changes" git push origin master ``` This workflow is **enforced and non-negotiable**. Every session must start with `git pull` and end with `git push`. --- ## ๐ŸŽฏ CURRENT PRIORITY โ€” READ THIS FIRST Every session must start by reading the active strategy document to know what to work on: ```bash cat docs/strategy/overall-remediation-plan.md ``` The strategy defines the current phase and task queue. **Do not pick tasks on your own.** Always work on the highest-priority incomplete task from the strategy. Current active task queue (update this when the strategy changes): | # | Task | Status | |---|------|--------| | TASK-001 | Playwright setup + baseline E2E tests | โฌœ | | TASK-002 | Enchanting E2E tests (3-step flow) | โฌœ | | TASK-003 | Equipment E2E tests (equip, 2H block, unequip) | โฌœ | | TASK-004 | Combat E2E tests (cast, HP, floor advance) | โฌœ | | TASK-005 | `globals.css` design tokens | โฌœ | | TASK-006 | Left panel redesign | โฌœ | | TASK-007 | Skill system v2 (`computeStats` + migration) | โฌœ | | TASK-008 | Enchanting UI fix (store as source of truth) | โฌœ | | TASK-009 | Attunement expansion (new attunements + path choice) | โฌœ | | TASK-010 | Prestige rework (path bonuses) | โฌœ | | TASK-011 | Full UI redesign (remaining tabs) | โฌœ | --- ## ๐Ÿ”„ Crash Recovery Protocol If the agent's session ends mid-task, a fresh session **must** resume from where it left off, not restart. ### Saving progress (MANDATORY after every significant step): ``` Call save_progress with: task_id: "TASK-XXX-task-name" status: "in_progress" completed_steps: ["step 1 description", "step 2 description"] next_step: "what to do next" notes: "any context for the next session" project_path: "/home/user/repos/Mana-Loop" ``` ### On session start โ€” check for existing progress: ```bash cat docs/.workflow/TASK-XXX-task-name.json 2>/dev/null ``` If a Work-in-Progress entry exists in the active-task-log: - **Resume from the last recorded step.** Do not restart the task. - Read the saved notes to understand context. If no Work-in-Progress entry exists: - Initialize the task using the Task Initialization Protocol below. --- ## ๐Ÿ“– MANDATORY CONTEXT FILES โ€” READ BEFORE EVERY TASK **You must read these files at the start of every session before writing any code:** ```bash # 1. Auto-generated project file tree cat docs/project-structure.txt # 2. Module dependency graph โ€” who imports whom cat docs/dependency-graph.json # 3. Circular dependency report โ€” red alert if non-empty cat docs/circular-deps.txt # 4. The strategy document (active priorities) cat docs/strategy/overall-remediation-plan.md # 5. Any existing progress checkpoint for current task cat docs/.workflow/TASK-*.json 2>/dev/null ``` --- ### How to use `docs/dependency-graph.json` The graph is a JSON object where **keys are files** and **values are arrays of files they import**. **To find the blast radius of changing a file** (what will break): ```bash node -e " const d = require('./docs/dependency-graph.json').graph; const target = 'stores/skillStore.ts'; const affected = Object.entries(d).filter(([,deps]) => deps.some(dep => dep.includes(target))); affected.forEach(([f]) => console.log(f)); " ``` **To find what a file depends on** (its imports): ```bash node -e " const d = require('./docs/dependency-graph.json').graph; const key = Object.keys(d).find(k => k.includes('skillStore')); console.log(JSON.stringify(d[key], null, 2)); " ``` ### How to use `docs/circular-deps.txt` If this file contains anything other than "No circular dependencies found", **stop and fix the circulars before touching any of the involved files**. Circular imports are the #1 cause of silent runtime failures in this codebase. ### When to re-generate the dependency graph manually The graph is auto-generated on commit via husky, but if you need fresh data mid-session: ```bash node .husky/scripts/generate-dependency-graph.js ``` --- ## ๐Ÿงฐ AVAILABLE TOOLS IN THIS ENVIRONMENT The following OpenWebUI tools are available in this agent session. Use them โ€” they exist to make your work safer and faster. --- ### 1. Sub Agent (`run_sub_agent`, `run_parallel_sub_agents`) **What it does:** Delegates a tool-heavy task to a fresh isolated context. The sub-agent runs its own tool loop and returns only the final result, keeping the main conversation context clean. **When to use it:** - Any investigation that requires 3+ sequential tool calls (file reads, git operations, analysis) - Parallel research tasks that don't depend on each other - Heavy grep/search operations that would pollute the main context **How to invoke:** ``` Call run_sub_agent with: description: "Brief task summary shown as status" prompt: "Full detailed instructions โ€” include ALL context the sub-agent needs, it has NO access to this conversation history" ``` **Critical:** The sub-agent starts with zero context. Paste the relevant file contents, task spec, and constraints directly into the `prompt` field. Do not assume it knows anything. **Parallel tasks:** ``` Call run_parallel_sub_agents with: tasks: [ { description: "...", prompt: "..." }, { description: "...", prompt: "..." } ] ``` Use this when tasks are independent (e.g. investigating combat while also reading skill files). --- ### 2. Dev Workflow Pro (`save_progress`, `run_checks`) **What it does:** Runs quality checks (`typecheck`, `lint`, `test`) from within the agent session, and saves task progress as JSON checkpoints in `docs/.workflow/`. **โš ๏ธ Configuration required:** The `project_path` valve must be set to `/home/user/repos/Mana-Loop` for this tool to work. If it returns "Project path is missing", the valve isn't configured โ€” fall back to `run_sub_agent` with a shell command. **Verify it works:** ``` Call run_checks with: checks: ["lint"] project_path: "/home/user/repos/Mana-Loop" ``` If this returns โœ… lint output, it's working. If it errors, use the sub-agent fallback below. **Sub-agent fallback (always works):** ``` Call run_sub_agent with: description: "Run lint and typecheck" prompt: "cd /home/user/repos/Mana-Loop && bun run lint && bun run typecheck. Return the full output including any errors." ``` **Saving progress between sessions:** ``` Call save_progress with: task_id: "TASK-001-playwright-setup" status: "in_progress" completed_steps: ["installed playwright", "configured playwright.config.ts"] next_step: "write first E2E test for enchanting flow" notes: "need to verify test:ui script works before writing tests" project_path: "/home/user/repos/Mana-Loop" ``` Progress is saved to `docs/.workflow/TASK-001-playwright-setup.json`. Read it at the start of a resumed task. --- ### 3. Advisor (`ask_advisor`, `debate`) **What it does:** Calls a specialist LLM in complete isolation to get a second opinion before making a decision. Zero context pollution โ€” only your question and the context you paste reaches it. **When to use it โ€” this is mandatory for:** - Splitting or refactoring any file โ†’ use `advisor_type: "refactor"` - Any new game mechanic that touches more than 2 systems โ†’ use `advisor_type: "code"` - Design decisions that could affect balance or lore โ†’ use `advisor_type: "lore"` - Before committing a significant implementation โ†’ use `advisor_type: "review"` **Advisor types:** | Type | When to use | |------|-------------| | `refactor` | Before splitting any file. Paste the FULL file content in `context`. | | `code` | TypeScript / React / Zustand / game architecture decisions | | `lore` | Game mechanic consistency, attunement balance, prestige design | | `review` | Bug-finding pass on a plan or code snippet before committing | | `challenge` | Argues AGAINST your approach โ€” run before major architectural decisions | | `general` | Anything else | **Example โ€” checking a refactor plan:** ``` Call ask_advisor with: question: "I want to split skillStore.ts into skillStore.ts and skillEvolution.ts. Is this safe? What are the circular import risks?" advisor_type: "refactor" context: "[paste the full skillStore.ts content here]" ``` --- ### 4. Game Dev Agent Skills (Inlet Filter) **What it does:** Automatically injects engineering skill workflows (spec, TDD, debug, refactor, perf, review, security) into the system prompt based on keywords in your message. **โš ๏ธ This is a Filter, not a Tool โ€” it requires specific setup to work:** 1. It must be added as a **Filter** in OpenWebUI under Workspace โ†’ Functions โ†’ Filters (NOT under Tools) 2. It must be toggled **ON** for the current model or workspace 3. Keyword detection is automatic โ€” the workflow injects based on what words appear in the user's message **Trigger keywords:** | Skill | Keywords that activate it | |-------|--------------------------| | `spec` | spec, specifications, prd, scope, requirements | | `debug` | bug, error, crash, broken, fix, not working | | `plan` | plan, breakdown, tasks, todo, roadmap, milestone | | `implement` | implement, build, write, create, add feature | | `tdd` | test, tdd, unit test, failing test, coverage, vitest | | `perf` | slow, lag, fps, frame time, memory leak, optimise | | `review` | review, code quality, refactor, clean up, PR | | `security` | auth, login, token, exploit, injection, hack | **If it's not injecting:** Check that it's installed as a Filter (not a Tool) and is enabled for the active model. In forced mode, set the `forced_skill` valve to the skill you want instead of `"auto"`. --- ## ๐Ÿ”ด BEFORE EDITING ANY FILE โ€” Impact Analysis Protocol Before modifying a function, store, or component, always answer these questions: ```bash # 1. Who imports this file? node -e " const d = require('./docs/dependency-graph.json').graph; const me = 'stores/skillStore.ts'; // change this Object.entries(d).filter(([,v]) => v.some(dep => dep.includes(me))) .forEach(([f]) => console.log('imports me:', f)); " # 2. Are there circular deps involving this file? grep -i "skillStore" docs/circular-deps.txt # 3. What tests cover this file? find src -name "*.test.ts" | xargs grep -l "skillStore" 2>/dev/null ``` If the impact is HIGH (5+ files import it, or it's in a circular chain) โ€” call the Advisor with `advisor_type: "review"` or `advisor_type: "challenge"` before making changes. --- ## ๐Ÿ—‚๏ธ Project Overview **Mana Loop** is a browser-based incremental/idle game built with: - **Framework:** Next.js 16 with App Router - **Language:** TypeScript 5 - **Styling:** Tailwind CSS 4 with shadcn/ui components - **State Management:** Zustand with persist middleware (modular store architecture) - **Database:** Prisma ORM with SQLite - **Test Runner:** Vitest - **Package Manager:** Bun ## Core Game Loop 1. **Mana Gathering** โ€” Click or auto-generate mana over time 2. **Studying** โ€” Spend mana to learn skills and spells 3. **Combat** โ€” Climb the Spire, defeat guardians, sign pacts 4. **Crafting** โ€” Enchant equipment with spell effects via 3-step process 5. **Prestige** โ€” Reset progress for permanent bonuses (Insight) --- ## Directory Structure **See `docs/project-structure.txt` for the full auto-generated tree.** The key directories: ``` src/lib/game/stores/ # โœ… USE THESE โ€” Zustand store modules src/lib/game/crafting-actions/ # Modular crafting system src/lib/game/data/ # Game data definitions src/lib/game/constants/ # Game constants by domain src/lib/game/utils/ # Utility functions src/lib/game/store/ # โš ๏ธ LEGACY โ€” migration in progress src/lib/game/store-modules/ # โš ๏ธ LEGACY โ€” being migrated to utils/ src/lib/game/skill-evolution-modules/ # โš ๏ธ LEGACY โ€” being replaced by computeStats() src/components/game/ # All game UI components (modular structure) src/lib/game/stores/__tests__/ # Store-level unit tests e2e/ # Playwright E2E tests (added in Phase 0) ``` --- ## Key Systems ### State Management | Store | File | Responsibility | |-------|------|---------------| | Game Store | `stores/gameStore.ts` | Core state, tick loop, equip/unequip | | Mana Store | `stores/manaStore.ts` | Raw mana, elements, conversion | | Combat Store | `stores/combatStore.ts` | Spire, spells, floor progression | | Prestige Store | `stores/prestigeStore.ts` | Insight, upgrades, loop end | | Skill Store | `stores/skillStore.ts` | Skill levels, studying | | UI Store | `stores/uiStore.ts` | Modal state, debug flags | Cross-store access pattern: ```typescript // In combatStore.ts, reading mana state: const manaState = useManaStore.getState(); ``` ### Effect System (`effects.ts`) โ€” CRITICAL All stat modifications flow through `getUnifiedEffects(state)`. **Never read skill levels directly to compute a stat** โ€” always use the unified effects object. When adding a new stat: 1. Add to `ComputedEffects` interface in `upgrade-effects.ts` 2. Add mapping in `computeEquipmentEffects()` in `effects.ts` 3. Apply in the relevant game logic using `getUnifiedEffects(state)` ### Crafting System (3-Step Enchantment) The enchantment flow is **Design โ†’ Prepare โ†’ Apply**. Each step is in its own action module: - `crafting-actions/design-actions.ts` - `crafting-actions/preparation-actions.ts` - `crafting-actions/application-actions.ts` The store is the **single source of truth** for enchantment selection state โ€” never use local component state for selected effects. ### Skill System (v2 โ€” `computeStats()`) The old `skill-evolution-modules/` system is being replaced by a flat `computeStats()` function (see strategy doc Phase 1). Until migration is complete: - Old skills still exist in `skill-evolution-modules/` - New skills will be defined in `constants/skills-v2.ts` - `computeStats()` in `constants/skills-v2.ts` is the authoritative stat calculator --- ## โš ๏ธ Common Pitfalls 1. **Forgetting `getUnifiedEffects()`** โ€” never modify stats directly; use the effect system 2. **Using legacy store** โ€” always use `stores/` (new), not `store/` (legacy) 3. **Not checking circular deps** โ€” read `docs/circular-deps.txt` before modifying shared files 4. **Bypassing crafting-actions** โ€” use modular actions for any crafting feature 5. **Using local state for enchantment selection** โ€” always use the crafting store 6. **Adding skills to `skill-evolution-modules/`** โ€” use `constants/skills-v2.ts` for new skills --- ## ๐Ÿงช Testing Priorities Tests are non-negotiable. Run `npm run test` before every commit. All tests must pass. **Priority order (if time is short, protect these first):** | Priority | Test Type | What | |----------|-----------|------| | ๐Ÿ”ด Critical | E2E | Enchantment flow (Design โ†’ Prepare โ†’ Apply) | | ๐Ÿ”ด Critical | E2E | Gear equipping + 2H weapon blocking | | ๐Ÿ”ด Critical | E2E | Combat tick and floor advancement | | ๐ŸŸก High | E2E | Locked effects cannot be selected | | ๐ŸŸก High | Unit | Store actions that modify `rawMana` | | ๐ŸŸก High | Unit | Store actions that modify `equippedInstances` | | ๐ŸŸก High | Unit | `computeStats()` returns correct values per skill level | | ๐ŸŸข Medium | Unit | `computeRegen`, `computeMaxMana`, `calcDamage` | | ๐ŸŸข Medium | Unit | `canAffordSpellCost`, `spendRawMana`, `deductSpellCost` | **When fixing a bug:** write the failing test FIRST, then fix until it passes. Test locations: - E2E: `e2e/*.spec.ts` - Store tests: `src/lib/game/stores/__tests__/` - Store-level tests: `src/lib/game/store-tests/` - Split tests: `src/lib/game/stores-split-tests/` --- ## Git Hooks (Husky) ### Pre-Commit Hook (`.husky/pre-commit`) Runs automatically before each commit: 1. **File Size Check** โ€” no staged file may exceed 400 lines 2. **Project Structure** โ€” regenerates `docs/project-structure.txt` 3. **Dependency Graph** โ€” regenerates `docs/dependency-graph.json` and `docs/circular-deps.txt` via madge 4. Auto-stages all generated docs files ### Post-Merge Hook (`.husky/post-merge`) Runs after merge โ€” auto-installs if `package.json` changed. ### Madge Setup If `docs/dependency-graph.json` is missing or stale, install madge and regenerate: ```bash bun add -d madge node .husky/scripts/generate-dependency-graph.js ``` --- ## File Size Guidelines **400 lines maximum** per file (enforced by pre-commit hook). | Directory | Purpose | Target | |-----------|---------|--------| | `stores/` | Zustand store modules | < 400 lines | | `crafting-actions/` | Crafting system actions | < 400 lines | | `constants/` | Game constants by domain | < 400 lines | | `data/` | Game data definitions | < 400 lines | | `components/game/tabs/` | UI tab components | < 400 lines | --- ## ๐Ÿšซ Banned Content ### Never Add These - **Lifesteal / Healing mechanics** โ€” the player cannot take damage. Healing is unnecessary. - **Scroll Crafting** โ€” violates NO INSTANT FINISHING design pillar. - **Ascension Skills** โ€” deleted. ### Banned Mana Types Never re-add: `life`, `blood`, `wood`, `mental`, `force` ### Removed Features - **LabTab** โ€” permanently removed. Do not re-add under any name. - **Pause button** โ€” does not exist. Do not add one. --- ## ๐Ÿ”ฎ Mana Types Reference ### Base (7) | Element | Symbol | Color | |---------|--------|-------| | Fire | ๐Ÿ”ฅ | #FF6B35 | | Water | ๐Ÿ’ง | #4ECDC4 | | Air | ๐ŸŒฌ๏ธ | #00D4FF | | Earth | โ›ฐ๏ธ | #F4A261 | | Light | โ˜€๏ธ | #FFD700 | | Dark | ๐ŸŒ‘ | #9B59B6 | | Death | ๐Ÿ’€ | #778CA3 | ### Utility (1) | Element | Symbol | Color | |---------|--------|-------| | Transference | ๐Ÿ”— | #1ABC9C | ### Compound (3) โ€” Fire+Earth=Metal, Earth+Water=Sand, Fire+Air=Lightning ### Exotic (3) โ€” Sand+Sand+Light=Crystal, Fire+Fire+Light=Stellar, Dark+Dark+Death=Void --- ## Adding New Things โ€” Quick Reference ### New Effect 1. Define in `data/enchantment-effects.ts` 2. Add stat mapping in `effects.ts` โ†’ `computeEquipmentEffects()` 3. Apply in game logic using `getUnifiedEffects(state)` ### New Skill 1. Define in `constants/skills-v2.ts` (NOT `skill-evolution-modules/`) 2. Add to `computeStats()` effect mapping 3. UI auto-reads from structure ### New Spell 1. Define in `constants/spells.ts` 2. Add enchantment in `data/enchantment-effects.ts` 3. Add research skill in `constants/skills-v2.ts` 4. Map research to effect in `EFFECT_RESEARCH_MAPPING` --- ## ๐Ÿ”„ Agent Operational Protocol ### 1. State & Resumption Protocol Before starting any implementation work, determine the current project state: 1. Read: - `docs/strategy/overall-remediation-plan.md` - `docs/active-task-log.md` (if it exists) - `docs/.workflow/TASK-*.json` (any saved progress) 2. Identify the first roadmap item marked `[ ]` in the **Current Priority** table at the top of this file. 3. If a Work-in-Progress entry exists for that task, **resume from the last recorded step**. Do not restart. 4. If no Work-in-Progress entry exists, initialize using the Task Initialization Protocol. ### 2. Task Initialization Protocol Before modifying code for a new task: 1. Update `docs/active-task-log.md` 2. Record: task ID, objective, files expected to change, current status, planned tests 3. Run baseline validation **before** editing: ```bash bun run lint && bun run test ``` 4. Record any failing baseline tests before implementation begins 5. Call `save_progress` after completing each significant step ### 3. Definition of Done A task is only complete when ALL of the following are true: - [ ] Implementation is complete - [ ] Lint passes - [ ] All relevant tests pass (see Testing Priorities above) - [ ] New tests added for bug fixes or new systems - [ ] `docs/strategy/overall-remediation-plan.md` updated: `[ ]` โ†’ `[x]` - [ ] `docs/active-task-log.md` updated (marked `ARCHIVED` or cleared) - [ ] Changes committed and pushed: ```bash git add -A git commit -m "feat: [task] โ€” [summary]" git push origin master ``` ### 4. Roadmap Execution Rules - Work on **ONE** roadmap task at a time unless explicitly told otherwise - Do not perform unrelated refactors - Do not expand scope beyond current task acceptance criteria - Large redesigns โ†’ split into `docs/tasks/` - Every task maps back to a strategy item