@dewtech/dare-cli 2.17.0 → 3.0.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 (344) hide show
  1. package/README.md +98 -3
  2. package/dist/__tests__/confidence.test.d.ts +2 -0
  3. package/dist/__tests__/confidence.test.d.ts.map +1 -0
  4. package/dist/__tests__/confidence.test.js +73 -0
  5. package/dist/__tests__/confidence.test.js.map +1 -0
  6. package/dist/__tests__/datamodel.test.d.ts +2 -0
  7. package/dist/__tests__/datamodel.test.d.ts.map +1 -0
  8. package/dist/__tests__/datamodel.test.js +131 -0
  9. package/dist/__tests__/datamodel.test.js.map +1 -0
  10. package/dist/__tests__/dna-detector.test.d.ts +2 -0
  11. package/dist/__tests__/dna-detector.test.d.ts.map +1 -0
  12. package/dist/__tests__/dna-detector.test.js +97 -0
  13. package/dist/__tests__/dna-detector.test.js.map +1 -0
  14. package/dist/__tests__/dna-facts.test.d.ts +2 -0
  15. package/dist/__tests__/dna-facts.test.d.ts.map +1 -0
  16. package/dist/__tests__/dna-facts.test.js +44 -0
  17. package/dist/__tests__/dna-facts.test.js.map +1 -0
  18. package/dist/__tests__/graph-renderer.test.d.ts +2 -0
  19. package/dist/__tests__/graph-renderer.test.d.ts.map +1 -0
  20. package/dist/__tests__/graph-renderer.test.js +85 -0
  21. package/dist/__tests__/graph-renderer.test.js.map +1 -0
  22. package/dist/__tests__/migration.test.d.ts +2 -0
  23. package/dist/__tests__/migration.test.d.ts.map +1 -0
  24. package/dist/__tests__/migration.test.js +77 -0
  25. package/dist/__tests__/migration.test.js.map +1 -0
  26. package/dist/__tests__/module-detector.test.d.ts +2 -0
  27. package/dist/__tests__/module-detector.test.d.ts.map +1 -0
  28. package/dist/__tests__/module-detector.test.js +83 -0
  29. package/dist/__tests__/module-detector.test.js.map +1 -0
  30. package/dist/__tests__/refine.test.js +49 -49
  31. package/dist/__tests__/reverse-facts.test.d.ts +2 -0
  32. package/dist/__tests__/reverse-facts.test.d.ts.map +1 -0
  33. package/dist/__tests__/reverse-facts.test.js +78 -0
  34. package/dist/__tests__/reverse-facts.test.js.map +1 -0
  35. package/dist/__tests__/review.test.js +38 -38
  36. package/dist/__tests__/validate.test.js +65 -65
  37. package/dist/bin/dare.js +32 -3
  38. package/dist/bin/dare.js.map +1 -1
  39. package/dist/commands/blueprint.js +122 -122
  40. package/dist/commands/dag.d.ts.map +1 -1
  41. package/dist/commands/dag.js +43 -79
  42. package/dist/commands/dag.js.map +1 -1
  43. package/dist/commands/dna.d.ts +3 -0
  44. package/dist/commands/dna.d.ts.map +1 -0
  45. package/dist/commands/dna.js +69 -0
  46. package/dist/commands/dna.js.map +1 -0
  47. package/dist/commands/migrate.d.ts +3 -0
  48. package/dist/commands/migrate.d.ts.map +1 -0
  49. package/dist/commands/migrate.js +101 -0
  50. package/dist/commands/migrate.js.map +1 -0
  51. package/dist/commands/new.d.ts +16 -0
  52. package/dist/commands/new.d.ts.map +1 -0
  53. package/dist/commands/new.js +103 -0
  54. package/dist/commands/new.js.map +1 -0
  55. package/dist/commands/reverse.d.ts +3 -0
  56. package/dist/commands/reverse.d.ts.map +1 -0
  57. package/dist/commands/reverse.js +201 -0
  58. package/dist/commands/reverse.js.map +1 -0
  59. package/dist/commands/welcome.d.ts +14 -0
  60. package/dist/commands/welcome.d.ts.map +1 -0
  61. package/dist/commands/welcome.js +29 -0
  62. package/dist/commands/welcome.js.map +1 -0
  63. package/dist/skills/commands/add.d.ts +23 -0
  64. package/dist/skills/commands/add.d.ts.map +1 -0
  65. package/dist/skills/commands/add.js +206 -0
  66. package/dist/skills/commands/add.js.map +1 -0
  67. package/dist/skills/commands/info.d.ts +14 -0
  68. package/dist/skills/commands/info.d.ts.map +1 -0
  69. package/dist/skills/commands/info.js +99 -0
  70. package/dist/skills/commands/info.js.map +1 -0
  71. package/dist/skills/commands/list.d.ts +19 -0
  72. package/dist/skills/commands/list.d.ts.map +1 -0
  73. package/dist/skills/commands/list.js +163 -0
  74. package/dist/skills/commands/list.js.map +1 -0
  75. package/dist/skills/commands/publish.d.ts +56 -0
  76. package/dist/skills/commands/publish.d.ts.map +1 -0
  77. package/dist/skills/commands/publish.js +272 -0
  78. package/dist/skills/commands/publish.js.map +1 -0
  79. package/dist/skills/commands/remove.d.ts +19 -0
  80. package/dist/skills/commands/remove.d.ts.map +1 -0
  81. package/dist/skills/commands/remove.js +96 -0
  82. package/dist/skills/commands/remove.js.map +1 -0
  83. package/dist/skills/commands/update.d.ts +31 -0
  84. package/dist/skills/commands/update.d.ts.map +1 -0
  85. package/dist/skills/commands/update.js +132 -0
  86. package/dist/skills/commands/update.js.map +1 -0
  87. package/dist/skills/index.d.ts +22 -0
  88. package/dist/skills/index.d.ts.map +1 -0
  89. package/dist/skills/index.js +33 -0
  90. package/dist/skills/index.js.map +1 -0
  91. package/dist/skills/manifest.d.ts +54 -0
  92. package/dist/skills/manifest.d.ts.map +1 -0
  93. package/dist/skills/manifest.js +162 -0
  94. package/dist/skills/manifest.js.map +1 -0
  95. package/dist/skills/registry-local.d.ts +67 -0
  96. package/dist/skills/registry-local.d.ts.map +1 -0
  97. package/dist/skills/registry-local.js +130 -0
  98. package/dist/skills/registry-local.js.map +1 -0
  99. package/dist/skills/registry-mock.json +109 -0
  100. package/dist/skills/registry-remote.d.ts +110 -0
  101. package/dist/skills/registry-remote.d.ts.map +1 -0
  102. package/dist/skills/registry-remote.js +246 -0
  103. package/dist/skills/registry-remote.js.map +1 -0
  104. package/dist/skills/registry.d.ts +49 -0
  105. package/dist/skills/registry.d.ts.map +1 -0
  106. package/dist/skills/registry.js +94 -0
  107. package/dist/skills/registry.js.map +1 -0
  108. package/dist/skills/tests/manifest.spec.d.ts +8 -0
  109. package/dist/skills/tests/manifest.spec.d.ts.map +1 -0
  110. package/dist/skills/tests/manifest.spec.js +176 -0
  111. package/dist/skills/tests/manifest.spec.js.map +1 -0
  112. package/dist/skills/tests/publish.spec.d.ts +12 -0
  113. package/dist/skills/tests/publish.spec.d.ts.map +1 -0
  114. package/dist/skills/tests/publish.spec.js +276 -0
  115. package/dist/skills/tests/publish.spec.js.map +1 -0
  116. package/dist/skills/tests/registry-local.spec.d.ts +8 -0
  117. package/dist/skills/tests/registry-local.spec.d.ts.map +1 -0
  118. package/dist/skills/tests/registry-local.spec.js +231 -0
  119. package/dist/skills/tests/registry-local.spec.js.map +1 -0
  120. package/dist/skills/tests/registry.spec.d.ts +7 -0
  121. package/dist/skills/tests/registry.spec.d.ts.map +1 -0
  122. package/dist/skills/tests/registry.spec.js +58 -0
  123. package/dist/skills/tests/registry.spec.js.map +1 -0
  124. package/dist/skills/tests/remote-registry.spec.d.ts +9 -0
  125. package/dist/skills/tests/remote-registry.spec.d.ts.map +1 -0
  126. package/dist/skills/tests/remote-registry.spec.js +357 -0
  127. package/dist/skills/tests/remote-registry.spec.js.map +1 -0
  128. package/dist/skills/tests/update.spec.d.ts +9 -0
  129. package/dist/skills/tests/update.spec.d.ts.map +1 -0
  130. package/dist/skills/tests/update.spec.js +166 -0
  131. package/dist/skills/tests/update.spec.js.map +1 -0
  132. package/dist/utils/banner.d.ts +28 -0
  133. package/dist/utils/banner.d.ts.map +1 -0
  134. package/dist/utils/banner.js +77 -0
  135. package/dist/utils/banner.js.map +1 -0
  136. package/dist/utils/banner.spec.d.ts +5 -0
  137. package/dist/utils/banner.spec.d.ts.map +1 -0
  138. package/dist/utils/banner.spec.js +253 -0
  139. package/dist/utils/banner.spec.js.map +1 -0
  140. package/dist/utils/confidence.d.ts +41 -0
  141. package/dist/utils/confidence.d.ts.map +1 -0
  142. package/dist/utils/confidence.js +101 -0
  143. package/dist/utils/confidence.js.map +1 -0
  144. package/dist/utils/datamodel.d.ts +41 -0
  145. package/dist/utils/datamodel.d.ts.map +1 -0
  146. package/dist/utils/datamodel.js +535 -0
  147. package/dist/utils/datamodel.js.map +1 -0
  148. package/dist/utils/dna-detector.d.ts +61 -0
  149. package/dist/utils/dna-detector.d.ts.map +1 -0
  150. package/dist/utils/dna-detector.js +354 -0
  151. package/dist/utils/dna-detector.js.map +1 -0
  152. package/dist/utils/dna-facts.d.ts +13 -0
  153. package/dist/utils/dna-facts.d.ts.map +1 -0
  154. package/dist/utils/dna-facts.js +109 -0
  155. package/dist/utils/dna-facts.js.map +1 -0
  156. package/dist/utils/excalidraw-renderer.d.ts +11 -71
  157. package/dist/utils/excalidraw-renderer.d.ts.map +1 -1
  158. package/dist/utils/excalidraw-renderer.js +29 -162
  159. package/dist/utils/excalidraw-renderer.js.map +1 -1
  160. package/dist/utils/graph-renderer.d.ts +115 -0
  161. package/dist/utils/graph-renderer.d.ts.map +1 -0
  162. package/dist/utils/graph-renderer.js +216 -0
  163. package/dist/utils/graph-renderer.js.map +1 -0
  164. package/dist/utils/migration.d.ts +64 -0
  165. package/dist/utils/migration.d.ts.map +1 -0
  166. package/dist/utils/migration.js +183 -0
  167. package/dist/utils/migration.js.map +1 -0
  168. package/dist/utils/module-detector.d.ts +46 -0
  169. package/dist/utils/module-detector.d.ts.map +1 -0
  170. package/dist/utils/module-detector.js +348 -0
  171. package/dist/utils/module-detector.js.map +1 -0
  172. package/dist/utils/project-generator.js +252 -252
  173. package/dist/utils/reverse-facts.d.ts +50 -0
  174. package/dist/utils/reverse-facts.d.ts.map +1 -0
  175. package/dist/utils/reverse-facts.js +291 -0
  176. package/dist/utils/reverse-facts.js.map +1 -0
  177. package/dist/utils/stack-bootstrap.js +371 -371
  178. package/package.json +8 -3
  179. package/templates/DARE-dag-example.yaml +280 -280
  180. package/templates/UPDATE-MANIFEST.json +48 -48
  181. package/templates/backend/node-nestjs/.env.example +9 -9
  182. package/templates/backend/node-nestjs/nest-cli.json +8 -8
  183. package/templates/backend/node-nestjs/package.json +50 -50
  184. package/templates/backend/node-nestjs/src/app.controller.ts +12 -12
  185. package/templates/backend/node-nestjs/src/app.module.ts +15 -15
  186. package/templates/backend/node-nestjs/src/app.service.ts +8 -8
  187. package/templates/backend/node-nestjs/src/main.ts +24 -24
  188. package/templates/backend/node-nestjs/tsconfig.json +21 -21
  189. package/templates/backend/php-laravel/.env.example +22 -22
  190. package/templates/backend/php-laravel/app/Http/Controllers/HealthController.php +15 -15
  191. package/templates/backend/php-laravel/composer.json +40 -40
  192. package/templates/backend/python-fastapi/.env.example +4 -4
  193. package/templates/backend/python-fastapi/app/api/router.py +8 -8
  194. package/templates/backend/python-fastapi/app/core/config.py +20 -20
  195. package/templates/backend/python-fastapi/main.py +35 -35
  196. package/templates/backend/python-fastapi/requirements.txt +13 -13
  197. package/templates/backend/rust-axum/.env.example +3 -3
  198. package/templates/backend/rust-axum/Cargo.toml +23 -23
  199. package/templates/backend/rust-axum/src/errors.rs +30 -30
  200. package/templates/backend/rust-axum/src/main.rs +32 -32
  201. package/templates/backend/rust-axum/src/routes.rs +6 -6
  202. package/templates/frontend/leptos-csr/.cargo/config.toml +2 -2
  203. package/templates/frontend/leptos-csr/Cargo.toml +16 -16
  204. package/templates/frontend/leptos-csr/Trunk.toml +10 -10
  205. package/templates/frontend/leptos-csr/index.html +11 -11
  206. package/templates/frontend/leptos-csr/src/lib.rs +20 -20
  207. package/templates/frontend/leptos-csr/style/main.scss +19 -19
  208. package/templates/frontend/leptos-fullstack/.cargo/config.toml +4 -4
  209. package/templates/frontend/leptos-fullstack/Cargo.toml +56 -56
  210. package/templates/frontend/leptos-fullstack/src/app.rs +49 -49
  211. package/templates/frontend/leptos-fullstack/src/lib.rs +9 -9
  212. package/templates/frontend/leptos-fullstack/src/main.rs +29 -29
  213. package/templates/frontend/leptos-fullstack/style/main.scss +19 -19
  214. package/templates/frontend/react/index.html +12 -12
  215. package/templates/frontend/react/package.json +35 -35
  216. package/templates/frontend/react/src/App.tsx +25 -25
  217. package/templates/frontend/react/src/main.tsx +9 -9
  218. package/templates/frontend/vue/package.json +32 -32
  219. package/templates/frontend/vue/src/App.vue +7 -7
  220. package/templates/frontend/vue/src/main.ts +10 -10
  221. package/templates/frontend/vue/src/router/index.ts +14 -14
  222. package/templates/frontend/vue/src/views/HomeView.vue +6 -6
  223. package/templates/hooks/pre-commit-dare-validate +24 -24
  224. package/templates/ide/antigravity/.agents/skills/dare-ax/SKILL.md +152 -0
  225. package/templates/ide/antigravity/.agents/skills/dare-dag-build/SKILL.md +154 -0
  226. package/templates/ide/antigravity/.agents/skills/dare-dag-run/SKILL.md +130 -0
  227. package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +203 -203
  228. package/templates/ide/antigravity/.agents/skills/dare-dna/SKILL.md +63 -0
  229. package/templates/ide/antigravity/.agents/skills/dare-docker/SKILL.md +315 -0
  230. package/templates/ide/antigravity/.agents/skills/dare-frontend-design/SKILL.md +192 -0
  231. package/templates/ide/antigravity/.agents/skills/dare-laravel-api/SKILL.md +337 -0
  232. package/templates/ide/antigravity/.agents/skills/dare-layered-design/SKILL.md +166 -0
  233. package/templates/ide/antigravity/.agents/skills/dare-llm-integration/SKILL.md +217 -0
  234. package/templates/ide/antigravity/.agents/skills/dare-migrate/SKILL.md +61 -0
  235. package/templates/ide/antigravity/.agents/skills/dare-quality-telemetry/SKILL.md +187 -0
  236. package/templates/ide/antigravity/.agents/skills/dare-realtime/SKILL.md +217 -0
  237. package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +114 -114
  238. package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +108 -0
  239. package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -111
  240. package/templates/ide/antigravity/.agents/skills/dare-rust-leptos/SKILL.md +263 -0
  241. package/templates/ide/antigravity/.agents/skills/dare-rust-workspace/SKILL.md +275 -275
  242. package/templates/ide/antigravity/.agents/skills/dare-security/SKILL.md +274 -0
  243. package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +265 -265
  244. package/templates/ide/antigravity/.agents/skills/dare-telemetry/SKILL.md +188 -0
  245. package/templates/ide/antigravity/.agents/skills/skill-fastapi-api/SKILL.md +343 -0
  246. package/templates/ide/antigravity/.agents/skills/skill-go-gin-api/SKILL.md +377 -0
  247. package/templates/ide/antigravity/.agents/skills/skill-mcp-server/SKILL.md +382 -0
  248. package/templates/ide/antigravity/.agents/skills/skill-nestjs-api/SKILL.md +326 -0
  249. package/templates/ide/antigravity/.agents/skills/skill-rails-api/SKILL.md +393 -0
  250. package/templates/ide/antigravity/templates/BLUEPRINT-template.md +193 -193
  251. package/templates/ide/antigravity/templates/DESIGN-template.md +129 -129
  252. package/templates/ide/antigravity/templates/TASK-SPEC-template.md +141 -141
  253. package/templates/ide/claude/.claude/commands/dare-ax.md +131 -0
  254. package/templates/ide/claude/.claude/commands/dare-blueprint.md +134 -134
  255. package/templates/ide/claude/.claude/commands/dare-bugfix-design.md +119 -0
  256. package/templates/ide/claude/.claude/commands/dare-dag-build.md +151 -151
  257. package/templates/ide/claude/.claude/commands/dare-dag-run.md +109 -109
  258. package/templates/ide/claude/.claude/commands/dare-dag-runner.md +117 -0
  259. package/templates/ide/claude/.claude/commands/dare-dag-viz.md +197 -197
  260. package/templates/ide/claude/.claude/commands/dare-design.md +69 -69
  261. package/templates/ide/claude/.claude/commands/dare-dna.md +75 -0
  262. package/templates/ide/claude/.claude/commands/dare-docker.md +207 -0
  263. package/templates/ide/claude/.claude/commands/dare-execute.md +152 -152
  264. package/templates/ide/claude/.claude/commands/dare-feature-design.md +147 -0
  265. package/templates/ide/claude/.claude/commands/dare-frontend-design.md +149 -0
  266. package/templates/ide/claude/.claude/commands/dare-laravel-api.md +211 -0
  267. package/templates/ide/claude/.claude/commands/dare-layered-design.md +124 -0
  268. package/templates/ide/claude/.claude/commands/dare-llm-integration.md +148 -0
  269. package/templates/ide/claude/.claude/commands/dare-migrate.md +72 -0
  270. package/templates/ide/claude/.claude/commands/dare-quality-telemetry.md +166 -0
  271. package/templates/ide/claude/.claude/commands/dare-realtime.md +159 -0
  272. package/templates/ide/claude/.claude/commands/dare-refine.md +145 -145
  273. package/templates/ide/claude/.claude/commands/dare-reverse.md +139 -0
  274. package/templates/ide/claude/.claude/commands/dare-review.md +113 -113
  275. package/templates/ide/claude/.claude/commands/dare-rust-leptos.md +269 -269
  276. package/templates/ide/claude/.claude/commands/dare-rust-workspace.md +209 -209
  277. package/templates/ide/claude/.claude/commands/dare-security.md +232 -232
  278. package/templates/ide/claude/.claude/commands/dare-tasks.md +70 -70
  279. package/templates/ide/claude/.claude/commands/dare-telemetry.md +132 -0
  280. package/templates/ide/claude/.claude/commands/skill-fastapi-api.md +205 -0
  281. package/templates/ide/claude/.claude/commands/skill-go-gin-api.md +232 -0
  282. package/templates/ide/claude/.claude/commands/skill-mcp-server.md +228 -0
  283. package/templates/ide/claude/.claude/commands/skill-nestjs-api.md +210 -0
  284. package/templates/ide/claude/.claude/commands/skill-rails-api.md +236 -0
  285. package/templates/ide/claude/.claude/settings.example.json +35 -35
  286. package/templates/ide/claude/CLAUDE.md +146 -146
  287. package/templates/ide/claude/templates/BLUEPRINT-template.md +193 -193
  288. package/templates/ide/claude/templates/DESIGN-template.md +129 -129
  289. package/templates/ide/claude/templates/TASK-SPEC-template.md +141 -141
  290. package/templates/ide/cursor/.cursor/commands/dag-viz.md +139 -0
  291. package/templates/ide/cursor/.cursor/commands/generate-blueprint.md +86 -86
  292. package/templates/ide/cursor/.cursor/commands/generate-design.md +35 -35
  293. package/templates/ide/cursor/.cursor/commands/generate-tasks.md +184 -184
  294. package/templates/ide/cursor/.cursor/commands/refine-task.md +107 -107
  295. package/templates/ide/cursor/.cursor/commands/review-task.md +91 -91
  296. package/templates/ide/cursor/.cursor/commands/run-dag.md +110 -110
  297. package/templates/ide/cursor/.cursor/rules/skill-ax.mdc +263 -0
  298. package/templates/ide/cursor/.cursor/rules/skill-dag-build.mdc +173 -0
  299. package/templates/ide/cursor/.cursor/rules/skill-dag-run.mdc +134 -0
  300. package/templates/ide/cursor/.cursor/rules/skill-dag-runner.mdc +221 -221
  301. package/templates/ide/cursor/.cursor/rules/skill-dna.mdc +63 -0
  302. package/templates/ide/cursor/.cursor/rules/skill-fastapi-api.mdc +352 -0
  303. package/templates/ide/cursor/.cursor/rules/skill-frontend-design.mdc +244 -0
  304. package/templates/ide/cursor/.cursor/rules/skill-go-gin-api.mdc +371 -0
  305. package/templates/ide/cursor/.cursor/rules/skill-layered-design.mdc +266 -0
  306. package/templates/ide/cursor/.cursor/rules/skill-llm-integration.mdc +295 -0
  307. package/templates/ide/cursor/.cursor/rules/skill-mcp-server.mdc +367 -0
  308. package/templates/ide/cursor/.cursor/rules/skill-migrate.mdc +58 -0
  309. package/templates/ide/cursor/.cursor/rules/skill-nestjs-api.mdc +346 -0
  310. package/templates/ide/cursor/.cursor/rules/skill-quality-telemetry.mdc +248 -0
  311. package/templates/ide/cursor/.cursor/rules/skill-rails-api.mdc +400 -0
  312. package/templates/ide/cursor/.cursor/rules/skill-realtime.mdc +262 -0
  313. package/templates/ide/cursor/.cursor/rules/skill-reverse.mdc +107 -0
  314. package/templates/ide/cursor/.cursor/rules/skill-rust-leptos.mdc +281 -0
  315. package/templates/ide/cursor/.cursor/rules/skill-rust-workspace.mdc +312 -312
  316. package/templates/ide/cursor/.cursor/rules/skill-security.mdc +245 -245
  317. package/templates/ide/cursor/templates/BLUEPRINT-template.md +193 -193
  318. package/templates/ide/cursor/templates/DESIGN-template.md +129 -129
  319. package/templates/ide/cursor/templates/TASK-SPEC-template.md +141 -141
  320. package/templates/shared/docker-compose.yml +41 -41
  321. package/dist/__tests__/dag-runner/adapters.test.d.ts +0 -2
  322. package/dist/__tests__/dag-runner/adapters.test.d.ts.map +0 -1
  323. package/dist/__tests__/dag-runner/adapters.test.js +0 -134
  324. package/dist/__tests__/dag-runner/adapters.test.js.map +0 -1
  325. package/dist/dag-runner/adapters/antigravity.d.ts +0 -6
  326. package/dist/dag-runner/adapters/antigravity.d.ts.map +0 -1
  327. package/dist/dag-runner/adapters/antigravity.js +0 -54
  328. package/dist/dag-runner/adapters/antigravity.js.map +0 -1
  329. package/dist/dag-runner/adapters/claude.d.ts +0 -6
  330. package/dist/dag-runner/adapters/claude.d.ts.map +0 -1
  331. package/dist/dag-runner/adapters/claude.js +0 -48
  332. package/dist/dag-runner/adapters/claude.js.map +0 -1
  333. package/dist/dag-runner/adapters/cursor.d.ts +0 -6
  334. package/dist/dag-runner/adapters/cursor.d.ts.map +0 -1
  335. package/dist/dag-runner/adapters/cursor.js +0 -58
  336. package/dist/dag-runner/adapters/cursor.js.map +0 -1
  337. package/dist/dag-runner/adapters/index.d.ts +0 -46
  338. package/dist/dag-runner/adapters/index.d.ts.map +0 -1
  339. package/dist/dag-runner/adapters/index.js +0 -55
  340. package/dist/dag-runner/adapters/index.js.map +0 -1
  341. package/dist/dag-runner/utils/timeout.d.ts +0 -27
  342. package/dist/dag-runner/utils/timeout.d.ts.map +0 -1
  343. package/dist/dag-runner/utils/timeout.js +0 -55
  344. package/dist/dag-runner/utils/timeout.js.map +0 -1
