@dewtech/dare-cli 3.0.0 → 3.2.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 (527) hide show
  1. package/README.md +47 -39
  2. package/dist/__tests__/ensure-skills.test.d.ts +2 -0
  3. package/dist/__tests__/ensure-skills.test.d.ts.map +1 -0
  4. package/dist/__tests__/ensure-skills.test.js +67 -0
  5. package/dist/__tests__/ensure-skills.test.js.map +1 -0
  6. package/dist/__tests__/ide-command-parity.test.d.ts +2 -0
  7. package/dist/__tests__/ide-command-parity.test.d.ts.map +1 -0
  8. package/dist/__tests__/ide-command-parity.test.js +58 -0
  9. package/dist/__tests__/ide-command-parity.test.js.map +1 -0
  10. package/dist/__tests__/reverse-collection.test.d.ts +2 -0
  11. package/dist/__tests__/reverse-collection.test.d.ts.map +1 -0
  12. package/dist/__tests__/reverse-collection.test.js +87 -0
  13. package/dist/__tests__/reverse-collection.test.js.map +1 -0
  14. package/dist/bin/dare.js +1 -3
  15. package/dist/bin/dare.js.map +1 -1
  16. package/dist/commands/__tests__/init.integration.spec.d.ts +2 -0
  17. package/dist/commands/__tests__/init.integration.spec.d.ts.map +1 -0
  18. package/dist/commands/__tests__/init.integration.spec.js +134 -0
  19. package/dist/commands/__tests__/init.integration.spec.js.map +1 -0
  20. package/dist/commands/dna.d.ts.map +1 -1
  21. package/dist/commands/dna.js +4 -0
  22. package/dist/commands/dna.js.map +1 -1
  23. package/dist/commands/init.d.ts.map +1 -1
  24. package/dist/commands/init.js +84 -1
  25. package/dist/commands/init.js.map +1 -1
  26. package/dist/commands/migrate.d.ts.map +1 -1
  27. package/dist/commands/migrate.js +4 -0
  28. package/dist/commands/migrate.js.map +1 -1
  29. package/dist/commands/new.d.ts.map +1 -1
  30. package/dist/commands/new.js +2 -1
  31. package/dist/commands/new.js.map +1 -1
  32. package/dist/commands/reverse.d.ts.map +1 -1
  33. package/dist/commands/reverse.js +27 -8
  34. package/dist/commands/reverse.js.map +1 -1
  35. package/dist/mcp-server/bin/server.js +0 -0
  36. package/dist/stacks/__tests__/dna-emitter.spec.d.ts +2 -0
  37. package/dist/stacks/__tests__/dna-emitter.spec.d.ts.map +1 -0
  38. package/dist/stacks/__tests__/dna-emitter.spec.js +207 -0
  39. package/dist/stacks/__tests__/dna-emitter.spec.js.map +1 -0
  40. package/dist/stacks/__tests__/dna.spec.d.ts +2 -0
  41. package/dist/stacks/__tests__/dna.spec.d.ts.map +1 -0
  42. package/dist/stacks/__tests__/dna.spec.js +211 -0
  43. package/dist/stacks/__tests__/dna.spec.js.map +1 -0
  44. package/dist/stacks/__tests__/parity-rails.fixture.json +228 -0
  45. package/dist/stacks/__tests__/parity-rails.spec.d.ts +2 -0
  46. package/dist/stacks/__tests__/parity-rails.spec.d.ts.map +1 -0
  47. package/dist/stacks/__tests__/parity-rails.spec.js +99 -0
  48. package/dist/stacks/__tests__/parity-rails.spec.js.map +1 -0
  49. package/dist/stacks/__tests__/registry.spec.d.ts +2 -0
  50. package/dist/stacks/__tests__/registry.spec.d.ts.map +1 -0
  51. package/dist/stacks/__tests__/registry.spec.js +101 -0
  52. package/dist/stacks/__tests__/registry.spec.js.map +1 -0
  53. package/dist/stacks/__tests__/template-engine.spec.d.ts +2 -0
  54. package/dist/stacks/__tests__/template-engine.spec.d.ts.map +1 -0
  55. package/dist/stacks/__tests__/template-engine.spec.js +149 -0
  56. package/dist/stacks/__tests__/template-engine.spec.js.map +1 -0
  57. package/dist/stacks/dna-emitter.d.ts +45 -0
  58. package/dist/stacks/dna-emitter.d.ts.map +1 -0
  59. package/dist/stacks/dna-emitter.js +267 -0
  60. package/dist/stacks/dna-emitter.js.map +1 -0
  61. package/dist/stacks/go-gin/__tests__/scaffold.spec.d.ts +2 -0
  62. package/dist/stacks/go-gin/__tests__/scaffold.spec.d.ts.map +1 -0
  63. package/dist/stacks/go-gin/__tests__/scaffold.spec.js +221 -0
  64. package/dist/stacks/go-gin/__tests__/scaffold.spec.js.map +1 -0
  65. package/dist/stacks/go-gin/scaffold.d.ts +3 -0
  66. package/dist/stacks/go-gin/scaffold.d.ts.map +1 -0
  67. package/dist/stacks/go-gin/scaffold.js +105 -0
  68. package/dist/stacks/go-gin/scaffold.js.map +1 -0
  69. package/dist/stacks/go-stdlib/__tests__/scaffold.spec.d.ts +2 -0
  70. package/dist/stacks/go-stdlib/__tests__/scaffold.spec.d.ts.map +1 -0
  71. package/dist/stacks/go-stdlib/__tests__/scaffold.spec.js +215 -0
  72. package/dist/stacks/go-stdlib/__tests__/scaffold.spec.js.map +1 -0
  73. package/dist/stacks/go-stdlib/scaffold.d.ts +3 -0
  74. package/dist/stacks/go-stdlib/scaffold.d.ts.map +1 -0
  75. package/dist/stacks/go-stdlib/scaffold.js +106 -0
  76. package/dist/stacks/go-stdlib/scaffold.js.map +1 -0
  77. package/dist/stacks/mcp-go/__tests__/scaffold.spec.d.ts +2 -0
  78. package/dist/stacks/mcp-go/__tests__/scaffold.spec.d.ts.map +1 -0
  79. package/dist/stacks/mcp-go/__tests__/scaffold.spec.js +203 -0
  80. package/dist/stacks/mcp-go/__tests__/scaffold.spec.js.map +1 -0
  81. package/dist/stacks/mcp-go/scaffold.d.ts +3 -0
  82. package/dist/stacks/mcp-go/scaffold.d.ts.map +1 -0
  83. package/dist/stacks/mcp-go/scaffold.js +94 -0
  84. package/dist/stacks/mcp-go/scaffold.js.map +1 -0
  85. package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.d.ts +2 -0
  86. package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.d.ts.map +1 -0
  87. package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.js +236 -0
  88. package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.js.map +1 -0
  89. package/dist/stacks/mcp-node-ts/scaffold.d.ts +3 -0
  90. package/dist/stacks/mcp-node-ts/scaffold.d.ts.map +1 -0
  91. package/dist/stacks/mcp-node-ts/scaffold.js +95 -0
  92. package/dist/stacks/mcp-node-ts/scaffold.js.map +1 -0
  93. package/dist/stacks/mcp-python/__tests__/scaffold.spec.d.ts +2 -0
  94. package/dist/stacks/mcp-python/__tests__/scaffold.spec.d.ts.map +1 -0
  95. package/dist/stacks/mcp-python/__tests__/scaffold.spec.js +228 -0
  96. package/dist/stacks/mcp-python/__tests__/scaffold.spec.js.map +1 -0
  97. package/dist/stacks/mcp-python/scaffold.d.ts +3 -0
  98. package/dist/stacks/mcp-python/scaffold.d.ts.map +1 -0
  99. package/dist/stacks/mcp-python/scaffold.js +98 -0
  100. package/dist/stacks/mcp-python/scaffold.js.map +1 -0
  101. package/dist/stacks/mcp-rust/__tests__/scaffold.spec.d.ts +2 -0
  102. package/dist/stacks/mcp-rust/__tests__/scaffold.spec.d.ts.map +1 -0
  103. package/dist/stacks/mcp-rust/__tests__/scaffold.spec.js +213 -0
  104. package/dist/stacks/mcp-rust/__tests__/scaffold.spec.js.map +1 -0
  105. package/dist/stacks/mcp-rust/scaffold.d.ts +3 -0
  106. package/dist/stacks/mcp-rust/scaffold.d.ts.map +1 -0
  107. package/dist/stacks/mcp-rust/scaffold.js +98 -0
  108. package/dist/stacks/mcp-rust/scaffold.js.map +1 -0
  109. package/dist/stacks/node-nestjs/__tests__/scaffold.spec.d.ts +2 -0
  110. package/dist/stacks/node-nestjs/__tests__/scaffold.spec.d.ts.map +1 -0
  111. package/dist/stacks/node-nestjs/__tests__/scaffold.spec.js +172 -0
  112. package/dist/stacks/node-nestjs/__tests__/scaffold.spec.js.map +1 -0
  113. package/dist/stacks/node-nestjs/scaffold.d.ts +3 -0
  114. package/dist/stacks/node-nestjs/scaffold.d.ts.map +1 -0
  115. package/dist/stacks/node-nestjs/scaffold.js +117 -0
  116. package/dist/stacks/node-nestjs/scaffold.js.map +1 -0
  117. package/dist/stacks/php-laravel/__tests__/scaffold.spec.d.ts +2 -0
  118. package/dist/stacks/php-laravel/__tests__/scaffold.spec.d.ts.map +1 -0
  119. package/dist/stacks/php-laravel/__tests__/scaffold.spec.js +205 -0
  120. package/dist/stacks/php-laravel/__tests__/scaffold.spec.js.map +1 -0
  121. package/dist/stacks/php-laravel/scaffold.d.ts +3 -0
  122. package/dist/stacks/php-laravel/scaffold.d.ts.map +1 -0
  123. package/dist/stacks/php-laravel/scaffold.js +109 -0
  124. package/dist/stacks/php-laravel/scaffold.js.map +1 -0
  125. package/dist/stacks/python-fastapi/__tests__/scaffold.spec.d.ts +2 -0
  126. package/dist/stacks/python-fastapi/__tests__/scaffold.spec.d.ts.map +1 -0
  127. package/dist/stacks/python-fastapi/__tests__/scaffold.spec.js +168 -0
  128. package/dist/stacks/python-fastapi/__tests__/scaffold.spec.js.map +1 -0
  129. package/dist/stacks/python-fastapi/scaffold.d.ts +3 -0
  130. package/dist/stacks/python-fastapi/scaffold.d.ts.map +1 -0
  131. package/dist/stacks/python-fastapi/scaffold.js +108 -0
  132. package/dist/stacks/python-fastapi/scaffold.js.map +1 -0
  133. package/dist/stacks/registry.d.ts +38 -0
  134. package/dist/stacks/registry.d.ts.map +1 -0
  135. package/dist/stacks/registry.js +153 -0
  136. package/dist/stacks/registry.js.map +1 -0
  137. package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.d.ts +6 -0
  138. package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.d.ts.map +1 -0
  139. package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.js +604 -0
  140. package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.js.map +1 -0
  141. package/dist/stacks/ruby-rails-8/scaffold.d.ts +91 -0
  142. package/dist/stacks/ruby-rails-8/scaffold.d.ts.map +1 -0
  143. package/dist/stacks/ruby-rails-8/scaffold.js +410 -0
  144. package/dist/stacks/ruby-rails-8/scaffold.js.map +1 -0
  145. package/dist/stacks/rust-axum/__tests__/scaffold.spec.d.ts +2 -0
  146. package/dist/stacks/rust-axum/__tests__/scaffold.spec.d.ts.map +1 -0
  147. package/dist/stacks/rust-axum/__tests__/scaffold.spec.js +203 -0
  148. package/dist/stacks/rust-axum/__tests__/scaffold.spec.js.map +1 -0
  149. package/dist/stacks/rust-axum/scaffold.d.ts +3 -0
  150. package/dist/stacks/rust-axum/scaffold.d.ts.map +1 -0
  151. package/dist/stacks/rust-axum/scaffold.js +105 -0
  152. package/dist/stacks/rust-axum/scaffold.js.map +1 -0
  153. package/dist/stacks/template-engine.d.ts +38 -0
  154. package/dist/stacks/template-engine.d.ts.map +1 -0
  155. package/dist/stacks/template-engine.js +134 -0
  156. package/dist/stacks/template-engine.js.map +1 -0
  157. package/dist/stacks/types.d.ts +69 -0
  158. package/dist/stacks/types.d.ts.map +1 -0
  159. package/dist/stacks/types.js +29 -0
  160. package/dist/stacks/types.js.map +1 -0
  161. package/dist/utils/datamodel.d.ts.map +1 -1
  162. package/dist/utils/datamodel.js +97 -20
  163. package/dist/utils/datamodel.js.map +1 -1
  164. package/dist/utils/project-generator.d.ts +22 -1
  165. package/dist/utils/project-generator.d.ts.map +1 -1
  166. package/dist/utils/project-generator.js +85 -7
  167. package/dist/utils/project-generator.js.map +1 -1
  168. package/dist/utils/reverse-facts.d.ts +3 -2
  169. package/dist/utils/reverse-facts.d.ts.map +1 -1
  170. package/dist/utils/reverse-facts.js +89 -8
  171. package/dist/utils/reverse-facts.js.map +1 -1
  172. package/dist/utils/stack-bootstrap.d.ts +3 -2
  173. package/dist/utils/stack-bootstrap.d.ts.map +1 -1
  174. package/dist/utils/stack-bootstrap.js +46 -16
  175. package/dist/utils/stack-bootstrap.js.map +1 -1
  176. package/package.json +91 -87
  177. package/templates/ide/antigravity/.agents/skills/dare-bootstrap/SKILL.md +32 -0
  178. package/templates/ide/antigravity/.agents/skills/dare-dag/SKILL.md +32 -0
  179. package/templates/ide/antigravity/.agents/skills/dare-discover/SKILL.md +33 -0
  180. package/templates/ide/antigravity/.agents/skills/dare-graph/SKILL.md +35 -0
  181. package/templates/ide/antigravity/.agents/skills/dare-info/SKILL.md +31 -0
  182. package/templates/ide/antigravity/.agents/skills/dare-init/SKILL.md +35 -0
  183. package/templates/ide/antigravity/.agents/skills/dare-skill/SKILL.md +35 -0
  184. package/templates/ide/antigravity/.agents/skills/dare-update/SKILL.md +33 -0
  185. package/templates/ide/antigravity/.agents/skills/dare-validate/SKILL.md +33 -0
  186. package/templates/ide/antigravity/.agents/skills/dare-welcome/SKILL.md +30 -0
  187. package/templates/ide/claude/.claude/commands/dare-bootstrap.md +27 -0
  188. package/templates/ide/claude/.claude/commands/dare-dag.md +27 -0
  189. package/templates/ide/claude/.claude/commands/dare-discover.md +28 -0
  190. package/templates/ide/claude/.claude/commands/dare-graph.md +30 -0
  191. package/templates/ide/claude/.claude/commands/dare-info.md +26 -0
  192. package/templates/ide/claude/.claude/commands/dare-init.md +30 -0
  193. package/templates/ide/claude/.claude/commands/dare-skill.md +30 -0
  194. package/templates/ide/claude/.claude/commands/dare-update.md +28 -0
  195. package/templates/ide/claude/.claude/commands/dare-validate.md +28 -0
  196. package/templates/ide/claude/.claude/commands/dare-welcome.md +25 -0
  197. package/templates/ide/cursor/.cursor/commands/{generate-blueprint.md → dare-blueprint.md} +1 -1
  198. package/templates/ide/cursor/.cursor/commands/dare-bootstrap.md +27 -0
  199. package/templates/ide/cursor/.cursor/commands/{run-dag.md → dare-dag-run.md} +1 -1
  200. package/templates/ide/cursor/.cursor/commands/{dag-viz.md → dare-dag-viz.md} +1 -1
  201. package/templates/ide/cursor/.cursor/commands/dare-dag.md +27 -0
  202. package/templates/ide/cursor/.cursor/commands/{generate-design.md → dare-design.md} +1 -1
  203. package/templates/ide/cursor/.cursor/commands/dare-discover.md +28 -0
  204. package/templates/ide/cursor/.cursor/commands/dare-dna.md +75 -0
  205. package/templates/ide/cursor/.cursor/commands/{generate-docker-compose.md → dare-docker-compose.md} +1 -1
  206. package/templates/ide/cursor/.cursor/commands/{generate-dockerfile.md → dare-dockerfile.md} +1 -1
  207. package/templates/ide/cursor/.cursor/commands/{execute-task.md → dare-execute.md} +1 -1
  208. package/templates/ide/cursor/.cursor/commands/dare-graph.md +30 -0
  209. package/templates/ide/cursor/.cursor/commands/dare-info.md +26 -0
  210. package/templates/ide/cursor/.cursor/commands/dare-init.md +30 -0
  211. package/templates/ide/cursor/.cursor/commands/dare-migrate.md +72 -0
  212. package/templates/ide/cursor/.cursor/commands/{refine-task.md → dare-refine.md} +1 -1
  213. package/templates/ide/cursor/.cursor/commands/dare-reverse.md +139 -0
  214. package/templates/ide/cursor/.cursor/commands/{review-task.md → dare-review.md} +1 -1
  215. package/templates/ide/cursor/.cursor/commands/dare-skill.md +30 -0
  216. package/templates/ide/cursor/.cursor/commands/{generate-tasks.md → dare-tasks.md} +1 -1
  217. package/templates/ide/cursor/.cursor/commands/{telemetry-report.md → dare-telemetry.md} +1 -1
  218. package/templates/ide/cursor/.cursor/commands/dare-update.md +28 -0
  219. package/templates/ide/cursor/.cursor/commands/dare-validate.md +28 -0
  220. package/templates/ide/cursor/.cursor/commands/dare-welcome.md +25 -0
  221. package/templates/stacks/go-gin/.dare/skills.yml +11 -0
  222. package/templates/stacks/go-gin/.env.example +24 -0
  223. package/templates/stacks/go-gin/.github/workflows/dare-ci.yml +42 -0
  224. package/templates/stacks/go-gin/README.md.tpl +38 -0
  225. package/templates/stacks/go-gin/cmd/server/main.go.tpl +78 -0
  226. package/templates/stacks/go-gin/db/migrations/0001_create_users.down.sql +2 -0
  227. package/templates/stacks/go-gin/db/migrations/0001_create_users.up.sql +12 -0
  228. package/templates/stacks/go-gin/db/queries/users.sql +23 -0
  229. package/templates/stacks/go-gin/gitignore +7 -0
  230. package/templates/stacks/go-gin/go.mod.tpl +17 -0
  231. package/templates/stacks/go-gin/internal/config/config.go +41 -0
  232. package/templates/stacks/go-gin/internal/db/postgres.go.tpl +25 -0
  233. package/templates/stacks/go-gin/internal/handler/auth_handler.go.tpl +72 -0
  234. package/templates/stacks/go-gin/internal/handler/users_handler.go.tpl +72 -0
  235. package/templates/stacks/go-gin/internal/handler/ws_handler.go +37 -0
  236. package/templates/stacks/go-gin/internal/llm/dummy.go +14 -0
  237. package/templates/stacks/go-gin/internal/llm/provider.go +8 -0
  238. package/templates/stacks/go-gin/internal/middleware/jwt.go.tpl +58 -0
  239. package/templates/stacks/go-gin/internal/middleware/rate_limit.go +55 -0
  240. package/templates/stacks/go-gin/internal/model/user.go +17 -0
  241. package/templates/stacks/go-gin/internal/repository/users_repository.go.tpl +79 -0
  242. package/templates/stacks/go-gin/internal/service/auth_service.go.tpl +55 -0
  243. package/templates/stacks/go-gin/internal/service/users_service.go.tpl +53 -0
  244. package/templates/stacks/go-gin/llms.txt.tpl +54 -0
  245. package/templates/stacks/go-gin/openapi.json.tpl +46 -0
  246. package/templates/stacks/go-gin/sqlc.yaml +14 -0
  247. package/templates/stacks/go-gin/tests/smoke_test.go.tpl +22 -0
  248. package/templates/stacks/go-stdlib/.dare/skills.yml +11 -0
  249. package/templates/stacks/go-stdlib/.env.example +24 -0
  250. package/templates/stacks/go-stdlib/.github/workflows/dare-ci.yml +42 -0
  251. package/templates/stacks/go-stdlib/README.md.tpl +41 -0
  252. package/templates/stacks/go-stdlib/cmd/server/main.go.tpl +82 -0
  253. package/templates/stacks/go-stdlib/db/migrations/0001_create_users.down.sql +2 -0
  254. package/templates/stacks/go-stdlib/db/migrations/0001_create_users.up.sql +12 -0
  255. package/templates/stacks/go-stdlib/db/queries/users.sql +23 -0
  256. package/templates/stacks/go-stdlib/gitignore +6 -0
  257. package/templates/stacks/go-stdlib/go.mod.tpl +15 -0
  258. package/templates/stacks/go-stdlib/internal/config/config.go +41 -0
  259. package/templates/stacks/go-stdlib/internal/db/postgres.go.tpl +24 -0
  260. package/templates/stacks/go-stdlib/internal/handler/auth_handler.go.tpl +71 -0
  261. package/templates/stacks/go-stdlib/internal/handler/users_handler.go.tpl +84 -0
  262. package/templates/stacks/go-stdlib/internal/handler/ws_handler.go +36 -0
  263. package/templates/stacks/go-stdlib/internal/httpx/json.go +32 -0
  264. package/templates/stacks/go-stdlib/internal/llm/dummy.go +14 -0
  265. package/templates/stacks/go-stdlib/internal/llm/provider.go +8 -0
  266. package/templates/stacks/go-stdlib/internal/middleware/chain.go +21 -0
  267. package/templates/stacks/go-stdlib/internal/middleware/cors.go +27 -0
  268. package/templates/stacks/go-stdlib/internal/middleware/jwt.go.tpl +51 -0
  269. package/templates/stacks/go-stdlib/internal/middleware/rate_limit.go +81 -0
  270. package/templates/stacks/go-stdlib/internal/model/user.go +17 -0
  271. package/templates/stacks/go-stdlib/internal/repository/users_repository.go.tpl +75 -0
  272. package/templates/stacks/go-stdlib/internal/service/auth_service.go.tpl +55 -0
  273. package/templates/stacks/go-stdlib/internal/service/users_service.go.tpl +53 -0
  274. package/templates/stacks/go-stdlib/llms.txt.tpl +60 -0
  275. package/templates/stacks/go-stdlib/openapi.json.tpl +46 -0
  276. package/templates/stacks/go-stdlib/sqlc.yaml +14 -0
  277. package/templates/stacks/go-stdlib/tests/smoke_test.go.tpl +45 -0
  278. package/templates/stacks/mcp-go/.dare/skills.yml +8 -0
  279. package/templates/stacks/mcp-go/.env.example +14 -0
  280. package/templates/stacks/mcp-go/.github/workflows/dare-ci.yml +42 -0
  281. package/templates/stacks/mcp-go/README.md.tpl +50 -0
  282. package/templates/stacks/mcp-go/cmd/server/main.go.tpl +62 -0
  283. package/templates/stacks/mcp-go/gitignore +6 -0
  284. package/templates/stacks/mcp-go/go.mod.tpl +9 -0
  285. package/templates/stacks/mcp-go/internal/prompts/summarize.go +9 -0
  286. package/templates/stacks/mcp-go/internal/server/server.go.tpl +80 -0
  287. package/templates/stacks/mcp-go/internal/tools/echo.go +15 -0
  288. package/templates/stacks/mcp-go/internal/transports/http.go.tpl +21 -0
  289. package/templates/stacks/mcp-go/internal/transports/sse.go.tpl +17 -0
  290. package/templates/stacks/mcp-go/internal/transports/stdio.go.tpl +14 -0
  291. package/templates/stacks/mcp-go/llms.txt.tpl +60 -0
  292. package/templates/stacks/mcp-go/openapi.json.tpl +31 -0
  293. package/templates/stacks/mcp-go/tests/echo_test.go.tpl +37 -0
  294. package/templates/stacks/mcp-node-ts/.dare/skills.yml +8 -0
  295. package/templates/stacks/mcp-node-ts/.env.example +16 -0
  296. package/templates/stacks/mcp-node-ts/.github/workflows/dare-ci.yml +54 -0
  297. package/templates/stacks/mcp-node-ts/README.md.hbs +49 -0
  298. package/templates/stacks/mcp-node-ts/gitignore +7 -0
  299. package/templates/stacks/mcp-node-ts/llms.txt.hbs +61 -0
  300. package/templates/stacks/mcp-node-ts/openapi.json.hbs +39 -0
  301. package/templates/stacks/mcp-node-ts/package.json.hbs +35 -0
  302. package/templates/stacks/mcp-node-ts/src/cli.ts.hbs +71 -0
  303. package/templates/stacks/mcp-node-ts/src/prompts/index.ts +36 -0
  304. package/templates/stacks/mcp-node-ts/src/server.ts.hbs +45 -0
  305. package/templates/stacks/mcp-node-ts/src/tools/echo.ts +23 -0
  306. package/templates/stacks/mcp-node-ts/src/tools/index.ts +18 -0
  307. package/templates/stacks/mcp-node-ts/src/transports/http.ts +68 -0
  308. package/templates/stacks/mcp-node-ts/src/transports/sse.ts +58 -0
  309. package/templates/stacks/mcp-node-ts/src/transports/stdio.ts +5 -0
  310. package/templates/stacks/mcp-node-ts/tests/echo.test.ts +50 -0
  311. package/templates/stacks/mcp-node-ts/tsconfig.json +17 -0
  312. package/templates/stacks/mcp-python/.dare/skills.yml +8 -0
  313. package/templates/stacks/mcp-python/.env.example +14 -0
  314. package/templates/stacks/mcp-python/.github/workflows/dare-ci.yml +42 -0
  315. package/templates/stacks/mcp-python/README.md.j2 +49 -0
  316. package/templates/stacks/mcp-python/gitignore +12 -0
  317. package/templates/stacks/mcp-python/llms.txt.j2 +56 -0
  318. package/templates/stacks/mcp-python/openapi.json.j2 +33 -0
  319. package/templates/stacks/mcp-python/pyproject.toml.j2 +37 -0
  320. package/templates/stacks/mcp-python/src/__init__.py +0 -0
  321. package/templates/stacks/mcp-python/src/cli.py.j2 +68 -0
  322. package/templates/stacks/mcp-python/src/prompts/__init__.py +0 -0
  323. package/templates/stacks/mcp-python/src/prompts/summarize.py +10 -0
  324. package/templates/stacks/mcp-python/src/server.py.j2 +28 -0
  325. package/templates/stacks/mcp-python/src/tools/__init__.py +0 -0
  326. package/templates/stacks/mcp-python/src/tools/echo.py +12 -0
  327. package/templates/stacks/mcp-python/src/transports/__init__.py +0 -0
  328. package/templates/stacks/mcp-python/src/transports/http.py +12 -0
  329. package/templates/stacks/mcp-python/src/transports/sse.py +13 -0
  330. package/templates/stacks/mcp-python/src/transports/stdio.py +6 -0
  331. package/templates/stacks/mcp-python/tests/__init__.py +0 -0
  332. package/templates/stacks/mcp-python/tests/test_echo.py +28 -0
  333. package/templates/stacks/mcp-rust/.dare/skills.yml +8 -0
  334. package/templates/stacks/mcp-rust/.env.example +14 -0
  335. package/templates/stacks/mcp-rust/.github/workflows/dare-ci.yml +38 -0
  336. package/templates/stacks/mcp-rust/Cargo.toml.tera +35 -0
  337. package/templates/stacks/mcp-rust/README.md.tera +50 -0
  338. package/templates/stacks/mcp-rust/gitignore +5 -0
  339. package/templates/stacks/mcp-rust/llms.txt.tera +60 -0
  340. package/templates/stacks/mcp-rust/openapi.json.tera +31 -0
  341. package/templates/stacks/mcp-rust/src/cli.rs.tera +33 -0
  342. package/templates/stacks/mcp-rust/src/lib.rs +6 -0
  343. package/templates/stacks/mcp-rust/src/main.rs.tera +30 -0
  344. package/templates/stacks/mcp-rust/src/prompts/mod.rs +1 -0
  345. package/templates/stacks/mcp-rust/src/prompts/summarize.rs +5 -0
  346. package/templates/stacks/mcp-rust/src/server.rs.tera +38 -0
  347. package/templates/stacks/mcp-rust/src/tools/echo.rs +18 -0
  348. package/templates/stacks/mcp-rust/src/tools/mod.rs +22 -0
  349. package/templates/stacks/mcp-rust/src/transports/http.rs +27 -0
  350. package/templates/stacks/mcp-rust/src/transports/mod.rs +3 -0
  351. package/templates/stacks/mcp-rust/src/transports/sse.rs +33 -0
  352. package/templates/stacks/mcp-rust/src/transports/stdio.rs +14 -0
  353. package/templates/stacks/mcp-rust/tests/echo_test.rs.tera +27 -0
  354. package/templates/stacks/node-nestjs/.dare/skills.yml +11 -0
  355. package/templates/stacks/node-nestjs/.env.example +21 -0
  356. package/templates/stacks/node-nestjs/.github/workflows/dare-ci.yml +54 -0
  357. package/templates/stacks/node-nestjs/README.md.hbs +35 -0
  358. package/templates/stacks/node-nestjs/gitignore +7 -0
  359. package/templates/stacks/node-nestjs/llms.txt.hbs +47 -0
  360. package/templates/stacks/node-nestjs/nest-cli.json +16 -0
  361. package/templates/stacks/node-nestjs/openapi.json.hbs +75 -0
  362. package/templates/stacks/node-nestjs/package.json.hbs +57 -0
  363. package/templates/stacks/node-nestjs/prisma/schema.prisma +25 -0
  364. package/templates/stacks/node-nestjs/prisma/seed.ts.hbs +25 -0
  365. package/templates/stacks/node-nestjs/src/app.module.ts +39 -0
  366. package/templates/stacks/node-nestjs/src/auth/auth.controller.ts +29 -0
  367. package/templates/stacks/node-nestjs/src/auth/auth.module.ts +25 -0
  368. package/templates/stacks/node-nestjs/src/auth/auth.service.ts +36 -0
  369. package/templates/stacks/node-nestjs/src/auth/dto/login-response.dto.ts +9 -0
  370. package/templates/stacks/node-nestjs/src/auth/dto/login.dto.ts +17 -0
  371. package/templates/stacks/node-nestjs/src/auth/jwt.strategy.ts +25 -0
  372. package/templates/stacks/node-nestjs/src/common/filters/problem-details.filter.ts +38 -0
  373. package/templates/stacks/node-nestjs/src/common/interceptors/json-response.interceptor.ts +13 -0
  374. package/templates/stacks/node-nestjs/src/main.ts.hbs +44 -0
  375. package/templates/stacks/node-nestjs/src/prisma/prisma.module.ts +9 -0
  376. package/templates/stacks/node-nestjs/src/prisma/prisma.service.ts +9 -0
  377. package/templates/stacks/node-nestjs/src/users/dto/create-user.dto.ts +22 -0
  378. package/templates/stacks/node-nestjs/src/users/dto/user.dto.ts +15 -0
  379. package/templates/stacks/node-nestjs/src/users/users.controller.ts +41 -0
  380. package/templates/stacks/node-nestjs/src/users/users.module.ts +11 -0
  381. package/templates/stacks/node-nestjs/src/users/users.repository.ts +38 -0
  382. package/templates/stacks/node-nestjs/src/users/users.service.ts +38 -0
  383. package/templates/stacks/node-nestjs/tsconfig.build.json +4 -0
  384. package/templates/stacks/node-nestjs/tsconfig.json +28 -0
  385. package/templates/stacks/php-laravel/.dare/skills.yml +11 -0
  386. package/templates/stacks/php-laravel/.env.example +41 -0
  387. package/templates/stacks/php-laravel/.github/workflows/dare-ci.yml +43 -0
  388. package/templates/stacks/php-laravel/README.md.hbs +36 -0
  389. package/templates/stacks/php-laravel/app/Http/Controllers/Api/AuthController.php +36 -0
  390. package/templates/stacks/php-laravel/app/Http/Controllers/Api/UsersController.php +33 -0
  391. package/templates/stacks/php-laravel/app/Http/Requests/CreateUserRequest.php +26 -0
  392. package/templates/stacks/php-laravel/app/Http/Requests/LoginRequest.php +34 -0
  393. package/templates/stacks/php-laravel/app/Llm/Contracts/LlmProvider.php +12 -0
  394. package/templates/stacks/php-laravel/app/Llm/Providers/DummyProvider.php +13 -0
  395. package/templates/stacks/php-laravel/app/Llm/Providers/OpenAiProvider.php +33 -0
  396. package/templates/stacks/php-laravel/app/Models/User.php +44 -0
  397. package/templates/stacks/php-laravel/app/Repositories/UsersRepository.php +32 -0
  398. package/templates/stacks/php-laravel/app/Services/AuthService.php +37 -0
  399. package/templates/stacks/php-laravel/app/Services/UsersService.php +57 -0
  400. package/templates/stacks/php-laravel/artisan +12 -0
  401. package/templates/stacks/php-laravel/bootstrap/app.php +29 -0
  402. package/templates/stacks/php-laravel/bootstrap/providers.php +5 -0
  403. package/templates/stacks/php-laravel/composer.json.hbs +58 -0
  404. package/templates/stacks/php-laravel/config/l5-swagger.php +41 -0
  405. package/templates/stacks/php-laravel/config/reverb.php +34 -0
  406. package/templates/stacks/php-laravel/config/sanctum.php +15 -0
  407. package/templates/stacks/php-laravel/database/migrations/2026_06_01_000001_create_users_table.php +27 -0
  408. package/templates/stacks/php-laravel/database/seeders/DatabaseSeeder.php +21 -0
  409. package/templates/stacks/php-laravel/gitignore +23 -0
  410. package/templates/stacks/php-laravel/llms.txt.hbs +53 -0
  411. package/templates/stacks/php-laravel/openapi.json.hbs +43 -0
  412. package/templates/stacks/php-laravel/phpstan.neon +9 -0
  413. package/templates/stacks/php-laravel/routes/api.php +13 -0
  414. package/templates/stacks/php-laravel/routes/channels.php +7 -0
  415. package/templates/stacks/php-laravel/tests/Feature/AuthTest.php +35 -0
  416. package/templates/stacks/php-laravel/tests/Feature/UsersTest.php +30 -0
  417. package/templates/stacks/php-laravel/tests/Pest.php +5 -0
  418. package/templates/stacks/python-fastapi/.dare/skills.yml +11 -0
  419. package/templates/stacks/python-fastapi/.env.example +21 -0
  420. package/templates/stacks/python-fastapi/.github/workflows/dare-ci.yml +43 -0
  421. package/templates/stacks/python-fastapi/README.md.j2 +35 -0
  422. package/templates/stacks/python-fastapi/alembic/env.py +46 -0
  423. package/templates/stacks/python-fastapi/alembic/script.py.mako +26 -0
  424. package/templates/stacks/python-fastapi/alembic/versions/0001_create_users.py.j2 +37 -0
  425. package/templates/stacks/python-fastapi/alembic.ini.j2 +39 -0
  426. package/templates/stacks/python-fastapi/app/__init__.py +0 -0
  427. package/templates/stacks/python-fastapi/app/core/__init__.py +0 -0
  428. package/templates/stacks/python-fastapi/app/core/config.py +24 -0
  429. package/templates/stacks/python-fastapi/app/core/security.py +34 -0
  430. package/templates/stacks/python-fastapi/app/db/__init__.py +0 -0
  431. package/templates/stacks/python-fastapi/app/db/session.py +22 -0
  432. package/templates/stacks/python-fastapi/app/main.py.j2 +36 -0
  433. package/templates/stacks/python-fastapi/app/models/__init__.py +3 -0
  434. package/templates/stacks/python-fastapi/app/models/user.py +30 -0
  435. package/templates/stacks/python-fastapi/app/repositories/__init__.py +0 -0
  436. package/templates/stacks/python-fastapi/app/repositories/user_repository.py +34 -0
  437. package/templates/stacks/python-fastapi/app/routers/__init__.py +0 -0
  438. package/templates/stacks/python-fastapi/app/routers/auth.py +37 -0
  439. package/templates/stacks/python-fastapi/app/routers/users.py +46 -0
  440. package/templates/stacks/python-fastapi/app/schemas/__init__.py +0 -0
  441. package/templates/stacks/python-fastapi/app/schemas/user.py +56 -0
  442. package/templates/stacks/python-fastapi/app/services/__init__.py +0 -0
  443. package/templates/stacks/python-fastapi/app/services/auth_service.py +22 -0
  444. package/templates/stacks/python-fastapi/app/services/user_service.py +31 -0
  445. package/templates/stacks/python-fastapi/gitignore +12 -0
  446. package/templates/stacks/python-fastapi/llms.txt.j2 +53 -0
  447. package/templates/stacks/python-fastapi/openapi.json.j2 +43 -0
  448. package/templates/stacks/python-fastapi/pyproject.toml.j2 +45 -0
  449. package/templates/stacks/python-fastapi/tests/__init__.py +0 -0
  450. package/templates/stacks/python-fastapi/tests/test_auth.py +22 -0
  451. package/templates/stacks/ruby-rails-8/.dare/skills.yml +50 -0
  452. package/templates/stacks/ruby-rails-8/.env.example +20 -0
  453. package/templates/stacks/ruby-rails-8/.github/workflows/dare-ci.yml +112 -0
  454. package/templates/stacks/ruby-rails-8/Gemfile.erb +61 -0
  455. package/templates/stacks/ruby-rails-8/app/channels/application_cable/channel.rb +11 -0
  456. package/templates/stacks/ruby-rails-8/app/channels/application_cable/connection.rb +34 -0
  457. package/templates/stacks/ruby-rails-8/app/channels/dare_updates_channel.rb +18 -0
  458. package/templates/stacks/ruby-rails-8/app/channels/user_updates_channel.rb +23 -0
  459. package/templates/stacks/ruby-rails-8/app/controllers/application_controller.rb +44 -0
  460. package/templates/stacks/ruby-rails-8/app/controllers/concerns/problem_details.rb +93 -0
  461. package/templates/stacks/ruby-rails-8/app/handlers/summarize_handler.rb +33 -0
  462. package/templates/stacks/ruby-rails-8/app/handlers/users_handler.rb +68 -0
  463. package/templates/stacks/ruby-rails-8/app/llm/cache/llm_cache.rb +44 -0
  464. package/templates/stacks/ruby-rails-8/app/llm/prompts/prompt_loader.rb +54 -0
  465. package/templates/stacks/ruby-rails-8/app/llm/prompts/summarize_v1.jinja2 +12 -0
  466. package/templates/stacks/ruby-rails-8/app/llm/providers/dummy_provider.rb +35 -0
  467. package/templates/stacks/ruby-rails-8/app/llm/providers/llm_provider.rb +67 -0
  468. package/templates/stacks/ruby-rails-8/app/llm/providers/openai_provider.rb +62 -0
  469. package/templates/stacks/ruby-rails-8/app/llm/rate_limit/token_bucket.rb +82 -0
  470. package/templates/stacks/ruby-rails-8/app/llm/validators/summarize_output_schema.json +21 -0
  471. package/templates/stacks/ruby-rails-8/app/llm/validators/validator.rb +52 -0
  472. package/templates/stacks/ruby-rails-8/app/models/user.rb +36 -0
  473. package/templates/stacks/ruby-rails-8/app/presenters/user_presenter.rb +48 -0
  474. package/templates/stacks/ruby-rails-8/app/repositories/document_repository.rb +57 -0
  475. package/templates/stacks/ruby-rails-8/app/repositories/user_repository.rb +73 -0
  476. package/templates/stacks/ruby-rails-8/app/services/create_user_service.rb +67 -0
  477. package/templates/stacks/ruby-rails-8/app/services/realtime_service.rb +53 -0
  478. package/templates/stacks/ruby-rails-8/app/services/summarize_document_service.rb +57 -0
  479. package/templates/stacks/ruby-rails-8/config/dare.yml +42 -0
  480. package/templates/stacks/ruby-rails-8/config/initializers/dare.rb +31 -0
  481. package/templates/stacks/ruby-rails-8/config/initializers/rack_attack.rb +64 -0
  482. package/templates/stacks/ruby-rails-8/config/initializers/rswag_api.rb +12 -0
  483. package/templates/stacks/ruby-rails-8/lib/tasks/dare.rake +159 -0
  484. package/templates/stacks/ruby-rails-8/llms.txt.erb +69 -0
  485. package/templates/stacks/ruby-rails-8/spec/api/summarize_spec.rb +56 -0
  486. package/templates/stacks/ruby-rails-8/spec/api/users_spec.rb +72 -0
  487. package/templates/stacks/ruby-rails-8/spec/channels/dare_updates_channel_spec.rb +61 -0
  488. package/templates/stacks/ruby-rails-8/spec/channels/user_updates_channel_spec.rb +56 -0
  489. package/templates/stacks/ruby-rails-8/spec/factories/users.rb +27 -0
  490. package/templates/stacks/ruby-rails-8/spec/handlers/users_handler_spec.rb +88 -0
  491. package/templates/stacks/ruby-rails-8/spec/rails_helper.rb +31 -0
  492. package/templates/stacks/ruby-rails-8/spec/services/create_user_service_spec.rb +88 -0
  493. package/templates/stacks/ruby-rails-8/spec/services/summarize_document_service_spec.rb +142 -0
  494. package/templates/stacks/ruby-rails-8/spec/swagger_helper.rb +73 -0
  495. package/templates/stacks/rust-axum/.dare/skills.yml +11 -0
  496. package/templates/stacks/rust-axum/.env.example +26 -0
  497. package/templates/stacks/rust-axum/.github/workflows/dare-ci.yml +40 -0
  498. package/templates/stacks/rust-axum/Cargo.toml.tera +53 -0
  499. package/templates/stacks/rust-axum/README.md.tera +37 -0
  500. package/templates/stacks/rust-axum/gitignore +5 -0
  501. package/templates/stacks/rust-axum/llms.txt.tera +54 -0
  502. package/templates/stacks/rust-axum/migrations/0001_create_users.sql +13 -0
  503. package/templates/stacks/rust-axum/openapi.json.tera +46 -0
  504. package/templates/stacks/rust-axum/src/config.rs +45 -0
  505. package/templates/stacks/rust-axum/src/errors.rs +48 -0
  506. package/templates/stacks/rust-axum/src/handlers/auth.rs +48 -0
  507. package/templates/stacks/rust-axum/src/handlers/mod.rs +3 -0
  508. package/templates/stacks/rust-axum/src/handlers/users.rs +81 -0
  509. package/templates/stacks/rust-axum/src/handlers/ws.rs +24 -0
  510. package/templates/stacks/rust-axum/src/lib.rs +19 -0
  511. package/templates/stacks/rust-axum/src/llm/mod.rs +1 -0
  512. package/templates/stacks/rust-axum/src/llm/provider.rs +48 -0
  513. package/templates/stacks/rust-axum/src/main.rs.tera +64 -0
  514. package/templates/stacks/rust-axum/src/middleware/auth.rs +20 -0
  515. package/templates/stacks/rust-axum/src/middleware/mod.rs +2 -0
  516. package/templates/stacks/rust-axum/src/middleware/rate_limit.rs +27 -0
  517. package/templates/stacks/rust-axum/src/models/mod.rs +1 -0
  518. package/templates/stacks/rust-axum/src/models/user.rs +13 -0
  519. package/templates/stacks/rust-axum/src/repositories/mod.rs +1 -0
  520. package/templates/stacks/rust-axum/src/repositories/user_repository.rs +62 -0
  521. package/templates/stacks/rust-axum/src/services/auth_service.rs +50 -0
  522. package/templates/stacks/rust-axum/src/services/mod.rs +2 -0
  523. package/templates/stacks/rust-axum/src/services/user_service.rs +53 -0
  524. package/templates/stacks/rust-axum/tests/integration_test.rs.tera +13 -0
  525. package/LICENSE +0 -21
  526. /package/templates/ide/cursor/.cursor/commands/{generate-bugfix-design.md → dare-bugfix-design.md} +0 -0
  527. /package/templates/ide/cursor/.cursor/commands/{generate-feature-design.md → dare-feature-design.md} +0 -0
