@dewtech/dare-cli 2.16.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 (408) hide show
  1. package/README.md +196 -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.d.ts +2 -0
  31. package/dist/__tests__/refine.test.d.ts.map +1 -0
  32. package/dist/__tests__/refine.test.js +186 -0
  33. package/dist/__tests__/refine.test.js.map +1 -0
  34. package/dist/__tests__/reverse-facts.test.d.ts +2 -0
  35. package/dist/__tests__/reverse-facts.test.d.ts.map +1 -0
  36. package/dist/__tests__/reverse-facts.test.js +78 -0
  37. package/dist/__tests__/reverse-facts.test.js.map +1 -0
  38. package/dist/__tests__/review.test.d.ts +2 -0
  39. package/dist/__tests__/review.test.d.ts.map +1 -0
  40. package/dist/__tests__/review.test.js +242 -0
  41. package/dist/__tests__/review.test.js.map +1 -0
  42. package/dist/__tests__/update.test.d.ts +2 -0
  43. package/dist/__tests__/update.test.d.ts.map +1 -0
  44. package/dist/__tests__/update.test.js +150 -0
  45. package/dist/__tests__/update.test.js.map +1 -0
  46. package/dist/__tests__/validate.test.js +65 -65
  47. package/dist/bin/dare.js +38 -3
  48. package/dist/bin/dare.js.map +1 -1
  49. package/dist/commands/blueprint.js +122 -122
  50. package/dist/commands/dag.d.ts.map +1 -1
  51. package/dist/commands/dag.js +43 -79
  52. package/dist/commands/dag.js.map +1 -1
  53. package/dist/commands/dna.d.ts +3 -0
  54. package/dist/commands/dna.d.ts.map +1 -0
  55. package/dist/commands/dna.js +69 -0
  56. package/dist/commands/dna.js.map +1 -0
  57. package/dist/commands/execute.d.ts.map +1 -1
  58. package/dist/commands/execute.js +76 -0
  59. package/dist/commands/execute.js.map +1 -1
  60. package/dist/commands/migrate.d.ts +3 -0
  61. package/dist/commands/migrate.d.ts.map +1 -0
  62. package/dist/commands/migrate.js +101 -0
  63. package/dist/commands/migrate.js.map +1 -0
  64. package/dist/commands/new.d.ts +16 -0
  65. package/dist/commands/new.d.ts.map +1 -0
  66. package/dist/commands/new.js +103 -0
  67. package/dist/commands/new.js.map +1 -0
  68. package/dist/commands/refine.d.ts +16 -0
  69. package/dist/commands/refine.d.ts.map +1 -0
  70. package/dist/commands/refine.js +167 -0
  71. package/dist/commands/refine.js.map +1 -0
  72. package/dist/commands/reverse.d.ts +3 -0
  73. package/dist/commands/reverse.d.ts.map +1 -0
  74. package/dist/commands/reverse.js +201 -0
  75. package/dist/commands/reverse.js.map +1 -0
  76. package/dist/commands/review.d.ts +16 -0
  77. package/dist/commands/review.d.ts.map +1 -0
  78. package/dist/commands/review.js +106 -0
  79. package/dist/commands/review.js.map +1 -0
  80. package/dist/commands/update.d.ts +13 -0
  81. package/dist/commands/update.d.ts.map +1 -0
  82. package/dist/commands/update.js +149 -0
  83. package/dist/commands/update.js.map +1 -0
  84. package/dist/commands/welcome.d.ts +14 -0
  85. package/dist/commands/welcome.d.ts.map +1 -0
  86. package/dist/commands/welcome.js +29 -0
  87. package/dist/commands/welcome.js.map +1 -0
  88. package/dist/skills/commands/add.d.ts +23 -0
  89. package/dist/skills/commands/add.d.ts.map +1 -0
  90. package/dist/skills/commands/add.js +206 -0
  91. package/dist/skills/commands/add.js.map +1 -0
  92. package/dist/skills/commands/info.d.ts +14 -0
  93. package/dist/skills/commands/info.d.ts.map +1 -0
  94. package/dist/skills/commands/info.js +99 -0
  95. package/dist/skills/commands/info.js.map +1 -0
  96. package/dist/skills/commands/list.d.ts +19 -0
  97. package/dist/skills/commands/list.d.ts.map +1 -0
  98. package/dist/skills/commands/list.js +163 -0
  99. package/dist/skills/commands/list.js.map +1 -0
  100. package/dist/skills/commands/publish.d.ts +56 -0
  101. package/dist/skills/commands/publish.d.ts.map +1 -0
  102. package/dist/skills/commands/publish.js +272 -0
  103. package/dist/skills/commands/publish.js.map +1 -0
  104. package/dist/skills/commands/remove.d.ts +19 -0
  105. package/dist/skills/commands/remove.d.ts.map +1 -0
  106. package/dist/skills/commands/remove.js +96 -0
  107. package/dist/skills/commands/remove.js.map +1 -0
  108. package/dist/skills/commands/update.d.ts +31 -0
  109. package/dist/skills/commands/update.d.ts.map +1 -0
  110. package/dist/skills/commands/update.js +132 -0
  111. package/dist/skills/commands/update.js.map +1 -0
  112. package/dist/skills/index.d.ts +22 -0
  113. package/dist/skills/index.d.ts.map +1 -0
  114. package/dist/skills/index.js +33 -0
  115. package/dist/skills/index.js.map +1 -0
  116. package/dist/skills/manifest.d.ts +54 -0
  117. package/dist/skills/manifest.d.ts.map +1 -0
  118. package/dist/skills/manifest.js +162 -0
  119. package/dist/skills/manifest.js.map +1 -0
  120. package/dist/skills/registry-local.d.ts +67 -0
  121. package/dist/skills/registry-local.d.ts.map +1 -0
  122. package/dist/skills/registry-local.js +130 -0
  123. package/dist/skills/registry-local.js.map +1 -0
  124. package/dist/skills/registry-mock.json +109 -0
  125. package/dist/skills/registry-remote.d.ts +110 -0
  126. package/dist/skills/registry-remote.d.ts.map +1 -0
  127. package/dist/skills/registry-remote.js +246 -0
  128. package/dist/skills/registry-remote.js.map +1 -0
  129. package/dist/skills/registry.d.ts +49 -0
  130. package/dist/skills/registry.d.ts.map +1 -0
  131. package/dist/skills/registry.js +94 -0
  132. package/dist/skills/registry.js.map +1 -0
  133. package/dist/skills/tests/manifest.spec.d.ts +8 -0
  134. package/dist/skills/tests/manifest.spec.d.ts.map +1 -0
  135. package/dist/skills/tests/manifest.spec.js +176 -0
  136. package/dist/skills/tests/manifest.spec.js.map +1 -0
  137. package/dist/skills/tests/publish.spec.d.ts +12 -0
  138. package/dist/skills/tests/publish.spec.d.ts.map +1 -0
  139. package/dist/skills/tests/publish.spec.js +276 -0
  140. package/dist/skills/tests/publish.spec.js.map +1 -0
  141. package/dist/skills/tests/registry-local.spec.d.ts +8 -0
  142. package/dist/skills/tests/registry-local.spec.d.ts.map +1 -0
  143. package/dist/skills/tests/registry-local.spec.js +231 -0
  144. package/dist/skills/tests/registry-local.spec.js.map +1 -0
  145. package/dist/skills/tests/registry.spec.d.ts +7 -0
  146. package/dist/skills/tests/registry.spec.d.ts.map +1 -0
  147. package/dist/skills/tests/registry.spec.js +58 -0
  148. package/dist/skills/tests/registry.spec.js.map +1 -0
  149. package/dist/skills/tests/remote-registry.spec.d.ts +9 -0
  150. package/dist/skills/tests/remote-registry.spec.d.ts.map +1 -0
  151. package/dist/skills/tests/remote-registry.spec.js +357 -0
  152. package/dist/skills/tests/remote-registry.spec.js.map +1 -0
  153. package/dist/skills/tests/update.spec.d.ts +9 -0
  154. package/dist/skills/tests/update.spec.d.ts.map +1 -0
  155. package/dist/skills/tests/update.spec.js +166 -0
  156. package/dist/skills/tests/update.spec.js.map +1 -0
  157. package/dist/types/Refine.types.d.ts +96 -0
  158. package/dist/types/Refine.types.d.ts.map +1 -0
  159. package/dist/types/Refine.types.js +19 -0
  160. package/dist/types/Refine.types.js.map +1 -0
  161. package/dist/types/Review.types.d.ts +86 -0
  162. package/dist/types/Review.types.d.ts.map +1 -0
  163. package/dist/types/Review.types.js +15 -0
  164. package/dist/types/Review.types.js.map +1 -0
  165. package/dist/types/UpdateManifest.types.d.ts +91 -0
  166. package/dist/types/UpdateManifest.types.d.ts.map +1 -0
  167. package/dist/types/UpdateManifest.types.js +13 -0
  168. package/dist/types/UpdateManifest.types.js.map +1 -0
  169. package/dist/utils/ReviewRunner.d.ts +42 -0
  170. package/dist/utils/ReviewRunner.d.ts.map +1 -0
  171. package/dist/utils/ReviewRunner.js +175 -0
  172. package/dist/utils/ReviewRunner.js.map +1 -0
  173. package/dist/utils/UpdateApplier.d.ts +42 -0
  174. package/dist/utils/UpdateApplier.d.ts.map +1 -0
  175. package/dist/utils/UpdateApplier.js +207 -0
  176. package/dist/utils/UpdateApplier.js.map +1 -0
  177. package/dist/utils/UpdateDetector.d.ts +56 -0
  178. package/dist/utils/UpdateDetector.d.ts.map +1 -0
  179. package/dist/utils/UpdateDetector.js +164 -0
  180. package/dist/utils/UpdateDetector.js.map +1 -0
  181. package/dist/utils/banner.d.ts +28 -0
  182. package/dist/utils/banner.d.ts.map +1 -0
  183. package/dist/utils/banner.js +77 -0
  184. package/dist/utils/banner.js.map +1 -0
  185. package/dist/utils/banner.spec.d.ts +5 -0
  186. package/dist/utils/banner.spec.d.ts.map +1 -0
  187. package/dist/utils/banner.spec.js +253 -0
  188. package/dist/utils/banner.spec.js.map +1 -0
  189. package/dist/utils/complexity-analyzer.d.ts +60 -0
  190. package/dist/utils/complexity-analyzer.d.ts.map +1 -0
  191. package/dist/utils/complexity-analyzer.js +292 -0
  192. package/dist/utils/complexity-analyzer.js.map +1 -0
  193. package/dist/utils/confidence.d.ts +41 -0
  194. package/dist/utils/confidence.d.ts.map +1 -0
  195. package/dist/utils/confidence.js +101 -0
  196. package/dist/utils/confidence.js.map +1 -0
  197. package/dist/utils/datamodel.d.ts +41 -0
  198. package/dist/utils/datamodel.d.ts.map +1 -0
  199. package/dist/utils/datamodel.js +535 -0
  200. package/dist/utils/datamodel.js.map +1 -0
  201. package/dist/utils/dna-detector.d.ts +61 -0
  202. package/dist/utils/dna-detector.d.ts.map +1 -0
  203. package/dist/utils/dna-detector.js +354 -0
  204. package/dist/utils/dna-detector.js.map +1 -0
  205. package/dist/utils/dna-facts.d.ts +13 -0
  206. package/dist/utils/dna-facts.d.ts.map +1 -0
  207. package/dist/utils/dna-facts.js +109 -0
  208. package/dist/utils/dna-facts.js.map +1 -0
  209. package/dist/utils/excalidraw-renderer.d.ts +11 -71
  210. package/dist/utils/excalidraw-renderer.d.ts.map +1 -1
  211. package/dist/utils/excalidraw-renderer.js +29 -162
  212. package/dist/utils/excalidraw-renderer.js.map +1 -1
  213. package/dist/utils/graph-renderer.d.ts +115 -0
  214. package/dist/utils/graph-renderer.d.ts.map +1 -0
  215. package/dist/utils/graph-renderer.js +216 -0
  216. package/dist/utils/graph-renderer.js.map +1 -0
  217. package/dist/utils/migration.d.ts +64 -0
  218. package/dist/utils/migration.d.ts.map +1 -0
  219. package/dist/utils/migration.js +183 -0
  220. package/dist/utils/migration.js.map +1 -0
  221. package/dist/utils/module-detector.d.ts +46 -0
  222. package/dist/utils/module-detector.d.ts.map +1 -0
  223. package/dist/utils/module-detector.js +348 -0
  224. package/dist/utils/module-detector.js.map +1 -0
  225. package/dist/utils/project-generator.d.ts.map +1 -1
  226. package/dist/utils/project-generator.js +273 -254
  227. package/dist/utils/project-generator.js.map +1 -1
  228. package/dist/utils/reverse-facts.d.ts +50 -0
  229. package/dist/utils/reverse-facts.d.ts.map +1 -0
  230. package/dist/utils/reverse-facts.js +291 -0
  231. package/dist/utils/reverse-facts.js.map +1 -0
  232. package/dist/utils/stack-bootstrap.js +371 -371
  233. package/dist/utils/static-analyzer.d.ts +29 -0
  234. package/dist/utils/static-analyzer.d.ts.map +1 -0
  235. package/dist/utils/static-analyzer.js +390 -0
  236. package/dist/utils/static-analyzer.js.map +1 -0
  237. package/dist/utils/version-compare.d.ts +27 -0
  238. package/dist/utils/version-compare.d.ts.map +1 -0
  239. package/dist/utils/version-compare.js +47 -0
  240. package/dist/utils/version-compare.js.map +1 -0
  241. package/package.json +8 -3
  242. package/templates/DARE-dag-example.yaml +280 -280
  243. package/templates/UPDATE-MANIFEST.json +48 -0
  244. package/templates/backend/node-nestjs/.env.example +9 -9
  245. package/templates/backend/node-nestjs/nest-cli.json +8 -8
  246. package/templates/backend/node-nestjs/package.json +50 -50
  247. package/templates/backend/node-nestjs/src/app.controller.ts +12 -12
  248. package/templates/backend/node-nestjs/src/app.module.ts +15 -15
  249. package/templates/backend/node-nestjs/src/app.service.ts +8 -8
  250. package/templates/backend/node-nestjs/src/main.ts +24 -24
  251. package/templates/backend/node-nestjs/tsconfig.json +21 -21
  252. package/templates/backend/php-laravel/.env.example +22 -22
  253. package/templates/backend/php-laravel/app/Http/Controllers/HealthController.php +15 -15
  254. package/templates/backend/php-laravel/composer.json +40 -40
  255. package/templates/backend/python-fastapi/.env.example +4 -4
  256. package/templates/backend/python-fastapi/app/api/router.py +8 -8
  257. package/templates/backend/python-fastapi/app/core/config.py +20 -20
  258. package/templates/backend/python-fastapi/main.py +35 -35
  259. package/templates/backend/python-fastapi/requirements.txt +13 -13
  260. package/templates/backend/rust-axum/.env.example +3 -3
  261. package/templates/backend/rust-axum/Cargo.toml +23 -23
  262. package/templates/backend/rust-axum/src/errors.rs +30 -30
  263. package/templates/backend/rust-axum/src/main.rs +32 -32
  264. package/templates/backend/rust-axum/src/routes.rs +6 -6
  265. package/templates/frontend/leptos-csr/.cargo/config.toml +2 -2
  266. package/templates/frontend/leptos-csr/Cargo.toml +16 -16
  267. package/templates/frontend/leptos-csr/Trunk.toml +10 -10
  268. package/templates/frontend/leptos-csr/index.html +11 -11
  269. package/templates/frontend/leptos-csr/src/lib.rs +20 -20
  270. package/templates/frontend/leptos-csr/style/main.scss +19 -19
  271. package/templates/frontend/leptos-fullstack/.cargo/config.toml +4 -4
  272. package/templates/frontend/leptos-fullstack/Cargo.toml +56 -56
  273. package/templates/frontend/leptos-fullstack/src/app.rs +49 -49
  274. package/templates/frontend/leptos-fullstack/src/lib.rs +9 -9
  275. package/templates/frontend/leptos-fullstack/src/main.rs +29 -29
  276. package/templates/frontend/leptos-fullstack/style/main.scss +19 -19
  277. package/templates/frontend/react/index.html +12 -12
  278. package/templates/frontend/react/package.json +35 -35
  279. package/templates/frontend/react/src/App.tsx +25 -25
  280. package/templates/frontend/react/src/main.tsx +9 -9
  281. package/templates/frontend/vue/package.json +32 -32
  282. package/templates/frontend/vue/src/App.vue +7 -7
  283. package/templates/frontend/vue/src/main.ts +10 -10
  284. package/templates/frontend/vue/src/router/index.ts +14 -14
  285. package/templates/frontend/vue/src/views/HomeView.vue +6 -6
  286. package/templates/hooks/pre-commit-dare-validate +24 -24
  287. package/templates/ide/antigravity/.agents/skills/dare-ax/SKILL.md +152 -0
  288. package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +180 -36
  289. package/templates/ide/antigravity/.agents/skills/dare-dag-build/SKILL.md +154 -0
  290. package/templates/ide/antigravity/.agents/skills/dare-dag-run/SKILL.md +130 -0
  291. package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +203 -203
  292. package/templates/ide/antigravity/.agents/skills/dare-dna/SKILL.md +63 -0
  293. package/templates/ide/antigravity/.agents/skills/dare-docker/SKILL.md +315 -0
  294. package/templates/ide/antigravity/.agents/skills/dare-frontend-design/SKILL.md +192 -0
  295. package/templates/ide/antigravity/.agents/skills/dare-laravel-api/SKILL.md +337 -0
  296. package/templates/ide/antigravity/.agents/skills/dare-layered-design/SKILL.md +166 -0
  297. package/templates/ide/antigravity/.agents/skills/dare-llm-integration/SKILL.md +217 -0
  298. package/templates/ide/antigravity/.agents/skills/dare-migrate/SKILL.md +61 -0
  299. package/templates/ide/antigravity/.agents/skills/dare-quality-telemetry/SKILL.md +187 -0
  300. package/templates/ide/antigravity/.agents/skills/dare-realtime/SKILL.md +217 -0
  301. package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +114 -0
  302. package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +108 -0
  303. package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -0
  304. package/templates/ide/antigravity/.agents/skills/dare-rust-leptos/SKILL.md +263 -0
  305. package/templates/ide/antigravity/.agents/skills/dare-rust-workspace/SKILL.md +275 -275
  306. package/templates/ide/antigravity/.agents/skills/dare-security/SKILL.md +274 -0
  307. package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +265 -224
  308. package/templates/ide/antigravity/.agents/skills/dare-telemetry/SKILL.md +188 -0
  309. package/templates/ide/antigravity/.agents/skills/skill-fastapi-api/SKILL.md +343 -0
  310. package/templates/ide/antigravity/.agents/skills/skill-go-gin-api/SKILL.md +377 -0
  311. package/templates/ide/antigravity/.agents/skills/skill-mcp-server/SKILL.md +382 -0
  312. package/templates/ide/antigravity/.agents/skills/skill-nestjs-api/SKILL.md +326 -0
  313. package/templates/ide/antigravity/.agents/skills/skill-rails-api/SKILL.md +393 -0
  314. package/templates/ide/antigravity/templates/BLUEPRINT-template.md +193 -193
  315. package/templates/ide/antigravity/templates/DESIGN-template.md +129 -129
  316. package/templates/ide/antigravity/templates/TASK-SPEC-template.md +141 -100
  317. package/templates/ide/claude/.claude/commands/dare-ax.md +131 -0
  318. package/templates/ide/claude/.claude/commands/dare-blueprint.md +134 -78
  319. package/templates/ide/claude/.claude/commands/dare-bugfix-design.md +119 -0
  320. package/templates/ide/claude/.claude/commands/dare-dag-build.md +151 -110
  321. package/templates/ide/claude/.claude/commands/dare-dag-run.md +109 -109
  322. package/templates/ide/claude/.claude/commands/dare-dag-runner.md +117 -0
  323. package/templates/ide/claude/.claude/commands/dare-dag-viz.md +197 -197
  324. package/templates/ide/claude/.claude/commands/dare-design.md +69 -69
  325. package/templates/ide/claude/.claude/commands/dare-dna.md +75 -0
  326. package/templates/ide/claude/.claude/commands/dare-docker.md +207 -0
  327. package/templates/ide/claude/.claude/commands/dare-execute.md +152 -152
  328. package/templates/ide/claude/.claude/commands/dare-feature-design.md +147 -0
  329. package/templates/ide/claude/.claude/commands/dare-frontend-design.md +149 -0
  330. package/templates/ide/claude/.claude/commands/dare-laravel-api.md +211 -0
  331. package/templates/ide/claude/.claude/commands/dare-layered-design.md +124 -0
  332. package/templates/ide/claude/.claude/commands/dare-llm-integration.md +148 -0
  333. package/templates/ide/claude/.claude/commands/dare-migrate.md +72 -0
  334. package/templates/ide/claude/.claude/commands/dare-quality-telemetry.md +166 -0
  335. package/templates/ide/claude/.claude/commands/dare-realtime.md +159 -0
  336. package/templates/ide/claude/.claude/commands/dare-refine.md +145 -0
  337. package/templates/ide/claude/.claude/commands/dare-reverse.md +139 -0
  338. package/templates/ide/claude/.claude/commands/dare-review.md +113 -0
  339. package/templates/ide/claude/.claude/commands/dare-rust-leptos.md +269 -269
  340. package/templates/ide/claude/.claude/commands/dare-rust-workspace.md +209 -209
  341. package/templates/ide/claude/.claude/commands/dare-security.md +232 -232
  342. package/templates/ide/claude/.claude/commands/dare-tasks.md +70 -70
  343. package/templates/ide/claude/.claude/commands/dare-telemetry.md +132 -0
  344. package/templates/ide/claude/.claude/commands/skill-fastapi-api.md +205 -0
  345. package/templates/ide/claude/.claude/commands/skill-go-gin-api.md +232 -0
  346. package/templates/ide/claude/.claude/commands/skill-mcp-server.md +228 -0
  347. package/templates/ide/claude/.claude/commands/skill-nestjs-api.md +210 -0
  348. package/templates/ide/claude/.claude/commands/skill-rails-api.md +236 -0
  349. package/templates/ide/claude/.claude/settings.example.json +35 -35
  350. package/templates/ide/claude/CLAUDE.md +146 -146
  351. package/templates/ide/claude/templates/BLUEPRINT-template.md +193 -193
  352. package/templates/ide/claude/templates/DESIGN-template.md +129 -129
  353. package/templates/ide/claude/templates/TASK-SPEC-template.md +141 -100
  354. package/templates/ide/cursor/.cursor/commands/dag-viz.md +139 -0
  355. package/templates/ide/cursor/.cursor/commands/generate-blueprint.md +86 -41
  356. package/templates/ide/cursor/.cursor/commands/generate-design.md +35 -35
  357. package/templates/ide/cursor/.cursor/commands/generate-tasks.md +184 -142
  358. package/templates/ide/cursor/.cursor/commands/refine-task.md +107 -0
  359. package/templates/ide/cursor/.cursor/commands/review-task.md +91 -0
  360. package/templates/ide/cursor/.cursor/commands/run-dag.md +110 -110
  361. package/templates/ide/cursor/.cursor/rules/skill-ax.mdc +263 -0
  362. package/templates/ide/cursor/.cursor/rules/skill-dag-build.mdc +173 -0
  363. package/templates/ide/cursor/.cursor/rules/skill-dag-run.mdc +134 -0
  364. package/templates/ide/cursor/.cursor/rules/skill-dag-runner.mdc +221 -221
  365. package/templates/ide/cursor/.cursor/rules/skill-dna.mdc +63 -0
  366. package/templates/ide/cursor/.cursor/rules/skill-fastapi-api.mdc +352 -0
  367. package/templates/ide/cursor/.cursor/rules/skill-frontend-design.mdc +244 -0
  368. package/templates/ide/cursor/.cursor/rules/skill-go-gin-api.mdc +371 -0
  369. package/templates/ide/cursor/.cursor/rules/skill-layered-design.mdc +266 -0
  370. package/templates/ide/cursor/.cursor/rules/skill-llm-integration.mdc +295 -0
  371. package/templates/ide/cursor/.cursor/rules/skill-mcp-server.mdc +367 -0
  372. package/templates/ide/cursor/.cursor/rules/skill-migrate.mdc +58 -0
  373. package/templates/ide/cursor/.cursor/rules/skill-nestjs-api.mdc +346 -0
  374. package/templates/ide/cursor/.cursor/rules/skill-quality-telemetry.mdc +248 -0
  375. package/templates/ide/cursor/.cursor/rules/skill-rails-api.mdc +400 -0
  376. package/templates/ide/cursor/.cursor/rules/skill-realtime.mdc +262 -0
  377. package/templates/ide/cursor/.cursor/rules/skill-reverse.mdc +107 -0
  378. package/templates/ide/cursor/.cursor/rules/skill-rust-leptos.mdc +281 -0
  379. package/templates/ide/cursor/.cursor/rules/skill-rust-workspace.mdc +312 -312
  380. package/templates/ide/cursor/.cursor/rules/skill-security.mdc +245 -245
  381. package/templates/ide/cursor/templates/BLUEPRINT-template.md +193 -193
  382. package/templates/ide/cursor/templates/DESIGN-template.md +129 -129
  383. package/templates/ide/cursor/templates/TASK-SPEC-template.md +141 -100
  384. package/templates/shared/docker-compose.yml +41 -41
  385. package/dist/__tests__/dag-runner/adapters.test.d.ts +0 -2
  386. package/dist/__tests__/dag-runner/adapters.test.d.ts.map +0 -1
  387. package/dist/__tests__/dag-runner/adapters.test.js +0 -134
  388. package/dist/__tests__/dag-runner/adapters.test.js.map +0 -1
  389. package/dist/dag-runner/adapters/antigravity.d.ts +0 -6
  390. package/dist/dag-runner/adapters/antigravity.d.ts.map +0 -1
  391. package/dist/dag-runner/adapters/antigravity.js +0 -54
  392. package/dist/dag-runner/adapters/antigravity.js.map +0 -1
  393. package/dist/dag-runner/adapters/claude.d.ts +0 -6
  394. package/dist/dag-runner/adapters/claude.d.ts.map +0 -1
  395. package/dist/dag-runner/adapters/claude.js +0 -48
  396. package/dist/dag-runner/adapters/claude.js.map +0 -1
  397. package/dist/dag-runner/adapters/cursor.d.ts +0 -6
  398. package/dist/dag-runner/adapters/cursor.d.ts.map +0 -1
  399. package/dist/dag-runner/adapters/cursor.js +0 -58
  400. package/dist/dag-runner/adapters/cursor.js.map +0 -1
  401. package/dist/dag-runner/adapters/index.d.ts +0 -46
  402. package/dist/dag-runner/adapters/index.d.ts.map +0 -1
  403. package/dist/dag-runner/adapters/index.js +0 -55
  404. package/dist/dag-runner/adapters/index.js.map +0 -1
  405. package/dist/dag-runner/utils/timeout.d.ts +0 -27
  406. package/dist/dag-runner/utils/timeout.d.ts.map +0 -1
  407. package/dist/dag-runner/utils/timeout.js +0 -55
  408. 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.
