stage-1: project bootstrap
Structure, config loader, personality/tools/memory from clawd, venv, 22 tests passing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
372
memory/kb/tools/ralph-workflow.md
Normal file
372
memory/kb/tools/ralph-workflow.md
Normal file
@@ -0,0 +1,372 @@
|
||||
# Ralph Workflow - Sistem Complet
|
||||
|
||||
**Versiune:** 2.0 (finală - funcțională)
|
||||
**Data:** 2026-02-09
|
||||
**Locație:** moltbot (LXC 110)
|
||||
|
||||
## Prezentare Generală
|
||||
|
||||
**Ralph** este un sistem pentru crearea și execuția autonomă a proiectelor software prin Claude Code, format din două componente:
|
||||
|
||||
1. **Echo (Opus)** → Generează PRD și user stories în Python
|
||||
2. **Ralph loop (Sonnet)** → Implementează autonom cu Claude Code
|
||||
|
||||
## Componente
|
||||
|
||||
### 1. ralph_prd_generator.py
|
||||
|
||||
**Locație:** `~/clawd/tools/ralph_prd_generator.py`
|
||||
|
||||
**Funcție:** Generează PRD markdown și prd.json fără să apeleze Claude Code.
|
||||
|
||||
**Features:**
|
||||
- Detectează tech stack automat (package.json, pyproject.toml, etc.)
|
||||
- Generează PRD conform template (obiective, stories, acceptance criteria)
|
||||
- Creează prd.json cu user stories prioritizate
|
||||
- Copiază templates (ralph.sh, prompt.md) în proiect
|
||||
- Configurează comenzi tech stack (start, build, lint, typecheck, test)
|
||||
|
||||
**Usage:**
|
||||
```python
|
||||
from tools.ralph_prd_generator import create_prd_and_json
|
||||
from pathlib import Path
|
||||
|
||||
prd_file, prd_json = create_prd_and_json(
|
||||
project_name="task-tracker", # kebab-case
|
||||
description="""
|
||||
Task tracker CLI în Python.
|
||||
Features:
|
||||
- Add/list/done tasks
|
||||
- SQLite storage
|
||||
- Export markdown
|
||||
- Tests cu pytest
|
||||
""",
|
||||
workspace_dir=Path.home() / "workspace"
|
||||
)
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
~/workspace/PROJECT-NAME/
|
||||
├── tasks/
|
||||
│ └── prd-PROJECT-NAME.md # PRD markdown
|
||||
└── scripts/
|
||||
└── ralph/
|
||||
├── prd.json # Stories JSON
|
||||
├── ralph.sh # Loop autonom (din templates)
|
||||
├── prompt.md # Instrucțiuni Claude Code
|
||||
├── progress.txt # Learnings
|
||||
├── logs/ # Logs execuție
|
||||
├── archive/ # Arhive rulări anterioare
|
||||
└── screenshots/ # Screenshots UI (dacă aplicabil)
|
||||
```
|
||||
|
||||
### 2. ralph_workflow.py
|
||||
|
||||
**Locație:** `~/clawd/tools/ralph_workflow.py`
|
||||
|
||||
**Funcție:** Wrapper simplu pentru workflow complet (PRD + lansare Ralph).
|
||||
|
||||
**Features:**
|
||||
- Apelează ralph_prd_generator pentru PRD
|
||||
- Lansează ralph.sh în background
|
||||
- Monitorizare status proiect
|
||||
|
||||
**Usage CLI:**
|
||||
```bash
|
||||
# Creează proiect complet (PRD + lansare Ralph)
|
||||
python3 tools/ralph_workflow.py create "project-name" "description"
|
||||
|
||||
# Verifică status
|
||||
python3 tools/ralph_workflow.py status "project-name"
|
||||
```
|
||||
|
||||
**Usage Python:**
|
||||
```python
|
||||
from tools.ralph_workflow import run_ralph, check_status
|
||||
from pathlib import Path
|
||||
|
||||
# Lansează Ralph (după ce ai prd.json)
|
||||
run_ralph(
|
||||
prd_json=Path.home() / "workspace" / "PROJECT" / "scripts" / "ralph" / "prd.json",
|
||||
max_iterations=20,
|
||||
background=True
|
||||
)
|
||||
|
||||
# Verifică status
|
||||
status = check_status(Path.home() / "workspace" / "PROJECT")
|
||||
print(f"Complete: {len(status['complete'])}")
|
||||
print(f"Incomplete: {len(status['incomplete'])}")
|
||||
```
|
||||
|
||||
### 3. ralph.sh
|
||||
|
||||
**Locație:** Copiat automat în `PROJECT/scripts/ralph/ralph.sh`
|
||||
**Source:** `~/clawd/skills/ralph/templates/ralph.sh`
|
||||
|
||||
**Funcție:** Loop autonom care apelează Claude Code pentru implementare.
|
||||
|
||||
**Workflow:**
|
||||
1. Citește prd.json
|
||||
2. Selectează story cu priority minimă și passes=false
|
||||
3. Rulează `claude` pentru implementare (folosește Sonnet implicit)
|
||||
4. Quality checks: typecheck, lint, test
|
||||
5. Git commit dacă toate pass
|
||||
6. Marchează passes=true în prd.json
|
||||
7. Update progress.txt cu learnings
|
||||
8. Repetă până toate stories complete sau max iterations
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
cd ~/workspace/PROJECT
|
||||
./scripts/ralph/ralph.sh 20 # max 20 iterații
|
||||
```
|
||||
|
||||
## Workflow Complet (pentru Echo)
|
||||
|
||||
### Seara (20:00) - evening-report
|
||||
|
||||
Echo propune 1-2 proiecte noi + 2-3 features pentru proiecte existente.
|
||||
Marius aprobă: "P pentru P1,P2" sau "F pentru F1,F3"
|
||||
|
||||
### Noapte (23:00) - night-execute
|
||||
|
||||
**Planning cu OPUS (Echo):**
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.path.append('/home/moltbot/clawd')
|
||||
|
||||
from tools.ralph_prd_generator import create_prd_and_json
|
||||
from tools.ralph_workflow import run_ralph
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
# Pentru fiecare proiect aprobat
|
||||
for project in approved_projects:
|
||||
# Generează PRD și prd.json (cu Opus)
|
||||
prd_file, prd_json = create_prd_and_json(
|
||||
project_name=project['name'],
|
||||
description=project['description'],
|
||||
workspace_dir=Path.home() / "workspace"
|
||||
)
|
||||
|
||||
if not prd_file or not prd_json:
|
||||
print(f"❌ Eroare la {project['name']}")
|
||||
continue
|
||||
|
||||
# Git init + commit
|
||||
project_dir = prd_json.parent.parent.parent
|
||||
subprocess.run(["git", "init"], cwd=project_dir)
|
||||
subprocess.run(["git", "add", "."], cwd=project_dir)
|
||||
subprocess.run(["git", "commit", "-m", "Initial commit with PRD"], cwd=project_dir)
|
||||
subprocess.run(["git", "remote", "add", "origin",
|
||||
f"https://gitea.romfast.ro/romfast/{project['name']}"],
|
||||
cwd=project_dir)
|
||||
subprocess.run(["git", "push", "-u", "origin", "main"], cwd=project_dir)
|
||||
|
||||
# Lansează Ralph loop (cu Sonnet)
|
||||
run_ralph(prd_json, max_iterations=20, background=True)
|
||||
|
||||
# Marchează [x] în approved-tasks.md
|
||||
```
|
||||
|
||||
**Implementare cu SONNET (Ralph loop automat):**
|
||||
- ralph.sh rulează autonom în background
|
||||
- Apelează Claude Code (Sonnet) pentru fiecare story
|
||||
- Quality checks + git commits automate
|
||||
- Toate commit-urile push-uite automat
|
||||
|
||||
### Dimineața (08:30) - morning-report
|
||||
|
||||
**Verifică status:**
|
||||
|
||||
```python
|
||||
from tools.ralph_workflow import check_status
|
||||
from pathlib import Path
|
||||
|
||||
for project_name in active_projects:
|
||||
status = check_status(Path.home() / "workspace" / project_name)
|
||||
|
||||
# Raportează în Discord
|
||||
print(f"""
|
||||
## 🔄 Proiecte Ralph
|
||||
|
||||
### {project_name}
|
||||
- ✅ Complete: {len(status['complete'])} stories
|
||||
- 🔄 Incomplete: {len(status['incomplete'])} stories
|
||||
- 🔄 Running: {'DA (PID: ' + str(status.get('pid', '')) + ')' if status['running'] else 'NU'}
|
||||
|
||||
**Stories complete:**
|
||||
{chr(10).join(f" - {s['id']}: {s['title']}" for s in status['complete'][:5])}
|
||||
|
||||
**Learnings:**
|
||||
{chr(10).join(f" {l}" for l in status['learnings'][-3:])}
|
||||
|
||||
🔗 https://gitea.romfast.ro/romfast/{project_name}
|
||||
""")
|
||||
```
|
||||
|
||||
## Structură Proiect
|
||||
|
||||
După workflow complet:
|
||||
|
||||
```
|
||||
~/workspace/PROJECT-NAME/
|
||||
├── tasks/
|
||||
│ └── prd-PROJECT-NAME.md # PRD markdown (generat de Opus)
|
||||
├── scripts/
|
||||
│ └── ralph/
|
||||
│ ├── prd.json # Stories (generat de Opus)
|
||||
│ ├── progress.txt # Learnings (generat de Ralph)
|
||||
│ ├── ralph.sh # Loop autonom
|
||||
│ ├── prompt.md # Instrucțiuni Claude Code
|
||||
│ ├── .ralph.pid # PID proces Ralph
|
||||
│ ├── logs/
|
||||
│ │ └── ralph.log # Output Ralph loop
|
||||
│ ├── archive/ # Arhive rulări anterioare
|
||||
│ └── screenshots/ # Screenshots UI
|
||||
├── src/ # Cod implementat de Ralph (Sonnet)
|
||||
└── .git/ # Git repo → gitea
|
||||
```
|
||||
|
||||
## Format prd.json
|
||||
|
||||
```json
|
||||
{
|
||||
"projectName": "feature-name",
|
||||
"branchName": "ralph/feature-name",
|
||||
"description": "Descriere scurtă",
|
||||
"techStack": {
|
||||
"type": "python",
|
||||
"commands": {
|
||||
"start": "python main.py",
|
||||
"build": "",
|
||||
"lint": "ruff check .",
|
||||
"typecheck": "mypy .",
|
||||
"test": "pytest"
|
||||
},
|
||||
"port": 8000
|
||||
},
|
||||
"userStories": [
|
||||
{
|
||||
"id": "US-001",
|
||||
"title": "Titlu story",
|
||||
"description": "Ca utilizator, vreau...",
|
||||
"priority": 10,
|
||||
"acceptanceCriteria": [
|
||||
"Criteriu specific",
|
||||
"pytest passes"
|
||||
],
|
||||
"requiresBrowserCheck": false,
|
||||
"passes": false,
|
||||
"notes": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Model Strategy (OBLIGATORIU)
|
||||
|
||||
| Componentă | Model | Rulează pe |
|
||||
|------------|-------|------------|
|
||||
| PRD generation | **Opus** | Echo session (moltbot) |
|
||||
| User stories creation | **Opus** | Echo session (moltbot) |
|
||||
| prd.json generation | **Opus** | Echo session (moltbot) |
|
||||
| Code implementation | **Sonnet** | Claude Code (via ralph.sh) |
|
||||
| Quality checks | **Sonnet** | Claude Code (via ralph.sh) |
|
||||
| Git commits | **Sonnet** | Claude Code (via ralph.sh) |
|
||||
|
||||
**Regula:**
|
||||
- **Opus (strategic)** = Planning, PRD, stories, decizie ce se implementează
|
||||
- **Sonnet (tactical)** = Coding, debugging, testing, implementare efectivă
|
||||
|
||||
## Monitorizare
|
||||
|
||||
### În timpul execuției
|
||||
|
||||
```bash
|
||||
# Verifică dacă Ralph rulează
|
||||
ps aux | grep ralph.sh
|
||||
|
||||
# Tail logs live
|
||||
tail -f ~/workspace/PROJECT/scripts/ralph/logs/ralph.log
|
||||
|
||||
# Verifică stories complete
|
||||
jq '.userStories[] | select(.passes == true) | {id, title}' \
|
||||
~/workspace/PROJECT/scripts/ralph/prd.json
|
||||
```
|
||||
|
||||
### Status Python
|
||||
|
||||
```python
|
||||
from tools.ralph_workflow import check_status
|
||||
from pathlib import Path
|
||||
|
||||
status = check_status(Path.home() / "workspace" / "PROJECT")
|
||||
|
||||
print(f"Running: {status['running']}")
|
||||
print(f"Complete: {len(status['complete'])}")
|
||||
print(f"Incomplete: {len(status['incomplete'])}")
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Ralph nu pornește
|
||||
|
||||
```bash
|
||||
# Verifică că ralph.sh există
|
||||
ls -la ~/workspace/PROJECT/scripts/ralph/ralph.sh
|
||||
|
||||
# Verifică prd.json valid
|
||||
jq '.' ~/workspace/PROJECT/scripts/ralph/prd.json
|
||||
```
|
||||
|
||||
### Ralph blochează pe o story
|
||||
|
||||
```bash
|
||||
# Verifică logs
|
||||
tail -50 ~/workspace/PROJECT/scripts/ralph/logs/ralph.log
|
||||
|
||||
# Marchează manual story ca done (pentru a continua)
|
||||
jq '.userStories[0].passes = true' \
|
||||
~/workspace/PROJECT/scripts/ralph/prd.json > tmp && mv tmp prd.json
|
||||
```
|
||||
|
||||
### Oprește Ralph
|
||||
|
||||
```bash
|
||||
# Kill process
|
||||
cat ~/workspace/PROJECT/scripts/ralph/.ralph.pid | xargs kill
|
||||
|
||||
# Sau kill all
|
||||
pkill -f ralph.sh
|
||||
```
|
||||
|
||||
## Templates Source
|
||||
|
||||
**Locație:** `~/clawd/skills/ralph/templates/`
|
||||
|
||||
**Fișiere:**
|
||||
- `ralph.sh` - Script principal loop
|
||||
- `prompt.md` - Instrucțiuni pentru Claude Code per iterație
|
||||
- `prd-template.json` - Template prd.json (opțional)
|
||||
|
||||
**NU edita template-urile** - sunt copiate automat în fiecare proiect.
|
||||
|
||||
## Diferențe față de sistemul vechi
|
||||
|
||||
| Înainte | Acum |
|
||||
|---------|------|
|
||||
| SSH către claude-agent | Local pe moltbot |
|
||||
| Claude Code prin tmux/pexpect | ralph.sh apelează claude direct |
|
||||
| Skills /ralph:prd interactive | Python generator în ralph_prd_generator.py |
|
||||
| Control manual sesiuni | Complet automat background |
|
||||
| Greu de debuguit | Logs clare, status checkable |
|
||||
|
||||
---
|
||||
|
||||
**Status:** ✅ PRODUCTION READY
|
||||
**Testat:** 2026-02-09
|
||||
**Version:** 2.0 (finală)
|
||||
**Next:** Integrare night-execute
|
||||
Reference in New Issue
Block a user