package/README.md CHANGED
@@ -9,27 +9,34 @@ A structured methodology for AI-assisted software development with mandatory hum
9
9
 
10
10
  ---
11
11
 
12
- ## ⚠ Read this first — How `dare init` runs the official scaffold
13
-
14
- `dare init` invokes the **official scaffold** of the stack you pick. That
15
- means it literally runs:
16
-
17
- | Stack | What `dare init` runs |
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) |
20
- | `php-laravel` | `composer create-project laravel/laravel:^11 .` |
21
- | `node-nestjs` | `npx @nestjs/cli new . --strict --skip-git` |
22
- | `python-fastapi` | `python -m venv .venv && python -m pip install -r requirements.txt` |
23
- | `rust-axum` | `cargo init` + write `Cargo.toml` (axum, sqlx, tokio…) |
24
- | `go-gin` | `go mod init` + `go get gin/godotenv` + starter files |
25
- | `go-stdlib` | `go mod init` + starter usando `net/http` (zero deps externas) |
26
- | `react`, `vue` | `npx degit vitejs/vite/packages/create-vite/template-<x> .` + `npm install` |
27
- | `rust-leptos` | Cargo workspace with `crates/server` (Axum) + `crates/web` (Leptos 0.7 SSR+hydrate) + `cargo fetch` |
28
- | `rust-leptos-csr` | Cargo workspace with `crates/server` (Axum) + `crates/web` (Leptos 0.7 CSR) + Trunk.toml + `cargo fetch` |
29
- | `mcp-server-node-ts` | `npm init` + `@modelcontextprotocol/sdk` |
30
- | `mcp-server-python` | `python -m venv .venv` + `pip install mcp[cli]` |
31
-
32
- These need a working `ruby` / `composer` / `npm` / `cargo` / `python` / `go`
12
+ ## ⚠ Read this first — How `dare init` scaffolds a project (v3.2)
13
+
14
+ `dare init` writes a **complete, DARE-shaped project** from generators
15
+ internalized in this package — no shell-out to the framework's official CLI
16
+ during init. Each backend + MCP stack lays down its full source tree
17
+ (Layered Design, OpenAPI, JWT auth, rate limit, `.env.example`,
18
+ `.dare/skills.yml`, CI gates), then prints the install/build steps to run next.
19
+
20
+ | Stack | What `dare init` writes |
21
+ |-------|-------------------------|
22
+ | `ruby-rails-8` | Rails 8 + Layered Design + Action Cable + LLM + RSpec |
23
+ | `node-nestjs` | NestJS 10 + Prisma + Swagger + Throttler + JWT |
24
+ | `python-fastapi` | FastAPI + Pydantic v2 + SQLAlchemy + Alembic + slowapi |
25
+ | `php-laravel` | Laravel 11 + Sanctum + FormRequest + Reverb + l5-swagger |
26
+ | `rust-axum` | Axum + Tower + utoipa + jsonwebtoken + argon2 + sqlx |
27
+ | `go-gin` | Gin + sqlc + swag + golang-jwt + gorilla/websocket |
28
+ | `go-stdlib` | net/http 1.22 (no framework) + sqlc + coder/websocket |
29
+ | `mcp-node-ts` | MCP server (`@modelcontextprotocol/sdk`) — stdio/sse/http |
30
+ | `mcp-python` | MCP server (`mcp[cli]` / FastMCP) — stdio/sse/http |
31
+ | `mcp-rust` (beta) | MCP server (`rmcp`) — stdio/sse/http |
32
+ | `mcp-go` (beta) | MCP server (`mark3labs/mcp-go`) stdio/sse/http |
33
+ | `react`, `vue` | Vite scaffold + DARE overlay |
34
+ | `rust-leptos` / `-csr` | Cargo workspace (Axum server + Leptos web) |
35
+
36
+ Non-interactive: `dare init <name> --stack <id>` or `dare init <name> --mcp <lang> [--transport stdio\|sse\|http]`.
37
+
38
+ Generation itself needs **no toolchain**. To build/run the generated project
39
+ afterwards you need that stack's `ruby` / `composer` / `npm` / `cargo` / `python` / `go`
33
40
  **somewhere**. There are three ways to provide it — you pick at init time
