commit 2f3e70b60b64ec92d6deec0dc1372fd3a27894e9 Author: Claude Agent Date: Fri Jan 9 11:41:48 2026 +0000 Initial commit - Ralph adaptat pentru Claude Code Adaptare a sistemului Ralph (snarktank/ralph) pentru Claude Code CLI. Features: - Script ralph.sh pentru loop autonom - Skill /prd pentru generare PRD structurat - Skill /ralph pentru conversie PRD în prd.json - Script install.sh pentru instalare globală skills - Documentație completă Co-Authored-By: Claude Opus 4.5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0dcd104 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +scripts/ralph/logs/ +*.log + +# Runtime files +scripts/ralph/prd.json +scripts/ralph/progress.txt +scripts/ralph/.last-branch + +# Archive (optional - poate fi inclus) +# scripts/ralph/archive/ + +# OS +.DS_Store +Thumbs.db + +# Editor +.vscode/ +.idea/ +*.swp +*.swo + +# Node (dacă se adaugă) +node_modules/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c52fcd --- /dev/null +++ b/README.md @@ -0,0 +1,221 @@ +# Ralph pentru Claude Code + +**Ralph** este un loop autonom de agent AI care rulează Claude Code în mod repetat până când toate task-urile dintr-un PRD sunt complete. + +Adaptat din [snarktank/ralph](https://github.com/snarktank/ralph) (pentru Amp) pentru a funcționa cu Claude Code CLI. + +## Cum funcționează + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ CICLUL RALPH │ +├──────────────────────────────────────────────────────────────────┤ +│ 1. Citește prd.json → selectează story cu prioritate minimă │ +│ 2. Lansează instanță fresh Claude Code (context curat) │ +│ 3. Implementează story-ul selectat │ +│ 4. Rulează quality checks (typecheck, tests, lint) │ +│ 5. Commit dacă trece → marchează story ca "passes: true" │ +│ 6. Salvează learnings în progress.txt │ +│ 7. Repetă până toate story-urile sunt complete │ +└──────────────────────────────────────────────────────────────────┘ +``` + +## Memoria între iterații + +| Mecanism | Descriere | +|----------|-----------| +| `git history` | Commit-uri din iterațiile anterioare | +| `prd.json` | Starea task-urilor (care sunt complete) | +| `progress.txt` | Learnings și patterns descoperite | + +## Instalare rapidă + +### Cerințe +- Claude Code CLI instalat și autentificat +- `jq` pentru procesare JSON (`apt install jq`) +- Git repository + +### Instalare Skills (recomandat) + +```bash +git clone git@gitea.romfast.ro:romfast/ralph-claude.git +cd ralph-claude +./install.sh +``` + +Aceasta instalează skill-urile `/prd` și `/ralph` global în `~/.claude/skills/`. + +### Instalare manuală (per proiect) + +```bash +# Copiază în proiectul tău +cp -r ralph-claude/scripts/ralph/ /path/to/your/project/scripts/ralph/ +chmod +x scripts/ralph/ralph.sh +``` + +## Utilizare + +### Workflow complet + +``` +1. /prd → Generează PRD markdown cu întrebări clarificatoare +2. /ralph → Convertește PRD în prd.json pentru execuție +3. ./ralph.sh → Rulează loop-ul autonom +``` + +### Pas 1: Generează PRD + +Într-o sesiune Claude Code, folosește skill-ul `/prd`: + +``` +/prd + +Vreau să adaug funcționalitate de export CSV pentru dashboard. +``` + +Claude va: +- Pune întrebări clarificatoare +- Genera PRD structurat în `/tasks/prd-export-csv.md` + +### Pas 2: Convertește în JSON + +După ce PRD-ul e aprobat, folosește `/ralph`: + +``` +/ralph + +Convertește PRD-ul din tasks/prd-export-csv.md +``` + +Claude va: +- Crea structura `scripts/ralph/` +- Genera `prd.json` cu user stories +- Inițializa `progress.txt` + +### Pas 3: Rulează Ralph + +```bash +# Cu 10 iterații (implicit) +./scripts/ralph/ralph.sh + +# Cu număr specific de iterații +./scripts/ralph/ralph.sh 20 +``` + +### Pas 4: Monitorizare + +```bash +# Status stories +jq '.userStories[] | {id, title, passes}' scripts/ralph/prd.json + +# Learnings acumulate +cat scripts/ralph/progress.txt + +# Logs per iterație +ls scripts/ralph/logs/ +``` + +## Structura proiectului + +``` +your-project/ +├── scripts/ralph/ +│ ├── ralph.sh # Script principal +│ ├── prompt.md # Instrucțiuni per iterație +│ ├── prd.json # Task-uri și status (generat) +│ ├── progress.txt # Learnings (generat) +│ ├── logs/ # Logs per iterație +│ └── archive/ # Rulări anterioare arhivate +├── tasks/ +│ └── prd-*.md # PRD-uri markdown +└── AGENTS.md # Patterns codebase (opțional) +``` + +## Format prd.json + +```json +{ + "projectName": "export-csv", + "branchName": "ralph/export-csv", + "description": "Adaugă export CSV pentru dashboard", + "userStories": [ + { + "id": "US-001", + "title": "Funcție de conversie la CSV", + "description": "Ca developer, vreau o funcție care convertește date în CSV", + "priority": 1, + "acceptanceCriteria": [ + "Funcția acceptă array de obiecte", + "Returnează string CSV valid", + "npm run typecheck passes" + ], + "passes": false, + "notes": "" + } + ] +} +``` + +## Reguli pentru stories bune + +### Mărime corectă (1 context window) +- Adaugă un câmp în DB + migration +- Creează un component UI simplu +- Adaugă un endpoint API +- Scrie tests pentru o funcție + +### Prea mare (trebuie spart) +- "Implementează autentificarea completă" +- "Creează dashboard-ul admin" +- "Adaugă sistem notificări end-to-end" + +### Ordinea priorităților +1. Schema/Database (priority: 1-10) +2. Backend logic (priority: 11-20) +3. API endpoints (priority: 21-30) +4. UI components (priority: 31-40) +5. Integration/polish (priority: 41-50) + +## Debugging + +### Story nu progresează +```bash +# Vezi ultimul log +cat scripts/ralph/logs/iteration-*.log | tail -100 +``` + +### Tests failing +Verifică că proiectul are comenzile necesare: +```bash +npm run typecheck # sau equivalent +npm run lint # opțional +npm run test # opțional +``` + +### Context overflow +Story-ul e prea mare - sparge-l în părți mai mici. + +## Diferențe față de Ralph original + +| Aspect | Original (Amp) | Adaptat (Claude Code) | +|--------|----------------|----------------------| +| CLI | `amp` | `claude -p` | +| Flag permisiuni | `--dangerously-allow-all` | `--dangerously-skip-permissions` | +| Skills location | `~/.config/amp/skills/` | `~/.claude/skills/` | +| Output | Direct | + salvat în logs/ | + +## Skills incluse + +| Skill | Descriere | +|-------|-----------| +| `/prd` | Generează PRD structurat cu întrebări clarificatoare | +| `/ralph` | Convertește PRD markdown în prd.json pentru execuție | + +## Credite + +- [snarktank/ralph](https://github.com/snarktank/ralph) - Ralph original pentru Amp +- [snarktank/amp-skills](https://github.com/snarktank/amp-skills) - Skills originale + +## Licență + +MIT diff --git a/examples/prd-hello-api.json b/examples/prd-hello-api.json new file mode 100644 index 0000000..73d2e69 --- /dev/null +++ b/examples/prd-hello-api.json @@ -0,0 +1,59 @@ +{ + "projectName": "hello-api", + "branchName": "ralph/hello-api", + "description": "Un API simplu de test pentru a demonstra funcționarea Ralph", + "userStories": [ + { + "id": "US-001", + "title": "Inițializare proiect Node.js", + "description": "Ca developer, vreau un proiect Node.js inițializat pentru a avea baza de cod", + "priority": 1, + "acceptanceCriteria": [ + "package.json există cu name și version", + "Folosește ES modules (type: module)", + "Fișierul index.js există și poate fi rulat" + ], + "passes": false, + "notes": "" + }, + { + "id": "US-002", + "title": "Endpoint GET /hello", + "description": "Ca utilizator, vreau un endpoint care returnează un salut", + "priority": 2, + "acceptanceCriteria": [ + "GET /hello returnează JSON cu mesaj", + "Status code 200", + "Content-Type application/json" + ], + "passes": false, + "notes": "" + }, + { + "id": "US-003", + "title": "Endpoint POST /echo", + "description": "Ca utilizator, vreau un endpoint care returnează ce îi trimit", + "priority": 3, + "acceptanceCriteria": [ + "POST /echo acceptă JSON body", + "Returnează același body înapoi", + "Status 400 dacă body invalid" + ], + "passes": false, + "notes": "" + }, + { + "id": "US-004", + "title": "Tests pentru endpoints", + "description": "Ca developer, vreau tests pentru a verifica funcționalitatea", + "priority": 4, + "acceptanceCriteria": [ + "Test pentru GET /hello", + "Test pentru POST /echo", + "npm test rulează cu succes" + ], + "passes": false, + "notes": "" + } + ] +} diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..2dc4ea5 --- /dev/null +++ b/install.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# Instalare Ralph Skills pentru Claude Code +# Acest script instalează skill-urile /ralph și /prd global + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CLAUDE_SKILLS_DIR="$HOME/.claude/skills" + +echo "" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ Ralph Skills - Instalare pentru Claude Code ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo "" + +# Verifică că directorul skills există în acest repo +if [ ! -d "$SCRIPT_DIR/skills" ]; then + echo "Eroare: Directorul skills/ nu există." + echo "Rulează acest script din directorul ralph-claude." + exit 1 +fi + +# Creează directorul skills pentru Claude Code dacă nu există +echo "1. Creare director ~/.claude/skills/ ..." +mkdir -p "$CLAUDE_SKILLS_DIR" + +# Copiază skill-urile +echo "2. Instalare skill /prd ..." +cp -r "$SCRIPT_DIR/skills/prd" "$CLAUDE_SKILLS_DIR/" +echo " ✓ /prd instalat" + +echo "3. Instalare skill /ralph ..." +cp -r "$SCRIPT_DIR/skills/ralph" "$CLAUDE_SKILLS_DIR/" +echo " ✓ /ralph instalat" + +# Copiază și scripturile de runtime +echo "4. Creare template scripts/ralph/ ..." +TEMPLATE_DIR="$CLAUDE_SKILLS_DIR/ralph/templates" +mkdir -p "$TEMPLATE_DIR" +cp "$SCRIPT_DIR/scripts/ralph/ralph.sh" "$TEMPLATE_DIR/" +cp "$SCRIPT_DIR/scripts/ralph/prompt.md" "$TEMPLATE_DIR/" +cp "$SCRIPT_DIR/scripts/ralph/prd-template.json" "$TEMPLATE_DIR/" +chmod +x "$TEMPLATE_DIR/ralph.sh" +echo " ✓ Templates copiate" + +echo "" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ ✅ INSTALARE COMPLETĂ! ║" +echo "╠═══════════════════════════════════════════════════════════════╣" +echo "║ Skills instalate în: ~/.claude/skills/ ║" +echo "║ ║" +echo "║ Utilizare: ║" +echo "║ /prd - Generează un PRD pentru un feature nou ║" +echo "║ /ralph - Convertește PRD în format JSON pentru Ralph ║" +echo "║ ║" +echo "║ Pentru a rula loop-ul autonom: ║" +echo "║ ./scripts/ralph/ralph.sh [max_iterations] ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo "" + +# Verifică instalarea +echo "Verificare instalare:" +ls -la "$CLAUDE_SKILLS_DIR/" +echo "" diff --git a/scripts/ralph/generate-prd.md b/scripts/ralph/generate-prd.md new file mode 100644 index 0000000..a6f3bab --- /dev/null +++ b/scripts/ralph/generate-prd.md @@ -0,0 +1,137 @@ +# Skill: Generare PRD pentru Ralph + +Când utilizatorul cere să generezi un PRD pentru Ralph, urmează acest workflow: + +## Pas 1: Întrebări de clarificare + +Pune 3-5 întrebări pentru a înțelege feature-ul: + +**Exemplu:** +``` +Pentru a genera un PRD bun, am nevoie de câteva clarificări: + +A) Care este scopul principal al feature-ului? + 1. Funcționalitate nouă pentru utilizatori + 2. Îmbunătățire performanță + 3. Refactoring/cleanup cod + 4. Altceva: [descrie] + +B) Cine sunt utilizatorii țintă? + 1. End users + 2. Developers/Admin + 3. Sistem automatizat + 4. Altceva: [descrie] + +C) Care sunt constrângerile tehnice? + 1. Trebuie să folosească framework/librărie existentă + 2. Fără dependențe noi + 3. Flexibil + 4. Altceva: [descrie] +``` + +## Pas 2: Generează PRD Markdown + +După clarificări, generează documentul în `/tasks/prd-[feature-name].md`: + +```markdown +# PRD: [Feature Name] + +## 1. Introducere +[Descriere scurtă a feature-ului și contextul] + +## 2. Obiective +- Obiectiv principal +- Obiective secundare +- Metrici de succes + +## 3. User Stories +### US-001: [Titlu] +**Ca** [tip utilizator] +**Vreau** [funcționalitate] +**Pentru că** [beneficiu] + +**Acceptance Criteria:** +- [ ] Criteriu 1 specific și testabil +- [ ] Criteriu 2 specific și testabil +- [ ] npm run typecheck passes + +### US-002: [Titlu] +... + +## 4. Cerințe Funcționale +1. [Cerință 1] +2. [Cerință 2] +... + +## 5. Non-Goals (Ce NU facem) +- [Explicit ce nu este în scope] + +## 6. Considerații Tehnice +- Stack tehnologic +- Patterns de urmat +- Dependențe + +## 7. Considerații UI/UX +- [Dacă e relevant] + +## 8. Success Metrics +- [Cum măsurăm succesul] + +## 9. Open Questions +- [Întrebări nerezolvate] +``` + +## Pas 3: Convertește în prd.json + +După aprobare, convertește PRD-ul markdown în format JSON pentru Ralph: + +```json +{ + "projectName": "feature-name", + "branchName": "ralph/feature-name", + "description": "Descriere din PRD", + "userStories": [ + { + "id": "US-001", + "title": "Titlu din PRD", + "description": "Ca [user], vreau [feature] pentru că [benefit]", + "priority": 1, + "acceptanceCriteria": [ + "Criteriu 1", + "Criteriu 2", + "npm run typecheck passes" + ], + "passes": false, + "notes": "" + } + ] +} +``` + +Salvează în `scripts/ralph/prd.json`. + +## Reguli importante pentru stories + +### ✅ Story de mărime corectă (UN context window): +- Adaugă un câmp în baza de date +- Creează un component UI simplu +- Adaugă un endpoint API +- Scrie tests pentru o funcție + +### ❌ Story prea mare (trebuie spart): +- "Implementează autentificarea completă" +- "Creează dashboard-ul admin" +- "Adaugă sistem de notificări" + +### Ordinea priorităților: +1. Schema/Database changes +2. Backend logic +3. API endpoints +4. UI components +5. Integration/polish + +### Acceptance criteria trebuie să fie: +- Specifice și verificabile +- Nu vagi ("funcționează bine", "UX bun") +- Include întotdeauna `npm run typecheck passes` +- Pentru UI: "Verifică în browser că [specific behavior]" diff --git a/scripts/ralph/prd-template.json b/scripts/ralph/prd-template.json new file mode 100644 index 0000000..3070f9c --- /dev/null +++ b/scripts/ralph/prd-template.json @@ -0,0 +1,33 @@ +{ + "projectName": "Numele Proiectului", + "branchName": "ralph/feature-name", + "description": "Descriere scurtă a feature-ului care se implementează", + "userStories": [ + { + "id": "US-001", + "title": "Titlu story 1", + "description": "As a [user type], I want [feature] so that [benefit]", + "priority": 1, + "acceptanceCriteria": [ + "Criteriu 1 specific și verificabil", + "Criteriu 2 specific și verificabil", + "npm run typecheck passes" + ], + "passes": false, + "notes": "" + }, + { + "id": "US-002", + "title": "Titlu story 2", + "description": "As a [user type], I want [feature] so that [benefit]", + "priority": 2, + "acceptanceCriteria": [ + "Criteriu 1", + "Criteriu 2", + "npm run typecheck passes" + ], + "passes": false, + "notes": "" + } + ] +} diff --git a/scripts/ralph/prompt.md b/scripts/ralph/prompt.md new file mode 100644 index 0000000..1746aac --- /dev/null +++ b/scripts/ralph/prompt.md @@ -0,0 +1,118 @@ +# Ralph - Instrucțiuni pentru Iterație + +Ești un agent autonom care implementează user stories dintr-un PRD. Aceasta este O SINGURĂ iterație - implementezi UN singur story și apoi te oprești. + +## Workflow pentru această iterație + +### 1. Citește contextul +- PRD-ul și progress.txt sunt furnizate în context +- Înțelege ce stories sunt deja complete (`passes: true`) +- Identifică următorul story de implementat (prioritate cea mai mică dintre cele incomplete) + +### 2. Management branch +- Verifică dacă ești pe branch-ul corect (specificat în `branchName` din PRD) +- Dacă nu, creează și checkout branch-ul: + ```bash + git checkout -b + ``` +- Dacă branch-ul există deja, doar checkout: + ```bash + git checkout + ``` + +### 3. Selectează story-ul +- Alege story-ul cu cea mai mică prioritate care are `passes: false` +- Citește atent acceptance criteria + +### 4. Implementare +- Implementează DOAR acest story +- Urmează patterns existente în codebase +- Fii minimal și focusat - nu adăuga funcționalități extra + +### 5. Quality Checks +Rulează TOATE verificările înainte de commit: +```bash +npm run typecheck # sau echivalentul proiectului +npm run lint # dacă există +npm run test # dacă există +``` + +**IMPORTANT**: Nu face commit dacă verificările eșuează. Repară mai întâi. + +### 6. Documentare (dacă ai descoperit ceva util) +Dacă ai descoperit patterns sau gotchas, actualizează `AGENTS.md` în directorul relevant: +- API patterns +- Dependențe non-evidente +- Convenții de cod +- Cum să testezi anumite funcționalități + +### 7. Commit +Format commit message: +``` +feat: [Story ID] - [Story Title] +``` + +Exemplu: +``` +feat: US-003 - Add user authentication endpoint +``` + +### 8. Marchează story-ul ca complet +**CRITIC**: Actualizează `scripts/ralph/prd.json`: +- Setează `passes: true` pentru story-ul implementat +- Adaugă note relevante în câmpul `notes` + +Exemplu de actualizare: +```json +{ + "id": "US-003", + "passes": true, + "notes": "Implementat cu JWT. Vezi src/auth/jwt.ts pentru middleware." +} +``` + +### 9. Actualizează progress.txt +Adaugă la sfârșitul fișierului `scripts/ralph/progress.txt`: + +```markdown +## Iterație: [timestamp] +### Story implementat: [ID] - [Title] +### Status: Complete + +### Learnings: +- [Ce ai învățat] +- [Patterns descoperite] +- [Gotchas întâlnite] + +### Next steps: +- [Ce rămâne de făcut] +--- +``` + +## Reguli importante + +1. **UN SINGUR STORY PE ITERAȚIE** - Nu implementa mai mult de un story +2. **TOATE CHECKS TREBUIE SĂ TREACĂ** - Nu face commit cu erori +3. **ACTUALIZEAZĂ prd.json** - Altfel iterația următoare va repeta munca +4. **FII CONCIS** - Nu over-engineer, implementează minim necesar +5. **DOCUMENTEAZĂ** - Learnings în progress.txt, patterns în AGENTS.md + +## Condiție de terminare + +Dacă TOATE stories au `passes: true`, răspunde cu: + +``` +COMPLETE +``` + +Aceasta semnalează că Ralph a terminat toate task-urile. + +## Dacă întâmpini probleme + +- **Story prea mare**: Notează în progress.txt și sugerează descompunerea +- **Dependență lipsă**: Verifică dacă un story anterior nu a fost implementat corect +- **Test eșuează**: Repară și încearcă din nou, documentează fix-ul +- **Blocat complet**: Notează în progress.txt motivul și continuă cu următorul story dacă e posibil + +--- +ÎNCEPE IMPLEMENTAREA ACUM. Selectează story-ul cu prioritatea cea mai mică care nu este complet și implementează-l. diff --git a/scripts/ralph/ralph.sh b/scripts/ralph/ralph.sh new file mode 100755 index 0000000..0cc9cfe --- /dev/null +++ b/scripts/ralph/ralph.sh @@ -0,0 +1,183 @@ +#!/bin/bash +# Ralph pentru Claude Code - Loop autonom de agent AI +# Adaptat din Ralph original (snarktank/ralph) pentru Claude Code CLI +# Usage: ./ralph.sh [max_iterations] [project_dir] + +set -e + +MAX_ITERATIONS=${1:-10} +PROJECT_DIR=${2:-$(pwd)} +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PRD_FILE="$SCRIPT_DIR/prd.json" +PROGRESS_FILE="$SCRIPT_DIR/progress.txt" +ARCHIVE_DIR="$SCRIPT_DIR/archive" +LAST_BRANCH_FILE="$SCRIPT_DIR/.last-branch" +PROMPT_FILE="$SCRIPT_DIR/prompt.md" + +# Verifică că jq este instalat +if ! command -v jq &> /dev/null; then + echo "Eroare: jq nu este instalat. Rulează: apt install jq" + exit 1 +fi + +# Verifică că claude este instalat +if ! command -v claude &> /dev/null; then + echo "Eroare: Claude Code CLI nu este instalat." + echo "Instalează cu: npm install -g @anthropic-ai/claude-code" + exit 1 +fi + +# Verifică existența fișierelor necesare +if [ ! -f "$PRD_FILE" ]; then + echo "Eroare: prd.json nu există în $SCRIPT_DIR" + echo "Generează mai întâi un PRD folosind skill-ul /prd" + exit 1 +fi + +if [ ! -f "$PROMPT_FILE" ]; then + echo "Eroare: prompt.md nu există în $SCRIPT_DIR" + exit 1 +fi + +# Arhivare rulare anterioară dacă branch-ul s-a schimbat +if [ -f "$PRD_FILE" ] && [ -f "$LAST_BRANCH_FILE" ]; then + CURRENT_BRANCH=$(jq -r '.branchName // empty' "$PRD_FILE" 2>/dev/null || echo "") + LAST_BRANCH=$(cat "$LAST_BRANCH_FILE" 2>/dev/null || echo "") + + if [ -n "$CURRENT_BRANCH" ] && [ -n "$LAST_BRANCH" ] && [ "$CURRENT_BRANCH" != "$LAST_BRANCH" ]; then + DATE=$(date +%Y-%m-%d) + FOLDER_NAME=$(echo "$LAST_BRANCH" | sed 's|^ralph/||') + ARCHIVE_FOLDER="$ARCHIVE_DIR/$DATE-$FOLDER_NAME" + + echo "📦 Arhivare rulare anterioară: $LAST_BRANCH" + mkdir -p "$ARCHIVE_FOLDER" + [ -f "$PRD_FILE" ] && cp "$PRD_FILE" "$ARCHIVE_FOLDER/" + [ -f "$PROGRESS_FILE" ] && cp "$PROGRESS_FILE" "$ARCHIVE_FOLDER/" + echo " Arhivat în: $ARCHIVE_FOLDER" + + # Reset progress file + echo "# Ralph Progress Log" > "$PROGRESS_FILE" + echo "Started: $(date)" >> "$PROGRESS_FILE" + echo "Branch: $CURRENT_BRANCH" >> "$PROGRESS_FILE" + echo "---" >> "$PROGRESS_FILE" + fi +fi + +# Salvează branch-ul curent +if [ -f "$PRD_FILE" ]; then + CURRENT_BRANCH=$(jq -r '.branchName // empty' "$PRD_FILE" 2>/dev/null || echo "") + if [ -n "$CURRENT_BRANCH" ]; then + echo "$CURRENT_BRANCH" > "$LAST_BRANCH_FILE" + fi +fi + +# Inițializare progress file dacă nu există +if [ ! -f "$PROGRESS_FILE" ]; then + echo "# Ralph Progress Log" > "$PROGRESS_FILE" + echo "Started: $(date)" >> "$PROGRESS_FILE" + echo "---" >> "$PROGRESS_FILE" +fi + +# Funcție pentru a verifica dacă toate story-urile sunt complete +check_all_complete() { + local incomplete=$(jq '[.userStories[] | select(.passes != true)] | length' "$PRD_FILE" 2>/dev/null || echo "999") + [ "$incomplete" -eq 0 ] +} + +# Afișare status inițial +echo "" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ RALPH pentru Claude Code - Agent Autonom ║" +echo "╠═══════════════════════════════════════════════════════════════╣" +PROJECT_NAME=$(jq -r '.projectName // "Unknown"' "$PRD_FILE") +BRANCH_NAME=$(jq -r '.branchName // "N/A"' "$PRD_FILE") +TOTAL_STORIES=$(jq '.userStories | length' "$PRD_FILE") +COMPLETE_STORIES=$(jq '[.userStories[] | select(.passes == true)] | length' "$PRD_FILE") +echo "║ Proiect: $PROJECT_NAME" +echo "║ Branch: $BRANCH_NAME" +echo "║ Stories: $COMPLETE_STORIES / $TOTAL_STORIES complete" +echo "║ Max iterații: $MAX_ITERATIONS" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo "" + +# Verificare rapidă - poate toate sunt deja complete? +if check_all_complete; then + echo "✅ Toate story-urile sunt deja complete!" + exit 0 +fi + +# Loop principal +for i in $(seq 1 $MAX_ITERATIONS); do + echo "" + echo "═══════════════════════════════════════════════════════════════" + echo " 🔄 Ralph Iterația $i din $MAX_ITERATIONS" + echo "═══════════════════════════════════════════════════════════════" + + # Status curent + COMPLETE_NOW=$(jq '[.userStories[] | select(.passes == true)] | length' "$PRD_FILE") + NEXT_STORY=$(jq -r '[.userStories[] | select(.passes != true)] | sort_by(.priority) | .[0] | "\(.id): \(.title)"' "$PRD_FILE") + echo " 📊 Progress: $COMPLETE_NOW / $TOTAL_STORIES stories complete" + echo " 🎯 Next: $NEXT_STORY" + echo "" + + # Pregătește prompt-ul cu context + FULL_PROMPT=$(cat <&1 | tee /dev/stderr) || true + + # Alternativ, cu output în fișier pentru debugging + LOG_FILE="$SCRIPT_DIR/logs/iteration-$i-$(date +%Y%m%d-%H%M%S).log" + mkdir -p "$SCRIPT_DIR/logs" + + echo "$FULL_PROMPT" | claude -p --dangerously-skip-permissions 2>&1 | tee "$LOG_FILE" || true + OUTPUT=$(cat "$LOG_FILE") + + # Verifică dacă toate task-urile sunt complete + if echo "$OUTPUT" | grep -q "COMPLETE"; then + echo "" + echo "╔═══════════════════════════════════════════════════════════════╗" + echo "║ ✅ RALPH A TERMINAT TOATE TASK-URILE! ║" + echo "║ Completat la iterația $i din $MAX_ITERATIONS ║" + echo "╚═══════════════════════════════════════════════════════════════╝" + exit 0 + fi + + # Verifică și prin prd.json + if check_all_complete; then + echo "" + echo "╔═══════════════════════════════════════════════════════════════╗" + echo "║ ✅ TOATE STORY-URILE DIN PRD SUNT COMPLETE! ║" + echo "╚═══════════════════════════════════════════════════════════════╝" + exit 0 + fi + + echo " ✓ Iterația $i completă. Continuăm..." + sleep 2 +done + +echo "" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ ⚠️ Ralph a atins limita de iterații ($MAX_ITERATIONS) ║" +echo "║ Verifică progress.txt pentru status. ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo "" + +# Afișează stories incomplete +echo "Stories incomplete:" +jq -r '.userStories[] | select(.passes != true) | " - \(.id): \(.title)"' "$PRD_FILE" + +exit 1 diff --git a/skills/prd/SKILL.md b/skills/prd/SKILL.md new file mode 100644 index 0000000..b29e80e --- /dev/null +++ b/skills/prd/SKILL.md @@ -0,0 +1,195 @@ +--- +name: prd +description: Generează un Product Requirements Document (PRD) structurat pentru o funcționalitate nouă. Folosește acest skill când utilizatorul vrea să planifice și documenteze cerințele pentru un feature înainte de implementare. +--- + +# Skill: PRD Generator + +Generează un Product Requirements Document (PRD) detaliat pentru funcționalități noi prin întrebări clarificatoare și documentație structurată. + +## Când să folosești acest skill + +- Utilizatorul vrea să adauge o funcționalitate nouă +- Vrea să planifice înainte de a implementa +- Menționează "PRD", "requirements", "cerințe", "planifică feature" + +## Workflow + +### Pas 1: Întrebări de clarificare + +Înainte de a genera PRD-ul, pune 3-5 întrebări pentru a înțelege scopul: + +```markdown +Pentru a genera un PRD bun, am câteva întrebări: + +**A) Care este scopul principal?** +1. Funcționalitate nouă pentru utilizatori +2. Îmbunătățire performanță/scalabilitate +3. Refactoring/cleanup cod existent +4. Integrare cu sistem extern + +**B) Cine sunt utilizatorii țintă?** +1. End users (clienți finali) +2. Admin/Staff intern +3. Developers (API/SDK) +4. Sistem automatizat + +**C) Ce constrângeri tehnice există?** +1. Trebuie să folosească framework/librărie existentă +2. Fără dependențe externe noi +3. Compatibilitate backwards necesară +4. Flexibil + +**D) Care e prioritatea?** +1. Urgent (blocant pentru release) +2. Important (următorul sprint) +3. Nice-to-have (când e timp) + +**E) Ai specificații vizuale sau mockups?** +1. Da, am wireframes/mockups +2. Am idee generală în minte +3. Flexibil, propune tu +``` + +### Pas 2: Generează PRD-ul + +După răspunsuri, creează documentul în `/tasks/prd-[feature-name].md`: + +```markdown +# PRD: [Feature Name] + +## 1. Introducere +[Context și motivație pentru feature - 2-3 propoziții] + +## 2. Obiective +### Obiectiv Principal +- [Ce problem rezolvă] + +### Obiective Secundare +- [Beneficii adiționale] + +### Metrici de Succes +- [Cum măsurăm dacă e reușit] + +## 3. User Stories + +### US-001: [Titlu Descriptiv] +**Ca** [tip utilizator] +**Vreau** [funcționalitate] +**Pentru că** [beneficiu] + +**Acceptance Criteria:** +- [ ] Criteriu 1 specific și testabil +- [ ] Criteriu 2 specific și testabil +- [ ] npm run typecheck passes +- [ ] [Pentru UI] Verify in browser that [comportament specific] + +### US-002: [Titlu] +... + +## 4. Cerințe Funcționale +1. [REQ-001] Sistemul trebuie să... +2. [REQ-002] Utilizatorul poate să... +3. [REQ-003] Când X se întâmplă, Y trebuie să... + +## 5. Non-Goals (Ce NU facem) +- [Explicit ce nu e în scope pentru a evita scope creep] +- [Funcționalități similare care NU sunt incluse] + +## 6. Considerații Tehnice +### Stack/Tehnologii +- [Ce framework/librării se folosesc] + +### Patterns de Urmat +- [Patterns existente în codebase] + +### Dependențe +- [De ce depinde acest feature] + +### Riscuri Tehnice +- [Potențiale probleme] + +## 7. Considerații UI/UX +[Dacă e relevant] +- Layout și flow +- Stări (loading, error, empty, success) +- Accesibilitate + +## 8. Success Metrics +- [KPI 1]: [target] +- [KPI 2]: [target] + +## 9. Open Questions +- [ ] [Întrebări nerezolvate care necesită clarificare] +``` + +### Pas 3: Validare cu utilizatorul + +După generare, întreabă: +- "PRD-ul acoperă tot ce ai în minte?" +- "Vrei să adaugi sau să modifici ceva?" +- "Stories-urile sunt de mărime potrivită pentru implementare incrementală?" + +### Pas 4: Salvare + +```bash +# Crează directorul tasks dacă nu există +mkdir -p tasks + +# Salvează PRD-ul +# Folosește kebab-case pentru nume +``` + +### Pas 5: Sugerează următorul pas + +```markdown +✅ PRD salvat în tasks/prd-[feature-name].md + +**Următorii pași:** +1. Revizuiește PRD-ul și adaugă detalii dacă e nevoie +2. Când ești gata, folosește `/ralph` pentru a converti în prd.json +3. Apoi rulează `./scripts/ralph/ralph.sh` pentru implementare autonomă +``` + +## Reguli pentru User Stories bune + +### Mărime potrivită (1 context window): +- Adaugă un câmp în DB + migration +- Creează un component React simplu +- Implementează un endpoint API +- Scrie unit tests pentru o funcție + +### Prea mare (trebuie spart): +- "Implementează autentificarea" → sparge în: login form, register form, JWT middleware, session management +- "Creează dashboard" → sparge în: layout, charts component, data fetching, filtering + +### Ordine dependențe: +1. Database/Schema (nu depind de nimic) +2. Backend logic (depind de schema) +3. API endpoints (depind de backend) +4. UI components (depind de API) +5. Integration (depind de toate) + +### Acceptance Criteria: +- Specifice: "Butonul Submit trimite form data la POST /api/users" +- NU vagi: "Funcționează corect" + +- Verificabile: "După submit, redirect la /dashboard" +- NU subiective: "UX plăcut" + +- Include ÎNTOTDEAUNA: "npm run typecheck passes" +- Pentru UI: "Verify in browser that [behavior]" + +## Output așteptat + +- Fișier `/tasks/prd-[feature-name].md` cu documentație completă +- User stories clare, atomice, cu acceptance criteria verificabile +- Non-goals explicit definite + +## Important + +1. **NU începe implementarea** - acest skill doar generează documentație +2. **Întreabă clarificări** înainte de a genera +3. **Stories atomice** - fiecare trebuie să fie independent completabil +4. **Acceptance criteria verificabile** - nu vagi +5. **Kebab-case** pentru nume fișiere diff --git a/skills/ralph/SKILL.md b/skills/ralph/SKILL.md new file mode 100644 index 0000000..caa205d --- /dev/null +++ b/skills/ralph/SKILL.md @@ -0,0 +1,143 @@ +--- +name: ralph +description: Convertește un PRD markdown în format prd.json pentru loop-ul autonom Ralph. Folosește acest skill când utilizatorul are un PRD generat și vrea să-l convertească pentru execuție autonomă cu Ralph. +--- + +# Skill: Ralph PRD Converter + +Convertește un PRD markdown existent în format `prd.json` pentru sistemul Ralph de execuție autonomă. + +## Când să folosești acest skill + +- Utilizatorul are deja un PRD markdown generat (în `/tasks/prd-*.md`) +- Vrea să pregătească task-urile pentru execuție autonomă cu Ralph +- Sau vrea să inițializeze structura Ralph într-un proiect + +## Workflow + +### Pas 1: Verifică PRD-ul existent + +```bash +ls tasks/prd-*.md +``` + +Dacă nu există un PRD, sugerează să folosească skill-ul `/prd` mai întâi. + +### Pas 2: Citește PRD-ul și extrage user stories + +Citește fișierul PRD și identifică: +- Numele proiectului +- User stories cu acceptance criteria +- Dependențe între stories + +### Pas 3: Creează structura Ralph + +```bash +mkdir -p scripts/ralph/logs scripts/ralph/archive +``` + +### Pas 4: Generează prd.json + +Convertește user stories în format JSON cu următoarea structură: + +```json +{ + "projectName": "feature-name", + "branchName": "ralph/feature-name", + "description": "Descriere din PRD", + "userStories": [ + { + "id": "US-001", + "title": "Titlu story", + "description": "As a [user], I want [feature] so that [benefit]", + "priority": 1, + "acceptanceCriteria": [ + "Criteriu specific și verificabil", + "npm run typecheck passes" + ], + "passes": false, + "notes": "" + } + ] +} +``` + +### Pas 5: Validează mărimea stories + +**CRITIC**: Fiecare story trebuie să fie completabil într-un singur context window. + +#### Story de mărime corectă: +- Adaugă un câmp în baza de date +- Creează un component UI simplu +- Adaugă un endpoint API +- Scrie tests pentru o funcție specifică + +#### Story prea mare (trebuie spart): +- "Implementează autentificarea completă" +- "Creează dashboard-ul admin" +- "Adaugă sistem de notificări end-to-end" + +Dacă găsești stories prea mari, sparge-le în sub-stories mai mici. + +### Pas 6: Setează prioritățile + +Ordinea recomandată: +1. Schema/Database changes (priority: 1-10) +2. Backend logic (priority: 11-20) +3. API endpoints (priority: 21-30) +4. UI components (priority: 31-40) +5. Integration/polish (priority: 41-50) + +Stories care depind de altele trebuie să aibă prioritate mai mare (număr mai mare). + +### Pas 7: Verifică acceptance criteria + +Fiecare story TREBUIE să aibă: +- Criterii specifice și verificabile (NU vagi ca "funcționează bine") +- `npm run typecheck passes` (sau echivalent) +- Pentru UI: `Verify in browser that [specific behavior]` + +### Pas 8: Copiază fișierele Ralph + +Dacă nu există deja, copiază: +- `scripts/ralph/ralph.sh` - scriptul principal +- `scripts/ralph/prompt.md` - instrucțiunile per iterație + +### Pas 9: Inițializează progress.txt + +```bash +echo "# Ralph Progress Log" > scripts/ralph/progress.txt +echo "Started: $(date)" >> scripts/ralph/progress.txt +echo "Project: [project-name]" >> scripts/ralph/progress.txt +echo "---" >> scripts/ralph/progress.txt +``` + +### Pas 10: Instrucțiuni finale + +După completare, informează utilizatorul: + +``` +✅ PRD convertit în scripts/ralph/prd.json + +Pentru a rula Ralph: + cd [project-directory] + ./scripts/ralph/ralph.sh [max_iterations] + +Monitorizare: + cat scripts/ralph/prd.json | jq '.userStories[] | {id, title, passes}' + cat scripts/ralph/progress.txt +``` + +## Output așteptat + +- `scripts/ralph/prd.json` - task-urile în format JSON +- `scripts/ralph/progress.txt` - log inițializat +- Structura de directoare completă + +## Reguli importante + +1. **NU începe implementarea** - acest skill doar convertește PRD-ul +2. **Validează mărimea stories** - sparge-le dacă sunt prea mari +3. **Prioritizează corect** - dependențele trebuie respectate +4. **Criterii verificabile** - nu vagi, ci specifice +5. **Inițializează `passes: false`** pentru toate stories diff --git a/skills/ralph/templates/prd-template.json b/skills/ralph/templates/prd-template.json new file mode 100644 index 0000000..42637e9 --- /dev/null +++ b/skills/ralph/templates/prd-template.json @@ -0,0 +1,19 @@ +{ + "projectName": "feature-name", + "branchName": "ralph/feature-name", + "description": "Descriere scurtă a feature-ului", + "userStories": [ + { + "id": "US-001", + "title": "Titlu story", + "description": "As a [user type], I want [feature] so that [benefit]", + "priority": 1, + "acceptanceCriteria": [ + "Criteriu specific și verificabil", + "npm run typecheck passes" + ], + "passes": false, + "notes": "" + } + ] +} diff --git a/skills/ralph/templates/prompt.md b/skills/ralph/templates/prompt.md new file mode 100644 index 0000000..cb8711a --- /dev/null +++ b/skills/ralph/templates/prompt.md @@ -0,0 +1,93 @@ +# Ralph - Instrucțiuni pentru Iterație + +Ești un agent autonom care implementează user stories dintr-un PRD. Aceasta este O SINGURĂ iterație - implementezi UN singur story și apoi te oprești. + +## Workflow pentru această iterație + +### 1. Citește contextul +- PRD-ul și progress.txt sunt furnizate în context +- Înțelege ce stories sunt deja complete (`passes: true`) +- Identifică următorul story de implementat (prioritate cea mai mică dintre cele incomplete) + +### 2. Management branch +- Verifică dacă ești pe branch-ul corect (specificat în `branchName` din PRD) +- Dacă nu, creează și checkout branch-ul: + ```bash + git checkout -b + ``` +- Dacă branch-ul există deja, doar checkout: + ```bash + git checkout + ``` + +### 3. Selectează story-ul +- Alege story-ul cu cea mai mică prioritate care are `passes: false` +- Citește atent acceptance criteria + +### 4. Implementare +- Implementează DOAR acest story +- Urmează patterns existente în codebase +- Fii minimal și focusat - nu adăuga funcționalități extra + +### 5. Quality Checks +Rulează TOATE verificările înainte de commit: +```bash +npm run typecheck # sau echivalentul proiectului +npm run lint # dacă există +npm run test # dacă există +``` + +**IMPORTANT**: Nu face commit dacă verificările eșuează. Repară mai întâi. + +### 6. Documentare (dacă ai descoperit ceva util) +Dacă ai descoperit patterns sau gotchas, actualizează `AGENTS.md` în directorul relevant: +- API patterns +- Dependențe non-evidente +- Convenții de cod +- Cum să testezi anumite funcționalități + +### 7. Commit +Format commit message: +``` +feat: [Story ID] - [Story Title] +``` + +### 8. Marchează story-ul ca complet +**CRITIC**: Actualizează `scripts/ralph/prd.json`: +- Setează `passes: true` pentru story-ul implementat +- Adaugă note relevante în câmpul `notes` + +### 9. Actualizează progress.txt +Adaugă la sfârșitul fișierului `scripts/ralph/progress.txt`: + +```markdown +## Iterație: [timestamp] +### Story implementat: [ID] - [Title] +### Status: Complete + +### Learnings: +- [Ce ai învățat] +- [Patterns descoperite] + +### Next steps: +- [Ce rămâne de făcut] +--- +``` + +## Reguli importante + +1. **UN SINGUR STORY PE ITERAȚIE** - Nu implementa mai mult de un story +2. **TOATE CHECKS TREBUIE SĂ TREACĂ** - Nu face commit cu erori +3. **ACTUALIZEAZĂ prd.json** - Altfel iterația următoare va repeta munca +4. **FII CONCIS** - Nu over-engineer + +## Condiție de terminare + +Dacă TOATE stories au `passes: true`, răspunde cu: + +``` +COMPLETE +``` + +--- +ÎNCEPE IMPLEMENTAREA ACUM. diff --git a/skills/ralph/templates/ralph.sh b/skills/ralph/templates/ralph.sh new file mode 100755 index 0000000..50fdd90 --- /dev/null +++ b/skills/ralph/templates/ralph.sh @@ -0,0 +1,179 @@ +#!/bin/bash +# Ralph pentru Claude Code - Loop autonom de agent AI +# Adaptat din Ralph original (snarktank/ralph) pentru Claude Code CLI +# Usage: ./ralph.sh [max_iterations] [project_dir] + +set -e + +MAX_ITERATIONS=${1:-10} +PROJECT_DIR=${2:-$(pwd)} +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PRD_FILE="$SCRIPT_DIR/prd.json" +PROGRESS_FILE="$SCRIPT_DIR/progress.txt" +ARCHIVE_DIR="$SCRIPT_DIR/archive" +LAST_BRANCH_FILE="$SCRIPT_DIR/.last-branch" +PROMPT_FILE="$SCRIPT_DIR/prompt.md" + +# Verifică că jq este instalat +if ! command -v jq &> /dev/null; then + echo "Eroare: jq nu este instalat. Rulează: apt install jq" + exit 1 +fi + +# Verifică că claude este instalat +if ! command -v claude &> /dev/null; then + echo "Eroare: Claude Code CLI nu este instalat." + echo "Instalează cu: npm install -g @anthropic-ai/claude-code" + exit 1 +fi + +# Verifică existența fișierelor necesare +if [ ! -f "$PRD_FILE" ]; then + echo "Eroare: prd.json nu există în $SCRIPT_DIR" + echo "Generează mai întâi un PRD folosind skill-ul /prd și apoi /ralph" + exit 1 +fi + +if [ ! -f "$PROMPT_FILE" ]; then + echo "Eroare: prompt.md nu există în $SCRIPT_DIR" + exit 1 +fi + +# Arhivare rulare anterioară dacă branch-ul s-a schimbat +if [ -f "$PRD_FILE" ] && [ -f "$LAST_BRANCH_FILE" ]; then + CURRENT_BRANCH=$(jq -r '.branchName // empty' "$PRD_FILE" 2>/dev/null || echo "") + LAST_BRANCH=$(cat "$LAST_BRANCH_FILE" 2>/dev/null || echo "") + + if [ -n "$CURRENT_BRANCH" ] && [ -n "$LAST_BRANCH" ] && [ "$CURRENT_BRANCH" != "$LAST_BRANCH" ]; then + DATE=$(date +%Y-%m-%d) + FOLDER_NAME=$(echo "$LAST_BRANCH" | sed 's|^ralph/||') + ARCHIVE_FOLDER="$ARCHIVE_DIR/$DATE-$FOLDER_NAME" + + echo "Arhivare rulare anterioară: $LAST_BRANCH" + mkdir -p "$ARCHIVE_FOLDER" + [ -f "$PRD_FILE" ] && cp "$PRD_FILE" "$ARCHIVE_FOLDER/" + [ -f "$PROGRESS_FILE" ] && cp "$PROGRESS_FILE" "$ARCHIVE_FOLDER/" + echo " Arhivat în: $ARCHIVE_FOLDER" + + # Reset progress file + echo "# Ralph Progress Log" > "$PROGRESS_FILE" + echo "Started: $(date)" >> "$PROGRESS_FILE" + echo "Branch: $CURRENT_BRANCH" >> "$PROGRESS_FILE" + echo "---" >> "$PROGRESS_FILE" + fi +fi + +# Salvează branch-ul curent +if [ -f "$PRD_FILE" ]; then + CURRENT_BRANCH=$(jq -r '.branchName // empty' "$PRD_FILE" 2>/dev/null || echo "") + if [ -n "$CURRENT_BRANCH" ]; then + echo "$CURRENT_BRANCH" > "$LAST_BRANCH_FILE" + fi +fi + +# Inițializare progress file dacă nu există +if [ ! -f "$PROGRESS_FILE" ]; then + echo "# Ralph Progress Log" > "$PROGRESS_FILE" + echo "Started: $(date)" >> "$PROGRESS_FILE" + echo "---" >> "$PROGRESS_FILE" +fi + +# Funcție pentru a verifica dacă toate story-urile sunt complete +check_all_complete() { + local incomplete=$(jq '[.userStories[] | select(.passes != true)] | length' "$PRD_FILE" 2>/dev/null || echo "999") + [ "$incomplete" -eq 0 ] +} + +# Afișare status inițial +echo "" +echo "=======================================================================" +echo " RALPH pentru Claude Code - Agent Autonom " +echo "=======================================================================" +PROJECT_NAME=$(jq -r '.projectName // "Unknown"' "$PRD_FILE") +BRANCH_NAME=$(jq -r '.branchName // "N/A"' "$PRD_FILE") +TOTAL_STORIES=$(jq '.userStories | length' "$PRD_FILE") +COMPLETE_STORIES=$(jq '[.userStories[] | select(.passes == true)] | length' "$PRD_FILE") +echo " Proiect: $PROJECT_NAME" +echo " Branch: $BRANCH_NAME" +echo " Stories: $COMPLETE_STORIES / $TOTAL_STORIES complete" +echo " Max iterații: $MAX_ITERATIONS" +echo "=======================================================================" +echo "" + +# Verificare rapidă - poate toate sunt deja complete? +if check_all_complete; then + echo "Toate story-urile sunt deja complete!" + exit 0 +fi + +# Loop principal +for i in $(seq 1 $MAX_ITERATIONS); do + echo "" + echo "===================================================================" + echo " Ralph Iterația $i din $MAX_ITERATIONS" + echo "===================================================================" + + # Status curent + COMPLETE_NOW=$(jq '[.userStories[] | select(.passes == true)] | length' "$PRD_FILE") + NEXT_STORY=$(jq -r '[.userStories[] | select(.passes != true)] | sort_by(.priority) | .[0] | "\(.id): \(.title)"' "$PRD_FILE") + echo " Progress: $COMPLETE_NOW / $TOTAL_STORIES stories complete" + echo " Next: $NEXT_STORY" + echo "" + + # Pregătește prompt-ul cu context + FULL_PROMPT=$(cat <&1 | tee "$LOG_FILE" || true + OUTPUT=$(cat "$LOG_FILE") + + # Verifică dacă toate task-urile sunt complete + if echo "$OUTPUT" | grep -q "COMPLETE"; then + echo "" + echo "===================================================================" + echo " RALPH A TERMINAT TOATE TASK-URILE!" + echo " Completat la iterația $i din $MAX_ITERATIONS" + echo "===================================================================" + exit 0 + fi + + # Verifică și prin prd.json + if check_all_complete; then + echo "" + echo "===================================================================" + echo " TOATE STORY-URILE DIN PRD SUNT COMPLETE!" + echo "===================================================================" + exit 0 + fi + + echo " Iterația $i completă. Continuăm..." + sleep 2 +done + +echo "" +echo "===================================================================" +echo " Ralph a atins limita de iterații ($MAX_ITERATIONS)" +echo " Verifică progress.txt pentru status." +echo "===================================================================" +echo "" + +# Afișează stories incomplete +echo "Stories incomplete:" +jq -r '.userStories[] | select(.passes != true) | " - \(.id): \(.title)"' "$PRD_FILE" + +exit 1