@punks/cli 0.1.16 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (508) hide show
  1. package/AGENTS.md +10 -0
  2. package/README.md +64 -0
  3. package/dist/data/AGENTS.md +123 -0
  4. package/dist/data/catalog/lint.ts +349 -0
  5. package/dist/data/catalog/packs.ts +44 -0
  6. package/dist/data/catalog/skills.ts +47 -0
  7. package/dist/data/catalog/tools.ts +22 -0
  8. package/dist/data/hooks/format-edited-file.mjs +554 -0
  9. package/dist/data/hooks/format-edited-file.py +157 -0
  10. package/dist/data/hooks/format-edited-file.sh +37 -0
  11. package/dist/data/hooks/require-tests-for-pr.mjs +144 -0
  12. package/dist/data/scripts/sync-subagents.mjs +420 -0
  13. package/dist/data/subagents/manifest.mjs +253 -0
  14. package/dist/index.js +46415 -0
  15. package/dist/skills/agnostic/backend/backend-domain-structure/SKILL.md +50 -0
  16. package/dist/skills/agnostic/backend/backend-domain-structure/agents/openai.yaml +4 -0
  17. package/dist/skills/agnostic/backend/backend-domain-structure/references/layout.md +167 -0
  18. package/dist/skills/agnostic/backend/backend-recoverable-actions/SKILL.md +49 -0
  19. package/dist/skills/agnostic/backend/backend-recoverable-actions/agents/openai.yaml +4 -0
  20. package/dist/skills/agnostic/backend/backend-recoverable-actions/references/strategy-matrix.md +34 -0
  21. package/dist/skills/agnostic/backend/backend-recoverable-actions/references/test-matrix.md +34 -0
  22. package/dist/skills/agnostic/docs/docs-maintenance/SKILL.md +193 -0
  23. package/dist/skills/agnostic/docs/docs-maintenance/agents/openai.yaml +4 -0
  24. package/dist/skills/agnostic/docs/docs-maintenance/references/concept-pages.md +48 -0
  25. package/dist/skills/agnostic/docs/docs-maintenance/references/flow-pages.md +41 -0
  26. package/dist/skills/agnostic/frontend/agent-browser/.clawdhub/origin.json +7 -0
  27. package/dist/skills/agnostic/frontend/agent-browser/SKILL.md +229 -0
  28. package/dist/skills/agnostic/frontend/agent-browser/references/authentication.md +202 -0
  29. package/dist/skills/agnostic/frontend/agent-browser/references/commands.md +259 -0
  30. package/dist/skills/agnostic/frontend/agent-browser/references/proxy-support.md +188 -0
  31. package/dist/skills/agnostic/frontend/agent-browser/references/session-management.md +193 -0
  32. package/dist/skills/agnostic/frontend/agent-browser/references/snapshot-refs.md +194 -0
  33. package/dist/skills/agnostic/frontend/agent-browser/references/video-recording.md +173 -0
  34. package/dist/skills/agnostic/frontend/agent-browser/templates/authenticated-session.sh +97 -0
  35. package/dist/skills/agnostic/frontend/agent-browser/templates/capture-workflow.sh +69 -0
  36. package/dist/skills/agnostic/frontend/agent-browser/templates/form-automation.sh +62 -0
  37. package/dist/skills/agnostic/frontend/design-taste-frontend/SKILL.md +226 -0
  38. package/dist/skills/agnostic/frontend/frontend-domain-structure/SKILL.md +55 -0
  39. package/dist/skills/agnostic/frontend/frontend-domain-structure/agents/openai.yaml +4 -0
  40. package/dist/skills/agnostic/frontend/frontend-domain-structure/references/react/structure.md +102 -0
  41. package/dist/skills/agnostic/frontend/frontend-domain-structure/references/structure.md +257 -0
  42. package/dist/skills/agnostic/frontend/gpt-taste/SKILL.md +74 -0
  43. package/dist/skills/agnostic/frontend/image-taste-frontend/SKILL.md +1102 -0
  44. package/dist/skills/agnostic/frontend/redesign-existing-projects/SKILL.md +178 -0
  45. package/dist/skills/agnostic/planning/create-plan/REFERENCE.md +37 -0
  46. package/dist/skills/agnostic/planning/create-plan/SKILL.md +69 -0
  47. package/dist/skills/agnostic/planning/create-plan/references/backlog-sync.md +44 -0
  48. package/dist/skills/agnostic/planning/create-plan/references/grill-phase.md +86 -0
  49. package/dist/skills/agnostic/planning/create-plan/references/plan-schema.md +66 -0
  50. package/dist/skills/agnostic/planning/create-plan/references/planner-phase.md +39 -0
  51. package/dist/skills/agnostic/planning/create-plan/references/stop-conditions.md +18 -0
  52. package/dist/skills/agnostic/planning/create-plan/references/tdd-phase.md +26 -0
  53. package/dist/skills/agnostic/planning/create-spec/SKILL.md +57 -0
  54. package/dist/skills/agnostic/planning/create-spec/assets/SPEC-TEMPLATE.md +91 -0
  55. package/dist/skills/agnostic/planning/create-spec/references/discovery.md +44 -0
  56. package/dist/skills/agnostic/planning/create-spec/references/folder-naming.md +27 -0
  57. package/dist/skills/agnostic/planning/create-spec/references/handoff.md +47 -0
  58. package/dist/skills/agnostic/planning/create-spec/references/questioning.md +41 -0
  59. package/dist/skills/agnostic/planning/create-spec/references/spec-quality-bar.md +58 -0
  60. package/dist/skills/agnostic/planning/create-spec/references/wiki-bookkeeping.md +26 -0
  61. package/dist/skills/agnostic/planning/grill-me/SKILL.md +28 -0
  62. package/dist/skills/agnostic/planning/implement-spec/SKILL.md +72 -0
  63. package/dist/skills/agnostic/planning/implement-spec/assets/IMPLEMENTATION-NOTES-TEMPLATE.md +47 -0
  64. package/dist/skills/agnostic/planning/implement-spec/references/lifecycle.md +149 -0
  65. package/dist/skills/agnostic/planning/implement-spec/references/parallel-orchestration.md +102 -0
  66. package/dist/skills/agnostic/planning/implement-spec/references/parallel-worker-brief.md +65 -0
  67. package/dist/skills/agnostic/planning/implement-spec/references/parallel.md +56 -0
  68. package/dist/skills/agnostic/planning/implement-spec/references/sequential.md +28 -0
  69. package/dist/skills/agnostic/planning/swarm-planner/SKILL.md +179 -0
  70. package/dist/skills/agnostic/quality/simplify/SKILL.md +14 -0
  71. package/dist/skills/agnostic/quality/tdd/SKILL.md +107 -0
  72. package/dist/skills/agnostic/quality/tdd/deep-modules.md +33 -0
  73. package/dist/skills/agnostic/quality/tdd/interface-design.md +31 -0
  74. package/dist/skills/agnostic/quality/tdd/mocking.md +59 -0
  75. package/dist/skills/agnostic/quality/tdd/refactoring.md +10 -0
  76. package/dist/skills/agnostic/quality/tdd/tests.md +61 -0
  77. package/dist/skills/agnostic/requirements/requirements-grill/SKILL.md +42 -0
  78. package/dist/skills/agnostic/requirements/requirements-grill/references/artifact-output.md +73 -0
  79. package/dist/skills/agnostic/requirements/requirements-grill/references/grilling-flow.md +57 -0
  80. package/dist/skills/agnostic/requirements/requirements-grill/references/wiki-output.md +94 -0
  81. package/dist/skills/agnostic/requirements/write-backlog/EXAMPLES.md +67 -0
  82. package/dist/skills/agnostic/requirements/write-backlog/REFERENCE.md +253 -0
  83. package/dist/skills/agnostic/requirements/write-backlog/SKILL.md +68 -0
  84. package/dist/skills/agnostic/requirements/write-backlog/assets/concepts/backlog-model.md +69 -0
  85. package/dist/skills/agnostic/requirements/write-backlog/assets/concepts/story-shape.md +66 -0
  86. package/dist/skills/agnostic/requirements/write-backlog/assets/providers/azure-devops-create-payload.md +63 -0
  87. package/dist/skills/agnostic/requirements/write-backlog/assets/providers/github-issues-create-payload.md +48 -0
  88. package/dist/skills/agnostic/requirements/write-backlog/assets/providers/linear-create-payload.md +76 -0
  89. package/dist/skills/agnostic/research/improve-codebase-architecture/REFERENCE.md +78 -0
  90. package/dist/skills/agnostic/research/improve-codebase-architecture/SKILL.md +76 -0
  91. package/dist/skills/agnostic/research/parallel-research/SKILL.md +68 -0
  92. package/dist/skills/agnostic/research/parallel-research/agents/openai.yaml +4 -0
  93. package/dist/skills/agnostic/subagents/swarm-planner/SKILL.md +179 -0
  94. package/dist/skills/agnostic/write-a-skill/SKILL.md +117 -0
  95. package/dist/skills/frameworks/better-auth/better-auth-best-practices/SKILL.md +166 -0
  96. package/dist/skills/frameworks/better-auth/better-auth-security-best-practices/SKILL.MD +432 -0
  97. package/dist/skills/frameworks/effect/effect-authoring/SKILL.md +116 -0
  98. package/dist/skills/frameworks/effect/effect-authoring/references/branded-types.md +98 -0
  99. package/dist/skills/frameworks/effect/effect-authoring/references/effect-atom-patterns.md +257 -0
  100. package/dist/skills/frameworks/effect/effect-authoring/references/effect-primitives.md +144 -0
  101. package/dist/skills/frameworks/effect/effect-authoring/references/error-patterns.md +156 -0
  102. package/dist/skills/frameworks/effect/effect-authoring/references/otel-patterns.md +113 -0
  103. package/dist/skills/frameworks/effect/effect-authoring/references/test-patterns.md +146 -0
  104. package/dist/skills/frameworks/effect/effect-backend-structure/SKILL.md +96 -0
  105. package/dist/skills/frameworks/effect/effect-backend-structure/agents/openai.yaml +4 -0
  106. package/dist/skills/frameworks/effect/effect-backend-structure/references/layout.md +68 -0
  107. package/dist/skills/frameworks/effect/effect-best-practices/SKILL.md +517 -0
  108. package/dist/skills/frameworks/effect/effect-best-practices/references/anti-patterns.md +392 -0
  109. package/dist/skills/frameworks/effect/effect-best-practices/references/effect-atom-patterns.md +653 -0
  110. package/dist/skills/frameworks/effect/effect-best-practices/references/error-patterns.md +464 -0
  111. package/dist/skills/frameworks/effect/effect-best-practices/references/language-server.md +287 -0
  112. package/dist/skills/frameworks/effect/effect-best-practices/references/layer-patterns.md +495 -0
  113. package/dist/skills/frameworks/effect/effect-best-practices/references/observability-patterns.md +342 -0
  114. package/dist/skills/frameworks/effect/effect-best-practices/references/rpc-cluster-patterns.md +418 -0
  115. package/dist/skills/frameworks/effect/effect-best-practices/references/schema-patterns.md +353 -0
  116. package/dist/skills/frameworks/effect/effect-best-practices/references/service-patterns.md +299 -0
  117. package/dist/skills/frameworks/effect/effect-recoverable-actions/SKILL.md +65 -0
  118. package/dist/skills/frameworks/effect/effect-recoverable-actions/agents/openai.yaml +4 -0
  119. package/dist/skills/frameworks/effect/effect-recoverable-actions/references/flow-examples.md +154 -0
  120. package/dist/skills/frameworks/effect/effect-recoverable-actions/references/source-backed-primitives.md +104 -0
  121. package/dist/skills/frameworks/effect/effect-recoverable-actions/references/strategy-matrix.md +34 -0
  122. package/dist/skills/frameworks/effect/effect-recoverable-actions/references/test-matrix.md +36 -0
  123. package/dist/skills/frameworks/elysia/elysiajs/SKILL.md +475 -0
  124. package/dist/skills/frameworks/elysia/elysiajs/examples/basic.ts +9 -0
  125. package/dist/skills/frameworks/elysia/elysiajs/examples/body-parser.ts +33 -0
  126. package/dist/skills/frameworks/elysia/elysiajs/examples/complex.ts +112 -0
  127. package/dist/skills/frameworks/elysia/elysiajs/examples/cookie.ts +45 -0
  128. package/dist/skills/frameworks/elysia/elysiajs/examples/error.ts +38 -0
  129. package/dist/skills/frameworks/elysia/elysiajs/examples/file.ts +10 -0
  130. package/dist/skills/frameworks/elysia/elysiajs/examples/guard.ts +34 -0
  131. package/dist/skills/frameworks/elysia/elysiajs/examples/map-response.ts +15 -0
  132. package/dist/skills/frameworks/elysia/elysiajs/examples/redirect.ts +6 -0
  133. package/dist/skills/frameworks/elysia/elysiajs/examples/rename.ts +32 -0
  134. package/dist/skills/frameworks/elysia/elysiajs/examples/schema.ts +61 -0
  135. package/dist/skills/frameworks/elysia/elysiajs/examples/state.ts +6 -0
  136. package/dist/skills/frameworks/elysia/elysiajs/examples/upload-file.ts +20 -0
  137. package/dist/skills/frameworks/elysia/elysiajs/examples/websocket.ts +25 -0
  138. package/dist/skills/frameworks/elysia/elysiajs/integrations/ai-sdk.md +92 -0
  139. package/dist/skills/frameworks/elysia/elysiajs/integrations/astro.md +59 -0
  140. package/dist/skills/frameworks/elysia/elysiajs/integrations/better-auth.md +117 -0
  141. package/dist/skills/frameworks/elysia/elysiajs/integrations/cloudflare-worker.md +95 -0
  142. package/dist/skills/frameworks/elysia/elysiajs/integrations/deno.md +34 -0
  143. package/dist/skills/frameworks/elysia/elysiajs/integrations/drizzle.md +258 -0
  144. package/dist/skills/frameworks/elysia/elysiajs/integrations/expo.md +95 -0
  145. package/dist/skills/frameworks/elysia/elysiajs/integrations/nextjs.md +103 -0
  146. package/dist/skills/frameworks/elysia/elysiajs/integrations/nodejs.md +64 -0
  147. package/dist/skills/frameworks/elysia/elysiajs/integrations/nuxt.md +67 -0
  148. package/dist/skills/frameworks/elysia/elysiajs/integrations/prisma.md +93 -0
  149. package/dist/skills/frameworks/elysia/elysiajs/integrations/react-email.md +134 -0
  150. package/dist/skills/frameworks/elysia/elysiajs/integrations/sveltekit.md +53 -0
  151. package/dist/skills/frameworks/elysia/elysiajs/integrations/tanstack-start.md +87 -0
  152. package/dist/skills/frameworks/elysia/elysiajs/integrations/vercel.md +55 -0
  153. package/dist/skills/frameworks/elysia/elysiajs/patterns/mvc.md +380 -0
  154. package/dist/skills/frameworks/elysia/elysiajs/plugins/bearer.md +30 -0
  155. package/dist/skills/frameworks/elysia/elysiajs/plugins/cors.md +141 -0
  156. package/dist/skills/frameworks/elysia/elysiajs/plugins/cron.md +265 -0
  157. package/dist/skills/frameworks/elysia/elysiajs/plugins/graphql-apollo.md +90 -0
  158. package/dist/skills/frameworks/elysia/elysiajs/plugins/graphql-yoga.md +87 -0
  159. package/dist/skills/frameworks/elysia/elysiajs/plugins/html.md +188 -0
  160. package/dist/skills/frameworks/elysia/elysiajs/plugins/jwt.md +197 -0
  161. package/dist/skills/frameworks/elysia/elysiajs/plugins/openapi.md +246 -0
  162. package/dist/skills/frameworks/elysia/elysiajs/plugins/opentelemetry.md +167 -0
  163. package/dist/skills/frameworks/elysia/elysiajs/plugins/server-timing.md +71 -0
  164. package/dist/skills/frameworks/elysia/elysiajs/plugins/static.md +84 -0
  165. package/dist/skills/frameworks/elysia/elysiajs/references/bun-fullstack-dev-server.md +129 -0
  166. package/dist/skills/frameworks/elysia/elysiajs/references/cookie.md +187 -0
  167. package/dist/skills/frameworks/elysia/elysiajs/references/deployment.md +413 -0
  168. package/dist/skills/frameworks/elysia/elysiajs/references/eden.md +158 -0
  169. package/dist/skills/frameworks/elysia/elysiajs/references/lifecycle.md +198 -0
  170. package/dist/skills/frameworks/elysia/elysiajs/references/macro.md +83 -0
  171. package/dist/skills/frameworks/elysia/elysiajs/references/plugin.md +207 -0
  172. package/dist/skills/frameworks/elysia/elysiajs/references/route.md +331 -0
  173. package/dist/skills/frameworks/elysia/elysiajs/references/testing.md +385 -0
  174. package/dist/skills/frameworks/elysia/elysiajs/references/validation.md +491 -0
  175. package/dist/skills/frameworks/elysia/elysiajs/references/websocket.md +250 -0
  176. package/dist/skills/frameworks/nestjs/nestjs-best-practices/.github/workflows/branch-protection.yml +24 -0
  177. package/dist/skills/frameworks/nestjs/nestjs-best-practices/.github/workflows/deploy.yml +61 -0
  178. package/dist/skills/frameworks/nestjs/nestjs-best-practices/AGENTS.md +5958 -0
  179. package/dist/skills/frameworks/nestjs/nestjs-best-practices/SKILL.md +130 -0
  180. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/api-use-dto-serialization.md +182 -0
  181. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/api-use-interceptors.md +202 -0
  182. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/api-use-pipes.md +205 -0
  183. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/api-versioning.md +191 -0
  184. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-avoid-circular-deps.md +80 -0
  185. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-feature-modules.md +82 -0
  186. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-module-sharing.md +141 -0
  187. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-single-responsibility.md +106 -0
  188. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-use-events.md +108 -0
  189. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-use-repository-pattern.md +97 -0
  190. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/db-avoid-n-plus-one.md +139 -0
  191. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/db-use-migrations.md +129 -0
  192. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/db-use-transactions.md +140 -0
  193. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/devops-graceful-shutdown.md +222 -0
  194. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/devops-use-config-module.md +167 -0
  195. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/devops-use-logging.md +232 -0
  196. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-avoid-service-locator.md +104 -0
  197. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-interface-segregation.md +165 -0
  198. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-liskov-substitution.md +221 -0
  199. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-prefer-constructor-injection.md +86 -0
  200. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-scope-awareness.md +94 -0
  201. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-use-interfaces-tokens.md +101 -0
  202. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/error-handle-async-errors.md +125 -0
  203. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/error-throw-http-exceptions.md +114 -0
  204. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/error-use-exception-filters.md +140 -0
  205. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/micro-use-health-checks.md +226 -0
  206. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/micro-use-patterns.md +167 -0
  207. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/micro-use-queues.md +252 -0
  208. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/perf-async-hooks.md +109 -0
  209. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/perf-lazy-loading.md +121 -0
  210. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/perf-optimize-database.md +131 -0
  211. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/perf-use-caching.md +128 -0
  212. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-auth-jwt.md +146 -0
  213. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-rate-limiting.md +125 -0
  214. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-sanitize-output.md +139 -0
  215. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-use-guards.md +135 -0
  216. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-validate-all-input.md +150 -0
  217. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/test-e2e-supertest.md +178 -0
  218. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/test-mock-external-services.md +179 -0
  219. package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/test-use-testing-module.md +153 -0
  220. package/dist/skills/frameworks/nestjs/nestjs-best-practices/scripts/build-agents.ts +299 -0
  221. package/dist/skills/frameworks/nestjs/nestjs-best-practices/scripts/build.sh +16 -0
  222. package/dist/skills/frameworks/nestjs/nestjs-best-practices/scripts/package-lock.json +237 -0
  223. package/dist/skills/frameworks/nestjs/nestjs-best-practices/scripts/package.json +15 -0
  224. package/dist/skills/frameworks/nestjs/nestjs-expert/SKILL.md +208 -0
  225. package/dist/skills/frameworks/nestjs/nestjs-expert/references/authentication.md +166 -0
  226. package/dist/skills/frameworks/nestjs/nestjs-expert/references/controllers-routing.md +111 -0
  227. package/dist/skills/frameworks/nestjs/nestjs-expert/references/dtos-validation.md +153 -0
  228. package/dist/skills/frameworks/nestjs/nestjs-expert/references/migration-from-express.md +1237 -0
  229. package/dist/skills/frameworks/nestjs/nestjs-expert/references/services-di.md +140 -0
  230. package/dist/skills/frameworks/nestjs/nestjs-expert/references/testing-patterns.md +186 -0
  231. package/dist/skills/frameworks/nextjs/next-best-practices/SKILL.md +153 -0
  232. package/dist/skills/frameworks/nextjs/next-best-practices/async-patterns.md +87 -0
  233. package/dist/skills/frameworks/nextjs/next-best-practices/bundling.md +180 -0
  234. package/dist/skills/frameworks/nextjs/next-best-practices/data-patterns.md +297 -0
  235. package/dist/skills/frameworks/nextjs/next-best-practices/debug-tricks.md +105 -0
  236. package/dist/skills/frameworks/nextjs/next-best-practices/directives.md +73 -0
  237. package/dist/skills/frameworks/nextjs/next-best-practices/error-handling.md +227 -0
  238. package/dist/skills/frameworks/nextjs/next-best-practices/file-conventions.md +140 -0
  239. package/dist/skills/frameworks/nextjs/next-best-practices/font.md +245 -0
  240. package/dist/skills/frameworks/nextjs/next-best-practices/functions.md +108 -0
  241. package/dist/skills/frameworks/nextjs/next-best-practices/hydration-error.md +91 -0
  242. package/dist/skills/frameworks/nextjs/next-best-practices/image.md +173 -0
  243. package/dist/skills/frameworks/nextjs/next-best-practices/metadata.md +301 -0
  244. package/dist/skills/frameworks/nextjs/next-best-practices/parallel-routes.md +287 -0
  245. package/dist/skills/frameworks/nextjs/next-best-practices/route-handlers.md +146 -0
  246. package/dist/skills/frameworks/nextjs/next-best-practices/rsc-boundaries.md +159 -0
  247. package/dist/skills/frameworks/nextjs/next-best-practices/runtime-selection.md +39 -0
  248. package/dist/skills/frameworks/nextjs/next-best-practices/scripts.md +141 -0
  249. package/dist/skills/frameworks/nextjs/next-best-practices/self-hosting.md +371 -0
  250. package/dist/skills/frameworks/nextjs/next-best-practices/suspense-boundaries.md +67 -0
  251. package/dist/skills/frameworks/nextjs/next-cache-components/SKILL.md +360 -0
  252. package/dist/skills/frameworks/react/async-react-patterns/SKILL.md +78 -0
  253. package/dist/skills/frameworks/react/vercel-composition-patterns/AGENTS.md +946 -0
  254. package/dist/skills/frameworks/react/vercel-composition-patterns/SKILL.md +89 -0
  255. package/dist/skills/frameworks/react/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  256. package/dist/skills/frameworks/react/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
  257. package/dist/skills/frameworks/react/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  258. package/dist/skills/frameworks/react/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
  259. package/dist/skills/frameworks/react/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
  260. package/dist/skills/frameworks/react/vercel-composition-patterns/rules/state-context-interface.md +191 -0
  261. package/dist/skills/frameworks/react/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
  262. package/dist/skills/frameworks/react/vercel-composition-patterns/rules/state-lift-state.md +125 -0
  263. package/dist/skills/frameworks/react/vercel-react-best-practices/AGENTS.md +3750 -0
  264. package/dist/skills/frameworks/react/vercel-react-best-practices/SKILL.md +148 -0
  265. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/advanced-effect-event-deps.md +56 -0
  266. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  267. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  268. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  269. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  270. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
  271. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-defer-await.md +82 -0
  272. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  273. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-parallel.md +28 -0
  274. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  275. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
  276. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  277. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  278. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  279. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  280. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  281. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  282. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  283. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  284. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  285. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  286. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  287. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  288. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  289. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  290. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
  291. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  292. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  293. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  294. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  295. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
  296. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  297. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  298. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  299. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  300. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  301. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  302. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  303. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  304. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  305. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
  306. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
  307. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  308. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  309. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  310. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  311. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  312. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  313. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  314. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  315. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  316. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  317. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  318. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
  319. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  320. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
  321. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  322. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
  323. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  324. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  325. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  326. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  327. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  328. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  329. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
  330. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-no-shared-module-state.md +50 -0
  331. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  332. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
  333. package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-serialization.md +38 -0
  334. package/dist/skills/frameworks/tanstack-query/tanstack-query/.claude-plugin/plugin.json +12 -0
  335. package/dist/skills/frameworks/tanstack-query/tanstack-query/SKILL.md +1058 -0
  336. package/dist/skills/frameworks/tanstack-query/tanstack-query/assets/example-template.txt +14 -0
  337. package/dist/skills/frameworks/tanstack-query/tanstack-query/references/best-practices.md +304 -0
  338. package/dist/skills/frameworks/tanstack-query/tanstack-query/references/common-patterns.md +271 -0
  339. package/dist/skills/frameworks/tanstack-query/tanstack-query/references/example-reference.md +26 -0
  340. package/dist/skills/frameworks/tanstack-query/tanstack-query/references/testing.md +282 -0
  341. package/dist/skills/frameworks/tanstack-query/tanstack-query/references/top-errors.md +332 -0
  342. package/dist/skills/frameworks/tanstack-query/tanstack-query/references/typescript-patterns.md +291 -0
  343. package/dist/skills/frameworks/tanstack-query/tanstack-query/references/v4-to-v5-migration.md +231 -0
  344. package/dist/skills/frameworks/tanstack-query/tanstack-query/rules/tanstack-query.md +126 -0
  345. package/dist/skills/frameworks/tanstack-query/tanstack-query/scripts/example-script.sh +15 -0
  346. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/custom-hooks-pattern.tsx +281 -0
  347. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/devtools-setup.tsx +248 -0
  348. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/error-boundary.tsx +243 -0
  349. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/package.json +31 -0
  350. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/provider-setup.tsx +50 -0
  351. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/query-client-config.ts +72 -0
  352. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/use-infinite-query.tsx +214 -0
  353. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/use-mutation-basic.tsx +201 -0
  354. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/use-mutation-optimistic.tsx +234 -0
  355. package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/use-query-basic.tsx +119 -0
  356. package/dist/skills/frameworks/trpc/tanstack-query/.claude-plugin/plugin.json +12 -0
  357. package/dist/skills/frameworks/trpc/tanstack-query/SKILL.md +1058 -0
  358. package/dist/skills/frameworks/trpc/tanstack-query/assets/example-template.txt +14 -0
  359. package/dist/skills/frameworks/trpc/tanstack-query/references/best-practices.md +304 -0
  360. package/dist/skills/frameworks/trpc/tanstack-query/references/common-patterns.md +271 -0
  361. package/dist/skills/frameworks/trpc/tanstack-query/references/example-reference.md +26 -0
  362. package/dist/skills/frameworks/trpc/tanstack-query/references/testing.md +282 -0
  363. package/dist/skills/frameworks/trpc/tanstack-query/references/top-errors.md +332 -0
  364. package/dist/skills/frameworks/trpc/tanstack-query/references/typescript-patterns.md +291 -0
  365. package/dist/skills/frameworks/trpc/tanstack-query/references/v4-to-v5-migration.md +231 -0
  366. package/dist/skills/frameworks/trpc/tanstack-query/rules/tanstack-query.md +126 -0
  367. package/dist/skills/frameworks/trpc/tanstack-query/scripts/example-script.sh +15 -0
  368. package/dist/skills/frameworks/trpc/tanstack-query/templates/custom-hooks-pattern.tsx +281 -0
  369. package/dist/skills/frameworks/trpc/tanstack-query/templates/devtools-setup.tsx +248 -0
  370. package/dist/skills/frameworks/trpc/tanstack-query/templates/error-boundary.tsx +243 -0
  371. package/dist/skills/frameworks/trpc/tanstack-query/templates/package.json +31 -0
  372. package/dist/skills/frameworks/trpc/tanstack-query/templates/provider-setup.tsx +50 -0
  373. package/dist/skills/frameworks/trpc/tanstack-query/templates/query-client-config.ts +72 -0
  374. package/dist/skills/frameworks/trpc/tanstack-query/templates/use-infinite-query.tsx +214 -0
  375. package/dist/skills/frameworks/trpc/tanstack-query/templates/use-mutation-basic.tsx +201 -0
  376. package/dist/skills/frameworks/trpc/tanstack-query/templates/use-mutation-optimistic.tsx +234 -0
  377. package/dist/skills/frameworks/trpc/tanstack-query/templates/use-query-basic.tsx +119 -0
  378. package/dist/skills/frameworks/turborepo/turborepo/SKILL.md +914 -0
  379. package/dist/skills/frameworks/turborepo/turborepo/command/turborepo.md +70 -0
  380. package/dist/skills/frameworks/turborepo/turborepo/references/best-practices/RULE.md +241 -0
  381. package/dist/skills/frameworks/turborepo/turborepo/references/best-practices/dependencies.md +246 -0
  382. package/dist/skills/frameworks/turborepo/turborepo/references/best-practices/packages.md +335 -0
  383. package/dist/skills/frameworks/turborepo/turborepo/references/best-practices/structure.md +270 -0
  384. package/dist/skills/frameworks/turborepo/turborepo/references/boundaries/RULE.md +126 -0
  385. package/dist/skills/frameworks/turborepo/turborepo/references/caching/RULE.md +107 -0
  386. package/dist/skills/frameworks/turborepo/turborepo/references/caching/gotchas.md +169 -0
  387. package/dist/skills/frameworks/turborepo/turborepo/references/caching/remote-cache.md +127 -0
  388. package/dist/skills/frameworks/turborepo/turborepo/references/ci/RULE.md +79 -0
  389. package/dist/skills/frameworks/turborepo/turborepo/references/ci/github-actions.md +162 -0
  390. package/dist/skills/frameworks/turborepo/turborepo/references/ci/patterns.md +145 -0
  391. package/dist/skills/frameworks/turborepo/turborepo/references/ci/vercel.md +103 -0
  392. package/dist/skills/frameworks/turborepo/turborepo/references/cli/RULE.md +100 -0
  393. package/dist/skills/frameworks/turborepo/turborepo/references/cli/commands.md +297 -0
  394. package/dist/skills/frameworks/turborepo/turborepo/references/configuration/RULE.md +211 -0
  395. package/dist/skills/frameworks/turborepo/turborepo/references/configuration/global-options.md +187 -0
  396. package/dist/skills/frameworks/turborepo/turborepo/references/configuration/gotchas.md +348 -0
  397. package/dist/skills/frameworks/turborepo/turborepo/references/configuration/tasks.md +285 -0
  398. package/dist/skills/frameworks/turborepo/turborepo/references/environment/RULE.md +96 -0
  399. package/dist/skills/frameworks/turborepo/turborepo/references/environment/gotchas.md +141 -0
  400. package/dist/skills/frameworks/turborepo/turborepo/references/environment/modes.md +101 -0
  401. package/dist/skills/frameworks/turborepo/turborepo/references/filtering/RULE.md +148 -0
  402. package/dist/skills/frameworks/turborepo/turborepo/references/filtering/patterns.md +152 -0
  403. package/dist/skills/frameworks/turborepo/turborepo/references/watch/RULE.md +99 -0
  404. package/dist/tsconfig.tsbuildinfo +1 -0
  405. package/docs/README.md +20 -0
  406. package/docs/reference/dp-requirements.md +210 -0
  407. package/docs/runbooks/dp-cli-scaffolding.md +187 -0
  408. package/package.json +24 -50
  409. package/.eslintignore +0 -4
  410. package/.eslintrc +0 -127
  411. package/.prettierignore +0 -4
  412. package/.prettierrc +0 -7
  413. package/bin/abstractions/builder.d.ts +0 -4
  414. package/bin/abstractions/builder.js +0 -7
  415. package/bin/builders/dotnet/base.d.ts +0 -18
  416. package/bin/builders/dotnet/base.js +0 -47
  417. package/bin/builders/dotnet/entity-configuration/index.d.ts +0 -8
  418. package/bin/builders/dotnet/entity-configuration/index.js +0 -29
  419. package/bin/builders/dotnet/entity-converter/index.d.ts +0 -8
  420. package/bin/builders/dotnet/entity-converter/index.js +0 -29
  421. package/bin/builders/dotnet/entity-model-create/index.d.ts +0 -8
  422. package/bin/builders/dotnet/entity-model-create/index.js +0 -29
  423. package/bin/builders/dotnet/entity-model-dto/index.d.ts +0 -8
  424. package/bin/builders/dotnet/entity-model-dto/index.js +0 -29
  425. package/bin/builders/dotnet/entity-model-list-item-dto/index.d.ts +0 -8
  426. package/bin/builders/dotnet/entity-model-list-item-dto/index.js +0 -29
  427. package/bin/builders/dotnet/entity-model-update/index.d.ts +0 -8
  428. package/bin/builders/dotnet/entity-model-update/index.js +0 -29
  429. package/bin/builders/dotnet/entity-search-parameters/index.d.ts +0 -8
  430. package/bin/builders/dotnet/entity-search-parameters/index.js +0 -29
  431. package/bin/builders/dotnet/entity-search-query-builder/index.d.ts +0 -8
  432. package/bin/builders/dotnet/entity-search-query-builder/index.js +0 -29
  433. package/bin/builders/dotnet/firestore-connector/index.d.ts +0 -8
  434. package/bin/builders/dotnet/firestore-connector/index.js +0 -29
  435. package/bin/builders/dotnet/firestore-mapper/index.d.ts +0 -8
  436. package/bin/builders/dotnet/firestore-mapper/index.js +0 -29
  437. package/bin/builders/dotnet/types.d.ts +0 -10
  438. package/bin/builders/dotnet/types.js +0 -3
  439. package/bin/commands/entity-add/__test__/dotnet/common.d.ts +0 -2
  440. package/bin/commands/entity-add/__test__/dotnet/common.js +0 -11
  441. package/bin/commands/entity-add/__test__/dotnet/render.configuration.spec.d.ts +0 -1
  442. package/bin/commands/entity-add/__test__/dotnet/render.configuration.spec.js +0 -22
  443. package/bin/commands/entity-add/__test__/dotnet/render.converter.spec.d.ts +0 -1
  444. package/bin/commands/entity-add/__test__/dotnet/render.converter.spec.js +0 -22
  445. package/bin/commands/entity-add/__test__/dotnet/render.firestore-connector.spec.d.ts +0 -1
  446. package/bin/commands/entity-add/__test__/dotnet/render.firestore-connector.spec.js +0 -22
  447. package/bin/commands/entity-add/__test__/dotnet/render.firestore-mapper.spec.d.ts +0 -1
  448. package/bin/commands/entity-add/__test__/dotnet/render.firestore-mapper.spec.js +0 -22
  449. package/bin/commands/entity-add/__test__/dotnet/render.model-create.spec.d.ts +0 -1
  450. package/bin/commands/entity-add/__test__/dotnet/render.model-create.spec.js +0 -22
  451. package/bin/commands/entity-add/__test__/dotnet/render.model-dto.spec.d.ts +0 -1
  452. package/bin/commands/entity-add/__test__/dotnet/render.model-dto.spec.js +0 -22
  453. package/bin/commands/entity-add/__test__/dotnet/render.model-list-item-dto.spec.d.ts +0 -1
  454. package/bin/commands/entity-add/__test__/dotnet/render.model-list-item-dto.spec.js +0 -22
  455. package/bin/commands/entity-add/__test__/dotnet/render.model-update.spec.d.ts +0 -1
  456. package/bin/commands/entity-add/__test__/dotnet/render.model-update.spec.js +0 -22
  457. package/bin/commands/entity-add/__test__/dotnet/render.search-parameters.spec.d.ts +0 -1
  458. package/bin/commands/entity-add/__test__/dotnet/render.search-parameters.spec.js +0 -22
  459. package/bin/commands/entity-add/__test__/dotnet/render.search-query.spec.d.ts +0 -1
  460. package/bin/commands/entity-add/__test__/dotnet/render.search-query.spec.js +0 -22
  461. package/bin/commands/entity-add/index.d.ts +0 -26
  462. package/bin/commands/entity-add/index.js +0 -44
  463. package/bin/logging/index.d.ts +0 -8
  464. package/bin/logging/index.js +0 -28
  465. package/bin/providers/rendering/base.d.ts +0 -3
  466. package/bin/providers/rendering/base.js +0 -7
  467. package/bin/providers/rendering/factory.d.ts +0 -5
  468. package/bin/providers/rendering/factory.js +0 -16
  469. package/bin/providers/rendering/handlebars.d.ts +0 -4
  470. package/bin/providers/rendering/handlebars.js +0 -16
  471. package/bin/renderer/index.d.ts +0 -6
  472. package/bin/renderer/index.js +0 -27
  473. package/bin/run.d.ts +0 -2
  474. package/bin/run.js +0 -70
  475. package/bin/services/folders.d.ts +0 -1
  476. package/bin/services/folders.js +0 -31
  477. package/bin/types/commands.d.ts +0 -5
  478. package/bin/types/commands.js +0 -3
  479. package/bin/utils/collections.d.ts +0 -1
  480. package/bin/utils/collections.js +0 -6
  481. package/bin/utils/files.d.ts +0 -3
  482. package/bin/utils/files.js +0 -19
  483. package/bin/utils/strings.d.ts +0 -4
  484. package/bin/utils/strings.js +0 -22
  485. package/bin/utils/text.d.ts +0 -1
  486. package/bin/utils/text.js +0 -8
  487. package/em-cli +0 -0
  488. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.configuration.spec.ts.snap +0 -49
  489. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.converter.spec.ts.snap +0 -53
  490. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.firestore-connector.spec.ts.snap +0 -20
  491. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.firestore-mapper.spec.ts.snap +0 -29
  492. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.model-create.spec.ts.snap +0 -10
  493. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.model-dto.spec.ts.snap +0 -9
  494. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.model-list-item-dto.spec.ts.snap +0 -11
  495. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.model-update.spec.ts.snap +0 -11
  496. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.search-parameters.spec.ts.snap +0 -29
  497. package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.search-query.spec.ts.snap +0 -42
  498. package/templates/dotnet/NewEntity/Configuration/<PluralizedEntity>Configuration.cs.template +0 -48
  499. package/templates/dotnet/NewEntity/Connectors/<PluralizedEntity>FirestoreConnector.cs.template +0 -15
  500. package/templates/dotnet/NewEntity/Converters/<PluralizedEntity>Converter.cs.template +0 -48
  501. package/templates/dotnet/NewEntity/Mappers/<PluralizedEntity>FirestoreMapper.cs.template +0 -25
  502. package/templates/dotnet/NewEntity/Models/<Entity>CreateInput.cs.template +0 -6
  503. package/templates/dotnet/NewEntity/Models/<Entity>Dto.cs.template +0 -5
  504. package/templates/dotnet/NewEntity/Models/<Entity>ListItemDto.cs.template +0 -6
  505. package/templates/dotnet/NewEntity/Models/<Entity>UpdateInput.cs.template +0 -6
  506. package/templates/dotnet/NewEntity/Search/<PluralizedEntity>QueryBuilder.cs.template +0 -38
  507. package/templates/dotnet/NewEntity/Search/<PluralizedEntity>SearchParameters.cs.template +0 -24
  508. package/tsconfig.json +0 -25
