create-ailk 0.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/LICENSE +201 -0
- package/README.md +39 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +80 -0
- package/dist/copy.d.ts +8 -0
- package/dist/copy.js +109 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/lib/pro-callout.d.ts +12 -0
- package/dist/lib/pro-callout.js +20 -0
- package/dist/parse-args.d.ts +13 -0
- package/dist/parse-args.js +81 -0
- package/dist/programmatic.d.ts +49 -0
- package/dist/programmatic.js +89 -0
- package/dist/substitute.d.ts +31 -0
- package/dist/substitute.js +45 -0
- package/dist/validate.d.ts +8 -0
- package/dist/validate.js +70 -0
- package/package.json +47 -0
- package/templates/.claude/.gitkeep +0 -0
- package/templates/.claude/agents/web.md +80 -0
- package/templates/.claude/rules/architecture.md +62 -0
- package/templates/.claude/rules/preserve-existing-style.md +51 -0
- package/templates/.claude/skills/README.md +43 -0
- package/templates/.claude/skills/add-schema/SKILL.md +270 -0
- package/templates/.claude/skills/add-schema/references/conflict-handling.md +200 -0
- package/templates/.claude/skills/add-schema/references/file-finding.md +123 -0
- package/templates/.claude/skills/add-schema/references/schema-types.md +131 -0
- package/templates/.claude/skills/audit-site/SKILL.md +213 -0
- package/templates/.claude/skills/audit-site/references/common-errors.md +113 -0
- package/templates/.claude/skills/audit-site/references/findings-glossary.md +138 -0
- package/templates/.claude/skills/audit-site/references/severity-levels.md +114 -0
- package/templates/.claude/skills/provision-config/SKILL.md +243 -0
- package/templates/.claude/skills/provision-config/references/env-vars-template.md +184 -0
- package/templates/.claude/skills/provision-config/references/runbook-template.md +248 -0
- package/templates/.claude/skills/provision-config/references/vercel-json-template.md +98 -0
- package/templates/.claude/skills/scaffold-auth/SKILL.md +261 -0
- package/templates/.claude/skills/scaffold-auth/references/env-vars.md +91 -0
- package/templates/.claude/skills/scaffold-auth/references/oauth-app-setup.md +171 -0
- package/templates/.claude/skills/scaffold-commerce/SKILL.md +310 -0
- package/templates/.claude/skills/scaffold-commerce/references/lookup-keys-template.md +71 -0
- package/templates/.claude/skills/scaffold-commerce/references/marketplace-brand-pages.md +83 -0
- package/templates/.claude/skills/scaffold-commerce/templates/marketplace-cta-route.tsx.tmpl +72 -0
- package/templates/.claude/skills/scaffold-page/SKILL.md +243 -0
- package/templates/.claude/skills/scaffold-page/references/page-types.md +169 -0
- package/templates/.claude/skills/scaffold-page/templates/content.mdx.tmpl +28 -0
- package/templates/.claude/skills/scaffold-page/templates/route.tsx.tmpl +28 -0
- package/templates/.claude/skills/suggest-site-pages/SKILL.md +242 -0
- package/templates/.claude/skills/suggest-site-pages/references/categories.md +287 -0
- package/templates/.env.example +205 -0
- package/templates/.gitkeep +2 -0
- package/templates/CLAUDE.md +142 -0
- package/templates/CONVENTIONS.md +222 -0
- package/templates/README.md +110 -0
- package/templates/apps/api/.env.example +40 -0
- package/templates/apps/api/CLAUDE.md +63 -0
- package/templates/apps/api/api/index.ts +144 -0
- package/templates/apps/api/jest.config.cjs +74 -0
- package/templates/apps/api/package.json +54 -0
- package/templates/apps/api/src/__tests__/factories/content-fixture.ts +138 -0
- package/templates/apps/api/src/__tests__/factories/index.ts +70 -0
- package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +82 -0
- package/templates/apps/api/src/__tests__/index.test.ts +118 -0
- package/templates/apps/api/src/__tests__/server.test.ts +207 -0
- package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +126 -0
- package/templates/apps/api/src/__tests__/setup.ts +24 -0
- package/templates/apps/api/src/cli.ts +30 -0
- package/templates/apps/api/src/config/__tests__/index.test.ts +97 -0
- package/templates/apps/api/src/config/index.ts +56 -0
- package/templates/apps/api/src/index.ts +32 -0
- package/templates/apps/api/src/lib/__mocks__/prisma-client.js +15 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +45 -0
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +178 -0
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +100 -0
- package/templates/apps/api/src/lib/__tests__/errors.test.ts +94 -0
- package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +144 -0
- package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +8 -0
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +227 -0
- package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +125 -0
- package/templates/apps/api/src/lib/__tests__/prisma.test.ts +165 -0
- package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +129 -0
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +74 -0
- package/templates/apps/api/src/lib/content-adapter.ts +86 -0
- package/templates/apps/api/src/lib/error-serializer.ts +77 -0
- package/templates/apps/api/src/lib/errors.ts +95 -0
- package/templates/apps/api/src/lib/file-fallback.ts +87 -0
- package/templates/apps/api/src/lib/lead-capture-store.ts +110 -0
- package/templates/apps/api/src/lib/locales.ts +201 -0
- package/templates/apps/api/src/lib/outbound-http.ts +122 -0
- package/templates/apps/api/src/lib/prisma.ts +21 -0
- package/templates/apps/api/src/lib/require-paid-tier.ts +53 -0
- package/templates/apps/api/src/lib/stripe.ts +30 -0
- package/templates/apps/api/src/lib/webhook-idempotency.ts +92 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +111 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +172 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +119 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +138 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +149 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +139 -0
- package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +175 -0
- package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +76 -0
- package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +153 -0
- package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +72 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +292 -0
- package/templates/apps/api/src/middleware/auth.ts +246 -0
- package/templates/apps/api/src/middleware/rate-limit.ts +132 -0
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +129 -0
- package/templates/apps/api/src/openapi/index.ts +12 -0
- package/templates/apps/api/src/openapi/spec.ts +408 -0
- package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +193 -0
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +201 -0
- package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +294 -0
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +486 -0
- package/templates/apps/api/src/routes/auth/tokens.ts +199 -0
- package/templates/apps/api/src/routes/auth/user.ts +244 -0
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +588 -0
- package/templates/apps/api/src/routes/checkout/index.ts +13 -0
- package/templates/apps/api/src/routes/checkout/sessions.ts +185 -0
- package/templates/apps/api/src/routes/content/__tests__/create.test.ts +239 -0
- package/templates/apps/api/src/routes/content/__tests__/delete.test.ts +201 -0
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +141 -0
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +122 -0
- package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +44 -0
- package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +118 -0
- package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +51 -0
- package/templates/apps/api/src/routes/content/__tests__/update.test.ts +252 -0
- package/templates/apps/api/src/routes/content/create.ts +114 -0
- package/templates/apps/api/src/routes/content/delete.ts +81 -0
- package/templates/apps/api/src/routes/content/get-page.ts +98 -0
- package/templates/apps/api/src/routes/content/index.ts +32 -0
- package/templates/apps/api/src/routes/content/list-pages.ts +83 -0
- package/templates/apps/api/src/routes/content/list-types.ts +19 -0
- package/templates/apps/api/src/routes/content/rate-limit.ts +13 -0
- package/templates/apps/api/src/routes/content/slug.ts +9 -0
- package/templates/apps/api/src/routes/content/update.ts +111 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +415 -0
- package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +165 -0
- package/templates/apps/api/src/routes/leads/index.ts +130 -0
- package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +296 -0
- package/templates/apps/api/src/routes/test/auth/session.ts +141 -0
- package/templates/apps/api/src/routes/webhooks/README.md +57 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +247 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +198 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +633 -0
- package/templates/apps/api/src/routes/webhooks/index.ts +41 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +253 -0
- package/templates/apps/api/src/server.ts +157 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +395 -0
- package/templates/apps/api/src/services/enrichment-shim.ts +53 -0
- package/templates/apps/api/src/services/lead-routing.ts +338 -0
- package/templates/apps/api/tsconfig.json +34 -0
- package/templates/apps/api/vercel.json +17 -0
- package/templates/apps/mcp/.env.example +52 -0
- package/templates/apps/mcp/CLAUDE.md +84 -0
- package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +52 -0
- package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +46 -0
- package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +36 -0
- package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +54 -0
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +110 -0
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +213 -0
- package/templates/apps/mcp/__tests__/audit.test.ts +217 -0
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +52 -0
- package/templates/apps/mcp/__tests__/create_page.test.ts +201 -0
- package/templates/apps/mcp/__tests__/delete_page.test.ts +176 -0
- package/templates/apps/mcp/__tests__/get_business_hours.test.ts +82 -0
- package/templates/apps/mcp/__tests__/get_faq.test.ts +80 -0
- package/templates/apps/mcp/__tests__/get_locations.test.ts +65 -0
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +90 -0
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +80 -0
- package/templates/apps/mcp/__tests__/get_site_info.test.ts +81 -0
- package/templates/apps/mcp/__tests__/http-transport.test.ts +323 -0
- package/templates/apps/mcp/__tests__/lib/errors.test.ts +75 -0
- package/templates/apps/mcp/__tests__/lib/require-paid-tier.test.ts +75 -0
- package/templates/apps/mcp/__tests__/list_pages.test.ts +112 -0
- package/templates/apps/mcp/__tests__/locale.test.ts +135 -0
- package/templates/apps/mcp/__tests__/parity.test.ts +205 -0
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +34 -0
- package/templates/apps/mcp/__tests__/read_content.test.ts +153 -0
- package/templates/apps/mcp/__tests__/request_callback.test.ts +163 -0
- package/templates/apps/mcp/__tests__/search_content.test.ts +153 -0
- package/templates/apps/mcp/__tests__/server.test.ts +115 -0
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +165 -0
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +161 -0
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +227 -0
- package/templates/apps/mcp/__tests__/tools/scaffold.test.ts +237 -0
- package/templates/apps/mcp/__tests__/update_page.test.ts +195 -0
- package/templates/apps/mcp/jest.config.cjs +82 -0
- package/templates/apps/mcp/package.json +37 -0
- package/templates/apps/mcp/src/abuse/daily-cap.ts +47 -0
- package/templates/apps/mcp/src/abuse/email-validator.ts +25 -0
- package/templates/apps/mcp/src/abuse/honeypot.ts +21 -0
- package/templates/apps/mcp/src/abuse/index.ts +111 -0
- package/templates/apps/mcp/src/abuse/user-agent-deny.ts +58 -0
- package/templates/apps/mcp/src/http-transport.ts +303 -0
- package/templates/apps/mcp/src/index.ts +67 -0
- package/templates/apps/mcp/src/lib/audit-single-page.ts +194 -0
- package/templates/apps/mcp/src/lib/errors.ts +61 -0
- package/templates/apps/mcp/src/lib/locales.ts +171 -0
- package/templates/apps/mcp/src/lib/require-paid-tier.ts +44 -0
- package/templates/apps/mcp/src/lib/resolve-locale.ts +30 -0
- package/templates/apps/mcp/src/server.ts +139 -0
- package/templates/apps/mcp/src/tools/audit.ts +103 -0
- package/templates/apps/mcp/src/tools/capture_lead.ts +52 -0
- package/templates/apps/mcp/src/tools/create_page.ts +95 -0
- package/templates/apps/mcp/src/tools/delete_page.ts +73 -0
- package/templates/apps/mcp/src/tools/get_business_hours.ts +66 -0
- package/templates/apps/mcp/src/tools/get_faq.ts +69 -0
- package/templates/apps/mcp/src/tools/get_locations.ts +85 -0
- package/templates/apps/mcp/src/tools/get_offerings.ts +66 -0
- package/templates/apps/mcp/src/tools/get_pricing.ts +74 -0
- package/templates/apps/mcp/src/tools/get_site_info.ts +84 -0
- package/templates/apps/mcp/src/tools/index.ts +125 -0
- package/templates/apps/mcp/src/tools/list_pages.ts +72 -0
- package/templates/apps/mcp/src/tools/purchase.ts +89 -0
- package/templates/apps/mcp/src/tools/read_content.ts +61 -0
- package/templates/apps/mcp/src/tools/request_callback.ts +51 -0
- package/templates/apps/mcp/src/tools/scaffold.ts +119 -0
- package/templates/apps/mcp/src/tools/search_content.ts +59 -0
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +47 -0
- package/templates/apps/mcp/src/tools/update_page.ts +91 -0
- package/templates/apps/mcp/tsconfig.json +19 -0
- package/templates/apps/web/.env.example +47 -0
- package/templates/apps/web/CLAUDE.md +81 -0
- package/templates/apps/web/__tests__/auth/adversarial/cookie-attributes.test.ts +94 -0
- package/templates/apps/web/__tests__/auth/adversarial/oauth-state-parameter.test.ts +75 -0
- package/templates/apps/web/__tests__/auth/adversarial/redirect-uri-allowlist.test.ts +82 -0
- package/templates/apps/web/__tests__/auth/env-helpers.test.ts +168 -0
- package/templates/apps/web/__tests__/authority-list-routes.test.tsx +208 -0
- package/templates/apps/web/__tests__/better-stack.test.ts +66 -0
- package/templates/apps/web/__tests__/blog-dir-resolution.test.ts +87 -0
- package/templates/apps/web/__tests__/blog-source-populated.test.ts +130 -0
- package/templates/apps/web/__tests__/data-testid-coverage.test.tsx +60 -0
- package/templates/apps/web/__tests__/google-analytics.test.tsx +104 -0
- package/templates/apps/web/__tests__/i18n/middleware.test.ts +119 -0
- package/templates/apps/web/__tests__/i18n/routing.test.ts +114 -0
- package/templates/apps/web/__tests__/i18n/translations.test.ts +191 -0
- package/templates/apps/web/__tests__/json-ld.test.ts +98 -0
- package/templates/apps/web/__tests__/knowledge-events-routes.test.tsx +580 -0
- package/templates/apps/web/__tests__/layout-stealth.test.ts +39 -0
- package/templates/apps/web/__tests__/lighthouse-fixtures/improvement-image-shrink.tsx +103 -0
- package/templates/apps/web/__tests__/lighthouse-fixtures/override-fixture.md +114 -0
- package/templates/apps/web/__tests__/lighthouse-fixtures/regression-bloat.tsx +94 -0
- package/templates/apps/web/__tests__/page.test.tsx +230 -0
- package/templates/apps/web/__tests__/products-services-phase1.test.tsx +321 -0
- package/templates/apps/web/__tests__/projects-routes.test.tsx +392 -0
- package/templates/apps/web/__tests__/resources-downloads-integrations-phase2.test.tsx +475 -0
- package/templates/apps/web/__tests__/routes/ai-plugin-json.test.ts +53 -0
- package/templates/apps/web/__tests__/routes/blog-route.test.tsx +191 -0
- package/templates/apps/web/__tests__/routes/llms-txt.test.ts +123 -0
- package/templates/apps/web/__tests__/routes/robots-txt.test.ts +52 -0
- package/templates/apps/web/__tests__/routes/sitemap-xml.test.ts +78 -0
- package/templates/apps/web/__tests__/routes/well-known-mcp.test.ts +203 -0
- package/templates/apps/web/__tests__/section-routes.test.tsx +693 -0
- package/templates/apps/web/__tests__/security-headers.test.ts +201 -0
- package/templates/apps/web/__tests__/sentry-config.test.ts +116 -0
- package/templates/apps/web/__tests__/setup.ts +82 -0
- package/templates/apps/web/__tests__/sitemap-locales.test.ts +415 -0
- package/templates/apps/web/__tests__/standalone-informational-routes.test.tsx +844 -0
- package/templates/apps/web/app/.well-known/ai-plugin.json/route.ts +81 -0
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +110 -0
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +58 -0
- package/templates/apps/web/app/[locale]/__tests__/layout.test.tsx +120 -0
- package/templates/apps/web/app/[locale]/__tests__/page-renderer-migration.test.tsx +202 -0
- package/templates/apps/web/app/[locale]/about/page.tsx +31 -0
- package/templates/apps/web/app/[locale]/blog/[[...slug]]/page.tsx +173 -0
- package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +45 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +117 -0
- package/templates/apps/web/app/[locale]/careers/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/case-studies/[slug]/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +113 -0
- package/templates/apps/web/app/[locale]/case-studies/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/clients/page.tsx +27 -0
- package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +130 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +152 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +92 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +79 -0
- package/templates/apps/web/app/[locale]/contact/error.tsx +24 -0
- package/templates/apps/web/app/[locale]/contact/page.tsx +38 -0
- package/templates/apps/web/app/[locale]/courses/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +119 -0
- package/templates/apps/web/app/[locale]/courses/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/dev/purchase/__tests__/actions.test.ts +160 -0
- package/templates/apps/web/app/[locale]/dev/purchase/error.tsx +25 -0
- package/templates/apps/web/app/[locale]/dev/purchase/page.tsx +117 -0
- package/templates/apps/web/app/[locale]/dev/purchase/purchase.actions.ts +58 -0
- package/templates/apps/web/app/[locale]/docs/[[...slug]]/page.tsx +118 -0
- package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +72 -0
- package/templates/apps/web/app/[locale]/downloads/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/events/[slug]/page.tsx +47 -0
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +130 -0
- package/templates/apps/web/app/[locale]/events/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/faq/page.tsx +36 -0
- package/templates/apps/web/app/[locale]/how-to/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +78 -0
- package/templates/apps/web/app/[locale]/how-to/page.tsx +40 -0
- package/templates/apps/web/app/[locale]/integrations/[slug]/page.tsx +43 -0
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +129 -0
- package/templates/apps/web/app/[locale]/integrations/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/launch-service/page.tsx +31 -0
- package/templates/apps/web/app/[locale]/layout.tsx +241 -0
- package/templates/apps/web/app/[locale]/page.tsx +41 -0
- package/templates/apps/web/app/[locale]/partners/[slug]/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +113 -0
- package/templates/apps/web/app/[locale]/partners/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/products/[slug]/page.tsx +43 -0
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +129 -0
- package/templates/apps/web/app/[locale]/products/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/projects/[slug]/page.tsx +39 -0
- package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +138 -0
- package/templates/apps/web/app/[locale]/projects/page.tsx +30 -0
- package/templates/apps/web/app/[locale]/resources/[slug]/page.tsx +51 -0
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +117 -0
- package/templates/apps/web/app/[locale]/resources/page.tsx +27 -0
- package/templates/apps/web/app/[locale]/services/[slug]/page.tsx +43 -0
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +129 -0
- package/templates/apps/web/app/[locale]/services/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +81 -0
- package/templates/apps/web/app/[locale]/software/page.tsx +39 -0
- package/templates/apps/web/app/[locale]/tech-articles/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +82 -0
- package/templates/apps/web/app/[locale]/tech-articles/page.tsx +39 -0
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/testimonials/page.tsx +27 -0
- package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/use-cases/page.tsx +27 -0
- package/templates/apps/web/app/[locale]/whitepapers/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +82 -0
- package/templates/apps/web/app/[locale]/whitepapers/page.tsx +39 -0
- package/templates/apps/web/app/__tests__/error-boundaries.test.tsx +152 -0
- package/templates/apps/web/app/api/auth/[...all]/route.ts +16 -0
- package/templates/apps/web/app/error-fallback.tsx +75 -0
- package/templates/apps/web/app/error.tsx +23 -0
- package/templates/apps/web/app/layout.tsx +18 -0
- package/templates/apps/web/app/llms.txt/route.ts +101 -0
- package/templates/apps/web/app/not-found.tsx +48 -0
- package/templates/apps/web/app/og/__tests__/route.test.ts +164 -0
- package/templates/apps/web/app/og/route.tsx +135 -0
- package/templates/apps/web/app/robots.txt/route.ts +36 -0
- package/templates/apps/web/app/sitemap.xml/route.ts +146 -0
- package/templates/apps/web/auth.ts +141 -0
- package/templates/apps/web/components/ThemeToggle.tsx +60 -0
- package/templates/apps/web/components/google-analytics.tsx +34 -0
- package/templates/apps/web/content/en/blog/index.mdx +15 -0
- package/templates/apps/web/content/en/blog/launching-ailk.mdx +20 -0
- package/templates/apps/web/content/en/docs/getting-started.mdx +30 -0
- package/templates/apps/web/i18n/request.ts +36 -0
- package/templates/apps/web/jest.config.cjs +100 -0
- package/templates/apps/web/lib/__mocks__/next-mdx-remote-rsc.js +12 -0
- package/templates/apps/web/lib/__mocks__/source-server.js +31 -0
- package/templates/apps/web/lib/__tests__/og.test.ts +65 -0
- package/templates/apps/web/lib/auth-env.ts +66 -0
- package/templates/apps/web/lib/blog-list-data.ts +95 -0
- package/templates/apps/web/lib/blog-post-data.ts +79 -0
- package/templates/apps/web/lib/nav-config.ts +13 -0
- package/templates/apps/web/lib/observability/better-stack.ts +27 -0
- package/templates/apps/web/lib/og.ts +23 -0
- package/templates/apps/web/lib/prisma-for-auth.ts +34 -0
- package/templates/apps/web/lib/source.ts +34 -0
- package/templates/apps/web/messages/en.json +131 -0
- package/templates/apps/web/middleware.ts +80 -0
- package/templates/apps/web/next.config.mjs +167 -0
- package/templates/apps/web/package.json +62 -0
- package/templates/apps/web/public/.well-known/security.txt +17 -0
- package/templates/apps/web/public/android-chrome-192x192.png +0 -0
- package/templates/apps/web/public/android-chrome-512x512.png +0 -0
- package/templates/apps/web/public/apple-touch-icon.png +0 -0
- package/templates/apps/web/public/favicon-16x16.png +0 -0
- package/templates/apps/web/public/favicon-32x32.png +0 -0
- package/templates/apps/web/public/favicon.ico +0 -0
- package/templates/apps/web/public/favicon.svg +4 -0
- package/templates/apps/web/public/logo-dark.svg +21 -0
- package/templates/apps/web/public/logo-light.svg +21 -0
- package/templates/apps/web/public/logomark-dark.svg +4 -0
- package/templates/apps/web/public/logomark-light.svg +4 -0
- package/templates/apps/web/public/og-default.png +0 -0
- package/templates/apps/web/public/site.webmanifest +19 -0
- package/templates/apps/web/scripts/assert-content-bundled.ts +55 -0
- package/templates/apps/web/security-headers.config.ts +132 -0
- package/templates/apps/web/sentry.client.config.ts +27 -0
- package/templates/apps/web/sentry.edge.config.ts +15 -0
- package/templates/apps/web/sentry.server.config.ts +20 -0
- package/templates/apps/web/source.config.ts +78 -0
- package/templates/apps/web/src/components/SiteNav.tsx +21 -0
- package/templates/apps/web/src/lib/routes.ts +37 -0
- package/templates/apps/web/tsconfig.json +35 -0
- package/templates/apps/web/types/messages.d.ts +19 -0
- package/templates/content/.gitkeep +0 -0
- package/templates/content/CLAUDE.md +85 -0
- package/templates/content/_site.mdx +38 -0
- package/templates/content/ar/HomePage/home.mdx +123 -0
- package/templates/content/ar/_site.mdx +35 -0
- package/templates/content/de/_site.mdx +29 -0
- package/templates/content/en/.gitkeep +0 -0
- package/templates/content/en/AboutPage/about.mdx +19 -0
- package/templates/content/en/AboutPage/about.schema.json +82 -0
- package/templates/content/en/BookCall/book-call.mdx +19 -0
- package/templates/content/en/BookCall/book-call.schema.json +121 -0
- package/templates/content/en/BreadcrumbList/site-breadcrumbs.mdx +20 -0
- package/templates/content/en/CareersList/careers.mdx +24 -0
- package/templates/content/en/CaseStudiesList/case-studies.mdx +22 -0
- package/templates/content/en/CaseStudiesList/showcase.mdx +8 -0
- package/templates/content/en/CaseStudy/ailk-aeo-rollout.mdx +32 -0
- package/templates/content/en/CaseStudy/schema-builder-migration.mdx +41 -0
- package/templates/content/en/ClientsList/clients.mdx +38 -0
- package/templates/content/en/ContactPage/contact.mdx +19 -0
- package/templates/content/en/ContactPage/contact.schema.json +100 -0
- package/templates/content/en/ContactPoint/primary.mdx +14 -0
- package/templates/content/en/Course/aeo-fundamentals.mdx +37 -0
- package/templates/content/en/Course/schema-builder-workshop.mdx +62 -0
- package/templates/content/en/CoursesList/courses.mdx +22 -0
- package/templates/content/en/DownloadsList/downloads.mdx +22 -0
- package/templates/content/en/Event/aeo-office-hours-may-2026.mdx +39 -0
- package/templates/content/en/Event/ailk-launch-day-2026.mdx +35 -0
- package/templates/content/en/EventsList/events.mdx +26 -0
- package/templates/content/en/FAQPage/faq.mdx +420 -0
- package/templates/content/en/FAQPage/faq.schema.json +231 -0
- package/templates/content/en/GlossaryList/glossary.mdx +19 -0
- package/templates/content/en/GlossaryList/glossary.schema.json +300 -0
- package/templates/content/en/HomePage/home.mdx +312 -0
- package/templates/content/en/HomePage/home.schema.json +88 -0
- package/templates/content/en/HomePage/launch-service.mdx +475 -0
- package/templates/content/en/HomePage/launch-service.schema.json +138 -0
- package/templates/content/en/HowTo/add-mdx-content.mdx +38 -0
- package/templates/content/en/HowTo/configure-aeo-scoring.mdx +35 -0
- package/templates/content/en/HowTo/set-up-json-ld.mdx +36 -0
- package/templates/content/en/Integration/github-actions.mdx +31 -0
- package/templates/content/en/Integration/openai-api.mdx +26 -0
- package/templates/content/en/Integration/vercel.mdx +32 -0
- package/templates/content/en/IntegrationsList/integrations.mdx +22 -0
- package/templates/content/en/JobPosting/content-strategist.mdx +46 -0
- package/templates/content/en/JobPosting/developer-advocate.mdx +47 -0
- package/templates/content/en/JobPosting/senior-fullstack-engineer.mdx +57 -0
- package/templates/content/en/LandingPage/aeo-audit.mdx +19 -0
- package/templates/content/en/LandingPage/aeo-audit.schema.json +92 -0
- package/templates/content/en/LandingPage/agency-waitlist.mdx +340 -0
- package/templates/content/en/LandingPage/agency-waitlist.schema.json +152 -0
- package/templates/content/en/LandingPage/developers.mdx +19 -0
- package/templates/content/en/LandingPage/developers.schema.json +109 -0
- package/templates/content/en/LandingPage/for-agencies.mdx +390 -0
- package/templates/content/en/LandingPage/for-agencies.schema.json +107 -0
- package/templates/content/en/LandingPage/for-ai-search-agencies.mdx +417 -0
- package/templates/content/en/LandingPage/for-ai-search-agencies.schema.json +105 -0
- package/templates/content/en/LandingPage/for-businesses.mdx +19 -0
- package/templates/content/en/LandingPage/for-businesses.schema.json +96 -0
- package/templates/content/en/LandingPage/platform.mdx +369 -0
- package/templates/content/en/LandingPage/platform.schema.json +166 -0
- package/templates/content/en/LandingPage/vs-ai-website-builders.mdx +19 -0
- package/templates/content/en/LandingPage/vs-ai-website-builders.schema.json +102 -0
- package/templates/content/en/LandingPage/vs-wordpress.mdx +19 -0
- package/templates/content/en/LandingPage/vs-wordpress.schema.json +53 -0
- package/templates/content/en/NewsletterSignup/newsletter.mdx +236 -0
- package/templates/content/en/NewsletterSignup/newsletter.schema.json +91 -0
- package/templates/content/en/Organization/site-owner.mdx +16 -0
- package/templates/content/en/Partner/prisma.mdx +31 -0
- package/templates/content/en/Partner/supabase.mdx +30 -0
- package/templates/content/en/Partner/vercel.mdx +28 -0
- package/templates/content/en/PartnersList/partners.mdx +22 -0
- package/templates/content/en/Person/founder.mdx +18 -0
- package/templates/content/en/Pricing/pricing.mdx +538 -0
- package/templates/content/en/Pricing/pricing.schema.json +209 -0
- package/templates/content/en/PrivacyPage/privacy.mdx +165 -0
- package/templates/content/en/PrivacyPage/privacy.schema.json +64 -0
- package/templates/content/en/Product/ailk.mdx +19 -0
- package/templates/content/en/Product/ailk.schema.json +94 -0
- package/templates/content/en/Product/api-launch-kit.mdx +26 -0
- package/templates/content/en/Product/launch-kit.mdx +28 -0
- package/templates/content/en/ProductsList/products.mdx +26 -0
- package/templates/content/en/Project/ailk-phase-2.mdx +54 -0
- package/templates/content/en/ProjectsList/projects.mdx +25 -0
- package/templates/content/en/ResourceDetail/aeo-scoring-guide.mdx +27 -0
- package/templates/content/en/ResourceDetail/content-model-whitepaper.mdx +28 -0
- package/templates/content/en/ResourceDetail/schema-org-quick-reference.mdx +39 -0
- package/templates/content/en/ResourcesHub/resources.mdx +22 -0
- package/templates/content/en/Service/consulting.mdx +22 -0
- package/templates/content/en/Service/implementation.mdx +30 -0
- package/templates/content/en/Service/launch-service.mdx +232 -0
- package/templates/content/en/Service/launch.mdx +228 -0
- package/templates/content/en/ServicesList/services.mdx +84 -0
- package/templates/content/en/SoftwareProduct/ailk-aeo.mdx +44 -0
- package/templates/content/en/SoftwareProduct/ailk-content-adapters.mdx +47 -0
- package/templates/content/en/SoftwareProduct/ailk-schema.mdx +49 -0
- package/templates/content/en/TeamList/team.mdx +63 -0
- package/templates/content/en/TeamMember/founder.mdx +72 -0
- package/templates/content/en/TermsPage/terms.mdx +19 -0
- package/templates/content/en/TermsPage/terms.schema.json +99 -0
- package/templates/content/en/TestimonialsList/testimonials.mdx +44 -0
- package/templates/content/en/UseCasesList/use-cases.mdx +30 -0
- package/templates/content/en/Whitepaper/ax-first-product-development.mdx +27 -0
- package/templates/content/en/Whitepaper/open-core-commercial-strategy.mdx +27 -0
- package/templates/content/en/Whitepaper/structured-data-for-answer-engines.mdx +31 -0
- package/templates/content/en-XA/AboutPage/about.mdx +8 -0
- package/templates/content/en-XA/FAQPage/faq.mdx +8 -0
- package/templates/content/en-XA/HomePage/home.mdx +8 -0
- package/templates/content/es/_site.mdx +30 -0
- package/templates/content/fr/_site.mdx +30 -0
- package/templates/content/ja/_site.mdx +30 -0
- package/templates/content/pt-BR/AboutPage/about.mdx +8 -0
- package/templates/content/pt-BR/FAQPage/faq.mdx +8 -0
- package/templates/content/pt-BR/HomePage/home.mdx +23 -0
- package/templates/database/CHANGELOG.md +5 -0
- package/templates/database/README.md +234 -0
- package/templates/database/__tests__/user-cascade.test.ts +125 -0
- package/templates/database/auth/.gitkeep +0 -0
- package/templates/database/config/.gitkeep +0 -0
- package/templates/database/content/.gitkeep +0 -0
- package/templates/database/inbox/.gitkeep +0 -0
- package/templates/database/inbox/README.md +3 -0
- package/templates/database/inbox/__tests__/schema.test.ts +40 -0
- package/templates/database/inbox/schema.prisma +52 -0
- package/templates/database/jest.config.cjs +29 -0
- package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +328 -0
- package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +100 -0
- package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +28 -0
- package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +25 -0
- package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +42 -0
- package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +67 -0
- package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +21 -0
- package/templates/database/migrations/migration_lock.toml +3 -0
- package/templates/database/ops/.gitkeep +0 -0
- package/templates/database/package.json +45 -0
- package/templates/database/prisma.config.ts +20 -0
- package/templates/database/schema.prisma +487 -0
- package/templates/database/scripts/db-generate-locked.sh +80 -0
- package/templates/database/seed-test.ts +85 -0
- package/templates/database/tsconfig.build.json +16 -0
- package/templates/database/tsconfig.json +9 -0
- package/templates/package.json +125 -0
- package/templates/pnpm-workspace.yaml +6 -0
- package/templates/project.yaml +59 -0
- package/templates/tsconfig.base.json +18 -0
- package/templates/tsconfig.json +45 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# OAuth + Magic-Link Setup — RUNBOOK Template
|
|
2
|
+
|
|
3
|
+
The `scaffold-auth` skill writes (or merges into) `RUNBOOK.md` at the
|
|
4
|
+
consumer's repo root using the per-provider sections below. Only the
|
|
5
|
+
sections for providers actually activated this session are emitted.
|
|
6
|
+
|
|
7
|
+
The skill **substitutes nothing** in these blocks at runtime — they're
|
|
8
|
+
copy-paste ready as-is. The only per-session variation is which
|
|
9
|
+
sections appear in the final runbook.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Provider section: magic-link (Resend)
|
|
14
|
+
|
|
15
|
+
```markdown
|
|
16
|
+
## Auth — magic-link (Resend)
|
|
17
|
+
|
|
18
|
+
Magic-link sign-in uses Resend as the email provider. Activation is
|
|
19
|
+
keyed off two env vars in `.env.local`:
|
|
20
|
+
|
|
21
|
+
- `AUTH_EMAIL_SERVER` — `smtp://resend:<API_KEY>@smtp.resend.com:465`
|
|
22
|
+
- `AUTH_EMAIL_FROM` — verified sender address on your Resend account
|
|
23
|
+
|
|
24
|
+
### One-time setup
|
|
25
|
+
|
|
26
|
+
1. Sign up at <https://resend.com> (free tier is fine for development).
|
|
27
|
+
2. Create an API key: <https://resend.com/api-keys>. Save it
|
|
28
|
+
somewhere safe — you'll only see it once.
|
|
29
|
+
3. Use a verified sender. For development, `onboarding@resend.dev` is
|
|
30
|
+
Resend's shared dev sender and works without verification. For
|
|
31
|
+
production, verify your own sending domain in the Resend dashboard.
|
|
32
|
+
|
|
33
|
+
### `.env.local` entries
|
|
34
|
+
|
|
35
|
+
\`\`\`
|
|
36
|
+
AUTH_EMAIL_SERVER=smtp://resend:re_yourapikeyhere@smtp.resend.com:465
|
|
37
|
+
AUTH_EMAIL_FROM=onboarding@resend.dev
|
|
38
|
+
\`\`\`
|
|
39
|
+
|
|
40
|
+
### Rotating the API key
|
|
41
|
+
|
|
42
|
+
If you rotate the Resend API key, update `AUTH_EMAIL_SERVER` in
|
|
43
|
+
`.env.local` and restart the dev server.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Provider section: Google OAuth
|
|
49
|
+
|
|
50
|
+
```markdown
|
|
51
|
+
## Auth — Google OAuth
|
|
52
|
+
|
|
53
|
+
Google sign-in is activated when both env vars are present in
|
|
54
|
+
`.env.local`:
|
|
55
|
+
|
|
56
|
+
- `GOOGLE_CLIENT_ID`
|
|
57
|
+
- `GOOGLE_CLIENT_SECRET`
|
|
58
|
+
|
|
59
|
+
### One-time setup
|
|
60
|
+
|
|
61
|
+
1. Open <https://console.cloud.google.com/apis/credentials>.
|
|
62
|
+
2. If you haven't yet, configure the OAuth consent screen:
|
|
63
|
+
- User type: **External** (unless you're inside a Workspace org).
|
|
64
|
+
- Fill in app name, support email, and developer contact email.
|
|
65
|
+
- Scopes are auto-populated by NextAuth at runtime — leave the
|
|
66
|
+
consent screen scope list empty.
|
|
67
|
+
3. Click **Create Credentials → OAuth client ID**.
|
|
68
|
+
4. Application type: **Web application**.
|
|
69
|
+
5. Name: anything (e.g., "AILK dev").
|
|
70
|
+
6. **Authorized redirect URIs** — add exactly:
|
|
71
|
+
`http://localhost:3000/api/auth/callback/google`
|
|
72
|
+
7. Click **Create**. Copy the Client ID and Client secret from the
|
|
73
|
+
dialog (you can return to copy them later via the Credentials page).
|
|
74
|
+
|
|
75
|
+
### `.env.local` entries
|
|
76
|
+
|
|
77
|
+
\`\`\`
|
|
78
|
+
GOOGLE_CLIENT_ID=...
|
|
79
|
+
GOOGLE_CLIENT_SECRET=...
|
|
80
|
+
\`\`\`
|
|
81
|
+
|
|
82
|
+
### Production callback URL
|
|
83
|
+
|
|
84
|
+
The `localhost` callback above is dev-only. For production, you'll
|
|
85
|
+
need to add a second redirect URI to the same OAuth client (or
|
|
86
|
+
create a separate prod client) of the form
|
|
87
|
+
`https://<your-prod-domain>/api/auth/callback/google`. The
|
|
88
|
+
`provision-config` skill or your future deploy skill will help you
|
|
89
|
+
wire this when you're ready to ship.
|
|
90
|
+
|
|
91
|
+
### Rotating the client secret
|
|
92
|
+
|
|
93
|
+
In the Google Console, find the OAuth client, generate a new secret,
|
|
94
|
+
update `GOOGLE_CLIENT_SECRET` in `.env.local`, and restart the dev
|
|
95
|
+
server. The Client ID stays the same.
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Provider section: GitHub OAuth
|
|
101
|
+
|
|
102
|
+
```markdown
|
|
103
|
+
## Auth — GitHub OAuth
|
|
104
|
+
|
|
105
|
+
GitHub sign-in is activated when both env vars are present in
|
|
106
|
+
`.env.local`:
|
|
107
|
+
|
|
108
|
+
- `GITHUB_CLIENT_ID`
|
|
109
|
+
- `GITHUB_CLIENT_SECRET`
|
|
110
|
+
|
|
111
|
+
### One-time setup
|
|
112
|
+
|
|
113
|
+
1. Open <https://github.com/settings/developers>.
|
|
114
|
+
2. Click **New OAuth App**.
|
|
115
|
+
3. Application name: anything (e.g., "AILK dev").
|
|
116
|
+
4. Homepage URL: `http://localhost:3000`
|
|
117
|
+
5. **Authorization callback URL** — add exactly:
|
|
118
|
+
`http://localhost:3000/api/auth/callback/github`
|
|
119
|
+
6. Click **Register application**.
|
|
120
|
+
7. On the resulting app page, click **Generate a new client secret**
|
|
121
|
+
and copy it immediately (GitHub shows it once).
|
|
122
|
+
8. Copy the Client ID from the same page.
|
|
123
|
+
|
|
124
|
+
### `.env.local` entries
|
|
125
|
+
|
|
126
|
+
\`\`\`
|
|
127
|
+
GITHUB_CLIENT_ID=...
|
|
128
|
+
GITHUB_CLIENT_SECRET=...
|
|
129
|
+
\`\`\`
|
|
130
|
+
|
|
131
|
+
### Production callback URL
|
|
132
|
+
|
|
133
|
+
The `localhost` callback above is dev-only. For production, either
|
|
134
|
+
register a separate OAuth App with a `https://<your-prod-domain>/...`
|
|
135
|
+
callback, or update this app's callback (GitHub allows multiple).
|
|
136
|
+
The `provision-config` skill or your future deploy skill will help
|
|
137
|
+
you wire this when you're ready to ship.
|
|
138
|
+
|
|
139
|
+
### Rotating the client secret
|
|
140
|
+
|
|
141
|
+
Generate a new client secret on the app's GitHub page, update
|
|
142
|
+
`GITHUB_CLIENT_SECRET` in `.env.local`, and restart the dev server.
|
|
143
|
+
The Client ID stays the same.
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Closing section (always emitted at the end of the runbook)
|
|
149
|
+
|
|
150
|
+
```markdown
|
|
151
|
+
## Activation summary
|
|
152
|
+
|
|
153
|
+
| Provider | Env vars | Active |
|
|
154
|
+
| ----------- | ------------------------------------------------- | ------ |
|
|
155
|
+
| magic-link | `AUTH_EMAIL_SERVER` + `AUTH_EMAIL_FROM` | <fill> |
|
|
156
|
+
| Google | `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` | <fill> |
|
|
157
|
+
| GitHub | `GITHUB_CLIENT_ID` + `GITHUB_CLIENT_SECRET` | <fill> |
|
|
158
|
+
|
|
159
|
+
A provider is **active** when both required env vars are set in
|
|
160
|
+
`.env.local`. The provider list is computed at server startup from env
|
|
161
|
+
vars only — there are no `auth.config.ts` edits to make.
|
|
162
|
+
|
|
163
|
+
To require sign-in for protected routes, set in `.env.local`:
|
|
164
|
+
|
|
165
|
+
\`\`\`
|
|
166
|
+
AILK_AUTH_REQUIRED=1
|
|
167
|
+
\`\`\`
|
|
168
|
+
|
|
169
|
+
Default (unset or `0`) is auth-disabled / public — useful while
|
|
170
|
+
building.
|
|
171
|
+
```
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scaffold-commerce
|
|
3
|
+
description: Wire up commerce on an AILK consumer site — either an external link to an existing storefront (Amazon, Etsy, Shopify, eBay, Gumroad, custom) via a `<MarketplaceCTA>` button, or direct payments via Stripe (test-mode only at v1). Use when the user says "let me sell something", "add a buy button", "wire up Stripe", "set up payments", "I have an Amazon store", or otherwise wants commerce wiring on their AILK site. Two-path branching — picks link vs direct first, never assumes Stripe.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# scaffold-commerce
|
|
7
|
+
|
|
8
|
+
Add commerce to an AILK site. The first question is always: **external
|
|
9
|
+
link to an existing storefront, or direct payments on this site?** Both
|
|
10
|
+
paths are conversational and emit minimal, consumer-owned source.
|
|
11
|
+
|
|
12
|
+
This skill is the canonical "sell stuff" entry point. Pricing UI itself
|
|
13
|
+
is `scaffold-page` (#362)'s lane (you scaffold a `/pricing` page with
|
|
14
|
+
that skill, then wire `lookup_key`s into it). Production webhook setup
|
|
15
|
+
is `provision-config` (#367)'s lane.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
The user wants to sell something — physical goods, digital goods,
|
|
20
|
+
subscriptions, services, courses, anything with a price. Triggers:
|
|
21
|
+
|
|
22
|
+
- "let me sell something" / "I want to sell"
|
|
23
|
+
- "add a buy button" / "add a buy now"
|
|
24
|
+
- "wire up Stripe" / "set up payments"
|
|
25
|
+
- "I have an Amazon / Etsy / Shopify / eBay / Gumroad store, link it"
|
|
26
|
+
- "what's the simplest way to charge for this?"
|
|
27
|
+
|
|
28
|
+
Skip this skill when:
|
|
29
|
+
|
|
30
|
+
- The user wants to _design_ a pricing page (lay out tiers, copy,
|
|
31
|
+
comparison table) — that's `scaffold-page` (#362) emitting a Product
|
|
32
|
+
page. Wire `lookup_key`s afterwards from this skill's output.
|
|
33
|
+
- The user wants to set up production Stripe (live mode, real webhooks).
|
|
34
|
+
Hard-blocked at v1 — sandbox-only is hook-enforced globally. Defer
|
|
35
|
+
with the same answer regardless: "v1 is test-mode only; production
|
|
36
|
+
setup is `provision-config` (#367)'s lane."
|
|
37
|
+
- The user is on a non-Stripe payment processor (Lemon Squeezy, Paddle,
|
|
38
|
+
Gumroad-as-payment-processor). v1 only supports Stripe for direct
|
|
39
|
+
payments. Acknowledge and stop; future PRs will add `--provider`
|
|
40
|
+
branches.
|
|
41
|
+
|
|
42
|
+
## The first question (always asked)
|
|
43
|
+
|
|
44
|
+
Greet the consumer with a clear two-path branch:
|
|
45
|
+
|
|
46
|
+
> "Two ways to sell on your AILK site:
|
|
47
|
+
>
|
|
48
|
+
> **Link to an existing store** — you already sell on Amazon, Etsy,
|
|
49
|
+
> Shopify, eBay, Gumroad, or your own storefront. We add a 'Buy on
|
|
50
|
+
> {marketplace}' button that links there.
|
|
51
|
+
>
|
|
52
|
+
> **Direct payments via Stripe** — you don't have a storefront yet, or
|
|
53
|
+
> you want checkout on your own site. We create products in your
|
|
54
|
+
> Stripe (test mode), wire env vars, and point you at the next steps.
|
|
55
|
+
>
|
|
56
|
+
> Which one?"
|
|
57
|
+
|
|
58
|
+
Wait for the consumer's choice. Then run the matching path.
|
|
59
|
+
|
|
60
|
+
## Link path
|
|
61
|
+
|
|
62
|
+
The link path emits source the consumer owns — no env wiring, no API
|
|
63
|
+
calls, no `@working-theory/ui` import.
|
|
64
|
+
|
|
65
|
+
### Step 1 — Collect the inputs
|
|
66
|
+
|
|
67
|
+
Ask conversationally for:
|
|
68
|
+
|
|
69
|
+
1. **URL** — the storefront URL. Validate it parses as a URL. Don't
|
|
70
|
+
accept plain text; prompt again if input fails.
|
|
71
|
+
2. **Button text** — defaults to "Buy on {marketplace}" where
|
|
72
|
+
`{marketplace}` is parsed from the URL hostname (e.g.,
|
|
73
|
+
`amazon.com` → "Amazon"). Consumer can override.
|
|
74
|
+
3. **Optional `iconSrc`** — a path to an SVG/PNG of the marketplace
|
|
75
|
+
logo, e.g., `/logos/amazon.svg`. Optional — clean text-only buttons
|
|
76
|
+
are fine. If the consumer wants logos, point them at
|
|
77
|
+
`references/marketplace-brand-pages.md` for sourcing.
|
|
78
|
+
|
|
79
|
+
### Step 2 — Emit the route template
|
|
80
|
+
|
|
81
|
+
Use `templates/marketplace-cta-route.tsx.tmpl` as the starting source.
|
|
82
|
+
The template defines `<MarketplaceCTA>` **inline** at the top of the
|
|
83
|
+
emitted route file (not bundled in `@working-theory/ui`, not imported from a
|
|
84
|
+
shared package). The consumer owns the component and can customize it.
|
|
85
|
+
|
|
86
|
+
The emitted file path is the consumer's call — typical placement is
|
|
87
|
+
`app/buy/page.tsx` for a dedicated landing, or inserted into an
|
|
88
|
+
existing page (e.g., `app/products/[slug]/page.tsx`) as a `<MarketplaceCTA>`
|
|
89
|
+
usage. Ask which.
|
|
90
|
+
|
|
91
|
+
### Step 3 — Confirm and write
|
|
92
|
+
|
|
93
|
+
Show the consumer the emitted file diff (or new file if standalone)
|
|
94
|
+
in a single confirmation step. After approval, write.
|
|
95
|
+
|
|
96
|
+
### Step 4 — No env wiring, no follow-up files
|
|
97
|
+
|
|
98
|
+
The link path is self-contained. Nothing to add to `.env.local`. No
|
|
99
|
+
references file write (the marketplace brand pages cheat-sheet ships
|
|
100
|
+
in the skill folder; the skill points at it but doesn't copy it into
|
|
101
|
+
the consumer's repo).
|
|
102
|
+
|
|
103
|
+
## Direct payments path (Stripe, test-mode only at v1)
|
|
104
|
+
|
|
105
|
+
The Stripe path uses the **Stripe MCP** (configured in the AILK
|
|
106
|
+
consumer scaffold's `.claude/settings.json`) to create products with
|
|
107
|
+
consumer-derived `lookup_key`s, writes test-mode env vars, and
|
|
108
|
+
surfaces created keys for the consumer to grep when wiring pricing UI.
|
|
109
|
+
|
|
110
|
+
### Step 1 — Defense-in-depth live-key check
|
|
111
|
+
|
|
112
|
+
Before any other action:
|
|
113
|
+
|
|
114
|
+
1. **Env detection.** Scan the consumer's `.env.local`, `.env`,
|
|
115
|
+
`.env.development`, and any `.env.example` for `sk_live_` or
|
|
116
|
+
`pk_live_`. If any match, refuse with:
|
|
117
|
+
|
|
118
|
+
> "AILK is sandbox-only at v1. I see a `sk_live_*` or `pk_live_*`
|
|
119
|
+
> value in your env files — replace it with a test-mode key from
|
|
120
|
+
> <https://dashboard.stripe.com/test/apikeys> before continuing.
|
|
121
|
+
> Production setup is `provision-config` (#367)'s lane and is
|
|
122
|
+
> deferred at v1."
|
|
123
|
+
|
|
124
|
+
Stop. No Stripe API calls fire.
|
|
125
|
+
|
|
126
|
+
2. **Paste detection.** If the consumer pastes a `sk_live_` or
|
|
127
|
+
`pk_live_` value during the flow, refuse with the same message
|
|
128
|
+
and stop.
|
|
129
|
+
|
|
130
|
+
This double-check is required by the brief and matches the global
|
|
131
|
+
hook-enforced sandbox-only constraint.
|
|
132
|
+
|
|
133
|
+
### Step 2 — Collect product inputs
|
|
134
|
+
|
|
135
|
+
Ask the consumer to describe each product they want to sell. Per
|
|
136
|
+
product:
|
|
137
|
+
|
|
138
|
+
- **Name** — e.g., "Pro plan", "Pizza", "Online course".
|
|
139
|
+
- **Price + interval** — e.g., "$29/month", "$15 one-time", "$199/year".
|
|
140
|
+
- **Optional features bullet list** — surfaced in the dashboard, not
|
|
141
|
+
required for the API call.
|
|
142
|
+
|
|
143
|
+
Loop until the consumer says "that's all" or equivalent.
|
|
144
|
+
|
|
145
|
+
### Step 3 — Derive `lookup_key`s
|
|
146
|
+
|
|
147
|
+
For each product, derive a stable, human-readable `lookup_key`:
|
|
148
|
+
|
|
149
|
+
- Lowercase the name, replace spaces with underscores.
|
|
150
|
+
- Append `_monthly` / `_yearly` / `_onetime` based on interval.
|
|
151
|
+
- Examples:
|
|
152
|
+
- "Pro plan, $29/month" → `pro_monthly`
|
|
153
|
+
- "Annual subscription, $199/year" → `annual_yearly`
|
|
154
|
+
- "Pizza, $15 one-time" → `pizza_onetime`
|
|
155
|
+
|
|
156
|
+
Show the derivations to the consumer and offer to override per-product
|
|
157
|
+
before any API call.
|
|
158
|
+
|
|
159
|
+
### Step 4 — Conflict handling (per product)
|
|
160
|
+
|
|
161
|
+
For each product, before creating it, query the consumer's Stripe
|
|
162
|
+
account for an existing product with the same `lookup_key` (use the
|
|
163
|
+
Stripe MCP — `stripe.products.list({lookup_keys: [...]})` or equivalent).
|
|
164
|
+
|
|
165
|
+
If one exists, **show + ask** (do not silently skip, do not refuse):
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
A product with lookup_key `pro_monthly` already exists:
|
|
169
|
+
Existing: "Pro plan" — $29/month — created 2026-04-15
|
|
170
|
+
Proposed: "Pro plan" — $29/month — new
|
|
171
|
+
|
|
172
|
+
What would you like to do?
|
|
173
|
+
- Keep existing (no change)
|
|
174
|
+
- Overwrite amounts (update price, keep lookup_key)
|
|
175
|
+
- Pick a different lookup_key (e.g., `pro_monthly_v2`)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Wait for choice. Apply.
|
|
179
|
+
|
|
180
|
+
### Step 5 — Create products + prices in Stripe
|
|
181
|
+
|
|
182
|
+
For each product (after conflict resolution), use the Stripe MCP:
|
|
183
|
+
|
|
184
|
+
1. **Create product:** `stripe.products.create({ name, ... })`.
|
|
185
|
+
2. **Create price:** `stripe.prices.create({ product: <id>, unit_amount, currency: 'usd', recurring: { interval } | undefined, lookup_key })`.
|
|
186
|
+
|
|
187
|
+
Surface created IDs in chat as you go so the consumer can verify in
|
|
188
|
+
their Stripe dashboard alongside the run.
|
|
189
|
+
|
|
190
|
+
### Step 6 — Write `.env.local`
|
|
191
|
+
|
|
192
|
+
After all products are created, write to the consumer's `.env.local`:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
STRIPE_SECRET_KEY=sk_test_...
|
|
196
|
+
STRIPE_PUBLISHABLE_KEY=pk_test_...
|
|
197
|
+
STRIPE_WEBHOOK_SECRET=
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Use the test-mode keys from the consumer's Stripe account (the
|
|
201
|
+
consumer pastes these from
|
|
202
|
+
<https://dashboard.stripe.com/test/apikeys>). Leave
|
|
203
|
+
`STRIPE_WEBHOOK_SECRET` empty — Step 7 fills it.
|
|
204
|
+
|
|
205
|
+
### Step 7 — Webhook setup (dev-only)
|
|
206
|
+
|
|
207
|
+
Tell the consumer to run, in a separate terminal:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
stripe listen --forward-to localhost:3000/api/webhooks/stripe
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The CLI prints a signing secret (`whsec_...`). Have the consumer paste
|
|
214
|
+
it into `.env.local` as `STRIPE_WEBHOOK_SECRET`.
|
|
215
|
+
|
|
216
|
+
Note: production webhook setup is **deferred to v2** — the consumer
|
|
217
|
+
will register a permanent webhook endpoint in Stripe's dashboard
|
|
218
|
+
during deploy. Point at `provision-config` (#367) or future deploy
|
|
219
|
+
skill for the production handoff. Do not attempt to register a
|
|
220
|
+
production webhook from this skill.
|
|
221
|
+
|
|
222
|
+
### Step 8 — Write `references/lookup-keys.md`
|
|
223
|
+
|
|
224
|
+
Use `references/lookup-keys-template.md` as the source. Instantiate
|
|
225
|
+
with the products created this session:
|
|
226
|
+
|
|
227
|
+
```markdown
|
|
228
|
+
# Lookup Keys — generated by scaffold-commerce
|
|
229
|
+
|
|
230
|
+
| Product | Lookup key | Amount | Interval |
|
|
231
|
+
| -------- | ------------- | ------ | -------- |
|
|
232
|
+
| Pro plan | `pro_monthly` | $29.00 | monthly |
|
|
233
|
+
| ... | ... | ... | ... |
|
|
234
|
+
|
|
235
|
+
When wiring a pricing page (`scaffold-page` (#362) on a `Product` slug),
|
|
236
|
+
import or reference these lookup keys. Stripe lookup keys are stable
|
|
237
|
+
across price recreates — safe to hard-code in your app.
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The consumer's filled-in `lookup-keys.md` lives in their repo (e.g.,
|
|
241
|
+
project root or a `docs/` folder) — point them at `scaffold-page`
|
|
242
|
+
(#362) for the pricing page that consumes these keys.
|
|
243
|
+
|
|
244
|
+
### Step 9 — Closing summary
|
|
245
|
+
|
|
246
|
+
Print:
|
|
247
|
+
|
|
248
|
+
- Number of products created (with `lookup_key`s).
|
|
249
|
+
- Path to `references/lookup-keys.md`.
|
|
250
|
+
- Reminder: webhook setup is dev-only at v1; production webhook is
|
|
251
|
+
`provision-config` (#367)'s lane.
|
|
252
|
+
- Pointer at `scaffold-page` (#362) for wiring pricing UI.
|
|
253
|
+
- Reminder: sandbox-only at v1. Live keys are hook-blocked globally.
|
|
254
|
+
|
|
255
|
+
## Output style
|
|
256
|
+
|
|
257
|
+
- **Two questions, two paths.** Don't lead with Stripe assumptions.
|
|
258
|
+
- **Live-key checks happen first** for the Stripe path. Always.
|
|
259
|
+
- **Show + ask on conflicts.** Never silently skip or auto-overwrite.
|
|
260
|
+
- **Source the consumer owns.** The link path emits inline source, not
|
|
261
|
+
an `@working-theory/ui` import. The consumer can edit any of it post-emit.
|
|
262
|
+
- **`lookup_key` derivations are visible.** Show the derivation; let
|
|
263
|
+
the consumer override before any API call.
|
|
264
|
+
|
|
265
|
+
## What this skill does NOT do
|
|
266
|
+
|
|
267
|
+
- Live-mode Stripe anything. Hook-blocked globally; SKILL refuses.
|
|
268
|
+
- Bundle marketplace logos (Amazon, Etsy, Shopify, eBay, Gumroad).
|
|
269
|
+
AILK doesn't ship those SVGs (trademark-redistribution concern). The
|
|
270
|
+
consumer drops their own SVG into `public/logos/` and passes
|
|
271
|
+
`iconSrc` to `<MarketplaceCTA>`. See
|
|
272
|
+
`references/marketplace-brand-pages.md` for official brand-kit
|
|
273
|
+
sources.
|
|
274
|
+
- Build a pricing page. That's `scaffold-page` (#362).
|
|
275
|
+
- Register a production webhook endpoint. That's `provision-config`
|
|
276
|
+
(#367) or future deploy skill.
|
|
277
|
+
- Use `pricebook.ts` or env-var price mapping. AILK uses
|
|
278
|
+
`lookup_key`s as the source of truth — they're stable across price
|
|
279
|
+
recreates.
|
|
280
|
+
- Auto-invoke other skills. Always points at the next skill by name;
|
|
281
|
+
consumer drives.
|
|
282
|
+
|
|
283
|
+
## References
|
|
284
|
+
|
|
285
|
+
- `references/marketplace-brand-pages.md` — links to official brand
|
|
286
|
+
kits (Amazon, Etsy, Shopify, eBay, Gumroad). Used by the link path
|
|
287
|
+
when the consumer wants logos. AILK does not bundle the SVGs.
|
|
288
|
+
- `references/lookup-keys-template.md` — template the skill instantiates
|
|
289
|
+
per session, lists every product the consumer created with its
|
|
290
|
+
`lookup_key` and price.
|
|
291
|
+
- `templates/marketplace-cta-route.tsx.tmpl` — emitted route source
|
|
292
|
+
the link path writes. Includes the inline `<MarketplaceCTA>`
|
|
293
|
+
component definition (not a separate package).
|
|
294
|
+
|
|
295
|
+
## Coordination
|
|
296
|
+
|
|
297
|
+
- **`scaffold-page` (#362)** — pricing UI. After this skill creates
|
|
298
|
+
products and surfaces `lookup_key`s, the consumer scaffolds a
|
|
299
|
+
`/pricing` page that consumes them.
|
|
300
|
+
- **`provision-config` (#367)** — production webhook setup, deploy
|
|
301
|
+
config, persistent leads (related infra). v1 is dev-mode only;
|
|
302
|
+
prod webhook lives there.
|
|
303
|
+
- **Stripe MCP** — used for product/price/lookup_key creation. Should
|
|
304
|
+
already be configured in `.claude/settings.json` from the consumer
|
|
305
|
+
scaffold. If missing, surface a clear "Stripe MCP not configured"
|
|
306
|
+
error and stop; do not invent the configuration.
|
|
307
|
+
- **`@working-theory/stripe-client`** — wrapper for Stripe SDK. The skill does
|
|
308
|
+
not import this directly (the skill is a prompt/template, not
|
|
309
|
+
runtime code). The consumer's `apps/api/routes/checkout/sessions.ts`
|
|
310
|
+
uses it.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Lookup Keys — generated by `scaffold-commerce`
|
|
2
|
+
|
|
3
|
+
This file lists every Stripe product the `scaffold-commerce` skill
|
|
4
|
+
created in your test-mode account. The skill writes one row per
|
|
5
|
+
product as it goes; re-running the skill appends new rows under
|
|
6
|
+
"## Added by re-run YYYY-MM-DD".
|
|
7
|
+
|
|
8
|
+
## How to use this file
|
|
9
|
+
|
|
10
|
+
Stripe `lookup_key`s are stable identifiers — they survive price
|
|
11
|
+
recreates (e.g., when you change an amount, you can keep the same
|
|
12
|
+
`lookup_key`). They're the canonical reference for AILK pricing UI.
|
|
13
|
+
|
|
14
|
+
When wiring a pricing page (e.g., from `scaffold-page` (#362) on a
|
|
15
|
+
`Product` slug), refer to `lookup_key` in your code:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// apps/web/app/pricing/page.tsx
|
|
19
|
+
const PRICING_LOOKUP_KEYS = ["pro_monthly", "team_monthly"];
|
|
20
|
+
|
|
21
|
+
// Server-side fetch (apps/api):
|
|
22
|
+
const prices = await stripe.prices.list({
|
|
23
|
+
lookup_keys: PRICING_LOOKUP_KEYS,
|
|
24
|
+
expand: ["data.product"],
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The pricing page renders from `prices`. If you change a price's
|
|
29
|
+
amount in the Stripe dashboard later, the `lookup_key` resolves to
|
|
30
|
+
the new price automatically — no app-code change needed.
|
|
31
|
+
|
|
32
|
+
## Products created this session
|
|
33
|
+
|
|
34
|
+
(The skill fills this table during Step 8 of the Stripe path. Empty
|
|
35
|
+
on first emit; populated as products are created.)
|
|
36
|
+
|
|
37
|
+
| Product | Lookup key | Amount | Interval | Stripe ID |
|
|
38
|
+
| ---------- | ---------- | ------ | -------- | --------- |
|
|
39
|
+
| _none yet_ | _ -_ | _-_ | _-_ | _-_ |
|
|
40
|
+
|
|
41
|
+
Example after a session that created two products:
|
|
42
|
+
|
|
43
|
+
| Product | Lookup key | Amount | Interval | Stripe ID |
|
|
44
|
+
| --------- | -------------- | ---------- | -------- | ---------------- |
|
|
45
|
+
| Pro plan | `pro_monthly` | $29.00 USD | monthly | `price_1XXXX...` |
|
|
46
|
+
| Team plan | `team_monthly` | $99.00 USD | monthly | `price_1YYYY...` |
|
|
47
|
+
|
|
48
|
+
## Re-running the skill
|
|
49
|
+
|
|
50
|
+
If you re-run `scaffold-commerce` and add more products:
|
|
51
|
+
|
|
52
|
+
- Existing rows are not modified.
|
|
53
|
+
- New products land under `## Added by re-run <DATE>` heading at the
|
|
54
|
+
end of the file.
|
|
55
|
+
- Conflict-handling (skill Step 4) means existing `lookup_key`s are
|
|
56
|
+
never silently changed — you'll be asked to keep / overwrite /
|
|
57
|
+
pick a different key.
|
|
58
|
+
|
|
59
|
+
## Pointers
|
|
60
|
+
|
|
61
|
+
- **Pricing page UI:** `scaffold-page` (#362) on a `Product` slug.
|
|
62
|
+
Wire the `PRICING_LOOKUP_KEYS` array to point at the keys above.
|
|
63
|
+
- **Production webhook:** `provision-config` (#367). Dev-mode
|
|
64
|
+
webhook is set up via `stripe listen` per skill Step 7.
|
|
65
|
+
- **Sandbox-only at v1:** AILK rejects live keys (`sk_live_*`,
|
|
66
|
+
`pk_live_*`) at multiple layers. Production setup is a future
|
|
67
|
+
deploy lane.
|
|
68
|
+
- **Stripe dashboard:**
|
|
69
|
+
- Test products: <https://dashboard.stripe.com/test/products>
|
|
70
|
+
- Test prices: <https://dashboard.stripe.com/test/prices>
|
|
71
|
+
- Test API keys: <https://dashboard.stripe.com/test/apikeys>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Marketplace Brand Pages
|
|
2
|
+
|
|
3
|
+
AILK does **not** bundle marketplace logo SVGs (Amazon, Etsy, Shopify,
|
|
4
|
+
eBay, Gumroad). Trademarks are not blanket-licensed for redistribution
|
|
5
|
+
through third-party templates, and shipping them in the AILK template
|
|
6
|
+
chain would put us in the redistribution chain.
|
|
7
|
+
|
|
8
|
+
Brand recognition value is preserved via the **brand name in the
|
|
9
|
+
button text** ("Buy on Amazon", "View on Etsy"). Consumers who want
|
|
10
|
+
the logo too can fetch it themselves from each marketplace's official
|
|
11
|
+
brand-kit page (links below) and drop it in their own `public/logos/`
|
|
12
|
+
directory, then pass `iconSrc="/logos/amazon.svg"` to
|
|
13
|
+
`<MarketplaceCTA>`.
|
|
14
|
+
|
|
15
|
+
Each link below points at the marketplace's first-party brand-asset
|
|
16
|
+
page. URLs may change; if a link breaks, search "<marketplace> brand
|
|
17
|
+
guidelines" or "<marketplace> press kit" — the canonical source is
|
|
18
|
+
always the marketplace's own brand site.
|
|
19
|
+
|
|
20
|
+
## Amazon
|
|
21
|
+
|
|
22
|
+
- **Brand assets:** <https://brand.amazon.com> (US Brand Standards)
|
|
23
|
+
- **Press / logo:** <https://www.aboutamazon.com/news/company-news/press-room>
|
|
24
|
+
- Notes: Amazon's brand guidelines restrict use of the smile-arrow
|
|
25
|
+
logo. The "Available at Amazon" badge is the consumer-permitted
|
|
26
|
+
affiliate-style asset.
|
|
27
|
+
|
|
28
|
+
## Etsy
|
|
29
|
+
|
|
30
|
+
- **Press kit:** <https://www.etsy.com/press>
|
|
31
|
+
- **Logo + brand guidelines:** linked from the press page.
|
|
32
|
+
- Notes: "Sell on Etsy" assets are for sellers; "Available on Etsy"
|
|
33
|
+
/ "Buy on Etsy" buttons are appropriate for outbound links.
|
|
34
|
+
|
|
35
|
+
## Shopify
|
|
36
|
+
|
|
37
|
+
- **Brand assets:** <https://www.shopify.com/news/brand-assets> (or
|
|
38
|
+
search "Shopify brand guidelines")
|
|
39
|
+
- Notes: Shopify provides logo files for partners; consumers using
|
|
40
|
+
Shopify as their backend can typically use the logo in
|
|
41
|
+
reasonable-context "Powered by Shopify" / "Buy on our Shopify
|
|
42
|
+
store" buttons.
|
|
43
|
+
|
|
44
|
+
## eBay
|
|
45
|
+
|
|
46
|
+
- **Brand center:** <https://partnernetwork.ebay.com/marketing-center>
|
|
47
|
+
(eBay Partner Network — affiliate context)
|
|
48
|
+
- **Press / logo:** <https://www.ebayinc.com/company/press-room>
|
|
49
|
+
- Notes: eBay distinguishes affiliate-context use (covered by EPN
|
|
50
|
+
assets) from general use. For "View on eBay" buttons linking to a
|
|
51
|
+
specific seller's storefront, the EPN assets apply.
|
|
52
|
+
|
|
53
|
+
## Gumroad
|
|
54
|
+
|
|
55
|
+
- **Brand assets:** <https://gumroad.com> (search the footer for
|
|
56
|
+
"press" or "brand"; Gumroad's logo policy is permissive for
|
|
57
|
+
outbound links to creator pages)
|
|
58
|
+
- Notes: simplest of the five; Gumroad's logo and "Available on
|
|
59
|
+
Gumroad" badge are typically copyable directly from their
|
|
60
|
+
about/press surface.
|
|
61
|
+
|
|
62
|
+
## Custom storefronts
|
|
63
|
+
|
|
64
|
+
If the consumer has their own storefront (Webflow, Squarespace,
|
|
65
|
+
Bigcartel, custom-built), they don't need a marketplace logo — a
|
|
66
|
+
plain "Buy now" or "Shop" button works. The `iconSrc` prop is
|
|
67
|
+
optional.
|
|
68
|
+
|
|
69
|
+
## Legal note (no legal advice)
|
|
70
|
+
|
|
71
|
+
- Trademarks are owned by the marketplaces. AILK does not grant
|
|
72
|
+
permission to use any marketplace logo; the consumer's use is
|
|
73
|
+
governed by each marketplace's brand guidelines.
|
|
74
|
+
- For affiliate context (consumer earns a referral fee), most
|
|
75
|
+
marketplaces have explicit affiliate-asset programs (Amazon
|
|
76
|
+
Associates, eBay Partner Network, etc.) with permitted logo use.
|
|
77
|
+
- For non-affiliate "I have a store there, send people to it"
|
|
78
|
+
context, the marketplace's general brand guidelines apply. When
|
|
79
|
+
in doubt, the brand name in text only — `Buy on {marketplace}`
|
|
80
|
+
— is always safe.
|
|
81
|
+
|
|
82
|
+
This file is informational. Consumers responsible for compliance
|
|
83
|
+
with each marketplace's brand guidelines for their specific use.
|