package/README.md CHANGED
@@ -16,6 +16,7 @@ means it literally runs:
16
16
 
17
17
  | Stack | What `dare init` runs |
18
18
  |-------|----------------------|
19
+ | `ruby-rails-8` | `rails new . --api --skip-test --skip-bundle --database=postgresql` + DARE templates (`packages/stacks/ruby-rails-8/` generator with Layered Design, OpenAPI, LLM integration, Action Cable, RSpec) |
19
20
  | `php-laravel` | `composer create-project laravel/laravel:^11 .` |
20
21
  | `node-nestjs` | `npx @nestjs/cli new . --strict --skip-git` |
21
22
  | `python-fastapi` | `python -m venv .venv && python -m pip install -r requirements.txt` |
@@ -28,7 +29,7 @@ means it literally runs:
28
29
  | `mcp-server-node-ts` | `npm init` + `@modelcontextprotocol/sdk` |
29
30
  | `mcp-server-python` | `python -m venv .venv` + `pip install mcp[cli]` |
30
31
 
31
- These need a working `composer` / `npm` / `cargo` / `python` / `go`
32
+ These need a working `ruby` / `composer` / `npm` / `cargo` / `python` / `go`
32
33
  **somewhere**. There are three ways to provide it — you pick at init time
33
34
  (prompt below), and the choice is saved in `dare.config.json` so