@@ -0,0 +1,353 @@
1
+ # Schema Patterns
2
+
3
+ ## Branded Types for IDs
4
+
5
+ **Always brand entity IDs** to prevent accidentally passing the wrong ID type:
6
+
7
+ ```typescript
8
+ import { Schema } from "effect"
9
+
10
+ // Entity IDs - always branded with namespace
11
+ export const UserId = Schema.UUID.pipe(Schema.brand("@App/UserId"))
12
+ export type UserId = Schema.Schema.Type<typeof UserId>
13
+
14
+ export const OrganizationId = Schema.UUID.pipe(Schema.brand("@App/OrganizationId"))
15
+ export type OrganizationId = Schema.Schema.Type<typeof OrganizationId>
16
+
17
+ export const OrderId = Schema.UUID.pipe(Schema.brand("@App/OrderId"))
18
+ export type OrderId = Schema.Schema.Type<typeof OrderId>
19
+
20
+ export const ProductId = Schema.UUID.pipe(Schema.brand("@App/ProductId"))
21
+ export type ProductId = Schema.Schema.Type<typeof ProductId>
22
+ ```
23
+
24
+ ### Branding Convention
25
+
26
+ Use `@Namespace/EntityName` format:
27
+ - `@App/UserId` - Main application entities
28
+ - `@Billing/InvoiceId` - Billing domain entities
29
+ - `@External/StripeCustomerId` - External system IDs
30
+
31
+ ### Creating Branded Values
32
+
33
+ ```typescript
34
+ // From string (validates UUID format)
35
+ const userId = Schema.decodeSync(UserId)("123e4567-e89b-12d3-a456-426614174000")
36
+
37
+ // Generate new ID
38
+ const newUserId = UserId.make(crypto.randomUUID())
39
+
40
+ // Type error - can't mix ID types
41
+ const order = yield* orderService.findById(userId) // Error: UserId is not OrderId
42
+ ```
43
+
44
+ ### When NOT to Brand
45
+
46
+ Don't brand simple strings that don't need type safety:
47
+
48
+ ```typescript
49
+ // NOT branded - acceptable
50
+ export const Url = Schema.String
51
+ export const FilePath = Schema.String
52
+ export const EmailAddress = Schema.String.pipe(Schema.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/))
53
+
54
+ // These don't need branding because:
55
+ // 1. They don't cross service boundaries in ways that could be confused
56
+ // 2. They're typically validated by format, not by type
57
+ ```
58
+
59
+ ## Schema.Struct for Domain Types
60
+
61
+ **Prefer Schema.Struct** over TypeScript interfaces for domain types:
62
+
63
+ ```typescript
64
+ // CORRECT - Schema.Struct
65
+ export const User = Schema.Struct({
66
+ id: UserId,
67
+ email: Schema.String,
68
+ name: Schema.String,
69
+ organizationId: OrganizationId,
70
+ role: Schema.Literal("admin", "member", "viewer"),
71
+ createdAt: Schema.DateTimeUtc,
72
+ updatedAt: Schema.DateTimeUtc,
73
+ })
74
+ export type User = Schema.Schema.Type<typeof User>
75
+
76
+ // Can derive encoded type for database/API
77
+ export type UserEncoded = Schema.Schema.Encoded<typeof User>
78
+ ```
79
+
80
+ ### Input Types for Mutations
81
+
82
+ ```typescript
83
+ export const CreateUserInput = Schema.Struct({
84
+ email: Schema.String.pipe(
85
+ Schema.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/),
86
+ Schema.annotations({ description: "Valid email address" }),
87
+ ),
88
+ name: Schema.String.pipe(
89
+ Schema.minLength(1),
90
+ Schema.maxLength(100),
91
+ ),
92
+ organizationId: OrganizationId,
93
+ role: Schema.optionalWith(
94
+ Schema.Literal("admin", "member", "viewer"),
95
+ { default: () => "member" as const }
96
+ ),
97
+ })
98
+ export type CreateUserInput = Schema.Schema.Type<typeof CreateUserInput>
99
+
100
+ export const UpdateUserInput = Schema.Struct({
101
+ name: Schema.optional(Schema.String.pipe(Schema.minLength(1))),
102
+ role: Schema.optional(Schema.Literal("admin", "member", "viewer")),
103
+ })
104
+ export type UpdateUserInput = Schema.Schema.Type<typeof UpdateUserInput>
105
+ ```
106
+
107
+ ## Schema.transform and transformOrFail
108
+
109
+ **Use transforms** instead of manual parsing:
110
+
111
+ ```typescript
112
+ // Transform string to Date
113
+ export const DateFromString = Schema.transform(
114
+ Schema.String,
115
+ Schema.DateTimeUtc,
116
+ {
117
+ decode: (s) => new Date(s),
118
+ encode: (d) => d.toISOString(),
119
+ }
120
+ )
121
+
122
+ // Transform with validation (can fail)
123
+ export const PositiveNumber = Schema.transformOrFail(
124
+ Schema.Number,
125
+ Schema.Number.pipe(Schema.brand("PositiveNumber")),
126
+ {
127
+ decode: (n, _, ast) =>
128
+ n > 0
129
+ ? ParseResult.succeed(n as Schema.Schema.Type<typeof PositiveNumber>)
130
+ : ParseResult.fail(new ParseResult.Type(ast, n, "Must be positive")),
131
+ encode: ParseResult.succeed,
132
+ }
133
+ )
134
+ ```
135
+
136
+ ### Common Transforms
137
+
138
+ ```typescript
139
+ // JSON string to object
140
+ export const JsonFromString = <A, I>(schema: Schema.Schema<A, I>) =>
141
+ Schema.transform(
142
+ Schema.String,
143
+ schema,
144
+ {
145
+ decode: (s) => JSON.parse(s),
146
+ encode: (a) => JSON.stringify(a),
147
+ }
148
+ )
149
+
150
+ // Comma-separated string to array
151
+ export const CommaSeparatedList = Schema.transform(
152
+ Schema.String,
153
+ Schema.Array(Schema.String),
154
+ {
155
+ decode: (s) => s.split(",").map((x) => x.trim()).filter(Boolean),
156
+ encode: (arr) => arr.join(","),
157
+ }
158
+ )
159
+
160
+ // Cents to dollars
161
+ export const DollarsFromCents = Schema.transform(
162
+ Schema.Number.pipe(Schema.int()),
163
+ Schema.Number,
164
+ {
165
+ decode: (cents) => cents / 100,
166
+ encode: (dollars) => Math.round(dollars * 100),
167
+ }
168
+ )
169
+ ```
170
+
171
+ ## Schema.Class for Entities with Methods
172
+
173
+ Use `Schema.Class` when entities need methods:
174
+
175
+ ```typescript
176
+ export class User extends Schema.Class<User>("User")({
177
+ id: UserId,
178
+ email: Schema.String,
179
+ name: Schema.String,
180
+ role: Schema.Literal("admin", "member", "viewer"),
181
+ createdAt: Schema.DateTimeUtc,
182
+ }) {
183
+ get isAdmin(): boolean {
184
+ return this.role === "admin"
185
+ }
186
+
187
+ get displayName(): string {
188
+ return this.name || this.email.split("@")[0]
189
+ }
190
+
191
+ canAccessResource(resource: Resource): boolean {
192
+ if (this.isAdmin) return true
193
+ return resource.ownerId === this.id
194
+ }
195
+ }
196
+
197
+ // Usage
198
+ const user = new User({
199
+ id: UserId.make(crypto.randomUUID()),
200
+ email: "alice@example.com",
201
+ name: "Alice",
202
+ role: "member",
203
+ createdAt: new Date(),
204
+ })
205
+
206
+ console.log(user.displayName) // "Alice"
207
+ console.log(user.isAdmin) // false
208
+ ```
209
+
210
+ ## Schema.annotations
211
+
212
+ Add annotations for documentation and validation messages:
213
+
214
+ ```typescript
215
+ export const CreateOrderInput = Schema.Struct({
216
+ productId: ProductId.pipe(
217
+ Schema.annotations({ description: "The product to order" }),
218
+ ),
219
+ quantity: Schema.Number.pipe(
220
+ Schema.int(),
221
+ Schema.positive(),
222
+ Schema.annotations({
223
+ description: "Number of items to order",
224
+ examples: [1, 5, 10],
225
+ }),
226
+ ),
227
+ shippingAddress: Schema.Struct({
228
+ line1: Schema.String.pipe(Schema.annotations({ description: "Street address" })),
229
+ line2: Schema.optional(Schema.String),
230
+ city: Schema.String,
231
+ state: Schema.String.pipe(Schema.length(2)),
232
+ zip: Schema.String.pipe(Schema.pattern(/^\d{5}(-\d{4})?$/)),
233
+ }).pipe(Schema.annotations({ description: "Shipping destination" })),
234
+ }).pipe(
235
+ Schema.annotations({
236
+ title: "Create Order Input",
237
+ description: "Input for creating a new order",
238
+ }),
239
+ )
240
+ ```
241
+
242
+ ## Optional Fields
243
+
244
+ Use `Schema.optional` and `Schema.optionalWith`:
245
+
246
+ ```typescript
247
+ export const UserPreferences = Schema.Struct({
248
+ // Optional, undefined if not provided
249
+ theme: Schema.optional(Schema.Literal("light", "dark")),
250
+
251
+ // Optional with default value
252
+ language: Schema.optionalWith(Schema.String, { default: () => "en" }),
253
+
254
+ // Optional with null support (for database compatibility)
255
+ bio: Schema.NullOr(Schema.String),
256
+
257
+ // Optional but must be present if set (no undefined)
258
+ timezone: Schema.optional(Schema.String, { exact: true }),
259
+ })
260
+ ```
261
+
262
+ ## Union Types and Discriminated Unions
263
+
264
+ ```typescript
265
+ // Simple union
266
+ export const PaymentMethod = Schema.Union(
267
+ Schema.Literal("card"),
268
+ Schema.Literal("bank_transfer"),
269
+ Schema.Literal("crypto"),
270
+ )
271
+
272
+ // Discriminated union (tagged)
273
+ export const PaymentDetails = Schema.Union(
274
+ Schema.Struct({
275
+ _tag: Schema.Literal("Card"),
276
+ cardNumber: Schema.String,
277
+ expiry: Schema.String,
278
+ cvv: Schema.String,
279
+ }),
280
+ Schema.Struct({
281
+ _tag: Schema.Literal("BankTransfer"),
282
+ accountNumber: Schema.String,
283
+ routingNumber: Schema.String,
284
+ }),
285
+ Schema.Struct({
286
+ _tag: Schema.Literal("Crypto"),
287
+ walletAddress: Schema.String,
288
+ network: Schema.Literal("ethereum", "bitcoin", "solana"),
289
+ }),
290
+ )
291
+ export type PaymentDetails = Schema.Schema.Type<typeof PaymentDetails>
292
+
293
+ // Usage with match
294
+ const processPayment = (details: PaymentDetails) => {
295
+ switch (details._tag) {
296
+ case "Card":
297
+ return processCard(details.cardNumber, details.expiry, details.cvv)
298
+ case "BankTransfer":
299
+ return processBankTransfer(details.accountNumber, details.routingNumber)
300
+ case "Crypto":
301
+ return processCrypto(details.walletAddress, details.network)
302
+ }
303
+ }
304
+ ```
305
+
306
+ ## Enums and Literals
307
+
308
+ ```typescript
309
+ // Use Literal for small, fixed sets
310
+ export const UserRole = Schema.Literal("admin", "member", "viewer")
311
+ export type UserRole = Schema.Schema.Type<typeof UserRole>
312
+
313
+ // Use Enums for larger sets or when you need runtime values
314
+ export const OrderStatus = Schema.Enums({
315
+ Pending: "pending",
316
+ Processing: "processing",
317
+ Shipped: "shipped",
318
+ Delivered: "delivered",
319
+ Cancelled: "cancelled",
320
+ } as const)
321
+ export type OrderStatus = Schema.Schema.Type<typeof OrderStatus>
322
+ ```
323
+
324
+ ## Recursive Schemas
325
+
326
+ ```typescript
327
+ interface Category {
328
+ id: string
329
+ name: string
330
+ children: readonly Category[]
331
+ }
332
+
333
+ export const Category: Schema.Schema<Category> = Schema.Struct({
334
+ id: Schema.String,
335
+ name: Schema.String,
336
+ children: Schema.Array(Schema.suspend(() => Category)),
337
+ })
338
+ ```
339
+
340
+ ## Decoding and Encoding
341
+
342
+ ```typescript
343
+ // Decode (parse) - use in services
344
+ const parseUser = Schema.decodeUnknown(User)
345
+ const result = yield* parseUser(rawData) // Effect<User, ParseError>
346
+
347
+ // Decode sync - only in controlled contexts
348
+ const user = Schema.decodeUnknownSync(User)(rawData)
349
+
350
+ // Encode - for serialization
351
+ const encodeUser = Schema.encode(User)
352
+ const encoded = yield* encodeUser(user) // Effect<UserEncoded, ParseError>
353
+ ```
@@ -0,0 +1,299 @@
1
+ # Service Patterns
2
+
3
+ ## Effect.Service Over Context.Tag
4
+
5
+ **Always prefer `Effect.Service`** for defining business logic services. This is the modern, recommended approach that provides:
6
+
7
+ 1. **Built-in `Default` layer** - No manual layer creation needed
8
+ 2. **Automatic accessors** - Direct method calls via `ServiceName.method()`
9
+ 3. **Proper dependency declaration** - Dependencies are explicit and type-checked
10
+ 4. **Consistent structure** - All services follow the same pattern
11
+
12
+ The underlying architecture is the same as the classic `Context.Tag` + `Layer` pattern: a service is a typed capability requirement, and a layer supplies the implementation. Keep that requirement visible in the Effect environment or the service `dependencies` array until a layer provides it.
13
+
14
+ ### Basic Service Definition
15
+
16
+ ```typescript
17
+ import { Effect, Layer } from "effect"
18
+
19
+ export class UserService extends Effect.Service<UserService>()("UserService", {
20
+ accessors: true,
21
+ effect: Effect.gen(function* () {
22
+ const findById = Effect.fn("UserService.findById")(function* (id: UserId) {
23
+ // Implementation
24
+ })
25
+
26
+ const findByEmail = Effect.fn("UserService.findByEmail")(function* (email: string) {
27
+ // Implementation
28
+ })
29
+
30
+ const create = Effect.fn("UserService.create")(function* (input: CreateUserInput) {
31
+ // Implementation
32
+ })
33
+
34
+ return { findById, findByEmail, create }
35
+ }),
36
+ }) {}
37
+ ```
38
+
39
+ ### Service with Dependencies
40
+
41
+ **Critical:** Always declare dependencies using the `dependencies` array. This ensures:
42
+ - Dependencies are automatically provided when using `ServiceName.Default`
43
+ - Type errors if dependencies are missing
44
+ - No manual `Layer.provide` at usage sites
45
+
46
+ ```typescript
47
+ export class OrderService extends Effect.Service<OrderService>()("OrderService", {
48
+ accessors: true,
49
+ dependencies: [
50
+ UserService.Default,
51
+ ProductService.Default,
52
+ InventoryService.Default,
53
+ ],
54
+ effect: Effect.gen(function* () {
55
+ // Dependencies are automatically available
56
+ const users = yield* UserService
57
+ const products = yield* ProductService
58
+ const inventory = yield* InventoryService
59
+
60
+ const create = Effect.fn("OrderService.create")(function* (input: CreateOrderInput) {
61
+ // Validate user exists
62
+ const user = yield* users.findById(input.userId)
63
+
64
+ // Check product availability
65
+ const product = yield* products.findById(input.productId)
66
+ const available = yield* inventory.checkAvailability(input.productId, input.quantity)
67
+
68
+ if (!available) {
69
+ return yield* Effect.fail(new InsufficientInventoryError({
70
+ productId: input.productId,
71
+ message: "Not enough inventory",
72
+ }))
73
+ }
74
+
75
+ // Create order...
76
+ })
77
+
78
+ return { create }
79
+ }),
80
+ }) {}
81
+ ```
82
+
83
+ ### Wrong: Leaking Dependencies
84
+
85
+ ```typescript
86
+ // WRONG - Dependencies not declared, must be provided manually
87
+ export class OrderService extends Effect.Service<OrderService>()("OrderService", {
88
+ accessors: true,
89
+ effect: Effect.gen(function* () {
90
+ const users = yield* UserService // Dependency not in `dependencies` array!
91
+ // ...
92
+ }),
93
+ }) {}
94
+
95
+ // Now every usage site must do this:
96
+ const program = OrderService.create(input).pipe(
97
+ Effect.provide(UserService.Default), // Annoying and error-prone
98
+ )
99
+ ```
100
+
101
+ ## Effect.fn for Tracing
102
+
103
+ **Always wrap service methods with `Effect.fn`**. This provides automatic tracing with meaningful span names.
104
+
105
+ ### Naming Convention
106
+
107
+ Use `ServiceName.methodName` format for span names:
108
+
109
+ ```typescript
110
+ const findById = Effect.fn("UserService.findById")(function* (id: UserId) {
111
+ yield* Effect.annotateCurrentSpan("userId", id)
112
+ // Implementation
113
+ })
114
+
115
+ const processPayment = Effect.fn("PaymentService.processPayment")(
116
+ function* (orderId: OrderId, amount: number, currency: string) {
117
+ yield* Effect.annotateCurrentSpan("orderId", orderId)
118
+ yield* Effect.annotateCurrentSpan("amount", amount)
119
+ yield* Effect.annotateCurrentSpan("currency", currency)
120
+ // Implementation
121
+ }
122
+ )
123
+ ```
124
+
125
+ ### Annotating Spans
126
+
127
+ Add important context to spans, but don't overdo it:
128
+
129
+ ```typescript
130
+ // CORRECT - Important business identifiers
131
+ yield* Effect.annotateCurrentSpan("userId", userId)
132
+ yield* Effect.annotateCurrentSpan("orderId", orderId)
133
+ yield* Effect.annotateCurrentSpan("amount", amount)
134
+
135
+ // WRONG - Too much detail, noise in traces
136
+ yield* Effect.annotateCurrentSpan("userEmail", user.email)
137
+ yield* Effect.annotateCurrentSpan("userName", user.name)
138
+ yield* Effect.annotateCurrentSpan("userCreatedAt", user.createdAt)
139
+ yield* Effect.annotateCurrentSpan("step", "validating")
140
+ yield* Effect.annotateCurrentSpan("step", "processing")
141
+ yield* Effect.annotateCurrentSpan("step", "completing")
142
+ ```
143
+
144
+ ## When Context.Tag is Acceptable
145
+
146
+ `Context.Tag` is appropriate **only** for infrastructure that's injected at runtime:
147
+
148
+ ### Cloudflare Worker Bindings
149
+
150
+ ```typescript
151
+ import { Context } from "effect"
152
+
153
+ // These are provided by the runtime, not created by our code
154
+ export class KVNamespace extends Context.Tag("KVNamespace")<
155
+ KVNamespace,
156
+ CloudflareKVNamespace
157
+ >() {}
158
+
159
+ export class R2Bucket extends Context.Tag("R2Bucket")<
160
+ R2Bucket,
161
+ CloudflareR2Bucket
162
+ >() {}
163
+
164
+ // In the worker entry point
165
+ const handler = {
166
+ fetch(request: Request, env: Env) {
167
+ return program.pipe(
168
+ Effect.provideService(KVNamespace, env.MY_KV),
169
+ Effect.provideService(R2Bucket, env.MY_BUCKET),
170
+ Effect.runPromise,
171
+ )
172
+ }
173
+ }
174
+ ```
175
+
176
+ ### Database/Redis Clients (Infrastructure)
177
+
178
+ ```typescript
179
+ // Infrastructure provided at app root - acceptable as Context.Tag
180
+ // But prefer using @effect/sql or similar typed clients
181
+
182
+ import { PgClient } from "@effect/sql-pg"
183
+
184
+ // PgClient is already a Context.Tag from the library
185
+ // Just provide it at the app root
186
+ const DatabaseLive = PgClient.layer({
187
+ host: Config.string("DB_HOST"),
188
+ port: Config.integer("DB_PORT"),
189
+ database: Config.string("DB_NAME"),
190
+ // ...
191
+ })
192
+ ```
193
+
194
+ ## Single Responsibility
195
+
196
+ Each service should have a focused responsibility:
197
+
198
+ ```typescript
199
+ // CORRECT - Focused services
200
+ export class UserService extends Effect.Service<UserService>()("UserService", { /* user operations */ }) {}
201
+ export class AuthService extends Effect.Service<AuthService>()("AuthService", { /* auth operations */ }) {}
202
+ export class NotificationService extends Effect.Service<NotificationService>()("NotificationService", { /* notifications */ }) {}
203
+
204
+ // WRONG - God service doing everything
205
+ export class AppService extends Effect.Service<AppService>()("AppService", {
206
+ effect: Effect.gen(function* () {
207
+ return {
208
+ createUser,
209
+ deleteUser,
210
+ login,
211
+ logout,
212
+ sendEmail,
213
+ sendPush,
214
+ processPayment,
215
+ // ... 50 more methods
216
+ }
217
+ }),
218
+ }) {}
219
+ ```
220
+
221
+ ## Service Interface Patterns
222
+
223
+ ### Return Types
224
+
225
+ Services should return `Effect` types, never `Promise`:
226
+
227
+ ```typescript
228
+ // CORRECT
229
+ const findById = Effect.fn("UserService.findById")(
230
+ function* (id: UserId): Effect.Effect<User, UserNotFoundError> {
231
+ // ...
232
+ }
233
+ )
234
+
235
+ // WRONG - Promise in service interface
236
+ const findById = async (id: UserId): Promise<User> => {
237
+ // ...
238
+ }
239
+ ```
240
+
241
+ ### Use Option for Nullable Results
242
+
243
+ ```typescript
244
+ // CORRECT - findById can fail, findByIdOption returns Option
245
+ const findById = Effect.fn("UserService.findById")(
246
+ function* (id: UserId): Effect.Effect<User, UserNotFoundError> {
247
+ const maybeUser = yield* repo.findById(id)
248
+ return yield* Option.match(maybeUser, {
249
+ onNone: () => Effect.fail(new UserNotFoundError({ userId: id, message: "Not found" })),
250
+ onSome: Effect.succeed,
251
+ })
252
+ }
253
+ )
254
+
255
+ const findByIdOption = Effect.fn("UserService.findByIdOption")(
256
+ function* (id: UserId): Effect.Effect<Option<User>> {
257
+ return yield* repo.findById(id)
258
+ }
259
+ )
260
+ ```
261
+
262
+ ## Testing Services
263
+
264
+ Create test implementations using the same pattern:
265
+
266
+ ```typescript
267
+ // Test implementation
268
+ export const UserServiceTest = Layer.succeed(
269
+ UserService,
270
+ UserService.of({
271
+ findById: (id) => Effect.succeed(mockUser),
272
+ create: (input) => Effect.succeed({ ...mockUser, ...input }),
273
+ })
274
+ )
275
+
276
+ // Or with Effect.Service for stateful mocks
277
+ export class UserServiceTest extends Effect.Service<UserService>()("UserService", {
278
+ accessors: true,
279
+ effect: Effect.gen(function* () {
280
+ const users = new Map<string, User>()
281
+
282
+ const findById = Effect.fn("UserService.findById")(function* (id: UserId) {
283
+ const user = users.get(id)
284
+ if (!user) return yield* Effect.fail(new UserNotFoundError({ userId: id, message: "Not found" }))
285
+ return user
286
+ })
287
+
288
+ const create = Effect.fn("UserService.create")(function* (input: CreateUserInput) {
289
+ const user = { id: UserId.make(crypto.randomUUID()), ...input }
290
+ users.set(user.id, user)
291
+ return user
292
+ })
293
+
294
+ return { findById, create }
295
+ }),
296
+ }) {}
297
+ ```
298
+
299
+ Do not mock Effect services with `vi.mock`, path-based import rewrites, or mutable module singletons. Tests should provide alternate implementations with `Layer.succeed`, a test `Effect.Service`, or a feature-local `tests/support/layer.ts`.