34
41
  (prompt below), and the choice is saved in `dare.config.json` so
35
42
  `dare bootstrap` reuses it later.
@@ -129,12 +136,14 @@ shipped with `dare init` already nudge the agent toward that pattern.
129
136
  |------|-----|---------|
130
137
  | **Node.js 18+** | runs `dare`, `dare-mcp-server` and the bundled GraphRAG engine | https://nodejs.org/ |
131
138
 
132
- ### Required to scaffold the chosen stack
139
+ ### Required to build/run the generated project
133
140
 
134
- `dare init` runs the **official scaffold** of the stack you pick (e.g.
135
- `composer create-project laravel/laravel`, `npm create vite@latest`,
136
- `go mod init`). It tries the native toolchain first; if it isn't on PATH,
137
- it falls back to running the equivalent **Docker image** automatically.
141
+ `dare init` itself needs no stack toolchain it writes the project from
142
+ internalized templates. To **build and run** what it generates, you need that
143
+ stack's toolchain (`composer`/`npm`/`cargo`/`go`/`python`/`ruby`). If you don't
144
+ have it natively but have Docker, run the build steps inside the stack's
145
+ official image (the `.github/workflows/dare-ci.yml` the project ships shows the
146
+ exact commands).
138
147
 
139
148
  Pick **one** of the two paths per stack:
