@dewtech/dare-cli 3.3.0 → 3.4.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 (582) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +764 -764
  3. package/dist/__tests__/confidence.test.js +13 -13
  4. package/dist/__tests__/dag-converter.test.js +56 -56
  5. package/dist/__tests__/mcp-server/server.test.js +3 -16
  6. package/dist/__tests__/mcp-server/server.test.js.map +1 -1
  7. package/dist/__tests__/project-generator.test.js +2 -2
  8. package/dist/__tests__/project-generator.test.js.map +1 -1
  9. package/dist/__tests__/refine.test.js +49 -49
  10. package/dist/__tests__/reverse-collection.test.js +6 -6
  11. package/dist/__tests__/review.test.js +38 -38
  12. package/dist/__tests__/security-hardening.test.d.ts +2 -0
  13. package/dist/__tests__/security-hardening.test.d.ts.map +1 -0
  14. package/dist/__tests__/security-hardening.test.js +101 -0
  15. package/dist/__tests__/security-hardening.test.js.map +1 -0
  16. package/dist/__tests__/validate.test.js +65 -65
  17. package/dist/bin/dare.js +0 -0
  18. package/dist/commands/__tests__/init-validation.test.d.ts +2 -0
  19. package/dist/commands/__tests__/init-validation.test.d.ts.map +1 -0
  20. package/dist/commands/__tests__/init-validation.test.js +81 -0
  21. package/dist/commands/__tests__/init-validation.test.js.map +1 -0
  22. package/dist/commands/__tests__/init.integration.spec.js +6 -4
  23. package/dist/commands/__tests__/init.integration.spec.js.map +1 -1
  24. package/dist/commands/__tests__/init.spec.d.ts +2 -0
  25. package/dist/commands/__tests__/init.spec.d.ts.map +1 -0
  26. package/dist/commands/__tests__/init.spec.js +88 -0
  27. package/dist/commands/__tests__/init.spec.js.map +1 -0
  28. package/dist/commands/blueprint.js +122 -122
  29. package/dist/commands/design.js +20 -20
  30. package/dist/commands/init-validation.d.ts +22 -0
  31. package/dist/commands/init-validation.d.ts.map +1 -0
  32. package/dist/commands/init-validation.js +54 -0
  33. package/dist/commands/init-validation.js.map +1 -0
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +26 -10
  36. package/dist/commands/init.js.map +1 -1
  37. package/dist/graphrag/graph-rag.js +24 -24
  38. package/dist/mcp-server/__tests__/auth.test.d.ts +2 -0
  39. package/dist/mcp-server/__tests__/auth.test.d.ts.map +1 -0
  40. package/dist/mcp-server/__tests__/auth.test.js +72 -0
  41. package/dist/mcp-server/__tests__/auth.test.js.map +1 -0
  42. package/dist/mcp-server/__tests__/boot-config.test.d.ts +2 -0
  43. package/dist/mcp-server/__tests__/boot-config.test.d.ts.map +1 -0
  44. package/dist/mcp-server/__tests__/boot-config.test.js +29 -0
  45. package/dist/mcp-server/__tests__/boot-config.test.js.map +1 -0
  46. package/dist/mcp-server/__tests__/error-sanitize.test.d.ts +2 -0
  47. package/dist/mcp-server/__tests__/error-sanitize.test.d.ts.map +1 -0
  48. package/dist/mcp-server/__tests__/error-sanitize.test.js +66 -0
  49. package/dist/mcp-server/__tests__/error-sanitize.test.js.map +1 -0
  50. package/dist/mcp-server/__tests__/path-confinement.test.d.ts +2 -0
  51. package/dist/mcp-server/__tests__/path-confinement.test.d.ts.map +1 -0
  52. package/dist/mcp-server/__tests__/path-confinement.test.js +135 -0
  53. package/dist/mcp-server/__tests__/path-confinement.test.js.map +1 -0
  54. package/dist/mcp-server/bin/server.js +18 -6
  55. package/dist/mcp-server/bin/server.js.map +1 -1
  56. package/dist/mcp-server/boot-config.d.ts +6 -0
  57. package/dist/mcp-server/boot-config.d.ts.map +1 -0
  58. package/dist/mcp-server/boot-config.js +17 -0
  59. package/dist/mcp-server/boot-config.js.map +1 -0
  60. package/dist/mcp-server/middleware/auth.d.ts +10 -0
  61. package/dist/mcp-server/middleware/auth.d.ts.map +1 -0
  62. package/dist/mcp-server/middleware/auth.js +44 -0
  63. package/dist/mcp-server/middleware/auth.js.map +1 -0
  64. package/dist/mcp-server/middleware/cors.d.ts +6 -0
  65. package/dist/mcp-server/middleware/cors.d.ts.map +1 -0
  66. package/dist/mcp-server/middleware/cors.js +30 -0
  67. package/dist/mcp-server/middleware/cors.js.map +1 -0
  68. package/dist/mcp-server/middleware/error-handler.d.ts +11 -0
  69. package/dist/mcp-server/middleware/error-handler.d.ts.map +1 -0
  70. package/dist/mcp-server/middleware/error-handler.js +14 -0
  71. package/dist/mcp-server/middleware/error-handler.js.map +1 -0
  72. package/dist/mcp-server/server.d.ts +7 -2
  73. package/dist/mcp-server/server.d.ts.map +1 -1
  74. package/dist/mcp-server/server.js +185 -105
  75. package/dist/mcp-server/server.js.map +1 -1
  76. package/dist/skills/registry-mock.json +109 -109
  77. package/dist/skills/tests/manifest.spec.js +20 -20
  78. package/dist/stacks/__tests__/dna-emitter.spec.js +6 -6
  79. package/dist/stacks/dna-emitter.js +69 -69
  80. package/dist/stacks/ruby-rails-8/scaffold.js +15 -15
  81. package/dist/utils/project-generator.d.ts.map +1 -1
  82. package/dist/utils/project-generator.js +254 -252
  83. package/dist/utils/project-generator.js.map +1 -1
  84. package/dist/utils/stack-bootstrap.js +371 -371
  85. package/dist/utils/templates.js +394 -394
  86. package/dist/verification/__tests__/anti-tamper.test.js +13 -13
  87. package/package.json +96 -93
  88. package/templates/DARE-dag-example.yaml +280 -280
  89. package/templates/UPDATE-MANIFEST.json +68 -68
  90. package/templates/backend/node-nestjs/.env.example +9 -9
  91. package/templates/backend/node-nestjs/nest-cli.json +8 -8
  92. package/templates/backend/node-nestjs/package.json +50 -50
  93. package/templates/backend/node-nestjs/src/app.controller.ts +12 -12
  94. package/templates/backend/node-nestjs/src/app.module.ts +15 -15
  95. package/templates/backend/node-nestjs/src/app.service.ts +8 -8
  96. package/templates/backend/node-nestjs/src/main.ts +24 -24
  97. package/templates/backend/node-nestjs/tsconfig.json +21 -21
  98. package/templates/backend/php-laravel/.env.example +22 -22
  99. package/templates/backend/php-laravel/app/Http/Controllers/HealthController.php +15 -15
  100. package/templates/backend/php-laravel/composer.json +40 -40
  101. package/templates/backend/python-fastapi/.env.example +4 -4
  102. package/templates/backend/python-fastapi/app/api/router.py +8 -8
  103. package/templates/backend/python-fastapi/app/core/config.py +20 -20
  104. package/templates/backend/python-fastapi/main.py +35 -35
  105. package/templates/backend/python-fastapi/requirements.txt +13 -13
  106. package/templates/backend/rust-axum/.env.example +3 -3
  107. package/templates/backend/rust-axum/Cargo.toml +23 -23
  108. package/templates/backend/rust-axum/src/errors.rs +30 -30
  109. package/templates/backend/rust-axum/src/main.rs +32 -32
  110. package/templates/backend/rust-axum/src/routes.rs +6 -6
  111. package/templates/frontend/leptos-csr/.cargo/config.toml +2 -2
  112. package/templates/frontend/leptos-csr/Cargo.toml +16 -16
  113. package/templates/frontend/leptos-csr/Trunk.toml +10 -10
  114. package/templates/frontend/leptos-csr/index.html +11 -11
  115. package/templates/frontend/leptos-csr/src/lib.rs +20 -20
  116. package/templates/frontend/leptos-csr/style/main.scss +19 -19
  117. package/templates/frontend/leptos-fullstack/.cargo/config.toml +4 -4
  118. package/templates/frontend/leptos-fullstack/Cargo.toml +56 -56
  119. package/templates/frontend/leptos-fullstack/src/app.rs +49 -49
  120. package/templates/frontend/leptos-fullstack/src/lib.rs +9 -9
  121. package/templates/frontend/leptos-fullstack/src/main.rs +29 -29
  122. package/templates/frontend/leptos-fullstack/style/main.scss +19 -19
  123. package/templates/frontend/react/index.html +12 -12
  124. package/templates/frontend/react/package.json +35 -35
  125. package/templates/frontend/react/src/App.tsx +25 -25
  126. package/templates/frontend/react/src/main.tsx +9 -9
  127. package/templates/frontend/vue/package.json +32 -32
  128. package/templates/frontend/vue/src/App.vue +7 -7
  129. package/templates/frontend/vue/src/main.ts +10 -10
  130. package/templates/frontend/vue/src/router/index.ts +14 -14
  131. package/templates/frontend/vue/src/views/HomeView.vue +6 -6
  132. package/templates/hooks/pre-commit-dare-validate +24 -24
  133. package/templates/ide/antigravity/.agents/skills/dare-ax/SKILL.md +152 -152
  134. package/templates/ide/antigravity/.agents/skills/dare-bench/SKILL.md +21 -21
  135. package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +368 -368
  136. package/templates/ide/antigravity/.agents/skills/dare-bootstrap/SKILL.md +32 -32
  137. package/templates/ide/antigravity/.agents/skills/dare-bugfix-design/SKILL.md +76 -76
  138. package/templates/ide/antigravity/.agents/skills/dare-dag/SKILL.md +32 -32
  139. package/templates/ide/antigravity/.agents/skills/dare-dag-build/SKILL.md +154 -154
  140. package/templates/ide/antigravity/.agents/skills/dare-dag-run/SKILL.md +130 -130
  141. package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +203 -203
  142. package/templates/ide/antigravity/.agents/skills/dare-design/SKILL.md +180 -180
  143. package/templates/ide/antigravity/.agents/skills/dare-discover/SKILL.md +33 -33
  144. package/templates/ide/antigravity/.agents/skills/dare-dna/SKILL.md +63 -63
  145. package/templates/ide/antigravity/.agents/skills/dare-docker/SKILL.md +315 -315
  146. package/templates/ide/antigravity/.agents/skills/dare-execute/SKILL.md +264 -264
  147. package/templates/ide/antigravity/.agents/skills/dare-feature-design/SKILL.md +74 -74
  148. package/templates/ide/antigravity/.agents/skills/dare-frontend-design/SKILL.md +192 -192
  149. package/templates/ide/antigravity/.agents/skills/dare-graph/SKILL.md +35 -35
  150. package/templates/ide/antigravity/.agents/skills/dare-info/SKILL.md +31 -31
  151. package/templates/ide/antigravity/.agents/skills/dare-init/SKILL.md +35 -35
  152. package/templates/ide/antigravity/.agents/skills/dare-laravel-api/SKILL.md +337 -337
  153. package/templates/ide/antigravity/.agents/skills/dare-layered-design/SKILL.md +166 -166
  154. package/templates/ide/antigravity/.agents/skills/dare-llm-integration/SKILL.md +217 -217
  155. package/templates/ide/antigravity/.agents/skills/dare-migrate/SKILL.md +61 -61
  156. package/templates/ide/antigravity/.agents/skills/dare-quality-telemetry/SKILL.md +187 -187
  157. package/templates/ide/antigravity/.agents/skills/dare-realtime/SKILL.md +217 -217
  158. package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +114 -114
  159. package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +108 -108
  160. package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -111
  161. package/templates/ide/antigravity/.agents/skills/dare-rust-leptos/SKILL.md +263 -263
  162. package/templates/ide/antigravity/.agents/skills/dare-rust-workspace/SKILL.md +275 -275
  163. package/templates/ide/antigravity/.agents/skills/dare-security/SKILL.md +274 -274
  164. package/templates/ide/antigravity/.agents/skills/dare-skill/SKILL.md +35 -35
  165. package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +265 -265
  166. package/templates/ide/antigravity/.agents/skills/dare-telemetry/SKILL.md +188 -188
  167. package/templates/ide/antigravity/.agents/skills/dare-update/SKILL.md +33 -33
  168. package/templates/ide/antigravity/.agents/skills/dare-validate/SKILL.md +33 -33
  169. package/templates/ide/antigravity/.agents/skills/dare-welcome/SKILL.md +30 -30
  170. package/templates/ide/antigravity/.agents/skills/skill-fastapi-api/SKILL.md +343 -343
  171. package/templates/ide/antigravity/.agents/skills/skill-go-gin-api/SKILL.md +377 -377
  172. package/templates/ide/antigravity/.agents/skills/skill-mcp-server/SKILL.md +382 -382
  173. package/templates/ide/antigravity/.agents/skills/skill-nestjs-api/SKILL.md +326 -326
  174. package/templates/ide/antigravity/.agents/skills/skill-rails-api/SKILL.md +393 -393
  175. package/templates/ide/antigravity/templates/BLUEPRINT-template.md +193 -193
  176. package/templates/ide/antigravity/templates/DESIGN-template.md +129 -129
  177. package/templates/ide/antigravity/templates/TASK-SPEC-template.md +141 -141
  178. package/templates/ide/antigravity/templates/TASKS-template.md +26 -26
  179. package/templates/ide/antigravity/templates/TELEMETRY-template.md +125 -125
  180. package/templates/ide/claude/.claude/commands/dare-ax.md +131 -131
  181. package/templates/ide/claude/.claude/commands/dare-bench.md +18 -18
  182. package/templates/ide/claude/.claude/commands/dare-blueprint.md +134 -134
  183. package/templates/ide/claude/.claude/commands/dare-bootstrap.md +27 -27
  184. package/templates/ide/claude/.claude/commands/dare-bugfix-design.md +119 -119
  185. package/templates/ide/claude/.claude/commands/dare-dag-build.md +151 -151
  186. package/templates/ide/claude/.claude/commands/dare-dag-run.md +109 -109
  187. package/templates/ide/claude/.claude/commands/dare-dag-runner.md +117 -117
  188. package/templates/ide/claude/.claude/commands/dare-dag-viz.md +197 -197
  189. package/templates/ide/claude/.claude/commands/dare-dag.md +27 -27
  190. package/templates/ide/claude/.claude/commands/dare-design.md +69 -69
  191. package/templates/ide/claude/.claude/commands/dare-discover.md +28 -28
  192. package/templates/ide/claude/.claude/commands/dare-dna.md +75 -75
  193. package/templates/ide/claude/.claude/commands/dare-docker.md +207 -207
  194. package/templates/ide/claude/.claude/commands/dare-execute.md +152 -152
  195. package/templates/ide/claude/.claude/commands/dare-feature-design.md +147 -147
  196. package/templates/ide/claude/.claude/commands/dare-frontend-design.md +149 -149
  197. package/templates/ide/claude/.claude/commands/dare-graph.md +30 -30
  198. package/templates/ide/claude/.claude/commands/dare-info.md +26 -26
  199. package/templates/ide/claude/.claude/commands/dare-init.md +30 -30
  200. package/templates/ide/claude/.claude/commands/dare-laravel-api.md +211 -211
  201. package/templates/ide/claude/.claude/commands/dare-layered-design.md +124 -124
  202. package/templates/ide/claude/.claude/commands/dare-llm-integration.md +148 -148
  203. package/templates/ide/claude/.claude/commands/dare-migrate.md +72 -72
  204. package/templates/ide/claude/.claude/commands/dare-quality-telemetry.md +166 -166
  205. package/templates/ide/claude/.claude/commands/dare-realtime.md +159 -159
  206. package/templates/ide/claude/.claude/commands/dare-refine.md +145 -145
  207. package/templates/ide/claude/.claude/commands/dare-reverse.md +139 -139
  208. package/templates/ide/claude/.claude/commands/dare-review.md +113 -113
  209. package/templates/ide/claude/.claude/commands/dare-rust-leptos.md +269 -269
  210. package/templates/ide/claude/.claude/commands/dare-rust-workspace.md +209 -209
  211. package/templates/ide/claude/.claude/commands/dare-security.md +232 -232
  212. package/templates/ide/claude/.claude/commands/dare-skill.md +30 -30
  213. package/templates/ide/claude/.claude/commands/dare-tasks.md +70 -70
  214. package/templates/ide/claude/.claude/commands/dare-telemetry.md +132 -132
  215. package/templates/ide/claude/.claude/commands/dare-update.md +28 -28
  216. package/templates/ide/claude/.claude/commands/dare-validate.md +28 -28
  217. package/templates/ide/claude/.claude/commands/dare-welcome.md +25 -25
  218. package/templates/ide/claude/.claude/commands/skill-fastapi-api.md +205 -205
  219. package/templates/ide/claude/.claude/commands/skill-go-gin-api.md +232 -232
  220. package/templates/ide/claude/.claude/commands/skill-mcp-server.md +228 -228
  221. package/templates/ide/claude/.claude/commands/skill-nestjs-api.md +210 -210
  222. package/templates/ide/claude/.claude/commands/skill-rails-api.md +236 -236
  223. package/templates/ide/claude/.claude/settings.example.json +35 -35
  224. package/templates/ide/claude/CLAUDE.md +146 -146
  225. package/templates/ide/claude/templates/BLUEPRINT-template.md +193 -193
  226. package/templates/ide/claude/templates/DESIGN-template.md +129 -129
  227. package/templates/ide/claude/templates/TASK-SPEC-template.md +141 -141
  228. package/templates/ide/claude/templates/TASKS-template.md +26 -26
  229. package/templates/ide/claude/templates/TELEMETRY-template.md +125 -125
  230. package/templates/ide/cursor/.cursor/commands/dare-bench.md +18 -18
  231. package/templates/ide/cursor/.cursor/commands/dare-blueprint.md +86 -86
  232. package/templates/ide/cursor/.cursor/commands/dare-bootstrap.md +27 -27
  233. package/templates/ide/cursor/.cursor/commands/dare-bugfix-design.md +64 -64
  234. package/templates/ide/cursor/.cursor/commands/dare-dag-run.md +110 -110
  235. package/templates/ide/cursor/.cursor/commands/dare-dag-viz.md +139 -139
  236. package/templates/ide/cursor/.cursor/commands/dare-dag.md +27 -27
  237. package/templates/ide/cursor/.cursor/commands/dare-design.md +35 -35
  238. package/templates/ide/cursor/.cursor/commands/dare-discover.md +28 -28
  239. package/templates/ide/cursor/.cursor/commands/dare-dna.md +75 -75
  240. package/templates/ide/cursor/.cursor/commands/dare-docker-compose.md +18 -18
  241. package/templates/ide/cursor/.cursor/commands/dare-dockerfile.md +17 -17
  242. package/templates/ide/cursor/.cursor/commands/dare-execute.md +19 -19
  243. package/templates/ide/cursor/.cursor/commands/dare-feature-design.md +64 -64
  244. package/templates/ide/cursor/.cursor/commands/dare-graph.md +30 -30
  245. package/templates/ide/cursor/.cursor/commands/dare-info.md +26 -26
  246. package/templates/ide/cursor/.cursor/commands/dare-init.md +30 -30
  247. package/templates/ide/cursor/.cursor/commands/dare-migrate.md +72 -72
  248. package/templates/ide/cursor/.cursor/commands/dare-refine.md +107 -107
  249. package/templates/ide/cursor/.cursor/commands/dare-reverse.md +139 -139
  250. package/templates/ide/cursor/.cursor/commands/dare-review.md +91 -91
  251. package/templates/ide/cursor/.cursor/commands/dare-skill.md +30 -30
  252. package/templates/ide/cursor/.cursor/commands/dare-tasks.md +184 -184
  253. package/templates/ide/cursor/.cursor/commands/dare-telemetry.md +42 -42
  254. package/templates/ide/cursor/.cursor/commands/dare-update.md +28 -28
  255. package/templates/ide/cursor/.cursor/commands/dare-validate.md +28 -28
  256. package/templates/ide/cursor/.cursor/commands/dare-welcome.md +25 -25
  257. package/templates/ide/cursor/.cursor/rules/skill-ax.mdc +263 -263
  258. package/templates/ide/cursor/.cursor/rules/skill-bugfix-design.mdc +51 -51
  259. package/templates/ide/cursor/.cursor/rules/skill-dag-build.mdc +173 -173
  260. package/templates/ide/cursor/.cursor/rules/skill-dag-run.mdc +134 -134
  261. package/templates/ide/cursor/.cursor/rules/skill-dag-runner.mdc +221 -221
  262. package/templates/ide/cursor/.cursor/rules/skill-dna.mdc +63 -63
  263. package/templates/ide/cursor/.cursor/rules/skill-docker.mdc +33 -33
  264. package/templates/ide/cursor/.cursor/rules/skill-fastapi-api.mdc +352 -352
  265. package/templates/ide/cursor/.cursor/rules/skill-feature-design.mdc +43 -43
  266. package/templates/ide/cursor/.cursor/rules/skill-frontend-design.mdc +244 -244
  267. package/templates/ide/cursor/.cursor/rules/skill-go-gin-api.mdc +371 -371
  268. package/templates/ide/cursor/.cursor/rules/skill-laravel-api.mdc +44 -44
  269. package/templates/ide/cursor/.cursor/rules/skill-layered-design.mdc +266 -266
  270. package/templates/ide/cursor/.cursor/rules/skill-llm-integration.mdc +295 -295
  271. package/templates/ide/cursor/.cursor/rules/skill-mcp-server.mdc +367 -367
  272. package/templates/ide/cursor/.cursor/rules/skill-migrate.mdc +58 -58
  273. package/templates/ide/cursor/.cursor/rules/skill-nestjs-api.mdc +346 -346
  274. package/templates/ide/cursor/.cursor/rules/skill-quality-telemetry.mdc +248 -248
  275. package/templates/ide/cursor/.cursor/rules/skill-rails-api.mdc +400 -400
  276. package/templates/ide/cursor/.cursor/rules/skill-realtime.mdc +262 -262
  277. package/templates/ide/cursor/.cursor/rules/skill-reverse.mdc +107 -107
  278. package/templates/ide/cursor/.cursor/rules/skill-rust-leptos.mdc +281 -281
  279. package/templates/ide/cursor/.cursor/rules/skill-rust-workspace.mdc +312 -312
  280. package/templates/ide/cursor/.cursor/rules/skill-security.mdc +245 -245
  281. package/templates/ide/cursor/.cursor/rules/skill-telemetry.mdc +156 -156
  282. package/templates/ide/cursor/templates/BLUEPRINT-template.md +193 -193
  283. package/templates/ide/cursor/templates/DESIGN-template.md +129 -129
  284. package/templates/ide/cursor/templates/TASK-SPEC-template.md +141 -141
  285. package/templates/ide/cursor/templates/TASKS-template.md +26 -26
  286. package/templates/ide/cursor/templates/TELEMETRY-template.md +125 -125
  287. package/templates/shared/docker-compose.yml +41 -41
  288. package/templates/stacks/go-gin/.dare/skills.yml +11 -11
  289. package/templates/stacks/go-gin/.env.example +24 -24
  290. package/templates/stacks/go-gin/.github/workflows/dare-ci.yml +42 -42
  291. package/templates/stacks/go-gin/README.md.tpl +38 -38
  292. package/templates/stacks/go-gin/cmd/server/main.go.tpl +78 -78
  293. package/templates/stacks/go-gin/db/migrations/0001_create_users.down.sql +2 -2
  294. package/templates/stacks/go-gin/db/migrations/0001_create_users.up.sql +12 -12
  295. package/templates/stacks/go-gin/db/queries/users.sql +23 -23
  296. package/templates/stacks/go-gin/gitignore +7 -7
  297. package/templates/stacks/go-gin/go.mod.tpl +17 -17
  298. package/templates/stacks/go-gin/internal/config/config.go +41 -41
  299. package/templates/stacks/go-gin/internal/db/postgres.go.tpl +25 -25
  300. package/templates/stacks/go-gin/internal/handler/auth_handler.go.tpl +72 -72
  301. package/templates/stacks/go-gin/internal/handler/users_handler.go.tpl +72 -72
  302. package/templates/stacks/go-gin/internal/handler/ws_handler.go +37 -37
  303. package/templates/stacks/go-gin/internal/llm/dummy.go +14 -14
  304. package/templates/stacks/go-gin/internal/llm/provider.go +8 -8
  305. package/templates/stacks/go-gin/internal/middleware/jwt.go.tpl +58 -58
  306. package/templates/stacks/go-gin/internal/middleware/rate_limit.go +55 -55
  307. package/templates/stacks/go-gin/internal/model/user.go +17 -17
  308. package/templates/stacks/go-gin/internal/repository/users_repository.go.tpl +79 -79
  309. package/templates/stacks/go-gin/internal/service/auth_service.go.tpl +55 -55
  310. package/templates/stacks/go-gin/internal/service/users_service.go.tpl +53 -53
  311. package/templates/stacks/go-gin/llms.txt.tpl +54 -54
  312. package/templates/stacks/go-gin/openapi.json.tpl +46 -46
  313. package/templates/stacks/go-gin/sqlc.yaml +14 -14
  314. package/templates/stacks/go-gin/tests/smoke_test.go.tpl +22 -22
  315. package/templates/stacks/go-stdlib/.dare/skills.yml +11 -11
  316. package/templates/stacks/go-stdlib/.env.example +24 -24
  317. package/templates/stacks/go-stdlib/.github/workflows/dare-ci.yml +42 -42
  318. package/templates/stacks/go-stdlib/README.md.tpl +41 -41
  319. package/templates/stacks/go-stdlib/cmd/server/main.go.tpl +82 -82
  320. package/templates/stacks/go-stdlib/db/migrations/0001_create_users.down.sql +2 -2
  321. package/templates/stacks/go-stdlib/db/migrations/0001_create_users.up.sql +12 -12
  322. package/templates/stacks/go-stdlib/db/queries/users.sql +23 -23
  323. package/templates/stacks/go-stdlib/gitignore +6 -6
  324. package/templates/stacks/go-stdlib/go.mod.tpl +15 -15
  325. package/templates/stacks/go-stdlib/internal/config/config.go +41 -41
  326. package/templates/stacks/go-stdlib/internal/db/postgres.go.tpl +24 -24
  327. package/templates/stacks/go-stdlib/internal/handler/auth_handler.go.tpl +71 -71
  328. package/templates/stacks/go-stdlib/internal/handler/users_handler.go.tpl +84 -84
  329. package/templates/stacks/go-stdlib/internal/handler/ws_handler.go +36 -36
  330. package/templates/stacks/go-stdlib/internal/httpx/json.go +32 -32
  331. package/templates/stacks/go-stdlib/internal/llm/dummy.go +14 -14
  332. package/templates/stacks/go-stdlib/internal/llm/provider.go +8 -8
  333. package/templates/stacks/go-stdlib/internal/middleware/chain.go +21 -21
  334. package/templates/stacks/go-stdlib/internal/middleware/cors.go +27 -27
  335. package/templates/stacks/go-stdlib/internal/middleware/jwt.go.tpl +51 -51
  336. package/templates/stacks/go-stdlib/internal/middleware/rate_limit.go +81 -81
  337. package/templates/stacks/go-stdlib/internal/model/user.go +17 -17
  338. package/templates/stacks/go-stdlib/internal/repository/users_repository.go.tpl +75 -75
  339. package/templates/stacks/go-stdlib/internal/service/auth_service.go.tpl +55 -55
  340. package/templates/stacks/go-stdlib/internal/service/users_service.go.tpl +53 -53
  341. package/templates/stacks/go-stdlib/llms.txt.tpl +60 -60
  342. package/templates/stacks/go-stdlib/openapi.json.tpl +46 -46
  343. package/templates/stacks/go-stdlib/sqlc.yaml +14 -14
  344. package/templates/stacks/go-stdlib/tests/smoke_test.go.tpl +45 -45
  345. package/templates/stacks/mcp-go/.dare/skills.yml +8 -8
  346. package/templates/stacks/mcp-go/.env.example +14 -14
  347. package/templates/stacks/mcp-go/.github/workflows/dare-ci.yml +42 -42
  348. package/templates/stacks/mcp-go/README.md.tpl +50 -50
  349. package/templates/stacks/mcp-go/cmd/server/main.go.tpl +62 -62
  350. package/templates/stacks/mcp-go/gitignore +6 -6
  351. package/templates/stacks/mcp-go/go.mod.tpl +9 -9
  352. package/templates/stacks/mcp-go/internal/prompts/summarize.go +9 -9
  353. package/templates/stacks/mcp-go/internal/server/server.go.tpl +80 -80
  354. package/templates/stacks/mcp-go/internal/tools/echo.go +15 -15
  355. package/templates/stacks/mcp-go/internal/transports/http.go.tpl +21 -21
  356. package/templates/stacks/mcp-go/internal/transports/sse.go.tpl +17 -17
  357. package/templates/stacks/mcp-go/internal/transports/stdio.go.tpl +14 -14
  358. package/templates/stacks/mcp-go/llms.txt.tpl +60 -60
  359. package/templates/stacks/mcp-go/openapi.json.tpl +31 -31
  360. package/templates/stacks/mcp-go/tests/echo_test.go.tpl +37 -37
  361. package/templates/stacks/mcp-node-ts/.dare/skills.yml +8 -8
  362. package/templates/stacks/mcp-node-ts/.env.example +16 -16
  363. package/templates/stacks/mcp-node-ts/.github/workflows/dare-ci.yml +54 -54
  364. package/templates/stacks/mcp-node-ts/README.md.hbs +49 -49
  365. package/templates/stacks/mcp-node-ts/gitignore +7 -7
  366. package/templates/stacks/mcp-node-ts/llms.txt.hbs +61 -61
  367. package/templates/stacks/mcp-node-ts/openapi.json.hbs +39 -39
  368. package/templates/stacks/mcp-node-ts/package.json.hbs +35 -35
  369. package/templates/stacks/mcp-node-ts/src/cli.ts.hbs +71 -71
  370. package/templates/stacks/mcp-node-ts/src/prompts/index.ts +36 -36
  371. package/templates/stacks/mcp-node-ts/src/server.ts.hbs +45 -45
  372. package/templates/stacks/mcp-node-ts/src/tools/echo.ts +23 -23
  373. package/templates/stacks/mcp-node-ts/src/tools/index.ts +18 -18
  374. package/templates/stacks/mcp-node-ts/src/transports/http.ts +68 -68
  375. package/templates/stacks/mcp-node-ts/src/transports/sse.ts +58 -58
  376. package/templates/stacks/mcp-node-ts/src/transports/stdio.ts +5 -5
  377. package/templates/stacks/mcp-node-ts/tests/echo.test.ts +50 -50
  378. package/templates/stacks/mcp-node-ts/tsconfig.json +17 -17
  379. package/templates/stacks/mcp-python/.dare/skills.yml +8 -8
  380. package/templates/stacks/mcp-python/.env.example +14 -14
  381. package/templates/stacks/mcp-python/.github/workflows/dare-ci.yml +42 -42
  382. package/templates/stacks/mcp-python/README.md.j2 +49 -49
  383. package/templates/stacks/mcp-python/gitignore +12 -12
  384. package/templates/stacks/mcp-python/llms.txt.j2 +56 -56
  385. package/templates/stacks/mcp-python/openapi.json.j2 +33 -33
  386. package/templates/stacks/mcp-python/pyproject.toml.j2 +37 -37
  387. package/templates/stacks/mcp-python/src/cli.py.j2 +68 -68
  388. package/templates/stacks/mcp-python/src/prompts/summarize.py +10 -10
  389. package/templates/stacks/mcp-python/src/server.py.j2 +28 -28
  390. package/templates/stacks/mcp-python/src/tools/echo.py +12 -12
  391. package/templates/stacks/mcp-python/src/transports/http.py +12 -12
  392. package/templates/stacks/mcp-python/src/transports/sse.py +13 -13
  393. package/templates/stacks/mcp-python/src/transports/stdio.py +6 -6
  394. package/templates/stacks/mcp-python/tests/test_echo.py +28 -28
  395. package/templates/stacks/mcp-rust/.dare/skills.yml +8 -8
  396. package/templates/stacks/mcp-rust/.env.example +14 -14
  397. package/templates/stacks/mcp-rust/.github/workflows/dare-ci.yml +38 -38
  398. package/templates/stacks/mcp-rust/Cargo.toml.tera +35 -35
  399. package/templates/stacks/mcp-rust/README.md.tera +50 -50
  400. package/templates/stacks/mcp-rust/gitignore +5 -5
  401. package/templates/stacks/mcp-rust/llms.txt.tera +60 -60
  402. package/templates/stacks/mcp-rust/openapi.json.tera +31 -31
  403. package/templates/stacks/mcp-rust/src/cli.rs.tera +33 -33
  404. package/templates/stacks/mcp-rust/src/lib.rs +6 -6
  405. package/templates/stacks/mcp-rust/src/main.rs.tera +30 -30
  406. package/templates/stacks/mcp-rust/src/prompts/mod.rs +1 -1
  407. package/templates/stacks/mcp-rust/src/prompts/summarize.rs +5 -5
  408. package/templates/stacks/mcp-rust/src/server.rs.tera +38 -38
  409. package/templates/stacks/mcp-rust/src/tools/echo.rs +18 -18
  410. package/templates/stacks/mcp-rust/src/tools/mod.rs +22 -22
  411. package/templates/stacks/mcp-rust/src/transports/http.rs +27 -27
  412. package/templates/stacks/mcp-rust/src/transports/mod.rs +3 -3
  413. package/templates/stacks/mcp-rust/src/transports/sse.rs +33 -33
  414. package/templates/stacks/mcp-rust/src/transports/stdio.rs +14 -14
  415. package/templates/stacks/mcp-rust/tests/echo_test.rs.tera +27 -27
  416. package/templates/stacks/node-nestjs/.dare/skills.yml +11 -11
  417. package/templates/stacks/node-nestjs/.env.example +21 -21
  418. package/templates/stacks/node-nestjs/.github/workflows/dare-ci.yml +54 -54
  419. package/templates/stacks/node-nestjs/README.md.hbs +35 -35
  420. package/templates/stacks/node-nestjs/gitignore +7 -7
  421. package/templates/stacks/node-nestjs/llms.txt.hbs +47 -47
  422. package/templates/stacks/node-nestjs/nest-cli.json +16 -16
  423. package/templates/stacks/node-nestjs/openapi.json.hbs +75 -75
  424. package/templates/stacks/node-nestjs/package.json.hbs +57 -57
  425. package/templates/stacks/node-nestjs/prisma/schema.prisma +25 -25
  426. package/templates/stacks/node-nestjs/prisma/seed.ts.hbs +25 -25
  427. package/templates/stacks/node-nestjs/src/app.module.ts +39 -39
  428. package/templates/stacks/node-nestjs/src/auth/auth.controller.ts +29 -29
  429. package/templates/stacks/node-nestjs/src/auth/auth.module.ts +25 -25
  430. package/templates/stacks/node-nestjs/src/auth/auth.service.ts +36 -36
  431. package/templates/stacks/node-nestjs/src/auth/dto/login-response.dto.ts +9 -9
  432. package/templates/stacks/node-nestjs/src/auth/dto/login.dto.ts +17 -17
  433. package/templates/stacks/node-nestjs/src/auth/jwt.strategy.ts +25 -25
  434. package/templates/stacks/node-nestjs/src/common/filters/problem-details.filter.ts +38 -38
  435. package/templates/stacks/node-nestjs/src/common/interceptors/json-response.interceptor.ts +13 -13
  436. package/templates/stacks/node-nestjs/src/main.ts.hbs +44 -44
  437. package/templates/stacks/node-nestjs/src/prisma/prisma.module.ts +9 -9
  438. package/templates/stacks/node-nestjs/src/prisma/prisma.service.ts +9 -9
  439. package/templates/stacks/node-nestjs/src/users/dto/create-user.dto.ts +22 -22
  440. package/templates/stacks/node-nestjs/src/users/dto/user.dto.ts +15 -15
  441. package/templates/stacks/node-nestjs/src/users/users.controller.ts +41 -41
  442. package/templates/stacks/node-nestjs/src/users/users.module.ts +11 -11
  443. package/templates/stacks/node-nestjs/src/users/users.repository.ts +38 -38
  444. package/templates/stacks/node-nestjs/src/users/users.service.ts +38 -38
  445. package/templates/stacks/node-nestjs/tsconfig.build.json +4 -4
  446. package/templates/stacks/node-nestjs/tsconfig.json +28 -28
  447. package/templates/stacks/php-laravel/.dare/skills.yml +11 -11
  448. package/templates/stacks/php-laravel/.env.example +41 -41
  449. package/templates/stacks/php-laravel/.github/workflows/dare-ci.yml +43 -43
  450. package/templates/stacks/php-laravel/README.md.hbs +36 -36
  451. package/templates/stacks/php-laravel/app/Http/Controllers/Api/AuthController.php +36 -36
  452. package/templates/stacks/php-laravel/app/Http/Controllers/Api/UsersController.php +33 -33
  453. package/templates/stacks/php-laravel/app/Http/Requests/CreateUserRequest.php +26 -26
  454. package/templates/stacks/php-laravel/app/Http/Requests/LoginRequest.php +34 -34
  455. package/templates/stacks/php-laravel/app/Llm/Contracts/LlmProvider.php +12 -12
  456. package/templates/stacks/php-laravel/app/Llm/Providers/DummyProvider.php +13 -13
  457. package/templates/stacks/php-laravel/app/Llm/Providers/OpenAiProvider.php +33 -33
  458. package/templates/stacks/php-laravel/app/Models/User.php +44 -44
  459. package/templates/stacks/php-laravel/app/Repositories/UsersRepository.php +32 -32
  460. package/templates/stacks/php-laravel/app/Services/AuthService.php +37 -37
  461. package/templates/stacks/php-laravel/app/Services/UsersService.php +57 -57
  462. package/templates/stacks/php-laravel/artisan +12 -12
  463. package/templates/stacks/php-laravel/bootstrap/app.php +29 -29
  464. package/templates/stacks/php-laravel/bootstrap/providers.php +5 -5
  465. package/templates/stacks/php-laravel/composer.json.hbs +58 -58
  466. package/templates/stacks/php-laravel/config/l5-swagger.php +41 -41
  467. package/templates/stacks/php-laravel/config/reverb.php +34 -34
  468. package/templates/stacks/php-laravel/config/sanctum.php +15 -15
  469. package/templates/stacks/php-laravel/database/migrations/2026_06_01_000001_create_users_table.php +27 -27
  470. package/templates/stacks/php-laravel/database/seeders/DatabaseSeeder.php +21 -21
  471. package/templates/stacks/php-laravel/gitignore +23 -23
  472. package/templates/stacks/php-laravel/llms.txt.hbs +53 -53
  473. package/templates/stacks/php-laravel/openapi.json.hbs +43 -43
  474. package/templates/stacks/php-laravel/phpstan.neon +9 -9
  475. package/templates/stacks/php-laravel/routes/api.php +13 -13
  476. package/templates/stacks/php-laravel/routes/channels.php +7 -7
  477. package/templates/stacks/php-laravel/tests/Feature/AuthTest.php +35 -35
  478. package/templates/stacks/php-laravel/tests/Feature/UsersTest.php +30 -30
  479. package/templates/stacks/php-laravel/tests/Pest.php +5 -5
  480. package/templates/stacks/python-fastapi/.dare/skills.yml +11 -11
  481. package/templates/stacks/python-fastapi/.env.example +21 -21
  482. package/templates/stacks/python-fastapi/.github/workflows/dare-ci.yml +43 -43
  483. package/templates/stacks/python-fastapi/README.md.j2 +35 -35
  484. package/templates/stacks/python-fastapi/alembic/env.py +46 -46
  485. package/templates/stacks/python-fastapi/alembic/script.py.mako +26 -26
  486. package/templates/stacks/python-fastapi/alembic/versions/0001_create_users.py.j2 +37 -37
  487. package/templates/stacks/python-fastapi/alembic.ini.j2 +39 -39
  488. package/templates/stacks/python-fastapi/app/core/config.py +24 -24
  489. package/templates/stacks/python-fastapi/app/core/security.py +34 -34
  490. package/templates/stacks/python-fastapi/app/db/session.py +22 -22
  491. package/templates/stacks/python-fastapi/app/main.py.j2 +36 -36
  492. package/templates/stacks/python-fastapi/app/models/__init__.py +3 -3
  493. package/templates/stacks/python-fastapi/app/models/user.py +30 -30
  494. package/templates/stacks/python-fastapi/app/repositories/user_repository.py +34 -34
  495. package/templates/stacks/python-fastapi/app/routers/auth.py +37 -37
  496. package/templates/stacks/python-fastapi/app/routers/users.py +46 -46
  497. package/templates/stacks/python-fastapi/app/schemas/user.py +56 -56
  498. package/templates/stacks/python-fastapi/app/services/auth_service.py +22 -22
  499. package/templates/stacks/python-fastapi/app/services/user_service.py +31 -31
  500. package/templates/stacks/python-fastapi/gitignore +12 -12
  501. package/templates/stacks/python-fastapi/llms.txt.j2 +53 -53
  502. package/templates/stacks/python-fastapi/openapi.json.j2 +43 -43
  503. package/templates/stacks/python-fastapi/pyproject.toml.j2 +45 -45
  504. package/templates/stacks/python-fastapi/tests/test_auth.py +22 -22
  505. package/templates/stacks/ruby-rails-8/.dare/skills.yml +50 -50
  506. package/templates/stacks/ruby-rails-8/.env.example +20 -20
  507. package/templates/stacks/ruby-rails-8/.github/workflows/dare-ci.yml +112 -112
  508. package/templates/stacks/ruby-rails-8/Gemfile.erb +61 -61
  509. package/templates/stacks/ruby-rails-8/app/channels/application_cable/channel.rb +11 -11
  510. package/templates/stacks/ruby-rails-8/app/channels/application_cable/connection.rb +34 -34
  511. package/templates/stacks/ruby-rails-8/app/channels/dare_updates_channel.rb +18 -18
  512. package/templates/stacks/ruby-rails-8/app/channels/user_updates_channel.rb +23 -23
  513. package/templates/stacks/ruby-rails-8/app/controllers/application_controller.rb +44 -44
  514. package/templates/stacks/ruby-rails-8/app/controllers/concerns/problem_details.rb +93 -93
  515. package/templates/stacks/ruby-rails-8/app/handlers/summarize_handler.rb +33 -33
  516. package/templates/stacks/ruby-rails-8/app/handlers/users_handler.rb +68 -68
  517. package/templates/stacks/ruby-rails-8/app/llm/cache/llm_cache.rb +44 -44
  518. package/templates/stacks/ruby-rails-8/app/llm/prompts/prompt_loader.rb +54 -54
  519. package/templates/stacks/ruby-rails-8/app/llm/prompts/summarize_v1.jinja2 +12 -12
  520. package/templates/stacks/ruby-rails-8/app/llm/providers/dummy_provider.rb +35 -35
  521. package/templates/stacks/ruby-rails-8/app/llm/providers/llm_provider.rb +67 -67
  522. package/templates/stacks/ruby-rails-8/app/llm/providers/openai_provider.rb +62 -62
  523. package/templates/stacks/ruby-rails-8/app/llm/rate_limit/token_bucket.rb +82 -82
  524. package/templates/stacks/ruby-rails-8/app/llm/validators/summarize_output_schema.json +21 -21
  525. package/templates/stacks/ruby-rails-8/app/llm/validators/validator.rb +52 -52
  526. package/templates/stacks/ruby-rails-8/app/models/user.rb +36 -36
  527. package/templates/stacks/ruby-rails-8/app/presenters/user_presenter.rb +48 -48
  528. package/templates/stacks/ruby-rails-8/app/repositories/document_repository.rb +57 -57
  529. package/templates/stacks/ruby-rails-8/app/repositories/user_repository.rb +73 -73
  530. package/templates/stacks/ruby-rails-8/app/services/create_user_service.rb +67 -67
  531. package/templates/stacks/ruby-rails-8/app/services/realtime_service.rb +53 -53
  532. package/templates/stacks/ruby-rails-8/app/services/summarize_document_service.rb +57 -57
  533. package/templates/stacks/ruby-rails-8/config/dare.yml +42 -42
  534. package/templates/stacks/ruby-rails-8/config/initializers/dare.rb +31 -31
  535. package/templates/stacks/ruby-rails-8/config/initializers/rack_attack.rb +64 -64
  536. package/templates/stacks/ruby-rails-8/config/initializers/rswag_api.rb +12 -12
  537. package/templates/stacks/ruby-rails-8/lib/tasks/dare.rake +159 -159
  538. package/templates/stacks/ruby-rails-8/llms.txt.erb +69 -69
  539. package/templates/stacks/ruby-rails-8/spec/api/summarize_spec.rb +56 -56
  540. package/templates/stacks/ruby-rails-8/spec/api/users_spec.rb +72 -72
  541. package/templates/stacks/ruby-rails-8/spec/channels/dare_updates_channel_spec.rb +61 -61
  542. package/templates/stacks/ruby-rails-8/spec/channels/user_updates_channel_spec.rb +56 -56
  543. package/templates/stacks/ruby-rails-8/spec/factories/users.rb +27 -27
  544. package/templates/stacks/ruby-rails-8/spec/handlers/users_handler_spec.rb +88 -88
  545. package/templates/stacks/ruby-rails-8/spec/rails_helper.rb +31 -31
  546. package/templates/stacks/ruby-rails-8/spec/services/create_user_service_spec.rb +88 -88
  547. package/templates/stacks/ruby-rails-8/spec/services/summarize_document_service_spec.rb +142 -142
  548. package/templates/stacks/ruby-rails-8/spec/swagger_helper.rb +73 -73
  549. package/templates/stacks/rust-axum/.dare/skills.yml +11 -11
  550. package/templates/stacks/rust-axum/.env.example +26 -26
  551. package/templates/stacks/rust-axum/.github/workflows/dare-ci.yml +40 -40
  552. package/templates/stacks/rust-axum/Cargo.toml.tera +53 -53
  553. package/templates/stacks/rust-axum/README.md.tera +37 -37
  554. package/templates/stacks/rust-axum/gitignore +5 -5
  555. package/templates/stacks/rust-axum/llms.txt.tera +54 -54
  556. package/templates/stacks/rust-axum/migrations/0001_create_users.sql +13 -13
  557. package/templates/stacks/rust-axum/openapi.json.tera +46 -46
  558. package/templates/stacks/rust-axum/src/config.rs +45 -45
  559. package/templates/stacks/rust-axum/src/errors.rs +48 -48
  560. package/templates/stacks/rust-axum/src/handlers/auth.rs +48 -48
  561. package/templates/stacks/rust-axum/src/handlers/mod.rs +3 -3
  562. package/templates/stacks/rust-axum/src/handlers/users.rs +81 -81
  563. package/templates/stacks/rust-axum/src/handlers/ws.rs +24 -24
  564. package/templates/stacks/rust-axum/src/lib.rs +19 -19
  565. package/templates/stacks/rust-axum/src/llm/mod.rs +1 -1
  566. package/templates/stacks/rust-axum/src/llm/provider.rs +48 -48
  567. package/templates/stacks/rust-axum/src/main.rs.tera +64 -64
  568. package/templates/stacks/rust-axum/src/middleware/auth.rs +20 -20
  569. package/templates/stacks/rust-axum/src/middleware/mod.rs +2 -2
  570. package/templates/stacks/rust-axum/src/middleware/rate_limit.rs +27 -27
  571. package/templates/stacks/rust-axum/src/models/mod.rs +1 -1
  572. package/templates/stacks/rust-axum/src/models/user.rs +13 -13
  573. package/templates/stacks/rust-axum/src/repositories/mod.rs +1 -1
  574. package/templates/stacks/rust-axum/src/repositories/user_repository.rs +62 -62
  575. package/templates/stacks/rust-axum/src/services/auth_service.rs +50 -50
  576. package/templates/stacks/rust-axum/src/services/mod.rs +2 -2
  577. package/templates/stacks/rust-axum/src/services/user_service.rs +53 -53
  578. package/templates/stacks/rust-axum/tests/integration_test.rs.tera +13 -13
  579. package/dist/commands/new.d.ts +0 -16
  580. package/dist/commands/new.d.ts.map +0 -1
  581. package/dist/commands/new.js +0 -104
  582. package/dist/commands/new.js.map +0 -1
