@dewtech/dare-cli 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -2
- package/dist/__tests__/dag-runner/dag-viz.test.d.ts +2 -0
- package/dist/__tests__/dag-runner/dag-viz.test.d.ts.map +1 -0
- package/dist/__tests__/dag-runner/dag-viz.test.js +72 -0
- package/dist/__tests__/dag-runner/dag-viz.test.js.map +1 -0
- package/dist/__tests__/dag-runner/ralph-loop.test.d.ts +2 -0
- package/dist/__tests__/dag-runner/ralph-loop.test.d.ts.map +1 -0
- package/dist/__tests__/dag-runner/ralph-loop.test.js +109 -0
- package/dist/__tests__/dag-runner/ralph-loop.test.js.map +1 -0
- package/dist/bin/dare.js +4 -0
- package/dist/bin/dare.js.map +1 -1
- package/dist/commands/blueprint.d.ts.map +1 -1
- package/dist/commands/blueprint.js +47 -25
- package/dist/commands/blueprint.js.map +1 -1
- package/dist/commands/bootstrap.d.ts +14 -0
- package/dist/commands/bootstrap.d.ts.map +1 -0
- package/dist/commands/bootstrap.js +103 -0
- package/dist/commands/bootstrap.js.map +1 -0
- package/dist/commands/dag.d.ts +11 -0
- package/dist/commands/dag.d.ts.map +1 -0
- package/dist/commands/dag.js +148 -0
- package/dist/commands/dag.js.map +1 -0
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +59 -5
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +1 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/dag-runner/ralph-loop.d.ts +42 -0
- package/dist/dag-runner/ralph-loop.d.ts.map +1 -0
- package/dist/dag-runner/ralph-loop.js +185 -0
- package/dist/dag-runner/ralph-loop.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/project-generator.d.ts +6 -0
- package/dist/utils/project-generator.d.ts.map +1 -1
- package/dist/utils/project-generator.js +112 -16
- package/dist/utils/project-generator.js.map +1 -1
- package/dist/utils/stack-bootstrap.d.ts +22 -0
- package/dist/utils/stack-bootstrap.d.ts.map +1 -0
- package/dist/utils/stack-bootstrap.js +334 -0
- package/dist/utils/stack-bootstrap.js.map +1 -0
- package/package.json +1 -1
- package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +30 -2
- package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +17 -3
- package/templates/ide/claude/.claude/commands/dare-blueprint.md +21 -2
- package/templates/ide/cursor/.cursor/commands/generate-tasks.md +29 -4
- package/templates/ide/cursor/.cursor/rules/skill-dag-runner.mdc +37 -2
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack bootstrap — runs the official scaffold for the chosen backend /
|
|
3
|
+
* frontend / MCP stack. Called by `dare init` BEFORE the DARE artifacts are
|
|
4
|
+
* copied on top.
|
|
5
|
+
*
|
|
6
|
+
* No fallbacks: if the required tool (composer / npm / cargo / python) is not
|
|
7
|
+
* on PATH, this module throws a clear error pointing to install instructions.
|
|
8
|
+
* Generating a fake skeleton is what got us into trouble before — we don't
|
|
9
|
+
* do that anymore.
|
|
10
|
+
*/
|
|
11
|
+
import { spawn } from 'node:child_process';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import fs from 'fs-extra';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
16
|
+
export async function bootstrapBackend(opts) {
|
|
17
|
+
switch (opts.stack) {
|
|
18
|
+
case 'php-laravel':
|
|
19
|
+
return bootstrapPhpLaravel(opts.dir, opts.projectName);
|
|
20
|
+
case 'node-nestjs':
|
|
21
|
+
return bootstrapNodeNestjs(opts.dir, opts.projectName);
|
|
22
|
+
case 'python-fastapi':
|
|
23
|
+
return bootstrapPythonFastapi(opts.dir);
|
|
24
|
+
case 'rust-axum':
|
|
25
|
+
return bootstrapRustAxum(opts.dir, opts.projectName);
|
|
26
|
+
case 'go-gin':
|
|
27
|
+
return bootstrapGoGin(opts.dir, opts.projectName);
|
|
28
|
+
default:
|
|
29
|
+
throw new Error(`Unknown backend stack: ${opts.stack}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function bootstrapFrontend(opts) {
|
|
33
|
+
switch (opts.stack) {
|
|
34
|
+
case 'react':
|
|
35
|
+
return bootstrapVite(opts.dir, 'react-ts');
|
|
36
|
+
case 'vue':
|
|
37
|
+
return bootstrapVite(opts.dir, 'vue-ts');
|
|
38
|
+
default:
|
|
39
|
+
throw new Error(`Unknown frontend stack: ${opts.stack}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function bootstrapMcp(opts) {
|
|
43
|
+
switch (opts.language) {
|
|
44
|
+
case 'node-ts':
|
|
45
|
+
return bootstrapMcpNode(opts.dir, opts.projectName);
|
|
46
|
+
case 'python':
|
|
47
|
+
return bootstrapMcpPython(opts.dir);
|
|
48
|
+
default:
|
|
49
|
+
throw new Error(`Unknown MCP language: ${opts.language}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ─── Per-stack scaffolds ────────────────────────────────────────────────────
|
|
53
|
+
async function bootstrapPhpLaravel(dir, projectName) {
|
|
54
|
+
await ensureCommand('composer', 'Install Composer: https://getcomposer.org/download/');
|
|
55
|
+
banner(`Bootstrapping Laravel 11 in ${dir}`);
|
|
56
|
+
await runCmd('composer', [
|
|
57
|
+
'create-project',
|
|
58
|
+
'laravel/laravel:^11',
|
|
59
|
+
'.',
|
|
60
|
+
'--no-interaction',
|
|
61
|
+
'--prefer-dist',
|
|
62
|
+
], dir);
|
|
63
|
+
await runCmd('composer', ['require', 'laravel/sanctum', 'tymon/jwt-auth', '--no-interaction'], dir);
|
|
64
|
+
await runCmd('composer', [
|
|
65
|
+
'require',
|
|
66
|
+
'--dev',
|
|
67
|
+
'laravel/pint',
|
|
68
|
+
'larastan/larastan',
|
|
69
|
+
'--no-interaction',
|
|
70
|
+
], dir);
|
|
71
|
+
// Best-effort: rename app to projectName in composer.json
|
|
72
|
+
await tryRenameComposerProject(dir, projectName);
|
|
73
|
+
}
|
|
74
|
+
async function bootstrapNodeNestjs(dir, projectName) {
|
|
75
|
+
await ensureCommand('npx', 'Install Node.js (includes npx): https://nodejs.org/');
|
|
76
|
+
banner(`Bootstrapping NestJS in ${dir}`);
|
|
77
|
+
await runCmd('npx', [
|
|
78
|
+
'-y',
|
|
79
|
+
'@nestjs/cli@latest',
|
|
80
|
+
'new',
|
|
81
|
+
'.',
|
|
82
|
+
'--skip-git',
|
|
83
|
+
'--strict',
|
|
84
|
+
'--package-manager',
|
|
85
|
+
'npm',
|
|
86
|
+
'--directory',
|
|
87
|
+
'.',
|
|
88
|
+
], dir);
|
|
89
|
+
await tryRenameNpmProject(dir, projectName);
|
|
90
|
+
}
|
|
91
|
+
async function bootstrapPythonFastapi(dir) {
|
|
92
|
+
await ensureCommand('python', 'Install Python 3.11+ from https://www.python.org/downloads/');
|
|
93
|
+
banner(`Bootstrapping FastAPI in ${dir}`);
|
|
94
|
+
// Create virtualenv
|
|
95
|
+
await runCmd('python', ['-m', 'venv', '.venv'], dir);
|
|
96
|
+
// Write a starter requirements.txt + main.py if not present (since FastAPI
|
|
97
|
+
// has no official scaffold). The DARE template copy will overwrite later
|
|
98
|
+
// only if we left placeholders here.
|
|
99
|
+
const reqPath = path.join(dir, 'requirements.txt');
|
|
100
|
+
if (!(await fs.pathExists(reqPath))) {
|
|
101
|
+
await fs.writeFile(reqPath, [
|
|
102
|
+
'fastapi>=0.115',
|
|
103
|
+
'uvicorn[standard]>=0.30',
|
|
104
|
+
'pydantic-settings>=2.4',
|
|
105
|
+
'sqlalchemy>=2.0',
|
|
106
|
+
'alembic>=1.13',
|
|
107
|
+
'asyncpg>=0.29',
|
|
108
|
+
'python-jose[cryptography]>=3.3',
|
|
109
|
+
'passlib[bcrypt]>=1.7',
|
|
110
|
+
'pytest>=8.0',
|
|
111
|
+
'pytest-asyncio>=0.23',
|
|
112
|
+
'ruff>=0.6',
|
|
113
|
+
'',
|
|
114
|
+
].join('\n'));
|
|
115
|
+
}
|
|
116
|
+
// pip install
|
|
117
|
+
const pip = path.join(dir, '.venv', process.platform === 'win32' ? 'Scripts\\pip.exe' : 'bin/pip');
|
|
118
|
+
await runCmd(pip, ['install', '--upgrade', 'pip'], dir);
|
|
119
|
+
await runCmd(pip, ['install', '-r', 'requirements.txt'], dir);
|
|
120
|
+
}
|
|
121
|
+
async function bootstrapRustAxum(dir, projectName) {
|
|
122
|
+
await ensureCommand('cargo', 'Install Rust toolchain: https://www.rust-lang.org/tools/install');
|
|
123
|
+
banner(`Bootstrapping Rust + Axum in ${dir}`);
|
|
124
|
+
await runCmd('cargo', ['init', '--name', sanitizeCrateName(projectName)], dir);
|
|
125
|
+
// Replace generated Cargo.toml with axum-ready dependencies.
|
|
126
|
+
const cargoToml = path.join(dir, 'Cargo.toml');
|
|
127
|
+
await fs.writeFile(cargoToml, [
|
|
128
|
+
`[package]`,
|
|
129
|
+
`name = "${sanitizeCrateName(projectName)}"`,
|
|
130
|
+
`version = "0.1.0"`,
|
|
131
|
+
`edition = "2021"`,
|
|
132
|
+
``,
|
|
133
|
+
`[dependencies]`,
|
|
134
|
+
`axum = "0.7"`,
|
|
135
|
+
`tokio = { version = "1.40", features = ["full"] }`,
|
|
136
|
+
`tower = "0.5"`,
|
|
137
|
+
`tower-http = { version = "0.6", features = ["cors", "trace"] }`,
|
|
138
|
+
`serde = { version = "1.0", features = ["derive"] }`,
|
|
139
|
+
`serde_json = "1.0"`,
|
|
140
|
+
`tracing = "0.1"`,
|
|
141
|
+
`tracing-subscriber = { version = "0.3", features = ["env-filter"] }`,
|
|
142
|
+
`thiserror = "1.0"`,
|
|
143
|
+
`anyhow = "1.0"`,
|
|
144
|
+
`uuid = { version = "1.10", features = ["v4", "serde"] }`,
|
|
145
|
+
`sqlx = { version = "0.8", features = ["runtime-tokio", "postgres", "uuid", "chrono"] }`,
|
|
146
|
+
``,
|
|
147
|
+
`[dev-dependencies]`,
|
|
148
|
+
`tokio = { version = "1.40", features = ["macros", "rt-multi-thread"] }`,
|
|
149
|
+
``,
|
|
150
|
+
].join('\n'));
|
|
151
|
+
// Pre-fetch dependencies so first build is faster.
|
|
152
|
+
await runCmd('cargo', ['fetch'], dir);
|
|
153
|
+
}
|
|
154
|
+
async function bootstrapGoGin(dir, projectName) {
|
|
155
|
+
await ensureCommand('go', 'Install Go 1.22+: https://go.dev/dl/');
|
|
156
|
+
banner(`Bootstrapping Go + Gin in ${dir}`);
|
|
157
|
+
const moduleName = sanitizeGoModule(projectName);
|
|
158
|
+
// 1) Initialize module
|
|
159
|
+
await runCmd('go', ['mod', 'init', moduleName], dir);
|
|
160
|
+
// 2) Add core deps
|
|
161
|
+
await runCmd('go', ['get', 'github.com/gin-gonic/gin@latest'], dir);
|
|
162
|
+
await runCmd('go', ['get', 'github.com/joho/godotenv@latest'], dir);
|
|
163
|
+
// 3) Lay down a working starter so go build / go test / go vet have
|
|
164
|
+
// something to compile against. Without this, `go vet ./...` would
|
|
165
|
+
// succeed trivially with zero packages and the Ralph Loop would be
|
|
166
|
+
// a no-op until the agent writes code.
|
|
167
|
+
await fs.ensureDir(path.join(dir, 'cmd', 'api'));
|
|
168
|
+
await fs.ensureDir(path.join(dir, 'internal', 'handlers'));
|
|
169
|
+
await fs.ensureDir(path.join(dir, 'internal', 'middleware'));
|
|
170
|
+
await fs.writeFile(path.join(dir, 'cmd', 'api', 'main.go'), `package main
|
|
171
|
+
|
|
172
|
+
import (
|
|
173
|
+
\t"log"
|
|
174
|
+
\t"os"
|
|
175
|
+
|
|
176
|
+
\t"github.com/gin-gonic/gin"
|
|
177
|
+
\t"${moduleName}/internal/handlers"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
func main() {
|
|
181
|
+
\tr := gin.Default()
|
|
182
|
+
|
|
183
|
+
\tr.GET("/healthz", handlers.Health)
|
|
184
|
+
|
|
185
|
+
\tv1 := r.Group("/api/v1")
|
|
186
|
+
\t{
|
|
187
|
+
\t\tv1.GET("/", func(c *gin.Context) {
|
|
188
|
+
\t\t\tc.JSON(200, gin.H{"message": "API v1"})
|
|
189
|
+
\t\t})
|
|
190
|
+
\t}
|
|
191
|
+
|
|
192
|
+
\tport := os.Getenv("PORT")
|
|
193
|
+
\tif port == "" {
|
|
194
|
+
\t\tport = "8080"
|
|
195
|
+
\t}
|
|
196
|
+
\tif err := r.Run(":" + port); err != nil {
|
|
197
|
+
\t\tlog.Fatal(err)
|
|
198
|
+
\t}
|
|
199
|
+
}
|
|
200
|
+
`);
|
|
201
|
+
await fs.writeFile(path.join(dir, 'internal', 'handlers', 'health.go'), `package handlers
|
|
202
|
+
|
|
203
|
+
import (
|
|
204
|
+
\t"net/http"
|
|
205
|
+
|
|
206
|
+
\t"github.com/gin-gonic/gin"
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
// Health returns 200 with a small status payload.
|
|
210
|
+
func Health(c *gin.Context) {
|
|
211
|
+
\tc.JSON(http.StatusOK, gin.H{"status": "ok"})
|
|
212
|
+
}
|
|
213
|
+
`);
|
|
214
|
+
await fs.writeFile(path.join(dir, 'internal', 'handlers', 'health_test.go'), `package handlers
|
|
215
|
+
|
|
216
|
+
import (
|
|
217
|
+
\t"net/http"
|
|
218
|
+
\t"net/http/httptest"
|
|
219
|
+
\t"testing"
|
|
220
|
+
|
|
221
|
+
\t"github.com/gin-gonic/gin"
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
func TestHealth(t *testing.T) {
|
|
225
|
+
\tgin.SetMode(gin.TestMode)
|
|
226
|
+
\tr := gin.New()
|
|
227
|
+
\tr.GET("/healthz", Health)
|
|
228
|
+
|
|
229
|
+
\treq := httptest.NewRequest(http.MethodGet, "/healthz", nil)
|
|
230
|
+
\trec := httptest.NewRecorder()
|
|
231
|
+
\tr.ServeHTTP(rec, req)
|
|
232
|
+
|
|
233
|
+
\tif rec.Code != http.StatusOK {
|
|
234
|
+
\t\tt.Fatalf("expected 200, got %d", rec.Code)
|
|
235
|
+
\t}
|
|
236
|
+
}
|
|
237
|
+
`);
|
|
238
|
+
// 4) Tidy go.mod and resolve transitive deps
|
|
239
|
+
await runCmd('go', ['mod', 'tidy'], dir);
|
|
240
|
+
}
|
|
241
|
+
async function bootstrapVite(dir, template) {
|
|
242
|
+
await ensureCommand('npm', 'Install Node.js: https://nodejs.org/');
|
|
243
|
+
banner(`Bootstrapping Vite (${template}) in ${dir}`);
|
|
244
|
+
// `npm create vite@latest . -- --template react-ts` requires the directory
|
|
245
|
+
// to be empty. We're being called from `dare init`, which created an empty
|
|
246
|
+
// directory, so this is fine.
|
|
247
|
+
await runCmd('npm', ['create', 'vite@latest', '.', '--', '--template', template], dir);
|
|
248
|
+
await runCmd('npm', ['install'], dir);
|
|
249
|
+
}
|
|
250
|
+
async function bootstrapMcpNode(dir, projectName) {
|
|
251
|
+
await ensureCommand('npm', 'Install Node.js: https://nodejs.org/');
|
|
252
|
+
banner(`Bootstrapping MCP server (TypeScript) in ${dir}`);
|
|
253
|
+
await runCmd('npm', ['init', '-y'], dir);
|
|
254
|
+
await runCmd('npm', ['install', '@modelcontextprotocol/sdk'], dir);
|
|
255
|
+
await runCmd('npm', ['install', '--save-dev', 'typescript', '@types/node', 'tsx', 'vitest'], dir);
|
|
256
|
+
await tryRenameNpmProject(dir, projectName);
|
|
257
|
+
}
|
|
258
|
+
async function bootstrapMcpPython(dir) {
|
|
259
|
+
await ensureCommand('python', 'Install Python 3.11+: https://www.python.org/downloads/');
|
|
260
|
+
banner(`Bootstrapping MCP server (Python) in ${dir}`);
|
|
261
|
+
await runCmd('python', ['-m', 'venv', '.venv'], dir);
|
|
262
|
+
const pip = path.join(dir, '.venv', process.platform === 'win32' ? 'Scripts\\pip.exe' : 'bin/pip');
|
|
263
|
+
await runCmd(pip, ['install', '--upgrade', 'pip'], dir);
|
|
264
|
+
await runCmd(pip, ['install', 'mcp[cli]', 'pytest', 'ruff'], dir);
|
|
265
|
+
}
|
|
266
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
267
|
+
function banner(msg) {
|
|
268
|
+
console.log(chalk.blue.bold(`\n📦 ${msg}\n`));
|
|
269
|
+
}
|
|
270
|
+
async function ensureCommand(cmd, hint) {
|
|
271
|
+
const exists = await hasCommand(cmd);
|
|
272
|
+
if (!exists) {
|
|
273
|
+
throw new Error(`Required tool not found on PATH: ${cmd}\n ${hint}\n` +
|
|
274
|
+
`dare init requires a working ${cmd} to scaffold the chosen stack.`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async function hasCommand(cmd) {
|
|
278
|
+
return new Promise((resolve) => {
|
|
279
|
+
const probe = spawn(cmd, ['--version'], { shell: true, stdio: 'ignore' });
|
|
280
|
+
probe.on('error', () => resolve(false));
|
|
281
|
+
probe.on('close', (code) => resolve(code === 0));
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
async function runCmd(cmd, args, cwd) {
|
|
285
|
+
console.log(chalk.gray(` $ ${cmd} ${args.join(' ')}`));
|
|
286
|
+
await new Promise((resolve, reject) => {
|
|
287
|
+
const proc = spawn(cmd, args, {
|
|
288
|
+
cwd,
|
|
289
|
+
stdio: 'inherit',
|
|
290
|
+
shell: true,
|
|
291
|
+
});
|
|
292
|
+
proc.on('error', (err) => reject(err));
|
|
293
|
+
proc.on('close', (code) => {
|
|
294
|
+
if (code === 0)
|
|
295
|
+
resolve();
|
|
296
|
+
else
|
|
297
|
+
reject(new Error(`${cmd} ${args.join(' ')} exited with code ${code}`));
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
function sanitizeCrateName(name) {
|
|
302
|
+
return name.toLowerCase().replace(/[^a-z0-9_]+/g, '_').replace(/^_+|_+$/g, '') || 'app';
|
|
303
|
+
}
|
|
304
|
+
function sanitizeGoModule(name) {
|
|
305
|
+
// Go module path: lowercase, hyphens allowed, no spaces or symbols.
|
|
306
|
+
return name.toLowerCase().replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '') || 'app';
|
|
307
|
+
}
|
|
308
|
+
async function tryRenameComposerProject(dir, projectName) {
|
|
309
|
+
const cj = path.join(dir, 'composer.json');
|
|
310
|
+
if (!(await fs.pathExists(cj)))
|
|
311
|
+
return;
|
|
312
|
+
try {
|
|
313
|
+
const data = await fs.readJson(cj);
|
|
314
|
+
data.name = `dare/${projectName.toLowerCase().replace(/[^a-z0-9-]+/g, '-')}`;
|
|
315
|
+
await fs.writeJson(cj, data, { spaces: 4 });
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
// non-critical
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
async function tryRenameNpmProject(dir, projectName) {
|
|
322
|
+
const pj = path.join(dir, 'package.json');
|
|
323
|
+
if (!(await fs.pathExists(pj)))
|
|
324
|
+
return;
|
|
325
|
+
try {
|
|
326
|
+
const data = await fs.readJson(pj);
|
|
327
|
+
data.name = projectName.toLowerCase().replace(/[^a-z0-9-]+/g, '-');
|
|
328
|
+
await fs.writeJson(pj, data, { spaces: 2 });
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
// non-critical
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=stack-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-bootstrap.js","sourceRoot":"","sources":["../../src/utils/stack-bootstrap.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -81,12 +81,20 @@ tasks:
|
|
|
81
81
|
2. Para cada prompt:
|
|
82
82
|
- leia spec_file se houver
|
|
83
83
|
- implemente
|
|
84
|
-
- rode build/test/lint (Ralph Loop)
|
|
85
84
|
3. dare execute --complete <id> --output "<resumo + arquivos tocados>"
|
|
86
|
-
|
|
85
|
+
↓ o CLI roda o RALPH LOOP automático (build → test → lint)
|
|
86
|
+
↓ se passar: task vira DONE
|
|
87
|
+
↓ se falhar: task vira FAILED com stderr capturado; corrija e retente
|
|
87
88
|
4. Volte ao passo 1 até não haver mais tasks ready
|
|
88
89
|
```
|
|
89
90
|
|
|
91
|
+
> **Ralph Loop é AUTOMÁTICO e OBRIGATÓRIO.** Você NÃO roda build/test/lint
|
|
92
|
+
> manualmente — o `dare execute --complete` faz isso. Se algum gate falhar,
|
|
93
|
+
> a task NÃO vai para DONE; vai para FAILED. Corrija e retente.
|
|
94
|
+
>
|
|
95
|
+
> **Não existe flag para pular o Ralph Loop.** Toda task passa pelos 3 gates
|
|
96
|
+
> da stack do projeto.
|
|
97
|
+
|
|
90
98
|
Comandos úteis:
|
|
91
99
|
|
|
92
100
|
```bash
|
|
@@ -164,6 +172,23 @@ O CLI reescreve a cada `--complete`/`--fail`:
|
|
|
164
172
|
| Tudo em rank 0 | Adicione deps reais quando há contenção |
|
|
165
173
|
| Cadeia linear | Reveja se as deps são necessárias |
|
|
166
174
|
|
|
175
|
+
## Antipatterns que você NÃO deve criar
|
|
176
|
+
|
|
177
|
+
- ❌ Task **"Ralph Loop final"** / **"Hardening"** / **"QA"** — gate é por task
|
|
178
|
+
- ❌ Tests com `assertTrue(true)` — o gate `test` roda de verdade
|
|
179
|
+
- ❌ "Setup project structure" antes de containerizar o app
|
|
180
|
+
|
|
181
|
+
## Ordem recomendada das primeiras tasks
|
|
182
|
+
|
|
183
|
+
1. **Containerize app** (Dockerfile + docker-compose + healthcheck)
|
|
184
|
+
2. **Database schema** (migrations + factories)
|
|
185
|
+
3. **Core endpoints / componentes**
|
|
186
|
+
4. **Auth / autorização**
|
|
187
|
+
5. **Test suite real** (assertions de verdade)
|
|
188
|
+
|
|
189
|
+
A task de container/compose pode estar em outra ordem para projetos sem
|
|
190
|
+
DB ou em monorepo já containerizado. Mas quase sempre é uma das primeiras.
|
|
191
|
+
|
|
167
192
|
## Checklist antes de aprovar
|
|
168
193
|
|
|
169
194
|
- [ ] Pelo menos 2 tasks no rank 0
|
|
@@ -172,4 +197,7 @@ O CLI reescreve a cada `--complete`/`--fail`:
|
|
|
172
197
|
- [ ] `complexity` reflete o esforço real
|
|
173
198
|
- [ ] `id` em kebab-case e único
|
|
174
199
|
- [ ] Sem ciclos
|
|
200
|
+
- [ ] **Sem task de "Ralph Loop final"** — gate é por task
|
|
201
|
+
- [ ] **Tests com assertions reais** — placeholder quebra o gate
|
|
202
|
+
- [ ] Container/runtime resolvido cedo
|
|
175
203
|
- [ ] Os 3 artefatos consistentes
|
|
@@ -182,14 +182,28 @@ Antes de entregar, confirme:
|
|
|
182
182
|
- [ ] Pelo menos 2 tasks no rank 0
|
|
183
183
|
- [ ] Cada `subtask_prompt` é executável sem contexto adicional
|
|
184
184
|
|
|
185
|
-
### Passo 7:
|
|
185
|
+
### Passo 7: Regenerar a visualização do DAG
|
|
186
186
|
|
|
187
|
-
|
|
187
|
+
Depois de salvar o `dare-dag.yaml`, rode:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
dare dag viz -o DARE/dag-graph.mmd
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Isso reescreve `DARE/dag-graph.mmd` (Mermaid) refletindo o grafo atualizado.
|
|
194
|
+
O usuário pode abrir o arquivo no Antigravity para visualizar o grafo
|
|
195
|
+
estático com cores por status antes de executar.
|
|
196
|
+
|
|
197
|
+
### Passo 8: Pedir aprovação
|
|
198
|
+
|
|
199
|
+
> Gerados os 4 artefatos da fase de execução:
|
|
188
200
|
> - `DARE/TASKS.md` ([N] tasks)
|
|
189
201
|
> - `DARE/dare-dag.yaml` ([N] ranks paralelos)
|
|
190
202
|
> - `DARE/EXECUTION/task-*.md` ([N] specs)
|
|
203
|
+
> - `DARE/dag-graph.mmd` (visualização Mermaid do DAG)
|
|
191
204
|
>
|
|
192
|
-
> Revise
|
|
205
|
+
> Revise (abra `dag-graph.mmd` para ver o grafo). Quando aprovar:
|
|
206
|
+
> `dare execute --next` para iniciar a execução.
|
|
193
207
|
|
|
194
208
|
## Boas práticas
|
|
195
209
|
|
|
@@ -71,6 +71,12 @@ tasks:
|
|
|
71
71
|
- `complexity` honesta: `HIGH` só para lógica crítica/segurança
|
|
72
72
|
- Output cap de 4000 chars: se a task gera muito, escreva em arquivo e
|
|
73
73
|
retorne só resumo + caminhos
|
|
74
|
+
- **A primeira task deve containerizar a aplicação** (Dockerfile + compose
|
|
75
|
+
+ healthcheck) — sem isso o Ralph Loop automático não tem onde rodar
|
|
76
|
+
- **NÃO crie task "Ralph Loop final" / "Hardening" / "QA final"** — o
|
|
77
|
+
Ralph Loop roda em CADA `dare execute --complete`, automaticamente
|
|
78
|
+
- **Tests com assertions reais** — `assertTrue(true)` quebra o gate `test`
|
|
79
|
+
e a task vai para FAILED
|
|
74
80
|
|
|
75
81
|
### 4. Gerar `DARE/TASKS.md` (visão humana)
|
|
76
82
|
|
|
@@ -115,9 +121,22 @@ Antes de entregar:
|
|
|
115
121
|
- [ ] Pelo menos 2 tasks no rank 0
|
|
116
122
|
- [ ] Cada `subtask_prompt` executável sem contexto adicional
|
|
117
123
|
|
|
118
|
-
### 7.
|
|
124
|
+
### 7. Regenerar a visualização do DAG
|
|
119
125
|
|
|
120
|
-
|
|
126
|
+
Depois de salvar o `dare-dag.yaml`, rode:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
dare dag viz -o DARE/dag-graph.mmd
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Isso reescreve `DARE/dag-graph.mmd` (Mermaid) refletindo o grafo atualizado.
|
|
133
|
+
O usuário pode abrir no editor com Markdown Preview Mermaid para ver o
|
|
134
|
+
grafo estático com cores por status antes de executar.
|
|
135
|
+
|
|
136
|
+
### 8. Aguardar aprovação humana
|
|
137
|
+
|
|
138
|
+
**Não execute nenhuma task** até o usuário revisar e aprovar os 5 artefatos
|
|
139
|
+
(BLUEPRINT, TASKS, dare-dag.yaml, EXECUTION/task-*, dag-graph.mmd).
|
|
121
140
|
|
|
122
141
|
## Templates disponíveis
|
|
123
142
|
|
|
@@ -29,6 +29,19 @@ executável pelo CLI) e `EXECUTION/task-<id>.md` (specs detalhadas por task).
|
|
|
29
29
|
ter tasks específicas ou estar explícitas nas tasks relevantes.
|
|
30
30
|
- Atribua `complexity` a cada task: LOW / MED / HIGH.
|
|
31
31
|
|
|
32
|
+
#### Regras inegociáveis de ordenação
|
|
33
|
+
|
|
34
|
+
1. **A primeira task deve preparar o ambiente local** — Dockerfile +
|
|
35
|
+
`docker-compose.yml` + healthcheck. Sem isso o Ralph Loop não tem onde
|
|
36
|
+
rodar build/test/lint. Exceção: projeto que já vive em monorepo
|
|
37
|
+
containerizado.
|
|
38
|
+
2. **Não crie task "Ralph Loop final" / "Hardening final"** — o Ralph Loop
|
|
39
|
+
roda automático em cada `dare execute --complete`. Não é uma task; é um
|
|
40
|
+
gate por task.
|
|
41
|
+
3. **Tests devem ter assertions reais** desde a task que os escreve.
|
|
42
|
+
Placeholders (`assertTrue(true)` etc.) fazem o gate `test` falhar e a
|
|
43
|
+
task vai para FAILED.
|
|
44
|
+
|
|
32
45
|
### 3. Gerar `DARE/TASKS.md` (visão humana)
|
|
33
46
|
|
|
34
47
|
Tabela com todas as tasks e dependências em formato legível:
|
|
@@ -106,12 +119,24 @@ de executar.
|
|
|
106
119
|
- Mesmas `complexity`.
|
|
107
120
|
- Sem ciclos.
|
|
108
121
|
|
|
109
|
-
### 7.
|
|
122
|
+
### 7. Regenerar a visualização do DAG
|
|
123
|
+
|
|
124
|
+
Depois de salvar o `dare-dag.yaml`, rode:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
dare dag viz -o DARE/dag-graph.mmd
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Isso reescreve `DARE/dag-graph.mmd` (Mermaid) refletindo o grafo atualizado.
|
|
131
|
+
O usuário pode abrir o arquivo no Cursor com a extensão Mermaid Preview.
|
|
132
|
+
|
|
133
|
+
### 8. Mensagem final ao usuário
|
|
110
134
|
|
|
111
|
-
> Gerados
|
|
135
|
+
> Gerados 4 artefatos da fase de execução:
|
|
112
136
|
> - `DARE/TASKS.md` ([N] tasks, visão humana)
|
|
113
137
|
> - `DARE/dare-dag.yaml` (grafo executável, [N] ranks paralelos)
|
|
114
138
|
> - `DARE/EXECUTION/task-*.md` ([N] specs detalhadas)
|
|
139
|
+
> - `DARE/dag-graph.mmd` (visualização Mermaid do DAG)
|
|
115
140
|
>
|
|
116
|
-
> Revise
|
|
117
|
-
>
|
|
141
|
+
> Revise (abra `dag-graph.mmd` para ver o grafo). Para executar:
|
|
142
|
+
> `/run-dag` ou `dare execute --next`.
|
|
@@ -76,12 +76,22 @@ tasks:
|
|
|
76
76
|
2. Para cada prompt:
|
|
77
77
|
- leia spec_file se houver
|
|
78
78
|
- implemente
|
|
79
|
-
- rode build/test/lint (Ralph Loop)
|
|
80
79
|
3. dare execute --complete <id> --output "<resumo + arquivos tocados>"
|
|
81
|
-
|
|
80
|
+
↓ o CLI roda o RALPH LOOP automático (build → test → lint)
|
|
81
|
+
↓ se passar: task vira DONE
|
|
82
|
+
↓ se falhar: task vira FAILED com stderr capturado; corrija e retente
|
|
82
83
|
4. Volte ao passo 1 até não haver mais tasks ready
|
|
83
84
|
```
|
|
84
85
|
|
|
86
|
+
> **Ralph Loop é AUTOMÁTICO e OBRIGATÓRIO.** Você NÃO roda build/test/lint
|
|
87
|
+
> manualmente — o `dare execute --complete` faz isso. Se algum gate falhar,
|
|
88
|
+
> a task NÃO vai para DONE; vai para FAILED. Você corrige o código e tenta
|
|
89
|
+
> de novo (`dare execute --complete <id>` outra vez, ou `--reset` antes se
|
|
90
|
+
> precisar zerar histórico).
|
|
91
|
+
>
|
|
92
|
+
> **Não existe flag para pular o Ralph Loop.** Toda task passa pelos 3 gates
|
|
93
|
+
> da stack do projeto.
|
|
94
|
+
|
|
85
95
|
Comandos úteis:
|
|
86
96
|
|
|
87
97
|
```bash
|
|
@@ -175,6 +185,28 @@ nada; o CLI cuida do cascade.
|
|
|
175
185
|
| Tudo em rank 0 | Conflito de escrita no mesmo arquivo | Adicione `depends_on` quando há contenção |
|
|
176
186
|
| Cadeia linear longa | Sem ganho de paralelismo | Reveja se as deps são reais |
|
|
177
187
|
|
|
188
|
+
## Antipatterns que você NÃO deve criar
|
|
189
|
+
|
|
190
|
+
- ❌ Task chamada **"Ralph Loop final"**, **"Hardening final"**, **"QA final"**
|
|
191
|
+
— Ralph Loop roda automaticamente em cada `--complete`. Não é uma task.
|
|
192
|
+
- ❌ Tests com `assertTrue(true)` ou equivalentes — o gate `test` vai rodar
|
|
193
|
+
de verdade. Placeholder não engana o CLI; só atrasa o ciclo.
|
|
194
|
+
- ❌ "Setup project structure" como primeira task quando o ambiente ainda
|
|
195
|
+
não foi containerizado — sem container/runtime, o Ralph Loop não roda.
|
|
196
|
+
|
|
197
|
+
## Ordem recomendada das primeiras tasks
|
|
198
|
+
|
|
199
|
+
1. **Containerize app** (Dockerfile + docker-compose + healthcheck) — sem
|
|
200
|
+
isso o Ralph Loop não tem onde rodar
|
|
201
|
+
2. **Database schema** (migrations + factories)
|
|
202
|
+
3. **Core endpoints / componentes**
|
|
203
|
+
4. **Auth / autorização**
|
|
204
|
+
5. **Test suite real** (com assertions de verdade)
|
|
205
|
+
|
|
206
|
+
A task de container/compose pode estar em **outra ordem** se o projeto já
|
|
207
|
+
vive em um container do monorepo, ou se a stack não precisa de DB. Mas
|
|
208
|
+
quase sempre é uma das primeiras — nunca a última.
|
|
209
|
+
|
|
178
210
|
## Checklist antes de aprovar um DAG
|
|
179
211
|
|
|
180
212
|
- [ ] Pelo menos 2 tasks no rank 0
|
|
@@ -183,4 +215,7 @@ nada; o CLI cuida do cascade.
|
|
|
183
215
|
- [ ] `complexity` reflete o esforço real (não tudo HIGH)
|
|
184
216
|
- [ ] `id` em kebab-case e único
|
|
185
217
|
- [ ] Sem ciclos
|
|
218
|
+
- [ ] **Sem task de "Ralph Loop final"** — Ralph Loop é gate por task
|
|
219
|
+
- [ ] **Tests com assertions reais** — placeholder quebra o gate `test`
|
|
220
|
+
- [ ] Container/runtime resolvido cedo, não na última task
|
|
186
221
|
- [ ] `TASKS.md` + `dare-dag.yaml` + `EXECUTION/task-*.md` consistentes
|