cfsa-antigravity 3.0.2 → 3.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/README.md +27 -10
- package/bin/cli.mjs +7 -6
- package/package.json +1 -1
- package/template/.agent/PRDS/codex-runtime-support.md +2 -2
- package/template/.agent/TASKS/codex-runtime-support.md +2 -2
- package/template/.agent/instructions/workflow.md +3 -3
- package/template/.agent/kit-sync.md +3 -3
- package/template/.agent/rules/completion-checklist.md +3 -3
- package/template/.agent/skills/parallel-agents/SKILL.md +1 -1
- package/template/.agent/skills/session-continuity/SKILL.md +6 -6
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +1 -1
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +3 -3
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +4 -4
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +1 -1
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +2 -2
- package/template/.agent/skills/session-continuity/protocols/11-parallel-synthesis.md +1 -1
- package/template/.agent/workflows/create-prd-architecture.md +2 -2
- package/template/.agent/workflows/create-prd-design-system.md +2 -2
- package/template/.agent/workflows/create-prd-security.md +2 -2
- package/template/.agent/workflows/create-prd-stack.md +2 -2
- package/template/.agent/workflows/create-prd.md +2 -2
- package/template/.agent/workflows/decompose-architecture-validate.md +1 -1
- package/template/.agent/workflows/decompose-architecture.md +2 -2
- package/template/.agent/workflows/ideate.md +2 -2
- package/template/.agent/workflows/implement-slice-setup.md +1 -1
- package/template/.agent/workflows/implement-slice-tdd.md +3 -3
- package/template/.agent/workflows/implement-slice.md +2 -2
- package/template/.agent/workflows/plan-phase-preflight.md +2 -2
- package/template/.agent/workflows/plan-phase-write.md +2 -2
- package/template/.agent/workflows/plan-phase.md +2 -2
- package/template/.agent/workflows/setup-workspace.md +2 -2
- package/template/.agent/workflows/update-architecture-map.md +1 -1
- package/template/.agent/workflows/validate-phase-quality.md +1 -1
- package/template/.agent/workflows/validate-phase-readiness.md +2 -2
- package/template/.agent/workflows/validate-phase.md +2 -2
- package/template/.agent/workflows/verify-infrastructure.md +1 -1
- package/template/.agent/workflows/write-architecture-spec-deepen.md +3 -3
- package/template/.agent/workflows/write-architecture-spec-design.md +1 -1
- package/template/.agent/workflows/write-architecture-spec.md +3 -3
- package/template/.agent/workflows/write-be-spec-classify.md +1 -1
- package/template/.agent/workflows/write-be-spec-write.md +3 -3
- package/template/.agent/workflows/write-be-spec.md +3 -3
- package/template/.agent/workflows/write-fe-spec-classify.md +1 -1
- package/template/.agent/workflows/write-fe-spec-write.md +2 -2
- package/template/.agent/workflows/write-fe-spec.md +3 -3
- package/template/.claude/README.md +3 -1
- package/template/.claude/instructions/workflow.md +3 -3
- package/template/.claude/kit-sync.md +3 -3
- package/template/.claude/rules/completion-checklist.md +3 -3
- package/template/.claude/skills/parallel-agents/SKILL.md +1 -1
- package/template/.claude/skills/plan-phase/SKILL.md +2 -2
- package/template/.claude/skills/plan-phase-preflight/SKILL.md +2 -2
- package/template/.claude/skills/session-continuity/SKILL.md +6 -6
- package/template/.claude/skills/session-continuity/protocols/01-session-resumption.md +1 -1
- package/template/.claude/skills/session-continuity/protocols/02-progress-generation.md +3 -3
- package/template/.claude/skills/session-continuity/protocols/03-progress-update.md +4 -4
- package/template/.claude/skills/session-continuity/protocols/07-spec-pipeline-generation.md +1 -1
- package/template/.claude/skills/session-continuity/protocols/08-spec-pipeline-update.md +2 -2
- package/template/.claude/skills/session-continuity/protocols/11-parallel-synthesis.md +1 -1
- package/template/.claude/skills/setup/setup-cfsa.md +1 -1
- package/template/.claude/skills/write-architecture-spec/SKILL.md +2 -2
- package/template/.claude/skills/write-architecture-spec-deepen/SKILL.md +1 -1
- package/template/.claude/skills/write-architecture-spec-design/SKILL.md +1 -1
- package/template/.claude/skills/write-be-spec/SKILL.md +3 -3
- package/template/.claude/skills/write-be-spec-classify/SKILL.md +1 -1
- package/template/.claude/skills/write-be-spec-write/SKILL.md +1 -1
- package/template/.claude/skills/write-fe-spec/SKILL.md +3 -3
- package/template/.claude/skills/write-fe-spec-write/SKILL.md +1 -1
- package/template/.codex/README.md +99 -0
- package/template/.codex/instructions/commands.md +24 -0
- package/template/.codex/instructions/example.md +21 -0
- package/template/.codex/instructions/patterns.md +61 -0
- package/template/.codex/instructions/structure.md +29 -0
- package/template/.codex/instructions/tech-stack.md +93 -0
- package/template/.codex/instructions/workflow.md +64 -0
- package/template/.codex/kit-sync.md +6 -0
- package/template/.codex/rules/boundary-not-placeholder.md +146 -0
- package/template/.codex/rules/completion-checklist.md +60 -0
- package/template/.codex/rules/debug-by-test.md +49 -0
- package/template/.codex/rules/decision-classification.md +113 -0
- package/template/.codex/rules/extensibility.md +52 -0
- package/template/.codex/rules/memory-capture.md +84 -0
- package/template/.codex/rules/question-vs-command.md +91 -0
- package/template/.codex/rules/security-first.md +54 -0
- package/template/.codex/rules/single-question.md +59 -0
- package/template/.codex/rules/skill-mcp-first.md +45 -0
- package/template/.codex/rules/source-before-ask.md +93 -0
- package/template/.codex/rules/specificity-standards.md +64 -0
- package/template/.codex/rules/tdd-contract-first.md +67 -0
- package/template/.codex/rules/vertical-slices.md +83 -0
- package/template/.codex/skill-library/MANIFEST.md +498 -0
- package/template/.codex/skill-library/README.md +38 -0
- package/template/.codex/skill-library/meta/claude-code/README.md +9 -0
- package/template/.codex/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.codex/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.codex/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.codex/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.codex/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.codex/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.codex/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.codex/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.codex/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.codex/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.codex/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.codex/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.codex/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.codex/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.codex/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.codex/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.codex/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.codex/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.codex/skill-library/stack/auth/lucia/SKILL.md +230 -0
- package/template/.codex/skill-library/stack/auth/supabase-auth/SKILL.md +293 -0
- package/template/.codex/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.codex/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.codex/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.codex/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.codex/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.codex/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.codex/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.codex/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.codex/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.codex/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.codex/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.codex/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.codex/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.codex/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.codex/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.codex/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.codex/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.codex/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.codex/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.codex/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.codex/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.codex/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.codex/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.codex/skill-library/stack/devops/git-advanced/SKILL.md +972 -0
- package/template/.codex/skill-library/stack/devops/git-workflow/SKILL.md +420 -0
- package/template/.codex/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.codex/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.codex/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.codex/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.codex/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.codex/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.codex/skill-library/stack/extensions/plasmo/SKILL.md +195 -0
- package/template/.codex/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.codex/skill-library/stack/extensions/wxt/SKILL.md +216 -0
- package/template/.codex/skill-library/stack/feature-flags/flagsmith/SKILL.md +187 -0
- package/template/.codex/skill-library/stack/feature-flags/launchdarkly/SKILL.md +183 -0
- package/template/.codex/skill-library/stack/feature-flags/posthog-flags/SKILL.md +189 -0
- package/template/.codex/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.codex/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.codex/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.codex/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.codex/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.codex/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.codex/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.codex/skill-library/stack/frameworks/svelte5/SKILL.md +81 -0
- package/template/.codex/skill-library/stack/frameworks/svelte5/references/events.md +353 -0
- package/template/.codex/skill-library/stack/frameworks/svelte5/references/migration.md +339 -0
- package/template/.codex/skill-library/stack/frameworks/svelte5/references/performance.md +443 -0
- package/template/.codex/skill-library/stack/frameworks/svelte5/references/runes.md +394 -0
- package/template/.codex/skill-library/stack/frameworks/svelte5/references/snippets.md +291 -0
- package/template/.codex/skill-library/stack/frameworks/svelte5/references/sveltekit.md +401 -0
- package/template/.codex/skill-library/stack/frameworks/svelte5/references/typescript.md +305 -0
- package/template/.codex/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.codex/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.codex/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.codex/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.codex/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.codex/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.codex/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.codex/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.codex/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.codex/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.codex/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.codex/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.codex/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.codex/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.codex/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.codex/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.codex/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.codex/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.codex/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.codex/skill-library/stack/messaging/nats/SKILL.md +147 -0
- package/template/.codex/skill-library/stack/messaging/rabbitmq/SKILL.md +178 -0
- package/template/.codex/skill-library/stack/messaging/sqs/SKILL.md +187 -0
- package/template/.codex/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.codex/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.codex/skill-library/stack/mobile/kotlin-compose/SKILL.md +215 -0
- package/template/.codex/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.codex/skill-library/stack/mobile/swiftui/SKILL.md +261 -0
- package/template/.codex/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.codex/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.codex/skill-library/stack/notifications/fcm/SKILL.md +229 -0
- package/template/.codex/skill-library/stack/notifications/sendgrid/SKILL.md +220 -0
- package/template/.codex/skill-library/stack/notifications/twilio/SKILL.md +204 -0
- package/template/.codex/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.codex/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.codex/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.codex/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.codex/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.codex/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.codex/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.codex/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.codex/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.codex/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.codex/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.codex/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.codex/skill-library/stack/search/algolia/SKILL.md +206 -0
- package/template/.codex/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.codex/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.codex/skill-library/stack/search/typesense/SKILL.md +189 -0
- package/template/.codex/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.codex/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.codex/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.codex/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.codex/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.codex/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.codex/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.codex/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.codex/skill-library/stack/storage/cloudflare-r2/SKILL.md +252 -0
- package/template/.codex/skill-library/stack/storage/gcs/SKILL.md +229 -0
- package/template/.codex/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.codex/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.codex/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.codex/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.codex/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.codex/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.codex/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.codex/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.codex/skill-library/stack/ui/svelte-flow/SKILL.md +390 -0
- package/template/.codex/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.codex/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.codex/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.codex/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.codex/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.codex/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.codex/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.codex/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.codex/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.codex/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.codex/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.codex/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.codex/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.codex/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.codex/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.codex/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.codex/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.codex/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.codex/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.codex/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.codex/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.codex/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.codex/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.codex/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.codex/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.codex/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.codex/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.codex/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.codex/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.codex/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.codex/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.codex/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.codex/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.codex/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.codex/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.codex/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.codex/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.codex/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.codex/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.codex/skill-library/surface/web/i18n-localization/SKILL.md +332 -0
- package/template/.codex/skill-library/surface/web/i18n-localization/references/icu-message-format.md +223 -0
- package/template/.codex/skill-library/surface/web/i18n-localization/references/intl-api-patterns.md +326 -0
- package/template/.codex/skill-library/surface/web/i18n-localization/references/rtl-support.md +298 -0
- package/template/.codex/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.codex/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.codex/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.codex/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.codex/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.codex/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.codex/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.codex/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.codex/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.codex/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.codex/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.codex/skills/README.md +78 -0
- package/template/.codex/skills/accessibility/SKILL.md +522 -0
- package/template/.codex/skills/accessibility/references/WCAG.md +162 -0
- package/template/.codex/skills/accessibility/references/ia-spec-checklist.md +35 -0
- package/template/.codex/skills/adversarial-review/SKILL.md +90 -0
- package/template/.codex/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.codex/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.codex/skills/api-design-principles/SKILL.md +169 -0
- package/template/.codex/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.codex/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.codex/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.codex/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.codex/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.codex/skills/api-versioning/SKILL.md +166 -0
- package/template/.codex/skills/api-versioning/references/typescript.md +157 -0
- package/template/.codex/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.codex/skills/audit-ambiguity/SKILL.md +54 -0
- package/template/.codex/skills/audit-ambiguity-execute/SKILL.md +86 -0
- package/template/.codex/skills/audit-ambiguity-rubrics/SKILL.md +58 -0
- package/template/.codex/skills/bootstrap-agents/SKILL.md +258 -0
- package/template/.codex/skills/bootstrap-agents-fill/SKILL.md +25 -0
- package/template/.codex/skills/bootstrap-agents-provision/SKILL.md +22 -0
- package/template/.codex/skills/brainstorming/SKILL.md +177 -0
- package/template/.codex/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.codex/skills/clean-code/SKILL.md +196 -0
- package/template/.codex/skills/clean-code/references/typescript.md +126 -0
- package/template/.codex/skills/code-review-pro/SKILL.md +152 -0
- package/template/.codex/skills/concise-planning/SKILL.md +107 -0
- package/template/.codex/skills/create-prd/SKILL.md +94 -0
- package/template/.codex/skills/create-prd-architecture/SKILL.md +72 -0
- package/template/.codex/skills/create-prd-compile/SKILL.md +85 -0
- package/template/.codex/skills/create-prd-design-system/SKILL.md +69 -0
- package/template/.codex/skills/create-prd-security/SKILL.md +66 -0
- package/template/.codex/skills/create-prd-stack/SKILL.md +84 -0
- package/template/.codex/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.codex/skills/database-schema-design/SKILL.md +205 -0
- package/template/.codex/skills/database-schema-design/references/relational.md +228 -0
- package/template/.codex/skills/decompose-architecture/SKILL.md +72 -0
- package/template/.codex/skills/decompose-architecture-structure/SKILL.md +62 -0
- package/template/.codex/skills/decompose-architecture-validate/SKILL.md +72 -0
- package/template/.codex/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.codex/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.codex/skills/design-direction/SKILL.md +45 -0
- package/template/.codex/skills/error-handling-patterns/SKILL.md +226 -0
- package/template/.codex/skills/error-handling-patterns/references/go.md +162 -0
- package/template/.codex/skills/error-handling-patterns/references/python.md +262 -0
- package/template/.codex/skills/error-handling-patterns/references/rust.md +112 -0
- package/template/.codex/skills/error-handling-patterns/references/typescript.md +178 -0
- package/template/.codex/skills/evolve-contract/SKILL.md +24 -0
- package/template/.codex/skills/evolve-feature/SKILL.md +18 -0
- package/template/.codex/skills/evolve-feature-cascade/SKILL.md +24 -0
- package/template/.codex/skills/evolve-feature-classify/SKILL.md +21 -0
- package/template/.codex/skills/find-skills/SKILL.md +145 -0
- package/template/.codex/skills/git-advanced/SKILL.md +972 -0
- package/template/.codex/skills/git-workflow/SKILL.md +420 -0
- package/template/.codex/skills/idea-extraction/SKILL.md +644 -0
- package/template/.codex/skills/ideate/SKILL.md +77 -0
- package/template/.codex/skills/ideate-discover/SKILL.md +89 -0
- package/template/.codex/skills/ideate-extract/SKILL.md +77 -0
- package/template/.codex/skills/ideate-validate/SKILL.md +75 -0
- package/template/.codex/skills/implement-slice/SKILL.md +64 -0
- package/template/.codex/skills/implement-slice-setup/SKILL.md +70 -0
- package/template/.codex/skills/implement-slice-tdd/SKILL.md +78 -0
- package/template/.codex/skills/logging-best-practices/SKILL.md +192 -0
- package/template/.codex/skills/logging-best-practices/references/go.md +49 -0
- package/template/.codex/skills/logging-best-practices/references/python.md +52 -0
- package/template/.codex/skills/logging-best-practices/references/typescript.md +215 -0
- package/template/.codex/skills/migration-management/SKILL.md +200 -0
- package/template/.codex/skills/migration-management/references/relational.md +214 -0
- package/template/.codex/skills/minimalist-surgical-development/SKILL.md +135 -0
- package/template/.codex/skills/parallel-agents/SKILL.md +165 -0
- package/template/.codex/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.codex/skills/parallel-feature-development/SKILL.md +157 -0
- package/template/.codex/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.codex/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.codex/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.codex/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.codex/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.codex/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.codex/skills/pipeline-rubrics/references/scoring.md +32 -0
- package/template/.codex/skills/pipeline-rubrics/references/vision-rubric.md +12 -0
- package/template/.codex/skills/plan-phase/SKILL.md +62 -0
- package/template/.codex/skills/plan-phase-preflight/SKILL.md +75 -0
- package/template/.codex/skills/plan-phase-write/SKILL.md +85 -0
- package/template/.codex/skills/prd-templates/SKILL.md +107 -0
- package/template/.codex/skills/prd-templates/references/architecture-completeness-checklist.md +28 -0
- package/template/.codex/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.codex/skills/prd-templates/references/be-spec-classification.md +41 -0
- package/template/.codex/skills/prd-templates/references/be-spec-template.md +107 -0
- package/template/.codex/skills/prd-templates/references/bootstrap-verification-protocol.md +50 -0
- package/template/.codex/skills/prd-templates/references/constraint-exploration.md +41 -0
- package/template/.codex/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.codex/skills/prd-templates/references/decision-confirmation-protocol.md +68 -0
- package/template/.codex/skills/prd-templates/references/decision-propagation.md +121 -0
- package/template/.codex/skills/prd-templates/references/decomposition-templates.md +226 -0
- package/template/.codex/skills/prd-templates/references/deep-ideation-loading-protocol.md +114 -0
- package/template/.codex/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.codex/skills/prd-templates/references/design-system-prerequisite-check.md +18 -0
- package/template/.codex/skills/prd-templates/references/domain-exhaustion-criteria.md +37 -0
- package/template/.codex/skills/prd-templates/references/engagement-tier-protocol.md +58 -0
- package/template/.codex/skills/prd-templates/references/engineering-standards-template.md +126 -0
- package/template/.codex/skills/prd-templates/references/evolution-layer-guidance.md +91 -0
- package/template/.codex/skills/prd-templates/references/expansion-modes.md +27 -0
- package/template/.codex/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.codex/skills/prd-templates/references/fe-spec-template.md +90 -0
- package/template/.codex/skills/prd-templates/references/feature-ledger-protocol.md +149 -0
- package/template/.codex/skills/prd-templates/references/folder-seeding-protocol.md +77 -0
- package/template/.codex/skills/prd-templates/references/fractal-cx-template.md +58 -0
- package/template/.codex/skills/prd-templates/references/fractal-feature-template.md +93 -0
- package/template/.codex/skills/prd-templates/references/fractal-node-index-template.md +55 -0
- package/template/.codex/skills/prd-templates/references/gate-applicability.md +92 -0
- package/template/.codex/skills/prd-templates/references/ideation-crosscut-template.md +36 -0
- package/template/.codex/skills/prd-templates/references/ideation-index-template.md +111 -0
- package/template/.codex/skills/prd-templates/references/ideation-meta-template.md +126 -0
- package/template/.codex/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.codex/skills/prd-templates/references/input-classification.md +23 -0
- package/template/.codex/skills/prd-templates/references/map-guard-protocol.md +65 -0
- package/template/.codex/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.codex/skills/prd-templates/references/persona-completeness-gate.md +20 -0
- package/template/.codex/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.codex/skills/prd-templates/references/placeholder-workflow-mapping.md +50 -0
- package/template/.codex/skills/prd-templates/references/shard-boundary-analysis.md +103 -0
- package/template/.codex/skills/prd-templates/references/shard-split-remediation.md +157 -0
- package/template/.codex/skills/prd-templates/references/skill-loading-protocol.md +36 -0
- package/template/.codex/skills/prd-templates/references/slice-completion-gates.md +29 -0
- package/template/.codex/skills/prd-templates/references/spec-coverage-sweep.md +44 -0
- package/template/.codex/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.codex/skills/prd-templates/references/tdd-testing-policy.md +39 -0
- package/template/.codex/skills/prd-templates/references/vision-template.md +57 -0
- package/template/.codex/skills/prd-templates/references/workflow-checkpoint-protocol.md +112 -0
- package/template/.codex/skills/prd-templates/references/write-verification-protocol.md +57 -0
- package/template/.codex/skills/prompt-engineer/SKILL.md +203 -0
- package/template/.codex/skills/propagate-decision/SKILL.md +18 -0
- package/template/.codex/skills/propagate-decision-apply/SKILL.md +22 -0
- package/template/.codex/skills/propagate-decision-scan/SKILL.md +20 -0
- package/template/.codex/skills/regex-patterns/SKILL.md +333 -0
- package/template/.codex/skills/regex-patterns/references/go.md +44 -0
- package/template/.codex/skills/regex-patterns/references/javascript.md +63 -0
- package/template/.codex/skills/regex-patterns/references/python.md +77 -0
- package/template/.codex/skills/regex-patterns/references/rust.md +43 -0
- package/template/.codex/skills/remediate-pipeline/SKILL.md +18 -0
- package/template/.codex/skills/remediate-pipeline-assess/SKILL.md +21 -0
- package/template/.codex/skills/remediate-pipeline-execute/SKILL.md +23 -0
- package/template/.codex/skills/remediate-shard-split/SKILL.md +21 -0
- package/template/.codex/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.codex/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.codex/skills/session-continuity/SKILL.md +732 -0
- package/template/.codex/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.codex/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.codex/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.codex/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.codex/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.codex/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.codex/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.codex/skills/session-continuity/protocols/08-spec-pipeline-update.md +65 -0
- package/template/.codex/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.codex/skills/session-continuity/protocols/10-placeholder-verification-gate.md +83 -0
- package/template/.codex/skills/session-continuity/protocols/11-parallel-synthesis.md +21 -0
- package/template/.codex/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.codex/skills/setup/README.md +24 -0
- package/template/.codex/skills/setup/setup-cfsa.md +200 -0
- package/template/.codex/skills/setup/setup-fill-placeholders.md +192 -0
- package/template/.codex/skills/setup/setup-provision-skills.md +82 -0
- package/template/.codex/skills/setup/setup-verify.md +89 -0
- package/template/.codex/skills/setup-workspace/SKILL.md +83 -0
- package/template/.codex/skills/setup-workspace-cicd/SKILL.md +56 -0
- package/template/.codex/skills/setup-workspace-data/SKILL.md +69 -0
- package/template/.codex/skills/setup-workspace-hosting/SKILL.md +59 -0
- package/template/.codex/skills/setup-workspace-scaffold/SKILL.md +72 -0
- package/template/.codex/skills/skill-creator/SKILL.md +203 -0
- package/template/.codex/skills/spec-writing/SKILL.md +110 -0
- package/template/.codex/skills/sync-kit/SKILL.md +23 -0
- package/template/.codex/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.codex/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.codex/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.codex/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.codex/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.codex/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.codex/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.codex/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.codex/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.codex/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.codex/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.codex/skills/tdd-workflow/SKILL.md +186 -0
- package/template/.codex/skills/tdd-workflow/references/typescript.md +231 -0
- package/template/.codex/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.codex/skills/tech-stack-catalog/references/constraint-questions.md +237 -0
- package/template/.codex/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.codex/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.codex/skills/technical-writer/SKILL.md +242 -0
- package/template/.codex/skills/testing-strategist/SKILL.md +319 -0
- package/template/.codex/skills/testing-strategist/references/typescript.md +328 -0
- package/template/.codex/skills/update-architecture-map/SKILL.md +21 -0
- package/template/.codex/skills/utilities/resolve-skill.md +195 -0
- package/template/.codex/skills/validate-phase/SKILL.md +62 -0
- package/template/.codex/skills/validate-phase-quality/SKILL.md +67 -0
- package/template/.codex/skills/validate-phase-readiness/SKILL.md +74 -0
- package/template/.codex/skills/verification-before-completion/SKILL.md +97 -0
- package/template/.codex/skills/verify-infrastructure/SKILL.md +25 -0
- package/template/.codex/skills/workflow-automation/SKILL.md +166 -0
- package/template/.codex/skills/workflow-automation/references/inngest.md +88 -0
- package/template/.codex/skills/workflow-automation/references/temporal.md +64 -0
- package/template/.codex/skills/write-architecture-spec/SKILL.md +78 -0
- package/template/.codex/skills/write-architecture-spec-deepen/SKILL.md +82 -0
- package/template/.codex/skills/write-architecture-spec-design/SKILL.md +80 -0
- package/template/.codex/skills/write-be-spec/SKILL.md +75 -0
- package/template/.codex/skills/write-be-spec-classify/SKILL.md +80 -0
- package/template/.codex/skills/write-be-spec-write/SKILL.md +99 -0
- package/template/.codex/skills/write-fe-spec/SKILL.md +79 -0
- package/template/.codex/skills/write-fe-spec-classify/SKILL.md +77 -0
- package/template/.codex/skills/write-fe-spec-write/SKILL.md +88 -0
- package/template/.factory/README.md +2 -3
- package/template/.factory/instructions/workflow.md +3 -3
- package/template/.factory/kit-sync.md +3 -3
- package/template/.factory/skills/completion-checklist/SKILL.md +3 -3
- package/template/.factory/skills/parallel-agents/SKILL.md +1 -1
- package/template/.factory/skills/plan-phase/SKILL.md +2 -2
- package/template/.factory/skills/plan-phase-preflight/SKILL.md +2 -2
- package/template/.factory/skills/session-continuity/SKILL.md +6 -6
- package/template/.factory/skills/session-continuity/protocols/01-session-resumption.md +1 -1
- package/template/.factory/skills/session-continuity/protocols/02-progress-generation.md +3 -3
- package/template/.factory/skills/session-continuity/protocols/03-progress-update.md +4 -4
- package/template/.factory/skills/session-continuity/protocols/07-spec-pipeline-generation.md +1 -1
- package/template/.factory/skills/session-continuity/protocols/08-spec-pipeline-update.md +2 -2
- package/template/.factory/skills/session-continuity/protocols/11-parallel-synthesis.md +1 -1
- package/template/.factory/skills/setup-cfsa/SKILL.md +1 -1
- package/template/.factory/skills/write-architecture-spec/SKILL.md +2 -2
- package/template/.factory/skills/write-architecture-spec-deepen/SKILL.md +1 -1
- package/template/.factory/skills/write-architecture-spec-design/SKILL.md +1 -1
- package/template/.factory/skills/write-be-spec/SKILL.md +3 -3
- package/template/.factory/skills/write-be-spec-classify/SKILL.md +1 -1
- package/template/.factory/skills/write-be-spec-write/SKILL.md +1 -1
- package/template/.factory/skills/write-fe-spec/SKILL.md +3 -3
- package/template/.factory/skills/write-fe-spec-write/SKILL.md +1 -1
- package/template/.memory/README.md +1 -0
- package/template/.memory/mcp-server/README.md +10 -2
- package/template/.memory/mcp-server/client.mjs +61 -18
- package/template/.memory/mcp-server/daemon.mjs +8 -3
- package/template/.memory/mcp-server/runtime.mjs +51 -14
- package/template/.memory/mcp-server/start.mjs +4 -2
- package/template/.memory/migrate/migrate-legacy.mjs +1 -0
- package/template/.memory/pipeline/README.md +1 -0
- package/template/CLAUDE.md +4 -4
- package/template/CODEX.md +6 -53
- package/template/GEMINI.md +2 -2
- package/template/docs/README.md +5 -2
- package/template/docs/kit-architecture.md +36 -19
- package/template/docs/progress-state-catalog.md +48 -0
- package/template/.factory/progress/memory/.gitkeep +0 -0
- /package/template/{.agent/progress → .codex/skills/skill-creator/references}/.gitkeep +0 -0
- /package/template/{.agent/progress/memory → .codex/skills/skill-creator/scripts}/.gitkeep +0 -0
- /package/template/{.agent/progress/sessions → .memory/pipeline/progress}/.gitkeep +0 -0
- /package/template/{.claude/progress → .memory/pipeline/progress/memory}/.gitkeep +0 -0
- /package/template/{.claude/progress/memory → .memory/pipeline/progress/phases}/.gitkeep +0 -0
- /package/template/{.claude → .memory/pipeline}/progress/sessions/.gitkeep +0 -0
- /package/template/{.factory/progress → .memory/pipeline/progress/slices}/.gitkeep +0 -0
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aws-s3
|
|
3
|
+
description: AWS S3 object storage for file uploads, downloads, presigned URLs, and CDN integration. Use when building file storage, media uploads, static asset hosting, backups, or integrating with S3-compatible services (MinIO, Cloudflare R2). Triggers on S3, presigned URL, file upload, bucket, multipart upload, object storage.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# AWS S3
|
|
8
|
+
|
|
9
|
+
Amazon S3 (Simple Storage Service) is object storage for any file type at any scale. This skill covers the AWS SDK v3 for JavaScript/TypeScript, which is the current standard. SDK v2 is deprecated.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
|
|
15
|
+
# For multipart uploads:
|
|
16
|
+
pnpm add @aws-sdk/lib-storage
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Client Configuration
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
23
|
+
|
|
24
|
+
const s3 = new S3Client({
|
|
25
|
+
region: process.env.AWS_REGION ?? 'us-east-1',
|
|
26
|
+
// Credentials resolved automatically from:
|
|
27
|
+
// 1. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
|
|
28
|
+
// 2. Shared credentials file (~/.aws/credentials)
|
|
29
|
+
// 3. IAM role (EC2, ECS, Lambda)
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### S3-Compatible Services
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// Cloudflare R2
|
|
37
|
+
const r2 = new S3Client({
|
|
38
|
+
region: 'auto',
|
|
39
|
+
endpoint: `https://${process.env.CF_ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
|
40
|
+
credentials: {
|
|
41
|
+
accessKeyId: process.env.R2_ACCESS_KEY_ID!,
|
|
42
|
+
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// MinIO (self-hosted)
|
|
47
|
+
const minio = new S3Client({
|
|
48
|
+
region: 'us-east-1',
|
|
49
|
+
endpoint: 'http://localhost:9000',
|
|
50
|
+
credentials: {
|
|
51
|
+
accessKeyId: process.env.MINIO_ACCESS_KEY!,
|
|
52
|
+
secretAccessKey: process.env.MINIO_SECRET_KEY!,
|
|
53
|
+
},
|
|
54
|
+
forcePathStyle: true, // Required for MinIO
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Basic Operations
|
|
59
|
+
|
|
60
|
+
### Upload an Object
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { PutObjectCommand } from '@aws-sdk/client-s3';
|
|
64
|
+
|
|
65
|
+
await s3.send(new PutObjectCommand({
|
|
66
|
+
Bucket: 'my-bucket',
|
|
67
|
+
Key: 'uploads/avatar.png',
|
|
68
|
+
Body: fileBuffer,
|
|
69
|
+
ContentType: 'image/png',
|
|
70
|
+
Metadata: { 'uploaded-by': 'user-123' },
|
|
71
|
+
}));
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Download an Object
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { GetObjectCommand } from '@aws-sdk/client-s3';
|
|
78
|
+
|
|
79
|
+
const response = await s3.send(new GetObjectCommand({
|
|
80
|
+
Bucket: 'my-bucket',
|
|
81
|
+
Key: 'uploads/avatar.png',
|
|
82
|
+
}));
|
|
83
|
+
|
|
84
|
+
// response.Body is a ReadableStream
|
|
85
|
+
const bytes = await response.Body?.transformToByteArray();
|
|
86
|
+
const text = await response.Body?.transformToString();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Delete an Object
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { DeleteObjectCommand, DeleteObjectsCommand } from '@aws-sdk/client-s3';
|
|
93
|
+
|
|
94
|
+
// Single delete
|
|
95
|
+
await s3.send(new DeleteObjectCommand({
|
|
96
|
+
Bucket: 'my-bucket',
|
|
97
|
+
Key: 'uploads/avatar.png',
|
|
98
|
+
}));
|
|
99
|
+
|
|
100
|
+
// Bulk delete (up to 1000 objects per request)
|
|
101
|
+
await s3.send(new DeleteObjectsCommand({
|
|
102
|
+
Bucket: 'my-bucket',
|
|
103
|
+
Delete: {
|
|
104
|
+
Objects: [
|
|
105
|
+
{ Key: 'uploads/a.png' },
|
|
106
|
+
{ Key: 'uploads/b.png' },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
}));
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### List Objects
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { ListObjectsV2Command } from '@aws-sdk/client-s3';
|
|
116
|
+
|
|
117
|
+
const response = await s3.send(new ListObjectsV2Command({
|
|
118
|
+
Bucket: 'my-bucket',
|
|
119
|
+
Prefix: 'uploads/',
|
|
120
|
+
MaxKeys: 100,
|
|
121
|
+
}));
|
|
122
|
+
|
|
123
|
+
for (const object of response.Contents ?? []) {
|
|
124
|
+
console.log(object.Key, object.Size, object.LastModified);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Paginate through all results
|
|
128
|
+
let continuationToken: string | undefined;
|
|
129
|
+
do {
|
|
130
|
+
const page = await s3.send(new ListObjectsV2Command({
|
|
131
|
+
Bucket: 'my-bucket',
|
|
132
|
+
Prefix: 'uploads/',
|
|
133
|
+
ContinuationToken: continuationToken,
|
|
134
|
+
}));
|
|
135
|
+
// process page.Contents
|
|
136
|
+
continuationToken = page.NextContinuationToken;
|
|
137
|
+
} while (continuationToken);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Head Object (Metadata Only)
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { HeadObjectCommand } from '@aws-sdk/client-s3';
|
|
144
|
+
|
|
145
|
+
const head = await s3.send(new HeadObjectCommand({
|
|
146
|
+
Bucket: 'my-bucket',
|
|
147
|
+
Key: 'uploads/avatar.png',
|
|
148
|
+
}));
|
|
149
|
+
console.log(head.ContentLength, head.ContentType, head.Metadata);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Presigned URLs
|
|
153
|
+
|
|
154
|
+
Presigned URLs grant temporary access to private objects without exposing credentials. This is the standard pattern for browser-based uploads and downloads.
|
|
155
|
+
|
|
156
|
+
### Presigned Download
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
160
|
+
import { GetObjectCommand } from '@aws-sdk/client-s3';
|
|
161
|
+
|
|
162
|
+
const downloadUrl = await getSignedUrl(s3, new GetObjectCommand({
|
|
163
|
+
Bucket: 'my-bucket',
|
|
164
|
+
Key: 'uploads/avatar.png',
|
|
165
|
+
}), {
|
|
166
|
+
expiresIn: 3600, // URL valid for 1 hour (seconds)
|
|
167
|
+
});
|
|
168
|
+
// Return this URL to the client for direct download
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Presigned Upload
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
175
|
+
import { PutObjectCommand } from '@aws-sdk/client-s3';
|
|
176
|
+
|
|
177
|
+
const uploadUrl = await getSignedUrl(s3, new PutObjectCommand({
|
|
178
|
+
Bucket: 'my-bucket',
|
|
179
|
+
Key: `uploads/${userId}/${filename}`,
|
|
180
|
+
ContentType: 'image/png',
|
|
181
|
+
}), {
|
|
182
|
+
expiresIn: 600, // 10 minutes to complete upload
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Client uploads directly to S3:
|
|
186
|
+
// await fetch(uploadUrl, { method: 'PUT', body: file, headers: { 'Content-Type': 'image/png' } });
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Anti-pattern**: Never pass presigned URLs in query strings or logs. They contain temporary credentials. Serve them over HTTPS only and set short expiration times.
|
|
190
|
+
|
|
191
|
+
## Multipart Uploads
|
|
192
|
+
|
|
193
|
+
For files larger than 100MB, use multipart uploads. The `@aws-sdk/lib-storage` package handles chunking, parallelism, and resume automatically.
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import { Upload } from '@aws-sdk/lib-storage';
|
|
197
|
+
|
|
198
|
+
const upload = new Upload({
|
|
199
|
+
client: s3,
|
|
200
|
+
params: {
|
|
201
|
+
Bucket: 'my-bucket',
|
|
202
|
+
Key: 'videos/large-file.mp4',
|
|
203
|
+
Body: readableStream,
|
|
204
|
+
ContentType: 'video/mp4',
|
|
205
|
+
},
|
|
206
|
+
queueSize: 4, // Parallel upload threads
|
|
207
|
+
partSize: 10 * 1024 * 1024, // 10MB per part (minimum 5MB)
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
upload.on('httpUploadProgress', (progress) => {
|
|
211
|
+
console.log(`${progress.loaded}/${progress.total} bytes`);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
await upload.done();
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## CORS Configuration
|
|
218
|
+
|
|
219
|
+
Required for browser-based direct uploads via presigned URLs:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { PutBucketCorsCommand } from '@aws-sdk/client-s3';
|
|
223
|
+
|
|
224
|
+
await s3.send(new PutBucketCorsCommand({
|
|
225
|
+
Bucket: 'my-bucket',
|
|
226
|
+
CORSConfiguration: {
|
|
227
|
+
CORSRules: [
|
|
228
|
+
{
|
|
229
|
+
AllowedOrigins: ['https://myapp.com'],
|
|
230
|
+
AllowedMethods: ['GET', 'PUT', 'POST'],
|
|
231
|
+
AllowedHeaders: ['*'],
|
|
232
|
+
ExposeHeaders: ['ETag'],
|
|
233
|
+
MaxAgeSeconds: 3600,
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
}));
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Bucket Policy
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { PutBucketPolicyCommand } from '@aws-sdk/client-s3';
|
|
244
|
+
|
|
245
|
+
// Public read for a specific prefix (e.g., static assets)
|
|
246
|
+
await s3.send(new PutBucketPolicyCommand({
|
|
247
|
+
Bucket: 'my-bucket',
|
|
248
|
+
Policy: JSON.stringify({
|
|
249
|
+
Version: '2012-10-17',
|
|
250
|
+
Statement: [
|
|
251
|
+
{
|
|
252
|
+
Sid: 'PublicReadAssets',
|
|
253
|
+
Effect: 'Allow',
|
|
254
|
+
Principal: '*',
|
|
255
|
+
Action: 's3:GetObject',
|
|
256
|
+
Resource: 'arn:aws:s3:::my-bucket/public/*',
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
}),
|
|
260
|
+
}));
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Lifecycle Rules
|
|
264
|
+
|
|
265
|
+
Automatically transition or expire objects:
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
import { PutBucketLifecycleConfigurationCommand } from '@aws-sdk/client-s3';
|
|
269
|
+
|
|
270
|
+
await s3.send(new PutBucketLifecycleConfigurationCommand({
|
|
271
|
+
Bucket: 'my-bucket',
|
|
272
|
+
LifecycleConfiguration: {
|
|
273
|
+
Rules: [
|
|
274
|
+
{
|
|
275
|
+
ID: 'archive-old-logs',
|
|
276
|
+
Status: 'Enabled',
|
|
277
|
+
Filter: { Prefix: 'logs/' },
|
|
278
|
+
Transitions: [
|
|
279
|
+
{ Days: 30, StorageClass: 'STANDARD_IA' },
|
|
280
|
+
{ Days: 90, StorageClass: 'GLACIER' },
|
|
281
|
+
],
|
|
282
|
+
Expiration: { Days: 365 },
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
ID: 'cleanup-temp',
|
|
286
|
+
Status: 'Enabled',
|
|
287
|
+
Filter: { Prefix: 'tmp/' },
|
|
288
|
+
Expiration: { Days: 1 },
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
ID: 'abort-incomplete-uploads',
|
|
292
|
+
Status: 'Enabled',
|
|
293
|
+
Filter: { Prefix: '' },
|
|
294
|
+
AbortIncompleteMultipartUpload: { DaysAfterInitiation: 7 },
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
},
|
|
298
|
+
}));
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Versioning
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import { PutBucketVersioningCommand } from '@aws-sdk/client-s3';
|
|
305
|
+
|
|
306
|
+
await s3.send(new PutBucketVersioningCommand({
|
|
307
|
+
Bucket: 'my-bucket',
|
|
308
|
+
VersioningConfiguration: { Status: 'Enabled' },
|
|
309
|
+
}));
|
|
310
|
+
|
|
311
|
+
// Retrieve a specific version
|
|
312
|
+
import { GetObjectCommand } from '@aws-sdk/client-s3';
|
|
313
|
+
const response = await s3.send(new GetObjectCommand({
|
|
314
|
+
Bucket: 'my-bucket',
|
|
315
|
+
Key: 'config.json',
|
|
316
|
+
VersionId: 'abc123',
|
|
317
|
+
}));
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Server-Side Encryption
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
// SSE-S3 (AWS-managed keys) — simplest, no extra cost
|
|
324
|
+
await s3.send(new PutObjectCommand({
|
|
325
|
+
Bucket: 'my-bucket',
|
|
326
|
+
Key: 'secret.pdf',
|
|
327
|
+
Body: fileBuffer,
|
|
328
|
+
ServerSideEncryption: 'AES256',
|
|
329
|
+
}));
|
|
330
|
+
|
|
331
|
+
// SSE-KMS (customer-managed keys via KMS)
|
|
332
|
+
await s3.send(new PutObjectCommand({
|
|
333
|
+
Bucket: 'my-bucket',
|
|
334
|
+
Key: 'secret.pdf',
|
|
335
|
+
Body: fileBuffer,
|
|
336
|
+
ServerSideEncryption: 'aws:kms',
|
|
337
|
+
SSEKMSKeyId: 'arn:aws:kms:us-east-1:123456:key/abc-def',
|
|
338
|
+
}));
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## CloudFront CDN Integration
|
|
342
|
+
|
|
343
|
+
Serve S3 objects through CloudFront for global caching and HTTPS:
|
|
344
|
+
|
|
345
|
+
1. Create a CloudFront Origin Access Control (OAC)
|
|
346
|
+
2. Point CloudFront origin to the S3 bucket
|
|
347
|
+
3. Update bucket policy to allow CloudFront access only
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"Version": "2012-10-17",
|
|
352
|
+
"Statement": [{
|
|
353
|
+
"Sid": "AllowCloudFrontOAC",
|
|
354
|
+
"Effect": "Allow",
|
|
355
|
+
"Principal": { "Service": "cloudfront.amazonaws.com" },
|
|
356
|
+
"Action": "s3:GetObject",
|
|
357
|
+
"Resource": "arn:aws:s3:::my-bucket/*",
|
|
358
|
+
"Condition": {
|
|
359
|
+
"StringEquals": {
|
|
360
|
+
"AWS:SourceArn": "arn:aws:cloudfront::123456:distribution/EDFDVBD6EXAMPLE"
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}]
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Event Notifications
|
|
368
|
+
|
|
369
|
+
Trigger Lambda, SQS, or SNS on S3 events:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
import { PutBucketNotificationConfigurationCommand } from '@aws-sdk/client-s3';
|
|
373
|
+
|
|
374
|
+
await s3.send(new PutBucketNotificationConfigurationCommand({
|
|
375
|
+
Bucket: 'my-bucket',
|
|
376
|
+
NotificationConfiguration: {
|
|
377
|
+
LambdaFunctionConfigurations: [
|
|
378
|
+
{
|
|
379
|
+
LambdaFunctionArn: 'arn:aws:lambda:us-east-1:123456:function:process-upload',
|
|
380
|
+
Events: ['s3:ObjectCreated:*'],
|
|
381
|
+
Filter: {
|
|
382
|
+
Key: { FilterRules: [{ Name: 'prefix', Value: 'uploads/' }] },
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
},
|
|
387
|
+
}));
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## Anti-Patterns
|
|
391
|
+
|
|
392
|
+
| Anti-Pattern | Why It Fails | Correct Approach |
|
|
393
|
+
|-------------|-------------|-----------------|
|
|
394
|
+
| Using SDK v2 (`aws-sdk`) | Deprecated, large bundle, no tree-shaking | Use `@aws-sdk/client-s3` (v3) |
|
|
395
|
+
| Storing files in the database | DB bloat, slow queries, expensive backups | Store in S3, save the key in DB |
|
|
396
|
+
| Public buckets without policy scoping | Full bucket exposure | Restrict `Principal` and `Resource` in policy |
|
|
397
|
+
| Long-lived presigned URLs | Security risk if URL leaks | Set `expiresIn` to minutes, not days |
|
|
398
|
+
| Not setting `ContentType` on upload | Files download instead of display in browser | Always set `ContentType` explicitly |
|
|
399
|
+
| Listing all objects without pagination | Timeout on large buckets | Use `ContinuationToken` pagination |
|
|
400
|
+
| Not aborting incomplete multipart uploads | Phantom storage charges | Add lifecycle rule to abort after N days |
|
|
401
|
+
| Using `forcePathStyle` with AWS S3 | Path-style is deprecated for AWS | Only use `forcePathStyle` for MinIO/local |
|
|
402
|
+
|
|
403
|
+
## Decision Guide
|
|
404
|
+
|
|
405
|
+
| Need | S3 Feature |
|
|
406
|
+
|------|-----------|
|
|
407
|
+
| Browser direct upload | Presigned PUT URL + CORS |
|
|
408
|
+
| Browser direct download | Presigned GET URL |
|
|
409
|
+
| Large file upload (>100MB) | Multipart upload via `@aws-sdk/lib-storage` |
|
|
410
|
+
| Global low-latency reads | CloudFront CDN in front of S3 |
|
|
411
|
+
| Automatic cleanup of old files | Lifecycle rules with expiration |
|
|
412
|
+
| File version history | Bucket versioning |
|
|
413
|
+
| Trigger processing on upload | Event notifications to Lambda/SQS |
|
|
414
|
+
| Encryption at rest | SSE-S3 (default) or SSE-KMS (custom keys) |
|
|
415
|
+
| S3 locally for development | MinIO with `forcePathStyle: true` |
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cloudflare-r2
|
|
3
|
+
description: "Cloudflare R2 object storage patterns covering Workers bindings, S3-compatible API, presigned URLs, multipart uploads, CORS, and lifecycle rules. Use when implementing file storage with Cloudflare R2."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
source: self
|
|
6
|
+
date_added: "2026-03-14"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Cloudflare R2
|
|
10
|
+
|
|
11
|
+
S3-compatible object storage with zero egress fees. Access via Workers bindings (fastest, no credentials needed) or S3-compatible API (for external clients).
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
- Project uses Cloudflare Workers/Pages and needs file storage
|
|
16
|
+
- Need S3-compatible storage without egress costs
|
|
17
|
+
- Serving static assets, user uploads, or media files
|
|
18
|
+
- Need presigned URLs for direct browser uploads
|
|
19
|
+
|
|
20
|
+
## When NOT to Use
|
|
21
|
+
|
|
22
|
+
- Need a full CDN with image transformations (use Cloudflare Images instead)
|
|
23
|
+
- Using AWS ecosystem exclusively (use S3 directly)
|
|
24
|
+
- Need object versioning (R2 does not support versioning)
|
|
25
|
+
|
|
26
|
+
## Workers Binding (Recommended)
|
|
27
|
+
|
|
28
|
+
The fastest integration — no credentials, no network hop.
|
|
29
|
+
|
|
30
|
+
### Setup (wrangler.toml)
|
|
31
|
+
|
|
32
|
+
```toml
|
|
33
|
+
[[r2_buckets]]
|
|
34
|
+
binding = "STORAGE"
|
|
35
|
+
bucket_name = "my-bucket"
|
|
36
|
+
preview_bucket_name = "my-bucket-preview"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Basic Operations
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
interface Env { STORAGE: R2Bucket; }
|
|
43
|
+
|
|
44
|
+
export default {
|
|
45
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
46
|
+
const url = new URL(request.url);
|
|
47
|
+
const key = url.pathname.slice(1); // Remove leading /
|
|
48
|
+
|
|
49
|
+
switch (request.method) {
|
|
50
|
+
case 'PUT': {
|
|
51
|
+
const object = await env.STORAGE.put(key, request.body, {
|
|
52
|
+
httpMetadata: {
|
|
53
|
+
contentType: request.headers.get('content-type') ?? 'application/octet-stream',
|
|
54
|
+
},
|
|
55
|
+
customMetadata: { uploadedBy: 'worker', timestamp: Date.now().toString() },
|
|
56
|
+
});
|
|
57
|
+
return Response.json({ key: object.key, size: object.size, etag: object.httpEtag });
|
|
58
|
+
}
|
|
59
|
+
case 'GET': {
|
|
60
|
+
const object = await env.STORAGE.get(key);
|
|
61
|
+
if (!object) return new Response('Not Found', { status: 404 });
|
|
62
|
+
|
|
63
|
+
const headers = new Headers();
|
|
64
|
+
object.writeHttpMetadata(headers);
|
|
65
|
+
headers.set('etag', object.httpEtag);
|
|
66
|
+
headers.set('cache-control', 'public, max-age=31536000, immutable');
|
|
67
|
+
return new Response(object.body, { headers });
|
|
68
|
+
}
|
|
69
|
+
case 'DELETE': {
|
|
70
|
+
await env.STORAGE.delete(key);
|
|
71
|
+
return new Response(null, { status: 204 });
|
|
72
|
+
}
|
|
73
|
+
default:
|
|
74
|
+
return new Response('Method Not Allowed', { status: 405 });
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
} satisfies ExportedHandler<Env>;
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### List Objects
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const listed = await env.STORAGE.list({
|
|
84
|
+
prefix: 'uploads/user-123/',
|
|
85
|
+
limit: 100,
|
|
86
|
+
cursor: previousCursor, // For pagination
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
for (const object of listed.objects) {
|
|
90
|
+
console.log(`${object.key} — ${object.size} bytes — ${object.uploaded}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (listed.truncated) {
|
|
94
|
+
// More results available — use listed.cursor for next page
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## S3-Compatible API (External Clients)
|
|
99
|
+
|
|
100
|
+
For server-side code outside Workers, use the AWS SDK with R2 endpoint.
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
104
|
+
|
|
105
|
+
const r2 = new S3Client({
|
|
106
|
+
region: 'auto',
|
|
107
|
+
endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
|
108
|
+
credentials: {
|
|
109
|
+
accessKeyId: R2_ACCESS_KEY_ID,
|
|
110
|
+
secretAccessKey: R2_SECRET_ACCESS_KEY,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Upload
|
|
115
|
+
await r2.send(new PutObjectCommand({
|
|
116
|
+
Bucket: 'my-bucket',
|
|
117
|
+
Key: 'uploads/photo.jpg',
|
|
118
|
+
Body: fileBuffer,
|
|
119
|
+
ContentType: 'image/jpeg',
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
// Download
|
|
123
|
+
const response = await r2.send(new GetObjectCommand({
|
|
124
|
+
Bucket: 'my-bucket',
|
|
125
|
+
Key: 'uploads/photo.jpg',
|
|
126
|
+
}));
|
|
127
|
+
const body = await response.Body?.transformToByteArray();
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Presigned URLs (Direct Browser Upload)
|
|
131
|
+
|
|
132
|
+
Generate server-side, use client-side — no credentials exposed to the browser.
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
136
|
+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
137
|
+
|
|
138
|
+
const r2 = new S3Client({
|
|
139
|
+
region: 'auto',
|
|
140
|
+
endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
|
141
|
+
credentials: { accessKeyId: R2_ACCESS_KEY_ID, secretAccessKey: R2_SECRET_ACCESS_KEY },
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Server: generate upload URL
|
|
145
|
+
async function generateUploadUrl(key: string, contentType: string): Promise<string> {
|
|
146
|
+
const command = new PutObjectCommand({
|
|
147
|
+
Bucket: 'my-bucket',
|
|
148
|
+
Key: key,
|
|
149
|
+
ContentType: contentType,
|
|
150
|
+
});
|
|
151
|
+
return getSignedUrl(r2, command, { expiresIn: 3600 }); // 1 hour
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Client: upload directly to R2
|
|
155
|
+
async function uploadFile(file: File) {
|
|
156
|
+
const res = await fetch('/api/upload-url', {
|
|
157
|
+
method: 'POST',
|
|
158
|
+
body: JSON.stringify({ filename: file.name, contentType: file.type }),
|
|
159
|
+
});
|
|
160
|
+
const { url } = await res.json();
|
|
161
|
+
|
|
162
|
+
await fetch(url, {
|
|
163
|
+
method: 'PUT',
|
|
164
|
+
body: file,
|
|
165
|
+
headers: { 'Content-Type': file.type },
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Multipart Uploads (Large Files)
|
|
171
|
+
|
|
172
|
+
For files over 100MB, use multipart uploads via Workers binding.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// Create multipart upload
|
|
176
|
+
const upload = await env.STORAGE.createMultipartUpload('large-file.zip');
|
|
177
|
+
|
|
178
|
+
// Upload parts (minimum 5MB per part except last)
|
|
179
|
+
const parts: R2UploadedPart[] = [];
|
|
180
|
+
let partNumber = 1;
|
|
181
|
+
for (const chunk of fileChunks) {
|
|
182
|
+
const part = await upload.uploadPart(partNumber, chunk);
|
|
183
|
+
parts.push(part);
|
|
184
|
+
partNumber++;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Complete upload
|
|
188
|
+
const object = await upload.complete(parts);
|
|
189
|
+
|
|
190
|
+
// Or abort if something fails
|
|
191
|
+
// await upload.abort();
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## CORS Configuration
|
|
195
|
+
|
|
196
|
+
Configure via the Cloudflare dashboard or API:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
[
|
|
200
|
+
{
|
|
201
|
+
"AllowedOrigins": ["https://example.com"],
|
|
202
|
+
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
|
|
203
|
+
"AllowedHeaders": ["Content-Type", "Authorization"],
|
|
204
|
+
"MaxAgeSeconds": 3600
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Public Bucket Access
|
|
210
|
+
|
|
211
|
+
Enable via `r2.dev` subdomain in dashboard, or use a custom domain with a Worker:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// Serve public assets via Worker + custom domain
|
|
215
|
+
export default {
|
|
216
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
217
|
+
const key = new URL(request.url).pathname.slice(1);
|
|
218
|
+
const object = await env.STORAGE.get(key);
|
|
219
|
+
if (!object) return new Response('Not Found', { status: 404 });
|
|
220
|
+
|
|
221
|
+
const headers = new Headers();
|
|
222
|
+
object.writeHttpMetadata(headers);
|
|
223
|
+
headers.set('cache-control', 'public, max-age=86400');
|
|
224
|
+
return new Response(object.body, { headers });
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Key Limits
|
|
230
|
+
|
|
231
|
+
| Limit | Value |
|
|
232
|
+
|-------|-------|
|
|
233
|
+
| Max object size (single PUT) | 5 GB |
|
|
234
|
+
| Max object size (multipart) | 5 TB |
|
|
235
|
+
| Min multipart part size | 5 MB (except last part) |
|
|
236
|
+
| Max parts per multipart upload | 10,000 |
|
|
237
|
+
| Max key length | 1,024 bytes |
|
|
238
|
+
| Max custom metadata per object | 2 KB |
|
|
239
|
+
| Presigned URL max expiry | 7 days (604,800 seconds) |
|
|
240
|
+
|
|
241
|
+
## Anti-Patterns
|
|
242
|
+
|
|
243
|
+
| Don't | Do |
|
|
244
|
+
|-------|-----|
|
|
245
|
+
| Use S3 API from Workers when you can bind directly | Use Workers bindings — faster, no credentials needed |
|
|
246
|
+
| Expose R2 API credentials to the browser | Use presigned URLs for direct browser uploads |
|
|
247
|
+
| Store credentials in wrangler.toml | Use `wrangler secret put` for API keys |
|
|
248
|
+
| Upload large files in a single PUT | Use multipart uploads for files over 100 MB |
|
|
249
|
+
| Skip Content-Type on uploads | Always set `contentType` — R2 won't guess it |
|
|
250
|
+
| Use `r2.dev` subdomain in production | Use a custom domain for branded, cacheable URLs |
|
|
251
|
+
| Forget to set cache headers on responses | Set `cache-control` headers for CDN caching |
|
|
252
|
+
| List all objects without pagination | Always use `limit` and `cursor` for large buckets |
|