Files
echo-core/CLAUDE.md
Marius Mutu 2bcefe1ab4 feat(projects): approval guard + worktree-aware ralph execution
Two structural fixes that together let users manage feature-branch
work without manual intervention:

Approval guard — `/plan/start` returns 409 `already_committed` if the
project status is approved/running/complete, unless the body opts in
with `force=true`. Frontend now renders "Re-planifică" instead of
"Planifică" on approved cards and gates it behind a confirm dialog
that threads `force=true` through. Prevents an accidental click from
wiping `status=approved` and burning a fresh planning subprocess.

Worktree awareness — projects can now declare that they target a
feature branch on an existing Gitea repo, not a repo-per-slug clone.
Three optional fields added to approved-tasks.json: `repo` (default
= slug), `branch` (feature branch to create), `base_branch` (default
main). Wired through `/p` flag parser in router.py, the dashboard
Propose modal's new "Avansat" section, and the night-execute prompt
which clones {repo} and creates {branch} from {base_branch} before
running ralph.

CLAUDE.md updated with both flows + the new schema fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 08:27:14 +00:00

334 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.**
## Cum funcționează
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
## Principii de Workflow
> **Aplicabilitate:** aceste principii se aplică pentru **modificări de cod** în acest repo sau în proiectele Ralph. Pentru conversații normale (răspunsuri la mesaje, căutări KB, sfaturi, coaching), nu se aplică — răspunde direct, natural.
### 1. Plan Mode pentru task-uri non-triviale
Pentru orice task de cod cu **3+ pași sau decizii arhitecturale**, intră în plan mode înainte să atingi cod. Dacă lucrurile o iau razna mid-task (5+ erori în lanț, scope creep, premise false), **STOP** și re-planifică imediat.
Folosește skill-urile gstack pentru review:
- `/plan-eng-review` — arhitectură, edge cases, performance
- `/plan-ceo-review` — scope, ambiție, 10-star product
- `/plan-design-review` — UI/UX înainte de implementare
- `/autoplan` — toate trei automat, cu approval gate la final
### 2. Strategie de subagenți
Folosește subagenți (`Agent` tool) liber pentru a păstra context window-ul curat. Offload research, exploration, parallel analysis. **Un singur task per subagent** — nu suprasolicita.
- `Explore` — căutări codebase
- `general-purpose` — research multi-step
- `Plan` — design de implementare
### 3. Self-Improvement Loop
După **ORICE** corectare de la Marius, actualizează `tasks/lessons.md` cu pattern-ul învățat. Scrie pentru tine viitor — ce a prevenit corectarea, regula, când se aplică.
La începutul oricărei sesiuni de cod (înainte de plan mode), **citește `tasks/lessons.md`** și aplică lecțiile relevante. Iterează pe ele neobosit pentru a evita rate drop-uri pe greșeli repetate.
Ralph va citi și el acest fișier între iterații (extensie viitoare — vezi `tools/ralph/prompt.md`).
### 4. Verificare înainte de „done"
Nu marca un task complet fără să verifici că funcționează. Comportamentul diferit între `main` și branch-ul tău contează doar dacă e relevant pentru task. Întreabă-te mereu: **„Ar aproba un staff engineer asta?"**
Folosește din gstack:
- `/qa` — test + fix loop iterativ
- `/qa-only` — doar raport de bug-uri
- `/review` — pre-merge diff review
- `/devex-review` — DX live audit
- `/ship` — full pipeline (tests + CHANGELOG + PR)
### 5. Cere eleganță (echilibrat)
Pentru schimbări non-triviale: pauză și întreabă **„e o cale mai elegantă?"** Dacă fix-ul se simte hacky, *„knowing everything I know now, implement the elegant solution"* — implementează soluția elegantă din capul locului.
**Skip pentru fixes simple, schimbări obvii** — nu over-engineer. Provoacă-ți munca înainte să o prezinți.
Folosește `/codex challenge` (mod adversarial care încearcă să spargă codul) sau `/codex review` pentru second opinion.
### 6. Bug fixing autonom
Când Marius dă un bug report: **just fix it**. Fără hand-holding. Indică logs, errors, failing tests — apoi rezolvă-le. Zero context switching cerut de la user.
Folosește `/investigate` pentru debugging sistematic (4 faze: investigate → analyze → hypothesize → implement). **Iron Law: fără fix fără root cause.**
Ralph face exact asta noaptea, autonom, pe proiectele aprobate.
## Task Management
Pentru work tracking folosește **Echo Task Board** (`dashboard/`), nu fișiere markdown. Endpoints în `dashboard/handlers/`.
1. **Plan First** — task-uri cu checkboxes în plan mode
2. **Verify Plan** — check-in cu Marius înainte de implementare la schimbări mari
3. **Track Progress** — marchează task-urile complete pe măsură ce le faci
4. **Explain Changes** — high-level summary la fiecare pas
5. **Document Results** — la final, secțiune review în PR sau în `tasks/<task>.md`
6. **Capture Lessons** — la corectări, update `tasks/lessons.md` (vezi principiul 3)
## Core Principles
- **Simplicitate înainte de toate** — fă cele mai simple schimbări posibile. Impact minim, cod minimal.
- **Zero lene** — root causes, nu temporary fixes. Standard de senior developer.
- **Impact minim** — atinge doar ce e necesar. Fără side effects la features noi.
## Comenzi
```bash
# Tests
source .venv/bin/activate && pytest tests/
pytest tests/test_router.py::test_clear_command -v
# Pornire
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
# Dependențe
source .venv/bin/activate && pip install -r requirements.txt
```
## Arhitectură
**Flow:** Adapter → `router.py``claude_session.py` → Claude CLI → split răspuns → reply pe Adapter
**Adaptoare** (concurente, `asyncio.gather()` în `src/main.py`):
- **Discord** (`src/adapters/discord_bot.py`) — slash commands, split la 2000 caractere
- **Telegram** (`src/adapters/telegram_bot.py`) — comenzi + inline keyboards, split la 4096 caractere
- **WhatsApp** (`src/adapters/whatsapp.py`) — polling Baileys bridge la `http://127.0.0.1:8098`, split la 4096 caractere
**Sesiuni** (`src/claude_session.py`): O sesiune persistentă per canal. `claude --resume <session_id>`. Mesajele externe sunt împachetate în markeri `[EXTERNAL CONTENT]`.
**State:** `sessions/active.json` — channel ID → `{session_id, model, message_count, ...}`
**Credențiale** (`src/credential_store.py`): Keyring de sistem, serviciu `"echo-core"`. Niciodată secrete ca argumente CLI.
**Config** (`src/config.py`): `config.json` cu dot-notation. Namespaces: `channels`, `telegram_channels`, `whatsapp_channels`.
**Scheduler** (`src/scheduler.py`): APScheduler + `cron/jobs.json`, sesiuni izolate.
**Heartbeat** (`src/heartbeat.py`): Verificări email, calendar, KB, git. Ore tăcere 23-08.
**Ralph** (`tools/ralph/`): Sistem autonom de execuție. `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`): Embeddings Ollama all-minilm (384 dim) + cosine similarity SQLite. Trăiește la `memory/` în acest repo — single source of truth. *Notă istorică:* era symlink la repo-ul legacy Clawdbot; consolidat în echo-core în migrația OpenClaw (2026-04).
**Dashboard** (`dashboard/`): Echo Task Board — HTTP API + UI static servit de `dashboard/api.py` pe portul 8088, de obicei în spatele unui reverse proxy la `/echo/`. Logica endpoint-urilor împărțită în mixin-uri `dashboard/handlers/*.py`; path-urile centralizate în `dashboard/constants.py`. Template systemd user unit la `dashboard/echo-taskboard.service`. `workspace.html` este hub-ul unificat de proiecte (fostul ralph.html + workspace.html); `/echo/ralph.html` → 302 redirect la `/echo/workspace.html`. Autentificare prin cookie httpOnly `dashboard=<token>`; `DASHBOARD_TOKEN` setat în `dashboard/.env`.
## Dashboard — Note arhitecturale
**Cookie auth:** dashboard folosește httpOnly cookie `dashboard=...`; SameSite=Strict; Path=/echo/. EventSource SSE trimite cookie-ul automat. `DASHBOARD_TOKEN` din `dashboard/.env` — setează o dată, restart service. Resetare: schimbă valoarea din .env + restart.
**jsonlock helper (`src/jsonlock.py`):** folosește `read_locked(path)` / `write_locked(path, mutator)` pentru orice scriere la `approved-tasks.json`, `sessions/*.json`. Lock pe sidecar `<path>.lock` (inode stabil chiar și după os.replace). Ordine canonică lock-uri: alfabetic după filename. Re-entrant (threading.local refcount).
**Slug convention:** slug-urile proiectelor validează cu regex `^[a-z0-9][a-z0-9\-_]{1,38}[a-z0-9]$` — permit hifene ȘI underscore. Validare centralizată în `dashboard/handlers/_validators.py`.
**Proxy timeout:** pentru nginx/caddy, setează `proxy_read_timeout >= 60s` și `proxy_buffering off` pentru `/echo/api/projects/stream` și `/echo/api/projects/<slug>/plan/*` (SSE + planning au răspunsuri lungi).
**Planning fragmentation (known limit):** sesiunile de planning pornite din Discord/Telegram nu se fuzionează cu cele din dashboard. Dashboard afișează sesiunea cea mai recentă per slug indiferent de adapter. P3 follow-up.
## Ralph — Execuție autonomă de proiecte
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 de aprobare
Marius → /a <slug> (Discord/Telegram/WhatsApp → router.py → status: approved
SAU /plan <slug> → planning agent conversational → final-plan.md → approved)
23:00 night-execute → citește approved, clonează repo dacă lipsește, generează PRD din final-plan.md,
lansează ralph.sh; actualizează approved-tasks.json (running, pid: PID)
08:30 morning-report → citește approved-tasks.json + prd.json per proiect, raportează stories done/total
Live dashboard → /echo/workspace.html — cards per proiect cu status, iter, ETA, log, stop; realtime SSE
```
**Două căi de aprobare**:
- **Direct**: `/a <slug>` — pentru proiecte simple unde descrierea e suficientă
- **Conversational** (W2 — `/plan <slug>` SAU buton "Planifică" pe `/l`): Echo poartă o conversație multi-fază prin skills gstack (`/office-hours``/plan-ceo-review``/plan-eng-review` → opțional `/plan-design-review` dacă tags include "ui"), produce `~/workspace/<slug>/scripts/ralph/final-plan.md` și prezintă rezumat cu butonul "✅ Dau drumul tonight". `night-execute` îl folosește ca input pentru PRD generator (Opus extrage user stories cu acceptanceCriteria, tags, dependsOn).
**Comenzi** (funcționează pe toate adaptoarele — Discord, Telegram, WhatsApp):
| Comandă | Efect |
|---------|-------|
| `/p <slug> <descriere>` | Adaugă proiect nou cu status `pending` |
| `/a` | Listează proiectele pending |
| `/a <slug>` sau `/a P1,P2` | Aprobă pentru tonight (path direct) |
| `/plan <slug>` | Pornește planning agent conversational (multi-fază skills gstack) |
| `/cancel` | Anulează planning în curs (revert status → pending) |
| `/l` | **Discord/Telegram**: meniu interactiv (Views/InlineKeyboardMarkup) cu butoane per proiect; **WhatsApp**: text plain + redirect spre Discord/TG |
| `/l <slug>` | Status proiect specific |
| `/k <slug>` | Trimite SIGTERM la ralph.sh PID |
**UX interactiv** (Discord/Telegram):
- `/l` deschide `RalphRootView` (Discord) / InlineKeyboardMarkup (Telegram) cu butoane per workspace project
- Click pe proiect → submeniu cu acțiuni: Propune feature (modal/ForceReply), 🧠 Planifică (W2), 👁 Vezi PRD, 📊 Status, ✅ Aprobă tonight, 🛑 Stop, 🔙 Înapoi
- La sfârșitul planning: butoane ✅ Dau drumul tonight / ✏️ Mai gândim / 🛑 Anulează
- State per `(adapter, channel)` în `sessions/ralph_flow.json` și `sessions/planning.json` (TTL 10min/60min)
Pe **Discord**: slash commands native cu autocomplete dinamic: `/p <tab>` listează workspace, `/a <tab>` pending, `/k <tab>` running. Modal cu `TextInput` pentru descriere. Critical pattern: `await interaction.response.defer(ephemeral=True)` în orice button callback cu I/O (Discord 3s timeout).
Pe **Telegram**: `callback_ralph` cu pattern `^ralph:` rutează acțiuni; `ForceReply` pentru input text descriere.
Pe **WhatsApp**: text-only — meniu redirect la Discord/Telegram. **Text-keyword shortcuts**: `aprob <slug>``/a <slug>`, `stop <slug>``/k <slug>`, `stare`/`stare <slug>``/l`/`/l <slug>` (case-insensitive, doar pe WhatsApp; Discord/Telegram nu sunt afectate). `propose` intentionally NOT covered — descrierea fragilă.
**Aliasuri legacy** (funcționează încă pentru backwards compat): `!propose`, `!approve`, `!status`, `!stop`.
**Fișiere cheie Ralph:**
| Path | Rol |
|------|-----|
| `approved-tasks.json` | Coordonare între cron jobs + UX. Schema: `{name, description, status, planning_session_id, final_plan_path, repo, branch, base_branch, proposed_at, approved_at, started_at, pid}` |
| `prompts/planning_agent.md` | System prompt pentru `PlanningSession` (multi-fază conversational) |
| `src/planning_session.py` | Wrapper subprocess `claude -p` cu working dir = `~/workspace/<slug>/`, `--add-dir` skills gstack + project artifacts. `--max-turns=20` cu retry pe `error_max_turns` |
| `src/planning_orchestrator.py` | Coordonează fazele: fresh subprocess per skill phase; coordinează prin disk artifacts gstack convention; tag detection ui-scope |
| `sessions/planning.json` | State per `(adapter, channel)` planning session: session_id, current_phase, etc. — pentru re-resume la restart |
| `tools/ralph/ralph.sh` | Bash loop DAG-aware: N iterații × `claude` CLI per story; folosește `tools/ralph_dag.py` pentru selecție topologică, retry guard (3 retries), rate-limit detection |
| `tools/ralph/prompt.md` | Smart gates dispatcher pe `story.tags` (Faza 3): refactor→/workflow:simplify, ui→/qa+screenshot, vercel→push+gh checks, db→schema diff, default→/review |
| `tools/ralph/prd-template.json` | Template prd.json: stories cu `acceptanceCriteria[]`, `tags[]`, `dependsOn[]`, `passes`, `retries` |
| `tools/ralph_prd_generator.py` | Generează prd.json. Cu `final_plan_path` (de la PlanningOrchestrator) → Opus extrage stories cu acceptance criteria. Fără → backwards-compat description-only |
| `tools/ralph_dag.py` | Pure functions Python (testabile): `infer_tags_from_paths`, `force_include_tags`, `topological_eligible`, `mark_failed`, blocked propagation iterativă. CLI subcommands chemate din ralph.sh (`infer-tags`, `next-story`, `mark-failed`, `incr-retry`) |
| `tools/ralph_usage.py` | Rate limit budget tracking: pure functions `extract_usage_entry`, `parse_usage_jsonl`, `aggregate_by_day`, `aggregate_by_project` + CLI append/summarize. Atomic write JSONL |
| `~/workspace/<name>/scripts/ralph/usage.jsonl` | Append-only log per `claude -p` call (cost, tokens, model, duration) — generat din ralph.sh, agregat de `/api/ralph/usage` |
| `~/workspace/<name>/scripts/ralph/final-plan.md` | Output planning agent — citit de PRD generator |
| `~/workspace/<name>/scripts/ralph/prd.json` | PRD per proiect cu schema extinsă |
| `~/workspace/<name>/scripts/ralph/logs/` | Loguri ralph.sh per rulare |
| `dashboard/handlers/ralph.py` | Endpoints `/api/ralph/status`, `/<slug>/log`, `/<slug>/prd`, `/<slug>/stop`, `/<slug>/rollback`, `/usage[?days=N]`, `/stream` (SSE) |
| `dashboard/handlers/projects.py` | Endpoints unificate proiecte: `/api/projects`, `/propose`, `/approve`, `/unapprove`, `/cancel`, `/<slug>/plan/*`, `/stream` (SSE), `/signature` |
| `dashboard/workspace.html` | Hub unificat proiecte — cards status/iter/ETA, log, prd, stop/rollback. Realtime SSE cu fallback polling 5s. Înlocuiește ralph.html (care face 302 redirect aici) |
| `dashboard/.env` | `GITEA_TOKEN` pentru clone HTTPS la `gitea.romfast.ro`; `DASHBOARD_TOKEN` pentru cookie auth |
**Status flow:** `pending` → (`planning` →) `approved``running``complete` / `failed` / `stopped` / `blocked` (DAG)
**Story status (în prd.json):** `passes:false` + `retries:N``passes:true` SAU `failed:rate_limited|max_retries`
**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/<name>.git`
### Features pe repo-uri existente (worktree-aware)
Slug-ul proiectului nu trebuie să corespundă cu un repo Gitea. Pentru o feature pe un repo existent (ex: `roa2web-telegram-bonuri` ca feature pe `roa2web`), folosește câmpurile opționale `repo`, `branch`, `base_branch`:
- **`repo`** — numele repo-ului Gitea de clonat (default: slug-ul proiectului).
- **`branch`** — feature branch nou care va fi creat după clone (default: niciunul, ralph lucrează pe HEAD-ul default).
- **`base_branch`** — branch-ul de la care porneste `branch` (default: `main`).
Cum le setezi:
- **CLI/chat:** `/p <slug> --repo <name> --branch <feature> [--base-branch <name>] <descriere>` (parser în `_ralph_propose` la `src/router.py`).
- **Dashboard:** modal Propose → secțiunea „Avansat" cu câmpuri pentru repo/branch/base_branch.
Night-execute (`cron/jobs.json`) detectează câmpurile și clonează `repo` în `~/workspace/<slug>/`, apoi `git checkout -b <branch> <base_branch>` dacă `branch` e setat. Dacă clone-ul eșuează (repo inexistent), proiectul e marcat `failed` fără să mai pornească ralph.
### Approval guard — protejare împotriva re-planning accidental
`/plan/start` (POST `/api/projects/<slug>/plan/start`) refuză cu 409 `already_committed` dacă proiectul e deja `approved`/`running`/`complete`. Pentru a re-iniția planning-ul intenționat:
- **Dashboard:** butonul „Re-planifică" pe cards aprobate cere confirm explicit înainte să trimită `force=true` în body.
- **API direct:** trimite `{"force": true, "description": "..."}` în body-ul de la `/plan/start`.
Asta previne situația în care un click accidental pe „Planifică" șterge `status=approved` și pornește un nou subprocess Claude (cu cost asociat).
## Convenție import-uri
Import-uri absolute via `sys.path.insert(0, PROJECT_ROOT)`: `from src.config import ...`, `from src.adapters.discord_bot import ...`. Fără import-uri circulare.
## Fișiere cheie
| Path | Rol |
|------|-----|
| `src/main.py` | Entry point — adaptoare + scheduler + heartbeat |
| `src/router.py` | Comenzi vs mesaje Claude |
| `src/claude_session.py` | Wrapper Claude CLI cu `--resume` |
| `src/credential_store.py` | Secrete keyring |
| `cli.py` | Diagnostice CLI (eco) |
| `config.json` | Config runtime |
| `bridge/whatsapp/index.js` | Bridge Baileys + Express, port 8098 |
| `personality/*.md` | System prompt — cine ești |
| `memory/` | Knowledge base — embeddings + SQLite (în repo, nu symlink) |
| `dashboard/api.py` | Task Board HTTP API (port 8088) |
| `dashboard/handlers/` | Mixin-uri endpoints (git, cron, habits, eco, files, pdf, workspace, youtube, projects, ralph, auth) |
| `dashboard/handlers/projects.py` | Endpoints unificate proiecte: `/api/projects`, `/propose`, `/approve`, `/unapprove`, `/cancel`, `/<slug>/plan/*`, `/stream` (SSE) |
| `dashboard/handlers/auth.py` | Login/logout cu cookie httpOnly `dashboard=<token>`; `DASHBOARD_TOKEN` din `.env` |
| `dashboard/handlers/_validators.py` | Validatori slug/descriere partajați. Slug regex: `^[a-z0-9][a-z0-9\-_]{1,38}[a-z0-9]$` (permite hifene ȘI underscore) |
| `dashboard/static/tokens.css` | Design tokens CSS (`--color-*`, `--space-*`, etc.) — shared variables pentru toate paginile |
| `dashboard/DESIGN.md` | Design system source-of-truth: tokens, componente, regula no-emoji |
| `dashboard/constants.py` | Path-uri centralizate + config Gitea pentru dashboard |
| `dashboard/echo-taskboard.service` | Template systemd user unit |
| `src/jsonlock.py` | Flock helper pentru scrieri concurente: `read_locked(path)`, `write_locked(path, mutator)`, `LockTimeoutError`. Sidecar `<path>.lock` (inode stabil). Re-entrant per thread. Ordine canonică: alfabetic |
| `src/approved_tasks_cli.py` | CLI wrapper pentru shell scripts: scrie în `approved-tasks.json` prin jsonlock. Usage: `python3 -m src.approved_tasks_cli set-status --slug X --status Y` |
| `cron/jobs.json` | Job-uri APScheduler (schemă plată, Europe/Bucharest) |
| `approved-tasks.json` | Fișier coordonare Ralph — status proiecte autonome (extins cu `planning_session_id`, `final_plan_path`) |
| `tasks/lessons.md` | Lecții capturate din corectările lui Marius (citit la session start) |
| `tasks/spike-planning-findings.md` | Validare empirică Spike Step 0 (subprocess `claude -p` + skills gstack + `--resume` round-trip) |
| `prompts/planning_agent.md` | System prompt pentru planning agent multi-fază (W2) |
| `src/ralph_flow.py` | State per `(adapter, chat, user)` pentru UX flow (TTL 10min) |
| `src/planning_session.py` | Wrapper Claude subprocess pentru planning agent |
| `src/planning_orchestrator.py` | Orchestrare faze gstack skills (W2) |
| `src/adapters/discord_views.py` | Discord Views/Modal pentru UX interactiv (W1) |
| `tools/ralph/ralph.sh` | Bash loop DAG-aware (W3): N iter × claude CLI per story |
| `tools/ralph_dag.py` | DAG helpers + CLI (W3) |
| `tools/ralph_prd_generator.py` | Generează PRD + prd.json cu Opus |
## gstack
Folosește skill-ul `/browse` din gstack pentru orice navigare web. Nu folosi tool-uri `mcp__claude-in-chrome__*`.
Skill-uri disponibile:
- `/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`