@dewtech/dare-cli 3.0.0 → 3.1.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 (453) hide show
  1. package/README.md +45 -39
  2. package/dist/bin/dare.js +1 -3
  3. package/dist/bin/dare.js.map +1 -1
  4. package/dist/commands/__tests__/init.integration.spec.d.ts +2 -0
  5. package/dist/commands/__tests__/init.integration.spec.d.ts.map +1 -0
  6. package/dist/commands/__tests__/init.integration.spec.js +134 -0
  7. package/dist/commands/__tests__/init.integration.spec.js.map +1 -0
  8. package/dist/commands/init.d.ts.map +1 -1
  9. package/dist/commands/init.js +84 -1
  10. package/dist/commands/init.js.map +1 -1
  11. package/dist/commands/new.d.ts.map +1 -1
  12. package/dist/commands/new.js +2 -1
  13. package/dist/commands/new.js.map +1 -1
  14. package/dist/mcp-server/bin/server.js +0 -0
  15. package/dist/stacks/__tests__/dna-emitter.spec.d.ts +2 -0
  16. package/dist/stacks/__tests__/dna-emitter.spec.d.ts.map +1 -0
  17. package/dist/stacks/__tests__/dna-emitter.spec.js +207 -0
  18. package/dist/stacks/__tests__/dna-emitter.spec.js.map +1 -0
  19. package/dist/stacks/__tests__/dna.spec.d.ts +2 -0
  20. package/dist/stacks/__tests__/dna.spec.d.ts.map +1 -0
  21. package/dist/stacks/__tests__/dna.spec.js +211 -0
  22. package/dist/stacks/__tests__/dna.spec.js.map +1 -0
  23. package/dist/stacks/__tests__/parity-rails.fixture.json +228 -0
  24. package/dist/stacks/__tests__/parity-rails.spec.d.ts +2 -0
  25. package/dist/stacks/__tests__/parity-rails.spec.d.ts.map +1 -0
  26. package/dist/stacks/__tests__/parity-rails.spec.js +99 -0
  27. package/dist/stacks/__tests__/parity-rails.spec.js.map +1 -0
  28. package/dist/stacks/__tests__/registry.spec.d.ts +2 -0
  29. package/dist/stacks/__tests__/registry.spec.d.ts.map +1 -0
  30. package/dist/stacks/__tests__/registry.spec.js +101 -0
  31. package/dist/stacks/__tests__/registry.spec.js.map +1 -0
  32. package/dist/stacks/__tests__/template-engine.spec.d.ts +2 -0
  33. package/dist/stacks/__tests__/template-engine.spec.d.ts.map +1 -0
  34. package/dist/stacks/__tests__/template-engine.spec.js +149 -0
  35. package/dist/stacks/__tests__/template-engine.spec.js.map +1 -0
  36. package/dist/stacks/dna-emitter.d.ts +45 -0
  37. package/dist/stacks/dna-emitter.d.ts.map +1 -0
  38. package/dist/stacks/dna-emitter.js +267 -0
  39. package/dist/stacks/dna-emitter.js.map +1 -0
  40. package/dist/stacks/go-gin/__tests__/scaffold.spec.d.ts +2 -0
  41. package/dist/stacks/go-gin/__tests__/scaffold.spec.d.ts.map +1 -0
  42. package/dist/stacks/go-gin/__tests__/scaffold.spec.js +221 -0
  43. package/dist/stacks/go-gin/__tests__/scaffold.spec.js.map +1 -0
  44. package/dist/stacks/go-gin/scaffold.d.ts +3 -0
  45. package/dist/stacks/go-gin/scaffold.d.ts.map +1 -0
  46. package/dist/stacks/go-gin/scaffold.js +105 -0
  47. package/dist/stacks/go-gin/scaffold.js.map +1 -0
  48. package/dist/stacks/go-stdlib/__tests__/scaffold.spec.d.ts +2 -0
  49. package/dist/stacks/go-stdlib/__tests__/scaffold.spec.d.ts.map +1 -0
  50. package/dist/stacks/go-stdlib/__tests__/scaffold.spec.js +215 -0
  51. package/dist/stacks/go-stdlib/__tests__/scaffold.spec.js.map +1 -0
  52. package/dist/stacks/go-stdlib/scaffold.d.ts +3 -0
  53. package/dist/stacks/go-stdlib/scaffold.d.ts.map +1 -0
  54. package/dist/stacks/go-stdlib/scaffold.js +106 -0
  55. package/dist/stacks/go-stdlib/scaffold.js.map +1 -0
  56. package/dist/stacks/mcp-go/__tests__/scaffold.spec.d.ts +2 -0
  57. package/dist/stacks/mcp-go/__tests__/scaffold.spec.d.ts.map +1 -0
  58. package/dist/stacks/mcp-go/__tests__/scaffold.spec.js +203 -0
  59. package/dist/stacks/mcp-go/__tests__/scaffold.spec.js.map +1 -0
  60. package/dist/stacks/mcp-go/scaffold.d.ts +3 -0
  61. package/dist/stacks/mcp-go/scaffold.d.ts.map +1 -0
  62. package/dist/stacks/mcp-go/scaffold.js +94 -0
  63. package/dist/stacks/mcp-go/scaffold.js.map +1 -0
  64. package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.d.ts +2 -0
  65. package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.d.ts.map +1 -0
  66. package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.js +236 -0
  67. package/dist/stacks/mcp-node-ts/__tests__/scaffold.spec.js.map +1 -0
  68. package/dist/stacks/mcp-node-ts/scaffold.d.ts +3 -0
  69. package/dist/stacks/mcp-node-ts/scaffold.d.ts.map +1 -0
  70. package/dist/stacks/mcp-node-ts/scaffold.js +95 -0
  71. package/dist/stacks/mcp-node-ts/scaffold.js.map +1 -0
  72. package/dist/stacks/mcp-python/__tests__/scaffold.spec.d.ts +2 -0
  73. package/dist/stacks/mcp-python/__tests__/scaffold.spec.d.ts.map +1 -0
  74. package/dist/stacks/mcp-python/__tests__/scaffold.spec.js +228 -0
  75. package/dist/stacks/mcp-python/__tests__/scaffold.spec.js.map +1 -0
  76. package/dist/stacks/mcp-python/scaffold.d.ts +3 -0
  77. package/dist/stacks/mcp-python/scaffold.d.ts.map +1 -0
  78. package/dist/stacks/mcp-python/scaffold.js +98 -0
  79. package/dist/stacks/mcp-python/scaffold.js.map +1 -0
  80. package/dist/stacks/mcp-rust/__tests__/scaffold.spec.d.ts +2 -0
  81. package/dist/stacks/mcp-rust/__tests__/scaffold.spec.d.ts.map +1 -0
  82. package/dist/stacks/mcp-rust/__tests__/scaffold.spec.js +213 -0
  83. package/dist/stacks/mcp-rust/__tests__/scaffold.spec.js.map +1 -0
  84. package/dist/stacks/mcp-rust/scaffold.d.ts +3 -0
  85. package/dist/stacks/mcp-rust/scaffold.d.ts.map +1 -0
  86. package/dist/stacks/mcp-rust/scaffold.js +98 -0
  87. package/dist/stacks/mcp-rust/scaffold.js.map +1 -0
  88. package/dist/stacks/node-nestjs/__tests__/scaffold.spec.d.ts +2 -0
  89. package/dist/stacks/node-nestjs/__tests__/scaffold.spec.d.ts.map +1 -0
  90. package/dist/stacks/node-nestjs/__tests__/scaffold.spec.js +172 -0
  91. package/dist/stacks/node-nestjs/__tests__/scaffold.spec.js.map +1 -0
  92. package/dist/stacks/node-nestjs/scaffold.d.ts +3 -0
  93. package/dist/stacks/node-nestjs/scaffold.d.ts.map +1 -0
  94. package/dist/stacks/node-nestjs/scaffold.js +117 -0
  95. package/dist/stacks/node-nestjs/scaffold.js.map +1 -0
  96. package/dist/stacks/php-laravel/__tests__/scaffold.spec.d.ts +2 -0
  97. package/dist/stacks/php-laravel/__tests__/scaffold.spec.d.ts.map +1 -0
  98. package/dist/stacks/php-laravel/__tests__/scaffold.spec.js +205 -0
  99. package/dist/stacks/php-laravel/__tests__/scaffold.spec.js.map +1 -0
  100. package/dist/stacks/php-laravel/scaffold.d.ts +3 -0
  101. package/dist/stacks/php-laravel/scaffold.d.ts.map +1 -0
  102. package/dist/stacks/php-laravel/scaffold.js +109 -0
  103. package/dist/stacks/php-laravel/scaffold.js.map +1 -0
  104. package/dist/stacks/python-fastapi/__tests__/scaffold.spec.d.ts +2 -0
  105. package/dist/stacks/python-fastapi/__tests__/scaffold.spec.d.ts.map +1 -0
  106. package/dist/stacks/python-fastapi/__tests__/scaffold.spec.js +168 -0
  107. package/dist/stacks/python-fastapi/__tests__/scaffold.spec.js.map +1 -0
  108. package/dist/stacks/python-fastapi/scaffold.d.ts +3 -0
  109. package/dist/stacks/python-fastapi/scaffold.d.ts.map +1 -0
  110. package/dist/stacks/python-fastapi/scaffold.js +108 -0
  111. package/dist/stacks/python-fastapi/scaffold.js.map +1 -0
  112. package/dist/stacks/registry.d.ts +38 -0
  113. package/dist/stacks/registry.d.ts.map +1 -0
  114. package/dist/stacks/registry.js +153 -0
  115. package/dist/stacks/registry.js.map +1 -0
  116. package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.d.ts +6 -0
  117. package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.d.ts.map +1 -0
  118. package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.js +604 -0
  119. package/dist/stacks/ruby-rails-8/__tests__/scaffold.spec.js.map +1 -0
  120. package/dist/stacks/ruby-rails-8/scaffold.d.ts +91 -0
  121. package/dist/stacks/ruby-rails-8/scaffold.d.ts.map +1 -0
  122. package/dist/stacks/ruby-rails-8/scaffold.js +410 -0
  123. package/dist/stacks/ruby-rails-8/scaffold.js.map +1 -0
  124. package/dist/stacks/rust-axum/__tests__/scaffold.spec.d.ts +2 -0
  125. package/dist/stacks/rust-axum/__tests__/scaffold.spec.d.ts.map +1 -0
  126. package/dist/stacks/rust-axum/__tests__/scaffold.spec.js +203 -0
  127. package/dist/stacks/rust-axum/__tests__/scaffold.spec.js.map +1 -0
  128. package/dist/stacks/rust-axum/scaffold.d.ts +3 -0
  129. package/dist/stacks/rust-axum/scaffold.d.ts.map +1 -0
  130. package/dist/stacks/rust-axum/scaffold.js +105 -0
  131. package/dist/stacks/rust-axum/scaffold.js.map +1 -0
  132. package/dist/stacks/template-engine.d.ts +38 -0
  133. package/dist/stacks/template-engine.d.ts.map +1 -0
  134. package/dist/stacks/template-engine.js +134 -0
  135. package/dist/stacks/template-engine.js.map +1 -0
  136. package/dist/stacks/types.d.ts +69 -0
  137. package/dist/stacks/types.d.ts.map +1 -0
  138. package/dist/stacks/types.js +29 -0
  139. package/dist/stacks/types.js.map +1 -0
  140. package/dist/utils/project-generator.d.ts +1 -1
  141. package/dist/utils/project-generator.d.ts.map +1 -1
  142. package/dist/utils/project-generator.js +16 -7
  143. package/dist/utils/project-generator.js.map +1 -1
  144. package/dist/utils/stack-bootstrap.d.ts +3 -2
  145. package/dist/utils/stack-bootstrap.d.ts.map +1 -1
  146. package/dist/utils/stack-bootstrap.js +46 -16
  147. package/dist/utils/stack-bootstrap.js.map +1 -1
  148. package/package.json +91 -87
  149. package/templates/stacks/go-gin/.dare/skills.yml +11 -0
  150. package/templates/stacks/go-gin/.env.example +24 -0
  151. package/templates/stacks/go-gin/.github/workflows/dare-ci.yml +42 -0
  152. package/templates/stacks/go-gin/README.md.tpl +38 -0
  153. package/templates/stacks/go-gin/cmd/server/main.go.tpl +78 -0
  154. package/templates/stacks/go-gin/db/migrations/0001_create_users.down.sql +2 -0
  155. package/templates/stacks/go-gin/db/migrations/0001_create_users.up.sql +12 -0
  156. package/templates/stacks/go-gin/db/queries/users.sql +23 -0
  157. package/templates/stacks/go-gin/gitignore +7 -0
  158. package/templates/stacks/go-gin/go.mod.tpl +17 -0
  159. package/templates/stacks/go-gin/internal/config/config.go +41 -0
  160. package/templates/stacks/go-gin/internal/db/postgres.go.tpl +25 -0
  161. package/templates/stacks/go-gin/internal/handler/auth_handler.go.tpl +72 -0
  162. package/templates/stacks/go-gin/internal/handler/users_handler.go.tpl +72 -0
  163. package/templates/stacks/go-gin/internal/handler/ws_handler.go +37 -0
  164. package/templates/stacks/go-gin/internal/llm/dummy.go +14 -0
  165. package/templates/stacks/go-gin/internal/llm/provider.go +8 -0
  166. package/templates/stacks/go-gin/internal/middleware/jwt.go.tpl +58 -0
  167. package/templates/stacks/go-gin/internal/middleware/rate_limit.go +55 -0
  168. package/templates/stacks/go-gin/internal/model/user.go +17 -0
  169. package/templates/stacks/go-gin/internal/repository/users_repository.go.tpl +79 -0
  170. package/templates/stacks/go-gin/internal/service/auth_service.go.tpl +55 -0
  171. package/templates/stacks/go-gin/internal/service/users_service.go.tpl +53 -0
  172. package/templates/stacks/go-gin/llms.txt.tpl +54 -0
  173. package/templates/stacks/go-gin/openapi.json.tpl +46 -0
  174. package/templates/stacks/go-gin/sqlc.yaml +14 -0
  175. package/templates/stacks/go-gin/tests/smoke_test.go.tpl +22 -0
  176. package/templates/stacks/go-stdlib/.dare/skills.yml +11 -0
  177. package/templates/stacks/go-stdlib/.env.example +24 -0
  178. package/templates/stacks/go-stdlib/.github/workflows/dare-ci.yml +42 -0
  179. package/templates/stacks/go-stdlib/README.md.tpl +41 -0
  180. package/templates/stacks/go-stdlib/cmd/server/main.go.tpl +82 -0
  181. package/templates/stacks/go-stdlib/db/migrations/0001_create_users.down.sql +2 -0
  182. package/templates/stacks/go-stdlib/db/migrations/0001_create_users.up.sql +12 -0
  183. package/templates/stacks/go-stdlib/db/queries/users.sql +23 -0
  184. package/templates/stacks/go-stdlib/gitignore +6 -0
  185. package/templates/stacks/go-stdlib/go.mod.tpl +15 -0
  186. package/templates/stacks/go-stdlib/internal/config/config.go +41 -0
  187. package/templates/stacks/go-stdlib/internal/db/postgres.go.tpl +24 -0
  188. package/templates/stacks/go-stdlib/internal/handler/auth_handler.go.tpl +71 -0
  189. package/templates/stacks/go-stdlib/internal/handler/users_handler.go.tpl +84 -0
  190. package/templates/stacks/go-stdlib/internal/handler/ws_handler.go +36 -0
  191. package/templates/stacks/go-stdlib/internal/httpx/json.go +32 -0
  192. package/templates/stacks/go-stdlib/internal/llm/dummy.go +14 -0
  193. package/templates/stacks/go-stdlib/internal/llm/provider.go +8 -0
  194. package/templates/stacks/go-stdlib/internal/middleware/chain.go +21 -0
  195. package/templates/stacks/go-stdlib/internal/middleware/cors.go +27 -0
  196. package/templates/stacks/go-stdlib/internal/middleware/jwt.go.tpl +51 -0
  197. package/templates/stacks/go-stdlib/internal/middleware/rate_limit.go +81 -0
  198. package/templates/stacks/go-stdlib/internal/model/user.go +17 -0
  199. package/templates/stacks/go-stdlib/internal/repository/users_repository.go.tpl +75 -0
  200. package/templates/stacks/go-stdlib/internal/service/auth_service.go.tpl +55 -0
  201. package/templates/stacks/go-stdlib/internal/service/users_service.go.tpl +53 -0
  202. package/templates/stacks/go-stdlib/llms.txt.tpl +60 -0
  203. package/templates/stacks/go-stdlib/openapi.json.tpl +46 -0
  204. package/templates/stacks/go-stdlib/sqlc.yaml +14 -0
  205. package/templates/stacks/go-stdlib/tests/smoke_test.go.tpl +45 -0
  206. package/templates/stacks/mcp-go/.dare/skills.yml +8 -0
  207. package/templates/stacks/mcp-go/.env.example +14 -0
  208. package/templates/stacks/mcp-go/.github/workflows/dare-ci.yml +42 -0
  209. package/templates/stacks/mcp-go/README.md.tpl +50 -0
  210. package/templates/stacks/mcp-go/cmd/server/main.go.tpl +62 -0
  211. package/templates/stacks/mcp-go/gitignore +6 -0
  212. package/templates/stacks/mcp-go/go.mod.tpl +9 -0
  213. package/templates/stacks/mcp-go/internal/prompts/summarize.go +9 -0
  214. package/templates/stacks/mcp-go/internal/server/server.go.tpl +80 -0
  215. package/templates/stacks/mcp-go/internal/tools/echo.go +15 -0
  216. package/templates/stacks/mcp-go/internal/transports/http.go.tpl +21 -0
  217. package/templates/stacks/mcp-go/internal/transports/sse.go.tpl +17 -0
  218. package/templates/stacks/mcp-go/internal/transports/stdio.go.tpl +14 -0
  219. package/templates/stacks/mcp-go/llms.txt.tpl +60 -0
  220. package/templates/stacks/mcp-go/openapi.json.tpl +31 -0
  221. package/templates/stacks/mcp-go/tests/echo_test.go.tpl +37 -0
  222. package/templates/stacks/mcp-node-ts/.dare/skills.yml +8 -0
  223. package/templates/stacks/mcp-node-ts/.env.example +16 -0
  224. package/templates/stacks/mcp-node-ts/.github/workflows/dare-ci.yml +54 -0
  225. package/templates/stacks/mcp-node-ts/README.md.hbs +49 -0
  226. package/templates/stacks/mcp-node-ts/gitignore +7 -0
  227. package/templates/stacks/mcp-node-ts/llms.txt.hbs +61 -0
  228. package/templates/stacks/mcp-node-ts/openapi.json.hbs +39 -0
  229. package/templates/stacks/mcp-node-ts/package.json.hbs +35 -0
  230. package/templates/stacks/mcp-node-ts/src/cli.ts.hbs +71 -0
  231. package/templates/stacks/mcp-node-ts/src/prompts/index.ts +36 -0
  232. package/templates/stacks/mcp-node-ts/src/server.ts.hbs +45 -0
  233. package/templates/stacks/mcp-node-ts/src/tools/echo.ts +23 -0
  234. package/templates/stacks/mcp-node-ts/src/tools/index.ts +18 -0
  235. package/templates/stacks/mcp-node-ts/src/transports/http.ts +68 -0
  236. package/templates/stacks/mcp-node-ts/src/transports/sse.ts +58 -0
  237. package/templates/stacks/mcp-node-ts/src/transports/stdio.ts +5 -0
  238. package/templates/stacks/mcp-node-ts/tests/echo.test.ts +50 -0
  239. package/templates/stacks/mcp-node-ts/tsconfig.json +17 -0
  240. package/templates/stacks/mcp-python/.dare/skills.yml +8 -0
  241. package/templates/stacks/mcp-python/.env.example +14 -0
  242. package/templates/stacks/mcp-python/.github/workflows/dare-ci.yml +42 -0
  243. package/templates/stacks/mcp-python/README.md.j2 +49 -0
  244. package/templates/stacks/mcp-python/gitignore +12 -0
  245. package/templates/stacks/mcp-python/llms.txt.j2 +56 -0
  246. package/templates/stacks/mcp-python/openapi.json.j2 +33 -0
  247. package/templates/stacks/mcp-python/pyproject.toml.j2 +37 -0
  248. package/templates/stacks/mcp-python/src/__init__.py +0 -0
  249. package/templates/stacks/mcp-python/src/cli.py.j2 +68 -0
  250. package/templates/stacks/mcp-python/src/prompts/__init__.py +0 -0
  251. package/templates/stacks/mcp-python/src/prompts/summarize.py +10 -0
  252. package/templates/stacks/mcp-python/src/server.py.j2 +28 -0
  253. package/templates/stacks/mcp-python/src/tools/__init__.py +0 -0
  254. package/templates/stacks/mcp-python/src/tools/echo.py +12 -0
  255. package/templates/stacks/mcp-python/src/transports/__init__.py +0 -0
  256. package/templates/stacks/mcp-python/src/transports/http.py +12 -0
  257. package/templates/stacks/mcp-python/src/transports/sse.py +13 -0
  258. package/templates/stacks/mcp-python/src/transports/stdio.py +6 -0
  259. package/templates/stacks/mcp-python/tests/__init__.py +0 -0
  260. package/templates/stacks/mcp-python/tests/test_echo.py +28 -0
  261. package/templates/stacks/mcp-rust/.dare/skills.yml +8 -0
  262. package/templates/stacks/mcp-rust/.env.example +14 -0
  263. package/templates/stacks/mcp-rust/.github/workflows/dare-ci.yml +38 -0
  264. package/templates/stacks/mcp-rust/Cargo.toml.tera +35 -0
  265. package/templates/stacks/mcp-rust/README.md.tera +50 -0
  266. package/templates/stacks/mcp-rust/gitignore +5 -0
  267. package/templates/stacks/mcp-rust/llms.txt.tera +60 -0
  268. package/templates/stacks/mcp-rust/openapi.json.tera +31 -0
  269. package/templates/stacks/mcp-rust/src/cli.rs.tera +33 -0
  270. package/templates/stacks/mcp-rust/src/lib.rs +6 -0
  271. package/templates/stacks/mcp-rust/src/main.rs.tera +30 -0
  272. package/templates/stacks/mcp-rust/src/prompts/mod.rs +1 -0
  273. package/templates/stacks/mcp-rust/src/prompts/summarize.rs +5 -0
  274. package/templates/stacks/mcp-rust/src/server.rs.tera +38 -0
  275. package/templates/stacks/mcp-rust/src/tools/echo.rs +18 -0
  276. package/templates/stacks/mcp-rust/src/tools/mod.rs +22 -0
  277. package/templates/stacks/mcp-rust/src/transports/http.rs +27 -0
  278. package/templates/stacks/mcp-rust/src/transports/mod.rs +3 -0
  279. package/templates/stacks/mcp-rust/src/transports/sse.rs +33 -0
  280. package/templates/stacks/mcp-rust/src/transports/stdio.rs +14 -0
  281. package/templates/stacks/mcp-rust/tests/echo_test.rs.tera +27 -0
  282. package/templates/stacks/node-nestjs/.dare/skills.yml +11 -0
  283. package/templates/stacks/node-nestjs/.env.example +21 -0
  284. package/templates/stacks/node-nestjs/.github/workflows/dare-ci.yml +54 -0
  285. package/templates/stacks/node-nestjs/README.md.hbs +35 -0
  286. package/templates/stacks/node-nestjs/gitignore +7 -0
  287. package/templates/stacks/node-nestjs/llms.txt.hbs +47 -0
  288. package/templates/stacks/node-nestjs/nest-cli.json +16 -0
  289. package/templates/stacks/node-nestjs/openapi.json.hbs +75 -0
  290. package/templates/stacks/node-nestjs/package.json.hbs +57 -0
  291. package/templates/stacks/node-nestjs/prisma/schema.prisma +25 -0
  292. package/templates/stacks/node-nestjs/prisma/seed.ts.hbs +25 -0
  293. package/templates/stacks/node-nestjs/src/app.module.ts +39 -0
  294. package/templates/stacks/node-nestjs/src/auth/auth.controller.ts +29 -0
  295. package/templates/stacks/node-nestjs/src/auth/auth.module.ts +25 -0
  296. package/templates/stacks/node-nestjs/src/auth/auth.service.ts +36 -0
  297. package/templates/stacks/node-nestjs/src/auth/dto/login-response.dto.ts +9 -0
  298. package/templates/stacks/node-nestjs/src/auth/dto/login.dto.ts +17 -0
  299. package/templates/stacks/node-nestjs/src/auth/jwt.strategy.ts +25 -0
  300. package/templates/stacks/node-nestjs/src/common/filters/problem-details.filter.ts +38 -0
  301. package/templates/stacks/node-nestjs/src/common/interceptors/json-response.interceptor.ts +13 -0
  302. package/templates/stacks/node-nestjs/src/main.ts.hbs +44 -0
  303. package/templates/stacks/node-nestjs/src/prisma/prisma.module.ts +9 -0
  304. package/templates/stacks/node-nestjs/src/prisma/prisma.service.ts +9 -0
  305. package/templates/stacks/node-nestjs/src/users/dto/create-user.dto.ts +22 -0
  306. package/templates/stacks/node-nestjs/src/users/dto/user.dto.ts +15 -0
  307. package/templates/stacks/node-nestjs/src/users/users.controller.ts +41 -0
  308. package/templates/stacks/node-nestjs/src/users/users.module.ts +11 -0
  309. package/templates/stacks/node-nestjs/src/users/users.repository.ts +38 -0
  310. package/templates/stacks/node-nestjs/src/users/users.service.ts +38 -0
  311. package/templates/stacks/node-nestjs/tsconfig.build.json +4 -0
  312. package/templates/stacks/node-nestjs/tsconfig.json +28 -0
  313. package/templates/stacks/php-laravel/.dare/skills.yml +11 -0
  314. package/templates/stacks/php-laravel/.env.example +41 -0
  315. package/templates/stacks/php-laravel/.github/workflows/dare-ci.yml +43 -0
  316. package/templates/stacks/php-laravel/README.md.hbs +36 -0
  317. package/templates/stacks/php-laravel/app/Http/Controllers/Api/AuthController.php +36 -0
  318. package/templates/stacks/php-laravel/app/Http/Controllers/Api/UsersController.php +33 -0
  319. package/templates/stacks/php-laravel/app/Http/Requests/CreateUserRequest.php +26 -0
  320. package/templates/stacks/php-laravel/app/Http/Requests/LoginRequest.php +34 -0
  321. package/templates/stacks/php-laravel/app/Llm/Contracts/LlmProvider.php +12 -0
  322. package/templates/stacks/php-laravel/app/Llm/Providers/DummyProvider.php +13 -0
  323. package/templates/stacks/php-laravel/app/Llm/Providers/OpenAiProvider.php +33 -0
  324. package/templates/stacks/php-laravel/app/Models/User.php +44 -0
  325. package/templates/stacks/php-laravel/app/Repositories/UsersRepository.php +32 -0
  326. package/templates/stacks/php-laravel/app/Services/AuthService.php +37 -0
  327. package/templates/stacks/php-laravel/app/Services/UsersService.php +57 -0
  328. package/templates/stacks/php-laravel/artisan +12 -0
  329. package/templates/stacks/php-laravel/bootstrap/app.php +29 -0
  330. package/templates/stacks/php-laravel/bootstrap/providers.php +5 -0
  331. package/templates/stacks/php-laravel/composer.json.hbs +58 -0
  332. package/templates/stacks/php-laravel/config/l5-swagger.php +41 -0
  333. package/templates/stacks/php-laravel/config/reverb.php +34 -0
  334. package/templates/stacks/php-laravel/config/sanctum.php +15 -0
  335. package/templates/stacks/php-laravel/database/migrations/2026_06_01_000001_create_users_table.php +27 -0
  336. package/templates/stacks/php-laravel/database/seeders/DatabaseSeeder.php +21 -0
  337. package/templates/stacks/php-laravel/gitignore +23 -0
  338. package/templates/stacks/php-laravel/llms.txt.hbs +53 -0
  339. package/templates/stacks/php-laravel/openapi.json.hbs +43 -0
  340. package/templates/stacks/php-laravel/phpstan.neon +9 -0
  341. package/templates/stacks/php-laravel/routes/api.php +13 -0
  342. package/templates/stacks/php-laravel/routes/channels.php +7 -0
  343. package/templates/stacks/php-laravel/tests/Feature/AuthTest.php +35 -0
  344. package/templates/stacks/php-laravel/tests/Feature/UsersTest.php +30 -0
  345. package/templates/stacks/php-laravel/tests/Pest.php +5 -0
  346. package/templates/stacks/python-fastapi/.dare/skills.yml +11 -0
  347. package/templates/stacks/python-fastapi/.env.example +21 -0
  348. package/templates/stacks/python-fastapi/.github/workflows/dare-ci.yml +43 -0
  349. package/templates/stacks/python-fastapi/README.md.j2 +35 -0
  350. package/templates/stacks/python-fastapi/alembic/env.py +46 -0
  351. package/templates/stacks/python-fastapi/alembic/script.py.mako +26 -0
  352. package/templates/stacks/python-fastapi/alembic/versions/0001_create_users.py.j2 +37 -0
  353. package/templates/stacks/python-fastapi/alembic.ini.j2 +39 -0
  354. package/templates/stacks/python-fastapi/app/__init__.py +0 -0
  355. package/templates/stacks/python-fastapi/app/core/__init__.py +0 -0
  356. package/templates/stacks/python-fastapi/app/core/config.py +24 -0
  357. package/templates/stacks/python-fastapi/app/core/security.py +34 -0
  358. package/templates/stacks/python-fastapi/app/db/__init__.py +0 -0
  359. package/templates/stacks/python-fastapi/app/db/session.py +22 -0
  360. package/templates/stacks/python-fastapi/app/main.py.j2 +36 -0
  361. package/templates/stacks/python-fastapi/app/models/__init__.py +3 -0
  362. package/templates/stacks/python-fastapi/app/models/user.py +30 -0
  363. package/templates/stacks/python-fastapi/app/repositories/__init__.py +0 -0
  364. package/templates/stacks/python-fastapi/app/repositories/user_repository.py +34 -0
  365. package/templates/stacks/python-fastapi/app/routers/__init__.py +0 -0
  366. package/templates/stacks/python-fastapi/app/routers/auth.py +37 -0
  367. package/templates/stacks/python-fastapi/app/routers/users.py +46 -0
  368. package/templates/stacks/python-fastapi/app/schemas/__init__.py +0 -0
  369. package/templates/stacks/python-fastapi/app/schemas/user.py +56 -0
  370. package/templates/stacks/python-fastapi/app/services/__init__.py +0 -0
  371. package/templates/stacks/python-fastapi/app/services/auth_service.py +22 -0
  372. package/templates/stacks/python-fastapi/app/services/user_service.py +31 -0
  373. package/templates/stacks/python-fastapi/gitignore +12 -0
  374. package/templates/stacks/python-fastapi/llms.txt.j2 +53 -0
  375. package/templates/stacks/python-fastapi/openapi.json.j2 +43 -0
  376. package/templates/stacks/python-fastapi/pyproject.toml.j2 +45 -0
  377. package/templates/stacks/python-fastapi/tests/__init__.py +0 -0
  378. package/templates/stacks/python-fastapi/tests/test_auth.py +22 -0
  379. package/templates/stacks/ruby-rails-8/.dare/skills.yml +50 -0
  380. package/templates/stacks/ruby-rails-8/.env.example +20 -0
  381. package/templates/stacks/ruby-rails-8/.github/workflows/dare-ci.yml +112 -0
  382. package/templates/stacks/ruby-rails-8/Gemfile.erb +61 -0
  383. package/templates/stacks/ruby-rails-8/app/channels/application_cable/channel.rb +11 -0
  384. package/templates/stacks/ruby-rails-8/app/channels/application_cable/connection.rb +34 -0
  385. package/templates/stacks/ruby-rails-8/app/channels/dare_updates_channel.rb +18 -0
  386. package/templates/stacks/ruby-rails-8/app/channels/user_updates_channel.rb +23 -0
  387. package/templates/stacks/ruby-rails-8/app/controllers/application_controller.rb +44 -0
  388. package/templates/stacks/ruby-rails-8/app/controllers/concerns/problem_details.rb +93 -0
  389. package/templates/stacks/ruby-rails-8/app/handlers/summarize_handler.rb +33 -0
  390. package/templates/stacks/ruby-rails-8/app/handlers/users_handler.rb +68 -0
  391. package/templates/stacks/ruby-rails-8/app/llm/cache/llm_cache.rb +44 -0
  392. package/templates/stacks/ruby-rails-8/app/llm/prompts/prompt_loader.rb +54 -0
  393. package/templates/stacks/ruby-rails-8/app/llm/prompts/summarize_v1.jinja2 +12 -0
  394. package/templates/stacks/ruby-rails-8/app/llm/providers/dummy_provider.rb +35 -0
  395. package/templates/stacks/ruby-rails-8/app/llm/providers/llm_provider.rb +67 -0
  396. package/templates/stacks/ruby-rails-8/app/llm/providers/openai_provider.rb +62 -0
  397. package/templates/stacks/ruby-rails-8/app/llm/rate_limit/token_bucket.rb +82 -0
  398. package/templates/stacks/ruby-rails-8/app/llm/validators/summarize_output_schema.json +21 -0
  399. package/templates/stacks/ruby-rails-8/app/llm/validators/validator.rb +52 -0
  400. package/templates/stacks/ruby-rails-8/app/models/user.rb +36 -0
  401. package/templates/stacks/ruby-rails-8/app/presenters/user_presenter.rb +48 -0
  402. package/templates/stacks/ruby-rails-8/app/repositories/document_repository.rb +57 -0
  403. package/templates/stacks/ruby-rails-8/app/repositories/user_repository.rb +73 -0
  404. package/templates/stacks/ruby-rails-8/app/services/create_user_service.rb +67 -0
  405. package/templates/stacks/ruby-rails-8/app/services/realtime_service.rb +53 -0
  406. package/templates/stacks/ruby-rails-8/app/services/summarize_document_service.rb +57 -0
  407. package/templates/stacks/ruby-rails-8/config/dare.yml +42 -0
  408. package/templates/stacks/ruby-rails-8/config/initializers/dare.rb +31 -0
  409. package/templates/stacks/ruby-rails-8/config/initializers/rack_attack.rb +64 -0
  410. package/templates/stacks/ruby-rails-8/config/initializers/rswag_api.rb +12 -0
  411. package/templates/stacks/ruby-rails-8/lib/tasks/dare.rake +159 -0
  412. package/templates/stacks/ruby-rails-8/llms.txt.erb +69 -0
  413. package/templates/stacks/ruby-rails-8/spec/api/summarize_spec.rb +56 -0
  414. package/templates/stacks/ruby-rails-8/spec/api/users_spec.rb +72 -0
  415. package/templates/stacks/ruby-rails-8/spec/channels/dare_updates_channel_spec.rb +61 -0
  416. package/templates/stacks/ruby-rails-8/spec/channels/user_updates_channel_spec.rb +56 -0
  417. package/templates/stacks/ruby-rails-8/spec/factories/users.rb +27 -0
  418. package/templates/stacks/ruby-rails-8/spec/handlers/users_handler_spec.rb +88 -0
  419. package/templates/stacks/ruby-rails-8/spec/rails_helper.rb +31 -0
  420. package/templates/stacks/ruby-rails-8/spec/services/create_user_service_spec.rb +88 -0
  421. package/templates/stacks/ruby-rails-8/spec/services/summarize_document_service_spec.rb +142 -0
  422. package/templates/stacks/ruby-rails-8/spec/swagger_helper.rb +73 -0
  423. package/templates/stacks/rust-axum/.dare/skills.yml +11 -0
  424. package/templates/stacks/rust-axum/.env.example +26 -0
  425. package/templates/stacks/rust-axum/.github/workflows/dare-ci.yml +40 -0
  426. package/templates/stacks/rust-axum/Cargo.toml.tera +53 -0
  427. package/templates/stacks/rust-axum/README.md.tera +37 -0
  428. package/templates/stacks/rust-axum/gitignore +5 -0
  429. package/templates/stacks/rust-axum/llms.txt.tera +54 -0
  430. package/templates/stacks/rust-axum/migrations/0001_create_users.sql +13 -0
  431. package/templates/stacks/rust-axum/openapi.json.tera +46 -0
  432. package/templates/stacks/rust-axum/src/config.rs +45 -0
  433. package/templates/stacks/rust-axum/src/errors.rs +48 -0
  434. package/templates/stacks/rust-axum/src/handlers/auth.rs +48 -0
  435. package/templates/stacks/rust-axum/src/handlers/mod.rs +3 -0
  436. package/templates/stacks/rust-axum/src/handlers/users.rs +81 -0
  437. package/templates/stacks/rust-axum/src/handlers/ws.rs +24 -0
  438. package/templates/stacks/rust-axum/src/lib.rs +19 -0
  439. package/templates/stacks/rust-axum/src/llm/mod.rs +1 -0
  440. package/templates/stacks/rust-axum/src/llm/provider.rs +48 -0
  441. package/templates/stacks/rust-axum/src/main.rs.tera +64 -0
  442. package/templates/stacks/rust-axum/src/middleware/auth.rs +20 -0
  443. package/templates/stacks/rust-axum/src/middleware/mod.rs +2 -0
  444. package/templates/stacks/rust-axum/src/middleware/rate_limit.rs +27 -0
  445. package/templates/stacks/rust-axum/src/models/mod.rs +1 -0
  446. package/templates/stacks/rust-axum/src/models/user.rs +13 -0
  447. package/templates/stacks/rust-axum/src/repositories/mod.rs +1 -0
  448. package/templates/stacks/rust-axum/src/repositories/user_repository.rs +62 -0
  449. package/templates/stacks/rust-axum/src/services/auth_service.rs +50 -0
  450. package/templates/stacks/rust-axum/src/services/mod.rs +2 -0
  451. package/templates/stacks/rust-axum/src/services/user_service.rs +53 -0
  452. package/templates/stacks/rust-axum/tests/integration_test.rs.tera +13 -0
  453. package/LICENSE +0 -21
