Files
Mana-Loop/AGENTS.md
T
2026-05-13 12:16:11 +02:00

612 lines
21 KiB
Markdown
Executable File

# 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