# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Frankenbot is a multi-agent event management system for the Diversity Ball Wien 2026. It's a Flask app (single-file `app.py`, ~3400 lines) with 13 specialized AI agents that handle tasks like budgeting, catering, music rights, tax advice, and team coordination. Agents are executed via **OpenCode CLI** (`opencode run`) which connects to Claude models via Anthropic. ## Running the App ```bash # Start directly python3 app.py # Or via systemd (production) sudo systemctl restart frankenbot sudo systemctl status frankenbot sudo journalctl -u frankenbot -f # App runs on port 5050 (not 5000, that's Zou/Kitsu) # Accessible at https://frankenbot.equalizent.media/ ``` ## Architecture ### Agent System Each agent lives in `agents//` with: - `systemprompt.md` - Role and instructions - `personality.md` - Behavioral traits - `reminders.md` - Persistent notes - `memory/` - JSON files (tasks.json, notes.json, conversations.json, max 100 entries each) - `work/` - Agent output directory (used as cwd during execution) **Execution flow:** User prompt → load systemprompt + personality + memory summary + team summary → call `opencode run --model --format json ` → parse response for special commands (@CREATE_SUBTASK, @SEND_EMAIL, @ASK_ORCHESTRATOR, etc.) → return to user. Model assignments are in `agent_config.json`. Fallback model: `opencode/big-pickle`. ### Database (SQLite: `email_journal.db`) Four tables: `email_journal` (IMAP message tracking), `tasks` (persistent task queue with status pending→in_progress→completed), `team_members` (real people with roles/contact), `app_settings` (key-value config). Auto-migrated on startup. ### Background Threads (5 daemon threads) 1. **EmailPoller** - IMAP check every 2 min, whitelist-filtered (@diversityball.at) 2. **TaskWorker** - Processes email tasks from queue every 10s 3. **TaskBeat** - Auto-delegates pending orchestrator tasks every 10s 4. **OrchestratorBeat** - Escalates stuck tasks every 30 min 5. **TelegramBot** - Polls for messages (if configured) ### SSE Streaming `/api/agent-stream` uses `subprocess.Popen` with OpenCode, reads stdout line-by-line, yields JSON SSE events. Browser uses `fetch()` + ReadableStream. Nginx must have `proxy_buffering off`. ### Authentication Single shared password (`APP_PASSWORD` in .env). `@login_required` decorator on all routes except `/login` and `/logout`. Flask session with 7-day lifetime. ## Key Files | File | What it does | |---|---| | `app.py` | Everything: routes, agent execution, DB, email, telegram, background threads | | `agent_config.json` | Agent → model mapping (editable via web UI /agents) | | `.env` | APP_PASSWORD, email credentials (IMAP/SMTP), Telegram token | | `templates/base.html` | Shared layout (Bootstrap 5, dark theme, navbar) | | `static/style.css` | All custom styles | ## Important Patterns - **Agent commands**: Agents can embed `@CREATE_SUBTASK`, `@SEND_EMAIL`, `@ASK_ORCHESTRATOR`, `@SUGGEST_AGENT`, `@READ_KNOWLEDGE`, `@SEND_TELEGRAM`, `@UPDATE_TEAM_MEMBER` in their responses. These are parsed by `parse_agent_commands()` and executed by the system. - **Session cookie limit**: Don't store large data in Flask session (4KB cookie limit). The orchestrator knowledge base and agent prompts must be loaded on-demand, not cached in session. - **Port 5050**: Port 5000 is used by Zou/Kitsu on this server. Don't change back to 5000. - **OpenCode CLI**: Must be installed and authenticated separately (`opencode auth`). Binary at `~/.opencode/bin/opencode`. ## Deployment - **Server**: 212.186.132.27 (signtime-kitsu) - **nginx**: Reverse proxy on `frankenbot.equalizent.media` → localhost:5050 - **SSL**: Let's Encrypt via certbot (auto-renew) - **systemd**: `/etc/systemd/system/frankenbot.service`, runs as user `eric` - **Git remote**: `https://git.poweroftwo.studio/Pjot/frankenbot.git`