@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.
- package/AGENTS.md +10 -0
- package/README.md +64 -0
- package/dist/data/AGENTS.md +123 -0
- package/dist/data/catalog/lint.ts +349 -0
- package/dist/data/catalog/packs.ts +44 -0
- package/dist/data/catalog/skills.ts +47 -0
- package/dist/data/catalog/tools.ts +22 -0
- package/dist/data/hooks/format-edited-file.mjs +554 -0
- package/dist/data/hooks/format-edited-file.py +157 -0
- package/dist/data/hooks/format-edited-file.sh +37 -0
- package/dist/data/hooks/require-tests-for-pr.mjs +144 -0
- package/dist/data/scripts/sync-subagents.mjs +420 -0
- package/dist/data/subagents/manifest.mjs +253 -0
- package/dist/index.js +46415 -0
- package/dist/skills/agnostic/backend/backend-domain-structure/SKILL.md +50 -0
- package/dist/skills/agnostic/backend/backend-domain-structure/agents/openai.yaml +4 -0
- package/dist/skills/agnostic/backend/backend-domain-structure/references/layout.md +167 -0
- package/dist/skills/agnostic/backend/backend-recoverable-actions/SKILL.md +49 -0
- package/dist/skills/agnostic/backend/backend-recoverable-actions/agents/openai.yaml +4 -0
- package/dist/skills/agnostic/backend/backend-recoverable-actions/references/strategy-matrix.md +34 -0
- package/dist/skills/agnostic/backend/backend-recoverable-actions/references/test-matrix.md +34 -0
- package/dist/skills/agnostic/docs/docs-maintenance/SKILL.md +193 -0
- package/dist/skills/agnostic/docs/docs-maintenance/agents/openai.yaml +4 -0
- package/dist/skills/agnostic/docs/docs-maintenance/references/concept-pages.md +48 -0
- package/dist/skills/agnostic/docs/docs-maintenance/references/flow-pages.md +41 -0
- package/dist/skills/agnostic/frontend/agent-browser/.clawdhub/origin.json +7 -0
- package/dist/skills/agnostic/frontend/agent-browser/SKILL.md +229 -0
- package/dist/skills/agnostic/frontend/agent-browser/references/authentication.md +202 -0
- package/dist/skills/agnostic/frontend/agent-browser/references/commands.md +259 -0
- package/dist/skills/agnostic/frontend/agent-browser/references/proxy-support.md +188 -0
- package/dist/skills/agnostic/frontend/agent-browser/references/session-management.md +193 -0
- package/dist/skills/agnostic/frontend/agent-browser/references/snapshot-refs.md +194 -0
- package/dist/skills/agnostic/frontend/agent-browser/references/video-recording.md +173 -0
- package/dist/skills/agnostic/frontend/agent-browser/templates/authenticated-session.sh +97 -0
- package/dist/skills/agnostic/frontend/agent-browser/templates/capture-workflow.sh +69 -0
- package/dist/skills/agnostic/frontend/agent-browser/templates/form-automation.sh +62 -0
- package/dist/skills/agnostic/frontend/design-taste-frontend/SKILL.md +226 -0
- package/dist/skills/agnostic/frontend/frontend-domain-structure/SKILL.md +55 -0
- package/dist/skills/agnostic/frontend/frontend-domain-structure/agents/openai.yaml +4 -0
- package/dist/skills/agnostic/frontend/frontend-domain-structure/references/react/structure.md +102 -0
- package/dist/skills/agnostic/frontend/frontend-domain-structure/references/structure.md +257 -0
- package/dist/skills/agnostic/frontend/gpt-taste/SKILL.md +74 -0
- package/dist/skills/agnostic/frontend/image-taste-frontend/SKILL.md +1102 -0
- package/dist/skills/agnostic/frontend/redesign-existing-projects/SKILL.md +178 -0
- package/dist/skills/agnostic/planning/create-plan/REFERENCE.md +37 -0
- package/dist/skills/agnostic/planning/create-plan/SKILL.md +69 -0
- package/dist/skills/agnostic/planning/create-plan/references/backlog-sync.md +44 -0
- package/dist/skills/agnostic/planning/create-plan/references/grill-phase.md +86 -0
- package/dist/skills/agnostic/planning/create-plan/references/plan-schema.md +66 -0
- package/dist/skills/agnostic/planning/create-plan/references/planner-phase.md +39 -0
- package/dist/skills/agnostic/planning/create-plan/references/stop-conditions.md +18 -0
- package/dist/skills/agnostic/planning/create-plan/references/tdd-phase.md +26 -0
- package/dist/skills/agnostic/planning/create-spec/SKILL.md +57 -0
- package/dist/skills/agnostic/planning/create-spec/assets/SPEC-TEMPLATE.md +91 -0
- package/dist/skills/agnostic/planning/create-spec/references/discovery.md +44 -0
- package/dist/skills/agnostic/planning/create-spec/references/folder-naming.md +27 -0
- package/dist/skills/agnostic/planning/create-spec/references/handoff.md +47 -0
- package/dist/skills/agnostic/planning/create-spec/references/questioning.md +41 -0
- package/dist/skills/agnostic/planning/create-spec/references/spec-quality-bar.md +58 -0
- package/dist/skills/agnostic/planning/create-spec/references/wiki-bookkeeping.md +26 -0
- package/dist/skills/agnostic/planning/grill-me/SKILL.md +28 -0
- package/dist/skills/agnostic/planning/implement-spec/SKILL.md +72 -0
- package/dist/skills/agnostic/planning/implement-spec/assets/IMPLEMENTATION-NOTES-TEMPLATE.md +47 -0
- package/dist/skills/agnostic/planning/implement-spec/references/lifecycle.md +149 -0
- package/dist/skills/agnostic/planning/implement-spec/references/parallel-orchestration.md +102 -0
- package/dist/skills/agnostic/planning/implement-spec/references/parallel-worker-brief.md +65 -0
- package/dist/skills/agnostic/planning/implement-spec/references/parallel.md +56 -0
- package/dist/skills/agnostic/planning/implement-spec/references/sequential.md +28 -0
- package/dist/skills/agnostic/planning/swarm-planner/SKILL.md +179 -0
- package/dist/skills/agnostic/quality/simplify/SKILL.md +14 -0
- package/dist/skills/agnostic/quality/tdd/SKILL.md +107 -0
- package/dist/skills/agnostic/quality/tdd/deep-modules.md +33 -0
- package/dist/skills/agnostic/quality/tdd/interface-design.md +31 -0
- package/dist/skills/agnostic/quality/tdd/mocking.md +59 -0
- package/dist/skills/agnostic/quality/tdd/refactoring.md +10 -0
- package/dist/skills/agnostic/quality/tdd/tests.md +61 -0
- package/dist/skills/agnostic/requirements/requirements-grill/SKILL.md +42 -0
- package/dist/skills/agnostic/requirements/requirements-grill/references/artifact-output.md +73 -0
- package/dist/skills/agnostic/requirements/requirements-grill/references/grilling-flow.md +57 -0
- package/dist/skills/agnostic/requirements/requirements-grill/references/wiki-output.md +94 -0
- package/dist/skills/agnostic/requirements/write-backlog/EXAMPLES.md +67 -0
- package/dist/skills/agnostic/requirements/write-backlog/REFERENCE.md +253 -0
- package/dist/skills/agnostic/requirements/write-backlog/SKILL.md +68 -0
- package/dist/skills/agnostic/requirements/write-backlog/assets/concepts/backlog-model.md +69 -0
- package/dist/skills/agnostic/requirements/write-backlog/assets/concepts/story-shape.md +66 -0
- package/dist/skills/agnostic/requirements/write-backlog/assets/providers/azure-devops-create-payload.md +63 -0
- package/dist/skills/agnostic/requirements/write-backlog/assets/providers/github-issues-create-payload.md +48 -0
- package/dist/skills/agnostic/requirements/write-backlog/assets/providers/linear-create-payload.md +76 -0
- package/dist/skills/agnostic/research/improve-codebase-architecture/REFERENCE.md +78 -0
- package/dist/skills/agnostic/research/improve-codebase-architecture/SKILL.md +76 -0
- package/dist/skills/agnostic/research/parallel-research/SKILL.md +68 -0
- package/dist/skills/agnostic/research/parallel-research/agents/openai.yaml +4 -0
- package/dist/skills/agnostic/subagents/swarm-planner/SKILL.md +179 -0
- package/dist/skills/agnostic/write-a-skill/SKILL.md +117 -0
- package/dist/skills/frameworks/better-auth/better-auth-best-practices/SKILL.md +166 -0
- package/dist/skills/frameworks/better-auth/better-auth-security-best-practices/SKILL.MD +432 -0
- package/dist/skills/frameworks/effect/effect-authoring/SKILL.md +116 -0
- package/dist/skills/frameworks/effect/effect-authoring/references/branded-types.md +98 -0
- package/dist/skills/frameworks/effect/effect-authoring/references/effect-atom-patterns.md +257 -0
- package/dist/skills/frameworks/effect/effect-authoring/references/effect-primitives.md +144 -0
- package/dist/skills/frameworks/effect/effect-authoring/references/error-patterns.md +156 -0
- package/dist/skills/frameworks/effect/effect-authoring/references/otel-patterns.md +113 -0
- package/dist/skills/frameworks/effect/effect-authoring/references/test-patterns.md +146 -0
- package/dist/skills/frameworks/effect/effect-backend-structure/SKILL.md +96 -0
- package/dist/skills/frameworks/effect/effect-backend-structure/agents/openai.yaml +4 -0
- package/dist/skills/frameworks/effect/effect-backend-structure/references/layout.md +68 -0
- package/dist/skills/frameworks/effect/effect-best-practices/SKILL.md +517 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/anti-patterns.md +392 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/effect-atom-patterns.md +653 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/error-patterns.md +464 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/language-server.md +287 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/layer-patterns.md +495 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/observability-patterns.md +342 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/rpc-cluster-patterns.md +418 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/schema-patterns.md +353 -0
- package/dist/skills/frameworks/effect/effect-best-practices/references/service-patterns.md +299 -0
- package/dist/skills/frameworks/effect/effect-recoverable-actions/SKILL.md +65 -0
- package/dist/skills/frameworks/effect/effect-recoverable-actions/agents/openai.yaml +4 -0
- package/dist/skills/frameworks/effect/effect-recoverable-actions/references/flow-examples.md +154 -0
- package/dist/skills/frameworks/effect/effect-recoverable-actions/references/source-backed-primitives.md +104 -0
- package/dist/skills/frameworks/effect/effect-recoverable-actions/references/strategy-matrix.md +34 -0
- package/dist/skills/frameworks/effect/effect-recoverable-actions/references/test-matrix.md +36 -0
- package/dist/skills/frameworks/elysia/elysiajs/SKILL.md +475 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/basic.ts +9 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/body-parser.ts +33 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/complex.ts +112 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/cookie.ts +45 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/error.ts +38 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/file.ts +10 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/guard.ts +34 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/map-response.ts +15 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/redirect.ts +6 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/rename.ts +32 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/schema.ts +61 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/state.ts +6 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/upload-file.ts +20 -0
- package/dist/skills/frameworks/elysia/elysiajs/examples/websocket.ts +25 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/ai-sdk.md +92 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/astro.md +59 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/better-auth.md +117 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/cloudflare-worker.md +95 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/deno.md +34 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/drizzle.md +258 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/expo.md +95 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/nextjs.md +103 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/nodejs.md +64 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/nuxt.md +67 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/prisma.md +93 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/react-email.md +134 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/sveltekit.md +53 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/tanstack-start.md +87 -0
- package/dist/skills/frameworks/elysia/elysiajs/integrations/vercel.md +55 -0
- package/dist/skills/frameworks/elysia/elysiajs/patterns/mvc.md +380 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/bearer.md +30 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/cors.md +141 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/cron.md +265 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/graphql-apollo.md +90 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/graphql-yoga.md +87 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/html.md +188 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/jwt.md +197 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/openapi.md +246 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/opentelemetry.md +167 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/server-timing.md +71 -0
- package/dist/skills/frameworks/elysia/elysiajs/plugins/static.md +84 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/bun-fullstack-dev-server.md +129 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/cookie.md +187 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/deployment.md +413 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/eden.md +158 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/lifecycle.md +198 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/macro.md +83 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/plugin.md +207 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/route.md +331 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/testing.md +385 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/validation.md +491 -0
- package/dist/skills/frameworks/elysia/elysiajs/references/websocket.md +250 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/.github/workflows/branch-protection.yml +24 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/.github/workflows/deploy.yml +61 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/AGENTS.md +5958 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/SKILL.md +130 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/api-use-dto-serialization.md +182 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/api-use-interceptors.md +202 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/api-use-pipes.md +205 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/api-versioning.md +191 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-avoid-circular-deps.md +80 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-feature-modules.md +82 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-module-sharing.md +141 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-single-responsibility.md +106 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-use-events.md +108 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/arch-use-repository-pattern.md +97 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/db-avoid-n-plus-one.md +139 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/db-use-migrations.md +129 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/db-use-transactions.md +140 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/devops-graceful-shutdown.md +222 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/devops-use-config-module.md +167 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/devops-use-logging.md +232 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-avoid-service-locator.md +104 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-interface-segregation.md +165 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-liskov-substitution.md +221 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-prefer-constructor-injection.md +86 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-scope-awareness.md +94 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/di-use-interfaces-tokens.md +101 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/error-handle-async-errors.md +125 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/error-throw-http-exceptions.md +114 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/error-use-exception-filters.md +140 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/micro-use-health-checks.md +226 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/micro-use-patterns.md +167 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/micro-use-queues.md +252 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/perf-async-hooks.md +109 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/perf-lazy-loading.md +121 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/perf-optimize-database.md +131 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/perf-use-caching.md +128 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-auth-jwt.md +146 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-rate-limiting.md +125 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-sanitize-output.md +139 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-use-guards.md +135 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/security-validate-all-input.md +150 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/test-e2e-supertest.md +178 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/test-mock-external-services.md +179 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/rules/test-use-testing-module.md +153 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/scripts/build-agents.ts +299 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/scripts/build.sh +16 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/scripts/package-lock.json +237 -0
- package/dist/skills/frameworks/nestjs/nestjs-best-practices/scripts/package.json +15 -0
- package/dist/skills/frameworks/nestjs/nestjs-expert/SKILL.md +208 -0
- package/dist/skills/frameworks/nestjs/nestjs-expert/references/authentication.md +166 -0
- package/dist/skills/frameworks/nestjs/nestjs-expert/references/controllers-routing.md +111 -0
- package/dist/skills/frameworks/nestjs/nestjs-expert/references/dtos-validation.md +153 -0
- package/dist/skills/frameworks/nestjs/nestjs-expert/references/migration-from-express.md +1237 -0
- package/dist/skills/frameworks/nestjs/nestjs-expert/references/services-di.md +140 -0
- package/dist/skills/frameworks/nestjs/nestjs-expert/references/testing-patterns.md +186 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/SKILL.md +153 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/async-patterns.md +87 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/bundling.md +180 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/data-patterns.md +297 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/debug-tricks.md +105 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/directives.md +73 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/error-handling.md +227 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/file-conventions.md +140 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/font.md +245 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/functions.md +108 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/hydration-error.md +91 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/image.md +173 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/metadata.md +301 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/parallel-routes.md +287 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/route-handlers.md +146 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/rsc-boundaries.md +159 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/runtime-selection.md +39 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/scripts.md +141 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/self-hosting.md +371 -0
- package/dist/skills/frameworks/nextjs/next-best-practices/suspense-boundaries.md +67 -0
- package/dist/skills/frameworks/nextjs/next-cache-components/SKILL.md +360 -0
- package/dist/skills/frameworks/react/async-react-patterns/SKILL.md +78 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/AGENTS.md +946 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/SKILL.md +89 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/dist/skills/frameworks/react/vercel-composition-patterns/rules/state-lift-state.md +125 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/AGENTS.md +3750 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/SKILL.md +148 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/advanced-effect-event-deps.md +56 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-defer-await.md +82 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/dist/skills/frameworks/react/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/.claude-plugin/plugin.json +12 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/SKILL.md +1058 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/assets/example-template.txt +14 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/references/best-practices.md +304 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/references/common-patterns.md +271 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/references/example-reference.md +26 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/references/testing.md +282 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/references/top-errors.md +332 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/references/typescript-patterns.md +291 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/references/v4-to-v5-migration.md +231 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/rules/tanstack-query.md +126 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/scripts/example-script.sh +15 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/custom-hooks-pattern.tsx +281 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/devtools-setup.tsx +248 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/error-boundary.tsx +243 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/package.json +31 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/provider-setup.tsx +50 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/query-client-config.ts +72 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/use-infinite-query.tsx +214 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/use-mutation-basic.tsx +201 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/use-mutation-optimistic.tsx +234 -0
- package/dist/skills/frameworks/tanstack-query/tanstack-query/templates/use-query-basic.tsx +119 -0
- package/dist/skills/frameworks/trpc/tanstack-query/.claude-plugin/plugin.json +12 -0
- package/dist/skills/frameworks/trpc/tanstack-query/SKILL.md +1058 -0
- package/dist/skills/frameworks/trpc/tanstack-query/assets/example-template.txt +14 -0
- package/dist/skills/frameworks/trpc/tanstack-query/references/best-practices.md +304 -0
- package/dist/skills/frameworks/trpc/tanstack-query/references/common-patterns.md +271 -0
- package/dist/skills/frameworks/trpc/tanstack-query/references/example-reference.md +26 -0
- package/dist/skills/frameworks/trpc/tanstack-query/references/testing.md +282 -0
- package/dist/skills/frameworks/trpc/tanstack-query/references/top-errors.md +332 -0
- package/dist/skills/frameworks/trpc/tanstack-query/references/typescript-patterns.md +291 -0
- package/dist/skills/frameworks/trpc/tanstack-query/references/v4-to-v5-migration.md +231 -0
- package/dist/skills/frameworks/trpc/tanstack-query/rules/tanstack-query.md +126 -0
- package/dist/skills/frameworks/trpc/tanstack-query/scripts/example-script.sh +15 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/custom-hooks-pattern.tsx +281 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/devtools-setup.tsx +248 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/error-boundary.tsx +243 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/package.json +31 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/provider-setup.tsx +50 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/query-client-config.ts +72 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/use-infinite-query.tsx +214 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/use-mutation-basic.tsx +201 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/use-mutation-optimistic.tsx +234 -0
- package/dist/skills/frameworks/trpc/tanstack-query/templates/use-query-basic.tsx +119 -0
- package/dist/skills/frameworks/turborepo/turborepo/SKILL.md +914 -0
- package/dist/skills/frameworks/turborepo/turborepo/command/turborepo.md +70 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/best-practices/RULE.md +241 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/best-practices/dependencies.md +246 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/best-practices/packages.md +335 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/best-practices/structure.md +270 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/boundaries/RULE.md +126 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/caching/RULE.md +107 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/caching/gotchas.md +169 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/caching/remote-cache.md +127 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/ci/RULE.md +79 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/ci/github-actions.md +162 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/ci/patterns.md +145 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/ci/vercel.md +103 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/cli/RULE.md +100 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/cli/commands.md +297 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/configuration/RULE.md +211 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/configuration/global-options.md +187 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/configuration/gotchas.md +348 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/configuration/tasks.md +285 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/environment/RULE.md +96 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/environment/gotchas.md +141 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/environment/modes.md +101 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/filtering/RULE.md +148 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/filtering/patterns.md +152 -0
- package/dist/skills/frameworks/turborepo/turborepo/references/watch/RULE.md +99 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/README.md +20 -0
- package/docs/reference/dp-requirements.md +210 -0
- package/docs/runbooks/dp-cli-scaffolding.md +187 -0
- package/package.json +24 -50
- package/.eslintignore +0 -4
- package/.eslintrc +0 -127
- package/.prettierignore +0 -4
- package/.prettierrc +0 -7
- package/bin/abstractions/builder.d.ts +0 -4
- package/bin/abstractions/builder.js +0 -7
- package/bin/builders/dotnet/base.d.ts +0 -18
- package/bin/builders/dotnet/base.js +0 -47
- package/bin/builders/dotnet/entity-configuration/index.d.ts +0 -8
- package/bin/builders/dotnet/entity-configuration/index.js +0 -29
- package/bin/builders/dotnet/entity-converter/index.d.ts +0 -8
- package/bin/builders/dotnet/entity-converter/index.js +0 -29
- package/bin/builders/dotnet/entity-model-create/index.d.ts +0 -8
- package/bin/builders/dotnet/entity-model-create/index.js +0 -29
- package/bin/builders/dotnet/entity-model-dto/index.d.ts +0 -8
- package/bin/builders/dotnet/entity-model-dto/index.js +0 -29
- package/bin/builders/dotnet/entity-model-list-item-dto/index.d.ts +0 -8
- package/bin/builders/dotnet/entity-model-list-item-dto/index.js +0 -29
- package/bin/builders/dotnet/entity-model-update/index.d.ts +0 -8
- package/bin/builders/dotnet/entity-model-update/index.js +0 -29
- package/bin/builders/dotnet/entity-search-parameters/index.d.ts +0 -8
- package/bin/builders/dotnet/entity-search-parameters/index.js +0 -29
- package/bin/builders/dotnet/entity-search-query-builder/index.d.ts +0 -8
- package/bin/builders/dotnet/entity-search-query-builder/index.js +0 -29
- package/bin/builders/dotnet/firestore-connector/index.d.ts +0 -8
- package/bin/builders/dotnet/firestore-connector/index.js +0 -29
- package/bin/builders/dotnet/firestore-mapper/index.d.ts +0 -8
- package/bin/builders/dotnet/firestore-mapper/index.js +0 -29
- package/bin/builders/dotnet/types.d.ts +0 -10
- package/bin/builders/dotnet/types.js +0 -3
- package/bin/commands/entity-add/__test__/dotnet/common.d.ts +0 -2
- package/bin/commands/entity-add/__test__/dotnet/common.js +0 -11
- package/bin/commands/entity-add/__test__/dotnet/render.configuration.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.configuration.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.converter.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.converter.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.firestore-connector.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.firestore-connector.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.firestore-mapper.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.firestore-mapper.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.model-create.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.model-create.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.model-dto.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.model-dto.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.model-list-item-dto.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.model-list-item-dto.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.model-update.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.model-update.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.search-parameters.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.search-parameters.spec.js +0 -22
- package/bin/commands/entity-add/__test__/dotnet/render.search-query.spec.d.ts +0 -1
- package/bin/commands/entity-add/__test__/dotnet/render.search-query.spec.js +0 -22
- package/bin/commands/entity-add/index.d.ts +0 -26
- package/bin/commands/entity-add/index.js +0 -44
- package/bin/logging/index.d.ts +0 -8
- package/bin/logging/index.js +0 -28
- package/bin/providers/rendering/base.d.ts +0 -3
- package/bin/providers/rendering/base.js +0 -7
- package/bin/providers/rendering/factory.d.ts +0 -5
- package/bin/providers/rendering/factory.js +0 -16
- package/bin/providers/rendering/handlebars.d.ts +0 -4
- package/bin/providers/rendering/handlebars.js +0 -16
- package/bin/renderer/index.d.ts +0 -6
- package/bin/renderer/index.js +0 -27
- package/bin/run.d.ts +0 -2
- package/bin/run.js +0 -70
- package/bin/services/folders.d.ts +0 -1
- package/bin/services/folders.js +0 -31
- package/bin/types/commands.d.ts +0 -5
- package/bin/types/commands.js +0 -3
- package/bin/utils/collections.d.ts +0 -1
- package/bin/utils/collections.js +0 -6
- package/bin/utils/files.d.ts +0 -3
- package/bin/utils/files.js +0 -19
- package/bin/utils/strings.d.ts +0 -4
- package/bin/utils/strings.js +0 -22
- package/bin/utils/text.d.ts +0 -1
- package/bin/utils/text.js +0 -8
- package/em-cli +0 -0
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.configuration.spec.ts.snap +0 -49
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.converter.spec.ts.snap +0 -53
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.firestore-connector.spec.ts.snap +0 -20
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.firestore-mapper.spec.ts.snap +0 -29
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.model-create.spec.ts.snap +0 -10
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.model-dto.spec.ts.snap +0 -9
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.model-list-item-dto.spec.ts.snap +0 -11
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.model-update.spec.ts.snap +0 -11
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.search-parameters.spec.ts.snap +0 -29
- package/src/commands/entity-add/__test__/dotnet/__snapshots__/render.search-query.spec.ts.snap +0 -42
- package/templates/dotnet/NewEntity/Configuration/<PluralizedEntity>Configuration.cs.template +0 -48
- package/templates/dotnet/NewEntity/Connectors/<PluralizedEntity>FirestoreConnector.cs.template +0 -15
- package/templates/dotnet/NewEntity/Converters/<PluralizedEntity>Converter.cs.template +0 -48
- package/templates/dotnet/NewEntity/Mappers/<PluralizedEntity>FirestoreMapper.cs.template +0 -25
- package/templates/dotnet/NewEntity/Models/<Entity>CreateInput.cs.template +0 -6
- package/templates/dotnet/NewEntity/Models/<Entity>Dto.cs.template +0 -5
- package/templates/dotnet/NewEntity/Models/<Entity>ListItemDto.cs.template +0 -6
- package/templates/dotnet/NewEntity/Models/<Entity>UpdateInput.cs.template +0 -6
- package/templates/dotnet/NewEntity/Search/<PluralizedEntity>QueryBuilder.cs.template +0 -38
- package/templates/dotnet/NewEntity/Search/<PluralizedEntity>SearchParameters.cs.template +0 -24
- package/tsconfig.json +0 -25
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: better-auth-security-best-practices
|
|
3
|
+
description: Configure rate limiting, manage auth secrets, set up CSRF protection, define trusted origins, secure sessions and cookies, encrypt OAuth tokens, track IP addresses, and implement audit logging for Better Auth. Use when users need to secure their auth setup, prevent brute force attacks, or harden a Better Auth deployment.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Secret Management
|
|
7
|
+
|
|
8
|
+
### Configuring the Secret
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { betterAuth } from "better-auth";
|
|
12
|
+
|
|
13
|
+
export const auth = betterAuth({
|
|
14
|
+
secret: process.env.BETTER_AUTH_SECRET, // or via `BETTER_AUTH_SECRET` env
|
|
15
|
+
});
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Better Auth looks for secrets in this order:
|
|
19
|
+
1. `options.secret` in your config
|
|
20
|
+
2. `BETTER_AUTH_SECRET` environment variable
|
|
21
|
+
3. `AUTH_SECRET` environment variable
|
|
22
|
+
|
|
23
|
+
### Secret Requirements
|
|
24
|
+
|
|
25
|
+
- Rejects default/placeholder secrets in production
|
|
26
|
+
- Warns if shorter than 32 characters or entropy below 120 bits
|
|
27
|
+
- Generate: `openssl rand -base64 32`
|
|
28
|
+
- Never commit secrets to version control
|
|
29
|
+
|
|
30
|
+
## Rate Limiting
|
|
31
|
+
|
|
32
|
+
Enabled in production by default. Applies to all endpoints. Plugins can override per-endpoint.
|
|
33
|
+
|
|
34
|
+
### Default Configuration
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { betterAuth } from "better-auth";
|
|
38
|
+
|
|
39
|
+
export const auth = betterAuth({
|
|
40
|
+
rateLimit: {
|
|
41
|
+
enabled: true, // Default: true in production
|
|
42
|
+
window: 10, // Time window in seconds (default: 10)
|
|
43
|
+
max: 100, // Max requests per window (default: 100)
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Storage Options
|
|
49
|
+
|
|
50
|
+
Options: `"memory"` (resets on restart, avoid on serverless), `"database"` (persistent), `"secondary-storage"` (Redis, default when available).
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
rateLimit: {
|
|
54
|
+
storage: "database",
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Custom Storage
|
|
59
|
+
|
|
60
|
+
Implement your own rate limit storage:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
rateLimit: {
|
|
64
|
+
customStorage: {
|
|
65
|
+
get: async (key) => {
|
|
66
|
+
// Return { count: number, expiresAt: number } or null
|
|
67
|
+
},
|
|
68
|
+
set: async (key, data) => {
|
|
69
|
+
// Store the rate limit data
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Per-Endpoint Rules
|
|
76
|
+
|
|
77
|
+
Sensitive endpoints default to 3 requests per 10 seconds (`/sign-in`, `/sign-up`, `/change-password`, `/change-email`). Override:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
rateLimit: {
|
|
81
|
+
customRules: {
|
|
82
|
+
"/api/auth/sign-in/email": {
|
|
83
|
+
window: 60, // 1 minute window
|
|
84
|
+
max: 5, // 5 attempts
|
|
85
|
+
},
|
|
86
|
+
"/api/auth/some-safe-endpoint": false, // Disable rate limiting
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## CSRF Protection
|
|
92
|
+
|
|
93
|
+
Multi-layer protection: origin header validation, Fetch Metadata checks, and first-login protection.
|
|
94
|
+
|
|
95
|
+
### Configuration
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { betterAuth } from "better-auth";
|
|
99
|
+
|
|
100
|
+
export const auth = betterAuth({
|
|
101
|
+
advanced: {
|
|
102
|
+
disableCSRFCheck: false, // Default: false (keep enabled)
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Only disable for testing or with an alternative CSRF mechanism.
|
|
108
|
+
|
|
109
|
+
## Trusted Origins
|
|
110
|
+
|
|
111
|
+
### Configuring Trusted Origins
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { betterAuth } from "better-auth";
|
|
115
|
+
|
|
116
|
+
export const auth = betterAuth({
|
|
117
|
+
baseURL: "https://api.example.com",
|
|
118
|
+
trustedOrigins: [
|
|
119
|
+
"https://app.example.com",
|
|
120
|
+
"https://admin.example.com",
|
|
121
|
+
],
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The `baseURL` origin is automatically trusted. Also configurable via env: `BETTER_AUTH_TRUSTED_ORIGINS=https://app.example.com,https://admin.example.com`
|
|
126
|
+
|
|
127
|
+
### Wildcard Patterns
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
trustedOrigins: [
|
|
131
|
+
"*.example.com", // Matches any subdomain
|
|
132
|
+
"https://*.example.com", // Protocol-specific wildcard
|
|
133
|
+
"exp://192.168.*.*:*/*", // Custom schemes (e.g., Expo)
|
|
134
|
+
]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Dynamic Trusted Origins
|
|
138
|
+
|
|
139
|
+
Compute trusted origins based on the request:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
trustedOrigins: async (request) => {
|
|
143
|
+
// Validate against database, header, etc.
|
|
144
|
+
const tenant = getTenantFromRequest(request);
|
|
145
|
+
return [`https://${tenant}.myapp.com`];
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Validates `callbackURL`, `redirectTo`, `errorCallbackURL`, `newUserCallbackURL`, and `origin` against trusted origins. Invalid URLs receive 403.
|
|
150
|
+
|
|
151
|
+
## Session Security
|
|
152
|
+
|
|
153
|
+
### Session Expiration
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { betterAuth } from "better-auth";
|
|
157
|
+
|
|
158
|
+
export const auth = betterAuth({
|
|
159
|
+
session: {
|
|
160
|
+
expiresIn: 60 * 60 * 24 * 7, // 7 days (default)
|
|
161
|
+
updateAge: 60 * 60 * 24, // Refresh session every 24 hours (default)
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Session Caching Strategies
|
|
167
|
+
|
|
168
|
+
Cache session data in cookies to reduce database queries:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
session: {
|
|
172
|
+
cookieCache: {
|
|
173
|
+
enabled: true,
|
|
174
|
+
maxAge: 60 * 5, // 5 minutes
|
|
175
|
+
strategy: "compact", // Options: "compact", "jwt", "jwe"
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Strategies: `"compact"` (Base64url + HMAC, smallest), `"jwt"` (HS256, standard), `"jwe"` (encrypted, use when session has sensitive data).
|
|
181
|
+
|
|
182
|
+
## Cookie Security
|
|
183
|
+
|
|
184
|
+
Defaults: `secure: true` (HTTPS/production), `sameSite: "lax"`, `httpOnly: true`, `path: "/"`, prefix `__Secure-`.
|
|
185
|
+
|
|
186
|
+
### Custom Cookie Configuration
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
import { betterAuth } from "better-auth";
|
|
190
|
+
|
|
191
|
+
export const auth = betterAuth({
|
|
192
|
+
advanced: {
|
|
193
|
+
useSecureCookies: true, // Force secure cookies
|
|
194
|
+
cookiePrefix: "myapp", // Custom prefix (default: "better-auth")
|
|
195
|
+
defaultCookieAttributes: {
|
|
196
|
+
sameSite: "strict", // Stricter CSRF protection
|
|
197
|
+
path: "/auth", // Limit cookie scope
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Cross-Subdomain Cookies
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
advanced: {
|
|
207
|
+
crossSubDomainCookies: {
|
|
208
|
+
enabled: true,
|
|
209
|
+
domain: ".example.com", // Note the leading dot
|
|
210
|
+
additionalCookies: ["session_token", "session_data"],
|
|
211
|
+
},
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Only enable if you need authentication sharing and trust all subdomains.
|
|
216
|
+
|
|
217
|
+
## OAuth / Social Provider Security
|
|
218
|
+
|
|
219
|
+
PKCE is automatic for all OAuth flows. State tokens are 32-char random strings expiring after 10 minutes.
|
|
220
|
+
|
|
221
|
+
### State Parameter Storage
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
import { betterAuth } from "better-auth";
|
|
225
|
+
|
|
226
|
+
export const auth = betterAuth({
|
|
227
|
+
account: {
|
|
228
|
+
storeStateStrategy: "cookie", // Options: "cookie" (default), "database"
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Encrypting OAuth Tokens
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
account: {
|
|
237
|
+
encryptOAuthTokens: true, // Uses AES-256-GCM
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Enable if storing OAuth tokens for API access on behalf of users. Use `skipStateCookieCheck: true` only for mobile apps that cannot maintain cookies.
|
|
242
|
+
|
|
243
|
+
## IP-Based Security
|
|
244
|
+
|
|
245
|
+
### IP Address Configuration
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
import { betterAuth } from "better-auth";
|
|
249
|
+
|
|
250
|
+
export const auth = betterAuth({
|
|
251
|
+
advanced: {
|
|
252
|
+
ipAddress: {
|
|
253
|
+
ipAddressHeaders: ["x-forwarded-for", "x-real-ip"], // Headers to check
|
|
254
|
+
disableIpTracking: false, // Keep enabled for rate limiting
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Set `ipv6Subnet` (128, 64, 48, 32; default 64) to group IPv6 addresses. Enable `trustedProxyHeaders: true` only if behind a trusted reverse proxy.
|
|
261
|
+
|
|
262
|
+
## Database Hooks for Security Auditing
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
import { betterAuth } from "better-auth";
|
|
266
|
+
|
|
267
|
+
export const auth = betterAuth({
|
|
268
|
+
databaseHooks: {
|
|
269
|
+
session: {
|
|
270
|
+
create: {
|
|
271
|
+
after: async ({ data, ctx }) => {
|
|
272
|
+
await auditLog("session.created", {
|
|
273
|
+
userId: data.userId,
|
|
274
|
+
ip: ctx?.request?.headers.get("x-forwarded-for"),
|
|
275
|
+
userAgent: ctx?.request?.headers.get("user-agent"),
|
|
276
|
+
});
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
delete: {
|
|
280
|
+
before: async ({ data }) => {
|
|
281
|
+
await auditLog("session.revoked", { sessionId: data.id });
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
user: {
|
|
286
|
+
update: {
|
|
287
|
+
after: async ({ data, oldData }) => {
|
|
288
|
+
if (oldData?.email !== data.email) {
|
|
289
|
+
await auditLog("user.email_changed", {
|
|
290
|
+
userId: data.id,
|
|
291
|
+
oldEmail: oldData?.email,
|
|
292
|
+
newEmail: data.email,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
account: {
|
|
299
|
+
create: {
|
|
300
|
+
after: async ({ data }) => {
|
|
301
|
+
await auditLog("account.linked", {
|
|
302
|
+
userId: data.userId,
|
|
303
|
+
provider: data.providerId,
|
|
304
|
+
});
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Return `false` from a `before` hook to prevent an operation.
|
|
313
|
+
|
|
314
|
+
## Background Tasks
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
import { betterAuth } from "better-auth";
|
|
318
|
+
|
|
319
|
+
export const auth = betterAuth({
|
|
320
|
+
advanced: {
|
|
321
|
+
backgroundTasks: {
|
|
322
|
+
handler: (promise) => {
|
|
323
|
+
// Platform-specific handler
|
|
324
|
+
// Vercel: waitUntil(promise)
|
|
325
|
+
// Cloudflare: ctx.waitUntil(promise)
|
|
326
|
+
waitUntil(promise);
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Ensures operations like sending emails don't affect response timing.
|
|
334
|
+
|
|
335
|
+
## Account Enumeration Prevention
|
|
336
|
+
|
|
337
|
+
Built-in: consistent response messages, dummy operations on invalid requests, background email sending. Return generic error messages ("Invalid credentials") rather than specific ones ("User not found").
|
|
338
|
+
|
|
339
|
+
## Complete Security Configuration Example
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
import { betterAuth } from "better-auth";
|
|
343
|
+
|
|
344
|
+
export const auth = betterAuth({
|
|
345
|
+
secret: process.env.BETTER_AUTH_SECRET,
|
|
346
|
+
baseURL: "https://api.example.com",
|
|
347
|
+
trustedOrigins: [
|
|
348
|
+
"https://app.example.com",
|
|
349
|
+
"https://*.preview.example.com",
|
|
350
|
+
],
|
|
351
|
+
|
|
352
|
+
// Rate limiting
|
|
353
|
+
rateLimit: {
|
|
354
|
+
enabled: true,
|
|
355
|
+
storage: "secondary-storage",
|
|
356
|
+
customRules: {
|
|
357
|
+
"/api/auth/sign-in/email": { window: 60, max: 5 },
|
|
358
|
+
"/api/auth/sign-up/email": { window: 60, max: 3 },
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
// Session security
|
|
363
|
+
session: {
|
|
364
|
+
expiresIn: 60 * 60 * 24 * 7, // 7 days
|
|
365
|
+
updateAge: 60 * 60 * 24, // 24 hours
|
|
366
|
+
freshAge: 60 * 60, // 1 hour for sensitive actions
|
|
367
|
+
cookieCache: {
|
|
368
|
+
enabled: true,
|
|
369
|
+
maxAge: 300,
|
|
370
|
+
strategy: "jwe", // Encrypted session data
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
|
|
374
|
+
// OAuth security
|
|
375
|
+
account: {
|
|
376
|
+
encryptOAuthTokens: true,
|
|
377
|
+
storeStateStrategy: "cookie",
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
// Advanced settings
|
|
382
|
+
advanced: {
|
|
383
|
+
useSecureCookies: true,
|
|
384
|
+
cookiePrefix: "myapp",
|
|
385
|
+
defaultCookieAttributes: {
|
|
386
|
+
sameSite: "lax",
|
|
387
|
+
},
|
|
388
|
+
ipAddress: {
|
|
389
|
+
ipAddressHeaders: ["x-forwarded-for"],
|
|
390
|
+
ipv6Subnet: 64,
|
|
391
|
+
},
|
|
392
|
+
backgroundTasks: {
|
|
393
|
+
handler: (promise) => waitUntil(promise),
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
// Security auditing
|
|
398
|
+
databaseHooks: {
|
|
399
|
+
session: {
|
|
400
|
+
create: {
|
|
401
|
+
after: async ({ data, ctx }) => {
|
|
402
|
+
console.log(`New session for user ${data.userId}`);
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
user: {
|
|
407
|
+
update: {
|
|
408
|
+
after: async ({ data, oldData }) => {
|
|
409
|
+
if (oldData?.email !== data.email) {
|
|
410
|
+
console.log(`Email changed for user ${data.id}`);
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
## Security Checklist
|
|
420
|
+
|
|
421
|
+
Before deploying to production:
|
|
422
|
+
|
|
423
|
+
- [ ] **Secret**: Use a strong, unique secret (32+ characters, high entropy)
|
|
424
|
+
- [ ] **HTTPS**: Ensure `baseURL` uses HTTPS
|
|
425
|
+
- [ ] **Trusted Origins**: Configure all valid origins (frontend, mobile apps)
|
|
426
|
+
- [ ] **Rate Limiting**: Keep enabled with appropriate limits
|
|
427
|
+
- [ ] **CSRF Protection**: Keep enabled (`disableCSRFCheck: false`)
|
|
428
|
+
- [ ] **Secure Cookies**: Enabled automatically with HTTPS
|
|
429
|
+
- [ ] **OAuth Tokens**: Consider `encryptOAuthTokens: true` if storing tokens
|
|
430
|
+
- [ ] **Background Tasks**: Configure for serverless platforms
|
|
431
|
+
- [ ] **Audit Logging**: Implement via `databaseHooks` or `hooks`
|
|
432
|
+
- [ ] **IP Tracking**: Configure headers if behind a proxy
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: effect-authoring
|
|
3
|
+
description: >-
|
|
4
|
+
Use when asked to plan, write, build, fix, refactor, or review Effect-TS
|
|
5
|
+
code. Apply before editing so the first implementation follows repo
|
|
6
|
+
conventions for Effect primitives, branded IDs, observability, error design,
|
|
7
|
+
`@effect/vitest`, and Effect-Atom, especially in `packages/api`.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Effect-TS Authoring Guide
|
|
11
|
+
|
|
12
|
+
Use this skill before edits. Optimize for correct code on first pass, not a scorecard after the fact.
|
|
13
|
+
|
|
14
|
+
## Workflow
|
|
15
|
+
|
|
16
|
+
### Step 1: Classify the Task Before Writing
|
|
17
|
+
|
|
18
|
+
Sort the requested change into the smallest relevant set:
|
|
19
|
+
|
|
20
|
+
- **Backend Effect code**: Effect services, procedures, repositories, layers, schemas, domain actions
|
|
21
|
+
- **Test code**: `.test.ts` files, test layers, failure-path coverage
|
|
22
|
+
- **UI / Effect-Atom code**: `.tsx` files using Effect-Atom, RPC, HttpApi clients
|
|
23
|
+
|
|
24
|
+
Skip config/docs unless they change the implementation contract.
|
|
25
|
+
|
|
26
|
+
### Step 2: Load Only the References Needed for the Task
|
|
27
|
+
|
|
28
|
+
Read the minimum reference set before editing:
|
|
29
|
+
|
|
30
|
+
- **Backend Effect code**: `references/effect-primitives.md`, `references/branded-types.md`, `references/otel-patterns.md`, `references/error-patterns.md`
|
|
31
|
+
- **Test code**: `references/test-patterns.md`
|
|
32
|
+
- **UI / Effect-Atom code**: `references/effect-atom-patterns.md`
|
|
33
|
+
|
|
34
|
+
If uncertain about Effect library behavior, run `opensrc path effect` or `opensrc path Effect-TS/effect` to resolve the local checkout path, then inspect there instead of guessing.
|
|
35
|
+
|
|
36
|
+
### Step 3: Build a Pre-Write Checklist
|
|
37
|
+
|
|
38
|
+
Turn the loaded references into a short implementation checklist for the exact files/functions being changed.
|
|
39
|
+
|
|
40
|
+
For backend Effect work, check for these constraints up front:
|
|
41
|
+
|
|
42
|
+
- Make dependencies visible as Effect requirements or `Effect.Service` dependencies; do not hide them behind concrete imports
|
|
43
|
+
- Provide implementations with `Layer`s; avoid call-site `Effect.provide` except at runner/test boundaries
|
|
44
|
+
- Use Effect primitives over native patterns where the repo expects them: `Array`, `Match`, `Option`, `Schema`, `Effect.forEach`, `Layer`
|
|
45
|
+
- Avoid `try/catch`, `async/await`, `console.log`, ad-hoc validation, and plain `Error` classes in Effect code
|
|
46
|
+
- Carry branded IDs through boundaries; do not fall back to raw `string` / `number`
|
|
47
|
+
- Use named `Effect.fn("Service.method")` wrappers for named effectful functions
|
|
48
|
+
- Annotate spans with essential IDs and business context only
|
|
49
|
+
- Prefer `Schema.TaggedError` and `catchTag` with rich context over generic failures
|
|
50
|
+
|
|
51
|
+
For test work, check for these constraints up front:
|
|
52
|
+
|
|
53
|
+
- Use `@effect/vitest`, not plain `vitest`
|
|
54
|
+
- Prefer `it.layer(...)` and `it.scoped(...)`
|
|
55
|
+
- Replace Effect services with test layers, not `vi.mock`
|
|
56
|
+
- Test failures with `Effect.either` / tagged errors, not `try/catch`
|
|
57
|
+
|
|
58
|
+
For UI work, check for these constraints up front:
|
|
59
|
+
|
|
60
|
+
- Prefer Effect-Atom typesafe clients for first-party Effect backends
|
|
61
|
+
- Avoid `useEffect` + `fetch` state machines when an atom/query should own the data flow
|
|
62
|
+
|
|
63
|
+
### Step 4: Inspect Local Patterns Before Editing
|
|
64
|
+
|
|
65
|
+
Read adjacent modules before writing:
|
|
66
|
+
|
|
67
|
+
- existing tagged error names
|
|
68
|
+
- local branded type definitions
|
|
69
|
+
- layer composition style
|
|
70
|
+
- service/action boundaries
|
|
71
|
+
- trace naming conventions
|
|
72
|
+
- nearby test harness patterns
|
|
73
|
+
|
|
74
|
+
Prefer repo-local patterns over generic examples from the references.
|
|
75
|
+
|
|
76
|
+
### Step 5: Write the Code Against the Checklist
|
|
77
|
+
|
|
78
|
+
Implement directly against the pre-write checklist. Treat the references as authoring constraints, not post-hoc review criteria.
|
|
79
|
+
|
|
80
|
+
If a reference conflicts with established local conventions, follow the local convention and call out the mismatch briefly in the final response.
|
|
81
|
+
|
|
82
|
+
Do not start with a review-style `git diff` workflow when the task is code generation or refactoring. Start from the requested change and the target files.
|
|
83
|
+
|
|
84
|
+
### Step 6: Validate Immediately After Editing
|
|
85
|
+
|
|
86
|
+
Run the narrowest useful validation for the touched area:
|
|
87
|
+
|
|
88
|
+
- targeted tests
|
|
89
|
+
- relevant typecheck
|
|
90
|
+
- lint if the changed surface is lint-sensitive
|
|
91
|
+
- any repo-specific command that proves the new behavior
|
|
92
|
+
|
|
93
|
+
If validation fails, fix the code before moving on.
|
|
94
|
+
|
|
95
|
+
### Step 7: Switch to Review Mode Only When Needed
|
|
96
|
+
|
|
97
|
+
Use review-style findings only when:
|
|
98
|
+
|
|
99
|
+
- the user explicitly asks for a review, audit, or score
|
|
100
|
+
- the task is read-only
|
|
101
|
+
- a final spot-check is needed after implementation
|
|
102
|
+
|
|
103
|
+
In review mode, use the same references, but report findings instead of treating them as a pre-write checklist.
|
|
104
|
+
|
|
105
|
+
Do not default to spawning review subagents during authoring. That adds latency and pushes correctness to the end of the workflow.
|
|
106
|
+
|
|
107
|
+
## Reference Files
|
|
108
|
+
|
|
109
|
+
Load on demand:
|
|
110
|
+
|
|
111
|
+
- `references/effect-primitives.md` — Effect Array, Match, Option, Schema, `Effect.forEach`, Layer
|
|
112
|
+
- `references/branded-types.md` — branded IDs and boundary consistency
|
|
113
|
+
- `references/otel-patterns.md` — `Effect.fn`, span annotations, structured logging
|
|
114
|
+
- `references/error-patterns.md` — `Schema.TaggedError`, `catchTag`, error context
|
|
115
|
+
- `references/test-patterns.md` — `@effect/vitest`, `it.layer`, failure-path testing
|
|
116
|
+
- `references/effect-atom-patterns.md` — Effect-Atom queries, mutations, client patterns
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Branded Types Checklist
|
|
2
|
+
|
|
3
|
+
## Core Rule
|
|
4
|
+
|
|
5
|
+
All entity IDs MUST use branded types via `Schema.brand()`. Never use plain `string` or `number` for IDs. This prevents mixing up IDs of different entity types at compile time.
|
|
6
|
+
|
|
7
|
+
## How to Define Branded Types
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { Schema } from "effect"
|
|
11
|
+
|
|
12
|
+
// Integer IDs
|
|
13
|
+
export const UserId = Schema.Int.pipe(Schema.brand("@myorg/schema/UserId"))
|
|
14
|
+
export type UserId = Schema.Schema.Type<typeof UserId>
|
|
15
|
+
|
|
16
|
+
// String IDs
|
|
17
|
+
export const ApiKey = Schema.String.pipe(Schema.brand("@myorg/schema/ApiKey"))
|
|
18
|
+
export type ApiKey = Schema.Schema.Type<typeof ApiKey>
|
|
19
|
+
|
|
20
|
+
// FromString variants (for URL params that arrive as strings)
|
|
21
|
+
export const UserIdFromString = Schema.NumberFromString.pipe(
|
|
22
|
+
Schema.brand("@myorg/schema/UserId")
|
|
23
|
+
)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Define branded types for every entity ID in your domain (e.g., `UserId`, `OrganizationId`, `ProjectId`, `OrderId`, `ProductId`, etc.) and colocate them in a shared branded types module.
|
|
27
|
+
|
|
28
|
+
## Checklist
|
|
29
|
+
|
|
30
|
+
### 1. Function Parameters Use Branded Types Directly
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// GOOD
|
|
34
|
+
const findById = (userId: UserId, organizationId: OrganizationId) => ...
|
|
35
|
+
|
|
36
|
+
// BAD
|
|
37
|
+
const findById = (userId: number, organizationId: number) => ...
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. No `as` Casting for IDs
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// GOOD
|
|
44
|
+
import { Schema } from "effect"
|
|
45
|
+
const id = Schema.decodeSync(UserId)(rawValue)
|
|
46
|
+
// or use the branded constructor
|
|
47
|
+
const id = UserId.make(rawValue)
|
|
48
|
+
|
|
49
|
+
// BAD
|
|
50
|
+
const id = rawValue as UserId
|
|
51
|
+
const id = someNumber as unknown as UserId
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3. *FromString Variants for URL/Route Params
|
|
55
|
+
|
|
56
|
+
URL params arrive as strings. Use `*FromString` schemas to decode them.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// GOOD
|
|
60
|
+
const params = Schema.Struct({
|
|
61
|
+
userId: UserIdFromString,
|
|
62
|
+
projectId: ProjectIdFromString,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// BAD
|
|
66
|
+
const userId = parseInt(req.params.userId) as UserId
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 4. Database Schema Alignment
|
|
70
|
+
|
|
71
|
+
When a database column uses a branded type, all code accessing that column must use the same branded type throughout. Check that:
|
|
72
|
+
- Repository method params match column types
|
|
73
|
+
- Service method params propagate branded types (not plain numbers)
|
|
74
|
+
- API handler params decode to branded types before passing to services
|
|
75
|
+
|
|
76
|
+
### 5. No Plain string/number in Domain Types
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// GOOD
|
|
80
|
+
interface OrderConfig {
|
|
81
|
+
orderId: OrderId
|
|
82
|
+
userId: UserId
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// BAD
|
|
86
|
+
interface OrderConfig {
|
|
87
|
+
orderId: number
|
|
88
|
+
userId: number
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Where to Check
|
|
93
|
+
|
|
94
|
+
- Function signatures (params and return types)
|
|
95
|
+
- Interface/type definitions containing IDs
|
|
96
|
+
- Schema definitions for API input/output
|
|
97
|
+
- Database query `.where()` clauses
|
|
98
|
+
- Variable declarations storing IDs
|