34
35
  `dare bootstrap` reuses it later.
@@ -139,6 +140,7 @@ Pick **one** of the two paths per stack:
139
140
 
140
141
  | Stack | Native toolchain | Docker fallback (used if native missing) |
141
142
  |-------|------------------|------------------------------------------|
143
+ | `ruby-rails-8` | Ruby 3.3+ · Bundler 2+ · Rails 8 — https://www.ruby-lang.org/ | `ruby:3.3-slim` |
142
144
  | `php-laravel` | PHP 8.2+ · Composer 2+ — https://getcomposer.org/ | `composer:latest` |
143
145
  | `node-nestjs` | Node 18+ (bundles `npx`) | `node:20-alpine` |
144
146
  | `python-fastapi` | Python 3.11+ — https://www.python.org/downloads/ | `python:3.12-slim` |
@@ -151,6 +153,8 @@ Pick **one** of the two paths per stack:
151
153
  | `mcp-server-node-ts` | Node 18+ | `node:20-alpine` |
152
154
  | `mcp-server-python` | Python 3.11+ | `python:3.12-slim` |
153
155
 
156
+ > **v3.0.0:** `ruby-rails-8` is the only stack with a full generator in `packages/stacks/`. All others run the framework's official scaffold + DARE skill templates on top. Full generators for `node-nestjs`, `python-fastapi`, `go-gin`, `php-laravel` and MCP servers are on the [v3.1.x roadmap](https://github.com/dewtech-technologies/dare-method/blob/main/ROADMAP.md#em-desenvolvimento-ativo---v31x).
157
+
154
158
  > **TL;DR:** if you have **Docker Desktop** installed, you don't strictly need