@@ -0,0 +1,6 @@
1
+ //! Public crate surface — re-exported for tests and the bin.
2
+ pub mod cli;
3
+ pub mod prompts;
4
+ pub mod server;
5
+ pub mod tools;
6
+ pub mod transports;
@@ -0,0 +1,30 @@
1
+ //! {{ projectName }} — MCP server entrypoint.
2
+ use clap::Parser;
3
+ use tracing_subscriber::EnvFilter;
4
+
5
+ use {{ crateName }}::cli::{Cli, Transport};
6
+ use {{ crateName }}::tools;
7
+ use {{ crateName }}::transports;
8
+
9
+ #[tokio::main]
10
+ async fn main() -> anyhow::Result<()> {
11
+ let cli = Cli::parse();
12
+
13
+ // --json --list-tools short-circuits before starting any transport (M-03).
14
+ if cli.list_tools && cli.json {
15
+ let inventory = tools::inventory_json();
16
+ println!("{}", serde_json::to_string_pretty(&inventory)?);
17
+ return Ok(());
18
+ }
19
+
20
+ tracing_subscriber::fmt()
21
+ .with_env_filter(EnvFilter::from_default_env())
22
+ .with_writer(std::io::stderr)
23
+ .init();
24
+
25
+ match cli.transport {
26
+ Transport::Stdio => transports::stdio::run().await,
27
+ Transport::Sse => transports::sse::run(&cli.host, cli.port).await,
28
+ Transport::Http => transports::http::run(&cli.host, cli.port).await,
29
+ }
30
+ }
@@ -0,0 +1 @@
1
+ pub mod summarize;
@@ -0,0 +1,5 @@
1
+ //! Summarize prompt — returns the templated user-message body.
2
+
3
+ pub fn summarize(text: &str) -> String {
4
+ format!("Summarize the following text in 1-2 sentences.\n\n{text}")
5
+ }
@@ -0,0 +1,38 @@
1
+ //! MCP service definition — wires tools + prompts via the rmcp SDK.
2
+ //!
3
+ //! NOTE: the rmcp API is pre-1.0; the exact handler-registration surface may
4
+ //! shift between releases. The structure below keeps the SDK glue thin and the
5
+ //! business logic in `tools::` / `prompts::` (pure, unit-tested) so a breaking
6
+ //! rmcp change only touches this file.
7
+ use rmcp::{
8
+ handler::server::ServerHandler,
9
+ model::{ServerCapabilities, ServerInfo},
10
+ };
11
+
12
+ use crate::tools;
13
+
14
+ #[derive(Clone, Default)]
15
+ pub struct DareMcpService;
16
+
17
+ impl ServerHandler for DareMcpService {
18
+ fn get_info(&self) -> ServerInfo {
19
+ ServerInfo {
20
+ instructions: Some(
21
+ "DARE-shaped MCP server ({{ projectName }}). Tools: echo. Prompts: summarize."
22
+ .into(),
23
+ ),
24
+ capabilities: ServerCapabilities::builder()
25
+ .enable_tools()
26
+ .enable_prompts()
27
+ .build(),
28
+ ..Default::default()
29
+ }
30
+ }
31
+ }
32
+
33
+ /// Convenience constructor used by every transport.
34
+ pub fn build_service() -> DareMcpService {
35
+ // Touch the tool inventory so a missing tool module is a compile error.
36
+ let _ = tools::inventory_json();
37
+ DareMcpService
38
+ }
@@ -0,0 +1,18 @@
1
+ //! Echo tool — pure function, unit-tested independently of the SDK.
2
+
3
+ /// Returns its input verbatim.
4
+ ///
5
+ /// # Errors
6
+ /// Returns `Err` when `text` is empty.
7
+ pub fn echo(text: &str) -> Result<String, EchoError> {
8
+ if text.is_empty() {
9
+ return Err(EchoError::Empty);
10
+ }
11
+ Ok(text.to_string())
12
+ }
13
+
14
+ #[derive(Debug, thiserror::Error, PartialEq, Eq)]
15
+ pub enum EchoError {
16
+ #[error("text must be a non-empty string")]
17
+ Empty,
18
+ }
@@ -0,0 +1,22 @@
1
+ pub mod echo;
2
+
3
+ use serde_json::{json, Value};
4
+
5
+ /// Machine-readable tool inventory for `--json --list-tools` (M-03).
6
+ pub fn inventory_json() -> Value {
7
+ json!({
8
+ "tools": [
9
+ {
10
+ "name": "echo",
11
+ "description": "Returns its input. Canonical smoke test for an MCP server.",
12
+ "inputSchema": {
13
+ "type": "object",
14
+ "required": ["text"],
15
+ "properties": {
16
+ "text": { "type": "string", "minLength": 1 }
17
+ }
18
+ }
19
+ }
20
+ ]
21
+ })
22
+ }
@@ -0,0 +1,27 @@
1
+ //! Streamable HTTP transport.
2
+ //!
3
+ //! rmcp exposes a streamable-http server behind a feature flag in recent
4
+ //! releases (pre-1.0). This wrapper centralizes the bind logic; swap the route
5
+ //! bodies for rmcp's StreamableHttpService integration for your version.
6
+ use std::net::SocketAddr;
7
+
8
+ use crate::server::build_service;
9
+
10
+ pub async fn run(host: &str, port: u16) -> anyhow::Result<()> {
11
+ let addr: SocketAddr = format!("{host}:{port}").parse()?;
12
+ tracing::info!("mcp/http listening on {addr}");
13
+
14
+ let _service = build_service();
15
+
16
+ let app = axum::Router::new()
17
+ .route(
18
+ "/messages",
19
+ axum::routing::post(|| async { "MCP streamable-http endpoint — wire rmcp here" })
20
+ .get(|| async { "MCP streamable-http endpoint — wire rmcp here" }),
21
+ )
22
+ .layer(tower_http::cors::CorsLayer::permissive());
23
+
24
+ let listener = tokio::net::TcpListener::bind(addr).await?;
25
+ axum::serve(listener, app).await?;
26
+ Ok(())
27
+ }
@@ -0,0 +1,3 @@
1
+ pub mod http;
2
+ pub mod sse;
3
+ pub mod stdio;
@@ -0,0 +1,33 @@
1
+ //! SSE-over-HTTP transport.
2
+ //!
3
+ //! rmcp exposes an SSE server behind the `transport-sse-server` feature in
4
+ //! recent releases; the surface is pre-1.0. This wrapper keeps the bind logic
5
+ //! in one place. If the SDK feature name or constructor changes, only this
6
+ //! file needs editing.
7
+ use std::net::SocketAddr;
8
+
9
+ use crate::server::build_service;
10
+
11
+ pub async fn run(host: &str, port: u16) -> anyhow::Result<()> {
12
+ let addr: SocketAddr = format!("{host}:{port}").parse()?;
13
+ tracing::info!("mcp/sse listening on {addr}");
14
+
15
+ // Build the service so capabilities are validated even if the concrete
16
+ // SSE wiring below is adjusted for your rmcp version.
17
+ let _service = build_service();
18
+
19
+ // Minimal axum app that documents where the SSE endpoints live. Replace
20
+ // the route bodies with rmcp's SSE server integration for your version
21
+ // (e.g. rmcp::transport::sse_server::SseServer::serve(addr)).
22
+ let app = axum::Router::new()
23
+ .route("/sse", axum::routing::get(|| async { "MCP SSE endpoint — wire rmcp SseServer here" }))
24
+ .route(
25
+ "/messages",
26
+ axum::routing::post(|| async { "MCP message endpoint — wire rmcp SseServer here" }),
27
+ )
28
+ .layer(tower_http::cors::CorsLayer::permissive());
29
+
30
+ let listener = tokio::net::TcpListener::bind(addr).await?;
31
+ axum::serve(listener, app).await?;
32
+ Ok(())
33
+ }
@@ -0,0 +1,14 @@
1
+ //! stdio transport — default for local agents.
2
+ //!
3
+ //! Uses rmcp's stdio server. The exact serve call may differ across rmcp
4
+ //! versions; adjust here if `cargo build` fails after an SDK bump.
5
+ use rmcp::ServiceExt;
6
+
7
+ use crate::server::build_service;
8
+
9
+ pub async fn run() -> anyhow::Result<()> {
10
+ let service = build_service();
11
+ let server = service.serve((tokio::io::stdin(), tokio::io::stdout())).await?;
12
+ server.waiting().await?;
13
+ Ok(())
14
+ }
@@ -0,0 +1,27 @@
1
+ //! Smoke tests — pure tools/prompts, no SDK or transport needed.
2
+ use {{ crateName }}::prompts::summarize::summarize;
3
+ use {{ crateName }}::tools::echo::{echo, EchoError};
4
+
5
+ #[test]
6
+ fn echo_returns_input() {
7
+ assert_eq!(echo("hello").unwrap(), "hello");
8
+ }
9
+
10
+ #[test]
11
+ fn echo_rejects_empty() {
12
+ assert_eq!(echo(""), Err(EchoError::Empty));
13
+ }
14
+
15
+ #[test]
16
+ fn summarize_includes_input() {
17
+ let out = summarize("long text here");
18
+ assert!(out.contains("long text here"));
19
+ assert!(out.contains("Summarize"));
20
+ }
21
+
22
+ #[test]
23
+ fn tool_inventory_lists_echo() {
24
+ let inv = {{ crateName }}::tools::inventory_json();
25
+ let tools = inv["tools"].as_array().expect("tools array");
26
+ assert!(tools.iter().any(|t| t["name"] == "echo"));
27
+ }
@@ -0,0 +1,11 @@
1
+ version: 1
2
+ skills:
3
+ - id: skill-nestjs-api
4
+ source: skill-nestjs-api
5
+ description: NestJS Layered Design + Prisma + JWT + Swagger
6
+ - id: dare-ax
7
+ source: dare-ax
8
+ description: Agent eXperience invariants (llms.txt, OpenAPI, --json, rate limit)
9
+ - id: dare-layered-design
10
+ source: dare-layered-design
11
+ description: Handler → Service → Repository → Model 4-layer architecture
@@ -0,0 +1,21 @@
1
+ # Application
2
+ PORT=3000
3
+ LOG_LEVEL=info
4
+
5
+ # Database
6
+ DATABASE_URL=postgresql://user:pass@localhost:5432/myapi
7
+
8
+ # JWT auth
9
+ JWT_SECRET=replace-me-in-prod
10
+ JWT_EXPIRES_IN=15m
11
+
12
+ # Password hashing
13
+ BCRYPT_COST=12
14
+
15
+ # Throttler (rate limit)
16
+ RATE_LIMIT_RPM=60
17
+ RATE_LIMIT_TTL=60
18
+
19
+ # LLM provider (optional)
20
+ # LLM_PROVIDER=dummy
21
+ # OPENAI_API_KEY=
@@ -0,0 +1,54 @@
1
+ name: DARE CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ audit:
11
+ name: Audit dependencies
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: pnpm/action-setup@v3
16
+ with:
17
+ version: 9
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: 20
21
+ cache: pnpm
22
+ - run: pnpm install --frozen-lockfile
23
+ - run: pnpm audit --audit-level=high
24
+
25
+ lint:
26
+ name: Lint
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: pnpm/action-setup@v3
31
+ with:
32
+ version: 9
33
+ - uses: actions/setup-node@v4
34
+ with:
35
+ node-version: 20
36
+ cache: pnpm
37
+ - run: pnpm install --frozen-lockfile
38
+ - run: pnpm lint
39
+
40
+ test:
41
+ name: Test
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+ - uses: pnpm/action-setup@v3
46
+ with:
47
+ version: 9
48
+ - uses: actions/setup-node@v4
49
+ with:
50
+ node-version: 20
51
+ cache: pnpm
52
+ - run: pnpm install --frozen-lockfile
53
+ - run: pnpm prisma generate
54
+ - run: pnpm test
@@ -0,0 +1,35 @@
1
+ # {{projectName}}
2
+
3
+ DARE-shaped NestJS API. Layered Design (Handler → Service → Repository → Model).
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ cp .env.example .env
9
+ docker compose up -d postgres
10
+ pnpm install
11
+ pnpm prisma migrate dev --name init
12
+ pnpm prisma db seed
13
+ pnpm start:dev
14
+ ```
15
+
16
+ ## Endpoints
17
+
18
+ - `POST /auth/login` — exchange email/password for JWT
19
+ - `GET /auth/me` — current user (Bearer JWT)
20
+ - `GET /users` — list users (paginated)
21
+ - `POST /users` — create user (admin only)
22
+ - `GET /openapi.json` — OpenAPI 3.1 surface
23
+ - `GET /api` — Swagger UI
24
+
25
+ ## Commands
26
+
27
+ - `pnpm start:dev` — dev with watch
28
+ - `pnpm test` — run tests
29
+ - `pnpm lint` — ESLint
30
+ - `pnpm audit` — dependency audit (fails on HIGH+)
31
+
32
+ ## DARE Method
33
+
34
+ This project was scaffolded with the [DARE Method](https://github.com/dewtech-technologies/dare-method).
35
+ See `.dare/skills.yml` for installed skills, `llms.txt` for agent context.
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ dist
3
+ coverage
4
+ .env
5
+ .env.local
6
+ *.log
7
+ .DS_Store
@@ -0,0 +1,47 @@
1
+ # {{projectName}}
2
+
3
+ DARE-shaped NestJS 10 API. Layered Design: Handler → Service → Repository → Model.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ cp .env.example .env
9
+ docker compose up -d postgres
10
+ pnpm install
11
+ pnpm prisma migrate dev --name init
12
+ pnpm prisma db seed
13
+ pnpm start:dev
14
+ ```
15
+
16
+ ## Commands
17
+
18
+ - `pnpm start:dev` — dev server with watch (port 3000)
19
+ - `pnpm test` — vitest run
20
+ - `pnpm lint` — eslint
21
+ - `pnpm audit` — pnpm audit --audit-level=high
22
+ - `pnpm prisma migrate dev` — apply DB migrations
23
+
24
+ ## Endpoints
25
+
26
+ | Method | Path | Auth | Description |
27
+ |---|---|---|---|
28
+ | POST | `/auth/login` | none | Exchange email+password for JWT |
29
+ | GET | `/auth/me` | Bearer | Current user info |
30
+ | GET | `/users` | Bearer | List users (query: page, limit) |
31
+ | POST | `/users` | Bearer (admin) | Create user |
32
+ | GET | `/openapi.json` | none | OpenAPI 3.1 document |
33
+ | GET | `/api` | none | Swagger UI |
34
+
35
+ ## Layered Design
36
+
37
+ - `src/auth/`, `src/users/` — feature modules
38
+ - Each module has: controller (HTTP), service (logic), repository (DB), dto (validation)
39
+ - Prisma is encapsulated behind repositories; controllers and services never see Prisma directly
40
+
41
+ ## Env vars
42
+
43
+ See `.env.example`. Required: `DATABASE_URL`, `JWT_SECRET`.
44
+
45
+ ## DARE skills
46
+
47
+ See `.dare/skills.yml`.
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/nest-cli",
3
+ "collection": "@nestjs/schematics",
4
+ "sourceRoot": "src",
5
+ "compilerOptions": {
6
+ "plugins": [
7
+ {
8
+ "name": "@nestjs/swagger",
9
+ "options": {
10
+ "introspectComments": true,
11
+ "classValidatorShim": true
12
+ }
13
+ }
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,75 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "{{projectName}}",
5
+ "version": "0.1.0",
6
+ "description": "DARE-shaped NestJS API"
7
+ },
8
+ "paths": {
9
+ "/auth/login": {
10
+ "post": {
11
+ "summary": "Exchange email+password for JWT",
12
+ "requestBody": {
13
+ "required": true,
14
+ "content": {
15
+ "application/json": {
16
+ "schema": {
17
+ "type": "object",
18
+ "required": ["email", "password"],
19
+ "properties": {
20
+ "email": { "type": "string", "format": "email" },
21
+ "password": { "type": "string", "minLength": 8 }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ },
27
+ "responses": {
28
+ "200": {
29
+ "description": "JWT issued",
30
+ "content": {
31
+ "application/json": {
32
+ "schema": {
33
+ "type": "object",
34
+ "properties": {
35
+ "accessToken": { "type": "string" },
36
+ "expiresIn": { "type": "integer" }
37
+ }
38
+ }
39
+ }
40
+ }
41
+ },
42
+ "401": { "description": "Invalid credentials" }
43
+ }
44
+ }
45
+ },
46
+ "/auth/me": {
47
+ "get": {
48
+ "summary": "Current user",
49
+ "security": [{ "bearer": [] }],
50
+ "responses": { "200": { "description": "User info" }, "401": { "description": "Unauthorized" } }
51
+ }
52
+ },
53
+ "/users": {
54
+ "get": {
55
+ "summary": "List users",
56
+ "security": [{ "bearer": [] }],
57
+ "parameters": [
58
+ { "name": "page", "in": "query", "schema": { "type": "integer", "minimum": 1, "default": 1 } },
59
+ { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }
60
+ ],
61
+ "responses": { "200": { "description": "Page of users" } }
62
+ },
63
+ "post": {
64
+ "summary": "Create user (admin)",
65
+ "security": [{ "bearer": [] }],
66
+ "responses": { "201": { "description": "Created" }, "403": { "description": "Forbidden" } }
67
+ }
68
+ }
69
+ },
70
+ "components": {
71
+ "securitySchemes": {
72
+ "bearer": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }
73
+ }
74
+ }
75
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "DARE-shaped NestJS API",
6
+ "scripts": {
7
+ "build": "nest build",
8
+ "start": "nest start",
9
+ "start:dev": "nest start --watch",
10
+ "start:prod": "node dist/main",
11
+ "test": "vitest run",
12
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
13
+ "lint": "eslint src --ext .ts",
14
+ "audit": "pnpm audit --audit-level=high"
15
+ },
16
+ "dependencies": {
17
+ "@nestjs/common": "^10.3.0",
18
+ "@nestjs/config": "^3.2.0",
19
+ "@nestjs/core": "^10.3.0",
20
+ "@nestjs/jwt": "^10.2.0",
21
+ "@nestjs/passport": "^10.0.3",
22
+ "@nestjs/platform-express": "^10.3.0",
23
+ "@nestjs/swagger": "^7.3.0",
24
+ "@nestjs/throttler": "^6.0.0",
25
+ "@prisma/client": "^5.14.0",
26
+ "bcrypt": "^5.1.1",
27
+ "class-transformer": "^0.5.1",
28
+ "class-validator": "^0.14.1",
29
+ "nestjs-pino": "^4.0.0",
30
+ "passport": "^0.7.0",
31
+ "passport-jwt": "^4.0.1",
32
+ "pino-http": "^9.0.0",
33
+ "pino-pretty": "^11.0.0",
34
+ "reflect-metadata": "^0.2.0",
35
+ "rxjs": "^7.8.0"
36
+ },
37
+ "devDependencies": {
38
+ "@nestjs/cli": "^10.3.2",
39
+ "@nestjs/schematics": "^10.1.1",
40
+ "@nestjs/testing": "^10.3.0",
41
+ "@types/bcrypt": "^5.0.0",
42
+ "@types/express": "^4.17.0",
43
+ "@types/node": "^20.11.0",
44
+ "@types/passport-jwt": "^4.0.1",
45
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
46
+ "@typescript-eslint/parser": "^7.0.0",
47
+ "eslint": "^8.57.0",
48
+ "prisma": "^5.14.0",
49
+ "ts-node": "^10.9.2",
50
+ "tsx": "^4.16.0",
51
+ "typescript": "^5.4.5",
52
+ "vitest": "^1.6.0"
53
+ },
54
+ "prisma": {
55
+ "seed": "tsx prisma/seed.ts"
56
+ }
57
+ }
@@ -0,0 +1,25 @@
1
+ // SPDX-License-Identifier: MIT
2
+ generator client {
3
+ provider = "prisma-client-js"
4
+ }
5
+
6
+ datasource db {
7
+ provider = "postgresql"
8
+ url = env("DATABASE_URL")
9
+ }
10
+
11
+ model User {
12
+ id String @id @default(uuid())
13
+ email String @unique
14
+ password String
15
+ role Role @default(USER)
16
+ createdAt DateTime @default(now())
17
+ updatedAt DateTime @updatedAt
18
+
19
+ @@index([email])
20
+ }
21
+
22
+ enum Role {
23
+ USER
24
+ ADMIN
25
+ }
@@ -0,0 +1,25 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+ import * as bcrypt from 'bcrypt';
3
+
4
+ const prisma = new PrismaClient();
5
+
6
+ async function main(): Promise<void> {
7
+ const cost = Number(process.env.BCRYPT_COST ?? 12);
8
+ await prisma.user.upsert({
9
+ where: { email: 'admin@{{projectName}}.local' },
10
+ update: {},
11
+ create: {
12
+ email: 'admin@{{projectName}}.local',
13
+ password: await bcrypt.hash('Admin0Pass', cost),
14
+ role: 'ADMIN',
15
+ },
16
+ });
17
+ console.log('[seed] admin user ready');
18
+ }
19
+
20
+ main()
21
+ .catch((err) => {
22
+ console.error(err);
23
+ process.exit(1);
24
+ })
25
+ .finally(() => prisma.$disconnect());
@@ -0,0 +1,39 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { ConfigModule } from '@nestjs/config';
3
+ import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
4
+ import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
5
+ import { LoggerModule } from 'nestjs-pino';
6
+ import { AuthModule } from './auth/auth.module.js';
7
+ import { UsersModule } from './users/users.module.js';
8
+ import { PrismaModule } from './prisma/prisma.module.js';
9
+ import { JsonResponseInterceptor } from './common/interceptors/json-response.interceptor.js';
10
+
11
+ @Module({
12
+ imports: [
13
+ ConfigModule.forRoot({ isGlobal: true }),
14
+ LoggerModule.forRoot({
15
+ pinoHttp: {
16
+ level: process.env.LOG_LEVEL ?? 'info',
17
+ transport:
18
+ process.env.NODE_ENV !== 'production'
19
+ ? { target: 'pino-pretty' }
20
+ : undefined,
21
+ },
22
+ }),
23
+ // Rate limit — knobs in env.
24
+ ThrottlerModule.forRoot([
25
+ {
26
+ ttl: Number(process.env.RATE_LIMIT_TTL ?? 60) * 1000,
27
+ limit: Number(process.env.RATE_LIMIT_RPM ?? 60),
28
+ },
29
+ ]),
30
+ PrismaModule,
31
+ AuthModule,
32
+ UsersModule,
33
+ ],
34
+ providers: [
35
+ { provide: APP_GUARD, useClass: ThrottlerGuard },
36
+ { provide: APP_INTERCEPTOR, useClass: JsonResponseInterceptor },
37
+ ],
38
+ })
39
+ export class AppModule {}