140
149
 
@@ -150,10 +159,14 @@ Pick **one** of the two paths per stack:
150
159
  | `react`, `vue` | Node 18+ (bundles `npm`) | `node:20-alpine` |
151
160
  | `rust-leptos` | Rust 1.83+ (rustup) + **cargo-leptos 0.2.22** — `cargo install cargo-leptos --version 0.2.22` | `ghcr.io/dewtech-technologies/dare-rust-leptos:1` |
152
161
  | `rust-leptos-csr` | Rust 1.83+ (rustup) + **trunk** — `cargo install trunk` | `ghcr.io/dewtech-technologies/dare-rust-leptos:1` |
153
- | `mcp-server-node-ts` | Node 18+ | `node:20-alpine` |
154
- | `mcp-server-python` | Python 3.11+ | `python:3.12-slim` |
162
+ | `mcp-node-ts` | Node 18+ | `node:20-alpine` |
163
+ | `mcp-python` | Python 3.11+ | `python:3.12-slim` |
164
+ | `mcp-rust` (beta) | Rust 1.78+ (rustup) | `rust:1.83` |
165
+ | `mcp-go` (beta) | Go 1.23+ — https://go.dev/dl/ | `golang:1.25` |
155
166
 
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).
167
+ > **v3.2.0:** full **CLI ↔ IDE parity** — every one of the 18 CLI commands is invocable as `/dare-<cmd>` across all three IDEs (Cursor, Claude Code, Antigravity); a parity test fails the build if a command is missing a skill. Brownfield commands now **collect real data by default**: `dare reverse`/`dna` extract endpoints + entities and render them into `IDEIA.md` and the module specs (no more skeleton-only artifacts).
168
+
169
+ > **v3.1.0:** all **11 stacks** ship a full generator internalized in `@dewtech/dare-cli` — 7 backend (ruby-rails-8, node-nestjs, python-fastapi, php-laravel, rust-axum, go-gin, go-stdlib) + 4 MCP (mcp-node-ts, mcp-python, mcp-rust, mcp-go). No isolated stack packages; everything is in one publishable tarball (fixes the `npm install -g` 404 of earlier releases). `dare new` was removed — `dare init` is the only scaffolding entrypoint.
157
170
 