@@ -375,6 +453,104 @@ of each canonical DARE artifact, active GraphRAG backend, and task progress.
375
453
  dare info
376
454
  ```
377
455
 
456
+ ### `dare review` ← new in v2.17.0
457
+
458
+ **Anti-stub gate.** Audita os arquivos que uma task tocou e detecta padrões de "fake completeness": `TODO`/`FIXME`, stubs (`throw new Error('not implemented')`, `todo!()`, `NotImplementedError`), funções vazias, retorno-fantasma (`return null` como única statement), mocks fora de testes (`jest.fn`, `vi.mock`, `sinon.stub`, `MagicMock`), comentários-placeholder (`// implement later`).
459
+
460
+ A camada estática (regex, determinística) é só metade. A IDE agent pode rodar a skill `dare-review` / `review-task` para validar critério-a-critério se a implementação atende a spec, emitir um `SemanticVerdict` JSON, e o CLI funde os dois numa única decisão.
461
+
462
+ ```bash
463
+ # Audita os arquivos listados em DARE/EXECUTION/task-034.md
464
+ dare review task-034
465
+
466
+ # Em CI:
467
+ dare review task-034 --strict --format json
468
+
469
+ # Lista explícita de arquivos:
470
+ dare review task-034 --files src/auth/login.ts src/auth/register.ts
471
+
472
+ # Funde com verdito semântico do agente:
473
+ dare review task-034 --from-agent .dare/verdict-task-034.json
474
+ ```
475
+
476
+ **Gate opt-in no Ralph Loop:** com `review.onComplete: true` em `dare.config.json`, `dare execute --complete <id>` bloqueia DONE se a review falhar. Para projetos novos (`dare init` v2.17+) já vem ligado; projetos legados permanecem off até o dev flipar.
477
+
478
+ ### `dare refine` ← new in v2.17.0
479
+
480
+ **Anti-monstro.** Mede complexidade de uma task e, opcionalmente, propõe quebra em sub-tasks menores. Heurística determinística pesa # arquivos, # funções/endpoints, # testes, # dependências, keywords "pesadas" (refactor/migrate/integrate/multiple) — produz um score em LOW (0–5) / MED (6–12) / HIGH (13–20) / CRITICAL (21+).
481
+
482
+ ```bash
483
+ # Apenas mede e reporta:
484
+ dare refine task-034
485
+
486
+ # Mede + propõe quebra em sub-tasks (task-034a, task-034b, ...):
487
+ dare refine task-034 --split
488
+
489
+ # Anota TASKS.md marcando a task para split (o agente regenera as specs):
490
+ dare refine task-034 --split --apply
491
+
492
+ # Em CI: exit code 2 se HIGH/CRITICAL:
493
+ dare refine task-034 --strict
494
+ ```
495
+
496
+ A camada determinística agrupa arquivos por diretório raiz. A IDE agent (skills `dare-refine` / `refine-task`) refina o split semanticamente — por camada (Model/Controller/Service), por endpoint, por feature, refactor-then-feature, migration-then-code.
497
+
498
+ Thresholds configuráveis em `dare.config.json`:
499
+
500
+ ```jsonc
501
+ {
502
+ "refine": {
503
+ "thresholds": { "low": 5, "med": 12, "high": 20 }
504
+ }
505
+ }
506
+ ```
507
+
508
+ ### `dare update` ← new in v2.17.0
509
+
510
+ Sync the **project's DARE setup** (templates, slash commands, skills, schema)
511
+ with the version of the CLI currently installed. Useful when you upgrade the
512
+ CLI globally (`npm install -g @dewtech/dare-cli@latest`) and want a previous
513
+ project to pick up the new improvements — **without touching your DESIGN /
514
+ BLUEPRINT / TASKS / dare-dag.yaml artifacts**.
515
+
516
+ Different from upgrading the CLI itself: `npm update -g @dewtech/dare-cli`
517
+ changes the binary on your machine; `dare update` changes the *project files
518
+ on disk* to match what that binary now ships.
519
+
520
+ ```bash
521
+ dare update # interactive (recommended)
522
+ dare update --dry-run # preview: shows changelog + affected files, writes nothing
523
+ dare update --yes # CI: apply, preserve customizations, no prompts
524
+ dare update --force # also overwrite files the dev customized (dangerous)
525
+ dare update --target 2.17.0 # update to a specific release instead of the installed CLI
526
+ ```
527
+
528
+ **What it does:**
529
+
530
+ 1. Reads `version` from `dare.config.json` (the project's last-known DARE version).
531
+ 2. Loads `templates/UPDATE-MANIFEST.json` (ships with the CLI) and lists every
532
+ release between the project's version and the CLI's version.
533
+ 3. Prints the changelog for each pending release and the list of files
534
+ affected for your IDE (cursor / claude-code / antigravity / hybrid).
535
+ 4. For each file, classifies the situation:
536
+ - **identical** → skip
537
+ - **missing** → create
538
+ - **apply** → file matches the previous template hash, safe to overwrite
539
+ - **customized** → file diverges from the previous template; prompt
540
+ (`keep` / `replace`) unless `--yes` (keep) or `--force` (replace).
541
+ 5. Backs up every affected file to `.dare/backup-<from-version>/` before
542
+ writing.
543
+ 6. Runs any schema migrations declared by the release (e.g. renaming a
544
+ config field).
545
+ 7. Stamps `version` and `updatedAt` in `dare.config.json`.
546
+
547
+ **Adding entries when you cut a release:** each new CLI version that ships
548
+ template changes needs a corresponding entry in `templates/UPDATE-MANIFEST.json`
549
+ listing `changes` (added / modified / removed / renamed) and optional
550
+ `migrations`. The applier filters changes by `appliesTo: [ide]`, so a
551
+ template that's cursor-only won't be installed in a Claude Code project and
552
+ vice versa.
553
+
378
554
  ### `dare validate`
379
555
 
380
556
  Static checks on `dare-dag.yaml` — ideal for pre-commit hooks and CI.
@@ -522,13 +698,30 @@ npm run inspect
522
698
 
523
699
  | Type | Options |
524
700
  |------|---------|
525
- | **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 |
526
702
  | **Frontend** | React 18+ · Vue 3+ · Leptos fullstack (Rust SSR+WASM) · Leptos CSR (Rust WASM) |
527
703
  | **MCP Server** | TypeScript/Node.js · Python — stdio / SSE / HTTP Stream |
528
704
  | **IDE / Agent** | Claude Code · Cursor · Antigravity · Hybrid |
529
705
 
530
706
  ---
531
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
+
532
725
  ## O que vem com o pacote (v2.0+)
533
726
 
534
727
  A partir da v2.0 o `@dewtech/dare-cli` é um **pacote único** que inclui todas as
@@ -542,7 +735,7 @@ Isso já dá:
542
735
 
543
736
  | Componente | O que é |
544
737
  |------------|---------|
545
- | CLI `dare` | `init`, `design`, `blueprint`, `execute`, `discover` |
738
+ | CLI `dare` | `init`, `design`, `blueprint`, `execute`, `discover`, `reverse`, `dna`, `migrate` |
546
739
  | CLI `dare-mcp-server` | Servidor MCP local de contexto (~95% economia de tokens) |
547
740
  | Engine GraphRAG | Grafo de conhecimento com SQLite + FTS5 |
548
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":"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,gBAAgB,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEtF,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,UAAU,CAAC,CAAC,CAAC;IACjE,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,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,sBAAsB,EAAE,+HAA+H;SACxJ,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAE,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,yBAAyB;QAC1F,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAE,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,oBAAoB,EAAE,8HAA8H;SACrJ,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAE,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7E,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QAC7E,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,eAAe,EAAE,yEAAyE;YAC1F,gBAAgB,EAAE,+BAA+B;SAClD,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,sBAAsB,EAAE,gFAAgF;SACzG,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,EAAE,0BAA0B,CAAC,CAAC;QACrD,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAClC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,EAAE,UAAU,EAAE,uBAAuB,EAAE,CAAC,CAAC;QACxE,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;QACrE,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAE/E,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,gBAAgB,EAAE,wJAAwJ;YAC1K,oBAAoB,EAAE,2EAA2E;YACjG,kBAAkB,EAAE,qEAAqE;SAC1F,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,sBAAsB;QAC3D,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,8BAA8B;QACnE,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,+BAA+B;QACnE,MAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAE,CAAC;QAC/D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,QAAQ,EAAE,+GAA+G;YACzH,SAAS,EAAE,gDAAgD;YAC3D,SAAS,EAAE,wCAAwC;YACnD,WAAW,EAAE,6DAA6D;YAC1E,kBAAkB,EAAE,yEAAyE;SAC9F,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,8BAA8B;QACvE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,oCAAoC;QAC7E,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,4BAA4B;QACpE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,uBAAuB;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,+BAA+B;QACvE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,gBAAgB;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uDAAuD,EAAE,GAAG,EAAE;IACrE,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,gBAAgB,EAAE,kDAAkD;YACpE,iBAAiB,EAAE,2DAA2D;SAC/E,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAE,CAAC;QACvD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7D,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAE,CAAC;QACxD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -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":"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"}
@@ -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":""}