@olives/devos 2.1.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/AGENTS.md +316 -0
- package/.agents/README.md +55 -0
- package/.agents/agents/architect.md +18 -0
- package/.agents/agents/dba.md +25 -0
- package/.agents/agents/developer.md +40 -0
- package/.agents/agents/devops.md +18 -0
- package/.agents/agents/memory-manager.md +38 -0
- package/.agents/agents/orchestrator.md +92 -0
- package/.agents/agents/qa.md +53 -0
- package/.agents/agents/release-manager.md +41 -0
- package/.agents/agents/researcher.md +19 -0
- package/.agents/agents/security.md +27 -0
- package/.agents/agents/tester.md +21 -0
- package/.agents/commands/README.md +42 -0
- package/.agents/commands/architect.md +16 -0
- package/.agents/commands/commit.md +15 -0
- package/.agents/commands/deploy.md +18 -0
- package/.agents/commands/fix.md +19 -0
- package/.agents/commands/refactor.md +19 -0
- package/.agents/commands/research.md +19 -0
- package/.agents/commands/review.md +21 -0
- package/.agents/commands/secure.md +23 -0
- package/.agents/commands/status.md +16 -0
- package/.agents/commands/test.md +16 -0
- package/.agents/scripts/commit.sh +73 -0
- package/.agents/scripts/install-hooks.sh +72 -0
- package/.agents/skills/agent-browser/SKILL.md +50 -0
- package/.agents/skills/agent-development/SKILL.md +415 -0
- package/.agents/skills/agent-development/examples/agent-creation-prompt.md +238 -0
- package/.agents/skills/agent-development/examples/complete-agent-examples.md +427 -0
- package/.agents/skills/agent-development/references/agent-creation-system-prompt.md +207 -0
- package/.agents/skills/agent-development/references/system-prompt-design.md +411 -0
- package/.agents/skills/agent-development/references/triggering-examples.md +491 -0
- package/.agents/skills/agent-development/scripts/validate-agent.sh +217 -0
- package/.agents/skills/backend-dev-guidelines/SKILL.md +352 -0
- package/.agents/skills/backend-dev-guidelines/resources/architecture-overview.md +451 -0
- package/.agents/skills/backend-dev-guidelines/resources/async-and-errors.md +307 -0
- package/.agents/skills/backend-dev-guidelines/resources/complete-examples.md +638 -0
- package/.agents/skills/backend-dev-guidelines/resources/configuration.md +275 -0
- package/.agents/skills/backend-dev-guidelines/resources/database-patterns.md +224 -0
- package/.agents/skills/backend-dev-guidelines/resources/middleware-guide.md +213 -0
- package/.agents/skills/backend-dev-guidelines/resources/routing-and-controllers.md +756 -0
- package/.agents/skills/backend-dev-guidelines/resources/sentry-and-monitoring.md +336 -0
- package/.agents/skills/backend-dev-guidelines/resources/services-and-repositories.md +789 -0
- package/.agents/skills/backend-dev-guidelines/resources/testing-guide.md +235 -0
- package/.agents/skills/backend-dev-guidelines/resources/validation-patterns.md +754 -0
- package/.agents/skills/backend-development/SKILL.md +156 -0
- package/.agents/skills/backend-patterns/SKILL.md +562 -0
- package/.agents/skills/brainstorming/SKILL.md +159 -0
- package/.agents/skills/brainstorming/scripts/frame-template.html +213 -0
- package/.agents/skills/brainstorming/scripts/helper.js +167 -0
- package/.agents/skills/brainstorming/scripts/server.cjs +723 -0
- package/.agents/skills/brainstorming/scripts/start-server.sh +209 -0
- package/.agents/skills/brainstorming/scripts/stop-server.sh +120 -0
- package/.agents/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/.agents/skills/brainstorming/visual-companion.md +291 -0
- package/.agents/skills/code-reviewer/SKILL.md +65 -0
- package/.agents/skills/content-strategy/SKILL.md +365 -0
- package/.agents/skills/content-strategy/evals/evals.json +90 -0
- package/.agents/skills/content-strategy/references/headless-cms.md +194 -0
- package/.agents/skills/deploy-to-vercel/SKILL.md +296 -0
- package/.agents/skills/deploy-to-vercel/resources/deploy-codex.sh +301 -0
- package/.agents/skills/deploy-to-vercel/resources/deploy.sh +301 -0
- package/.agents/skills/deployment-checklist/SKILL.md +119 -0
- package/.agents/skills/design/SKILL.md +170 -0
- package/.agents/skills/design-an-interface/SKILL.md +94 -0
- package/.agents/skills/expose-localhost/SKILL.md +211 -0
- package/.agents/skills/expose-localhost/references/TROUBLESHOOTING.md +27 -0
- package/.agents/skills/find-skills/SKILL.md +142 -0
- package/.agents/skills/frontend-ui-engineering/SKILL.md +328 -0
- package/.agents/skills/git-commit/SKILL.md +124 -0
- package/.agents/skills/git-ops/SKILL.md +53 -0
- package/.agents/skills/git-workflow/SKILL.md +167 -0
- package/.agents/skills/google-agents-cli-adk-code/SKILL.md +72 -0
- package/.agents/skills/google-agents-cli-adk-code/references/adk-python.md +937 -0
- package/.agents/skills/google-agents-cli-adk-code/references/adk-workflows.md +507 -0
- package/.agents/skills/google-agents-cli-workflow/SKILL.md +310 -0
- package/.agents/skills/google-agents-cli-workflow/references/commands.md +12 -0
- package/.agents/skills/google-agents-cli-workflow/references/internals.md +24 -0
- package/.agents/skills/google-agents-cli-workflow/references/samples.md +59 -0
- package/.agents/skills/google-agents-cli-workflow/references/spec-template.md +25 -0
- package/.agents/skills/google-agents-cli-workflow/references/terminology.md +11 -0
- package/.agents/skills/grill-me/SKILL.md +47 -0
- package/.agents/skills/grill-with-docs/SKILL.md +7 -0
- package/.agents/skills/human-checkpoint/SKILL.md +21 -0
- package/.agents/skills/image/SKILL.md +340 -0
- package/.agents/skills/image/evals/evals.json +89 -0
- package/.agents/skills/image/references/ai-image-prompting.md +229 -0
- package/.agents/skills/image-generation/SKILL.md +374 -0
- package/.agents/skills/imagegen/LICENSE.txt +201 -0
- package/.agents/skills/imagegen/SKILL.md +279 -0
- package/.agents/skills/imagegen/agents/openai.yaml +6 -0
- package/.agents/skills/imagegen/assets/imagegen-small.svg +5 -0
- package/.agents/skills/imagegen/assets/imagegen.png +0 -0
- package/.agents/skills/imagegen/references/cli.md +160 -0
- package/.agents/skills/imagegen/references/codex-network.md +33 -0
- package/.agents/skills/imagegen/references/image-api.md +49 -0
- package/.agents/skills/imagegen/references/prompting.md +98 -0
- package/.agents/skills/imagegen/references/sample-prompts.md +376 -0
- package/.agents/skills/imagegen/scripts/image_gen.py +926 -0
- package/.agents/skills/imagegen-frontend-web/SKILL.md +987 -0
- package/.agents/skills/laravel-security/SKILL.md +948 -0
- package/.agents/skills/laravel-specialist/SKILL.md +264 -0
- package/.agents/skills/laravel-specialist/references/eloquent.md +351 -0
- package/.agents/skills/laravel-specialist/references/livewire.md +512 -0
- package/.agents/skills/laravel-specialist/references/queues.md +423 -0
- package/.agents/skills/laravel-specialist/references/routing.md +362 -0
- package/.agents/skills/laravel-specialist/references/testing.md +522 -0
- package/.agents/skills/laravel-tdd/SKILL.md +675 -0
- package/.agents/skills/laravel-verification/SKILL.md +180 -0
- package/.agents/skills/modern-web-guidance/SKILL.md +114 -0
- package/.agents/skills/modern-web-guidance/guides/accessibility/accessibility.md +463 -0
- package/.agents/skills/modern-web-guidance/guides/accessibility/accessible-error-announcement.md +207 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/language-detection.md +89 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/language-model.md +189 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/prompt-api.md +189 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/summarizer.md +154 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/translator.md +162 -0
- package/.agents/skills/modern-web-guidance/guides/css/css.md +527 -0
- package/.agents/skills/modern-web-guidance/guides/css/highlight-text-ranges.md +128 -0
- package/.agents/skills/modern-web-guidance/guides/css-layout/css-layout.md +305 -0
- package/.agents/skills/modern-web-guidance/guides/forms/animated-select-picker.md +178 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-address-form.md +75 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-highlight-inputs.md +45 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-payment-form.md +125 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-sign-in-form.md +135 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-sign-up-form.md +145 -0
- package/.agents/skills/modern-web-guidance/guides/forms/brand-consistent-forms.md +255 -0
- package/.agents/skills/modern-web-guidance/guides/forms/branded-select-styling.md +114 -0
- package/.agents/skills/modern-web-guidance/guides/forms/custom-select-picker-layouts.md +103 -0
- package/.agents/skills/modern-web-guidance/guides/forms/form-fields-automatically-fit-contents.md +121 -0
- package/.agents/skills/modern-web-guidance/guides/forms/forms.md +372 -0
- package/.agents/skills/modern-web-guidance/guides/forms/required-field-feedback.md +214 -0
- package/.agents/skills/modern-web-guidance/guides/forms/rich-media-picker.md +132 -0
- package/.agents/skills/modern-web-guidance/guides/forms/select-menu-interaction.md +180 -0
- package/.agents/skills/modern-web-guidance/guides/forms/validate-input-after-interaction.md +258 -0
- package/.agents/skills/modern-web-guidance/guides/html/html.md +407 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-authentication.md +205 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-conditional-create.md +134 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-management.md +211 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-reauthentication.md +128 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-registration.md +181 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkeys.md +38 -0
- package/.agents/skills/modern-web-guidance/guides/performance/batch-analytics-events.md +154 -0
- package/.agents/skills/modern-web-guidance/guides/performance/break-up-long-tasks.md +60 -0
- package/.agents/skills/modern-web-guidance/guides/performance/calculate-total-foreground-time.md +69 -0
- package/.agents/skills/modern-web-guidance/guides/performance/conditional-async-dependencies.md +71 -0
- package/.agents/skills/modern-web-guidance/guides/performance/defer-rendering-heavy-content.md +106 -0
- package/.agents/skills/modern-web-guidance/guides/performance/defer-work-until-scroll-ends.md +78 -0
- package/.agents/skills/modern-web-guidance/guides/performance/deprioritize-background-fetches.md +37 -0
- package/.agents/skills/modern-web-guidance/guides/performance/detect-initial-visibility-state.md +99 -0
- package/.agents/skills/modern-web-guidance/guides/performance/efficient-background-processing.md +117 -0
- package/.agents/skills/modern-web-guidance/guides/performance/faster-spa-view-transitions.md +79 -0
- package/.agents/skills/modern-web-guidance/guides/performance/full-session-analytics.md +135 -0
- package/.agents/skills/modern-web-guidance/guides/performance/identify-heavy-scripts.md +69 -0
- package/.agents/skills/modern-web-guidance/guides/performance/identify-inp-causes.md +73 -0
- package/.agents/skills/modern-web-guidance/guides/performance/improve-next-page-load-performance.md +119 -0
- package/.agents/skills/modern-web-guidance/guides/performance/interactions-in-complex-layouts.md +78 -0
- package/.agents/skills/modern-web-guidance/guides/performance/optimize-image-priority.md +61 -0
- package/.agents/skills/modern-web-guidance/guides/performance/optimize-preload-priority.md +41 -0
- package/.agents/skills/modern-web-guidance/guides/performance/optimize-script-priority.md +38 -0
- package/.agents/skills/modern-web-guidance/guides/performance/performance.md +366 -0
- package/.agents/skills/modern-web-guidance/guides/performance/resolution-optimized-pseudo-elements.md +47 -0
- package/.agents/skills/modern-web-guidance/guides/performance/schedule-tasks-by-priority.md +59 -0
- package/.agents/skills/modern-web-guidance/guides/performance/sequence-distributed-events.md +76 -0
- package/.agents/skills/modern-web-guidance/guides/privacy/privacy.md +247 -0
- package/.agents/skills/modern-web-guidance/guides/security/security.md +350 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/adapt-scrollbar-to-contrast-preferences.md +74 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/anchor-positioning-tab-underline.md +95 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/animate-element-entry-exit.md +131 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/animate-to-from-top-layer.md +140 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/animate-to-intrinsic-sizes.md +127 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/apply-webgl-shaders.md +239 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/calculate-event-differentials.md +85 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/calculate-with-intrinsic-sizes.md +196 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/capture-location-agnostic-data.md +63 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/carousel-slide-effects.md +187 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/carousel-snap-highlights.md +136 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/child-state-based-styling.md +101 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/complex-shapes.md +73 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/component-specific-light-dark-theme.md +179 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/consistent-cross-document-transitions.md +226 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/content-based-styling.md +118 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/coordinate-global-events.md +79 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/cross-document-transitions.md +127 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/custom-button-actions.md +173 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/customize-scrollbar-color-and-thickness.md +59 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/dark-mode.md +295 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/declarative-dialog-popover-control.md +238 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/deliver-optimized-decorative-images.md +49 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/design-token-reactivity.md +174 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/directional-navigation-transitions.md +125 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/dynamic-sibling-animations.md +54 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/dynamic-sibling-styling.md +98 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/export-html-media-from-canvas.md +256 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/expose-canvas-content-to-browser-features.md +401 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/flicker-free-client-side-ab-testing.md +168 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/fluid-scaling.md +78 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/format-human-readable-durations.md +87 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/group-element-transitions.md +124 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/improve-text-layout-and-legibility.md +76 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/individual-transform-properties.md +92 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/interactive-content-in-3d-scenes.md +383 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/interactive-content-reveal.md +118 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/interest-triggered-action-previews.md +79 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/interest-triggered-tooltips.md +132 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/light-dismiss-a-dialog.md +84 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/manage-recurring-intervals.md +73 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/model-partial-time-concepts.md +96 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/move-dom-element-without-losing-state.md +57 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/navigation-drawer.md +357 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/overflow-clipping-control.md +180 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/parallax-scroll-effects.md +230 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/persistent-app-tours.md +112 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/persistent-toast-notifications.md +30 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/persistent-top-layer-ui.md +48 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/physics-based-easing.md +118 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/platform-controls-dismiss-dialog.md +38 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/position-aware-tooltips.md +154 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/precise-text-alignment.md +99 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/prevent-text-wrapping.md +62 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/pull-to-reveal.md +83 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/reduce-style-repetition.md +87 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/resilient-context-menus-and-nested-dropdowns.md +102 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/same-document-transitions.md +177 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-entry-exit-effects.md +173 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-position-aware-elements.md +128 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-progress-indicator.md +133 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-snap-realtime-feedback.md +153 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-snap-state-sync.md +93 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-target-on-load.md +56 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scrollability-affordance-hints.md +124 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scrollytelling.md +181 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/search-hidden-content.md +136 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/shaped-cutouts.md +146 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/shrinking-header-on-scroll.md +126 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/size-aware-styling.md +104 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/soft-edge-content-fade.md +62 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/stabilize-reactive-state.md +72 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/stack-drill-down.md +680 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/style-parent-with-has.md +199 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/support-global-calendar-systems.md +107 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/swipe-to-remove.md +527 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/visually-stable-font-fallbacks.md +49 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/visually-stable-mixed-fonts.md +61 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/visually-texture-content.md +76 -0
- package/.agents/skills/modern-web-guidance/guides/webmcp/agentic-forms.md +116 -0
- package/.agents/skills/modern-web-guidance/guides/webmcp/agentic-javascript-tools.md +116 -0
- package/.agents/skills/modern-web-guidance/guides/webmcp/webmcp.md +43 -0
- package/.agents/skills/nextjs-app-router-patterns/SKILL.md +114 -0
- package/.agents/skills/nextjs-app-router-patterns/references/details.md +428 -0
- package/.agents/skills/nextjs-developer/SKILL.md +145 -0
- package/.agents/skills/nextjs-developer/references/app-router.md +311 -0
- package/.agents/skills/nextjs-developer/references/data-fetching.md +482 -0
- package/.agents/skills/nextjs-developer/references/deployment.md +545 -0
- package/.agents/skills/nextjs-developer/references/server-actions.md +462 -0
- package/.agents/skills/nextjs-developer/references/server-components.md +384 -0
- package/.agents/skills/nextjs-supabase-auth/SKILL.md +313 -0
- package/.agents/skills/nodejs-backend-patterns/SKILL.md +45 -0
- package/.agents/skills/nodejs-backend-patterns/references/advanced-patterns.md +430 -0
- package/.agents/skills/nodejs-backend-patterns/references/details.md +599 -0
- package/.agents/skills/performance-engineer/SKILL.md +181 -0
- package/.agents/skills/project-requirements/SKILL.md +43 -0
- package/.agents/skills/qa/SKILL.md +130 -0
- package/.agents/skills/security-review/LICENSE +22 -0
- package/.agents/skills/security-review/SKILL.md +312 -0
- package/.agents/skills/security-review/infrastructure/docker.md +432 -0
- package/.agents/skills/security-review/languages/javascript.md +387 -0
- package/.agents/skills/security-review/languages/python.md +363 -0
- package/.agents/skills/security-review/references/api-security.md +519 -0
- package/.agents/skills/security-review/references/authentication.md +353 -0
- package/.agents/skills/security-review/references/authorization.md +372 -0
- package/.agents/skills/security-review/references/business-logic.md +443 -0
- package/.agents/skills/security-review/references/cryptography.md +329 -0
- package/.agents/skills/security-review/references/csrf.md +398 -0
- package/.agents/skills/security-review/references/data-protection.md +378 -0
- package/.agents/skills/security-review/references/deserialization.md +410 -0
- package/.agents/skills/security-review/references/error-handling.md +436 -0
- package/.agents/skills/security-review/references/file-security.md +457 -0
- package/.agents/skills/security-review/references/injection.md +259 -0
- package/.agents/skills/security-review/references/logging.md +433 -0
- package/.agents/skills/security-review/references/misconfiguration.md +435 -0
- package/.agents/skills/security-review/references/modern-threats.md +475 -0
- package/.agents/skills/security-review/references/ssrf.md +413 -0
- package/.agents/skills/security-review/references/supply-chain.md +405 -0
- package/.agents/skills/security-review/references/xss.md +336 -0
- package/.agents/skills/seo-aeo-best-practices/SKILL.md +37 -0
- package/.agents/skills/seo-aeo-best-practices/references/aeo-considerations.md +159 -0
- package/.agents/skills/seo-aeo-best-practices/references/eeat-principles.md +127 -0
- package/.agents/skills/seo-aeo-best-practices/references/structured-data.md +183 -0
- package/.agents/skills/seo-aeo-best-practices/references/technical-seo.md +188 -0
- package/.agents/skills/seo-geo/.claude-plugin/plugin.json +29 -0
- package/.agents/skills/seo-geo/SKILL.md +250 -0
- package/.agents/skills/seo-geo/examples/opc-skills-case-study.md +330 -0
- package/.agents/skills/seo-geo/references/geo-research.md +319 -0
- package/.agents/skills/seo-geo/references/google-docs-summary.md +65 -0
- package/.agents/skills/seo-geo/references/platform-algorithms.md +354 -0
- package/.agents/skills/seo-geo/references/schema-templates.md +517 -0
- package/.agents/skills/seo-geo/references/seo-checklist.md +249 -0
- package/.agents/skills/seo-geo/references/tools-and-apis.md +313 -0
- package/.agents/skills/seo-geo/scripts/autocomplete_ideas.py +74 -0
- package/.agents/skills/seo-geo/scripts/backlinks.py +37 -0
- package/.agents/skills/seo-geo/scripts/competitor_gap.py +80 -0
- package/.agents/skills/seo-geo/scripts/credential.py +12 -0
- package/.agents/skills/seo-geo/scripts/dataforseo_api.py +104 -0
- package/.agents/skills/seo-geo/scripts/domain_overview.py +44 -0
- package/.agents/skills/seo-geo/scripts/keyword_research.py +38 -0
- package/.agents/skills/seo-geo/scripts/related_keywords.py +84 -0
- package/.agents/skills/seo-geo/scripts/seo_audit.py +151 -0
- package/.agents/skills/seo-geo/scripts/serp_analysis.py +41 -0
- package/.agents/skills/shadcn-ui/README.md +248 -0
- package/.agents/skills/shadcn-ui/SKILL.md +326 -0
- package/.agents/skills/shadcn-ui/examples/auth-layout.tsx +177 -0
- package/.agents/skills/shadcn-ui/examples/data-table.tsx +313 -0
- package/.agents/skills/shadcn-ui/examples/form-pattern.tsx +177 -0
- package/.agents/skills/shadcn-ui/resources/component-catalog.md +481 -0
- package/.agents/skills/shadcn-ui/resources/customization-guide.md +516 -0
- package/.agents/skills/shadcn-ui/resources/migration-guide.md +463 -0
- package/.agents/skills/shadcn-ui/resources/setup-guide.md +412 -0
- package/.agents/skills/shadcn-ui/scripts/verify-setup.sh +134 -0
- package/.agents/skills/skill-creator/LICENSE.txt +202 -0
- package/.agents/skills/skill-creator/SKILL.md +485 -0
- package/.agents/skills/skill-creator/agents/analyzer.md +274 -0
- package/.agents/skills/skill-creator/agents/comparator.md +202 -0
- package/.agents/skills/skill-creator/agents/grader.md +223 -0
- package/.agents/skills/skill-creator/assets/eval_review.html +146 -0
- package/.agents/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.agents/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.agents/skills/skill-creator/references/schemas.md +430 -0
- package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
- package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.agents/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.agents/skills/skill-creator/scripts/improve_description.py +247 -0
- package/.agents/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.agents/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.agents/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.agents/skills/skill-creator/scripts/run_loop.py +328 -0
- package/.agents/skills/skill-creator/scripts/utils.py +47 -0
- package/.agents/skills/stacks/SKILL.md +21 -0
- package/.agents/skills/stacks/django.md +187 -0
- package/.agents/skills/stacks/express.md +16 -0
- package/.agents/skills/stacks/fastapi.md +17 -0
- package/.agents/skills/stacks/laravel.md +18 -0
- package/.agents/skills/stacks/nextjs.md +20 -0
- package/.agents/skills/stacks/react-native.md +170 -0
- package/.agents/skills/supabase/CHANGELOG.md +35 -0
- package/.agents/skills/supabase/SKILL.md +135 -0
- package/.agents/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/.agents/skills/supabase/references/skill-feedback.md +17 -0
- package/.agents/skills/supabase-postgres-best-practices/CHANGELOG.md +29 -0
- package/.agents/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/.agents/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/.agents/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/.agents/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/.agents/skills/task-contract/SKILL.md +29 -0
- package/.agents/skills/token-optimization/SKILL.md +40 -0
- package/.agents/skills/ui-designer/SKILL.md +76 -0
- package/.agents/skills/ui-ux-pro-max/SKILL.md +704 -0
- package/.agents/skills/ui-ux-pro-max/data/_sync_all.py +414 -0
- package/.agents/skills/ui-ux-pro-max/data/app-interface.csv +31 -0
- package/.agents/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agents/skills/ui-ux-pro-max/data/colors.csv +162 -0
- package/.agents/skills/ui-ux-pro-max/data/design.csv +1776 -0
- package/.agents/skills/ui-ux-pro-max/data/draft.csv +1779 -0
- package/.agents/skills/ui-ux-pro-max/data/google-fonts.csv +1924 -0
- package/.agents/skills/ui-ux-pro-max/data/icons.csv +106 -0
- package/.agents/skills/ui-ux-pro-max/data/landing.csv +35 -0
- package/.agents/skills/ui-ux-pro-max/data/motion.csv +17 -0
- package/.agents/skills/ui-ux-pro-max/data/products.csv +162 -0
- package/.agents/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/angular.csv +51 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/laravel.csv +51 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/threejs.csv +54 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agents/skills/ui-ux-pro-max/data/styles.csv +85 -0
- package/.agents/skills/ui-ux-pro-max/data/typography.csv +74 -0
- package/.agents/skills/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
- package/.agents/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agents/skills/ui-ux-pro-max/scripts/core.py +274 -0
- package/.agents/skills/ui-ux-pro-max/scripts/design_system.py +1329 -0
- package/.agents/skills/ui-ux-pro-max/scripts/search.py +127 -0
- package/.agents/skills/vercel-cli-with-tokens/SKILL.md +353 -0
- package/.agents/skills/vercel-composition-patterns/AGENTS.md +946 -0
- package/.agents/skills/vercel-composition-patterns/README.md +60 -0
- package/.agents/skills/vercel-composition-patterns/SKILL.md +89 -0
- package/.agents/skills/vercel-composition-patterns/metadata.json +11 -0
- package/.agents/skills/vercel-composition-patterns/rules/_sections.md +29 -0
- package/.agents/skills/vercel-composition-patterns/rules/_template.md +24 -0
- package/.agents/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/.agents/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
- package/.agents/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/.agents/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/.agents/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/.agents/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/.agents/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/.agents/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
- package/.agents/skills/vercel-optimize/AGENTS.md +48 -0
- package/.agents/skills/vercel-optimize/CONTRIBUTING.md +41 -0
- package/.agents/skills/vercel-optimize/README.md +91 -0
- package/.agents/skills/vercel-optimize/SKILL.md +322 -0
- package/.agents/skills/vercel-optimize/lib/auth-route.mjs +23 -0
- package/.agents/skills/vercel-optimize/lib/budget-summary.mjs +182 -0
- package/.agents/skills/vercel-optimize/lib/citations.mjs +139 -0
- package/.agents/skills/vercel-optimize/lib/cost-coverage.mjs +143 -0
- package/.agents/skills/vercel-optimize/lib/dedup-recs.mjs +325 -0
- package/.agents/skills/vercel-optimize/lib/deep-dive.mjs +350 -0
- package/.agents/skills/vercel-optimize/lib/display-labels.mjs +185 -0
- package/.agents/skills/vercel-optimize/lib/extract-claims.mjs +550 -0
- package/.agents/skills/vercel-optimize/lib/framework-support.mjs +67 -0
- package/.agents/skills/vercel-optimize/lib/gates/build-minutes-fanout.mjs +69 -0
- package/.agents/skills/vercel-optimize/lib/gates/cold-start.mjs +66 -0
- package/.agents/skills/vercel-optimize/lib/gates/contract.mjs +79 -0
- package/.agents/skills/vercel-optimize/lib/gates/cwv-poor.mjs +87 -0
- package/.agents/skills/vercel-optimize/lib/gates/external-api-slow.mjs +55 -0
- package/.agents/skills/vercel-optimize/lib/gates/hard-gates.mjs +73 -0
- package/.agents/skills/vercel-optimize/lib/gates/index.mjs +45 -0
- package/.agents/skills/vercel-optimize/lib/gates/isr-overrevalidation.mjs +62 -0
- package/.agents/skills/vercel-optimize/lib/gates/middleware-heavy.mjs +51 -0
- package/.agents/skills/vercel-optimize/lib/gates/observability-events-attribution.mjs +56 -0
- package/.agents/skills/vercel-optimize/lib/gates/platform-bot-protection.mjs +115 -0
- package/.agents/skills/vercel-optimize/lib/gates/platform-fluid-compute.mjs +83 -0
- package/.agents/skills/vercel-optimize/lib/gates/region-misconfig.mjs +64 -0
- package/.agents/skills/vercel-optimize/lib/gates/route-errors.mjs +80 -0
- package/.agents/skills/vercel-optimize/lib/gates/scanner-driven.mjs +122 -0
- package/.agents/skills/vercel-optimize/lib/gates/select-candidates.mjs +134 -0
- package/.agents/skills/vercel-optimize/lib/gates/slow-route.mjs +88 -0
- package/.agents/skills/vercel-optimize/lib/gates/types.d.ts +38 -0
- package/.agents/skills/vercel-optimize/lib/gates/uncached-route.mjs +93 -0
- package/.agents/skills/vercel-optimize/lib/gates/usage-spike-triage.mjs +121 -0
- package/.agents/skills/vercel-optimize/lib/grade-recommendation.mjs +155 -0
- package/.agents/skills/vercel-optimize/lib/impact-label.mjs +126 -0
- package/.agents/skills/vercel-optimize/lib/impact-magnitude.mjs +60 -0
- package/.agents/skills/vercel-optimize/lib/investigation-brief.mjs +610 -0
- package/.agents/skills/vercel-optimize/lib/observation-safety.mjs +174 -0
- package/.agents/skills/vercel-optimize/lib/project-facts.mjs +99 -0
- package/.agents/skills/vercel-optimize/lib/queries.mjs +315 -0
- package/.agents/skills/vercel-optimize/lib/reconcile-candidates.mjs +372 -0
- package/.agents/skills/vercel-optimize/lib/render-report.mjs +955 -0
- package/.agents/skills/vercel-optimize/lib/repo-root.mjs +86 -0
- package/.agents/skills/vercel-optimize/lib/route-normalize.mjs +220 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/bot-protection-certainty.mjs +38 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/cache-tag-invalidation-certainty.mjs +30 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/count-correct.mjs +52 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/function-duration-invocations.mjs +38 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/index.mjs +79 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/middleware-conflict.mjs +36 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/missing-citation.mjs +16 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/pre-release.mjs +74 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/rate-limit.mjs +67 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/rendering-mode-mislabel.mjs +38 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/undeclared-dep.mjs +78 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/vercel-directive-strip.mjs +37 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/window-units.mjs +32 -0
- package/.agents/skills/vercel-optimize/lib/scanners/cache-components-suspense-dedupe.mjs +109 -0
- package/.agents/skills/vercel-optimize/lib/scanners/edge-heavy-import.mjs +94 -0
- package/.agents/skills/vercel-optimize/lib/scanners/force-dynamic.mjs +42 -0
- package/.agents/skills/vercel-optimize/lib/scanners/headers-in-page.mjs +44 -0
- package/.agents/skills/vercel-optimize/lib/scanners/index.mjs +35 -0
- package/.agents/skills/vercel-optimize/lib/scanners/large-static-asset.mjs +92 -0
- package/.agents/skills/vercel-optimize/lib/scanners/max-age-without-s-maxage.mjs +42 -0
- package/.agents/skills/vercel-optimize/lib/scanners/middleware-broad-matcher.mjs +55 -0
- package/.agents/skills/vercel-optimize/lib/scanners/missing-cache-headers.mjs +90 -0
- package/.agents/skills/vercel-optimize/lib/scanners/prisma-include-tree.mjs +42 -0
- package/.agents/skills/vercel-optimize/lib/scanners/region-pin-in-config.mjs +88 -0
- package/.agents/skills/vercel-optimize/lib/scanners/source-maps-production.mjs +36 -0
- package/.agents/skills/vercel-optimize/lib/scanners/sveltekit-prerender-missing.mjs +43 -0
- package/.agents/skills/vercel-optimize/lib/scanners/turbo-force-bypass.mjs +129 -0
- package/.agents/skills/vercel-optimize/lib/scanners/unoptimized-image.mjs +113 -0
- package/.agents/skills/vercel-optimize/lib/scanners/use-cache-date-stamp.mjs +106 -0
- package/.agents/skills/vercel-optimize/lib/support-topics.mjs +355 -0
- package/.agents/skills/vercel-optimize/lib/throttle.mjs +273 -0
- package/.agents/skills/vercel-optimize/lib/util.mjs +17 -0
- package/.agents/skills/vercel-optimize/lib/vercel.mjs +864 -0
- package/.agents/skills/vercel-optimize/lib/verify-claim.mjs +1296 -0
- package/.agents/skills/vercel-optimize/lib/workspace-resolver.mjs +521 -0
- package/.agents/skills/vercel-optimize/metadata.json +14 -0
- package/.agents/skills/vercel-optimize/references/candidates.md +176 -0
- package/.agents/skills/vercel-optimize/references/data-collection.md +218 -0
- package/.agents/skills/vercel-optimize/references/docs-library.json +683 -0
- package/.agents/skills/vercel-optimize/references/doctrine.md +105 -0
- package/.agents/skills/vercel-optimize/references/observability-plus.md +108 -0
- package/.agents/skills/vercel-optimize/references/playbooks/README.md +53 -0
- package/.agents/skills/vercel-optimize/references/playbooks/ai-application.md +32 -0
- package/.agents/skills/vercel-optimize/references/playbooks/api-service.md +30 -0
- package/.agents/skills/vercel-optimize/references/playbooks/content-site.md +30 -0
- package/.agents/skills/vercel-optimize/references/playbooks/ecommerce.md +30 -0
- package/.agents/skills/vercel-optimize/references/playbooks/marketing.md +30 -0
- package/.agents/skills/vercel-optimize/references/playbooks/saas.md +31 -0
- package/.agents/skills/vercel-optimize/references/playbooks/sveltekit.md +75 -0
- package/.agents/skills/vercel-optimize/references/recommendations.md +203 -0
- package/.agents/skills/vercel-optimize/references/scanner-patterns.md +251 -0
- package/.agents/skills/vercel-optimize/references/scoring.md +205 -0
- package/.agents/skills/vercel-optimize/references/support-topics/README.md +46 -0
- package/.agents/skills/vercel-optimize/references/support-topics/astro-edge-middleware-scope.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/astro-output-mode-and-isr.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/auth-preserving-parallelization.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/bot-protection-product-guardrails.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/build-minutes-monorepo-fanout.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/cache-components-static-shell-boundaries.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/cache-components-suspense-dedupe-pitfall.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/cdn-cache-auth-safety.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/cold-start-initialization-bundle.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/core-web-vitals-client-bottlenecks.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/database-egress-pooling-region.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/dynamic-rendering-traps.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/external-api-critical-path-platform.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/external-api-critical-path.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/fast-data-transfer-payloads.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/fluid-compute-caveats.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/function-duration-io-and-after.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/function-invocation-reduction.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/function-region-misconfiguration-ttfb.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/image-optimization-cost-control.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/isr-revalidation-static-generation.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/middleware-proxy-edge-cost.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-fetch-revalidate-floor.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-font-cls-self-hosting.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-heavy-ui-lazy-load-boundaries.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-image-lcp-preload-sizes.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-route-handler-get-cache-defaults.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-script-third-party-strategy.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/nextjs-version-cache-semantics.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/not-found-catchall-request-waste.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/nuxt-route-rules-cache-isr.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/observability-events-cost-attribution.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/post-response-work-waituntil.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/route-error-durable-offload.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/route-error-runtime-limits.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/runtime-cache-reusable-data.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/sveltekit-isr-prerender-safety.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/sveltekit-split-cold-start-tradeoff.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/usage-spike-triage.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/use-cache-date-stamp-isr-write-amplifier.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/use-cache-remote-shared-origin-data.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/workflow-resumable-stream-routes.md +23 -0
- package/.agents/skills/vercel-optimize/references/verification.md +102 -0
- package/.agents/skills/vercel-optimize/references/voice.md +76 -0
- package/.agents/skills/vercel-optimize/scripts/budget-summary.mjs +56 -0
- package/.agents/skills/vercel-optimize/scripts/build-docs.mjs +74 -0
- package/.agents/skills/vercel-optimize/scripts/check-citations.mjs +81 -0
- package/.agents/skills/vercel-optimize/scripts/check-docs-fresh.mjs +93 -0
- package/.agents/skills/vercel-optimize/scripts/collect-signals.mjs +576 -0
- package/.agents/skills/vercel-optimize/scripts/collect-sub-agent-outputs.mjs +296 -0
- package/.agents/skills/vercel-optimize/scripts/deep-dive.mjs +319 -0
- package/.agents/skills/vercel-optimize/scripts/gate-investigations.mjs +166 -0
- package/.agents/skills/vercel-optimize/scripts/merge-signals.mjs +192 -0
- package/.agents/skills/vercel-optimize/scripts/prepare-investigation-brief.mjs +231 -0
- package/.agents/skills/vercel-optimize/scripts/reconcile-candidates.mjs +62 -0
- package/.agents/skills/vercel-optimize/scripts/render-report.mjs +437 -0
- package/.agents/skills/vercel-optimize/scripts/scan-codebase.mjs +313 -0
- package/.agents/skills/vercel-optimize/scripts/verify-and-regen.mjs +346 -0
- package/.agents/skills/vercel-optimize/scripts/verify-finding.mjs +19 -0
- package/.agents/skills/vercel-react-best-practices/AGENTS.md +3810 -0
- package/.agents/skills/vercel-react-best-practices/README.md +123 -0
- package/.agents/skills/vercel-react-best-practices/SKILL.md +149 -0
- package/.agents/skills/vercel-react-best-practices/metadata.json +15 -0
- package/.agents/skills/vercel-react-best-practices/rules/_sections.md +46 -0
- package/.agents/skills/vercel-react-best-practices/rules/_template.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md +56 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md +63 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/.agents/skills/vercel-react-native-skills/AGENTS.md +2897 -0
- package/.agents/skills/vercel-react-native-skills/README.md +165 -0
- package/.agents/skills/vercel-react-native-skills/SKILL.md +121 -0
- package/.agents/skills/vercel-react-native-skills/metadata.json +16 -0
- package/.agents/skills/vercel-react-native-skills/rules/_sections.md +86 -0
- package/.agents/skills/vercel-react-native-skills/rules/_template.md +28 -0
- package/.agents/skills/vercel-react-native-skills/rules/animation-derived-value.md +53 -0
- package/.agents/skills/vercel-react-native-skills/rules/animation-gesture-detector-press.md +95 -0
- package/.agents/skills/vercel-react-native-skills/rules/animation-gpu-properties.md +65 -0
- package/.agents/skills/vercel-react-native-skills/rules/design-system-compound-components.md +66 -0
- package/.agents/skills/vercel-react-native-skills/rules/fonts-config-plugin.md +71 -0
- package/.agents/skills/vercel-react-native-skills/rules/imports-design-system-folder.md +68 -0
- package/.agents/skills/vercel-react-native-skills/rules/js-hoist-intl.md +61 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-callbacks.md +44 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-function-references.md +132 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-images.md +53 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-inline-objects.md +97 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-item-expensive.md +94 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-item-memo.md +82 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-item-types.md +104 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-virtualize.md +67 -0
- package/.agents/skills/vercel-react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
- package/.agents/skills/vercel-react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
- package/.agents/skills/vercel-react-native-skills/rules/navigation-native-navigators.md +188 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-state-dispatcher.md +91 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-state-fallback.md +56 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-state-minimize.md +65 -0
- package/.agents/skills/vercel-react-native-skills/rules/rendering-no-falsy-and.md +74 -0
- package/.agents/skills/vercel-react-native-skills/rules/rendering-text-in-text-component.md +36 -0
- package/.agents/skills/vercel-react-native-skills/rules/scroll-position-no-state.md +82 -0
- package/.agents/skills/vercel-react-native-skills/rules/state-ground-truth.md +80 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-expo-image.md +66 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-image-gallery.md +104 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-measure-views.md +78 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-menus.md +174 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-native-modals.md +77 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-pressable.md +61 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-safe-area-scroll.md +65 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-styling.md +87 -0
- package/.agents/skills/vercel-react-view-transitions/AGENTS.md +955 -0
- package/.agents/skills/vercel-react-view-transitions/README.md +42 -0
- package/.agents/skills/vercel-react-view-transitions/SKILL.md +320 -0
- package/.agents/skills/vercel-react-view-transitions/metadata.json +12 -0
- package/.agents/skills/vercel-react-view-transitions/references/css-recipes.md +242 -0
- package/.agents/skills/vercel-react-view-transitions/references/implementation.md +182 -0
- package/.agents/skills/vercel-react-view-transitions/references/nextjs.md +176 -0
- package/.agents/skills/vercel-react-view-transitions/references/patterns.md +262 -0
- package/.agents/skills/web-design-guidelines/SKILL.md +39 -0
- package/.agents/skills/workflow-metrics/SKILL.md +18 -0
- package/.agents/skills/writing-guidelines/SKILL.md +39 -0
- package/CODING_STANDARDS.md +49 -0
- package/LICENSE +21 -0
- package/README.md +556 -0
- package/VERSION +1 -0
- package/bin/devos.js +893 -0
- package/docs/.gitkeep +0 -0
- package/docs/ARCHITECTURE.md +114 -0
- package/docs/CHANGELOG.md +61 -0
- package/docs/CURRENT_STATE.md +39 -0
- package/docs/FIELD_REPORT_2026-08-20.md +130 -0
- package/docs/GETTING_STARTED.md +130 -0
- package/docs/LESSONS.md +24 -0
- package/docs/PRE_COMMIT_HOOK.md +152 -0
- package/docs/SLASH_COMMANDS.md +116 -0
- package/docs/TUTORIAL.md +75 -0
- package/package.json +54 -0
- package/scripts/smoke-test.js +167 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Passkey Conditional Create (Post-Login Promotion)
|
|
2
|
+
|
|
3
|
+
This guide details how to automatically and silently register a passkey for a user immediately after a successful password-based sign-in, minimizing friction and boosting passkey adoption.
|
|
4
|
+
|
|
5
|
+
## The Right Trigger Moment
|
|
6
|
+
|
|
7
|
+
Automatic passkey creation (also known as Conditional Create or silent post-login promotion) MUST only be triggered **immediately after a successful, full sign-in that involved a password**.
|
|
8
|
+
* Do not attempt conditional creation for passwordless flows (e.g., magic links, SMS OTP, or identity federation).
|
|
9
|
+
* If multi-factor authentication is required, you MUST wait until all factors have succeeded before initiating conditional creation.
|
|
10
|
+
* Ensure a valid, authenticated user session is active before making requests to creation endpoints.
|
|
11
|
+
|
|
12
|
+
## Implementation Steps
|
|
13
|
+
|
|
14
|
+
### 1. Abort Prior Autofill Actions
|
|
15
|
+
If the sign-in page utilizes form autofill (Conditional UI/Get), the active credential get call must be aborted to prevent browser conflicts.
|
|
16
|
+
* Call `abortController.abort()` on the `AbortController` attached to the pending `navigator.credentials.get()` autofill request before calling `navigator.credentials.create()`.
|
|
17
|
+
|
|
18
|
+
### 2. Feature Detection
|
|
19
|
+
Determine whether Conditional Create is available by checking `conditionalCreate` with `PublicKeyCredential.getClientCapabilities()`.
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
const capabilities = await PublicKeyCredential.getClientCapabilities();
|
|
23
|
+
if (capabilities.conditionalCreate) {
|
|
24
|
+
// Conditional create is available
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 3. Create a passkey with Conditional Create
|
|
29
|
+
* Pass `mediation: 'conditional'` within the `navigator.credentials.create()` options. This signals the browser to handle the passkey creation flow silently in the background or contextually without throwing obtrusive modal dialogs.
|
|
30
|
+
* Populate `excludeCredentials` with the user's existing passkey credential IDs to avoid registering duplicate keys.
|
|
31
|
+
|
|
32
|
+
### 4. Silent Error Handling
|
|
33
|
+
* Wrap the passkey creation prompt (`navigator.credentials.create`) in a try/catch block. You MUST catch and silently ignore typical user-facing exceptions (`InvalidStateError`, `NotAllowedError`, `AbortError`) without rendering any error UI to the user.
|
|
34
|
+
|
|
35
|
+
### 5. Server-Side User Presence Verification
|
|
36
|
+
* The server-side verification endpoint MUST relax the User Presence (UP) requirement (`requireUserPresence: false`) **ONLY** when verifying credentials produced by a conditional-create trigger. Strict presence verification must remain active for standard explicit creations.
|
|
37
|
+
|
|
38
|
+
### 6. Handle Failed Server Verification gracefully
|
|
39
|
+
* If `navigator.credentials.create()` succeeds but the server verification fetch returns a bad response (e.g., signature verification fails), invoke `PublicKeyCredential.signalUnknownCredential()` to prevent orphaned credentials from lingering in the passkey provider.
|
|
40
|
+
|
|
41
|
+
## Code Example
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
// optionsFetch and registerVerifyFetch are app-defined server endpoint requests
|
|
45
|
+
import { optionsFetch, registerVerifyFetch } from './api.js';
|
|
46
|
+
|
|
47
|
+
async function triggerConditionalCreate(loginAbortController) {
|
|
48
|
+
const capabilities = await PublicKeyCredential.getClientCapabilities();
|
|
49
|
+
if (capabilities.conditionalCreate !== true) {
|
|
50
|
+
return; // Platform does not support conditional creation
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 1. Abort any active autofill conditional-get controllers to clear the WebAuthn pipeline
|
|
54
|
+
loginAbortController.abort();
|
|
55
|
+
|
|
56
|
+
// 2. Fetch creation options signaling the backend that this is a conditional request
|
|
57
|
+
const creationOptionsJSON = await optionsFetch({ conditional: true });
|
|
58
|
+
const publicKey = PublicKeyCredential.parseCreationOptionsFromJSON(creationOptionsJSON);
|
|
59
|
+
|
|
60
|
+
let credential;
|
|
61
|
+
try {
|
|
62
|
+
// 3. Invoke silent credentials creation prompt
|
|
63
|
+
credential = await navigator.credentials.create({
|
|
64
|
+
publicKey,
|
|
65
|
+
mediation: 'conditional' // Silent background creation mediation
|
|
66
|
+
});
|
|
67
|
+
} catch (e) {
|
|
68
|
+
// 4. Silently swallow common WebAuthn browser exceptions
|
|
69
|
+
if (['InvalidStateError', 'NotAllowedError', 'AbortError'].includes(e.name)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
console.error('Unexpected conditional create error:', e);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 5. Server verification step using dedicated Try/Catch block
|
|
77
|
+
let encodedResponse = credential.toJSON();
|
|
78
|
+
try {
|
|
79
|
+
const response = await registerVerifyFetch(encodedResponse);
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
// If the server verification fails, clean up using Signal API
|
|
82
|
+
if (PublicKeyCredential.signalUnknownCredential) {
|
|
83
|
+
await PublicKeyCredential.signalUnknownCredential({
|
|
84
|
+
rpId, // RP ID must match the one defined on the server
|
|
85
|
+
credentialId: encodedResponse.id
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} catch (serverErr) {
|
|
90
|
+
console.error('Verification network failure:', serverErr);
|
|
91
|
+
if (PublicKeyCredential.signalUnknownCredential) {
|
|
92
|
+
await PublicKeyCredential.signalUnknownCredential({
|
|
93
|
+
rpId, // RP ID must match the one defined on the server
|
|
94
|
+
credentialId: encodedResponse.id
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Fallback Strategies
|
|
102
|
+
|
|
103
|
+
### Passkey feature detection fallback
|
|
104
|
+
|
|
105
|
+
Baseline status for the api.PublicKeyCredential.getClientCapabilities_static capability: Newly available. It's been Baseline since 2025-02-06.
|
|
106
|
+
Supported by: Chrome 133 (Feb 2025), Edge 133 (Feb 2025), Firefox 135 (Feb 2025), and Safari 17.4 (Mar 2024).
|
|
107
|
+
|
|
108
|
+
Always install 'webauthn-polyfills' and import it in the context.
|
|
109
|
+
Consider as long as `PublicKeyCredential` is supported, `PublicKeyCredential.getClientCapabilities` is also supported.
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
import 'webauthn-polyfills';
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Signal API Synchronization Fallback
|
|
116
|
+
|
|
117
|
+
Web authentication signal methods has limited availability.
|
|
118
|
+
Supported by: Chrome 132 (Jan 2025), Edge 132 (Jan 2025), and Safari 26 (Sep 2025).
|
|
119
|
+
Unsupported in: Firefox.
|
|
120
|
+
|
|
121
|
+
The WebAuthn Signal API (`webauthn-signals`) is a progressive optimization used to keep password managers in sync with the server credential state.
|
|
122
|
+
* **Fallback Experience**: Gated via `if (PublicKeyCredential.signalUnknownCredential)`. If unsupported, the background verification sync is bypassed gracefully without throwing browser exceptions.
|
|
123
|
+
|
|
124
|
+
### Easy JSON Serialization Fallback
|
|
125
|
+
|
|
126
|
+
Baseline status for the api.PublicKeyCredential.parseCreationOptionsFromJSON_static capability: Newly available. It's been Baseline since 2025-03-31.
|
|
127
|
+
Supported by: Chrome 129 (Sep 2024), Edge 129 (Sep 2024), Firefox 119 (Oct 2023), and Safari 18.4 (Mar 2025).
|
|
128
|
+
|
|
129
|
+
Always install 'webauthn-polyfills' and import it in the context.
|
|
130
|
+
Consider as long as `PublicKeyCredential` is supported, `PublicKeyCredential.parseCreationOptionsFromJSON` and `PublicKeyCredential.prototype.toJSON` are also supported.
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
import 'webauthn-polyfills';
|
|
134
|
+
```
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Passkey Management Guide
|
|
2
|
+
|
|
3
|
+
This guide details how to enable users to view, rename, and delete their registered passkeys while keeping saved credentials perfectly synchronized between the server and the user's password managers using the Signal API.
|
|
4
|
+
|
|
5
|
+
## Server-Side Operations
|
|
6
|
+
|
|
7
|
+
Your backend database layer and endpoints MUST support common CRUD actions for registered credentials. Decoupled from framework-specific libraries, the server exposes endpoints to:
|
|
8
|
+
|
|
9
|
+
1. **List all user credentials**: Fetch all `StoredPasskeyCredential` records matching the signed-in user's ID.
|
|
10
|
+
2. **Update credential names**: Accept a new custom string name for a specific credential ID and persist the update.
|
|
11
|
+
3. **Delete credentials**: Remove a specific credential ID from the database.
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
// Node.js routing example for credential CRUD
|
|
15
|
+
router.get('/api/credentials', checkUserAuthenticated, async (req, res) => {
|
|
16
|
+
const list = await db.findCredentialsByUserId(req.user.id);
|
|
17
|
+
return res.json(list);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
router.put('/api/credential/:id', checkUserAuthenticated, async (req, res) => {
|
|
21
|
+
const { id } = req.params;
|
|
22
|
+
const { name } = req.body;
|
|
23
|
+
const cred = await db.findCredentialById(id);
|
|
24
|
+
if (!cred || cred.passkeyUserId !== req.user.id) {
|
|
25
|
+
return res.status(404).json({ error: 'Credential not found.' });
|
|
26
|
+
}
|
|
27
|
+
cred.name = name;
|
|
28
|
+
await db.saveCredential(cred);
|
|
29
|
+
return res.json(cred);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
router.delete('/api/credential/:id', checkUserAuthenticated, async (req, res) => {
|
|
33
|
+
const { id } = req.params;
|
|
34
|
+
const cred = await db.findCredentialById(id);
|
|
35
|
+
if (!cred || cred.passkeyUserId !== req.user.id) {
|
|
36
|
+
return res.status(404).json({ error: 'Credential not found.' });
|
|
37
|
+
}
|
|
38
|
+
await db.deleteCredential(id);
|
|
39
|
+
return res.json({ success: true });
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Client-Side Management UI
|
|
44
|
+
|
|
45
|
+
Render a dedicated settings panel allowing users to easily audit and manage their registered authentication options:
|
|
46
|
+
|
|
47
|
+
1. **Display saved list**: Fetch list from your endpoint and render individual credential rows. If the response is empty, render a helpful empty-state message (e.g., "No passkeys found").
|
|
48
|
+
2. **Map AAGUID Metadata**: For each passkey, lookup its `aaguid` property against your local registry to render its provider details. See [Determine the passkey provider from AAGUID](#aaguid) section for more details.
|
|
49
|
+
3. **Per-Item UI Requirements**: Every row inside the list container MUST render:
|
|
50
|
+
* **Provider Icon**: AAGUID-derived image or data URI.
|
|
51
|
+
* **Provider/Custom Name**: AAGUID-derived name or user-renamed string.
|
|
52
|
+
* **Registration Date**: The database-persisted raw epoch timestamp `registeredAt` formatted to a human-readable date for client display.
|
|
53
|
+
* **Last Used Date**: The database-persisted raw epoch timestamp `lastUsedAt` formatted to a human-readable date (if present) for client display.
|
|
54
|
+
* **Rename Button**: Triggers a rename text input modal.
|
|
55
|
+
* **Delete Button**: Triggers deletion.
|
|
56
|
+
4. **Conditional "Create Passkey" Button**:
|
|
57
|
+
* Offer a prominent "Create passkey" registration trigger button on the management page. Before rendering this UI element, the page MUST feature-detect capabilities using `PublicKeyCredential.getClientCapabilities()` to verify platform authenticator is supported. If passkeys are unsupported, hide this button and gracefully encourage standard MFA enrollments instead.
|
|
58
|
+
* Allow registering a security key by omitting `authenticatorSelection.authenticatorAttachment` on `navigator.credentials.create()` call.
|
|
59
|
+
|
|
60
|
+
## Signal API Synchronization
|
|
61
|
+
|
|
62
|
+
The Signal API lets the application communicate credential states to password managers, keeping the user's synced vaults and your backend database in lockstep.
|
|
63
|
+
|
|
64
|
+
* **Parameter Encoding Rule**:
|
|
65
|
+
* All `userId` and credential ID parameters passed to Signal API methods (`signalAllAcceptedCredentials`, `signalCurrentUserDetails`) MUST be **Base64URL-encoded strings**.
|
|
66
|
+
* **Initiating Page Load Sync**:
|
|
67
|
+
* The application MUST invoke `signalAllAcceptedCredentials()` automatically in a `DOMContentLoaded` page load event listener.
|
|
68
|
+
* **Management Updates Sync**:
|
|
69
|
+
* The application MUST invoke `signalAllAcceptedCredentials()` immediately within your delete credential click handler post-fetch.
|
|
70
|
+
* The application MUST invoke `signalCurrentUserDetails()` immediately within your username or display name rename click handler post-fetch.
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
// Client-side management synchronization ES module
|
|
74
|
+
import { listFetch, renameFetch, deleteFetch } from './api.js';
|
|
75
|
+
|
|
76
|
+
// Base64URL-encoded User ID string (illustration only)
|
|
77
|
+
const base64UrlUserId = "M2YPl-KGnA8";
|
|
78
|
+
|
|
79
|
+
async function syncAcceptedCredentials(currentCredentialsList) {
|
|
80
|
+
try {
|
|
81
|
+
const credentialIds = currentCredentialsList.map(c => c.id); // Map of Base64URL credential ID strings
|
|
82
|
+
|
|
83
|
+
await PublicKeyCredential.signalAllAcceptedCredentials({
|
|
84
|
+
rpId, // RP ID must match the one defined on the server
|
|
85
|
+
userId: base64UrlUserId, // User ID Base64URL-encoded string
|
|
86
|
+
allAcceptedCredentialIds: credentialIds
|
|
87
|
+
});
|
|
88
|
+
} catch (e) {
|
|
89
|
+
console.error('SignalAllAcceptedCredentials sync failure:', e);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function loadManagementPanel() {
|
|
94
|
+
const response = await listFetch();
|
|
95
|
+
const list = await response.json();
|
|
96
|
+
|
|
97
|
+
renderUI(list);
|
|
98
|
+
// Sync on page load
|
|
99
|
+
await syncAcceptedCredentials(list);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function performDelete(credentialId) {
|
|
103
|
+
const response = await deleteFetch(credentialId);
|
|
104
|
+
if (response.ok) {
|
|
105
|
+
const updatedResponse = await listFetch();
|
|
106
|
+
const updatedList = await updatedResponse.json();
|
|
107
|
+
|
|
108
|
+
renderUI(updatedList);
|
|
109
|
+
// Sync after deletion
|
|
110
|
+
await syncAcceptedCredentials(updatedList);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function performRename(rpId, userId, updatedName, updatedDisplayName) {
|
|
115
|
+
const response = await renameFetch({ name: updatedName, displayName: updatedDisplayName });
|
|
116
|
+
if (response.ok) {
|
|
117
|
+
try {
|
|
118
|
+
await PublicKeyCredential.signalCurrentUserDetails({
|
|
119
|
+
rpId, // RP ID must match the one defined on the server
|
|
120
|
+
userId, // Base64URL-encoded user ID
|
|
121
|
+
name: updatedName, // Updated username
|
|
122
|
+
displayName: updatedDisplayName // Updated display name
|
|
123
|
+
});
|
|
124
|
+
} catch (e) {
|
|
125
|
+
console.error('SignalCurrentUserDetails sync failure:', e);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Determine the passkey provider from AAGUID {: #aaguid }
|
|
132
|
+
|
|
133
|
+
An AAGUID (Authenticator Attestation Globally Unique Identifier) is a 128-bit identifier that represents the model of the authenticator, not a specific instance. It is included in the authenticator data during passkey registration and can be used to determine which passkey provider (e.g. Google Password Manager, iCloud Keychain, 1Password) created a credential.
|
|
134
|
+
|
|
135
|
+
AAGUID should only be used to help users with passkey management. It can be modified unless cryptographically attested, which platform passkeys currently don't support.
|
|
136
|
+
|
|
137
|
+
### 1. AAGUID Registry
|
|
138
|
+
|
|
139
|
+
A community-maintained JSON mapping of AAGUIDs to provider names and icons is available at:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
https://raw.githubusercontent.com/passkeydeveloper/passkey-authenticator-aaguids/refs/heads/main/combined_aaguid.json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Each entry has the following schema:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"<aaguid-uuid>": {
|
|
150
|
+
"name": "Provider Name",
|
|
151
|
+
"icon_light": "data:image/png;base64,...",
|
|
152
|
+
"icon_dark": "data:image/png;base64,..."
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 2. Using AAGUID After Registration
|
|
158
|
+
|
|
159
|
+
After verifying a registration response, read the `aaguid` from the registration result and look it up against the registry to populate the credential's `name` and `providerIcon`:
|
|
160
|
+
|
|
161
|
+
Before looking up the AAGUID in the registry, check if it equals `'00000000-0000-0000-0000-000000000000'`. If so, skip the registry lookup and set `name` to a fallback (e.g. device name from user-agent, or "Unknown passkey provider") and `providerIcon` to `undefined`. Only look up the registry for non-zeroed AAGUIDs.
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
import aaguids from './aaguids.json' with { type: 'json' };
|
|
165
|
+
|
|
166
|
+
const { aaguid } = registrationInfo;
|
|
167
|
+
if (aaguid === '00000000-0000-0000-0000-000000000000') {
|
|
168
|
+
// use the device name as the passkey provider based on
|
|
169
|
+
// the information derived from the user agent string,
|
|
170
|
+
// or just say "Unknown passkey provider"
|
|
171
|
+
} else {
|
|
172
|
+
const provider = aaguids[aaguid];
|
|
173
|
+
const credential = {
|
|
174
|
+
// ...other fields
|
|
175
|
+
aaguid,
|
|
176
|
+
name: provider?.name || 'Unknown passkey provider',
|
|
177
|
+
providerIcon: provider?.icon_light,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Fallback Strategies
|
|
183
|
+
|
|
184
|
+
### Passkey feature detection fallback
|
|
185
|
+
|
|
186
|
+
Baseline status for the api.PublicKeyCredential.getClientCapabilities_static capability: Newly available. It's been Baseline since 2025-02-06.
|
|
187
|
+
Supported by: Chrome 133 (Feb 2025), Edge 133 (Feb 2025), Firefox 135 (Feb 2025), and Safari 17.4 (Mar 2024).
|
|
188
|
+
|
|
189
|
+
Always install 'webauthn-polyfills' and import it in the context.
|
|
190
|
+
Consider as long as `PublicKeyCredential` is supported, `PublicKeyCredential.getClientCapabilities` is also supported.
|
|
191
|
+
|
|
192
|
+
```js
|
|
193
|
+
import 'webauthn-polyfills';
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Signal API Synchronization Fallback
|
|
197
|
+
|
|
198
|
+
Web authentication signal methods has limited availability.
|
|
199
|
+
Supported by: Chrome 132 (Jan 2025), Edge 132 (Jan 2025), and Safari 26 (Sep 2025).
|
|
200
|
+
Unsupported in: Firefox.
|
|
201
|
+
If the browser does not support `PublicKeyCredential.parseRequestOptionsFromJSON`, use the 'webauthn-polyfills':
|
|
202
|
+
|
|
203
|
+
```html
|
|
204
|
+
<script type="module">
|
|
205
|
+
if (!PublicKeyCredential.parseRequestOptionsFromJSON) {
|
|
206
|
+
await import('https://unpkg.com/webauthn-polyfills');
|
|
207
|
+
}
|
|
208
|
+
</script>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
This will also add support for `PublicKeyCredential.prototype.toJSON`.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Passkey Reauthentication Guide
|
|
2
|
+
|
|
3
|
+
This delta-focused guide details how to implement step-up authentication or re-verification for a signed-in user before they perform sensitive account changes (e.g. passwords updates, financial transfers).
|
|
4
|
+
|
|
5
|
+
## Delta Flow Architecture
|
|
6
|
+
|
|
7
|
+
Unlike regular authentication, passkey reauthentication constrains passkey dialog prompts strictly to the logged-in user's pre-registered credentials to prevent account-mixing or passkey spoofing during active sessions.
|
|
8
|
+
|
|
9
|
+
## Server-Side
|
|
10
|
+
|
|
11
|
+
### Options Generation Delta
|
|
12
|
+
|
|
13
|
+
Create an endpoint that populates the allowed credentials parameters specifically for the active, known user:
|
|
14
|
+
|
|
15
|
+
**Constrain Credentials**: Populate the `allowCredentials` options array with specific `PublicKeyCredentialDescriptor` records mapping all registered credential IDs for the signed-in user. Leaving this empty or omitting it regresses to discoverable credentials, violating session safety.
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
// Node.js step-up options generation example
|
|
19
|
+
router.post("/api/reauth/options", enforceActiveSession, async (req, res) => {
|
|
20
|
+
const userPasskeys = await db.findCredentialsByUserId(req.user.id);
|
|
21
|
+
|
|
22
|
+
const options = {
|
|
23
|
+
challenge: serverGeneratedBase64UrlChallenge, // Random challenge stored in user session
|
|
24
|
+
rpId: "example.com",
|
|
25
|
+
// Enforce allowance strictly limited to the user's credentials list
|
|
26
|
+
allowCredentials: userPasskeys.map((cred) => ({
|
|
27
|
+
type: "public-key",
|
|
28
|
+
id: cred.id,
|
|
29
|
+
transports: cred.transports, // Speeds up resolution by indicating platform transports
|
|
30
|
+
})),
|
|
31
|
+
};
|
|
32
|
+
return res.json(options);
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Verification Endpoint Delta
|
|
37
|
+
|
|
38
|
+
Verify the assertion returned by the client:
|
|
39
|
+
|
|
40
|
+
**Verify Account Ownership**: The verification endpoint MUST explicitly verify that the resulting authenticated credential ID returned by the client resolves to a stored credential record whose associated user ID strictly matches the active signed-in user (`storedCredential.passkeyUserId === req.user.id`). If a valid passkey of a _different_ user is returned, authentication MUST be rejected immediately.
|
|
41
|
+
|
|
42
|
+
## Client-Side Flow Deltas
|
|
43
|
+
|
|
44
|
+
Applications choose from two reauthentication interfaces depending on the transaction UI:
|
|
45
|
+
|
|
46
|
+
### A. Button Flow (No Input Fields)
|
|
47
|
+
|
|
48
|
+
Trigger reauthentication when a user presses a "Verify Identity" or "Proceed with Transaction" button.
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<button id="reauth-btn" data-testid="reauth-button">Confirm Transaction</button>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
let reauthAbortController = new AbortController();
|
|
56
|
+
|
|
57
|
+
async function triggerButtonReauth() {
|
|
58
|
+
// Abort any background suggestion flows to avoid passkey prompt collisions
|
|
59
|
+
reauthAbortController.abort();
|
|
60
|
+
reauthAbortController = new AbortController();
|
|
61
|
+
|
|
62
|
+
const optionsResponse = await fetch("/api/reauth/options", {
|
|
63
|
+
method: "POST",
|
|
64
|
+
});
|
|
65
|
+
const optionsJSON = await optionsResponse.json();
|
|
66
|
+
const publicKey =
|
|
67
|
+
PublicKeyCredential.parseRequestOptionsFromJSON(optionsJSON);
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const credential = await navigator.credentials.get({
|
|
71
|
+
publicKey,
|
|
72
|
+
signal: reauthAbortController.signal,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (credential) {
|
|
76
|
+
const encodedCredential = credential.toJSON();
|
|
77
|
+
const verifyResponse = await fetch("/api/reauth/verify", {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers: { "Content-Type": "application/json" },
|
|
80
|
+
body: JSON.stringify(encodedCredential),
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (verifyResponse.ok) {
|
|
84
|
+
showTransactionSuccessUI();
|
|
85
|
+
} else if (verifyResponse.status === 404 && PublicKeyCredential.signalUnknownCredential) {
|
|
86
|
+
await PublicKeyCredential.signalUnknownCredential({
|
|
87
|
+
rpId, // RP ID must match the one defined on the server
|
|
88
|
+
credentialId: encodedCredential.id
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} catch (err) {
|
|
93
|
+
if (err.name === "NotAllowedError") {
|
|
94
|
+
console.log("User cancelled reauthentication.");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
document
|
|
100
|
+
.getElementById("reauth-btn")
|
|
101
|
+
.addEventListener("click", triggerButtonReauth);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Fallback Strategies
|
|
105
|
+
|
|
106
|
+
### Passkey feature detection fallback
|
|
107
|
+
|
|
108
|
+
Baseline status for the api.PublicKeyCredential.getClientCapabilities_static capability: Newly available. It's been Baseline since 2025-02-06.
|
|
109
|
+
Supported by: Chrome 133 (Feb 2025), Edge 133 (Feb 2025), Firefox 135 (Feb 2025), and Safari 17.4 (Mar 2024).
|
|
110
|
+
|
|
111
|
+
Always install 'webauthn-polyfills' and import it in the context.
|
|
112
|
+
Consider as long as `PublicKeyCredential` is supported, `PublicKeyCredential.getClientCapabilities` is also supported.
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
import 'webauthn-polyfills';
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Easy JSON Serialization Fallback
|
|
119
|
+
|
|
120
|
+
Baseline status for the api.PublicKeyCredential.parseRequestOptionsFromJSON_static capability: Newly available. It's been Baseline since 2025-03-31.
|
|
121
|
+
Supported by: Chrome 129 (Sep 2024), Edge 129 (Sep 2024), Firefox 119 (Oct 2023), and Safari 18.4 (Mar 2025).
|
|
122
|
+
|
|
123
|
+
Always install 'webauthn-polyfills' and import it in the context.
|
|
124
|
+
Consider as long as `PublicKeyCredential` is supported, `PublicKeyCredential.parseRequestOptionsFromJSON` and `PublicKeyCredential.prototype.toJSON` are also supported.
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
import 'webauthn-polyfills';
|
|
128
|
+
```
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Passkey Registration Guide
|
|
2
|
+
|
|
3
|
+
This guide details how to enable users to register a passkey for their account, providing a highly secure, phishing-resistant passwordless sign-in alternative.
|
|
4
|
+
|
|
5
|
+
## Database Requirements
|
|
6
|
+
|
|
7
|
+
To support passkey registrations, your database credential table must store the following fields:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export interface StoredPasskeyCredential {
|
|
11
|
+
id: string; // Base64URL-encoded credential ID (unique lookup key)
|
|
12
|
+
passkeyUserId: string; // Associated application user ID
|
|
13
|
+
credentialPublicKey: string; // Base64URL-encoded public key used to verify assertion signatures
|
|
14
|
+
credentialType: "public-key";
|
|
15
|
+
credentialDeviceType: "singleDevice" | "multiDevice"; // Helps distinguish device-bound vs cloud-synced passkeys
|
|
16
|
+
credentialBackedUp: boolean; // Boolean backup state reported by the authenticator
|
|
17
|
+
aaguid: string; // Authenticator Attestation GUID
|
|
18
|
+
providerIcon?: string; // Provider icon derived from the AAGUID registry (dark or light theme URLs)
|
|
19
|
+
name: string; // Provider name derived from AAGUID registry
|
|
20
|
+
transports: string[]; // Array of transport names (e.g. 'internal', 'hybrid') necessary for exclusion options
|
|
21
|
+
lastUsedAt?: number; // Optional epoch timestamp of last sign-in
|
|
22
|
+
registeredAt: number; // Registration epoch timestamp
|
|
23
|
+
counter: number; // Authenticator sign-in signature counter used to prevent replay attacks
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Server-Side
|
|
28
|
+
|
|
29
|
+
### Options Generation
|
|
30
|
+
|
|
31
|
+
Create an endpoint that generates WebAuthn creation parameters. Rely on a vetted library per category standards instead of hand-rolling cryptography.
|
|
32
|
+
|
|
33
|
+
1. **Use the predefined RP ID**: Use the predefined proper RP ID as a constant string.
|
|
34
|
+
2. **Create a secure Challenge**: Generate a high-entropy, cryptographically secure random buffer on the server, store it securely in the user's session, and encode it as Base64URL for options delivery.
|
|
35
|
+
3. **Avoid Duplicate Passkeys**: Map the user's existing pre-registered credential IDs to the `excludeCredentials` options array. This prevents the authenticator from registering duplicate credentials on the same passkey provider account.
|
|
36
|
+
4. **Enforce Discoverable Credentials**: Set `requireResidentKey: true` and `residentKey: "required"` in the `authenticatorSelection` options to request a discoverable credential, which is necessary for discoverable sign-ins.
|
|
37
|
+
5. **Configure User Verification**: Specify `userVerification: "preferred"` or `userVerification: "required"`. Many compliance use cases (e.g., finance, healthcare) require `'required'` to enforce user verification on creation.
|
|
38
|
+
6. **Determine Attachment Scope**:
|
|
39
|
+
- **Promotion Flow**: When proposing passkey creation right after standard password sign-ins or post-signup promotions, set `authenticatorAttachment: "platform"` to enforce platform authenticator and bypass external security key prompts.
|
|
40
|
+
- **Management Flow**: When called from a dedicated settings or security panel where external security keys are supported in addition to platform authenticator, omit the `authenticatorAttachment` property entirely.
|
|
41
|
+
- _Tip_: Accept a `promotion: boolean` request flag to conditionally handle both flows with a single endpoint.
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
// Options generation example
|
|
45
|
+
const options = {
|
|
46
|
+
challenge: serverGeneratedBase64UrlChallenge, // Cryptographically random challenge
|
|
47
|
+
rp: { id: "example.com", name: "Secure Application" },
|
|
48
|
+
user: {
|
|
49
|
+
id: userBase64UrlId, // Unique base64url string identifying the account
|
|
50
|
+
name: "user@example.com",
|
|
51
|
+
displayName: "Jane Doe",
|
|
52
|
+
},
|
|
53
|
+
pubKeyCredParams: [
|
|
54
|
+
{
|
|
55
|
+
type: "public-key",
|
|
56
|
+
alg: -7,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
type: "public-key",
|
|
60
|
+
alg: -257,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
excludeCredentials: userExistingCredentials.map((cred) => ({
|
|
64
|
+
type: "public-key",
|
|
65
|
+
id: cred.id,
|
|
66
|
+
transports: cred.transports,
|
|
67
|
+
})),
|
|
68
|
+
authenticatorSelection: {
|
|
69
|
+
residentKey: "required",
|
|
70
|
+
requireResidentKey: true,
|
|
71
|
+
userVerification: "preferred",
|
|
72
|
+
...(isPromotionFlow && { authenticatorAttachment: "platform" }),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Verification
|
|
78
|
+
|
|
79
|
+
1. **Challenge Verification**: Securely verify the challenge against the expected session bound challenge.
|
|
80
|
+
2. **Verify User Presence**:
|
|
81
|
+
- Ensure that the User Present (UP) flag returned in the parsed authenticator data is `true` to confirm physical user presence at the time of creation.
|
|
82
|
+
3. **Relaxing Verification for 'preferred'**:
|
|
83
|
+
- When the creation options specified `userVerification: "preferred"`, the server-side verification call MUST be configured with `requireUserVerification: false`. Otherwise, authenticators that register without user verification (e.g., screen locks disabled) will trigger spurious server verification failures.
|
|
84
|
+
|
|
85
|
+
## Client-Side Logic
|
|
86
|
+
|
|
87
|
+
1. **Gate the UI on page load**:
|
|
88
|
+
- On page load, call `PublicKeyCredential.getClientCapabilities()` and **disable the "Create passkey" button** if `conditionalGet` or `passkeyPlatformAuthenticator` is not available.
|
|
89
|
+
2. **Invoke creation & Serialize**: Decode server options with `PublicKeyCredential.parseCreationOptionsFromJSON()` and pass the resulting configuration to `navigator.credentials.create()`.
|
|
90
|
+
- Call `credential.toJSON()` to encode the `AuthenticatorAttestationResponse` into a valid, JSON-serializable object before fetching the verification endpoint.
|
|
91
|
+
3. **Handle WebAuthn Exceptions**:
|
|
92
|
+
- `InvalidStateError`: A matching passkey already exists (matched by `excludeCredentials`).
|
|
93
|
+
- `NotAllowedError`: The user cancelled or timed out the authentication passkey dialog.
|
|
94
|
+
- `AbortError`: The operation has been aborted.
|
|
95
|
+
- `SecurityError`: Secure origins (HTTPS) or RP ID mismatch errors (configuration issues).
|
|
96
|
+
4. **Try/Catch Segregation for Signal API**:
|
|
97
|
+
- Wrap server verification `fetch()` call in a try/catch block. Call `signalUnknownCredential()` when the server verification fetch fails (any status `response.ok === false` or network throws).
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
// optionsFetch and registerVerifyFetch are app-defined HTTP methods
|
|
101
|
+
import { optionsFetch, registerVerifyFetch } from "./api.js";
|
|
102
|
+
|
|
103
|
+
async function registerPasskey(isPromotion = false) {
|
|
104
|
+
// Verify passkey capability and conditional UI are available
|
|
105
|
+
const capabilities = await PublicKeyCredential.getClientCapabilities();
|
|
106
|
+
if (
|
|
107
|
+
!capabilities.passkeyPlatformAuthenticator ||
|
|
108
|
+
!capabilities.conditionalGet
|
|
109
|
+
) {
|
|
110
|
+
// Hide "Create passkey" buttons and fall back to password flows instead
|
|
111
|
+
showStandardPasswordFallbackUI();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const creationOptionsJSON = await optionsFetch({ promotion: isPromotion });
|
|
116
|
+
const publicKey =
|
|
117
|
+
PublicKeyCredential.parseCreationOptionsFromJSON(creationOptionsJSON);
|
|
118
|
+
|
|
119
|
+
let credential;
|
|
120
|
+
try {
|
|
121
|
+
// passkey prompt execution
|
|
122
|
+
credential = await navigator.credentials.create({ publicKey });
|
|
123
|
+
} catch (err) {
|
|
124
|
+
if (err.name === "InvalidStateError") {
|
|
125
|
+
console.log("A passkey already exists for this account.");
|
|
126
|
+
alert("A passkey already exists for this account.");
|
|
127
|
+
} else if (err.name === "SecurityError") {
|
|
128
|
+
console.error("Configuration RP ID or Secure Context error.");
|
|
129
|
+
alert("Configuration RP ID or Secure Context error.");
|
|
130
|
+
} else if (err.name === "NotAllowedError") {
|
|
131
|
+
console.log("User cancelled the passkey dialog.");
|
|
132
|
+
} else if (err.name === "AbortError") {
|
|
133
|
+
console.log("The creation operation has been aborted.");
|
|
134
|
+
}
|
|
135
|
+
return; // Safe API exit, do not signal unknown for standard WebAuthn cancels
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Server Verification phase (Segregated Try/Catch)
|
|
139
|
+
let encodedResponse = credential.toJSON();
|
|
140
|
+
try {
|
|
141
|
+
const response = await registerVerifyFetch(encodedResponse);
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
// Server verification failed to verify/authenticate the credential (orphaned)
|
|
144
|
+
await PublicKeyCredential.signalUnknownCredential({
|
|
145
|
+
rpId, // RP ID must match the one defined on the server
|
|
146
|
+
credentialId: encodedResponse.id, // Base64URL-encoded credential ID
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
} catch (serverErr) {
|
|
150
|
+
console.error("Server verification network failure:", serverErr);
|
|
151
|
+
await publickeycredential.signalunknowncredential({
|
|
152
|
+
rpId, // RP ID must match the one defined on the server
|
|
153
|
+
credentialid: encodedresponse.id, // base64url-encoded credential id
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Fallback Strategies
|
|
160
|
+
|
|
161
|
+
### Signal API Synchronization Fallback
|
|
162
|
+
|
|
163
|
+
Web authentication signal methods has limited availability.
|
|
164
|
+
Supported by: Chrome 132 (Jan 2025), Edge 132 (Jan 2025), and Safari 26 (Sep 2025).
|
|
165
|
+
Unsupported in: Firefox.
|
|
166
|
+
|
|
167
|
+
The WebAuthn Signal API (`webauthn-signals`) is a progressive optimization used to keep password managers in sync with the server credential state.
|
|
168
|
+
|
|
169
|
+
- **Fallback Experience**: If `PublicKeyCredential.signalUnknownCredential` is unsupported by the browser, the call MUST be bypassed safely via feature detection gating (`if (PublicKeyCredential.signalUnknownCredential)`), and the server-side verification simply logs the failure without triggering manager updates.
|
|
170
|
+
|
|
171
|
+
### Easy JSON Serialization Fallback
|
|
172
|
+
|
|
173
|
+
Baseline status for the api.PublicKeyCredential.parseCreationOptionsFromJSON_static capability: Newly available. It's been Baseline since 2025-03-31.
|
|
174
|
+
Supported by: Chrome 129 (Sep 2024), Edge 129 (Sep 2024), Firefox 119 (Oct 2023), and Safari 18.4 (Mar 2025).
|
|
175
|
+
|
|
176
|
+
Always install 'webauthn-polyfills' and import it in the context.
|
|
177
|
+
Consider as long as `PublicKeyCredential` is supported, `PublicKeyCredential.parseCreationOptionsFromJSON` and `PublicKeyCredential.prototype.toJSON` are also supported.
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
import 'webauthn-polyfills';
|
|
181
|
+
```
|