158
171
  > **TL;DR:** if you have **Docker Desktop** installed, you don't strictly need
159
172
  > any other toolchain — `dare init` will pull the right image on demand.
@@ -425,16 +438,11 @@ specific stacks. As of v2.15.0:
425
438
 
426
439
  ### `dare bootstrap`
427
440
 
428
- Run the official scaffold for a project's stack on **an existing project**
429
- (created in older versions or with `--skip-bootstrap`). Reads
430
- `dare.config.json` and dispatches to:
431
-
432
- - `composer create-project laravel/laravel` for `php-laravel`
433
- - `npx @nestjs/cli new` for `node-nestjs`
434
- - `npm create vite` for `react` / `vue`
435
- - `python -m venv` + `pip install` for `python-fastapi`
436
- - `cargo init` + axum-ready `Cargo.toml` for `rust-axum`
437
- - `npm init` + `@modelcontextprotocol/sdk` for `mcp-server-node`
441
+ Lay down a stack's DARE-shaped source on **an existing project** (created in
442
+ older versions or with `--skip-bootstrap`). Reads `dare.config.json` and runs
443
+ the internalized generator for the configured stack — the same one `dare init`
444
+ uses. Frontend stacks (`react` / `vue` / `rust-leptos`) still use their Vite /
445
+ Cargo scaffold.
438
446
 
