Add Ralph skill for autonomous PRD creation and implementation
This commit is contained in:
@@ -862,7 +862,7 @@ def clean_vtt(content):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
port = 8080
|
||||
port = 8088
|
||||
os.chdir(KANBAN_DIR)
|
||||
|
||||
print(f"Starting Echo Task Board API on port {port}")
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="icon" type="image/svg+xml" href="/echo/favicon.svg">
|
||||
<title>Echo · Files</title>
|
||||
<link rel="stylesheet" href="common.css">
|
||||
<link rel="stylesheet" href="/echo/common.css">
|
||||
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
|
||||
<script src="swipe-nav.js"></script>
|
||||
<script src="/echo/swipe-nav.js"></script>
|
||||
<style>
|
||||
.main {
|
||||
display: flex;
|
||||
@@ -829,20 +829,20 @@
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<a href="index.html" class="logo">
|
||||
<a href="/echo/index.html" class="logo">
|
||||
<i data-lucide="circle-dot"></i>
|
||||
Echo
|
||||
</a>
|
||||
<nav class="nav">
|
||||
<a href="index.html" class="nav-item">
|
||||
<a href="/echo/index.html" class="nav-item">
|
||||
<i data-lucide="layout-list"></i>
|
||||
<span>Tasks</span>
|
||||
</a>
|
||||
<a href="notes.html" class="nav-item">
|
||||
<a href="/echo/notes.html" class="nav-item">
|
||||
<i data-lucide="file-text"></i>
|
||||
<span>KB</span>
|
||||
</a>
|
||||
<a href="files.html" class="nav-item active">
|
||||
<a href="/echo/files.html" class="nav-item active">
|
||||
<i data-lucide="folder"></i>
|
||||
<span>Files</span>
|
||||
</a>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Echo · Grup Sprijin</title>
|
||||
<link rel="stylesheet" href="common.css">
|
||||
<link rel="stylesheet" href="/echo/common.css">
|
||||
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
||||
<style>
|
||||
.main {
|
||||
@@ -233,24 +233,24 @@
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<a href="index.html" class="logo">
|
||||
<a href="/echo/index.html" class="logo">
|
||||
<i data-lucide="circle-dot"></i>
|
||||
Echo
|
||||
</a>
|
||||
<nav class="nav">
|
||||
<a href="index.html" class="nav-item">
|
||||
<a href="/echo/index.html" class="nav-item">
|
||||
<i data-lucide="layout-list"></i>
|
||||
<span>Tasks</span>
|
||||
</a>
|
||||
<a href="notes.html" class="nav-item">
|
||||
<a href="/echo/notes.html" class="nav-item">
|
||||
<i data-lucide="file-text"></i>
|
||||
<span>Notes</span>
|
||||
</a>
|
||||
<a href="files.html" class="nav-item">
|
||||
<a href="/echo/files.html" class="nav-item">
|
||||
<i data-lucide="folder"></i>
|
||||
<span>Files</span>
|
||||
</a>
|
||||
<a href="grup-sprijin.html" class="nav-item active">
|
||||
<a href="/echo/grup-sprijin.html" class="nav-item active">
|
||||
<i data-lucide="heart-handshake"></i>
|
||||
<span>Grup</span>
|
||||
</a>
|
||||
@@ -476,7 +476,7 @@
|
||||
if (fise.length > 0) {
|
||||
document.getElementById('fiseSection').style.display = 'block';
|
||||
document.getElementById('fiseList').innerHTML = fise.map(f => `
|
||||
<a href="files.html#kanban/grup-sprijin/${f.name}" class="filter-btn" style="text-decoration: none;">
|
||||
<a href="/echo/files.html#kanban/grup-sprijin/${f.name}" class="filter-btn" style="text-decoration: none;">
|
||||
${f.name.replace('fisa-', '').replace('.md', '')}
|
||||
</a>
|
||||
`).join('');
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="icon" type="image/svg+xml" href="/echo/favicon.svg">
|
||||
<title>Echo · Dashboard</title>
|
||||
<link rel="stylesheet" href="common.css">
|
||||
<link rel="stylesheet" href="/echo/common.css">
|
||||
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
||||
<script src="swipe-nav.js"></script>
|
||||
<script src="/echo/swipe-nav.js"></script>
|
||||
<style>
|
||||
.main {
|
||||
max-width: 1400px;
|
||||
@@ -1054,20 +1054,20 @@
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<a href="index.html" class="logo">
|
||||
<a href="/echo/index.html" class="logo">
|
||||
<i data-lucide="circle-dot"></i>
|
||||
Echo
|
||||
</a>
|
||||
<nav class="nav">
|
||||
<a href="index.html" class="nav-item active">
|
||||
<a href="/echo/index.html" class="nav-item active">
|
||||
<i data-lucide="layout-dashboard"></i>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
<a href="notes.html" class="nav-item">
|
||||
<a href="/echo/notes.html" class="nav-item">
|
||||
<i data-lucide="file-text"></i>
|
||||
<span>KB</span>
|
||||
</a>
|
||||
<a href="files.html" class="nav-item">
|
||||
<a href="/echo/files.html" class="nav-item">
|
||||
<i data-lucide="folder"></i>
|
||||
<span>Files</span>
|
||||
</a>
|
||||
@@ -1526,7 +1526,7 @@
|
||||
|
||||
async function loadGitStatus() {
|
||||
try {
|
||||
const response = await fetch('./api/git?' + Date.now());
|
||||
const response = await fetch('/echo/api/git?' + Date.now());
|
||||
if (!response.ok) throw new Error('API error');
|
||||
const git = await response.json();
|
||||
|
||||
@@ -1560,7 +1560,7 @@
|
||||
const more = git.uncommittedCount > 3 ? ` +${git.uncommittedCount - 3}` : '';
|
||||
html += `<div class="status-detail-item uncommitted">
|
||||
<i data-lucide="alert-circle"></i>
|
||||
<span><a href="files.html?git=1" style="color:var(--warning)"><strong>${git.uncommittedCount}</strong> necomise</a>: ${files}${more}</span>
|
||||
<span><a href="/echo/files.html?git=1" style="color:var(--warning)"><strong>${git.uncommittedCount}</strong> necomise</a>: ${files}${more}</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -1582,7 +1582,7 @@
|
||||
|
||||
async function loadAnafStatus() {
|
||||
try {
|
||||
const response = await fetch('status.json?' + Date.now());
|
||||
const response = await fetch('/echo/status.json?' + Date.now());
|
||||
if (!response.ok) throw new Error('No status.json');
|
||||
const status = await response.json();
|
||||
|
||||
@@ -1610,7 +1610,7 @@
|
||||
|
||||
async function loadCronStatus() {
|
||||
try {
|
||||
const response = await fetch('./api/cron?' + Date.now());
|
||||
const response = await fetch('/echo/api/cron?' + Date.now());
|
||||
if (!response.ok) throw new Error('API error');
|
||||
const data = await response.json();
|
||||
|
||||
@@ -1681,7 +1681,7 @@
|
||||
|
||||
async function loadAgentsStatus() {
|
||||
try {
|
||||
const response = await fetch('./api/agents?' + Date.now());
|
||||
const response = await fetch('/echo/api/agents?' + Date.now());
|
||||
if (!response.ok) throw new Error('API error');
|
||||
const data = await response.json();
|
||||
|
||||
@@ -1737,7 +1737,7 @@
|
||||
|
||||
async function loadTodos() {
|
||||
try {
|
||||
const response = await fetch('todos.json?' + Date.now());
|
||||
const response = await fetch('/echo/todos.json?' + Date.now());
|
||||
if (response.ok) {
|
||||
todosData = await response.json();
|
||||
renderTodos();
|
||||
@@ -1991,7 +1991,7 @@
|
||||
// ===== ISSUES =====
|
||||
async function loadIssues() {
|
||||
try {
|
||||
const response = await fetch('issues.json?' + Date.now());
|
||||
const response = await fetch('/echo/issues.json?' + Date.now());
|
||||
issuesData = await response.json();
|
||||
populateProgramSelect();
|
||||
renderIssues();
|
||||
@@ -2017,7 +2017,7 @@
|
||||
async function loadActivity() {
|
||||
try {
|
||||
// Fetch from unified activity API
|
||||
const response = await fetch('./api/activity?t=' + Date.now());
|
||||
const response = await fetch('/echo/api/activity?t=' + Date.now());
|
||||
const data = await response.json();
|
||||
|
||||
if (data.error) throw new Error(data.error);
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="icon" type="image/svg+xml" href="/echo/favicon.svg">
|
||||
<title>Echo · KB</title>
|
||||
<link rel="stylesheet" href="common.css">
|
||||
<link rel="stylesheet" href="/echo/common.css">
|
||||
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
||||
<script src="swipe-nav.js"></script>
|
||||
<script src="/echo/swipe-nav.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<style>
|
||||
.main {
|
||||
@@ -679,20 +679,20 @@
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<a href="index.html" class="logo">
|
||||
<a href="/echo/index.html" class="logo">
|
||||
<i data-lucide="circle-dot"></i>
|
||||
Echo
|
||||
</a>
|
||||
<nav class="nav">
|
||||
<a href="index.html" class="nav-item">
|
||||
<a href="/echo/index.html" class="nav-item">
|
||||
<i data-lucide="layout-list"></i>
|
||||
<span>Tasks</span>
|
||||
</a>
|
||||
<a href="notes.html" class="nav-item active">
|
||||
<a href="/echo/notes.html" class="nav-item active">
|
||||
<i data-lucide="file-text"></i>
|
||||
<span>KB</span>
|
||||
</a>
|
||||
<a href="files.html" class="nav-item">
|
||||
<a href="/echo/files.html" class="nav-item">
|
||||
<i data-lucide="folder"></i>
|
||||
<span>Files</span>
|
||||
</a>
|
||||
@@ -1172,7 +1172,7 @@
|
||||
<div class="note-card" onclick="openNote('${note.file}')">
|
||||
<div class="note-title">
|
||||
${note.title}
|
||||
<a href="files.html#${filesPath}" class="note-file-link" onclick="event.stopPropagation()" title="${filesPath}">
|
||||
<a href="/echo/files.html#${filesPath}" class="note-file-link" onclick="event.stopPropagation()" title="${filesPath}">
|
||||
<i data-lucide="external-link"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"ok": true,
|
||||
"status": "OK",
|
||||
"message": "Nicio modificare detectată",
|
||||
"lastCheck": "06 Feb 2026, 14:00",
|
||||
"lastCheck": "09 Feb 2026, 08:00",
|
||||
"changesCount": 0
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"lastUpdated": "2026-02-08T07:00:00.000Z",
|
||||
"lastUpdated": "2026-02-08T14:32:35.511Z",
|
||||
"items": [
|
||||
{
|
||||
"id": "prov-2026-02-08",
|
||||
@@ -8,8 +8,8 @@
|
||||
"example": "Scenariul tău real: Într-un exercițiu NLP, partenerul te blochează sau critică. În loc să rămâi în defensivă ('e greu') → aplici pattern interrupt din Tony Robbins: observi fiziologia (umeri contractați?), schimbi focusul (ce pot învăța despre cum reacționez?), schimbi limbajul ('e provocator' în loc de 'e greu'). Exercițiul devine mirror pentru tiparele tale în relații/business - exact cum reacționezi când angajatul nu înțelege sau când clientul critică.",
|
||||
"domain": "self",
|
||||
"dueDate": "2026-02-08",
|
||||
"done": false,
|
||||
"doneAt": null,
|
||||
"done": true,
|
||||
"doneAt": "2026-02-08T14:32:35.511Z",
|
||||
"source": "Tony Robbins - The Secret to an Extraordinary Life + Monica Ion - Legea Fractalilor",
|
||||
"sourceUrl": "https://moltbot.tailf7372d.ts.net/echo/files.html#memory/kb/coaching/2026-02-08-dimineata.md",
|
||||
"createdAt": "2026-02-08T07:00:00.000Z"
|
||||
|
||||
200
memory/kb/exercitii/diagnostic-platou-financiar.md
Normal file
200
memory/kb/exercitii/diagnostic-platou-financiar.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# Diagnostic Platou Financiar - Chestionar
|
||||
|
||||
**Pentru:** Marius
|
||||
**Data:** Luni 9 februarie 2026, 15:00
|
||||
**Timp estimat:** 10-15 minute
|
||||
|
||||
## Context
|
||||
|
||||
Ai atins un platou financiar și, deși lucrezi și ești competent, veniturile nu cresc. Acest chestionar te ajută să identifici CARE dintre cele 8 blocaje psihologice posibile este dominant pentru tine.
|
||||
|
||||
**Important:** Răspunde SINCER, nu "cum ar trebui". Blocajele nu sunt defecte - sunt pattern-uri învățate pe care le poți schimba când le-ai identificat.
|
||||
|
||||
---
|
||||
|
||||
## Blocaj #1: Identitate lipită de nivelul actual
|
||||
|
||||
**Întrebări:**
|
||||
|
||||
1. Când te gândești la tine ca antreprenor, te vezi mai degrabă ca:
|
||||
- [ ] Cineva care SE DESCURCĂ și rezolvă probleme zilnice
|
||||
- [ ] Cineva care CREȘTE și explorează noi oportunități
|
||||
- [ ] Cineva care E OCUPAT și își face treaba bine
|
||||
|
||||
2. Dacă ai câștiga dublu față de acum, ce s-ar schimba LA TINE (nu în viață - LA TINE)?
|
||||
- Răspuns liber:
|
||||
|
||||
3. Completează: "Sunt genul de antreprenor care..."
|
||||
- Răspuns liber:
|
||||
|
||||
**Scor blocaj #1:** (auto-evaluat 1-10, 10=foarte blocant)
|
||||
|
||||
---
|
||||
|
||||
## Blocaj #2: Creștere = durere > plăcere
|
||||
|
||||
**Întrebări:**
|
||||
|
||||
1. Când te gândești la prospecting/clienți noi, primele 3 gânduri care îți vin:
|
||||
- 1.
|
||||
- 2.
|
||||
- 3.
|
||||
|
||||
2. Ai avut vreodată experiență neplăcută cu un client nou (cerințe excesive, plăți întârziate, supărări)? Descrie pe scurt:
|
||||
|
||||
3. Pe o scală 1-10, cât de mult asociezi "clienți noi" cu:
|
||||
- Mai multă muncă: __/10
|
||||
- Mai mult stres: __/10
|
||||
- Mai multe probleme: __/10
|
||||
- Mai multe oportunități: __/10 (invers = indiciu blocaj)
|
||||
|
||||
**Scor blocaj #2:** (auto-evaluat 1-10)
|
||||
|
||||
---
|
||||
|
||||
## Blocaj #3: Nivelul de merit (cât poți primi fără vinovăție)
|
||||
|
||||
**Întrebări:**
|
||||
|
||||
1. Dacă un client ți-ar oferi dublu față de tariful actual pentru ACEEAȘI muncă, ai simți:
|
||||
- [ ] Bucurie, merit
|
||||
- [ ] Inconfort, "e prea mult"
|
||||
- [ ] Suspiciune, "ce vor în plus?"
|
||||
|
||||
2. Completează: "Mă simt confortabil să cer [sumă] pentru munca mea, dar peste asta deja mi se pare..."
|
||||
- Răspuns liber:
|
||||
|
||||
3. Câți bani ai putea câștiga lunar FĂRĂ să simți că "nu merită" sau "e exagerat"?
|
||||
- Suma confortabilă:
|
||||
- Suma "deja îmi e rușine să cer":
|
||||
|
||||
**Scor blocaj #3:** (auto-evaluat 1-10)
|
||||
|
||||
---
|
||||
|
||||
## Blocaj #4: Bani = conflict sau pierdere
|
||||
|
||||
**Întrebări:**
|
||||
|
||||
1. Când ai câștigat mai mulți bani, s-a întâmplat vreodată:
|
||||
- [ ] Cheltuieli neașteptate mari (reparații, sănătate, etc.)
|
||||
- [ ] Conflicte în familie/relații
|
||||
- [ ] Cereri de bani de la alții
|
||||
- [ ] Probleme cu clienții
|
||||
|
||||
2. Există vreo experiență din trecut când "bani mulți = probleme"? Descrie:
|
||||
|
||||
3. Inconsistent: perioadele când câștigi mai mult sunt urmate de:
|
||||
- [ ] Perioade de cheltuieli mari
|
||||
- [ ] Lipsă clienți
|
||||
- [ ] Probleme neprevăzute
|
||||
- [ ] Nimic special (dacă DA aici → blocaj mic)
|
||||
|
||||
**Scor blocaj #4:** (auto-evaluat 1-10)
|
||||
|
||||
---
|
||||
|
||||
## Blocaj #5: Dezamăgiri și condiționări ("am câștigat mai mult dar viața nu s-a îmbunătățit")
|
||||
|
||||
**Întrebări:**
|
||||
|
||||
1. Ai avut perioade când ai câștigat mai mult dar NU te-ai simțit mai fericit/împlinit?
|
||||
- [ ] Da, des
|
||||
- [ ] Da, uneori
|
||||
- [ ] Nu
|
||||
|
||||
2. Când câștigi mai mult, ce se schimbă în VIAȚA TA (nu în cont)?
|
||||
- Răspuns liber:
|
||||
|
||||
3. Completează: "Mi-am dorit mai mulți bani ca să pot... dar când i-am avut, am descoperit că..."
|
||||
- Răspuns liber:
|
||||
|
||||
**Scor blocaj #5:** (auto-evaluat 1-10)
|
||||
|
||||
---
|
||||
|
||||
## Blocaj #6: Relația cu părinții (motivații greșite)
|
||||
|
||||
**Întrebări:**
|
||||
|
||||
1. Când te gândești la părinții tăi și bani, ce crezi că ar spune despre câștigul tău actual?
|
||||
- Răspuns liber:
|
||||
|
||||
2. Dacă ai câștiga mult mai mult, ai face-o pentru:
|
||||
- [ ] Ca să îi fac mândri
|
||||
- [ ] Ca să demonstrez că pot
|
||||
- [ ] Ca să am libertate și resurse (pentru mine)
|
||||
- [ ] Ca să îmi dovedesc valoarea
|
||||
|
||||
3. Există vreo frază de la părinți despre bani care îți sună în cap când te gândești la prosperitate? (ex: "banii nu cresc în copaci", "bogații sunt...")
|
||||
- Răspuns liber:
|
||||
|
||||
**Scor blocaj #6:** (auto-evaluat 1-10)
|
||||
|
||||
---
|
||||
|
||||
## Blocaj #7: Setarea "vreau" = lipsă
|
||||
|
||||
**Întrebări:**
|
||||
|
||||
1. Când spui "Vreau mai mulți bani", cum te simți?
|
||||
- [ ] Motivat, energizat
|
||||
- [ ] Frustrat, neîmplinit (pentru că "vreau" = "nu am")
|
||||
- [ ] Vinovie ("nu ar trebui să vreau mai mult")
|
||||
|
||||
2. Completează: "Dacă AȘ AVEA mai mulți bani, aș putea..."
|
||||
- Răspuns liber:
|
||||
|
||||
3. Poți imagina/simți deja cum e să ai venitul dorit, sau mereu rămâne "ceva ce va fi în viitor"?
|
||||
- Răspuns liber:
|
||||
|
||||
**Scor blocaj #7:** (auto-evaluat 1-10)
|
||||
|
||||
---
|
||||
|
||||
## Blocaj #8: Lipsa de autenticitate ("ce trebuie" vs "ce rezonează")
|
||||
|
||||
**Întrebări:**
|
||||
|
||||
1. Câți bani crezi că "TREBUIE" să câștigi vs câți bani VREI cu adevărat să câștigi?
|
||||
- Trebuie:
|
||||
- Vreau cu adevărat:
|
||||
|
||||
2. Faci lucruri în business pentru că "așa se face" sau pentru că chiar rezonează cu tine?
|
||||
- % "așa se face":
|
||||
- % "rezonează cu mine":
|
||||
|
||||
3. Dacă ai putea câștiga aceeași sumă făcând ceva COMPLET diferit de ceea ce faci acum, ai schimba?
|
||||
- [ ] Da, imediat
|
||||
- [ ] Poate, depinde
|
||||
- [ ] Nu, îmi place ce fac
|
||||
|
||||
**Scor blocaj #8:** (auto-evaluat 1-10)
|
||||
|
||||
---
|
||||
|
||||
## Rezumat Scoruri
|
||||
|
||||
| Blocaj | Scor (1-10) | Dominant? |
|
||||
|--------|-------------|-----------|
|
||||
| #1: Identitate lipită de nivel actual | | |
|
||||
| #2: Creștere = durere > plăcere | | |
|
||||
| #3: Nivel de merit (vinovăție) | | |
|
||||
| #4: Bani = conflict sau pierdere | | |
|
||||
| #5: Dezamăgiri și condiționări | | |
|
||||
| #6: Relația cu părinții | | |
|
||||
| #7: Setarea "vreau" = lipsă | | |
|
||||
| #8: Lipsa de autenticitate | | |
|
||||
|
||||
**Blocajul/blocajele DOMINANTE (scor >7):**
|
||||
|
||||
---
|
||||
|
||||
## Următorii pași
|
||||
|
||||
După ce completezi, vom discuta:
|
||||
1. Care blocaj e dominant (sau combinație de 2-3)
|
||||
2. De ce tocmai ăsta e activ la tine (pattern-uri din trecut)
|
||||
3. Cum se lucrează pe el (tehnici NLP/coaching specifice)
|
||||
|
||||
**Sursă:** Friday Spark #183 - 8 Blocaje Financiare Invizibile
|
||||
@@ -1,5 +1,26 @@
|
||||
{
|
||||
"notes": [
|
||||
{
|
||||
"file": "notes-data/projects/monica-ion/youtube/2026-02-09-monica-ion-povestea-lui-marc-ep7-relatie-angajati.md",
|
||||
"title": "Monica Ion - Povestea lui Marc - Episodul 7: Relația cu angajații și dinamica puterii",
|
||||
"date": "2026-02-09",
|
||||
"tags": [
|
||||
"angajati",
|
||||
"leadership",
|
||||
"transformare",
|
||||
"pierdere"
|
||||
],
|
||||
"domains": [
|
||||
"work",
|
||||
"growth"
|
||||
],
|
||||
"types": [],
|
||||
"category": "projects",
|
||||
"project": "monica-ion",
|
||||
"subdir": "youtube",
|
||||
"video": "",
|
||||
"tldr": "Monica Ion lucrează cu Mark pe relația cu angajații și frica de pierdere. Mark vine agitat cu teama de a pierde un angajat tehnic genial. Monica folosește **legea transformării** pentru a vindeca dure..."
|
||||
},
|
||||
{
|
||||
"file": "notes-data/coaching/2026-02-08-dimineata.md",
|
||||
"title": "Gândul de dimineață - 2026-02-08",
|
||||
@@ -23,6 +44,19 @@
|
||||
"video": "",
|
||||
"tldr": "Duminică - a doua zi NLP M4 (7-8 februarie). Ieri a fost despre claritate mentală ÎNAINTE de învățare (bucle deschise). Astăzi e despre INTEGRARE ÎN TIMPUL învățării - nu aștepta să aplici acasă, apli..."
|
||||
},
|
||||
{
|
||||
"file": "notes-data/exercitii/diagnostic-platou-financiar.md",
|
||||
"title": "Diagnostic Platou Financiar - Chestionar",
|
||||
"date": "2026-02-08",
|
||||
"tags": [],
|
||||
"domains": [],
|
||||
"types": [],
|
||||
"category": "exercitii",
|
||||
"project": null,
|
||||
"subdir": null,
|
||||
"video": "",
|
||||
"tldr": "**Sursă:** Friday Spark #183 - 8 Blocaje Financiare Invizibile"
|
||||
},
|
||||
{
|
||||
"file": "notes-data/insights/2026-02-08.md",
|
||||
"title": "8 Februarie 2026 - Insights Profunde",
|
||||
@@ -107,6 +141,21 @@
|
||||
"video": "",
|
||||
"tldr": "→ Concept: Schimb echitabil - buclele deschise blochează oportunități"
|
||||
},
|
||||
{
|
||||
"file": "memory/2026-02-08.md",
|
||||
"title": "2026-02-08",
|
||||
"date": "2026-02-08",
|
||||
"tags": [],
|
||||
"domains": [],
|
||||
"types": [
|
||||
"memory"
|
||||
],
|
||||
"category": "memory",
|
||||
"project": null,
|
||||
"subdir": null,
|
||||
"video": "",
|
||||
"tldr": "**Trimis:** Discord #echo-work la 09:30 (UTC 07:30)"
|
||||
},
|
||||
{
|
||||
"file": "notes-data/coaching/2026-02-07-seara.md",
|
||||
"title": "Gândul de Seară - 7 februarie 2026",
|
||||
@@ -331,6 +380,45 @@
|
||||
"video": "",
|
||||
"tldr": "Nu forțez răspuns - întrebările sunt plantate pentru reflecție personală."
|
||||
},
|
||||
{
|
||||
"file": "notes-data/emails/2026-02-06_fwd-ziua-1-legea-dualității.md",
|
||||
"title": "Fwd: Ziua 1 – Legea Dualității ☯️",
|
||||
"date": "2026-02-06",
|
||||
"tags": [],
|
||||
"domains": [],
|
||||
"types": [],
|
||||
"category": "emails",
|
||||
"project": null,
|
||||
"subdir": null,
|
||||
"video": "",
|
||||
"tldr": "<!-- Echo: completează cu rezumat -->"
|
||||
},
|
||||
{
|
||||
"file": "notes-data/emails/2026-02-06_re-raport-dimineata-6-februarie-2026.md",
|
||||
"title": "Re: Raport Dimineata 6 februarie 2026",
|
||||
"date": "2026-02-06",
|
||||
"tags": [],
|
||||
"domains": [],
|
||||
"types": [],
|
||||
"category": "emails",
|
||||
"project": null,
|
||||
"subdir": null,
|
||||
"video": "",
|
||||
"tldr": "<!-- Echo: completează cu rezumat -->"
|
||||
},
|
||||
{
|
||||
"file": "notes-data/emails/2026-02-06_fwd-3-2-1-keeping-your-body-loose-and-head-clear-h.md",
|
||||
"title": "Fwd: 3-2-1: Keeping your body loose and head clear, how to find",
|
||||
"date": "2026-02-06",
|
||||
"tags": [],
|
||||
"domains": [],
|
||||
"types": [],
|
||||
"category": "emails",
|
||||
"project": null,
|
||||
"subdir": null,
|
||||
"video": "",
|
||||
"tldr": "<!-- Echo: completează cu rezumat -->"
|
||||
},
|
||||
{
|
||||
"file": "notes-data/exercitii/reframe-credinte-limitatoare.md",
|
||||
"title": "Exercițiu: Reframe Credințe Limitatoare (NLP)",
|
||||
@@ -2087,6 +2175,19 @@
|
||||
"video": "",
|
||||
"tldr": "- [ ] Documentare în kb/projects/FLUX-JOBURI.md"
|
||||
},
|
||||
{
|
||||
"file": "notes-data/conversations/2026-01-30-conversatie-completa.md",
|
||||
"title": "2026-01-30 - Conversație completă dimineață",
|
||||
"date": "2026-01-30",
|
||||
"tags": [],
|
||||
"domains": [],
|
||||
"types": [],
|
||||
"category": "conversations",
|
||||
"project": null,
|
||||
"subdir": null,
|
||||
"video": "",
|
||||
"tldr": "6. **Nevoie:** Accountability - check-in-uri regulate ca să nu amâne."
|
||||
},
|
||||
{
|
||||
"file": "notes-data/projects/vending-master/README.md",
|
||||
"title": "Proiect: Vending Master - Integrare Website → ROA",
|
||||
@@ -2424,21 +2525,6 @@
|
||||
"video": "",
|
||||
"tldr": "- Experimente post negru"
|
||||
},
|
||||
{
|
||||
"file": "conversations/2026-01-30-conversatie-completa.md",
|
||||
"title": "2026-01-30 - Conversație completă dimineață",
|
||||
"date": "2026-01-30",
|
||||
"tags": [],
|
||||
"domains": [],
|
||||
"types": [
|
||||
"conversation"
|
||||
],
|
||||
"category": "conversations",
|
||||
"project": null,
|
||||
"subdir": null,
|
||||
"video": "",
|
||||
"tldr": "6. **Nevoie:** Accountability - check-in-uri regulate ca să nu amâne."
|
||||
},
|
||||
{
|
||||
"file": "notes-data/youtube/2026-01-29_cloudflare-tunnel-localhost-public.md",
|
||||
"title": "Cloudflare Tunnel: Make Localhost Public Without Port Forwarding",
|
||||
@@ -2558,28 +2644,28 @@
|
||||
}
|
||||
],
|
||||
"stats": {
|
||||
"total": 143,
|
||||
"total": 149,
|
||||
"by_domain": {
|
||||
"work": 40,
|
||||
"work": 41,
|
||||
"health": 25,
|
||||
"growth": 51,
|
||||
"growth": 52,
|
||||
"sprijin": 28,
|
||||
"scout": 2
|
||||
},
|
||||
"by_category": {
|
||||
"articole": 0,
|
||||
"coaching": 16,
|
||||
"emails": 1,
|
||||
"exercitii": 3,
|
||||
"conversations": 0,
|
||||
"emails": 4,
|
||||
"exercitii": 4,
|
||||
"health": 1,
|
||||
"insights": 14,
|
||||
"projects": 43,
|
||||
"projects": 44,
|
||||
"reflectii": 3,
|
||||
"retete": 1,
|
||||
"tools": 4,
|
||||
"youtube": 42,
|
||||
"memory": 14,
|
||||
"conversations": 1
|
||||
"memory": 15
|
||||
}
|
||||
},
|
||||
"domains": [
|
||||
@@ -2603,6 +2689,7 @@
|
||||
"categories": [
|
||||
"articole",
|
||||
"coaching",
|
||||
"conversations",
|
||||
"emails",
|
||||
"exercitii",
|
||||
"health",
|
||||
@@ -2612,7 +2699,6 @@
|
||||
"retete",
|
||||
"tools",
|
||||
"youtube",
|
||||
"memory",
|
||||
"conversations"
|
||||
"memory"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
# Monica Ion - Povestea lui Marc - Episodul 7: Relația cu angajații și dinamica puterii
|
||||
|
||||
**Sursă:** https://youtu.be/X7eTzN9IJhc
|
||||
**Durată:** 50:12
|
||||
**Data:** 2026-02-09
|
||||
**Tags:** @work @growth #coaching #angajati #leadership #transformare #pierdere
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
Monica Ion lucrează cu Mark pe relația cu angajații și frica de pierdere. Mark vine agitat cu teama de a pierde un angajat tehnic genial. Monica folosește **legea transformării** pentru a vindeca durerea legată de Marian - angajatul plecat când era greu. Demonstrează că trăsăturile admirate (suport tehnic, rezolvare rapidă, etc.) au fost preluate de alți membri ai echipei și că plecarea lui Marian a adus beneficii: sistem mai robust, încredere în sine, echipă mai aliniată. Subliniem tipar major: sacrificiu pentru angajați, milă, lipsă limite → acumulare durere → sabotare creștere business.
|
||||
|
||||
---
|
||||
|
||||
## Puncte cheie
|
||||
|
||||
### 1. Pattern toxic: Sacrificiu → Durere → Sabotare
|
||||
Mark se sacrifică pentru angajați (le face treaba, le dă bani, tolerează încălcări) → acumulează mai multă durere decât plăcere în relație cu firma → subconștientul sabotează creșterea.
|
||||
|
||||
**Exemple concrete:**
|
||||
- Angajat care bea și juca la noroc → îl împrumuta cu bani știind că vor fi folosiți prost
|
||||
- Le face treaba angajaților când ei nu termină
|
||||
- Milă de a-i da afară → "e singurul care aduce bani în familie"
|
||||
|
||||
### 2. Legea transformării aplicată la Marian
|
||||
**Principiu:** Nimic nu se pierde, totul se transformă.
|
||||
|
||||
**Trăsături percepute pierdute prin plecarea lui Marian:**
|
||||
1. Suport tehnic practic
|
||||
2. Rezolvare probleme rapid
|
||||
3. Bună dispoziție în echipă
|
||||
4. Atent la detalii
|
||||
5. Ajutor disponibil
|
||||
6. Specialist pe aparate AMA
|
||||
7. Soluții pentru aparate AMA
|
||||
|
||||
**Cine a preluat trăsăturile:**
|
||||
- Matei, Ionel, Clara → suport tehnic, soluții practice
|
||||
- Clara → bună dispoziție, relație mai bună cu clienții
|
||||
- Matei, Vlad, Clara → atenție la detalii
|
||||
- Ionel, Clara, echipa în general → ajutor disponibil
|
||||
- Om de la furnizor + Mark → specialist AMA
|
||||
|
||||
**Concluzie:** Toate trăsăturile au fost preluate calitativ și cantitativ egal sau superior!
|
||||
|
||||
### 3. Beneficii formă nouă > Dezavantaje formă veche
|
||||
|
||||
**Suport tehnic (Matei, Ionel, Clara):**
|
||||
- ✅ Mai meticuloși
|
||||
- ✅ Opinii mai flexibile (soluții eficiente, nu doar corecte tehnic)
|
||||
- ✅ Componentă feminină prietenoasă (Clara)
|
||||
- ✅ Relație mai bună cu angajații clienților
|
||||
- ❌ Marian: Riguros dar inflexibil, aroganță, conflicte ego → sabotaj plăți de la clienți
|
||||
|
||||
**Ajutor disponibil (Ionel, Clara, echipa):**
|
||||
- ✅ Echipă aliniată, "bate inimile în același ritm"
|
||||
- ✅ Nu mai există dependență de un singur om
|
||||
- ✅ Clienții văd echipă implicată, nu un singur om
|
||||
- ✅ Backgrounduri tehnice diverse → acoperire mai mare, creștere business
|
||||
- ❌ Marian: Presiune pe un om, oboseală, timp prelungit facturare/livrare
|
||||
|
||||
### 4. Beneficii concrete ale plecării lui Marian
|
||||
|
||||
**Impact emotional:**
|
||||
- Eliberare de fața lui veșnic obosită și tracasată
|
||||
- Nu mai duce vinovăție acasă în relație cu familia
|
||||
- Poate cere mai mult de la oameni și poate spune "nu" clienților
|
||||
|
||||
**Impact strategic:**
|
||||
- Realizare că are nevoie de sistem, nu dependență oameni
|
||||
- Sistematizare: training-uri înregistrate (nu mai repetă)
|
||||
- Poate învăța și preda mai mult pe parte tehnică
|
||||
|
||||
**Impact încredere:**
|
||||
- Creștere încredere în abilitățile tehnice proprii
|
||||
- Creștere încredere în abilitățile echipei
|
||||
- Nu mai supraprețuiește pe alții, nu se mai subprețuiește pe sine
|
||||
- Nu mai așteaptă aprobarea lui Marian → ritm alert
|
||||
- Clienții și colegii au mai mare încredere în soluțiile lui Mark
|
||||
|
||||
**Impact cultură organizațională:**
|
||||
- Atmosferă de încredere în firmă între membri echipei
|
||||
- Oameni mai disponibili, mai mobilizați (teamă pierdere loc muncă, dar și efect pozitiv)
|
||||
|
||||
### 5. Echilibrare admirație: Marian nu a fost perfect
|
||||
|
||||
Mark admira certitudinea și rapiditatea lui Marian → identificare momente când Marian:
|
||||
- A avut ezitări cu clienți din Dej, Vâlcea, Cluj
|
||||
- S-a consultat cu furnizori (nu avea certitudine)
|
||||
- A venit la Mark cu 2 soluții, nu putea alege (nu avea certitudine)
|
||||
|
||||
**Concluzie:** "Percep ca pe o eliberare și văd că e în ordine. Mă bucur că a plecat."
|
||||
|
||||
### 6. REGULA DE AUR pentru creșterea firmelor
|
||||
|
||||
> **"Motivul principal pentru care nu mai cresc firmele este că proprietarii acumulează mai multă durere decât plăcere în relația cu firma."**
|
||||
|
||||
Dacă durere > plăcere → subconștientul te protejează → sabotaj creștere → nu găsești angajați → nu te expui riscuri.
|
||||
|
||||
**Surse durere:**
|
||||
- Pierderi financiare neechilibrate
|
||||
- Angajați care pleacă (percepție pierdere)
|
||||
- Sacrificiu pentru angajați (durere acumulată)
|
||||
|
||||
### 7. Legea fractalilor
|
||||
|
||||
> "Așa cum faci un lucru, așa le faci pe toate."
|
||||
|
||||
Pattern-ul lui Mark:
|
||||
- Cu banii: O dată generos, o dată strâns, disperare
|
||||
- Cu angajații: O dată milă/sacrificiu, o dată evită să îi vadă (să nu desfășoare latura întunecată)
|
||||
- Cu firma: Acumulare durere → sabotare creștere
|
||||
|
||||
### 8. Link cu merit (nivelul personal)
|
||||
|
||||
> "Capacitatea unei persoane de a delega, de a și face treaba, de a trăi în aliniere cu ea însăși și de a cere rezultate are în mod direct legătură cu nivelul de merit al persoanei respective."
|
||||
|
||||
Lucrarea pe vină și rușine → creștere merit → capacitate de a pune limite ferme și delega.
|
||||
|
||||
---
|
||||
|
||||
## Quote-uri cheie
|
||||
|
||||
> "Motivul principal pentru care nu mai cresc firmele este că proprietarii acumulează mai multă durere decât plăcere în relația cu firma. Dacă acumulezi mai multă durere decât plăcere, sistemul tău nervos te va proteja, te va sabota în a te expune la riscuri care pot să genereze același tip de durere."
|
||||
|
||||
> "Așa cum faci un lucru, așa le faci pe toate. Acest lucru se vede și în relație cu angajații și se vede și în relație cu firmă, se vede și în relație cu banii." *(legea fractalilor)*
|
||||
|
||||
> "Te sacrifici pentru ei. Asta înseamnă că le dai bani lor când nu ți dai ție, că le faci munca lor și ajungi tu mai târziu acasă și ajungi obosit, că acumulezi tu durere în relație cu firma ca să i protejezi pe ei și acest sacrificiu se întoarce împotriva ta."
|
||||
|
||||
> "Nimic nu se pierde. Totul se transformă și în esență tot ce percepi că ai pierdut prin plecarea lui Marian a fost preluat și manifestat către tine de către alții."
|
||||
|
||||
> "Prin faptul că a plecat Marian, pe specializarea lui, ai dobândit mai multă încredere în abilitățile tale tehnice și un alt beneficiu este că ai dobândit mai multă încredere în abilitățile tehnice ale echipei."
|
||||
|
||||
> "Ai început să le cer oamenilor mai mult din ce vreau și am început să le spun și clienților nu, pentru că nu l mai aveam pe Marian cu mai puțină vină decât am avut o până atunci."
|
||||
|
||||
> "Am realizat atunci că am nevoie de un sistem, că nu am sistem și că mă bazez prea mult pe oameni."
|
||||
|
||||
---
|
||||
|
||||
## Exercițiu final: Viața fără teama de pierdere
|
||||
|
||||
**Pas 1:** Închide ochii, imaginează-ți viața fără teamă de a pierde (oameni, bani, lucruri).
|
||||
|
||||
**Pas 2:** Du-te înapoi la o percepție de pierdere (părinte, iubit, sumă bani).
|
||||
|
||||
**Pas 3:** Vizualizează locul de pierdere în corp (unde doare, tensiune) → trimite lumină cu intenția să vindeci → până tensiunea dispare.
|
||||
|
||||
**Pas 4:** Vezi cum te simți în corp și în realitate fără durerea respectivă, fără teama pierderii:
|
||||
- Ce e posibil pentru tine?
|
||||
- Cum se schimbă discuțiile tale cu cei din jur?
|
||||
- Cum se schimbă acțiunile tale?
|
||||
- La ce fel de clienți ai acces?
|
||||
- La ce fel de resurse ai acces?
|
||||
- Ce poți să ceri, ce n-ai cerut până acum de frică?
|
||||
|
||||
**Pas 5:** Notează cu detalii cum arată viața ta dacă dizolvi această durere a pierderii.
|
||||
|
||||
**Pas 6:** Împărtășește pe grupul de WhatsApp (sau jurnal) ce te lasă inima.
|
||||
|
||||
**Notă:** E doar un exercițiu de imaginație, nu rezolvă cauza principală corect și complet. Asta se face în **Inspired Money Foundation** cu abordare strategică.
|
||||
|
||||
---
|
||||
|
||||
## Contextul seria "Povestea lui Marc"
|
||||
|
||||
**Progrese Mark până acum:**
|
||||
- Creștere vânzări (liduri, contracte, volum)
|
||||
- Aliniere cu soția legat de bani (exercițiu poșeta)
|
||||
- Clienți noi (semn trend ascendent)
|
||||
- Facturare servicii consultanță tehnică (primele reușite)
|
||||
- Proiect secret (primele rezultate pozitive, clienți plătesc)
|
||||
|
||||
**Tema următoare:** Angajatul genial care nu respectă regulile și percepția de milă → stabilirea limitelor ferme.
|
||||
|
||||
---
|
||||
|
||||
## Aplicabilitate pentru Marius
|
||||
|
||||
### Pattern-uri similare identificate:
|
||||
1. **Sacrificiu pentru angajați:** Marius face treaba angajatului nou (4 luni), îi explică de mai multe ori → acumulare durere
|
||||
2. **Teamă pierdere angajat:** Colega 70 ani (probleme vedere) → dependență, nu delegare completă
|
||||
3. **Milă/responsabilitate:** "Cum îl învăț mai eficient?" vs. "Ce limite clare stabilesc?"
|
||||
|
||||
### Acțiuni concrete inspirate:
|
||||
1. **Identifică trăsături pierdute:** Dacă angajatul nou ar pleca, ce percepi că pierzi? → vezi cine le-a preluat deja (tu, colega, sisteme)
|
||||
2. **Sistematizare:** Training-uri înregistrate (video/doc) pentru ROA → reduce dependența de tine
|
||||
3. **Echilibrare durere-plăcere:** Notează beneficii firmă vs. dureri acumulate → unde e balanta?
|
||||
4. **Limite ferme:** Ce reguli tolerezi încălcate? Care e costul sacrificiului tău?
|
||||
|
||||
### Link cu obiectivele tale:
|
||||
- **Scop concediu:** Sistematizare permite înlocuire → pauze fără stres
|
||||
- **Creștere business:** Dizolvare durere acumulată → disponibilitate pentru clienți noi, proiecte noi
|
||||
- **Încredere în sine:** Nu supraaprecia pe alții, nu te subaprecia pe tine (ca Mark cu Marian)
|
||||
|
||||
---
|
||||
|
||||
## Meta
|
||||
|
||||
**Program menționat:** Inspired Money Foundation (Monica Ion)
|
||||
**Tehnici:** Legea transformării, Legea dualității, Legea fractalilor, Echilibrare pierdere
|
||||
**Teme conectate:** Vină, rușine, merit, sacrificiu, limite, sisteme vs. oameni
|
||||
1
ralph-claude
Submodule
1
ralph-claude
Submodule
Submodule ralph-claude added at ecd8bed527
261
skills/ralph/README.md
Normal file
261
skills/ralph/README.md
Normal file
@@ -0,0 +1,261 @@
|
||||
# Ralph Plugin
|
||||
|
||||
**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 Claude Code CLI, cu îmbunătățiri inspirate din [coleam00/ai-agents-masterclass](https://github.com/coleam00/ai-agents-masterclass).
|
||||
|
||||
## Comenzi disponibile
|
||||
|
||||
| Comandă | Descriere |
|
||||
|---------|-----------|
|
||||
| `/ralph:prd` | Generează PRD structurat cu detecție context și întrebări adaptive |
|
||||
| `/ralph:convert` | Convertește PRD markdown în prd.json și configurează proiectul |
|
||||
|
||||
## Features
|
||||
|
||||
### Detecție Automată Context
|
||||
- Detectează automat tech stack-ul din fișierele de config (package.json, pyproject.toml, etc.)
|
||||
- Adaptează întrebările: ~10 pentru proiecte noi vs ~5-7 pentru features în proiecte existente
|
||||
- Extrage comenzile reale din proiect (npm scripts, etc.)
|
||||
|
||||
### Întrebări Interactive
|
||||
- Folosește `AskUserQuestion` pentru UX interactiv (nu text simplu)
|
||||
- Web research opțional pentru best practices (WebSearch)
|
||||
- Întrebări adaptive bazate pe context detectat
|
||||
|
||||
### Verificare Vizuală Browser
|
||||
- Folosește **agent-browser CLI** pentru verificări UI
|
||||
- Snapshots compacte cu referințe (@e1, @e2) - eficiente cu tokeni
|
||||
- Screenshots salvate automat pentru referință
|
||||
|
||||
### Configurare Automată
|
||||
- Generează `.claude/settings.json` cu allow-list per tech stack
|
||||
- Actualizează prompt.md cu comenzile reale ale proiectului
|
||||
- Arhivare automată a rulărilor anterioare
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ WORKFLOW RALPH │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 1. /ralph:prd │
|
||||
│ ├─ Detectează context proiect (existent vs nou) │
|
||||
│ ├─ Pune întrebări adaptive cu AskUserQuestion │
|
||||
│ ├─ (Opțional) WebSearch pentru best practices │
|
||||
│ └─ Generează PRD în /tasks/prd-*.md │
|
||||
│ │
|
||||
│ 2. /ralph:convert │
|
||||
│ ├─ Detectează tech stack și comenzi │
|
||||
│ ├─ Generează .claude/settings.json (allow-list) │
|
||||
│ ├─ Copiază și configurează scripts/ralph/ │
|
||||
│ └─ Creează prd.json cu techStack info │
|
||||
│ │
|
||||
│ 3. ./scripts/ralph/ralph.sh [max_iterations] │
|
||||
│ ├─ Selectează story cu prioritate minimă │
|
||||
│ ├─ Lansează Claude Code (context curat) │
|
||||
│ ├─ Implementează + quality checks │
|
||||
│ ├─ Verificare browser pentru UI (agent-browser) │
|
||||
│ ├─ Commit + marchează passes: true │
|
||||
│ └─ Repetă până toate complete │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Cerințe
|
||||
|
||||
### Obligatorii
|
||||
- **Claude Code CLI** instalat și autentificat
|
||||
- **jq** pentru procesare JSON
|
||||
- **Git** repository
|
||||
|
||||
### Recomandate (pentru verificări UI)
|
||||
- **agent-browser** - pentru verificări vizuale browser
|
||||
```bash
|
||||
npm install -g agent-browser && agent-browser install
|
||||
```
|
||||
|
||||
## Utilizare
|
||||
|
||||
### Pas 1: Generează PRD
|
||||
|
||||
```
|
||||
/ralph:prd
|
||||
|
||||
Vreau să adaug funcționalitate de export CSV pentru dashboard.
|
||||
```
|
||||
|
||||
Claude va:
|
||||
1. Detecta dacă există proiect (package.json, etc.)
|
||||
2. Pune întrebări adaptive:
|
||||
- Proiect nou: ~10 întrebări (stack, arhitectură, UI, auth, etc.)
|
||||
- Feature în proiect existent: ~5-7 întrebări (tip, UI, DB, security)
|
||||
3. Opțional: WebSearch pentru best practices
|
||||
4. Genera PRD în `/tasks/prd-export-csv.md`
|
||||
|
||||
### Pas 2: Convertește în JSON
|
||||
|
||||
```
|
||||
/ralph:convert
|
||||
|
||||
Convertește PRD-ul din tasks/prd-export-csv.md
|
||||
```
|
||||
|
||||
Claude va:
|
||||
1. Detecta tech stack și extrage comenzile din package.json/etc.
|
||||
2. Genera `.claude/settings.json` cu allow-list
|
||||
3. Crea structura `scripts/ralph/` cu fișierele configurate
|
||||
4. Genera `prd.json` cu techStack info
|
||||
|
||||
### Pas 3: Rulează Ralph
|
||||
|
||||
```bash
|
||||
./scripts/ralph/ralph.sh 20 # 20 iterații max
|
||||
```
|
||||
|
||||
### Pas 4: Monitorizare
|
||||
|
||||
```bash
|
||||
# Status stories
|
||||
jq '.userStories[] | {id, title, passes}' scripts/ralph/prd.json
|
||||
|
||||
# Progress log
|
||||
cat scripts/ralph/progress.txt
|
||||
|
||||
# Screenshots UI
|
||||
ls scripts/ralph/screenshots/
|
||||
```
|
||||
|
||||
## Structura proiectului
|
||||
|
||||
După `/ralph:convert`:
|
||||
|
||||
```
|
||||
your-project/
|
||||
├── .claude/
|
||||
│ └── settings.json # Permissions allow-list (generat)
|
||||
├── scripts/ralph/
|
||||
│ ├── ralph.sh # Script principal
|
||||
│ ├── prompt.md # Instrucțiuni per iterație (cu comenzi reale)
|
||||
│ ├── prd.json # Task-uri cu techStack (generat)
|
||||
│ ├── progress.txt # Learnings (generat)
|
||||
│ ├── logs/ # Logs per iterație
|
||||
│ ├── archive/ # Arhive rulări anterioare
|
||||
│ └── screenshots/ # Screenshots verificări UI
|
||||
└── tasks/
|
||||
└── prd-*.md # PRD-uri markdown
|
||||
```
|
||||
|
||||
## Format prd.json
|
||||
|
||||
```json
|
||||
{
|
||||
"projectName": "feature-name",
|
||||
"branchName": "ralph/feature-name",
|
||||
"description": "Descriere feature",
|
||||
"techStack": {
|
||||
"type": "nextjs",
|
||||
"commands": {
|
||||
"start": "npm run dev",
|
||||
"build": "npm run build",
|
||||
"lint": "npm run lint",
|
||||
"typecheck": "npm run typecheck",
|
||||
"test": "npm test"
|
||||
},
|
||||
"port": 3000
|
||||
},
|
||||
"userStories": [
|
||||
{
|
||||
"id": "US-001",
|
||||
"title": "Titlu story",
|
||||
"description": "As a user...",
|
||||
"priority": 1,
|
||||
"acceptanceCriteria": ["..."],
|
||||
"requiresBrowserCheck": true,
|
||||
"passes": false,
|
||||
"notes": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Verificare Browser cu agent-browser
|
||||
|
||||
Pentru stories cu UI (`requiresBrowserCheck: true`), Ralph folosește **agent-browser CLI**:
|
||||
|
||||
```bash
|
||||
# Navighează
|
||||
agent-browser navigate "http://localhost:3000"
|
||||
|
||||
# Snapshot (referințe compacte @e1, @e2, etc.)
|
||||
agent-browser snapshot
|
||||
|
||||
# Interacțiuni
|
||||
agent-browser click @e5
|
||||
agent-browser fill @e3 "value"
|
||||
|
||||
# Screenshot
|
||||
agent-browser screenshot ./scripts/ralph/screenshots/US-001.png
|
||||
|
||||
# Console errors
|
||||
agent-browser console
|
||||
```
|
||||
|
||||
**De ce agent-browser (nu Playwright MCP):**
|
||||
- Referințe compacte (@e1, @e2) - consum minim tokeni
|
||||
- Fiecare iterație Ralph are context limitat
|
||||
- CLI simplu, fără server MCP
|
||||
- Optimizat pentru agenți AI
|
||||
|
||||
## 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
|
||||
|
||||
### 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)
|
||||
|
||||
### Acceptance Criteria
|
||||
- Specifice și verificabile
|
||||
- Include comanda typecheck reală din proiect
|
||||
- Pentru UI: "Verificare vizuală browser că [behavior]"
|
||||
|
||||
## settings.json Auto-Generate
|
||||
|
||||
Per tech stack detectat:
|
||||
|
||||
**Next.js/TypeScript:**
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"npm run dev", "npm run build", "npm run lint",
|
||||
"npm run typecheck", "npx prisma *", "npm test"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Python/FastAPI:**
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"uvicorn * --reload", "python -m pytest",
|
||||
"ruff check .", "mypy .", "alembic *"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Credite
|
||||
|
||||
- [snarktank/ralph](https://github.com/snarktank/ralph) - Ralph original pentru Amp
|
||||
- [coleam00/ai-agents-masterclass](https://github.com/coleam00/ai-agents-masterclass) - Inspirație pentru îmbunătățiri
|
||||
- [vercel-labs/agent-browser](https://github.com/vercel-labs/agent-browser) - Browser CLI pentru verificări UI
|
||||
206
skills/ralph/SKILL.md
Normal file
206
skills/ralph/SKILL.md
Normal file
@@ -0,0 +1,206 @@
|
||||
---
|
||||
name: ralph
|
||||
description: Autonomous PRD creation and conversion for Claude Code autonomous loops - context detection, adaptive questions, browser verification
|
||||
metadata:
|
||||
{
|
||||
"openclaw": { "emoji": "🔄", "requires": { "anyBins": ["claude", "jq", "git"] } },
|
||||
}
|
||||
---
|
||||
|
||||
# Ralph - Autonomous Loop for PRD Implementation
|
||||
|
||||
**Ralph** este un sistem pentru crearea și execuția autonomă a Product Requirements Documents (PRD) cu Claude Code.
|
||||
|
||||
Adaptat din [snarktank/ralph](https://github.com/snarktank/ralph) pentru Claude Code CLI, cu îmbunătățiri inspirate din [coleam00/ai-agents-masterclass](https://github.com/coleam00/ai-agents-masterclass).
|
||||
|
||||
## Comenzi disponibile
|
||||
|
||||
| Comandă | Descriere |
|
||||
|---------|-----------|
|
||||
| `/ralph:prd` | Generează PRD structurat cu detecție context și întrebări adaptive |
|
||||
| `/ralph:convert` | Convertește PRD markdown în prd.json și configurează proiectul |
|
||||
|
||||
## Features
|
||||
|
||||
### Detecție Automată Context
|
||||
- Detectează automat tech stack-ul din fișierele de config (package.json, pyproject.toml, etc.)
|
||||
- Adaptează întrebările: ~10 pentru proiecte noi vs ~5-7 pentru features în proiecte existente
|
||||
- Extrage comenzile reale din proiect (npm scripts, etc.)
|
||||
|
||||
### Întrebări Interactive
|
||||
- Folosește `AskUserQuestion` pentru UX interactiv (nu text simplu)
|
||||
- Web research opțional pentru best practices (WebSearch)
|
||||
- Întrebări adaptive bazate pe context detectat
|
||||
|
||||
### Verificare Vizuală Browser
|
||||
- Folosește **agent-browser CLI** pentru verificări UI
|
||||
- Snapshots compacte cu referințe (@e1, @e2) - eficiente cu tokeni
|
||||
- Screenshots salvate automat pentru referință
|
||||
|
||||
### Configurare Automată
|
||||
- Generează `.claude/settings.json` cu allow-list per tech stack
|
||||
- Actualizează prompt.md cu comenzile reale ale proiectului
|
||||
- Arhivare automată a rulărilor anterioare
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ WORKFLOW RALPH │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 1. /ralph:prd │
|
||||
│ ├─ Detectează context proiect (existent vs nou) │
|
||||
│ ├─ Pune întrebări adaptive cu AskUserQuestion │
|
||||
│ ├─ (Opțional) WebSearch pentru best practices │
|
||||
│ └─ Generează PRD în /tasks/prd-*.md │
|
||||
│ │
|
||||
│ 2. /ralph:convert │
|
||||
│ ├─ Detectează tech stack și comenzi │
|
||||
│ ├─ Generează .claude/settings.json (allow-list) │
|
||||
│ ├─ Copiază și configurează scripts/ralph/ │
|
||||
│ └─ Creează prd.json cu techStack info │
|
||||
│ │
|
||||
│ 3. ./scripts/ralph/ralph.sh [max_iterations] │
|
||||
│ ├─ Selectează story cu prioritate minimă │
|
||||
│ ├─ Lansează Claude Code (context curat) │
|
||||
│ ├─ Implementează + quality checks │
|
||||
│ ├─ Verificare browser pentru UI (agent-browser) │
|
||||
│ ├─ Commit + marchează passes: true │
|
||||
│ └─ Repetă până toate complete │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Când să folosești acest skill
|
||||
|
||||
### Folosește `/ralph:prd` când:
|
||||
- Utilizatorul vrea să adauge o funcționalitate nouă
|
||||
- Vrea să planifice înainte de a implementa
|
||||
- Menționează "PRD", "requirements", "cerințe", "planifică feature"
|
||||
|
||||
### Folosește `/ralph:convert` când:
|
||||
- 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
|
||||
|
||||
## Cerințe
|
||||
|
||||
### Obligatorii
|
||||
- **Claude Code CLI** instalat și autentificat
|
||||
- **jq** pentru procesare JSON
|
||||
- **Git** repository
|
||||
|
||||
### Recomandate (pentru verificări UI)
|
||||
- **agent-browser** - pentru verificări vizuale browser
|
||||
```bash
|
||||
npm install -g agent-browser && agent-browser install
|
||||
```
|
||||
|
||||
## Utilizare rapidă
|
||||
|
||||
### Pas 1: Generează PRD
|
||||
|
||||
Invocă skill-ul și descrie feature-ul:
|
||||
|
||||
```
|
||||
/ralph:prd
|
||||
|
||||
Vreau să adaug funcționalitate de export CSV pentru dashboard.
|
||||
```
|
||||
|
||||
Claude va detecta contextul, pune întrebări adaptive și genera PRD-ul.
|
||||
|
||||
### Pas 2: Convertește în JSON
|
||||
|
||||
```
|
||||
/ralph:convert
|
||||
|
||||
Convertește PRD-ul din tasks/prd-export-csv.md
|
||||
```
|
||||
|
||||
### Pas 3: Rulează Ralph
|
||||
|
||||
```bash
|
||||
./scripts/ralph/ralph.sh 20 # 20 iterații max
|
||||
```
|
||||
|
||||
## Structura proiectului
|
||||
|
||||
După `/ralph:convert`:
|
||||
|
||||
```
|
||||
your-project/
|
||||
├── .claude/
|
||||
│ └── settings.json # Permissions allow-list (generat)
|
||||
├── scripts/ralph/
|
||||
│ ├── ralph.sh # Script principal
|
||||
│ ├── prompt.md # Instrucțiuni per iterație (cu comenzi reale)
|
||||
│ ├── prd.json # Task-uri cu techStack (generat)
|
||||
│ ├── progress.txt # Learnings (generat)
|
||||
│ ├── logs/ # Logs per iterație
|
||||
│ ├── archive/ # Arhive rulări anterioare
|
||||
│ └── screenshots/ # Screenshots verificări UI
|
||||
└── tasks/
|
||||
└── prd-*.md # PRD-uri markdown
|
||||
```
|
||||
|
||||
## Instrucțiuni pentru Agent
|
||||
|
||||
Când utilizatorul invocă `/ralph:prd` sau `/ralph:convert`:
|
||||
|
||||
1. **Citește documentația specifică comenzii** din `commands/prd.md` sau `commands/convert.md`
|
||||
2. **Urmează workflow-ul exact** din documentație
|
||||
3. **Folosește template-urile** din `templates/` când este necesar
|
||||
4. **Salvează output-ul** în locația corectă (`tasks/` pentru PRD, `scripts/ralph/` pentru conversie)
|
||||
|
||||
## Format prd.json
|
||||
|
||||
```json
|
||||
{
|
||||
"projectName": "feature-name",
|
||||
"branchName": "ralph/feature-name",
|
||||
"description": "Descriere feature",
|
||||
"techStack": {
|
||||
"type": "nextjs",
|
||||
"commands": {
|
||||
"start": "npm run dev",
|
||||
"build": "npm run build",
|
||||
"lint": "npm run lint",
|
||||
"typecheck": "npm run typecheck",
|
||||
"test": "npm test"
|
||||
},
|
||||
"port": 3000
|
||||
},
|
||||
"userStories": [
|
||||
{
|
||||
"id": "US-001",
|
||||
"title": "Titlu story",
|
||||
"description": "As a user...",
|
||||
"priority": 1,
|
||||
"acceptanceCriteria": ["..."],
|
||||
"requiresBrowserCheck": true,
|
||||
"passes": false,
|
||||
"notes": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Verificare Browser cu agent-browser
|
||||
|
||||
Pentru stories cu UI (`requiresBrowserCheck: true`), Ralph folosește **agent-browser CLI** pentru verificări vizuale eficiente.
|
||||
|
||||
## Credite
|
||||
|
||||
- [snarktank/ralph](https://github.com/snarktank/ralph) - Ralph original pentru Amp
|
||||
- [coleam00/ai-agents-masterclass](https://github.com/coleam00/ai-agents-masterclass) - Inspirație pentru îmbunătățiri
|
||||
- [vercel-labs/agent-browser](https://github.com/vercel-labs/agent-browser) - Browser CLI pentru verificări UI
|
||||
|
||||
## Template Files Location
|
||||
|
||||
Template-urile pentru acest skill sunt în:
|
||||
- `templates/prompt.md` - Instrucțiuni pentru fiecare iterație Ralph
|
||||
- `templates/ralph.sh` - Script-ul principal de execuție
|
||||
- `templates/prd-template.json` - Template JSON pentru PRD
|
||||
- `commands/prd.md` - Documentație detaliată pentru `/ralph:prd`
|
||||
- `commands/convert.md` - Documentație detaliată pentru `/ralph:convert`
|
||||
- `examples/` - Exemple de PRD-uri generate
|
||||
361
skills/ralph/commands/convert.md
Normal file
361
skills/ralph/commands/convert.md
Normal file
@@ -0,0 +1,361 @@
|
||||
---
|
||||
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 `/ralph: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: Detectează Tech Stack
|
||||
|
||||
**Verifică fișierele de config pentru a determina stack-ul:**
|
||||
|
||||
```
|
||||
package.json → Node.js/JavaScript
|
||||
pyproject.toml → Python
|
||||
go.mod → Go
|
||||
Cargo.toml → Rust
|
||||
pom.xml → Java
|
||||
```
|
||||
|
||||
**Extrage comenzi din config:**
|
||||
|
||||
Pentru `package.json`:
|
||||
```javascript
|
||||
// Citește scripts section:
|
||||
{
|
||||
"scripts": {
|
||||
"dev": "next dev", // → START_COMMAND
|
||||
"build": "next build", // → BUILD_COMMAND
|
||||
"lint": "eslint .", // → LINT_COMMAND
|
||||
"typecheck": "tsc --noEmit" // → TYPECHECK_COMMAND
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Mapare comenzi standard:**
|
||||
|
||||
| Stack | Start | Build | Lint | Typecheck |
|
||||
|-------|-------|-------|------|-----------|
|
||||
| Next.js | npm run dev | npm run build | npm run lint | npm run typecheck |
|
||||
| Node/Express | npm start | npm run build | npm run lint | npm run typecheck |
|
||||
| Python/FastAPI | uvicorn main:app --reload | - | ruff check . | mypy . |
|
||||
| Go | go run . | go build | golangci-lint run | - |
|
||||
| Rust | cargo run | cargo build | cargo clippy | - |
|
||||
|
||||
### Pas 4: Creează structura Ralph
|
||||
|
||||
```bash
|
||||
mkdir -p scripts/ralph/logs scripts/ralph/archive scripts/ralph/screenshots
|
||||
```
|
||||
|
||||
### Pas 5: Generează .claude/settings.json
|
||||
|
||||
**IMPORTANT**: Generează configurația pentru permissions allow-list bazat pe tech stack detectat.
|
||||
|
||||
```bash
|
||||
mkdir -p .claude
|
||||
```
|
||||
|
||||
**Template settings.json per stack:**
|
||||
|
||||
#### Next.js / TypeScript:
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(npm run dev)",
|
||||
"Bash(npm run build)",
|
||||
"Bash(npm run lint)",
|
||||
"Bash(npm run typecheck)",
|
||||
"Bash(npx prisma:*)",
|
||||
"Bash(npm test)",
|
||||
"Bash(npm run test:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Node.js / Express:
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(npm start)",
|
||||
"Bash(npm run dev)",
|
||||
"Bash(npm run build)",
|
||||
"Bash(npm run lint)",
|
||||
"Bash(npm test)",
|
||||
"Bash(npm run test:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Python / FastAPI:
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(uvicorn:*)",
|
||||
"Bash(python -m pytest:*)",
|
||||
"Bash(pytest:*)",
|
||||
"Bash(ruff check:*)",
|
||||
"Bash(ruff format:*)",
|
||||
"Bash(mypy:*)",
|
||||
"Bash(pip install:*)",
|
||||
"Bash(alembic:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Go:
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(go run:*)",
|
||||
"Bash(go build:*)",
|
||||
"Bash(go test:*)",
|
||||
"Bash(golangci-lint:*)",
|
||||
"Bash(go mod:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Generic (fără config detectat):
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(npm run:*)",
|
||||
"Bash(npm test)",
|
||||
"Bash(npm start)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Verifică și merging:**
|
||||
- Dacă `.claude/settings.json` există deja, citește-l și merge permissions
|
||||
- Nu suprascrie setări existente, doar adaugă cele lipsă
|
||||
|
||||
### Pas 6: 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",
|
||||
"techStack": {
|
||||
"type": "nextjs",
|
||||
"commands": {
|
||||
"start": "npm run dev",
|
||||
"build": "npm run build",
|
||||
"lint": "npm run lint",
|
||||
"typecheck": "npm run typecheck",
|
||||
"test": "npm test"
|
||||
},
|
||||
"port": 3000
|
||||
},
|
||||
"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"
|
||||
],
|
||||
"requiresBrowserCheck": true,
|
||||
"passes": false,
|
||||
"notes": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Câmpuri noi:**
|
||||
- `techStack` - informații despre stack-ul detectat
|
||||
- `techStack.commands` - comenzile reale din proiect
|
||||
- `techStack.port` - portul pentru dev server
|
||||
- `requiresBrowserCheck` - true dacă story-ul are UI
|
||||
|
||||
### Pas 7: 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 8: 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 9: Verifică acceptance criteria
|
||||
|
||||
Fiecare story TREBUIE să aibă:
|
||||
- Criterii specifice și verificabile (NU vagi ca "funcționează bine")
|
||||
- Comanda reală de typecheck: `{TYPECHECK_COMMAND} passes`
|
||||
- Pentru UI: `Verificare vizuală browser: [specific behavior]`
|
||||
|
||||
### Pas 10: Copiază template-urile Ralph din plugin
|
||||
|
||||
**IMPORTANT**: Copiază fișierele template direct din plugin pentru a asigura consistența.
|
||||
|
||||
**Execută următoarele comenzi:**
|
||||
|
||||
```bash
|
||||
# Găsește locația plugin-ului Ralph
|
||||
RALPH_PLUGIN=$(find /workspace -type f -name "ralph.sh" -path "*/plugins/ralph/templates/*" 2>/dev/null | head -1 | xargs dirname 2>/dev/null)
|
||||
|
||||
# Verifică că plugin-ul a fost găsit
|
||||
if [ -z "$RALPH_PLUGIN" ]; then
|
||||
echo "EROARE: Nu am găsit plugin-ul Ralph în /workspace"
|
||||
echo "Asigură-te că claude-plugins este clonat în /workspace"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Plugin Ralph găsit în: $RALPH_PLUGIN"
|
||||
|
||||
# Copiază template-urile
|
||||
cp "$RALPH_PLUGIN/prompt.md" scripts/ralph/
|
||||
cp "$RALPH_PLUGIN/ralph.sh" scripts/ralph/
|
||||
chmod +x scripts/ralph/ralph.sh
|
||||
|
||||
echo "Template-uri copiate din plugin"
|
||||
```
|
||||
|
||||
**Dacă plugin-ul NU este găsit:**
|
||||
- Informează utilizatorul că trebuie să cloneze `claude-plugins` în `/workspace`
|
||||
- Sau să specifice manual locația plugin-ului
|
||||
|
||||
**NU genera fișierele manual** - copiază-le întotdeauna din plugin pentru a păstra consistența și a beneficia de actualizări.
|
||||
|
||||
### Pas 11: 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 "Stack: [detected-stack]" >> scripts/ralph/progress.txt
|
||||
echo "---" >> scripts/ralph/progress.txt
|
||||
```
|
||||
|
||||
### Pas 12: Verificare finală
|
||||
|
||||
**Verifică că toate fișierele sunt create:**
|
||||
|
||||
```
|
||||
scripts/ralph/
|
||||
├── ralph.sh # Script principal
|
||||
├── prompt.md # Instrucțiuni (cu comenzi reale)
|
||||
├── prd.json # Task-uri și status
|
||||
├── progress.txt # Log inițializat
|
||||
├── logs/ # Director pentru logs
|
||||
├── archive/ # Director pentru arhivare
|
||||
└── screenshots/ # Director pentru verificări vizuale
|
||||
|
||||
.claude/
|
||||
└── settings.json # Permissions allow-list
|
||||
```
|
||||
|
||||
### Pas 13: Instrucțiuni finale
|
||||
|
||||
După completare, informează utilizatorul:
|
||||
|
||||
```
|
||||
PRD convertit în scripts/ralph/prd.json
|
||||
|
||||
Structură creată:
|
||||
scripts/ralph/ - Fișiere Ralph
|
||||
scripts/ralph/screenshots/ - Pentru verificări vizuale
|
||||
.claude/settings.json - Permissions pentru comenzi
|
||||
|
||||
Tech stack detectat: {stack}
|
||||
Comenzi configurate:
|
||||
Start: {START_COMMAND}
|
||||
Build: {BUILD_COMMAND}
|
||||
Typecheck: {TYPECHECK_COMMAND}
|
||||
Lint: {LINT_COMMAND}
|
||||
Test: {TEST_COMMAND}
|
||||
|
||||
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
|
||||
|
||||
IMPORTANT:
|
||||
- Ralph va folosi agent-browser pentru verificări vizuale UI
|
||||
- Screenshots se salvează în scripts/ralph/screenshots/
|
||||
- Asigură-te că ai agent-browser instalat: npm install -g agent-browser && agent-browser install
|
||||
```
|
||||
|
||||
## Output așteptat
|
||||
|
||||
- `scripts/ralph/prd.json` - task-urile în format JSON cu tech stack info
|
||||
- `scripts/ralph/progress.txt` - log inițializat
|
||||
- `scripts/ralph/prompt.md` - copiat din plugin (single source of truth)
|
||||
- `scripts/ralph/ralph.sh` - copiat din plugin (single source of truth)
|
||||
- `scripts/ralph/screenshots/` - director pentru verificări vizuale
|
||||
- `.claude/settings.json` - permissions allow-list pentru tech stack
|
||||
- Structura de directoare completă
|
||||
|
||||
## Reguli importante
|
||||
|
||||
1. **NU începe implementarea** - acest skill doar convertește PRD-ul
|
||||
2. **Detectează tech stack** - pentru comenzi și settings.json
|
||||
3. **Validează mărimea stories** - sparge-le dacă sunt prea mari
|
||||
4. **Prioritizează corect** - dependențele trebuie respectate
|
||||
5. **Criterii verificabile** - nu vagi, ci specifice
|
||||
6. **Inițializează `passes: false`** pentru toate stories
|
||||
7. **Generează settings.json** - pentru allow-list permissions
|
||||
8. **COPIAZĂ template-urile din plugin** - NU le genera manual, folosește `find` pentru a localiza plugin-ul și copiază `prompt.md` și `ralph.sh` din templates/
|
||||
462
skills/ralph/commands/prd.md
Normal file
462
skills/ralph/commands/prd.md
Normal file
@@ -0,0 +1,462 @@
|
||||
---
|
||||
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 prin detecție automată a contextului și întrebări adaptive.
|
||||
|
||||
## 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
|
||||
|
||||
### FAZA 1: Detecție Context Proiect
|
||||
|
||||
**Verifică existența fișierelor de config pentru a determina modul:**
|
||||
|
||||
```
|
||||
package.json → Node.js/JavaScript ecosystem
|
||||
pyproject.toml → Python
|
||||
requirements.txt → Python (legacy)
|
||||
go.mod → Go
|
||||
Cargo.toml → Rust
|
||||
pom.xml → Java (Maven)
|
||||
build.gradle → Java (Gradle)
|
||||
composer.json → PHP
|
||||
Gemfile → Ruby
|
||||
```
|
||||
|
||||
**DACĂ găsit config file:**
|
||||
1. Citește fișierul de config pentru a extrage:
|
||||
- Dependențe principale (framework-uri, librării)
|
||||
- Scripturi disponibile (pentru package.json)
|
||||
- Versiuni
|
||||
2. Analizează structura directoarelor:
|
||||
- `src/`, `app/`, `components/`, `pages/`, `api/`
|
||||
- Identifică patterns: Next.js, React, Express, etc.
|
||||
3. Raportează utilizatorului:
|
||||
```
|
||||
Am detectat un proiect existent:
|
||||
- Stack: Next.js 14, TypeScript, Prisma, TailwindCSS
|
||||
- Structură: App Router (app/), API routes (app/api/)
|
||||
- Scripts: dev, build, lint, typecheck
|
||||
```
|
||||
4. Setează: **FEATURE_MODE**
|
||||
|
||||
**DACĂ NU găsit config file:**
|
||||
1. Raportează: "Nu am detectat un proiect existent. Vom crea PRD pentru proiect nou."
|
||||
2. Setează: **NEW_PROJECT_MODE**
|
||||
|
||||
---
|
||||
|
||||
### FAZA 2: Întrebări Adaptive cu AskUserQuestion
|
||||
|
||||
**IMPORTANT**: Folosește tool-ul `AskUserQuestion` pentru întrebări interactive, NU text simplu.
|
||||
|
||||
---
|
||||
|
||||
#### IF NEW_PROJECT_MODE:
|
||||
|
||||
**Întrebarea 1** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Ce tip de proiect vrei să creezi?",
|
||||
"header": "Tip proiect",
|
||||
"options": [
|
||||
{"label": "Web Application", "description": "Frontend + Backend, UI interactiv"},
|
||||
{"label": "API / Backend", "description": "REST/GraphQL API, servicii backend"},
|
||||
{"label": "CLI Tool", "description": "Command-line application"},
|
||||
{"label": "Library / SDK", "description": "Cod reutilizabil pentru alți developeri"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 2** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Cine sunt utilizatorii țintă?",
|
||||
"header": "Audiență",
|
||||
"options": [
|
||||
{"label": "End users", "description": "Clienți finali, public larg"},
|
||||
{"label": "Developers", "description": "API/SDK consumers, tehnici"},
|
||||
{"label": "Admin / Staff", "description": "Utilizatori interni, back-office"},
|
||||
{"label": "Sistem automatizat", "description": "Integrări machine-to-machine"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 3** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Ce tech stack preferi?",
|
||||
"header": "Stack",
|
||||
"options": [
|
||||
{"label": "Next.js + TypeScript (Recommended)", "description": "Full-stack React, App Router, API routes"},
|
||||
{"label": "Node.js + Express", "description": "Backend flexibil, REST API"},
|
||||
{"label": "Python + FastAPI", "description": "API modern, async, type hints"},
|
||||
{"label": "Go", "description": "Performance, simplitate, concurrency"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 4** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Ce arhitectură de date preferi?",
|
||||
"header": "Database",
|
||||
"options": [
|
||||
{"label": "PostgreSQL + Prisma (Recommended)", "description": "Relațional, ORM type-safe"},
|
||||
{"label": "MongoDB", "description": "Document store, schema flexibilă"},
|
||||
{"label": "SQLite", "description": "Simplitate, embedded, local-first"},
|
||||
{"label": "Fără persistență", "description": "In-memory, stateless"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 5** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Cum va arăta interfața?",
|
||||
"header": "UI/UX",
|
||||
"options": [
|
||||
{"label": "Dashboard / Admin Panel", "description": "Tabele, grafice, forms complexe"},
|
||||
{"label": "Landing + App simplu", "description": "Marketing + funcționalitate core"},
|
||||
{"label": "API only (no UI)", "description": "Doar backend, documentație API"},
|
||||
{"label": "CLI interface", "description": "Terminal-based interaction"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 6** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Ce tip de autentificare e necesar?",
|
||||
"header": "Auth",
|
||||
"options": [
|
||||
{"label": "Email + Password", "description": "Classic login, JWT sessions"},
|
||||
{"label": "OAuth / Social login", "description": "Google, GitHub, etc."},
|
||||
{"label": "API Keys", "description": "Pentru servicii și integrări"},
|
||||
{"label": "Fără autentificare", "description": "Public access"}
|
||||
],
|
||||
"multiSelect": true
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 7** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Ce integrări externe sunt necesare?",
|
||||
"header": "Integrări",
|
||||
"options": [
|
||||
{"label": "Payment (Stripe)", "description": "Procesare plăți, subscriptions"},
|
||||
{"label": "Email (Resend/SendGrid)", "description": "Trimitere emails tranzacționale"},
|
||||
{"label": "Storage (S3/Cloudflare)", "description": "Upload fișiere, imagini"},
|
||||
{"label": "Niciuna", "description": "Self-contained, fără dependențe externe"}
|
||||
],
|
||||
"multiSelect": true
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 8** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Care e prioritatea acestui proiect?",
|
||||
"header": "Prioritate",
|
||||
"options": [
|
||||
{"label": "MVP rapid", "description": "Funcționalitate minimă, lansare rapidă"},
|
||||
{"label": "Produs complet", "description": "Feature-complete, production-ready"},
|
||||
{"label": "Proof of concept", "description": "Validare idee, poate fi refăcut"},
|
||||
{"label": "Learning project", "description": "Experimentare, nu contează calitatea"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 9** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Cum definim succesul? Ce criterii trebuie îndeplinite?",
|
||||
"header": "Success",
|
||||
"options": [
|
||||
{"label": "Funcționalitate completă", "description": "Toate features funcționează conform spec"},
|
||||
{"label": "Performance targets", "description": "Timp răspuns < X ms, throughput > Y"},
|
||||
{"label": "User adoption", "description": "N utilizatori activi, engagement"},
|
||||
{"label": "Code quality", "description": "Test coverage > 80%, no critical bugs"}
|
||||
],
|
||||
"multiSelect": true
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 10** (text liber - cere descriere):
|
||||
```
|
||||
Descrie pe scurt proiectul în 2-3 propoziții:
|
||||
- Ce problemă rezolvă?
|
||||
- Care e funcționalitatea principală?
|
||||
```
|
||||
|
||||
**Întrebarea 11 - Web Research** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Vrei să cercetez best practices și patterns pentru acest stack?",
|
||||
"header": "Research",
|
||||
"options": [
|
||||
{"label": "Da, cercetează", "description": "WebSearch pentru patterns și recomandări"},
|
||||
{"label": "Nu, continuă", "description": "Am experiență cu acest stack"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**DACĂ utilizatorul alege "Da, cercetează":**
|
||||
- Folosește `WebSearch` pentru: "[stack] best practices 2026"
|
||||
- Integrează findings în secțiunea "Considerații Tehnice" din PRD
|
||||
|
||||
---
|
||||
|
||||
#### IF FEATURE_MODE:
|
||||
|
||||
**Întrebarea 1** (text liber):
|
||||
```
|
||||
Descrie feature-ul pe care vrei să-l adaugi:
|
||||
- Ce funcționalitate nouă?
|
||||
- Care e scopul principal?
|
||||
```
|
||||
|
||||
**Întrebarea 2** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Ce tip de feature este acesta?",
|
||||
"header": "Tip feature",
|
||||
"options": [
|
||||
{"label": "Funcționalitate nouă", "description": "Ceva ce nu există în app"},
|
||||
{"label": "Îmbunătățire UX", "description": "Flow mai bun, mai intuitiv"},
|
||||
{"label": "Performance", "description": "Optimizare viteză, eficiență"},
|
||||
{"label": "Integrare externă", "description": "Conectare cu alt sistem/serviciu"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 3** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Implică modificări de UI?",
|
||||
"header": "UI changes",
|
||||
"options": [
|
||||
{"label": "Da - componente noi", "description": "Pagini sau secțiuni noi"},
|
||||
{"label": "Da - modificări existente", "description": "Update la UI existent"},
|
||||
{"label": "Nu - doar backend", "description": "Logic, API, fără UI"}
|
||||
],
|
||||
"multiSelect": false
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 4** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Necesită modificări în baza de date?",
|
||||
"header": "DB changes",
|
||||
"options": [
|
||||
{"label": "Da - tabele noi", "description": "Noi entități de stocat"},
|
||||
{"label": "Da - coloane noi", "description": "Câmpuri noi pe tabele existente"},
|
||||
{"label": "Da - relații noi", "description": "Legături între tabele"},
|
||||
{"label": "Nu", "description": "Schema rămâne neschimbată"}
|
||||
],
|
||||
"multiSelect": true
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 5** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Sunt necesare integrări noi cu servicii externe?",
|
||||
"header": "Integrări",
|
||||
"options": [
|
||||
{"label": "Da - API extern", "description": "Conectare la serviciu terț"},
|
||||
{"label": "Da - Webhooks", "description": "Primire/trimitere events"},
|
||||
{"label": "Nu", "description": "Self-contained în app"}
|
||||
],
|
||||
"multiSelect": true
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 6** (AskUserQuestion):
|
||||
```json
|
||||
{
|
||||
"question": "Există considerații speciale de security?",
|
||||
"header": "Security",
|
||||
"options": [
|
||||
{"label": "Autorizare/permisiuni", "description": "Cine poate accesa ce"},
|
||||
{"label": "Date sensibile", "description": "PII, payment, credentials"},
|
||||
{"label": "Rate limiting", "description": "Protecție abuse"},
|
||||
{"label": "Nu, standard", "description": "Fără cerințe speciale"}
|
||||
],
|
||||
"multiSelect": true
|
||||
}
|
||||
```
|
||||
|
||||
**Întrebarea 7** (text liber):
|
||||
```
|
||||
Cum verificăm că feature-ul funcționează corect?
|
||||
Descrie acceptance criteria (ce trebuie să se întâmple când e gata):
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### FAZA 3: 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 bazate pe răspunsuri]
|
||||
|
||||
## 2. Context Tehnic
|
||||
[DOAR pentru FEATURE_MODE - include stack-ul detectat]
|
||||
- **Stack**: [detectat din config]
|
||||
- **Structură**: [detectat din directoare]
|
||||
- **Comenzi disponibile**: [din package.json scripts]
|
||||
|
||||
## 3. Obiective
|
||||
### Obiectiv Principal
|
||||
- [Ce problemă rezolvă - din răspunsuri]
|
||||
|
||||
### Obiective Secundare
|
||||
- [Beneficii adiționale]
|
||||
|
||||
### Metrici de Succes
|
||||
- [Din răspunsul la întrebarea despre success criteria]
|
||||
|
||||
## 4. User Stories
|
||||
|
||||
### US-001: [Titlu Descriptiv]
|
||||
**Ca** [tip utilizator - din răspunsuri]
|
||||
**Vreau** [funcționalitate]
|
||||
**Pentru că** [beneficiu]
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- [ ] Criteriu 1 specific și testabil
|
||||
- [ ] Criteriu 2 specific și testabil
|
||||
- [ ] {TYPECHECK_COMMAND} passes
|
||||
- [ ] [Pentru UI] Verificare vizuală cu browser: [comportament specific]
|
||||
|
||||
### US-002: [Titlu]
|
||||
...
|
||||
|
||||
## 5. 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ă...
|
||||
|
||||
## 6. Non-Goals (Ce NU facem)
|
||||
- [Explicit ce nu e în scope pentru a evita scope creep]
|
||||
- [Funcționalități similare care NU sunt incluse]
|
||||
|
||||
## 7. Considerații Tehnice
|
||||
### Stack/Tehnologii
|
||||
- [Din detecție sau răspunsuri]
|
||||
|
||||
### Patterns de Urmat
|
||||
- [Patterns existente în codebase - din analiză]
|
||||
|
||||
### Dependențe
|
||||
- [De ce depinde acest feature]
|
||||
|
||||
### Riscuri Tehnice
|
||||
- [Potențiale probleme]
|
||||
|
||||
### Best Practices
|
||||
[Dacă s-a făcut WebSearch, include findings aici]
|
||||
|
||||
## 8. Considerații UI/UX
|
||||
[Dacă UI changes != "Nu - doar backend"]
|
||||
- Layout și flow
|
||||
- Stări (loading, error, empty, success)
|
||||
- Accesibilitate
|
||||
|
||||
## 9. Considerații Security
|
||||
[Din răspunsul la întrebarea despre security]
|
||||
|
||||
## 10. Open Questions
|
||||
- [ ] [Întrebări nerezolvate care necesită clarificare]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### FAZA 4: Validare și salvare
|
||||
|
||||
1. **Afișează preview** al PRD-ului generat
|
||||
2. **Întreabă** utilizatorul:
|
||||
- "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ă?"
|
||||
3. **Salvează** în `/tasks/prd-[feature-name].md`
|
||||
4. **Sugerează următorul pas**:
|
||||
```
|
||||
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:convert` 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 comanda de typecheck din proiect
|
||||
- Pentru UI: "Verificare vizuală cu browser că [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
|
||||
- Context tehnic detectat (pentru FEATURE_MODE)
|
||||
|
||||
## Important
|
||||
|
||||
1. **NU începe implementarea** - acest skill doar generează documentație
|
||||
2. **Folosește AskUserQuestion** pentru întrebări interactive
|
||||
3. **Detectează contextul** înainte de a pune întrebări
|
||||
4. **Stories atomice** - fiecare trebuie să fie independent completabil
|
||||
5. **Acceptance criteria verificabile** - nu vagi
|
||||
6. **Kebab-case** pentru nume fișiere
|
||||
59
skills/ralph/examples/prd-hello-api.json
Normal file
59
skills/ralph/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": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
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": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
207
skills/ralph/templates/prompt.md
Normal file
207
skills/ralph/templates/prompt.md
Normal file
@@ -0,0 +1,207 @@
|
||||
# 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)
|
||||
- Notează `techStack.commands` din PRD pentru comenzile corecte
|
||||
|
||||
### 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
|
||||
- Verifică câmpul `requiresBrowserCheck` - dacă e `true`, trebuie verificare vizuală
|
||||
|
||||
### 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. Folosește comenzile din `techStack.commands`:
|
||||
|
||||
```bash
|
||||
# Folosește comenzile din prd.json techStack.commands:
|
||||
{techStack.commands.typecheck} # Type checking
|
||||
{techStack.commands.lint} # Linting
|
||||
{techStack.commands.test} # Tests (dacă există)
|
||||
```
|
||||
|
||||
**Comenzi standard per stack:**
|
||||
|
||||
| Stack | Typecheck | Lint | Test |
|
||||
|-------|-----------|------|------|
|
||||
| Next.js/TS | npm run typecheck | npm run lint | npm test |
|
||||
| Node.js | npm run typecheck | npm run lint | npm test |
|
||||
| Python | mypy . | ruff check . | python -m pytest |
|
||||
| Go | - | golangci-lint run | go test ./... |
|
||||
|
||||
**IMPORTANT**: Nu face commit dacă verificările eșuează. Repară mai întâi.
|
||||
|
||||
### 6. Verificare Browser (pentru UI stories)
|
||||
|
||||
**DACĂ story-ul are `requiresBrowserCheck: true` sau implică UI:**
|
||||
|
||||
Folosește **agent-browser CLI** pentru verificare vizuală. Agent-browser e optimizat pentru agenți AI cu referințe compacte (@e1, @e2) care consumă minim tokeni.
|
||||
|
||||
#### 6.1 Pornește dev server-ul
|
||||
```bash
|
||||
# Folosește comanda din techStack.commands.start
|
||||
{techStack.commands.start}
|
||||
# Exemplu: npm run dev
|
||||
```
|
||||
|
||||
Așteaptă să pornească (verifică output-ul pentru "ready" sau similar).
|
||||
|
||||
#### 6.2 Navighează la pagină
|
||||
```bash
|
||||
agent-browser navigate "http://localhost:{techStack.port}"
|
||||
# Exemplu: agent-browser navigate "http://localhost:3000"
|
||||
```
|
||||
|
||||
#### 6.3 Ia snapshot pentru verificare
|
||||
```bash
|
||||
agent-browser snapshot
|
||||
```
|
||||
|
||||
Snapshot-ul returnează o listă de elemente cu referințe compacte:
|
||||
```
|
||||
@e1: heading "Welcome"
|
||||
@e2: button "Login"
|
||||
@e3: textbox "Email"
|
||||
@e4: textbox "Password"
|
||||
@e5: button "Submit"
|
||||
```
|
||||
|
||||
**Verifică în snapshot:**
|
||||
- Elementele cheie din acceptance criteria există
|
||||
- Textul e corect
|
||||
- Structura paginii e corectă
|
||||
|
||||
#### 6.4 Testează interacțiunile (dacă e cazul)
|
||||
```bash
|
||||
# Click pe un element
|
||||
agent-browser click @e2
|
||||
|
||||
# Fill un input
|
||||
agent-browser fill @e3 "test@example.com"
|
||||
|
||||
# Așteaptă o schimbare
|
||||
agent-browser snapshot # verifică noua stare
|
||||
```
|
||||
|
||||
#### 6.5 Salvează screenshot ca dovadă
|
||||
```bash
|
||||
agent-browser screenshot ./scripts/ralph/screenshots/US-{id}-$(date +%Y%m%d-%H%M%S).png
|
||||
# Exemplu: agent-browser screenshot ./scripts/ralph/screenshots/US-001-20240115-143022.png
|
||||
```
|
||||
|
||||
#### 6.6 Verifică erori
|
||||
```bash
|
||||
# Verifică console pentru erori
|
||||
agent-browser console
|
||||
```
|
||||
|
||||
**IMPORTANT**:
|
||||
- NU marca story-ul complete dacă verificarea vizuală eșuează!
|
||||
- Dacă găsești erori în browser, repară-le înainte de commit
|
||||
- Screenshots sunt salvate în `scripts/ralph/screenshots/` pentru referință
|
||||
|
||||
### 7. 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
|
||||
|
||||
### 8. Commit
|
||||
Format commit message:
|
||||
```
|
||||
feat: [Story ID] - [Story Title]
|
||||
```
|
||||
|
||||
### 9. 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`
|
||||
|
||||
### 10. Actualizează progress.txt
|
||||
Adaugă la sfârșitul fișierului `scripts/ralph/progress.txt`:
|
||||
|
||||
```markdown
|
||||
## Iterație: [timestamp]
|
||||
### Story implementat: [ID] - [Title]
|
||||
### Status: Complete
|
||||
|
||||
### Verificări:
|
||||
- Typecheck: PASS
|
||||
- Lint: PASS
|
||||
- Tests: PASS/SKIP
|
||||
- Browser check: PASS/N/A
|
||||
|
||||
### 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. **VERIFICARE BROWSER PENTRU UI** - Obligatorie dacă `requiresBrowserCheck: true`
|
||||
4. **ACTUALIZEAZĂ prd.json** - Altfel iterația următoare va repeta munca
|
||||
5. **FII CONCIS** - Nu over-engineer
|
||||
|
||||
## Comenzi agent-browser (referință rapidă)
|
||||
|
||||
```bash
|
||||
# Navigare
|
||||
agent-browser navigate "http://localhost:3000/page"
|
||||
|
||||
# Snapshot (vedere compactă a paginii)
|
||||
agent-browser snapshot
|
||||
|
||||
# Click pe element (folosind ref din snapshot)
|
||||
agent-browser click @e5
|
||||
|
||||
# Fill input
|
||||
agent-browser fill @e3 "value"
|
||||
|
||||
# Screenshot
|
||||
agent-browser screenshot ./path/to/file.png
|
||||
|
||||
# Console logs
|
||||
agent-browser console
|
||||
|
||||
# Așteaptă text
|
||||
agent-browser wait-for "Loading complete"
|
||||
```
|
||||
|
||||
## Condiție de terminare
|
||||
|
||||
Dacă TOATE stories au `passes: true`, răspunde cu:
|
||||
|
||||
```
|
||||
<promise>COMPLETE</promise>
|
||||
```
|
||||
|
||||
---
|
||||
ÎNCEPE IMPLEMENTAREA ACUM.
|
||||
193
skills/ralph/templates/ralph.sh
Executable file
193
skills/ralph/templates/ralph.sh
Executable file
@@ -0,0 +1,193 @@
|
||||
#!/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"
|
||||
SCREENSHOTS_DIR="$SCRIPT_DIR/screenshots"
|
||||
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ă agent-browser (opțional, pentru verificări UI)
|
||||
if ! command -v agent-browser &> /dev/null; then
|
||||
echo "Notă: agent-browser nu este instalat."
|
||||
echo "Pentru verificări vizuale UI, instalează cu: npm install -g agent-browser && agent-browser install"
|
||||
echo "Continuăm fără verificări browser..."
|
||||
echo ""
|
||||
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
|
||||
|
||||
# Creează directoare necesare
|
||||
mkdir -p "$SCRIPT_DIR/logs" "$SCRIPT_DIR/archive" "$SCRIPT_DIR/screenshots"
|
||||
|
||||
# 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 " Screenshots: $SCREENSHOTS_DIR"
|
||||
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"
|
||||
|
||||
# --output-format json avoids streaming mode issues
|
||||
echo "$FULL_PROMPT" | claude -p --dangerously-skip-permissions --output-format json 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
|
||||
1
test-ralph-workflow/scripts/ralph/.last-branch
Normal file
1
test-ralph-workflow/scripts/ralph/.last-branch
Normal file
@@ -0,0 +1 @@
|
||||
main
|
||||
118
test-ralph-workflow/scripts/ralph/prompt.md
Normal file
118
test-ralph-workflow/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
test-ralph-workflow/scripts/ralph/ralph.sh
Executable file
183
test-ralph-workflow/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
|
||||
47
test-ralph-workflow/tasks/prd-hello-test.md
Normal file
47
test-ralph-workflow/tasks/prd-hello-test.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# PRD: Hello Ralph Workflow Test
|
||||
|
||||
## 1. Introducere
|
||||
Proiect minimal pentru testare workflow Ralph: PRD → Stories → Implementare automată
|
||||
|
||||
## 2. Obiective
|
||||
### Obiectiv Principal
|
||||
- Validare completă workflow Ralph pe moltbot
|
||||
|
||||
### Metrici de Succes
|
||||
- PRD generat corect
|
||||
- Stories executate automat de Ralph (Sonnet)
|
||||
- Code commits cu quality checks
|
||||
|
||||
## 3. User Stories
|
||||
|
||||
### US-001: Setup proiect Node.js
|
||||
**Ca** developer
|
||||
**Vreau** un proiect Node.js minimal cu package.json
|
||||
**Pentru că** validez că Ralph poate initializa proiecte
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- package.json există cu name="hello-ralph-test", version="1.0.0"
|
||||
- README.md există cu descriere proiect
|
||||
- .gitignore există cu node_modules/
|
||||
|
||||
### US-002: Funcție hello simpla
|
||||
**Ca** user
|
||||
**Vreau** o funcție hello(name) care returnează salut
|
||||
**Pentru că** validez că Ralph poate scrie cod funcțional
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- src/hello.js există
|
||||
- Funcție hello(name) returnează "Hello, {name}!"
|
||||
- Exportată ca module.exports = { hello }
|
||||
- Funcția trimite toLowerCase pe name
|
||||
|
||||
### US-003: Test pentru hello
|
||||
**Ca** developer
|
||||
**Vreau** un test simplu pentru funcția hello
|
||||
**Pentru că** validez quality checks Ralph
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- package.json include "test" script și dev dependency jest
|
||||
- tests/hello.test.js există
|
||||
- Test verifică hello("World") === "Hello, world!"
|
||||
- npm test passes
|
||||
Reference in New Issue
Block a user