@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,517 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: effect-best-practices
|
|
3
|
+
description: Enforces Effect-TS patterns for services, errors, layers, and atoms. Use when writing code with Effect.Service, Schema.TaggedError, Layer composition, or effect-atom React components.
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0.0"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Effect-TS Best Practices
|
|
9
|
+
|
|
10
|
+
This skill enforces opinionated, consistent patterns for Effect-TS codebases. These patterns optimize for type safety, testability, observability, and maintainability.
|
|
11
|
+
|
|
12
|
+
## Effect Language Server (Required)
|
|
13
|
+
|
|
14
|
+
**The Effect Language Server is essential for Effect development.** It catches errors at edit-time that TypeScript alone cannot detect, provides Effect-specific refactors, and improves developer productivity.
|
|
15
|
+
|
|
16
|
+
### Setup
|
|
17
|
+
|
|
18
|
+
1. Install:
|
|
19
|
+
```bash
|
|
20
|
+
npm install @effect/language-service --save-dev
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. Add to `tsconfig.json`:
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"compilerOptions": {
|
|
27
|
+
"plugins": [{ "name": "@effect/language-service" }]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
3. Configure your editor to use workspace TypeScript:
|
|
33
|
+
- **VSCode**: F1 → "TypeScript: Select TypeScript Version" → "Use Workspace Version"
|
|
34
|
+
- **JetBrains**: Settings → Languages & Frameworks → TypeScript → Use workspace version
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
- **Diagnostics**: Detects 30+ Effect-specific issues (floating Effects, missing requirements, incorrect yield patterns)
|
|
39
|
+
- **Quick Info**: Hover to see Effect type parameters (Success, Error, Requirements)
|
|
40
|
+
- **Completions**: Auto-complete `Self`, Duration strings, Schema brands
|
|
41
|
+
- **Refactors**: Convert async → Effect.gen, auto-compose Layers, transform to Schema
|
|
42
|
+
|
|
43
|
+
### Build-Time Diagnostics
|
|
44
|
+
|
|
45
|
+
For CI enforcement:
|
|
46
|
+
```bash
|
|
47
|
+
npx effect-language-service patch
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
See `references/language-server.md` for configuration options and CLI tools.
|
|
51
|
+
|
|
52
|
+
## Quick Reference: Critical Rules
|
|
53
|
+
|
|
54
|
+
| Category | DO | DON'T |
|
|
55
|
+
|----------|-----|-------|
|
|
56
|
+
| Services | `Effect.Service` with `accessors: true` | `Context.Tag` for business logic |
|
|
57
|
+
| Dependencies | `dependencies: [Dep.Default]` in service | Manual `Layer.provide` at usage sites |
|
|
58
|
+
| Test Doubles | test `Layer`s | `vi.mock` / path-based module mocks |
|
|
59
|
+
| Layers | `Layer.mergeAll` for flat composition | Deeply nested `Layer.provide` chains |
|
|
60
|
+
| Layer Chaining | `Layer.provideMerge` for incremental composition | Multiple `Layer.provide` (creates nested types) |
|
|
61
|
+
| Errors | `Schema.TaggedError` with `message` field | Plain classes or generic Error |
|
|
62
|
+
| Error Specificity | `UserNotFoundError`, `SessionExpiredError` | Generic `NotFoundError`, `BadRequestError` |
|
|
63
|
+
| Error Handling | `catchTag`/`catchTags` | `catchAll` or `mapError` |
|
|
64
|
+
| IDs | `Schema.UUID.pipe(Schema.brand("@App/EntityId"))` | Plain `string` for entity IDs |
|
|
65
|
+
| Functions | `Effect.fn("Service.method")` | Anonymous generators |
|
|
66
|
+
| Logging | `Effect.log` with structured data | `console.log` |
|
|
67
|
+
| Config | `Config.*` with validation | `process.env` directly |
|
|
68
|
+
| Options | `Option.match` with both cases | `Option.getOrThrow` |
|
|
69
|
+
| Nullability | `Option<T>` in domain types | `null`/`undefined` |
|
|
70
|
+
| Atoms | `Atom.make` outside components | Creating atoms inside render |
|
|
71
|
+
| Atom State | `Atom.keepAlive` for global state | Forgetting keepAlive for persistent state |
|
|
72
|
+
| Atom Updates | `useAtomSet` in React components | `Atom.update` imperatively from React |
|
|
73
|
+
| Atom Cleanup | `get.addFinalizer()` for side effects | Missing cleanup for event listeners |
|
|
74
|
+
| Atom Results | `Result.builder` with `onErrorTag` | Ignoring loading/error states |
|
|
75
|
+
|
|
76
|
+
## Service Definition Pattern
|
|
77
|
+
|
|
78
|
+
**Always use `Effect.Service`** for business logic services. This provides automatic accessors, built-in `Default` layer, and proper dependency declaration.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { Effect } from "effect"
|
|
82
|
+
|
|
83
|
+
export class UserService extends Effect.Service<UserService>()("UserService", {
|
|
84
|
+
accessors: true,
|
|
85
|
+
dependencies: [UserRepo.Default, CacheService.Default],
|
|
86
|
+
effect: Effect.gen(function* () {
|
|
87
|
+
const repo = yield* UserRepo
|
|
88
|
+
const cache = yield* CacheService
|
|
89
|
+
|
|
90
|
+
const findById = Effect.fn("UserService.findById")(function* (id: UserId) {
|
|
91
|
+
const cached = yield* cache.get(id)
|
|
92
|
+
if (Option.isSome(cached)) return cached.value
|
|
93
|
+
|
|
94
|
+
const user = yield* repo.findById(id)
|
|
95
|
+
yield* cache.set(id, user)
|
|
96
|
+
return user
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const create = Effect.fn("UserService.create")(function* (data: CreateUserInput) {
|
|
100
|
+
const user = yield* repo.create(data)
|
|
101
|
+
yield* Effect.log("User created", { userId: user.id })
|
|
102
|
+
return user
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
return { findById, create }
|
|
106
|
+
}),
|
|
107
|
+
}) {}
|
|
108
|
+
|
|
109
|
+
// Usage - dependencies are already wired
|
|
110
|
+
const program = Effect.gen(function* () {
|
|
111
|
+
const user = yield* UserService.findById(userId)
|
|
112
|
+
return user
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
// At app root
|
|
116
|
+
const MainLive = Layer.mergeAll(UserService.Default, OtherService.Default)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**When `Context.Tag` is acceptable:**
|
|
120
|
+
- Infrastructure with runtime injection (Cloudflare KV, worker bindings)
|
|
121
|
+
- Factory patterns where resources are provided externally
|
|
122
|
+
|
|
123
|
+
See `references/service-patterns.md` for detailed patterns.
|
|
124
|
+
|
|
125
|
+
**Conceptual rule:** whether a capability is expressed with `Effect.Service` or an infrastructure `Context.Tag`, the dependency must stay visible as an Effect requirement until a layer provides it. Do not smuggle dependencies through concrete imports or module singletons.
|
|
126
|
+
|
|
127
|
+
## Error Definition Pattern
|
|
128
|
+
|
|
129
|
+
**Always use `Schema.TaggedError`** for errors. This makes them serializable (required for RPC) and provides consistent structure.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { Schema } from "effect"
|
|
133
|
+
import { HttpApiSchema } from "@effect/platform"
|
|
134
|
+
|
|
135
|
+
export class UserNotFoundError extends Schema.TaggedError<UserNotFoundError>()(
|
|
136
|
+
"UserNotFoundError",
|
|
137
|
+
{
|
|
138
|
+
userId: UserId,
|
|
139
|
+
message: Schema.String,
|
|
140
|
+
},
|
|
141
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
142
|
+
) {}
|
|
143
|
+
|
|
144
|
+
export class UserCreateError extends Schema.TaggedError<UserCreateError>()(
|
|
145
|
+
"UserCreateError",
|
|
146
|
+
{
|
|
147
|
+
message: Schema.String,
|
|
148
|
+
cause: Schema.optional(Schema.String),
|
|
149
|
+
},
|
|
150
|
+
HttpApiSchema.annotations({ status: 400 }),
|
|
151
|
+
) {}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Error handling - use `catchTag`/`catchTags`:**
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
// CORRECT - preserves type information
|
|
158
|
+
yield* repo.findById(id).pipe(
|
|
159
|
+
Effect.catchTag("DatabaseError", (err) =>
|
|
160
|
+
Effect.fail(new UserNotFoundError({ userId: id, message: "Lookup failed" }))
|
|
161
|
+
),
|
|
162
|
+
Effect.catchTag("ConnectionError", (err) =>
|
|
163
|
+
Effect.fail(new ServiceUnavailableError({ message: "Database unreachable" }))
|
|
164
|
+
),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
// CORRECT - multiple tags at once
|
|
168
|
+
yield* effect.pipe(
|
|
169
|
+
Effect.catchTags({
|
|
170
|
+
DatabaseError: (err) => Effect.fail(new UserNotFoundError({ userId: id, message: err.message })),
|
|
171
|
+
ValidationError: (err) => Effect.fail(new InvalidEmailError({ email: input.email, message: err.message })),
|
|
172
|
+
}),
|
|
173
|
+
)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Prefer Explicit Over Generic Errors
|
|
177
|
+
|
|
178
|
+
**Every distinct failure reason deserves its own error type.** Don't collapse multiple failure modes into generic HTTP errors.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// WRONG - Generic errors lose information
|
|
182
|
+
export class NotFoundError extends Schema.TaggedError<NotFoundError>()(
|
|
183
|
+
"NotFoundError",
|
|
184
|
+
{ message: Schema.String },
|
|
185
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
186
|
+
) {}
|
|
187
|
+
|
|
188
|
+
// Then mapping everything to it:
|
|
189
|
+
Effect.catchTags({
|
|
190
|
+
UserNotFoundError: (err) => Effect.fail(new NotFoundError({ message: "Not found" })),
|
|
191
|
+
ChannelNotFoundError: (err) => Effect.fail(new NotFoundError({ message: "Not found" })),
|
|
192
|
+
MessageNotFoundError: (err) => Effect.fail(new NotFoundError({ message: "Not found" })),
|
|
193
|
+
})
|
|
194
|
+
// Frontend gets useless: { _tag: "NotFoundError", message: "Not found" }
|
|
195
|
+
// Which resource? User? Channel? Message? Can't tell!
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// CORRECT - Explicit domain errors with rich context
|
|
200
|
+
export class UserNotFoundError extends Schema.TaggedError<UserNotFoundError>()(
|
|
201
|
+
"UserNotFoundError",
|
|
202
|
+
{ userId: UserId, message: Schema.String },
|
|
203
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
204
|
+
) {}
|
|
205
|
+
|
|
206
|
+
export class ChannelNotFoundError extends Schema.TaggedError<ChannelNotFoundError>()(
|
|
207
|
+
"ChannelNotFoundError",
|
|
208
|
+
{ channelId: ChannelId, message: Schema.String },
|
|
209
|
+
HttpApiSchema.annotations({ status: 404 }),
|
|
210
|
+
) {}
|
|
211
|
+
|
|
212
|
+
export class SessionExpiredError extends Schema.TaggedError<SessionExpiredError>()(
|
|
213
|
+
"SessionExpiredError",
|
|
214
|
+
{ sessionId: SessionId, expiredAt: Schema.DateTimeUtc, message: Schema.String },
|
|
215
|
+
HttpApiSchema.annotations({ status: 401 }),
|
|
216
|
+
) {}
|
|
217
|
+
|
|
218
|
+
// Frontend can now show specific UI:
|
|
219
|
+
// - UserNotFoundError → "User doesn't exist"
|
|
220
|
+
// - ChannelNotFoundError → "Channel was deleted"
|
|
221
|
+
// - SessionExpiredError → "Your session expired. Please log in again."
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
See `references/error-patterns.md` for error remapping and retry patterns.
|
|
225
|
+
|
|
226
|
+
## Schema & Branded Types Pattern
|
|
227
|
+
|
|
228
|
+
**Brand all entity IDs** for type safety across service boundaries:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import { Schema } from "effect"
|
|
232
|
+
|
|
233
|
+
// Entity IDs - always branded
|
|
234
|
+
export const UserId = Schema.UUID.pipe(Schema.brand("@App/UserId"))
|
|
235
|
+
export type UserId = Schema.Schema.Type<typeof UserId>
|
|
236
|
+
|
|
237
|
+
export const OrganizationId = Schema.UUID.pipe(Schema.brand("@App/OrganizationId"))
|
|
238
|
+
export type OrganizationId = Schema.Schema.Type<typeof OrganizationId>
|
|
239
|
+
|
|
240
|
+
// Domain types - use Schema.Struct
|
|
241
|
+
export const User = Schema.Struct({
|
|
242
|
+
id: UserId,
|
|
243
|
+
email: Schema.String,
|
|
244
|
+
name: Schema.String,
|
|
245
|
+
organizationId: OrganizationId,
|
|
246
|
+
createdAt: Schema.DateTimeUtc,
|
|
247
|
+
})
|
|
248
|
+
export type User = Schema.Schema.Type<typeof User>
|
|
249
|
+
|
|
250
|
+
// Input types for mutations
|
|
251
|
+
export const CreateUserInput = Schema.Struct({
|
|
252
|
+
email: Schema.String.pipe(Schema.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)),
|
|
253
|
+
name: Schema.String.pipe(Schema.minLength(1)),
|
|
254
|
+
organizationId: OrganizationId,
|
|
255
|
+
})
|
|
256
|
+
export type CreateUserInput = Schema.Schema.Type<typeof CreateUserInput>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**When NOT to brand:**
|
|
260
|
+
- Simple strings that don't cross service boundaries (URLs, file paths)
|
|
261
|
+
- Primitive config values
|
|
262
|
+
|
|
263
|
+
See `references/schema-patterns.md` for transforms and advanced patterns.
|
|
264
|
+
|
|
265
|
+
## Function Pattern with Effect.fn
|
|
266
|
+
|
|
267
|
+
**Always use `Effect.fn`** for service methods. This provides automatic tracing with proper span names:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// CORRECT - Effect.fn with descriptive name
|
|
271
|
+
const findById = Effect.fn("UserService.findById")(function* (id: UserId) {
|
|
272
|
+
yield* Effect.annotateCurrentSpan("userId", id)
|
|
273
|
+
const user = yield* repo.findById(id)
|
|
274
|
+
return user
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
// CORRECT - Effect.fn with multiple parameters
|
|
278
|
+
const transfer = Effect.fn("AccountService.transfer")(
|
|
279
|
+
function* (fromId: AccountId, toId: AccountId, amount: number) {
|
|
280
|
+
yield* Effect.annotateCurrentSpan("fromId", fromId)
|
|
281
|
+
yield* Effect.annotateCurrentSpan("toId", toId)
|
|
282
|
+
yield* Effect.annotateCurrentSpan("amount", amount)
|
|
283
|
+
// ...
|
|
284
|
+
}
|
|
285
|
+
)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Layer Composition
|
|
289
|
+
|
|
290
|
+
**Declare dependencies in the service**, not at usage sites:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
// CORRECT - dependencies in service definition
|
|
294
|
+
export class OrderService extends Effect.Service<OrderService>()("OrderService", {
|
|
295
|
+
accessors: true,
|
|
296
|
+
dependencies: [
|
|
297
|
+
UserService.Default,
|
|
298
|
+
ProductService.Default,
|
|
299
|
+
PaymentService.Default,
|
|
300
|
+
],
|
|
301
|
+
effect: Effect.gen(function* () {
|
|
302
|
+
const users = yield* UserService
|
|
303
|
+
const products = yield* ProductService
|
|
304
|
+
const payments = yield* PaymentService
|
|
305
|
+
// ...
|
|
306
|
+
}),
|
|
307
|
+
}) {}
|
|
308
|
+
|
|
309
|
+
// At app root - simple merge
|
|
310
|
+
const AppLive = Layer.mergeAll(
|
|
311
|
+
OrderService.Default,
|
|
312
|
+
// Infrastructure layers (intentionally not in dependencies)
|
|
313
|
+
DatabaseLive,
|
|
314
|
+
RedisLive,
|
|
315
|
+
)
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Layer composition patterns:**
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// Use Layer.mergeAll for flat composition of same-level layers
|
|
322
|
+
const RepoLive = Layer.mergeAll(
|
|
323
|
+
UserRepo.Default,
|
|
324
|
+
OrderRepo.Default,
|
|
325
|
+
ProductRepo.Default,
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
// Use Layer.provideMerge for incremental chaining (flatter types than Layer.provide)
|
|
329
|
+
const MainLive = DatabaseLive.pipe(
|
|
330
|
+
Layer.provideMerge(ConfigServiceLive),
|
|
331
|
+
Layer.provideMerge(LoggerLive),
|
|
332
|
+
Layer.provideMerge(CacheLive),
|
|
333
|
+
)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Why layers over `Effect.provide`:**
|
|
337
|
+
- **Deduplication**: Layers memoize construction - same service instantiated once. `Effect.provide` creates new instances each call.
|
|
338
|
+
- **TypeScript performance**: Deep `Layer.provide` nesting creates complex recursive types that slow the LSP. `Layer.mergeAll` and `Layer.provideMerge` produce flatter types.
|
|
339
|
+
- **Resource management**: Scoped layers properly share and clean up resources.
|
|
340
|
+
- **Test substitution**: Tests replace capabilities by providing a different layer. Avoid `vi.mock` for Effect services.
|
|
341
|
+
|
|
342
|
+
See `references/layer-patterns.md` for testing layers, config-dependent layers, and the `layerConfig` pattern.
|
|
343
|
+
|
|
344
|
+
## Option Handling
|
|
345
|
+
|
|
346
|
+
**Never use `Option.getOrThrow`**. Always handle both cases explicitly:
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
// CORRECT - explicit handling
|
|
350
|
+
yield* Option.match(maybeUser, {
|
|
351
|
+
onNone: () => Effect.fail(new UserNotFoundError({ userId, message: "Not found" })),
|
|
352
|
+
onSome: (user) => Effect.succeed(user),
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
// CORRECT - with getOrElse for defaults
|
|
356
|
+
const name = Option.getOrElse(maybeName, () => "Anonymous")
|
|
357
|
+
|
|
358
|
+
// CORRECT - Option.map for transformations
|
|
359
|
+
const upperName = Option.map(maybeName, (n) => n.toUpperCase())
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Effect Atom (Frontend State)
|
|
363
|
+
|
|
364
|
+
Effect Atom provides reactive state management for React with Effect integration.
|
|
365
|
+
|
|
366
|
+
### Basic Atoms
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import { Atom } from "@effect-atom/atom-react"
|
|
370
|
+
|
|
371
|
+
// Define atoms OUTSIDE components
|
|
372
|
+
const countAtom = Atom.make(0)
|
|
373
|
+
|
|
374
|
+
// Use keepAlive for global state that should persist
|
|
375
|
+
const userPrefsAtom = Atom.make({ theme: "dark" }).pipe(Atom.keepAlive)
|
|
376
|
+
|
|
377
|
+
// Atom families for per-entity state
|
|
378
|
+
const modalAtomFamily = Atom.family((type: string) =>
|
|
379
|
+
Atom.make({ isOpen: false }).pipe(Atom.keepAlive)
|
|
380
|
+
)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### React Integration
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
import { useAtomValue, useAtomSet, useAtom, useAtomMount } from "@effect-atom/atom-react"
|
|
387
|
+
|
|
388
|
+
function Counter() {
|
|
389
|
+
const count = useAtomValue(countAtom) // Read only
|
|
390
|
+
const setCount = useAtomSet(countAtom) // Write only
|
|
391
|
+
const [value, setValue] = useAtom(countAtom) // Read + write
|
|
392
|
+
|
|
393
|
+
return <button onClick={() => setCount((c) => c + 1)}>{count}</button>
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Mount side-effect atoms without reading value
|
|
397
|
+
function App() {
|
|
398
|
+
useAtomMount(keyboardShortcutsAtom)
|
|
399
|
+
return <>{children}</>
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Handling Results with Result.builder
|
|
404
|
+
|
|
405
|
+
**Use `Result.builder`** for rendering effectful atom results. It provides chainable error handling with `onErrorTag`:
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
import { Result } from "@effect-atom/atom-react"
|
|
409
|
+
|
|
410
|
+
function UserProfile() {
|
|
411
|
+
const userResult = useAtomValue(userAtom) // Result<User, Error>
|
|
412
|
+
|
|
413
|
+
return Result.builder(userResult)
|
|
414
|
+
.onInitial(() => <div>Loading...</div>)
|
|
415
|
+
.onErrorTag("NotFoundError", () => <div>User not found</div>)
|
|
416
|
+
.onError((error) => <div>Error: {error.message}</div>)
|
|
417
|
+
.onSuccess((user) => <div>Hello, {user.name}</div>)
|
|
418
|
+
.render()
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Atoms with Side Effects
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
const scrollYAtom = Atom.make((get) => {
|
|
426
|
+
const onScroll = () => get.setSelf(window.scrollY)
|
|
427
|
+
|
|
428
|
+
window.addEventListener("scroll", onScroll)
|
|
429
|
+
get.addFinalizer(() => window.removeEventListener("scroll", onScroll)) // REQUIRED
|
|
430
|
+
|
|
431
|
+
return window.scrollY
|
|
432
|
+
}).pipe(Atom.keepAlive)
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### React Mutations
|
|
436
|
+
|
|
437
|
+
For mutation atoms, derive loading state from `result.waiting` instead of `useState`:
|
|
438
|
+
|
|
439
|
+
```typescript
|
|
440
|
+
const [result, mutate] = useAtom(deleteMutation, { mode: "promise" })
|
|
441
|
+
const isLoading = result.waiting // Updates automatically, no useState/finally needed
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**Dialog ownership:** Move mutation logic into dialog components. Dialog owns the mutation hook, loading state, and toasts. Parent provides data props and an `onSuccess` callback.
|
|
445
|
+
|
|
446
|
+
**Cache invalidation:** Use `reactivityKeys` on both mutation and query atoms to auto-invalidate queries after mutations — replaces manual `refresh()` calls.
|
|
447
|
+
|
|
448
|
+
See `references/effect-atom-patterns.md` for complete patterns including families, localStorage, mutations, and anti-patterns.
|
|
449
|
+
|
|
450
|
+
## RPC & Cluster Patterns
|
|
451
|
+
|
|
452
|
+
For RPC contracts and cluster workflows, see:
|
|
453
|
+
- `references/rpc-cluster-patterns.md` - RpcGroup, Workflow.make, Activity patterns
|
|
454
|
+
|
|
455
|
+
## Anti-Patterns (Forbidden)
|
|
456
|
+
|
|
457
|
+
These patterns are **never acceptable**:
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
// FORBIDDEN - runSync/runPromise inside services
|
|
461
|
+
const result = Effect.runSync(someEffect) // Never do this
|
|
462
|
+
|
|
463
|
+
// FORBIDDEN - throw inside Effect.gen
|
|
464
|
+
yield* Effect.gen(function* () {
|
|
465
|
+
if (bad) throw new Error("No!") // Use Effect.fail instead
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
// FORBIDDEN - catchAll losing type info
|
|
469
|
+
yield* effect.pipe(Effect.catchAll(() => Effect.fail(new GenericError())))
|
|
470
|
+
|
|
471
|
+
// FORBIDDEN - console.log
|
|
472
|
+
console.log("debug") // Use Effect.log
|
|
473
|
+
|
|
474
|
+
// FORBIDDEN - process.env directly
|
|
475
|
+
const key = process.env.API_KEY // Use Config.string("API_KEY")
|
|
476
|
+
|
|
477
|
+
// FORBIDDEN - null/undefined in domain types
|
|
478
|
+
type User = { name: string | null } // Use Option<string>
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
See `references/anti-patterns.md` for the complete list with rationale.
|
|
482
|
+
|
|
483
|
+
## Observability
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
// Structured logging
|
|
487
|
+
yield* Effect.log("Processing order", { orderId, userId, amount })
|
|
488
|
+
|
|
489
|
+
// Metrics
|
|
490
|
+
const orderCounter = Metric.counter("orders_processed")
|
|
491
|
+
yield* Metric.increment(orderCounter)
|
|
492
|
+
|
|
493
|
+
// Config with validation
|
|
494
|
+
const config = Config.all({
|
|
495
|
+
port: Config.integer("PORT").pipe(Config.withDefault(3000)),
|
|
496
|
+
apiKey: Config.redacted("API_KEY"),
|
|
497
|
+
maxRetries: Config.integer("MAX_RETRIES").pipe(
|
|
498
|
+
Config.validate({ message: "Must be positive", validation: (n) => n > 0 })
|
|
499
|
+
),
|
|
500
|
+
})
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
See `references/observability-patterns.md` for metrics and tracing patterns.
|
|
504
|
+
|
|
505
|
+
## Reference Files
|
|
506
|
+
|
|
507
|
+
For detailed patterns, consult these reference files in the `references/` directory:
|
|
508
|
+
|
|
509
|
+
- `language-server.md` - Effect Language Service setup, diagnostics, refactors, CLI tools
|
|
510
|
+
- `service-patterns.md` - Service definition, Effect.fn, Context.Tag exceptions
|
|
511
|
+
- `error-patterns.md` - Schema.TaggedError, error remapping, retry patterns
|
|
512
|
+
- `schema-patterns.md` - Branded types, transforms, Schema.Class
|
|
513
|
+
- `layer-patterns.md` - Dependency composition, testing layers
|
|
514
|
+
- `rpc-cluster-patterns.md` - RpcGroup, Workflow, Activity patterns
|
|
515
|
+
- `effect-atom-patterns.md` - Atom, families, React hooks, Result handling
|
|
516
|
+
- `anti-patterns.md` - Complete list of forbidden patterns
|
|
517
|
+
- `observability-patterns.md` - Logging, metrics, config patterns
|