@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.
Files changed (50) hide show
  1. package/README.md +42 -2
  2. package/dist/__tests__/dag-runner/dag-viz.test.d.ts +2 -0
  3. package/dist/__tests__/dag-runner/dag-viz.test.d.ts.map +1 -0
  4. package/dist/__tests__/dag-runner/dag-viz.test.js +72 -0
  5. package/dist/__tests__/dag-runner/dag-viz.test.js.map +1 -0
  6. package/dist/__tests__/dag-runner/ralph-loop.test.d.ts +2 -0
  7. package/dist/__tests__/dag-runner/ralph-loop.test.d.ts.map +1 -0
  8. package/dist/__tests__/dag-runner/ralph-loop.test.js +109 -0
  9. package/dist/__tests__/dag-runner/ralph-loop.test.js.map +1 -0
  10. package/dist/bin/dare.js +4 -0
  11. package/dist/bin/dare.js.map +1 -1
  12. package/dist/commands/blueprint.d.ts.map +1 -1
  13. package/dist/commands/blueprint.js +47 -25
  14. package/dist/commands/blueprint.js.map +1 -1
  15. package/dist/commands/bootstrap.d.ts +14 -0
  16. package/dist/commands/bootstrap.d.ts.map +1 -0
  17. package/dist/commands/bootstrap.js +103 -0
  18. package/dist/commands/bootstrap.js.map +1 -0
  19. package/dist/commands/dag.d.ts +11 -0
  20. package/dist/commands/dag.d.ts.map +1 -0
  21. package/dist/commands/dag.js +148 -0
  22. package/dist/commands/dag.js.map +1 -0
  23. package/dist/commands/execute.d.ts.map +1 -1
  24. package/dist/commands/execute.js +59 -5
  25. package/dist/commands/execute.js.map +1 -1
  26. package/dist/commands/init.d.ts.map +1 -1
  27. package/dist/commands/init.js +1 -0
  28. package/dist/commands/init.js.map +1 -1
  29. package/dist/dag-runner/ralph-loop.d.ts +42 -0
  30. package/dist/dag-runner/ralph-loop.d.ts.map +1 -0
  31. package/dist/dag-runner/ralph-loop.js +185 -0
  32. package/dist/dag-runner/ralph-loop.js.map +1 -0
  33. package/dist/index.d.ts +6 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +5 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/utils/project-generator.d.ts +6 -0
  38. package/dist/utils/project-generator.d.ts.map +1 -1
  39. package/dist/utils/project-generator.js +112 -16
  40. package/dist/utils/project-generator.js.map +1 -1
  41. package/dist/utils/stack-bootstrap.d.ts +22 -0
  42. package/dist/utils/stack-bootstrap.d.ts.map +1 -0
  43. package/dist/utils/stack-bootstrap.js +334 -0
  44. package/dist/utils/stack-bootstrap.js.map +1 -0
  45. package/package.json +1 -1
  46. package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +30 -2
  47. package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +17 -3
  48. package/templates/ide/claude/.claude/commands/dare-blueprint.md +21 -2
  49. package/templates/ide/cursor/.cursor/commands/generate-tasks.md +29 -4
  50. 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":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AA+B1B,+EAA+E;AAE/E,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAA6B;IAClE,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,aAAa;YAChB,OAAO,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACzD,KAAK,aAAa;YAChB,OAAO,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACzD,KAAK,gBAAgB;YACnB,OAAO,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,KAAK,WAAW;YACd,OAAO,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACvD,KAAK,QAAQ;YACX,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACpD;YACE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,KAAe,EAAE,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAA8B;IACpE,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,OAAO;YACV,OAAO,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC7C,KAAK,KAAK;YACR,OAAO,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC3C;YACE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,CAAC,KAAe,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAyB;IAC1D,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACtD,KAAK,QAAQ;YACX,OAAO,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,QAAkB,EAAE,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAED,+EAA+E;AAE/E,KAAK,UAAU,mBAAmB,CAAC,GAAW,EAAE,WAAmB;IACjE,MAAM,aAAa,CACjB,UAAU,EACV,qDAAqD,CACtD,CAAC;IACF,MAAM,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;IAE7C,MAAM,MAAM,CACV,UAAU,EACV;QACE,gBAAgB;QAChB,qBAAqB;QACrB,GAAG;QACH,kBAAkB;QAClB,eAAe;KAChB,EACD,GAAG,CACJ,CAAC;IAEF,MAAM,MAAM,CACV,UAAU,EACV,CAAC,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,EACpE,GAAG,CACJ,CAAC;IAEF,MAAM,MAAM,CACV,UAAU,EACV;QACE,SAAS;QACT,OAAO;QACP,cAAc;QACd,mBAAmB;QACnB,kBAAkB;KACnB,EACD,GAAG,CACJ,CAAC;IAEF,0DAA0D;IAC1D,MAAM,wBAAwB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,GAAW,EAAE,WAAmB;IACjE,MAAM,aAAa,CAAC,KAAK,EAAE,qDAAqD,CAAC,CAAC;IAClF,MAAM,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;IAEzC,MAAM,MAAM,CACV,KAAK,EACL;QACE,IAAI;QACJ,oBAAoB;QACpB,KAAK;QACL,GAAG;QACH,YAAY;QACZ,UAAU;QACV,mBAAmB;QACnB,KAAK;QACL,aAAa;QACb,GAAG;KACJ,EACD,GAAG,CACJ,CAAC;IAEF,MAAM,mBAAmB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AAC9C,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,GAAW;IAC/C,MAAM,aAAa,CACjB,QAAQ,EACR,6DAA6D,CAC9D,CAAC;IACF,MAAM,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;IAE1C,oBAAoB;IACpB,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;IAErD,2EAA2E;IAC3E,yEAAyE;IACzE,qCAAqC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IACnD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACpC,MAAM,EAAE,CAAC,SAAS,CAChB,OAAO,EACP;YACE,gBAAgB;YAChB,yBAAyB;YACzB,wBAAwB;YACxB,iBAAiB;YACjB,eAAe;YACf,eAAe;YACf,gCAAgC;YAChC,sBAAsB;YACtB,aAAa;YACb,sBAAsB;YACtB,WAAW;YACX,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC;IAED,cAAc;IACd,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CACnB,GAAG,EACH,OAAO,EACP,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAC9D,CAAC;IACF,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,kBAAkB,CAAC,EAAE,GAAG,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,WAAmB;IAC/D,MAAM,aAAa,CACjB,OAAO,EACP,iEAAiE,CAClE,CAAC;IACF,MAAM,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;IAE9C,MAAM,MAAM,CACV,OAAO,EACP,CAAC,MAAM,EAAE,QAAQ,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC,EAClD,GAAG,CACJ,CAAC;IAEF,6DAA6D;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC/C,MAAM,EAAE,CAAC,SAAS,CAChB,SAAS,EACT;QACE,WAAW;QACX,WAAW,iBAAiB,CAAC,WAAW,CAAC,GAAG;QAC5C,mBAAmB;QACnB,kBAAkB;QAClB,EAAE;QACF,gBAAgB;QAChB,cAAc;QACd,mDAAmD;QACnD,eAAe;QACf,gEAAgE;QAChE,oDAAoD;QACpD,oBAAoB;QACpB,iBAAiB;QACjB,qEAAqE;QACrE,mBAAmB;QACnB,gBAAgB;QAChB,yDAAyD;QACzD,wFAAwF;QACxF,EAAE;QACF,oBAAoB;QACpB,wEAAwE;QACxE,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,mDAAmD;IACnD,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,WAAmB;IAC5D,MAAM,aAAa,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;IAClE,MAAM,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;IAE3C,MAAM,UAAU,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAEjD,uBAAuB;IACvB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,GAAG,CAAC,CAAC;IAErD,mBAAmB;IACnB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,iCAAiC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpE,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,iCAAiC,CAAC,EAAE,GAAG,CAAC,CAAC;IAEpE,oEAAoE;IACpE,sEAAsE;IACtE,sEAAsE;IACtE,0CAA0C;IAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3D,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAE7D,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,EACvC;;;;;;;KAOC,UAAU;;;;;;;;;;;;;;;;;;;;;;;CAuBd,CACE,CAAC;IAEF,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,EACnD;;;;;;;;;;;;CAYH,CACE,CAAC;IAEF,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,CAAC,EACxD;;;;;;;;;;;;;;;;;;;;;;;CAuBH,CACE,CAAC;IAEF,6CAA6C;IAC7C,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,QAA+B;IACvE,MAAM,aAAa,CAAC,KAAK,EAAE,sCAAsC,CAAC,CAAC;IACnE,MAAM,CAAC,uBAAuB,QAAQ,QAAQ,GAAG,EAAE,CAAC,CAAC;IAErD,2EAA2E;IAC3E,2EAA2E;IAC3E,8BAA8B;IAC9B,MAAM,MAAM,CACV,KAAK,EACL,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,EAC5D,GAAG,CACJ,CAAC;IAEF,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,WAAmB;IAC9D,MAAM,aAAa,CAAC,KAAK,EAAE,sCAAsC,CAAC,CAAC;IACnE,MAAM,CAAC,4CAA4C,GAAG,EAAE,CAAC,CAAC;IAE1D,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACzC,MAAM,MAAM,CACV,KAAK,EACL,CAAC,SAAS,EAAE,2BAA2B,CAAC,EACxC,GAAG,CACJ,CAAC;IACF,MAAM,MAAM,CACV,KAAK,EACL,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,CAAC,EACvE,GAAG,CACJ,CAAC;IAEF,MAAM,mBAAmB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AAC9C,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAC3C,MAAM,aAAa,CAAC,QAAQ,EAAE,yDAAyD,CAAC,CAAC;IACzF,MAAM,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;IAEtD,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CACnB,GAAG,EACH,OAAO,EACP,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAC9D,CAAC;IACF,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;AACpE,CAAC;AAED,+EAA+E;AAE/E,SAAS,MAAM,CAAC,GAAW;IACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,IAAY;IACpD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,oCAAoC,GAAG,OAAO,IAAI,IAAI;YACpD,gCAAgC,GAAG,gCAAgC,CACtE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,GAAW;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1E,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,GAAW,EAAE,IAAc,EAAE,GAAW;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;YAC5B,GAAG;YACH,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;;gBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC;AAC1F,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,oEAAoE;IACpE,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC;AAC1F,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,GAAW,EAAE,WAAmB;IACtE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,QAAQ,WAAW,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,CAAC;QAC7E,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,GAAW,EAAE,WAAmB;IACjE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACnE,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dewtech/dare-cli",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "DARE Framework - CLI, GraphRAG engine, MCP server and shared types in a single package",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -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
- (ou --fail <id> --reason "..." se falhou)
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: Pedir aprovação
185
+ ### Passo 7: Regenerar a visualização do DAG
186
186
 
187
- > Gerados os 3 artefatos da fase de execução:
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. Quando aprovar, execute: `dare execute --parallel --runner antigravity`.
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. Aguardar aprovação humana
124
+ ### 7. Regenerar a visualização do DAG
119
125
 
120
- **Não execute nenhuma task** até o usuário revisar e aprovar os 4 artefatos.
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. Mensagem final ao usuário
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 3 artefatos da fase de execução:
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. Para executar tudo em paralelo: `/run-dag` ou `dare execute --parallel`.
117
- > Para uma task isolada: `/execute-task task-001`.
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
- (ou --fail <id> --reason "..." se falhou)
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