439
447
  ```bash
440
448
  dare bootstrap # refuses if vendor/ or node_modules/ already exist
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ensure-skills.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure-skills.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ensure-skills.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ // SPDX-License-Identifier: MIT
2
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
3
+ import path from 'node:path';
4
+ import os from 'node:os';
5
+ import fs from 'fs-extra';
6
+ import { ensureDareSkills } from '../utils/project-generator.js';
7
+ let dir;
8
+ beforeEach(async () => {
9
+ dir = await fs.mkdtemp(path.join(os.tmpdir(), 'ensure-skills-'));
10
+ });
11
+ afterEach(async () => {
12
+ await fs.remove(dir);
13
+ });
14
+ describe('ensureDareSkills — brownfield projects', () => {
15
+ describe('fresh project (no dare.config.json)', () => {
16
+ beforeEach(async () => {
17
+ await ensureDareSkills(dir);
18
+ });
19
+ it('writes a dare.config.json marker', async () => {
20
+ const cfg = await fs.readJSON(path.join(dir, 'dare.config.json'));
21
+ expect(cfg.ide).toBe('hybrid');
22
+ expect(cfg.installedBy).toContain('ensureDareSkills');
23
+ });
24
+ it('installs Cursor commands so /dare-* exists', async () => {
25
+ const cmds = path.join(dir, '.cursor', 'commands');
26
+ expect(await fs.pathExists(cmds)).toBe(true);
27
+ expect((await fs.readdir(cmds)).length).toBeGreaterThan(0);
28
+ });
29
+ it('installs Claude commands including dare-reverse', async () => {
30
+ const cmds = path.join(dir, '.claude', 'commands');
31
+ expect(await fs.pathExists(cmds)).toBe(true);
32
+ const files = await fs.readdir(cmds);
33
+ expect(files.some((f) => /reverse/i.test(f))).toBe(true);
34
+ });
35
+ it('installs Antigravity skills', async () => {
36
+ const skills = path.join(dir, '.agents', 'skills');
37
+ expect(await fs.pathExists(skills)).toBe(true);
38
+ expect((await fs.readdir(skills)).length).toBeGreaterThan(0);
39
+ });
40
+ it('creates the DARE/ working dir', async () => {
41
+ expect(await fs.pathExists(path.join(dir, 'DARE', 'EXECUTION'))).toBe(true);
42
+ });
43
+ });
44
+ describe('existing dare.config.json', () => {
45
+ it('refreshes IDE files without clobbering the config name', async () => {
46
+ await fs.writeJSON(path.join(dir, 'dare.config.json'), {
47
+ name: 'my-legacy-app',
48
+ structure: 'backend',
49
+ ide: 'cursor',
50
+ graphrag: 'sqlite',
51
+ mcp: false,
52
+ });
53
+ await ensureDareSkills(dir);
54
+ const cfg = await fs.readJSON(path.join(dir, 'dare.config.json'));
55
+ expect(cfg.name).toBe('my-legacy-app');
56
+ expect(cfg.ide).toBe('cursor');
57
+ // Cursor commands installed; claude not (ide is cursor only)
58
+ expect(await fs.pathExists(path.join(dir, '.cursor', 'commands'))).toBe(true);
59
+ expect(await fs.pathExists(path.join(dir, '.claude', 'commands'))).toBe(false);
60
+ });
61
+ });
62
+ it('is idempotent (second call does not throw)', async () => {
63
+ await ensureDareSkills(dir);
64
+ await expect(ensureDareSkills(dir)).resolves.not.toThrow();
65
+ });
66
+ });
67
+ //# sourceMappingURL=ensure-skills.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure-skills.test.js","sourceRoot":"","sources":["../../src/__tests__/ensure-skills.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ide-command-parity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ide-command-parity.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ide-command-parity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,58 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // Trava o contrato: TODO comando do `dare` CLI precisa estar disponível na IDE
4
+ // como `/dare-<cmd>` nas três IDEs suportadas (Claude, Cursor, Antigravity).
5
+ //
6
+ // Fonte da verdade dos arquivos de IDE: implementations/ (sincronizado para
7
+ // packages/cli/templates/ide/ no build). Se um comando novo for adicionado ao
8
+ // CLI sem o skill/command correspondente, este teste falha.
9
+ import { describe, it, expect } from 'vitest';
10
+ import fs from 'fs-extra';
11
+ import path from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
+ const REPO = path.resolve(__dirname, '..', '..', '..', '..');
15
+ const IMPL = path.join(REPO, 'implementations');
16
+ const BIN = path.resolve(__dirname, '..', 'bin', 'dare.ts');
17
+ // Cada comando registrado no CLI → o slug /dare-<cmd> esperado na IDE.
18
+ // Mantenha em sincronia com packages/cli/src/bin/dare.ts (program.addCommand).
19
+ const CLI_COMMANDS = {
20
+ init: 'dare-init',
21
+ bootstrap: 'dare-bootstrap',
22
+ discover: 'dare-discover',
23
+ reverse: 'dare-reverse',
24
+ dna: 'dare-dna',
25
+ migrate: 'dare-migrate',
26
+ design: 'dare-design',
27
+ blueprint: 'dare-blueprint',
28
+ execute: 'dare-execute',
29
+ graph: 'dare-graph',
30
+ dag: 'dare-dag',
31
+ validate: 'dare-validate',
32
+ info: 'dare-info',
33
+ update: 'dare-update',
34
+ review: 'dare-review',
35
+ refine: 'dare-refine',
36
+ skill: 'dare-skill',
37
+ welcome: 'dare-welcome',
38
+ };
39
+ const slugs = Object.values(CLI_COMMANDS);
40
+ describe('IDE command parity — every `dare <cmd>` exists as /dare-<cmd>', () => {
41
+ it('CLI_COMMANDS matches the number of commands registered in bin/dare.ts', async () => {
42
+ const src = await fs.readFile(BIN, 'utf8');
43
+ const registered = (src.match(/program\.addCommand\(/g) || []).length;
44
+ // Se este teste falhar: um comando foi adicionado/removido no CLI sem
45
+ // atualizar o mapa CLI_COMMANDS acima E criar o skill nas 3 IDEs.
46
+ expect(registered).toBe(Object.keys(CLI_COMMANDS).length);
47
+ });
48
+ it.each(slugs)('Claude Code expõe /%s', async (slug) => {
49
+ expect(await fs.pathExists(path.join(IMPL, 'claude', '.claude', 'commands', `${slug}.md`))).toBe(true);
50
+ });
51
+ it.each(slugs)('Cursor expõe /%s', async (slug) => {
52
+ expect(await fs.pathExists(path.join(IMPL, 'cursor', '.cursor', 'commands', `${slug}.md`))).toBe(true);
53
+ });
54
+ it.each(slugs)('Antigravity expõe /%s', async (slug) => {
55
+ expect(await fs.pathExists(path.join(IMPL, 'antigravity', '.agents', 'skills', slug, 'SKILL.md'))).toBe(true);
56
+ });
57
+ });
58
+ //# sourceMappingURL=ide-command-parity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ide-command-parity.test.js","sourceRoot":"","sources":["../../src/__tests__/ide-command-parity.test.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,4DAA4D;AAC5D,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;AAChD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAE5D,uEAAuE;AACvE,+EAA+E;AAC/E,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,WAAW;IACjB,SAAS,EAAE,gBAAgB;IAC3B,QAAQ,EAAE,eAAe;IACzB,OAAO,EAAE,cAAc;IACvB,GAAG,EAAE,UAAU;IACf,OAAO,EAAE,cAAc;IACvB,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,gBAAgB;IAC3B,OAAO,EAAE,cAAc;IACvB,KAAK,EAAE,YAAY;IACnB,GAAG,EAAE,UAAU;IACf,QAAQ,EAAE,eAAe;IACzB,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,cAAc;CACxB,CAAC;AAEF,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AAE1C,QAAQ,CAAC,+DAA+D,EAAE,GAAG,EAAE;IAC7E,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACtE,sEAAsE;QACtE,kEAAkE;QAClE,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACrD,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,kBAAkB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAChD,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACrD,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reverse-collection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverse-collection.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/reverse-collection.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,87 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // v3.2 — deterministic collection enhancements for `dare reverse`:
4
+ // - @Controller prefix composed into NestJS routes
5
+ // - DTOs / value shapes excluded from entities
6
+ // - IDEIA.md / module specs rendered with the extracted model (not skeletons)
7
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
8
+ import path from 'node:path';
9
+ import os from 'node:os';
10
+ import fs from 'fs-extra';
11
+ import { extractDataModel } from '../utils/datamodel.js';
12
+ import { buildFacts, renderIdeiaSkeleton, } from '../utils/reverse-facts.js';
13
+ import { detectProject } from '../utils/project-detector.js';
14
+ import { detectModules } from '../utils/module-detector.js';
15
+ let dir;
16
+ beforeEach(async () => {
17
+ dir = await fs.mkdtemp(path.join(os.tmpdir(), 'reverse-col-'));
18
+ });
19
+ afterEach(async () => {
20
+ await fs.remove(dir);
21
+ });
22
+ async function write(rel, content) {
23
+ const p = path.join(dir, rel);
24
+ await fs.ensureDir(path.dirname(p));
25
+ await fs.writeFile(p, content);
26
+ }
27
+ describe('extractDataModel — v3.2 collection', () => {
28
+ it('composes the @Controller prefix into NestJS routes', async () => {
29
+ await write('src/users/users.controller.ts', `@Controller('users')
30
+ export class UsersController {
31
+ @Get(':id') findOne() {}
32
+ @Post('bulk') bulk() {}
33
+ }`);
34
+ const model = await extractDataModel(dir);
35
+ const routes = model.endpoints.map((e) => `${e.method} ${e.route}`);
36
+ expect(routes).toContain('GET /users/:id');
37
+ expect(routes).toContain('POST /users/bulk');
38
+ });
39
+ it('handles an empty @Controller() prefix', async () => {
40
+ await write('src/health/health.controller.ts', `@Controller()
41
+ export class HealthController { @Get('health') h() {} }`);
42
+ const model = await extractDataModel(dir);
43
+ expect(model.endpoints.map((e) => e.route)).toContain('/health');
44
+ });
45
+ it('does NOT count DTOs as entities', async () => {
46
+ await write('src/users/dto/create-user.dto.ts', `export class CreateUserDto { email: string; password: string; }`);
47
+ await write('src/users/entities/user.entity.ts', `@Entity() export class User { id: string; email: string; }`);
48
+ const model = await extractDataModel(dir);
49
+ const names = model.entities.map((e) => e.name);
50
+ expect(names).toContain('User');
51
+ expect(names).not.toContain('CreateUserDto');
52
+ });
53
+ it('drops SQL keywords (CASCADE) but keeps lowercase table names', async () => {
54
+ await write('db/schema.sql', `CREATE TABLE produtos (id INT);
55
+ ALTER TABLE pedidos ADD CONSTRAINT fk FOREIGN KEY (pid) REFERENCES produtos(id) ON DELETE CASCADE;`);
56
+ const model = await extractDataModel(dir);
57
+ const names = model.entities.map((e) => e.name);
58
+ expect(names).toContain('produtos');
59
+ expect(names).not.toContain('CASCADE');
60
+ });
61
+ });
62
+ describe('renderIdeiaSkeleton / module spec — render real data', () => {
63
+ it('IDEIA fills API + data-model sections from the model (no AGENT placeholder)', async () => {
64
+ await write('src/orders/orders.controller.ts', `@Controller('orders') export class OrdersController { @Get() list() {} }`);
65
+ await write('src/orders/entities/order.entity.ts', `@Entity() export class Order { id: string; total: number; }`);
66
+ const detected = await detectProject(dir);
67
+ const graph = await detectModules(dir, {});
68
+ const facts = buildFacts(detected, graph, '2026-06-02T00:00:00Z');
69
+ const model = await extractDataModel(dir);
70
+ const ideia = renderIdeiaSkeleton(facts, false, model);
71
+ expect(ideia).toContain('Superfície de API — 1 endpoints 🟢');
72
+ expect(ideia).toContain('GET');
73
+ expect(ideia).toContain('/orders');
74
+ expect(ideia).toContain('Order');
75
+ // The API section is no longer a bare AGENT placeholder
76
+ expect(ideia).not.toMatch(/## Superfície de API\n<!-- AGENT/);
77
+ });
78
+ it('falls back to AGENT placeholder when no model is passed', async () => {
79
+ const detected = await detectProject(dir);
80
+ const graph = await detectModules(dir, {});
81
+ const facts = buildFacts(detected, graph, '2026-06-02T00:00:00Z');
82
+ const ideia = renderIdeiaSkeleton(facts, false);
83
+ expect(ideia).toContain('## Superfície de API');
84
+ expect(ideia).toMatch(/Superfície de API\n<!-- AGENT/);
85
+ });
86
+ });
87
+ //# sourceMappingURL=reverse-collection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverse-collection.test.js","sourceRoot":"","sources":["../../src/__tests__/reverse-collection.test.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,EAAE;AACF,mEAAmE;AACnE,qDAAqD;AACrD,iDAAiD;AACjD,gFAAgF;AAChF,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACL,UAAU,EACV,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,IAAI,GAAW,CAAC;AAEhB,UAAU,CAAC,KAAK,IAAI,EAAE;IACpB,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;AACjE,CAAC,CAAC,CAAC;AACH,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,KAAK,CAAC,GAAW,EAAE,OAAe;IAC/C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,KAAK,CACT,+BAA+B,EAC/B;;;;SAIG,CACJ,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,KAAK,CACT,iCAAiC,EACjC;+DACyD,CAC1D,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,KAAK,CACT,kCAAkC,EAClC,iEAAiE,CAClE,CAAC;QACF,MAAM,KAAK,CACT,mCAAmC,EACnC,4DAA4D,CAC7D,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,KAAK,CACT,eAAe,EACf;0GACoG,CACrG,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sDAAsD,EAAE,GAAG,EAAE;IACpE,EAAE,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;QAC3F,MAAM,KAAK,CACT,iCAAiC,EACjC,0EAA0E,CAC3E,CAAC;QACF,MAAM,KAAK,CACT,qCAAqC,EACrC,6DAA6D,CAC9D,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAE1C,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC;QAC9D,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACjC,wDAAwD;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/bin/dare.js CHANGED
@@ -17,7 +17,6 @@ import { bootstrapCommand } from '../commands/bootstrap.js';
17
17
  import { updateCommand } from '../commands/update.js';
18
18
  import { reviewCommand } from '../commands/review.js';
19
19
  import { refineCommand } from '../commands/refine.js';
20
- import { newCommand } from '../commands/new.js';
21
20
  import { skillCommand } from '../skills/index.js';
22
21
  import { welcomeCommand } from '../commands/welcome.js';
23
22
  import { printBanner } from '../utils/banner.js';
@@ -29,7 +28,6 @@ program
29
28
  .description('DARE Framework - Design · Architecture · Review · Execute methodology for AI-assisted development')
30
29
  .version(version)
31
30
  .option('--no-banner', 'Suppress ASCII art banner');
32
- program.addCommand(newCommand);
33
31
  program.addCommand(initCommand);
34
32
  program.addCommand(bootstrapCommand);
35
33
  program.addCommand(discoverCommand);
@@ -59,7 +57,7 @@ else {
59
57
  const noBanner = process.argv.includes('--no-banner');
60
58
  if (!noBanner) {
61
59
  // Show banner only for banner-eligible commands
62
- const BANNER_COMMANDS = ['new', '--version', '-V'];
60
+ const BANNER_COMMANDS = ['init', '--version', '-V'];
63
61
  const firstArg = process.argv[2] ?? '';
64
62
  if (BANNER_COMMANDS.includes(firstArg)) {
65
63
  printBanner();
@@ -1 +1 @@
1
- {"version":3,"file":"dare.js","sourceRoot":"","sources":["../../src/bin/dare.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dare.js","sourceRoot":"","sources":["../../src/bin/dare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=init.integration.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.integration.spec.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/init.integration.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,134 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // T-021 — Integration test: `dare init` Rails flow via programmatic call to
4
+ // `generateProjectStructure()`. Validates that selecting `ruby-rails-8` as
5
+ // the backend in init runs the v3.1 internalized scaffolder (registry path,
6
+ // not the legacy workspace dep).
7
+ //
8
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
9
+ import path from 'node:path';
10
+ import os from 'node:os';
11
+ import fs from 'fs-extra';
12
+ import { generateProjectStructure } from '../../utils/project-generator.js';
13
+ let tmpRoot;
14
+ let appDir;
15
+ beforeAll(async () => {
16
+ tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'init-rails-it-'));
17
+ appDir = path.join(tmpRoot, 'my-rails-app');
18
+ await generateProjectStructure({
19
+ name: 'my-rails-app',
20
+ structure: 'backend',
21
+ backend: 'ruby-rails-8',
22
+ outputDir: appDir,
23
+ // Defaults — what an interactive init would pass
24
+ toolchain: 'auto',
25
+ ide: 'cursor',
26
+ graphrag: 'sqlite',
27
+ mcp: false,
28
+ });
29
+ });
30
+ afterAll(async () => {
31
+ if (tmpRoot)
32
+ await fs.remove(tmpRoot);
33
+ });
34
+ describe('dare init — backend: ruby-rails-8', () => {
35
+ it('creates output directory', async () => {
36
+ expect(await fs.pathExists(appDir)).toBe(true);
37
+ });
38
+ it('writes dare.config.json with backend=ruby-rails-8', async () => {
39
+ const cfgPath = path.join(appDir, 'dare.config.json');
40
+ expect(await fs.pathExists(cfgPath)).toBe(true);
41
+ const cfg = await fs.readJSON(cfgPath);
42
+ expect(cfg.backend).toBe('ruby-rails-8');
43
+ expect(cfg.structure).toBe('backend');
44
+ expect(cfg.name).toBe('my-rails-app');
45
+ });
46
+ it('creates Rails-specific files (Gemfile, app/, config/)', async () => {
47
+ expect(await fs.pathExists(path.join(appDir, 'Gemfile'))).toBe(true);
48
+ expect(await fs.pathExists(path.join(appDir, 'app'))).toBe(true);
49
+ expect(await fs.pathExists(path.join(appDir, 'config'))).toBe(true);
50
+ });
51
+ it('creates llms.txt (DARE DNA)', async () => {
52
+ const llms = path.join(appDir, 'llms.txt');
53
+ expect(await fs.pathExists(llms)).toBe(true);
54
+ const content = await fs.readFile(llms, 'utf8');
55
+ expect(content.length).toBeGreaterThan(200);
56
+ });
57
+ it('creates .dare/skills.yml', async () => {
58
+ const skills = path.join(appDir, '.dare', 'skills.yml');
59
+ expect(await fs.pathExists(skills)).toBe(true);
60
+ });
61
+ it('creates DARE/ scaffolding (Method artifacts dir)', async () => {
62
+ expect(await fs.pathExists(path.join(appDir, 'DARE'))).toBe(true);
63
+ expect(await fs.pathExists(path.join(appDir, 'DARE', 'EXECUTION'))).toBe(true);
64
+ });
65
+ it('Rails Layered Design directories present', async () => {
66
+ for (const dir of ['app/handlers', 'app/services', 'app/repositories']) {
67
+ expect(await fs.pathExists(path.join(appDir, dir))).toBe(true);
68
+ }
69
+ });
70
+ });
71
+ // ── v3.1 routing gate ──────────────────────────────────────────────────────
72
+ //
73
+ // Regression guard for the gap found during npm-install simulation: every
74
+ // backend + MCP stack must route through the internalized registry scaffolder
75
+ // (DARE-shaped output), NOT the legacy official-tool bootstrap. Proven by the
76
+ // presence of the DNA artifacts the new scaffolders emit.
77
+ describe('dare init — all backends route through registry scaffolders', () => {
78
+ const BACKENDS = [
79
+ 'node-nestjs',
80
+ 'python-fastapi',
81
+ 'php-laravel',
82
+ 'rust-axum',
83
+ 'go-gin',
84
+ 'go-stdlib',
85
+ ];
86
+ it.each(BACKENDS)('%s emits DARE DNA (llms.txt + .dare/skills.yml + dare-ci.yml)', async (stack) => {
87
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), `init-${stack}-`));
88
+ const dir = path.join(root, 'app');
89
+ try {
90
+ await generateProjectStructure({
91
+ name: 'app',
92
+ structure: 'backend',
93
+ backend: stack,
94
+ outputDir: dir,
95
+ toolchain: 'auto',
96
+ ide: 'cursor',
97
+ graphrag: 'sqlite',
98
+ mcp: false,
99
+ });
100
+ expect(await fs.pathExists(path.join(dir, 'llms.txt')), `${stack} llms.txt`).toBe(true);
101
+ expect(await fs.pathExists(path.join(dir, '.dare/skills.yml')), `${stack} skills.yml`).toBe(true);
102
+ expect(await fs.pathExists(path.join(dir, '.github/workflows/dare-ci.yml')), `${stack} dare-ci.yml`).toBe(true);
103
+ }
104
+ finally {
105
+ await fs.remove(root);
106
+ }
107
+ });
108
+ });
109
+ describe('dare init — MCP variants route through registry scaffolders', () => {
110
+ const LANGS = ['node-ts', 'python', 'rust', 'go'];
111
+ it.each(LANGS)('mcp %s emits server + transports + DNA', async (lang) => {
112
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), `init-mcp-${lang}-`));
113
+ const dir = path.join(root, 'srv');
114
+ try {
115
+ await generateProjectStructure({
116
+ name: 'srv',
117
+ structure: 'mcp-server',
118
+ mcpLanguage: lang,
119
+ mcpTransport: 'stdio',
120
+ outputDir: dir,
121
+ toolchain: 'auto',
122
+ ide: 'cursor',
123
+ graphrag: 'sqlite',
124
+ mcp: false,
125
+ });
126
+ expect(await fs.pathExists(path.join(dir, 'llms.txt')), `${lang} llms.txt`).toBe(true);
127
+ expect(await fs.pathExists(path.join(dir, '.dare/skills.yml')), `${lang} skills.yml`).toBe(true);
128
+ }
129
+ finally {
130
+ await fs.remove(root);
131
+ }
132
+ });
133
+ });
134
+ //# sourceMappingURL=init.integration.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.integration.spec.js","sourceRoot":"","sources":["../../../src/commands/__tests__/init.integration.spec.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,iCAAiC;AACjC,EAAE;AACF,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAE5E,IAAI,OAAe,CAAC;AACpB,IAAI,MAAc,CAAC;AAEnB,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACrE,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAE5C,MAAM,wBAAwB,CAAC;QAC7B,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,cAAc;QACvB,SAAS,EAAE,MAAM;QACjB,iDAAiD;QACjD,SAAS,EAAE,MAAM;QACjB,GAAG,EAAE,QAAQ;QACb,QAAQ,EAAE,QAAQ;QAClB,GAAG,EAAE,KAAK;KACX,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,KAAK,IAAI,EAAE;IAClB,IAAI,OAAO;QAAE,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,KAAK,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,cAAc,EAAE,kBAAkB,CAAC,EAAE,CAAC;YACvE,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,EAAE;AACF,0EAA0E;AAC1E,8EAA8E;AAC9E,8EAA8E;AAC9E,0DAA0D;AAC1D,QAAQ,CAAC,6DAA6D,EAAE,GAAG,EAAE;IAC3E,MAAM,QAAQ,GAAG;QACf,aAAa;QACb,gBAAgB;QAChB,aAAa;QACb,WAAW;QACX,QAAQ;QACR,WAAW;KACH,CAAC;IAEX,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,+DAA+D,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACjG,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC;QACxE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,wBAAwB,CAAC;gBAC7B,IAAI,EAAE,KAAK;gBACX,SAAS,EAAE,SAAS;gBACpB,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,GAAG;gBACd,SAAS,EAAE,MAAM;gBACjB,GAAG,EAAE,QAAQ;gBACb,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,KAAK;aACX,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,EAAE,GAAG,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxF,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,EAAE,GAAG,KAAK,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClG,MAAM,CACJ,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,+BAA+B,CAAC,CAAC,EACpE,GAAG,KAAK,cAAc,CACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6DAA6D,EAAE,GAAG,EAAE;IAC3E,MAAM,KAAK,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAU,CAAC;IAE3D,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,wCAAwC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtE,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,YAAY,IAAI,GAAG,CAAC,CAAC,CAAC;QAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,wBAAwB,CAAC;gBAC7B,IAAI,EAAE,KAAK;gBACX,SAAS,EAAE,YAAY;gBACvB,WAAW,EAAE,IAAI;gBACjB,YAAY,EAAE,OAAO;gBACrB,SAAS,EAAE,GAAG;gBACd,SAAS,EAAE,MAAM;gBACjB,GAAG,EAAE,QAAQ;gBACb,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,KAAK;aACX,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,EAAE,GAAG,IAAI,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvF,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,EAAE,GAAG,IAAI,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnG,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"dna.d.ts","sourceRoot":"","sources":["../../src/commands/dna.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,eAAO,MAAM,UAAU,SA6CnB,CAAC"}
1
+ {"version":3,"file":"dna.d.ts","sourceRoot":"","sources":["../../src/commands/dna.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,eAAO,MAAM,UAAU,SAgDnB,CAAC"}
@@ -5,6 +5,7 @@ import fs from 'fs-extra';
5
5
  import path from 'path';
6
6
  import { detectDna } from '../utils/dna-detector.js';
7
7
  import { renderDnaSkeleton } from '../utils/dna-facts.js';
8
+ import { ensureDareSkills } from '../utils/project-generator.js';
8
9
  export const dnaCommand = new Command('dna')
9
10
  .description('Extract a legacy codebase\'s conventions into DARE/PROJECT-DNA.md (brownfield house-style ruleset)')
10
11
  .option('-d, --dir <path>', 'Target directory (default: current directory)')
@@ -13,6 +14,9 @@ export const dnaCommand = new Command('dna')
13
14
  const targetDir = path.resolve(opts.dir ?? process.cwd());
14
15
  console.log(chalk.blue.bold('\n🧬 DARE Framework - Project DNA (conventions)\n'));
15
16
  console.log(chalk.gray(` Scanning: ${targetDir}\n`));
17
+ // --check is read-only detection; don't install skills then.
18
+ if (!opts.check)
19
+ await ensureDareSkills(targetDir);
16
20
  const spinner = ora('Extracting conventions...').start();
17
21
  const generatedAt = new Date().toISOString();
18
22
  const facts = await detectDna(targetDir, generatedAt);