@@ -1,35 +1,35 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — DummyProvider for testing and development
4
- # Returns deterministic canned responses — no network calls
5
-
6
- module LLM
7
- module Providers
8
- class DummyProvider < LLMProvider
9
- DEFAULT_RESPONSE = "This is a dummy LLM response. Configure a real provider in config/dare.yml."
10
-
11
- def initialize(responses: {})
12
- # Allow injecting specific responses by prompt keyword for tests:
13
- # DummyProvider.new(responses: { "summarize" => "Summary here" })
14
- @responses = responses
15
- end
16
-
17
- def complete(model:, prompt:, max_tokens: 1024, temperature: 0.7, **_opts)
18
- matched_key = @responses.keys.find { |k| prompt.to_s.downcase.include?(k.to_s.downcase) }
19
- @responses.fetch(matched_key, DEFAULT_RESPONSE)
20
- end
21
-
22
- def chat(model:, messages:, max_tokens: 1024, temperature: 0.7, **_opts)
23
- last_content = messages.last&.dig(:content) || messages.last&.dig("content") || ""
24
- complete(model: model, prompt: last_content, max_tokens: max_tokens)
25
- end
26
-
27
- def stream(model:, prompt:, max_tokens: 1024, &block)
28
- response = complete(model: model, prompt: prompt, max_tokens: max_tokens)
29
- response.chars.each_slice(10).map(&:join).each do |chunk|
30
- block.call(chunk)
31
- end
32
- end
33
- end
34
- end
35
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — DummyProvider for testing and development
4
+ # Returns deterministic canned responses — no network calls
5
+
6
+ module LLM
7
+ module Providers
8
+ class DummyProvider < LLMProvider
9
+ DEFAULT_RESPONSE = "This is a dummy LLM response. Configure a real provider in config/dare.yml."
10
+
11
+ def initialize(responses: {})
12
+ # Allow injecting specific responses by prompt keyword for tests:
13
+ # DummyProvider.new(responses: { "summarize" => "Summary here" })
14
+ @responses = responses
15
+ end
16
+
17
+ def complete(model:, prompt:, max_tokens: 1024, temperature: 0.7, **_opts)
18
+ matched_key = @responses.keys.find { |k| prompt.to_s.downcase.include?(k.to_s.downcase) }
19
+ @responses.fetch(matched_key, DEFAULT_RESPONSE)
20
+ end
21
+
22
+ def chat(model:, messages:, max_tokens: 1024, temperature: 0.7, **_opts)
23
+ last_content = messages.last&.dig(:content) || messages.last&.dig("content") || ""
24
+ complete(model: model, prompt: last_content, max_tokens: max_tokens)
25
+ end
26
+
27
+ def stream(model:, prompt:, max_tokens: 1024, &block)
28
+ response = complete(model: model, prompt: prompt, max_tokens: max_tokens)
29
+ response.chars.each_slice(10).map(&:join).each do |chunk|
30
+ block.call(chunk)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,67 +1,67 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — LLMProvider interface
4
- # Convention (ADR-04): all LLM calls go through this interface
5
- # Implementations: OpenaiProvider, DummyProvider, LocalLlamaProvider
6
- #
7
- # Usage:
8
- # LLMProvider.instance.complete(model: "gpt-4o", prompt: "Summarize...", max_tokens: 150)
9
-
10
- module LLM
11
- module Providers
12
- class LLMProvider
13
- include Singleton
14
-
15
- # ── Factory: configure at boot from dare.yml ─────────────────────────
16
-
17
- # Override the singleton instance (useful in tests to inject DummyProvider)
18
- def self.configure(provider_instance)
19
- @configured_instance = provider_instance
20
- end
21
-
22
- def self.instance
23
- @configured_instance ||= build_from_config
24
- end
25
-
26
- def self.build_from_config
27
- provider_name = Rails.configuration.dare.llm_provider
28
-
29
- case provider_name
30
- when "openai"
31
- LLM::Providers::OpenaiProvider.new
32
- when "dummy"
33
- LLM::Providers::DummyProvider.new
34
- else
35
- raise ArgumentError, "Unknown LLM provider: #{provider_name}. Valid: openai, dummy"
36
- end
37
- end
38
-
39
- # ── Interface — subclasses must implement ─────────────────────────────
40
-
41
- # Complete a prompt and return the response text.
42
- #
43
- # @param model [String] e.g. "gpt-4o"
44
- # @param prompt [String] the full prompt text
45
- # @param max_tokens [Integer] maximum tokens in response
46
- # @param temperature [Float] 0.0 to 1.0
47
- # @return [String] the completion text
48
- def complete(model:, prompt:, max_tokens: 1024, temperature: 0.7, **_opts)
49
- raise NotImplementedError, "#{self.class} must implement #complete"
50
- end
51
-
52
- # Chat-style completion with messages array
53
- #
54
- # @param model [String]
55
- # @param messages [Array<Hash>] [{role: "user", content: "..."}]
56
- # @return [String] assistant message content
57
- def chat(model:, messages:, max_tokens: 1024, temperature: 0.7, **_opts)
58
- raise NotImplementedError, "#{self.class} must implement #chat"
59
- end
60
-
61
- # Stream a completion — yields chunks as they arrive.
62
- def stream(model:, prompt:, max_tokens: 1024, &block)
63
- raise NotImplementedError, "#{self.class} must implement #stream"
64
- end
65
- end
66
- end
67
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — LLMProvider interface
4
+ # Convention (ADR-04): all LLM calls go through this interface
5
+ # Implementations: OpenaiProvider, DummyProvider, LocalLlamaProvider
6
+ #
7
+ # Usage:
8
+ # LLMProvider.instance.complete(model: "gpt-4o", prompt: "Summarize...", max_tokens: 150)
9
+
10
+ module LLM
11
+ module Providers
12
+ class LLMProvider
13
+ include Singleton
14
+
15
+ # ── Factory: configure at boot from dare.yml ─────────────────────────
16
+
17
+ # Override the singleton instance (useful in tests to inject DummyProvider)
18
+ def self.configure(provider_instance)
19
+ @configured_instance = provider_instance
20
+ end
21
+
22
+ def self.instance
23
+ @configured_instance ||= build_from_config
24
+ end
25
+
26
+ def self.build_from_config
27
+ provider_name = Rails.configuration.dare.llm_provider
28
+
29
+ case provider_name
30
+ when "openai"
31
+ LLM::Providers::OpenaiProvider.new
32
+ when "dummy"
33
+ LLM::Providers::DummyProvider.new
34
+ else
35
+ raise ArgumentError, "Unknown LLM provider: #{provider_name}. Valid: openai, dummy"
36
+ end
37
+ end
38
+
39
+ # ── Interface — subclasses must implement ─────────────────────────────
40
+
41
+ # Complete a prompt and return the response text.
42
+ #
43
+ # @param model [String] e.g. "gpt-4o"
44
+ # @param prompt [String] the full prompt text
45
+ # @param max_tokens [Integer] maximum tokens in response
46
+ # @param temperature [Float] 0.0 to 1.0
47
+ # @return [String] the completion text
48
+ def complete(model:, prompt:, max_tokens: 1024, temperature: 0.7, **_opts)
49
+ raise NotImplementedError, "#{self.class} must implement #complete"
50
+ end
51
+
52
+ # Chat-style completion with messages array
53
+ #
54
+ # @param model [String]
55
+ # @param messages [Array<Hash>] [{role: "user", content: "..."}]
56
+ # @return [String] assistant message content
57
+ def chat(model:, messages:, max_tokens: 1024, temperature: 0.7, **_opts)
58
+ raise NotImplementedError, "#{self.class} must implement #chat"
59
+ end
60
+
61
+ # Stream a completion — yields chunks as they arrive.
62
+ def stream(model:, prompt:, max_tokens: 1024, &block)
63
+ raise NotImplementedError, "#{self.class} must implement #stream"
64
+ end
65
+ end
66
+ end
67
+ end
@@ -1,62 +1,62 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — OpenAI LLM provider
4
- # Uses Faraday for HTTP — no heavy SDK dependency
5
-
6
- module LLM
7
- module Providers
8
- class OpenaiProvider < LLMProvider
9
- BASE_URL = "https://api.openai.com/v1"
10
-
11
- def initialize(api_key: nil)
12
- @api_key = api_key || Rails.configuration.dare.llm_api_key
13
- raise ArgumentError, "OpenAI API key not configured. Set OPENAI_API_KEY." if @api_key.blank?
14
- end
15
-
16
- def complete(model:, prompt:, max_tokens: 1024, temperature: 0.7, **_opts)
17
- messages = [{ role: "user", content: prompt }]
18
- chat(model: model, messages: messages, max_tokens: max_tokens, temperature: temperature)
19
- end
20
-
21
- def chat(model:, messages:, max_tokens: 1024, temperature: 0.7, **_opts)
22
- response = connection.post("/v1/chat/completions") do |req|
23
- req.headers["Authorization"] = "Bearer #{@api_key}"
24
- req.headers["Content-Type"] = "application/json"
25
- req.body = {
26
- model: model,
27
- messages: messages,
28
- max_tokens: max_tokens,
29
- temperature: temperature
30
- }.to_json
31
- end
32
-
33
- handle_response(response)
34
- .dig("choices", 0, "message", "content")
35
- .to_s
36
- .strip
37
- end
38
-
39
- def stream(model:, prompt:, max_tokens: 1024, &block)
40
- # Streaming via SSE — basic implementation
41
- # For production use consider openai-ruby gem with native streaming
42
- raise NotImplementedError, "Streaming not yet implemented in OpenaiProvider. Use chat() instead."
43
- end
44
-
45
- private
46
-
47
- def connection
48
- @connection ||= Faraday.new(url: BASE_URL) do |f|
49
- f.request :retry, max: 2, interval: 0.5, retry_statuses: [429, 503]
50
- f.response :raise_error
51
- f.adapter Faraday.default_adapter
52
- end
53
- end
54
-
55
- def handle_response(response)
56
- JSON.parse(response.body)
57
- rescue JSON::ParserError => e
58
- raise "OpenAI returned non-JSON response: #{response.body.truncate(200)}"
59
- end
60
- end
61
- end
62
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — OpenAI LLM provider
4
+ # Uses Faraday for HTTP — no heavy SDK dependency
5
+
6
+ module LLM
7
+ module Providers
8
+ class OpenaiProvider < LLMProvider
9
+ BASE_URL = "https://api.openai.com/v1"
10
+
11
+ def initialize(api_key: nil)
12
+ @api_key = api_key || Rails.configuration.dare.llm_api_key
13
+ raise ArgumentError, "OpenAI API key not configured. Set OPENAI_API_KEY." if @api_key.blank?
14
+ end
15
+
16
+ def complete(model:, prompt:, max_tokens: 1024, temperature: 0.7, **_opts)
17
+ messages = [{ role: "user", content: prompt }]
18
+ chat(model: model, messages: messages, max_tokens: max_tokens, temperature: temperature)
19
+ end
20
+
21
+ def chat(model:, messages:, max_tokens: 1024, temperature: 0.7, **_opts)
22
+ response = connection.post("/v1/chat/completions") do |req|
23
+ req.headers["Authorization"] = "Bearer #{@api_key}"
24
+ req.headers["Content-Type"] = "application/json"
25
+ req.body = {
26
+ model: model,
27
+ messages: messages,
28
+ max_tokens: max_tokens,
29
+ temperature: temperature
30
+ }.to_json
31
+ end
32
+
33
+ handle_response(response)
34
+ .dig("choices", 0, "message", "content")
35
+ .to_s
36
+ .strip
37
+ end
38
+
39
+ def stream(model:, prompt:, max_tokens: 1024, &block)
40
+ # Streaming via SSE — basic implementation
41
+ # For production use consider openai-ruby gem with native streaming
42
+ raise NotImplementedError, "Streaming not yet implemented in OpenaiProvider. Use chat() instead."
43
+ end
44
+
45
+ private
46
+
47
+ def connection
48
+ @connection ||= Faraday.new(url: BASE_URL) do |f|
49
+ f.request :retry, max: 2, interval: 0.5, retry_statuses: [429, 503]
50
+ f.response :raise_error
51
+ f.adapter Faraday.default_adapter
52
+ end
53
+ end
54
+
55
+ def handle_response(response)
56
+ JSON.parse(response.body)
57
+ rescue JSON::ParserError => e
58
+ raise "OpenAI returned non-JSON response: #{response.body.truncate(200)}"
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,82 +1,82 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — Token Bucket rate limiter for LLM API calls
4
- # Prevents exceeding OpenAI/provider rate limits (tokens per minute)
5
- # Uses Redis for distributed state across multiple app instances
6
- #
7
- # Usage:
8
- # bucket = LLM::RateLimit::TokenBucket.new(user_id: current_user.id)
9
- # unless bucket.consume!(tokens: estimated_tokens)
10
- # raise RateLimitExceeded, "LLM token limit reached. Retry after #{bucket.retry_after}s"
11
- # end
12
-
13
- module LLM
14
- module RateLimit
15
- class TokenBucket
16
- class RateLimitExceeded < StandardError
17
- attr_reader :retry_after
18
-
19
- def initialize(retry_after: 60)
20
- @retry_after = retry_after
21
- super("LLM token rate limit exceeded. Retry after #{retry_after} seconds.")
22
- end
23
- end
24
-
25
- # Default: 100K tokens per minute per user (well below OpenAI limits)
26
- DEFAULT_CAPACITY = 100_000
27
- DEFAULT_REFILL_RPM = 100_000 # tokens refilled per minute
28
- WINDOW_SECONDS = 60
29
-
30
- def initialize(user_id:, capacity: DEFAULT_CAPACITY)
31
- @user_id = user_id
32
- @capacity = capacity
33
- @redis = Redis.new(url: Rails.configuration.dare.redis_url)
34
- end
35
-
36
- # Attempt to consume tokens. Returns true if allowed, false if rate-limited.
37
- def consume!(tokens: 1)
38
- key = redis_key
39
- now = Time.now.to_f
40
- window_start = now - WINDOW_SECONDS
41
-
42
- # Redis pipeline: count tokens used in current window + add new entry
43
- used = @redis.multi do |pipeline|
44
- pipeline.zremrangebyscore(key, "-inf", window_start)
45
- pipeline.zadd(key, now, "#{now}:#{tokens}")
46
- pipeline.zrange(key, 0, -1)
47
- pipeline.expire(key, WINDOW_SECONDS * 2)
48
- end
49
-
50
- # Tally tokens from sorted set entries
51
- entries = used[2] || []
52
- total_used = entries.sum do |entry|
53
- entry.split(":").last.to_i
54
- end
55
-
56
- if total_used > @capacity
57
- # Roll back the zadd we just did
58
- @redis.zrem(key, "#{now}:#{tokens}")
59
- return false
60
- end
61
-
62
- true
63
- end
64
-
65
- def retry_after
66
- # Time until oldest entry expires
67
- oldest = @redis.zrange(redis_key, 0, 0, with_scores: true).first
68
- return 0 unless oldest
69
-
70
- oldest_time = oldest[1]
71
- remaining = (oldest_time + WINDOW_SECONDS) - Time.now.to_f
72
- [remaining.ceil, 0].max
73
- end
74
-
75
- private
76
-
77
- def redis_key
78
- "llm_token_bucket:#{@user_id}"
79
- end
80
- end
81
- end
82
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — Token Bucket rate limiter for LLM API calls
4
+ # Prevents exceeding OpenAI/provider rate limits (tokens per minute)
5
+ # Uses Redis for distributed state across multiple app instances
6
+ #
7
+ # Usage:
8
+ # bucket = LLM::RateLimit::TokenBucket.new(user_id: current_user.id)
9
+ # unless bucket.consume!(tokens: estimated_tokens)
10
+ # raise RateLimitExceeded, "LLM token limit reached. Retry after #{bucket.retry_after}s"
11
+ # end
12
+
13
+ module LLM
14
+ module RateLimit
15
+ class TokenBucket
16
+ class RateLimitExceeded < StandardError
17
+ attr_reader :retry_after
18
+
19
+ def initialize(retry_after: 60)
20
+ @retry_after = retry_after
21
+ super("LLM token rate limit exceeded. Retry after #{retry_after} seconds.")
22
+ end
23
+ end
24
+
25
+ # Default: 100K tokens per minute per user (well below OpenAI limits)
26
+ DEFAULT_CAPACITY = 100_000
27
+ DEFAULT_REFILL_RPM = 100_000 # tokens refilled per minute
28
+ WINDOW_SECONDS = 60
29
+
30
+ def initialize(user_id:, capacity: DEFAULT_CAPACITY)
31
+ @user_id = user_id
32
+ @capacity = capacity
33
+ @redis = Redis.new(url: Rails.configuration.dare.redis_url)
34
+ end
35
+
36
+ # Attempt to consume tokens. Returns true if allowed, false if rate-limited.
37
+ def consume!(tokens: 1)
38
+ key = redis_key
39
+ now = Time.now.to_f
40
+ window_start = now - WINDOW_SECONDS
41
+
42
+ # Redis pipeline: count tokens used in current window + add new entry
43
+ used = @redis.multi do |pipeline|
44
+ pipeline.zremrangebyscore(key, "-inf", window_start)
45
+ pipeline.zadd(key, now, "#{now}:#{tokens}")
46
+ pipeline.zrange(key, 0, -1)
47
+ pipeline.expire(key, WINDOW_SECONDS * 2)
48
+ end
49
+
50
+ # Tally tokens from sorted set entries
51
+ entries = used[2] || []
52
+ total_used = entries.sum do |entry|
53
+ entry.split(":").last.to_i
54
+ end
55
+
56
+ if total_used > @capacity
57
+ # Roll back the zadd we just did
58
+ @redis.zrem(key, "#{now}:#{tokens}")
59
+ return false
60
+ end
61
+
62
+ true
63
+ end
64
+
65
+ def retry_after
66
+ # Time until oldest entry expires
67
+ oldest = @redis.zrange(redis_key, 0, 0, with_scores: true).first
68
+ return 0 unless oldest
69
+
70
+ oldest_time = oldest[1]
71
+ remaining = (oldest_time + WINDOW_SECONDS) - Time.now.to_f
72
+ [remaining.ceil, 0].max
73
+ end
74
+
75
+ private
76
+
77
+ def redis_key
78
+ "llm_token_bucket:#{@user_id}"
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,21 +1,21 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "title": "SummarizeOutput",
4
- "description": "Schema for LLM summarize operation output",
5
- "type": "object",
6
- "required": ["summary"],
7
- "properties": {
8
- "summary": {
9
- "type": "string",
10
- "minLength": 10,
11
- "maxLength": 2000,
12
- "description": "The summarized text"
13
- },
14
- "word_count": {
15
- "type": "integer",
16
- "minimum": 1,
17
- "description": "Optional word count of the summary"
18
- }
19
- },
20
- "additionalProperties": false
21
- }
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "SummarizeOutput",
4
+ "description": "Schema for LLM summarize operation output",
5
+ "type": "object",
6
+ "required": ["summary"],
7
+ "properties": {
8
+ "summary": {
9
+ "type": "string",
10
+ "minLength": 10,
11
+ "maxLength": 2000,
12
+ "description": "The summarized text"
13
+ },
14
+ "word_count": {
15
+ "type": "integer",
16
+ "minimum": 1,
17
+ "description": "Optional word count of the summary"
18
+ }
19
+ },
20
+ "additionalProperties": false
21
+ }
@@ -1,52 +1,52 @@
1
- # frozen_string_literal: true
2
-
3
- # DARE v3.0 — LLM Output Validator
4
- # Validates LLM responses against JSON Schema definitions
5
- # Schemas live in app/llm/validators/*.json
6
- #
7
- # Usage:
8
- # LLM::Validators::Validator.validate!("summarize_output", response_hash)
9
-
10
- module LLM
11
- module Validators
12
- class Validator
13
- SCHEMAS_DIR = Rails.root.join("app", "llm", "validators")
14
-
15
- class ValidationError < StandardError
16
- attr_reader :errors
17
-
18
- def initialize(schema_name, errors)
19
- @errors = errors
20
- super("LLM output failed validation for '#{schema_name}': #{errors.map { |e| e[:error] }.join(", ")}")
21
- end
22
- end
23
-
24
- # Validate a hash against a named JSON Schema.
25
- # Raises ValidationError if invalid.
26
- def self.validate!(schema_name, data)
27
- schema = load_schema!(schema_name)
28
- validator = JSONSchemer.schema(schema)
29
- errors = validator.validate(data).to_a
30
-
31
- raise ValidationError.new(schema_name, errors) if errors.any?
32
-
33
- true
34
- end
35
-
36
- # Returns true/false without raising
37
- def self.valid?(schema_name, data)
38
- validate!(schema_name, data)
39
- true
40
- rescue ValidationError
41
- false
42
- end
43
-
44
- private_class_method def self.load_schema!(name)
45
- path = SCHEMAS_DIR.join("#{name}.json")
46
- raise ArgumentError, "Schema not found: #{name}.json in #{SCHEMAS_DIR}" unless path.exist?
47
-
48
- JSON.parse(path.read)
49
- end
50
- end
51
- end
52
- end
1
+ # frozen_string_literal: true
2
+
3
+ # DARE v3.0 — LLM Output Validator
4
+ # Validates LLM responses against JSON Schema definitions
5
+ # Schemas live in app/llm/validators/*.json
6
+ #
7
+ # Usage:
8
+ # LLM::Validators::Validator.validate!("summarize_output", response_hash)
9
+
10
+ module LLM
11
+ module Validators
12
+ class Validator
13
+ SCHEMAS_DIR = Rails.root.join("app", "llm", "validators")
14
+
15
+ class ValidationError < StandardError
16
+ attr_reader :errors
17
+
18
+ def initialize(schema_name, errors)
19
+ @errors = errors
20
+ super("LLM output failed validation for '#{schema_name}': #{errors.map { |e| e[:error] }.join(", ")}")
21
+ end
22
+ end
23
+
24
+ # Validate a hash against a named JSON Schema.
25
+ # Raises ValidationError if invalid.
26
+ def self.validate!(schema_name, data)
27
+ schema = load_schema!(schema_name)
28
+ validator = JSONSchemer.schema(schema)
29
+ errors = validator.validate(data).to_a
30
+
31
+ raise ValidationError.new(schema_name, errors) if errors.any?
32
+
33
+ true
34
+ end
35
+
36
+ # Returns true/false without raising
37
+ def self.valid?(schema_name, data)
38
+ validate!(schema_name, data)
39
+ true
40
+ rescue ValidationError
41
+ false
42
+ end
43
+
44
+ private_class_method def self.load_schema!(name)
45
+ path = SCHEMAS_DIR.join("#{name}.json")
46
+ raise ArgumentError, "Schema not found: #{name}.json in #{SCHEMAS_DIR}" unless path.exist?
47
+
48
+ JSON.parse(path.read)
49
+ end
50
+ end
51
+ end
52
+ end