cfsa-antigravity 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/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: authjs
|
|
3
|
+
description: |
|
|
4
|
+
Build with Auth.js (NextAuth.js v5) — OAuth providers, credentials, JWT/database sessions, middleware route protection, and RBAC patterns. Use when: setting up authentication flows, configuring providers (Google, GitHub, Discord, email magic link, credentials), protecting routes with middleware, managing sessions (useSession, auth()), extending JWT/session types, implementing role-based access, or troubleshooting callback/redirect/CSRF errors.
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Auth.js (NextAuth.js v5)
|
|
9
|
+
|
|
10
|
+
**Status**: Production Ready
|
|
11
|
+
**Last Updated**: 2026-02-16
|
|
12
|
+
**Package**: `next-auth@5.x` (beta channel for v5)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Setup and Configuration
|
|
17
|
+
|
|
18
|
+
### 1. Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add next-auth@beta
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 2. Auth Configuration
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// src/auth.ts
|
|
28
|
+
import NextAuth from "next-auth";
|
|
29
|
+
import Google from "next-auth/providers/google";
|
|
30
|
+
import GitHub from "next-auth/providers/github";
|
|
31
|
+
import Credentials from "next-auth/providers/credentials";
|
|
32
|
+
import { DrizzleAdapter } from "@auth/drizzle-adapter";
|
|
33
|
+
import { db } from "@/db";
|
|
34
|
+
|
|
35
|
+
export const { handlers, auth, signIn, signOut } = NextAuth({
|
|
36
|
+
adapter: DrizzleAdapter(db),
|
|
37
|
+
providers: [
|
|
38
|
+
Google({
|
|
39
|
+
clientId: process.env.AUTH_GOOGLE_ID,
|
|
40
|
+
clientSecret: process.env.AUTH_GOOGLE_SECRET,
|
|
41
|
+
}),
|
|
42
|
+
GitHub({
|
|
43
|
+
clientId: process.env.AUTH_GITHUB_ID,
|
|
44
|
+
clientSecret: process.env.AUTH_GITHUB_SECRET,
|
|
45
|
+
}),
|
|
46
|
+
],
|
|
47
|
+
session: { strategy: "jwt" }, // or "database"
|
|
48
|
+
pages: {
|
|
49
|
+
signIn: "/auth/signin",
|
|
50
|
+
error: "/auth/error",
|
|
51
|
+
},
|
|
52
|
+
callbacks: {
|
|
53
|
+
authorized({ auth, request }) {
|
|
54
|
+
return !!auth?.user;
|
|
55
|
+
},
|
|
56
|
+
async jwt({ token, user, account }) {
|
|
57
|
+
if (user) {
|
|
58
|
+
token.id = user.id;
|
|
59
|
+
token.role = user.role;
|
|
60
|
+
}
|
|
61
|
+
return token;
|
|
62
|
+
},
|
|
63
|
+
async session({ session, token }) {
|
|
64
|
+
session.user.id = token.id as string;
|
|
65
|
+
session.user.role = token.role as string;
|
|
66
|
+
return session;
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 3. Route Handler
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// src/app/api/auth/[...nextauth]/route.ts
|
|
76
|
+
import { handlers } from "@/auth";
|
|
77
|
+
|
|
78
|
+
export const { GET, POST } = handlers;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 4. Environment Variables
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# .env.local
|
|
85
|
+
AUTH_SECRET="openssl rand -base64 33" # Required — generate with: npx auth secret
|
|
86
|
+
AUTH_GOOGLE_ID="..."
|
|
87
|
+
AUTH_GOOGLE_SECRET="..."
|
|
88
|
+
AUTH_GITHUB_ID="..."
|
|
89
|
+
AUTH_GITHUB_SECRET="..."
|
|
90
|
+
AUTH_URL="http://localhost:3000" # Only needed in non-Vercel deployments
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Provider Setup
|
|
96
|
+
|
|
97
|
+
### OAuth Providers (Google, GitHub, Discord)
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import Google from "next-auth/providers/google";
|
|
101
|
+
import GitHub from "next-auth/providers/github";
|
|
102
|
+
import Discord from "next-auth/providers/discord";
|
|
103
|
+
|
|
104
|
+
// Minimal — Auth.js auto-discovers env vars named AUTH_[PROVIDER]_ID / AUTH_[PROVIDER]_SECRET
|
|
105
|
+
providers: [Google, GitHub, Discord];
|
|
106
|
+
|
|
107
|
+
// With explicit config and scopes
|
|
108
|
+
providers: [
|
|
109
|
+
Google({
|
|
110
|
+
authorization: { params: { scope: "openid email profile" } },
|
|
111
|
+
// Request refresh token for offline access
|
|
112
|
+
authorization: {
|
|
113
|
+
params: { access_type: "offline", prompt: "consent" },
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
];
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Credentials Provider
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import Credentials from "next-auth/providers/credentials";
|
|
123
|
+
import { z } from "zod";
|
|
124
|
+
import bcrypt from "bcryptjs";
|
|
125
|
+
|
|
126
|
+
const LoginSchema = z.object({
|
|
127
|
+
email: z.string().email(),
|
|
128
|
+
password: z.string().min(8),
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
providers: [
|
|
132
|
+
Credentials({
|
|
133
|
+
credentials: {
|
|
134
|
+
email: { label: "Email", type: "email" },
|
|
135
|
+
password: { label: "Password", type: "password" },
|
|
136
|
+
},
|
|
137
|
+
async authorize(credentials) {
|
|
138
|
+
const parsed = LoginSchema.safeParse(credentials);
|
|
139
|
+
if (!parsed.success) return null;
|
|
140
|
+
|
|
141
|
+
const user = await db.query.users.findFirst({
|
|
142
|
+
where: eq(users.email, parsed.data.email),
|
|
143
|
+
});
|
|
144
|
+
if (!user?.hashedPassword) return null;
|
|
145
|
+
|
|
146
|
+
const valid = await bcrypt.compare(parsed.data.password, user.hashedPassword);
|
|
147
|
+
if (!valid) return null;
|
|
148
|
+
|
|
149
|
+
return { id: user.id, email: user.email, name: user.name, role: user.role };
|
|
150
|
+
},
|
|
151
|
+
}),
|
|
152
|
+
];
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Credentials caveats:**
|
|
156
|
+
- No built-in session persistence with database strategy — JWT only
|
|
157
|
+
- No automatic account linking with OAuth providers
|
|
158
|
+
- You own password hashing, rate limiting, brute force protection
|
|
159
|
+
- Auth.js strongly recommends OAuth or magic link over credentials
|
|
160
|
+
|
|
161
|
+
### Email Magic Link (Passwordless)
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import Resend from "next-auth/providers/resend";
|
|
165
|
+
|
|
166
|
+
providers: [
|
|
167
|
+
Resend({
|
|
168
|
+
from: "noreply@example.com",
|
|
169
|
+
// Requires a database adapter — tokens stored in verification table
|
|
170
|
+
}),
|
|
171
|
+
];
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Session Strategies
|
|
177
|
+
|
|
178
|
+
### JWT Sessions (Default)
|
|
179
|
+
|
|
180
|
+
- No database required for sessions
|
|
181
|
+
- Token stored in encrypted HTTP-only cookie
|
|
182
|
+
- Larger cookie size with extended token data
|
|
183
|
+
- Cannot be revoked server-side (stateless)
|
|
184
|
+
- Use when: serverless, edge runtime, no DB adapter needed
|
|
185
|
+
|
|
186
|
+
### Database Sessions
|
|
187
|
+
|
|
188
|
+
- Session stored in database via adapter
|
|
189
|
+
- Small session token in cookie, data in DB
|
|
190
|
+
- Can be revoked by deleting the session row
|
|
191
|
+
- Requires a database adapter (Drizzle, Prisma, etc.)
|
|
192
|
+
- Use when: need server-side session revocation, multi-device management
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// Database sessions
|
|
196
|
+
session: { strategy: "database", maxAge: 30 * 24 * 60 * 60 } // 30 days
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Middleware for Route Protection
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// src/middleware.ts
|
|
205
|
+
import { auth } from "@/auth";
|
|
206
|
+
|
|
207
|
+
export default auth((req) => {
|
|
208
|
+
const isLoggedIn = !!req.auth;
|
|
209
|
+
const isOnDashboard = req.nextUrl.pathname.startsWith("/dashboard");
|
|
210
|
+
const isOnAdmin = req.nextUrl.pathname.startsWith("/admin");
|
|
211
|
+
const isOnAuth = req.nextUrl.pathname.startsWith("/auth");
|
|
212
|
+
|
|
213
|
+
// Protect dashboard
|
|
214
|
+
if (isOnDashboard && !isLoggedIn) {
|
|
215
|
+
return Response.redirect(new URL("/auth/signin", req.nextUrl));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Protect admin routes — check role from JWT
|
|
219
|
+
if (isOnAdmin) {
|
|
220
|
+
if (!isLoggedIn) {
|
|
221
|
+
return Response.redirect(new URL("/auth/signin", req.nextUrl));
|
|
222
|
+
}
|
|
223
|
+
if (req.auth?.user?.role !== "admin") {
|
|
224
|
+
return Response.redirect(new URL("/unauthorized", req.nextUrl));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Redirect authenticated users away from auth pages
|
|
229
|
+
if (isOnAuth && isLoggedIn) {
|
|
230
|
+
return Response.redirect(new URL("/dashboard", req.nextUrl));
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
export const config = {
|
|
235
|
+
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
|
|
236
|
+
};
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Client-Side Usage
|
|
242
|
+
|
|
243
|
+
### useSession Hook
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
"use client";
|
|
247
|
+
import { useSession } from "next-auth/react";
|
|
248
|
+
|
|
249
|
+
export function UserProfile() {
|
|
250
|
+
const { data: session, status, update } = useSession();
|
|
251
|
+
|
|
252
|
+
if (status === "loading") return <Skeleton />;
|
|
253
|
+
if (status === "unauthenticated") return <SignInButton />;
|
|
254
|
+
|
|
255
|
+
return <p>Welcome, {session.user.name}</p>;
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### SessionProvider
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// src/app/providers.tsx
|
|
263
|
+
"use client";
|
|
264
|
+
import { SessionProvider } from "next-auth/react";
|
|
265
|
+
|
|
266
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
267
|
+
return <SessionProvider>{children}</SessionProvider>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// src/app/layout.tsx
|
|
271
|
+
import { Providers } from "./providers";
|
|
272
|
+
|
|
273
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
274
|
+
return (
|
|
275
|
+
<html>
|
|
276
|
+
<body>
|
|
277
|
+
<Providers>{children}</Providers>
|
|
278
|
+
</body>
|
|
279
|
+
</html>
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### signIn / signOut (Client)
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
"use client";
|
|
288
|
+
import { signIn, signOut } from "next-auth/react";
|
|
289
|
+
|
|
290
|
+
// OAuth sign-in — redirects to provider
|
|
291
|
+
<button onClick={() => signIn("google")}>Sign in with Google</button>
|
|
292
|
+
<button onClick={() => signIn("github", { callbackUrl: "/dashboard" })}>GitHub</button>
|
|
293
|
+
|
|
294
|
+
// Credentials sign-in — no redirect, handle response
|
|
295
|
+
const result = await signIn("credentials", {
|
|
296
|
+
email,
|
|
297
|
+
password,
|
|
298
|
+
redirect: false, // Prevent automatic redirect
|
|
299
|
+
});
|
|
300
|
+
if (result?.error) {
|
|
301
|
+
setError("Invalid credentials");
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Sign out
|
|
305
|
+
<button onClick={() => signOut({ callbackUrl: "/" })}>Sign out</button>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Server-Side Session Access
|
|
311
|
+
|
|
312
|
+
### In Server Components (App Router)
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// src/app/dashboard/page.tsx
|
|
316
|
+
import { auth } from "@/auth";
|
|
317
|
+
import { redirect } from "next/navigation";
|
|
318
|
+
|
|
319
|
+
export default async function DashboardPage() {
|
|
320
|
+
const session = await auth();
|
|
321
|
+
|
|
322
|
+
if (!session) redirect("/auth/signin");
|
|
323
|
+
|
|
324
|
+
return <h1>Welcome {session.user.name}</h1>;
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### In API Routes
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
// src/app/api/protected/route.ts
|
|
332
|
+
import { auth } from "@/auth";
|
|
333
|
+
|
|
334
|
+
export async function GET() {
|
|
335
|
+
const session = await auth();
|
|
336
|
+
|
|
337
|
+
if (!session) {
|
|
338
|
+
return Response.json({ error: "Unauthorized" }, { status: 401 });
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return Response.json({ user: session.user });
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### In Server Actions
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
"use server";
|
|
349
|
+
import { auth } from "@/auth";
|
|
350
|
+
|
|
351
|
+
export async function updateProfile(formData: FormData) {
|
|
352
|
+
const session = await auth();
|
|
353
|
+
if (!session?.user?.id) throw new Error("Unauthorized");
|
|
354
|
+
|
|
355
|
+
// Proceed with authorized action
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Custom Pages
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
// src/app/auth/signin/page.tsx
|
|
365
|
+
import { signIn, providerMap } from "@/auth";
|
|
366
|
+
|
|
367
|
+
export default async function SignInPage({
|
|
368
|
+
searchParams,
|
|
369
|
+
}: {
|
|
370
|
+
searchParams: { callbackUrl?: string; error?: string };
|
|
371
|
+
}) {
|
|
372
|
+
return (
|
|
373
|
+
<div>
|
|
374
|
+
{searchParams.error && <p>Authentication error: {searchParams.error}</p>}
|
|
375
|
+
|
|
376
|
+
{Object.values(providerMap).map((provider) => (
|
|
377
|
+
<form
|
|
378
|
+
key={provider.id}
|
|
379
|
+
action={async () => {
|
|
380
|
+
"use server";
|
|
381
|
+
await signIn(provider.id, { redirectTo: searchParams.callbackUrl ?? "/" });
|
|
382
|
+
}}
|
|
383
|
+
>
|
|
384
|
+
<button>Sign in with {provider.name}</button>
|
|
385
|
+
</form>
|
|
386
|
+
))}
|
|
387
|
+
</div>
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Database Adapters
|
|
395
|
+
|
|
396
|
+
### Drizzle Adapter
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
import { DrizzleAdapter } from "@auth/drizzle-adapter";
|
|
400
|
+
import { db } from "@/db";
|
|
401
|
+
|
|
402
|
+
export const { handlers, auth } = NextAuth({
|
|
403
|
+
adapter: DrizzleAdapter(db),
|
|
404
|
+
// Drizzle adapter requires specific table schemas — see @auth/drizzle-adapter docs
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Prisma Adapter
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
import { PrismaAdapter } from "@auth/prisma-adapter";
|
|
412
|
+
import { prisma } from "@/lib/prisma";
|
|
413
|
+
|
|
414
|
+
export const { handlers, auth } = NextAuth({
|
|
415
|
+
adapter: PrismaAdapter(prisma),
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Extending Session and JWT Types
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
// src/types/next-auth.d.ts
|
|
425
|
+
import { DefaultSession, DefaultJWT } from "next-auth";
|
|
426
|
+
|
|
427
|
+
declare module "next-auth" {
|
|
428
|
+
interface Session {
|
|
429
|
+
user: {
|
|
430
|
+
id: string;
|
|
431
|
+
role: "admin" | "user" | "moderator";
|
|
432
|
+
} & DefaultSession["user"];
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
interface User {
|
|
436
|
+
role: "admin" | "user" | "moderator";
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
declare module "next-auth/jwt" {
|
|
441
|
+
interface JWT {
|
|
442
|
+
id: string;
|
|
443
|
+
role: "admin" | "user" | "moderator";
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## Role-Based Access Control
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
// src/lib/auth-utils.ts
|
|
454
|
+
import { auth } from "@/auth";
|
|
455
|
+
|
|
456
|
+
type Role = "admin" | "user" | "moderator";
|
|
457
|
+
|
|
458
|
+
export async function requireRole(...roles: Role[]) {
|
|
459
|
+
const session = await auth();
|
|
460
|
+
if (!session?.user) throw new Error("Unauthenticated");
|
|
461
|
+
if (!roles.includes(session.user.role)) throw new Error("Forbidden");
|
|
462
|
+
return session;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Usage in server action
|
|
466
|
+
export async function deleteUser(userId: string) {
|
|
467
|
+
const session = await requireRole("admin");
|
|
468
|
+
// Only admins reach here
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Usage in API route
|
|
472
|
+
export async function GET() {
|
|
473
|
+
try {
|
|
474
|
+
const session = await requireRole("admin", "moderator");
|
|
475
|
+
return Response.json({ data: "restricted" });
|
|
476
|
+
} catch {
|
|
477
|
+
return Response.json({ error: "Forbidden" }, { status: 403 });
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## Account Linking
|
|
485
|
+
|
|
486
|
+
Auth.js links accounts by email by default when `allowDangerousEmailAccountLinking` is off. For explicit control:
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
callbacks: {
|
|
490
|
+
async signIn({ user, account, profile }) {
|
|
491
|
+
// Prevent sign-in if email not verified by OAuth provider
|
|
492
|
+
if (account?.provider === "google" && !profile?.email_verified) {
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
return true;
|
|
496
|
+
},
|
|
497
|
+
},
|
|
498
|
+
|
|
499
|
+
// To allow linking accounts with same email from different providers:
|
|
500
|
+
// WARNING: Only enable if your OAuth providers verify emails
|
|
501
|
+
providers: [
|
|
502
|
+
Google({ allowDangerousEmailAccountLinking: true }),
|
|
503
|
+
],
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## Edge Runtime Compatibility
|
|
509
|
+
|
|
510
|
+
Auth.js v5 is edge-compatible by default. Constraints:
|
|
511
|
+
- Database adapters may not work on edge — use JWT strategy
|
|
512
|
+
- `bcrypt` does not work on edge — use `bcryptjs` or `@noble/hashes`
|
|
513
|
+
- Node.js-only libraries in callbacks will break edge middleware
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
// For edge-compatible password hashing
|
|
517
|
+
import { hashSync, compareSync } from "bcryptjs";
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## Anti-Patterns
|
|
523
|
+
|
|
524
|
+
| Anti-Pattern | Why It Breaks | Correct Approach |
|
|
525
|
+
|---|---|---|
|
|
526
|
+
| Storing session data in localStorage | XSS vulnerable, not httpOnly | Auth.js uses httpOnly cookies automatically |
|
|
527
|
+
| Calling `auth()` in client components | `auth()` is server-only | Use `useSession()` in client, `auth()` in server |
|
|
528
|
+
| Checking auth only on client | Bypassable, flash of wrong content | Use middleware + server-side `auth()` |
|
|
529
|
+
| Exposing provider secrets in client bundle | Secret leak | Keep in `.env.local`, server-side only |
|
|
530
|
+
| Using `redirect: true` with credentials signIn | Cannot handle errors gracefully | Use `redirect: false` and handle `result.error` |
|
|
531
|
+
| Hardcoding `AUTH_URL` on Vercel | Breaks preview deployments | Omit it — Vercel sets `NEXTAUTH_URL` automatically |
|
|
532
|
+
| Skipping CSRF token in custom forms | CSRF vulnerability | Auth.js handles CSRF automatically via its routes |
|
|
533
|
+
| Mutating the `token` object in jwt callback without returning | Silent data loss | Always `return token` from jwt callback |
|
|
534
|
+
| Using database strategy with Credentials provider | Sessions are not created for credentials | Use JWT strategy with credentials, or use OAuth |
|
|
535
|
+
| Not handling the `authorized` callback | Middleware does not protect routes | Implement `authorized` or handle in middleware |
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## CSRF Protection
|
|
540
|
+
|
|
541
|
+
Auth.js v5 includes automatic CSRF protection:
|
|
542
|
+
- POST routes require a CSRF token (auto-managed by Auth.js forms)
|
|
543
|
+
- GET routes for sign-in/sign-out redirect safely
|
|
544
|
+
- Custom forms must use Auth.js action helpers (server actions) to inherit protection
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## Debugging
|
|
549
|
+
|
|
550
|
+
```typescript
|
|
551
|
+
// Enable debug logging
|
|
552
|
+
export const { handlers, auth } = NextAuth({
|
|
553
|
+
debug: process.env.NODE_ENV === "development",
|
|
554
|
+
logger: {
|
|
555
|
+
error(code, metadata) { console.error(code, metadata); },
|
|
556
|
+
warn(code) { console.warn(code); },
|
|
557
|
+
debug(code, metadata) { console.debug(code, metadata); },
|
|
558
|
+
},
|
|
559
|
+
});
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
Common issues:
|
|
563
|
+
- `OAUTH_CALLBACK_ERROR` — Check redirect URI matches provider config exactly
|
|
564
|
+
- `JWT_SESSION_ERROR` — AUTH_SECRET changed or missing
|
|
565
|
+
- Infinite redirect loops — Check middleware matcher excludes `/api/auth`
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
**Last verified**: 2026-02-16 | **Skill version**: 1.0.0
|