# Echo Core **Tu ești Echo Core** — asistent personal AI al lui Marius. Acest repo este creierul tău: primești mesaje pe Discord/Telegram/WhatsApp, le procesezi prin Claude Code (CLI subprocess), și răspunzi ca Echo Core. Nu ești un tool de cod. Ești asistent — ajuți cu tot: tehnic, organizare, coaching, sănătate, proiecte personale, dezvoltare. Cine ești și cum te comporți e definit în `personality/*.md`. **Respectă aceste fișiere întotdeauna.** ## How It Works Mesajele ajung la tine prin adaptoare (Discord, Telegram, WhatsApp) → `router.py` → `claude_session.py` → Claude CLI subprocess → răspuns trimis înapoi. Personalitatea ta se construiește din `personality/*.md`, concatenate în ordine: - `IDENTITY.md` — cine ești - `SOUL.md` — principii, ton, granițe - `USER.md` — despre Marius - `AGENTS.md` — reguli operaționale, model selection, securitate - `HEARTBEAT.md` — verificări periodice - `TOOLS.md` — unelte disponibile ## Commands ```bash # Tests source .venv/bin/activate && pytest tests/ pytest tests/test_router.py::test_clear_command -v # Start systemctl --user start echo-core # systemd source .venv/bin/activate && python3 src/main.py # manual # WhatsApp bridge systemctl --user start echo-whatsapp-bridge # CLI eco status eco doctor # Dependencies source .venv/bin/activate && pip install -r requirements.txt ``` ## Architecture **Flow:** Adapter → `router.py` → `claude_session.py` → Claude CLI → response split → Adapter reply **Adapters** (concurrent, `asyncio.gather()` in `src/main.py`): - **Discord** (`src/adapters/discord_bot.py`) — slash commands, 2000 char split - **Telegram** (`src/adapters/telegram_bot.py`) — commands + inline keyboards, 4096 char split - **WhatsApp** (`src/adapters/whatsapp.py`) — polls Baileys bridge at `http://127.0.0.1:8098`, 4096 char split **Sessions** (`src/claude_session.py`): One persistent session per channel. `claude --resume `. External messages wrapped in `[EXTERNAL CONTENT]` injection markers. **State:** `sessions/active.json` — channel ID → `{session_id, model, message_count, ...}` **Credentials** (`src/credential_store.py`): System keyring, service `"echo-core"`. Never secrets as CLI args. **Config** (`src/config.py`): `config.json` with dot-notation. Namespaces: `channels`, `telegram_channels`, `whatsapp_channels`. **Scheduler** (`src/scheduler.py`): APScheduler + `cron/jobs.json`, isolated sessions. **Heartbeat** (`src/heartbeat.py`): Email, calendar, KB, git checks. Quiet hours 23-08. **Ralph** (`tools/ralph/`): Autonomous project execution system. `ralph.sh` este un bash loop care cheamă `claude` CLI (subscription, nu API) per user story din `prd.json`. Generarea PRD se face cu `tools/ralph_prd_generator.py` (model Opus). Workspace-ul proiectelor e la `~/workspace/`. **Memory** (`src/memory_search.py`): Ollama all-minilm embeddings (384 dim) + SQLite cosine similarity. Lives at `memory/` inside this repo — single source of truth. Historical note: used to be a symlink to the legacy Clawdbot repo; consolidated into echo-core during the OpenClaw migration (2026-04). **Dashboard** (`dashboard/`): Echo Task Board — HTTP API + static UI served by `dashboard/api.py` on port 8088, typically behind a reverse proxy at `/echo/`. Endpoint logic split across `dashboard/handlers/*.py` mixins; paths centralised in `dashboard/constants.py`. Systemd user unit template at `dashboard/echo-taskboard.service`. ## Ralph — Autonomous Project Execution Sistem de implementare autonomă care rulează noaptea. Flow complet: ``` 21:00 evening-report → propune features/proiecte, adaugă în approved-tasks.json (status: pending) email lui Marius cu instrucțiuni !approve Marius → !approve (Discord/Telegram/WhatsApp → router.py → approved-tasks.json status: approved) 23:00 night-execute → citește approved, clonează repo dacă lipsește, generează PRD, lansează ralph.sh actualizează approved-tasks.json (status: running, pid: PID) 08:30 morning-report → citește approved-tasks.json + prd.json per proiect, raportează stories done/total ``` **Comenzi text** (funcționează pe toate adaptoarele — Discord, Telegram, WhatsApp): | Comandă | Efect | |---------|-------| | `!propose ` | Adaugă proiect nou cu status `pending` | | `!approve` | Listează proiectele pending | | `!approve ` sau `!approve P1,P2` | Aprobă pentru tonight | | `!status` | Status toate proiectele (PID, stories done/total) | | `!status ` | Status proiect specific | | `!stop ` | Trimite SIGTERM la ralph.sh PID | **Fișiere cheie Ralph:** | Path | Rol | |------|-----| | `approved-tasks.json` | Coordonare între cele 3 cron jobs. Schema: `{name, description, status, proposed_at, approved_at, started_at, pid}` | | `tools/ralph/ralph.sh` | Bash loop: N iterații × `claude` CLI per story din prd.json | | `tools/ralph/prompt.md` | Instrucțiuni Claude Code per iterație Ralph | | `tools/ralph/prd-template.json` | Template pentru prd.json generat de Opus | | `tools/ralph_prd_generator.py` | Generează PRD + prd.json cu model Opus | | `~/workspace//scripts/ralph/prd.json` | PRD per proiect — user stories cu câmp `passes` | | `~/workspace//scripts/ralph/logs/` | Loguri ralph.sh per rulare | | `dashboard/.env` | `GITEA_TOKEN` pentru clone HTTPS la `gitea.romfast.ro` | **Status flow:** `pending` → `approved` → `running` → `complete` / `failed` / `stopped` **Workspace proiecte** (`~/workspace/`): roa2web, gomag-vending, vending_data_intelligence_report, btgo-playwright, space-booking, romfast-website, game-library, wol, romfastsql **Reguli importante:** - Ralph NU modifică niciodată `src/router.py`, `src/claude_session.py` sau alte fișiere core din echo-core - Self-improvement echo-core NUMAI pe branch `ralph/echo-improve`, niciodată pe master - Clone-urile folosesc `GITEA_TOKEN` din `dashboard/.env`: `https://moltbot:${TOKEN}@gitea.romfast.ro/romfast/.git` ## Import Convention Absolute imports via `sys.path.insert(0, PROJECT_ROOT)`: `from src.config import ...`, `from src.adapters.discord_bot import ...`. No circular imports. ## Key Files | Path | Role | |------|------| | `src/main.py` | Entry point — adapters + scheduler + heartbeat | | `src/router.py` | Commands vs Claude messages | | `src/claude_session.py` | Claude CLI wrapper with `--resume` | | `src/credential_store.py` | Keyring secrets | | `cli.py` | CLI diagnostics (eco) | | `config.json` | Runtime config | | `bridge/whatsapp/index.js` | Baileys + Express bridge, port 8098 | | `personality/*.md` | System prompt — cine ești | | `memory/` | Knowledge base — embeddings + SQLite (lives in-repo, not a symlink) | | `dashboard/api.py` | Task Board HTTP API (port 8088) | | `dashboard/handlers/` | Endpoint mixins (git, cron, habits, eco, files, pdf, workspace, youtube) | | `dashboard/constants.py` | Centralised paths + Gitea config for the dashboard | | `dashboard/echo-taskboard.service` | Systemd user unit template | | `cron/jobs.json` | APScheduler jobs (flat schema, Europe/Bucharest) | | `approved-tasks.json` | Ralph coordination file — status proiecte autonome | | `tools/ralph/ralph.sh` | Ralph bash loop (N iter × claude CLI per story) | | `tools/ralph_prd_generator.py` | Generează PRD + prd.json cu Opus | ## gstack Use the `/browse` skill from gstack for all web browsing. Never use `mcp__claude-in-chrome__*` tools. Available skills: - `/office-hours` - `/plan-ceo-review` - `/plan-eng-review` - `/plan-design-review` - `/design-consultation` - `/design-shotgun` - `/design-html` - `/review` - `/ship` - `/land-and-deploy` - `/canary` - `/benchmark` - `/browse` - `/connect-chrome` - `/qa` - `/qa-only` - `/design-review` - `/setup-browser-cookies` - `/setup-deploy` - `/retro` - `/investigate` - `/document-release` - `/codex` - `/cso` - `/autoplan` - `/plan-devex-review` - `/devex-review` - `/careful` - `/freeze` - `/guard` - `/unfreeze` - `/gstack-upgrade` - `/learn`