155
159
  > any other toolchain — `dare init` will pull the right image on demand.
156
160
  > Native toolchains are faster and don't depend on Docker pulling images.
@@ -249,6 +253,80 @@ Recognizes: NestJS · React · Vue · Nuxt · Rust/Axum · FastAPI · Laravel ·
249
253
 
250
254
  ---
251
255
 
256
+ ### `dare reverse` ← brownfield (Phase 0)
257
+
258
+ Reverse-engineer an existing codebase into a Phase-0 understanding **without touching the source**.
259
+ Deterministically detects module boundaries, sizes them by LOC and infers the dependency graph.
260
+
261
+ ```bash
262
+ cd my-legacy-project
263
+ dare reverse # → DARE/IDEIA.md + REVERSE/module-*.md + reverse-facts.json + architecture.excalidraw
264
+ dare reverse --check # detection only, no files
265
+ dare reverse --modules api,auth
266
+ dare reverse --no-excalidraw
267
+ ```
268
+
269
+ **Confidence & traceability.** The `/dare-reverse` skill marks each claim 🟢 CONFIRMED (with
270
+ `file:line` evidence) · 🟡 INFERRED · 🔴 GAP. Then:
271
+
272
+ ```bash
273
+ dare reverse --report # deterministic confidence index from the markers (not LLM self-scored)
274
+ ```
275
+
276
+ → `confidence-report.md` + `traceability/code-spec-matrix.md`; the 🔴 become `gaps.md` + `questions.md`.
277
+
278
+ **Deep extraction (framework-agnostic per language):**
279
+
280
+ ```bash
281
+ dare reverse --deep # + ERD, API surface, C4, domain-rules, state-machines, permissions
282
+ ```
283
+
284
+ The CLI extracts the data model (`erd.md`) and endpoints (`api-surface.md`) deterministically from
285
+ **SQL inline (DDL + query tables), Prisma, ORMs and plain types/classes/structs** — so it works on
286
+ legacy projects **with or without a framework** (e.g. raw-PDO PHP without Laravel). Routes cover
287
+ multiple dialects per language (Express/Nest/Fastify, Laravel/Slim/Symfony, FastAPI/Flask/Django,
288
+ Rails/Sinatra, Gin/stdlib, Axum).
289
+
290
+ ---
291
+
292
+ ### `dare dna` ← brownfield
293
+
294
+ Extract the legacy codebase's **conventions** so the agent follows the house style instead of generic
295
+ defaults — for legacy you can't rewrite.
296
+
297
+ ```bash
298
+ cd my-legacy-project
299
+ dare dna # → DARE/PROJECT-DNA.md + dna-facts.json
300
+ dare dna --check
301
+ ```
302
+
303
+ Detects lint/format tooling, naming conventions, architecture layers, test framework, key libraries
304
+ (ORM/HTTP/auth/validation) and commit convention. The `/dare-dna` skill turns the facts into
305
+ actionable rules. Reuses `reverse-facts.json` if `dare reverse` already ran.
306
+
307
+ ---
308
+
309
+ ### `dare migrate` ← brownfield (Phase 2)
310
+
311
+ Plan a **safe migration** to a target stack, with **Gherkin parity scenarios** that guarantee
312
+ behavior is preserved. Requires `dare reverse` first.
313
+
314
+ ```bash
315
+ cd my-legacy-project
316
+ dare migrate --to go-gin # or rust-axum, node-nestjs, python-fastapi, php-laravel, ruby-rails-8…
317
+ dare migrate --check
318
+ ```
319
+
320
+ Consumes `IDEIA` + `DNA`, inherits the **blocking gaps** (🔴) as risks, and generates
321
+ `DARE/MIGRATION/MIGRATION.md` (paradigm, strategy, risk register, target architecture, cutover) +
322
+ `parity/<module>.feature` (the behavioral acceptance contract). The `/dare-migrate` skill fills the
323
+ strategy and the real parity scenarios.
324
+
325
+ > **Brownfield loop:** `reverse` (the *what*) → `dna` (the *how*) → `migrate` (reimplement with
326
+ > parity) → `design`/`blueprint`/`execute` on the target stack.
327
+
328
+ ---
329
+
252
330
  ### `dare design`
