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 <noreply@anthropic.com>
This commit is contained in:
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -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/
|
||||||
221
README.md
Normal file
221
README.md
Normal file
@@ -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
|
||||||
59
examples/prd-hello-api.json
Normal file
59
examples/prd-hello-api.json
Normal file
@@ -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": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
64
install.sh
Executable file
64
install.sh
Executable file
@@ -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 ""
|
||||||
137
scripts/ralph/generate-prd.md
Normal file
137
scripts/ralph/generate-prd.md
Normal file
@@ -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]"
|
||||||
33
scripts/ralph/prd-template.json
Normal file
33
scripts/ralph/prd-template.json
Normal file
@@ -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": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
118
scripts/ralph/prompt.md
Normal file
118
scripts/ralph/prompt.md
Normal file
@@ -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 <branchName>
|
||||||
|
```
|
||||||
|
- Dacă branch-ul există deja, doar checkout:
|
||||||
|
```bash
|
||||||
|
git checkout <branchName>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
|
||||||
|
```
|
||||||
|
<promise>COMPLETE</promise>
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
183
scripts/ralph/ralph.sh
Executable file
183
scripts/ralph/ralph.sh
Executable file
@@ -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 <<EOF
|
||||||
|
# Context pentru această iterație Ralph
|
||||||
|
|
||||||
|
## PRD (prd.json):
|
||||||
|
$(cat "$PRD_FILE")
|
||||||
|
|
||||||
|
## Progress până acum (progress.txt):
|
||||||
|
$(cat "$PROGRESS_FILE")
|
||||||
|
|
||||||
|
## Instrucțiuni pentru această iterație:
|
||||||
|
$(cat "$PROMPT_FILE")
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# Execută Claude Code în modul non-interactiv
|
||||||
|
# Folosim --dangerously-skip-permissions pentru a permite operațiuni fără confirmare
|
||||||
|
# OUTPUT=$(echo "$FULL_PROMPT" | claude -p --dangerously-skip-permissions 2>&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 "<promise>COMPLETE</promise>"; 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
|
||||||
195
skills/prd/SKILL.md
Normal file
195
skills/prd/SKILL.md
Normal file
@@ -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
|
||||||
143
skills/ralph/SKILL.md
Normal file
143
skills/ralph/SKILL.md
Normal file
@@ -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
|
||||||
19
skills/ralph/templates/prd-template.json
Normal file
19
skills/ralph/templates/prd-template.json
Normal file
@@ -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": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
93
skills/ralph/templates/prompt.md
Normal file
93
skills/ralph/templates/prompt.md
Normal file
@@ -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 <branchName>
|
||||||
|
```
|
||||||
|
- Dacă branch-ul există deja, doar checkout:
|
||||||
|
```bash
|
||||||
|
git checkout <branchName>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
|
||||||
|
```
|
||||||
|
<promise>COMPLETE</promise>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
ÎNCEPE IMPLEMENTAREA ACUM.
|
||||||
179
skills/ralph/templates/ralph.sh
Executable file
179
skills/ralph/templates/ralph.sh
Executable file
@@ -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 <<EOF
|
||||||
|
# Context pentru această iterație Ralph
|
||||||
|
|
||||||
|
## PRD (prd.json):
|
||||||
|
$(cat "$PRD_FILE")
|
||||||
|
|
||||||
|
## Progress până acum (progress.txt):
|
||||||
|
$(cat "$PROGRESS_FILE")
|
||||||
|
|
||||||
|
## Instrucțiuni pentru această iterație:
|
||||||
|
$(cat "$PROMPT_FILE")
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# Execută Claude Code în modul non-interactiv
|
||||||
|
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 "<promise>COMPLETE</promise>"; 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
|
||||||
Reference in New Issue
Block a user