253
331
 
254
332
  Generate `DARE/DESIGN.md` from a project description.
@@ -620,13 +698,30 @@ npm run inspect
620
698
 
621
699
  | Type | Options |
622
700
  |------|---------|
623
- | **Backend** | Rust/Axum · Node.js/NestJS · Python/FastAPI · PHP/Laravel · Go/Gin · Go/stdlib |
701
+ | **Backend** | Ruby on Rails 8 · Rust/Axum · Node.js/NestJS · Python/FastAPI · PHP/Laravel · Go/Gin · Go/stdlib |
624
702
  | **Frontend** | React 18+ · Vue 3+ · Leptos fullstack (Rust SSR+WASM) · Leptos CSR (Rust WASM) |
625
703
  | **MCP Server** | TypeScript/Node.js · Python — stdio / SSE / HTTP Stream |
626
704
  | **IDE / Agent** | Claude Code · Cursor · Antigravity · Hybrid |
627
705
 
628
706
  ---
629
707
 
708
+ ## Skills disponíveis (v3.0.0)
709
+
710
+ **32 skills em paridade total** nas 3 IDEs (Antigravity, Claude Code, Cursor). Cada skill existe em formato nativo de cada uma e é entregue por `dare init` / `dare update`.
711
+
712
+ | Categoria | Skills | Exemplos |
713
+ |---|---|---|
714
+ | **Método DARE** | 6 | `dare-design`, `dare-blueprint`, `dare-tasks`, `dare-execute`, `dare-review`, `dare-refine` |
715
+ | **DAG runner** | 4 | `dare-dag-build`, `dare-dag-run`, `dare-dag-runner`, `dare-dag-viz` |
716
+ | **Transversais** | 6 | `dare-ax`, `dare-layered-design`, `dare-llm-integration`, `dare-frontend-design`, `dare-realtime`, `dare-quality-telemetry` |
717
+ | **Stack / Tools** | 8 | `dare-docker`, `dare-security`, `dare-telemetry`, `dare-bugfix-design`, `dare-feature-design`, `dare-rust-workspace`, `dare-rust-leptos`, `dare-laravel-api` |
718
+ | **Stacks novas v3.0.0** | 5 | `dare-nestjs-api`, `dare-fastapi-api`, `dare-go-gin-api`, `dare-mcp-server`, `dare-rails-api` |
719
+ | **Brownfield** | 3 | `dare-reverse`, `dare-dna`, `dare-migrate` |
720
+
721
+ Ver tabela cruzada completa em [`docs/skills/INDEX.md`](https://github.com/dewtech-technologies/dare-method/blob/main/docs/skills/INDEX.md).
722
+
723
+ ---
724
+
630
725
  ## O que vem com o pacote (v2.0+)
631
726
 
632
727
  A partir da v2.0 o `@dewtech/dare-cli` é um **pacote único** que inclui todas as
@@ -640,7 +735,7 @@ Isso já dá:
640
735
 
641
736
  | Componente | O que é |
642
737
  |------------|---------|
643
- | CLI `dare` | `init`, `design`, `blueprint`, `execute`, `discover` |
738
+ | CLI `dare` | `init`, `design`, `blueprint`, `execute`, `discover`, `reverse`, `dna`, `migrate` |
644
739
  | CLI `dare-mcp-server` | Servidor MCP local de contexto (~95% economia de tokens) |
645
740
  | Engine GraphRAG | Grafo de conhecimento com SQLite + FTS5 |
646
741
  | DAG Task Runner | Execução paralela de tasks com Kahn's algorithm |
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=confidence.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/confidence.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,73 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { parseSpecConfidence, computeIndex, aggregate, renderConfidenceReport, renderCodeSpecMatrix, } from '../utils/confidence.js';
3
+ const SPEC = `# Módulo: auth
4
+
5
+ ## Fatos
6
+ - 🟢 **Caminho:** \`src/auth\`
7
+ - 🟢 **Linguagens:** .ts
8
+
9
+ ## Claims
10
+ - 🟢 Login delega a findUser. \`src/auth/login.ts:2\`
11
+ - 🟡 Provável validação ausente. \`src/auth/login.ts:5\`
12
+ - 🔴 Política de senha não determinável. → ver gaps.md
13
+
14
+ Texto normal não é claim. \`não-conta.ts:9\`
15
+ - item de lista sem marcador, ignorado
16
+ `;
17
+ describe('parseSpecConfidence', () => {
18
+ it('counts markers and extracts file:line evidence', () => {
19
+ const r = parseSpecConfidence('module-01-auth.md', SPEC);
20
+ expect(r.counts.confirmed).toBe(3); // 2 fatos + 1 claim
21
+ expect(r.counts.inferred).toBe(1);
22
+ expect(r.counts.gap).toBe(1);
23
+ expect(r.counts.total).toBe(5);
24
+ // Only evidence on marked claim lines is captured (not the plain text line).
25
+ expect(r.evidence).toEqual(['src/auth/login.ts:2', 'src/auth/login.ts:5']);
26
+ });
27
+ it('ignores non-claim lines (no marker)', () => {
28
+ const r = parseSpecConfidence('x.md', 'just prose\n- bullet\n## heading\n');
29
+ expect(r.counts.total).toBe(0);
30
+ expect(r.index).toBe(0);
31
+ });
32
+ });
33
+ describe('computeIndex', () => {
34
+ it('weights confirmed=1.0 and inferred=0.5', () => {
35
+ expect(computeIndex({ confirmed: 9, inferred: 1, gap: 1, total: 11 })).toBe(86.4);
36
+ expect(computeIndex({ confirmed: 4, inferred: 0, gap: 0, total: 4 })).toBe(100);
37
+ expect(computeIndex({ confirmed: 0, inferred: 0, gap: 0, total: 0 })).toBe(0);
38
+ });
39
+ });
40
+ describe('aggregate', () => {
41
+ it('sums counts across specs and recomputes the index', () => {
42
+ const specs = [
43
+ parseSpecConfidence('a.md', '- 🟢 x\n- 🟡 y'),
44
+ parseSpecConfidence('b.md', '- 🔴 z'),
45
+ ];
46
+ const { counts, index } = aggregate(specs);
47
+ expect(counts).toEqual({ confirmed: 1, inferred: 1, gap: 1, total: 3 });
48
+ expect(index).toBe(50); // (1 + 0.5) / 3
49
+ });
50
+ });
51
+ describe('renderConfidenceReport', () => {
52
+ it('renders a per-spec table with totals and the auditability caveat', () => {
53
+ const specs = [parseSpecConfidence('module-01-auth.md', SPEC)];
54
+ const md = renderConfidenceReport(specs, '2026-01-01T00:00:00.000Z');
55
+ expect(md).toContain('| module-01-auth.md | 3 | 1 | 1 | 70% |');
56
+ expect(md).toMatch(/\*\*Total\*\* \| \*\*3\*\* \| \*\*1\*\* \| \*\*1\*\*/);
57
+ expect(md).toContain('não auditoria factual externa');
58
+ });
59
+ });
60
+ describe('renderCodeSpecMatrix', () => {
61
+ it('lists evidence refs per spec', () => {
62
+ const specs = [parseSpecConfidence('module-01-auth.md', SPEC)];
63
+ const md = renderCodeSpecMatrix(specs, '2026-01-01T00:00:00.000Z');
64
+ expect(md).toContain('`module-01-auth.md`');
65
+ expect(md).toContain('`src/auth/login.ts:2`');
66
+ });
67
+ it('handles specs with no evidence gracefully', () => {
68
+ const specs = [parseSpecConfidence('empty.md', '- 🔴 sem evidência')];
69
+ const md = renderCodeSpecMatrix(specs, '2026-01-01T00:00:00.000Z');
70
+ expect(md).toContain('nenhuma evidência');
71
+ });
72
+ });
73
+ //# sourceMappingURL=confidence.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.test.js","sourceRoot":"","sources":["../../src/__tests__/confidence.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=datamodel.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datamodel.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/datamodel.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,131 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { extractDataModel, renderErd, renderApiSurface } from '../utils/datamodel.js';
6
+ const tmpDirs = [];
7
+ async function makeProject(files) {
8
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'dare-dm-'));
9
+ tmpDirs.push(dir);
10
+ for (const [rel, content] of Object.entries(files)) {
11
+ const abs = path.join(dir, rel);
12
+ await fs.ensureDir(path.dirname(abs));
13
+ await fs.writeFile(abs, content);
14
+ }
15
+ return dir;
16
+ }
17
+ afterEach(async () => {
18
+ while (tmpDirs.length)
19
+ await fs.remove(tmpDirs.pop());
20
+ });
21
+ describe('extractDataModel — Prisma', () => {
22
+ it('parses models, scalar fields, and relations (scalars are not relations)', async () => {
23
+ const root = await makeProject({
24
+ 'prisma/schema.prisma': `model User {\n id Int @id\n email String\n posts Post[]\n}\nmodel Post {\n id Int @id\n title String\n author User\n}\n`,
25
+ });
26
+ const dm = await extractDataModel(root);
27
+ const user = dm.entities.find((e) => e.name === 'User');
28
+ expect(user.fields.map((f) => f.name)).toEqual(['id', 'email']); // Int/String are scalars
29
+ expect(user.relations).toContainEqual({ to: 'Post', kind: 'has-many' });
30
+ const post = dm.entities.find((e) => e.name === 'Post');
31
+ expect(post.relations.some((r) => r.to === 'User')).toBe(true);
32
+ });
33
+ });
34
+ describe('extractDataModel — SQL', () => {
35
+ it('parses CREATE TABLE columns and FOREIGN KEY references', async () => {
36
+ const root = await makeProject({
37
+ 'migrations/001.sql': `CREATE TABLE orders (\n id INT PRIMARY KEY,\n user_id INT,\n total DECIMAL,\n FOREIGN KEY (user_id) REFERENCES users\n);`,
38
+ });
39
+ const dm = await extractDataModel(root);
40
+ const orders = dm.entities.find((e) => e.name === 'orders');
41
+ expect(orders.fields.map((f) => f.name)).toEqual(['id', 'user_id', 'total']);
42
+ expect(orders.relations).toContainEqual({ to: 'users', kind: 'references' });
43
+ expect(orders.source).toMatch(/001\.sql:1/);
44
+ });
45
+ });
46
+ describe('extractDataModel — endpoints', () => {
47
+ it('parses routes across frameworks with source refs', async () => {
48
+ const root = await makeProject({
49
+ 'src/routes.ts': `router.get('/users', h);\nrouter.post('/orders', h);\n@Get('/health')\n`,
50
+ 'app/routes.php': `Route::get('/ping', 'C@m');\n`,
51
+ });
52
+ const dm = await extractDataModel(root);
53
+ const keys = dm.endpoints.map((e) => `${e.method} ${e.route}`);
54
+ expect(keys).toContain('GET /users');
55
+ expect(keys).toContain('POST /orders');
56
+ expect(keys).toContain('GET /health');
57
+ expect(keys).toContain('GET /ping');
58
+ });
59
+ });
60
+ describe('renderErd / renderApiSurface', () => {
61
+ it('renders a Mermaid erDiagram with entities and relations', async () => {
62
+ const root = await makeProject({
63
+ 'prisma/schema.prisma': `model User {\n id Int @id\n posts Post[]\n}\nmodel Post {\n id Int @id\n}\n`,
64
+ });
65
+ const dm = await extractDataModel(root);
66
+ const md = renderErd(dm, '2026-01-01T00:00:00.000Z');
67
+ expect(md).toContain('erDiagram');
68
+ expect(md).toContain('USER ||--o{ POST');
69
+ expect(md).toMatch(/\| User \| /);
70
+ });
71
+ it('renders an empty-state ERD gracefully', async () => {
72
+ const root = await makeProject({ 'src/x.ts': 'export const x = 1;\n' });
73
+ const dm = await extractDataModel(root);
74
+ expect(renderErd(dm, 'now')).toContain('nenhuma entidade detectada');
75
+ expect(renderApiSurface(dm, 'now')).toContain('nenhum endpoint detectado');
76
+ });
77
+ });
78
+ // ── Fase 3.1: framework-agnostic por linguagem ──────────────────────────────
79
+ describe('framework-agnostic — legacy PHP (no Laravel)', () => {
80
+ it('extracts inline SQL DDL, query-only tables, plain model classes and Slim routes', async () => {
81
+ const root = await makeProject({
82
+ 'db/install.php': `<?php\n$pdo->exec("CREATE TABLE clientes (id INT PRIMARY KEY, nome VARCHAR(120));");\n$rows = $pdo->query("SELECT * FROM produtos WHERE ativo = 1");\n`,
83
+ 'models/Cliente.php': `<?php\nclass Cliente {\n public int $id;\n private ?string $email;\n}\n`,
84
+ 'public/index.php': `<?php\n$app->get('/clientes', 'h');\n$app->post('/pedidos', 'h');\n`,
85
+ });
86
+ const dm = await extractDataModel(root);
87
+ const names = dm.entities.map((e) => e.name);
88
+ expect(names).toContain('clientes'); // inline CREATE TABLE
89
+ expect(names).toContain('produtos'); // referenced only in a SELECT
90
+ expect(names).toContain('Cliente'); // plain typed class in models/
91
+ const cliente = dm.entities.find((e) => e.name === 'Cliente');
92
+ expect(cliente.fields.map((f) => f.name)).toEqual(['id', 'email']);
93
+ const routes = dm.endpoints.map((e) => `${e.method} ${e.route}`);
94
+ expect(routes).toContain('GET /clientes');
95
+ expect(routes).toContain('POST /pedidos');
96
+ });
97
+ });
98
+ describe('framework-agnostic — multi-dialect routing', () => {
99
+ it('parses Flask (methods array), Django (any), Go stdlib (any), Rust/Axum and Ruby', async () => {
100
+ const root = await makeProject({
101
+ 'app.py': `@app.route('/items', methods=['GET', 'POST'])\ndef items(): pass\n@app.route('/health')\ndef health(): pass\n`,
102
+ 'urls.py': `urlpatterns = [\n path('admin/', admin),\n]\n`,
103
+ 'main.go': `mux.HandleFunc("/go-route", handler)\n`,
104
+ 'routes.rs': `let app = Router::new().route("/users", get(list_users));\n`,
105
+ 'config/routes.rb': `Rails.application.routes.draw do\n get '/ruby-route', to: 'x#y'\nend\n`,
106
+ });
107
+ const dm = await extractDataModel(root);
108
+ const routes = dm.endpoints.map((e) => `${e.method} ${e.route}`);
109
+ expect(routes).toContain('GET /items');
110
+ expect(routes).toContain('POST /items'); // expanded from methods array
111
+ expect(routes).toContain('GET /health'); // Flask route without methods → GET
112
+ expect(routes).toContain('ANY admin/'); // Django path (method-less)
113
+ expect(routes).toContain('ANY /go-route'); // Go stdlib HandleFunc
114
+ expect(routes).toContain('GET /users'); // Rust/Axum (path then method)
115
+ expect(routes).toContain('GET /ruby-route'); // Rails/Sinatra
116
+ });
117
+ });
118
+ describe('framework-agnostic — type extraction across languages', () => {
119
+ it('extracts Go structs and Python dataclasses in data dirs', async () => {
120
+ const root = await makeProject({
121
+ 'models/user.go': `type User struct {\n ID int\n Name string\n}\n`,
122
+ 'domain/order.py': `@dataclass\nclass Order:\n id: int\n total: float\n`,
123
+ });
124
+ const dm = await extractDataModel(root);
125
+ const go = dm.entities.find((e) => e.name === 'User');
126
+ expect(go.fields.map((f) => f.name)).toEqual(['ID', 'Name']);
127
+ const py = dm.entities.find((e) => e.name === 'Order');
128
+ expect(py.fields.map((f) => f.name)).toEqual(['id', 'total']);
129
+ });
130
+ });
131
+ //# sourceMappingURL=datamodel.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datamodel.test.js","sourceRoot":"","sources":["../../src/__tests__/datamodel.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dna-detector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dna-detector.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dna-detector.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,97 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { detectDna } from '../utils/dna-detector.js';
6
+ const tmpDirs = [];
7
+ async function makeProject(files) {
8
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'dare-dna-'));
9
+ tmpDirs.push(dir);
10
+ for (const [rel, content] of Object.entries(files)) {
11
+ const abs = path.join(dir, rel);
12
+ await fs.ensureDir(path.dirname(abs));
13
+ await fs.writeFile(abs, content);
14
+ }
15
+ return dir;
16
+ }
17
+ afterEach(async () => {
18
+ while (tmpDirs.length)
19
+ await fs.remove(tmpDirs.pop());
20
+ });
21
+ const AT = '2026-01-01T00:00:00.000Z';
22
+ describe('detectDna — tooling', () => {
23
+ it('detects and parses Prettier + EditorConfig rules', async () => {
24
+ const root = await makeProject({
25
+ 'package.json': '{"name":"app","version":"1.0.0"}',
26
+ '.prettierrc': '{ "semi": false, "singleQuote": true, "tabWidth": 2 }',
27
+ '.editorconfig': 'root = true\n[*]\nindent_style = space\nindent_size = 2\n',
28
+ 'src/core/x.ts': 'export const x = 1;\n',
29
+ });
30
+ const facts = await detectDna(root, AT);
31
+ const prettier = facts.tooling.formatters.find((f) => f.name === 'Prettier');
32
+ expect(prettier).toBeTruthy();
33
+ expect(prettier?.rules?.semi).toBe(false);
34
+ expect(prettier?.rules?.singleQuote).toBe(true);
35
+ const editorconfig = facts.tooling.formatters.find((f) => f.name === 'EditorConfig');
36
+ expect(editorconfig?.rules?.indent_style).toBe('space');
37
+ });
38
+ it('detects ESLint from package.json#eslintConfig', async () => {
39
+ const root = await makeProject({
40
+ 'package.json': '{"name":"app","version":"1.0.0","eslintConfig":{"extends":"airbnb"}}',
41
+ 'src/core/x.ts': 'export const x = 1;\n',
42
+ });
43
+ const facts = await detectDna(root, AT);
44
+ expect(facts.tooling.linters.some((l) => l.name === 'ESLint')).toBe(true);
45
+ });
46
+ });
47
+ describe('detectDna — naming', () => {
48
+ it('reports the dominant file-naming style per extension', async () => {
49
+ const root = await makeProject({
50
+ 'src/api/user-controller.ts': 'export {};\n',
51
+ 'src/api/auth-controller.ts': 'export {};\n',
52
+ 'src/api/order-service.ts': 'export {};\n',
53
+ 'src/api/payment-gateway.ts': 'export {};\n',
54
+ });
55
+ const facts = await detectDna(root, AT);
56
+ const ts = facts.naming.find((n) => n.extension === '.ts');
57
+ expect(ts?.dominant).toBe('kebab-case');
58
+ });
59
+ });
60
+ describe('detectDna — architecture & libraries & testing', () => {
61
+ it('guesses layered/MVC from dirs and detects libs + test framework', async () => {
62
+ const root = await makeProject({
63
+ 'package.json': JSON.stringify({
64
+ name: 'app',
65
+ version: '1.0.0',
66
+ dependencies: { '@nestjs/core': '^10', '@prisma/client': '^5', zod: '^3' },
67
+ devDependencies: { vitest: '^1' },
68
+ }),
69
+ 'src/controllers/user.controller.ts': 'export class U {}\n',
70
+ 'src/services/user.service.ts': 'export class S {}\n',
71
+ 'src/repositories/user.repository.ts': 'export class R {}\n',
72
+ 'src/__tests__/user.test.ts': 'export const t = 1;\n',
73
+ });
74
+ const facts = await detectDna(root, AT);
75
+ expect(facts.architecture.detectedLayers).toEqual(expect.arrayContaining(['controllers', 'services', 'repositories']));
76
+ expect(facts.architecture.guess).toMatch(/Layered/);
77
+ expect(facts.libraries.orm).toBe('Prisma');
78
+ expect(facts.libraries.http).toBe('NestJS');
79
+ expect(facts.libraries.validation).toBe('Zod');
80
+ expect(facts.testing.framework).toBe('Vitest');
81
+ expect(facts.testing.testFiles).toBe(1);
82
+ });
83
+ });
84
+ describe('detectDna — reuses reverse-facts when present', () => {
85
+ it('reads the file inventory from DARE/REVERSE/reverse-facts.json', async () => {
86
+ const root = await makeProject({
87
+ 'DARE/REVERSE/reverse-facts.json': JSON.stringify({
88
+ modules: [{ id: 'm', name: 'm', path: 'm', files: ['m/alpha-thing.ts', 'm/beta-thing.ts'] }],
89
+ }),
90
+ });
91
+ const facts = await detectDna(root, AT);
92
+ expect(facts.fileInventorySource).toBe('reverse-facts');
93
+ const ts = facts.naming.find((n) => n.extension === '.ts');
94
+ expect(ts?.dominant).toBe('kebab-case');
95
+ });
96
+ });
97
+ //# sourceMappingURL=dna-detector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dna-detector.test.js","sourceRoot":"","sources":["../../src/__tests__/dna-detector.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,MAAM,OAAO,GAAa,EAAE,CAAC;AAE7B,KAAK,UAAU,WAAW,CAAC,KAA6B;IACtD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAChC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,OAAO,OAAO,CAAC,MAAM;QAAE,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAG,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAEH,MAAM,EAAE,GAAG,0BAA0B,CAAC;AAEtC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,cAAc,EAAE,kCAAkC;YAClD,aAAa,EAAE,uDAAuD;YACtE,eAAe,EAAE,2DAA2D;YAC5E,eAAe,EAAE,uBAAuB;SACzC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC7E,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC;QAC9B,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEhD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;QACrF,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,cAAc,EAAE,sEAAsE;YACtF,eAAe,EAAE,uBAAuB;SACzC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,4BAA4B,EAAE,cAAc;YAC5C,4BAA4B,EAAE,cAAc;YAC5C,0BAA0B,EAAE,cAAc;YAC1C,4BAA4B,EAAE,cAAc;SAC7C,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC;QAC3D,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;gBAC7B,IAAI,EAAE,KAAK;gBACX,OAAO,EAAE,OAAO;gBAChB,YAAY,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE;gBAC1E,eAAe,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;aAClC,CAAC;YACF,oCAAoC,EAAE,qBAAqB;YAC3D,8BAA8B,EAAE,qBAAqB;YACrD,qCAAqC,EAAE,qBAAqB;YAC5D,4BAA4B,EAAE,uBAAuB;SACtD,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,OAAO,CAC/C,MAAM,CAAC,eAAe,CAAC,CAAC,aAAa,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,CACpE,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;IAC7D,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,iCAAiC,EAAE,IAAI,CAAC,SAAS,CAAC;gBAChD,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,EAAE,CAAC;aAC7F,CAAC;SACH,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACxD,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC;QAC3D,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dna-facts.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dna-facts.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dna-facts.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { renderDnaSkeleton } from '../utils/dna-facts.js';
3
+ const facts = (over = {}) => ({
4
+ generatedAt: '2026-01-01T00:00:00.000Z',
5
+ fileInventorySource: 'module-detector',
6
+ tooling: {
7
+ linters: [{ name: 'ESLint', configPath: '.eslintrc.json' }],
8
+ formatters: [{ name: 'Prettier', configPath: '.prettierrc', rules: { semi: false, singleQuote: true } }],
9
+ },
10
+ naming: [{ extension: '.ts', dominant: 'kebab-case', counts: { 'kebab-case': 3 }, samples: ['a-b.ts'] }],
11
+ architecture: { detectedLayers: ['controllers', 'services'], guess: 'Layered (Controller → Service)' },
12
+ testing: { framework: 'Vitest', testFiles: 10, prodFiles: 40, ratio: 0.25 },
13
+ libraries: { orm: 'Prisma', http: 'NestJS', validation: 'Zod' },
14
+ commits: { sampled: 50, conventional: true, prefixes: { feat: 20, fix: 15 } },
15
+ ...over,
16
+ });
17
+ describe('renderDnaSkeleton', () => {
18
+ it('embeds deterministic facts and AGENT placeholders', () => {
19
+ const md = renderDnaSkeleton(facts());
20
+ expect(md).toContain('# PROJECT-DNA');
21
+ expect(md).toContain('**Prettier** (`.prettierrc`)');
22
+ expect(md).toContain('semi: false');
23
+ expect(md).toContain('| `.ts` | kebab-case |');
24
+ expect(md).toContain('Layered (Controller → Service)');
25
+ expect(md).toContain('| ORM / Dados | Prisma |');
26
+ expect(md).toContain('Vitest');
27
+ expect(md).toContain('<!-- AGENT'); // semantic sections left for the skill
28
+ expect(md).toContain('Regras de Ouro do Projeto');
29
+ });
30
+ it('renders the conventional-commits summary with prefixes', () => {
31
+ const md = renderDnaSkeleton(facts());
32
+ expect(md).toMatch(/\*\*segue Conventional Commits\*\*/);
33
+ expect(md).toContain('feat:20');
34
+ });
35
+ it('notes when git is unavailable', () => {
36
+ const md = renderDnaSkeleton(facts({ commits: null }));
37
+ expect(md).toContain('repositório git indisponível');
38
+ });
39
+ it('handles empty tooling gracefully', () => {
40
+ const md = renderDnaSkeleton(facts({ tooling: { linters: [], formatters: [] } }));
41
+ expect(md).toContain('_(nenhum detectado)_');
42
+ });
43
+ });
44
+ //# sourceMappingURL=dna-facts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dna-facts.test.js","sourceRoot":"","sources":["../../src/__tests__/dna-facts.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=graph-renderer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-renderer.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/graph-renderer.test.ts"],"names":[],"mappings":""}