create-ailk 0.6.1 → 0.8.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 +87 -14
- package/component-catalog.json +735 -95
- package/component-catalog.md +13 -7
- package/dist/add-module-core.d.ts +22 -0
- package/dist/add-module-core.js +50 -0
- package/dist/add-module.d.ts +89 -0
- package/dist/add-module.js +334 -0
- package/dist/category-profile.d.ts +126 -0
- package/dist/category-profile.js +262 -0
- package/dist/cli.js +89 -29
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -1
- package/dist/lib/extract-module-bundle.d.ts +56 -1
- package/dist/lib/extract-module-bundle.js +170 -14
- package/dist/lib/license-key-files.d.ts +15 -0
- package/dist/lib/license-key-files.js +102 -0
- package/dist/lib/module-license-gate.d.ts +79 -0
- package/dist/lib/module-license-gate.js +160 -12
- package/dist/lib/module-tier.d.ts +45 -16
- package/dist/lib/module-tier.js +76 -0
- package/dist/lib/pro-callout.d.ts +16 -10
- package/dist/lib/pro-callout.js +34 -3
- package/dist/license-set.d.ts +34 -0
- package/dist/license-set.js +194 -0
- package/dist/module-architecture.d.ts +20 -0
- package/dist/module-architecture.js +77 -19
- package/dist/modules/commerce/0.6.1.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.1.tar.gz +0 -0
- package/dist/modules/marketing-site/0.6.1.tar.gz +0 -0
- package/dist/modules/minimalism-site/0.6.1.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.1.tar.gz +0 -0
- package/dist/modules/saas-product/0.6.1.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.1.tar.gz +0 -0
- package/dist/modules/simple-service/0.6.1.tar.gz +0 -0
- package/dist/modules/workspace/0.6.1.tar.gz +0 -0
- package/dist/parse-args.d.ts +85 -10
- package/dist/parse-args.js +227 -15
- package/dist/programmatic.d.ts +81 -5
- package/dist/programmatic.js +291 -32
- package/dist/site-chrome.d.ts +18 -7
- package/dist/site-chrome.js +32 -14
- package/dist/site-roster.d.ts +127 -0
- package/dist/site-roster.js +499 -0
- package/dist/starter-grid.d.ts +216 -0
- package/dist/starter-grid.js +449 -0
- package/dist/surfaces.d.ts +20 -7
- package/dist/surfaces.js +204 -24
- package/dist/sync-routes.d.ts +9 -0
- package/dist/sync-routes.js +2 -2
- package/dist/template-manifest.d.ts +94 -19
- package/dist/template-manifest.js +170 -289
- package/dist/template-names.d.ts +14 -12
- package/dist/template-names.js +13 -17
- package/package.json +6 -4
- package/site-templates/_base/content/en/BookCall/book-call.mdx +52 -0
- package/site-templates/_base/content/en/Feature/feature-1.mdx +69 -0
- package/site-templates/_base/content/en/Feature/feature-2.mdx +69 -0
- package/site-templates/_base/content/en/Feature/feature-3.mdx +69 -0
- package/site-templates/_base/content/en/FeaturesList/features.mdx +91 -0
- package/site-templates/_base/content/en/GlossaryList/glossary.mdx +65 -0
- package/site-templates/_base/content/en/NewsletterSignup/newsletter.mdx +67 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-four.mdx +105 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-one.mdx +34 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-three.mdx +94 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-two.mdx +45 -0
- package/site-templates/_base/content/en/PortfolioList/portfolio.mdx +169 -0
- package/site-templates/_base/content/en/Pricing/pricing.mdx +71 -62
- package/site-templates/_base/content/en/PrivacyPage/privacy.mdx +17 -3
- package/site-templates/_base/content/en/TermsPage/terms.mdx +2 -3
- package/site-templates/_base/content/en/UseCase/persona-1.mdx +69 -0
- package/site-templates/_base/content/en/UseCase/persona-2.mdx +69 -0
- package/site-templates/_base/content/en/UseCase/persona-3.mdx +69 -0
- package/site-templates/designs/minimalism/DESIGN.md +162 -0
- package/site-templates/designs/standard/DESIGN.md +167 -0
- package/site-templates/marketing-site/DESIGN.md +59 -40
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +376 -57
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +230 -90
- package/site-templates/marketing-site/ailk-template.json +1 -0
- package/site-templates/marketing-site-free/DESIGN.md +59 -40
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +323 -63
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +323 -113
- package/site-templates/marketing-site-free/ailk-template.json +3 -2
- package/site-templates/marketing-site-free/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +199 -0
- package/site-templates/minimalism-site/DESIGN.md +54 -40
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +246 -19
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +173 -51
- package/site-templates/minimalism-site/ailk-template.json +3 -2
- package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +3 -37
- package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/saas-product/DESIGN.md +59 -40
- package/site-templates/saas-product/TEMPLATE-MANIFEST.md +9 -1
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +369 -0
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +302 -0
- package/site-templates/shapes/local-business-service/ailk-template.json +10 -0
- package/site-templates/{simple-service → shapes/local-business-service}/content/en/AboutPage/about.mdx +4 -4
- package/site-templates/shapes/local-business-service/content/en/HomePage/home.mdx +70 -0
- package/site-templates/shapes/local-business-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/local-business-service/content/en/PortfolioList/portfolio.mdx +171 -0
- package/site-templates/shapes/local-business-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/shapes/local-business-service/content/en/Service/first-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/Service/second-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/Service/third-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/ServicesList/services.mdx +61 -0
- package/site-templates/shapes/local-business-service/provenance.json +4 -0
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +362 -0
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +300 -0
- package/site-templates/shapes/organization-service/ailk-template.json +10 -0
- package/site-templates/shapes/organization-service/content/en/AboutPage/about.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/HomePage/home.mdx +85 -0
- package/site-templates/shapes/organization-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/organization-service/content/en/PortfolioList/portfolio.mdx +171 -0
- package/site-templates/shapes/organization-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/shapes/organization-service/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/ServicesList/services.mdx +72 -0
- package/site-templates/shapes/organization-service/provenance.json +4 -0
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +369 -0
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +299 -0
- package/site-templates/shapes/person-service/ailk-template.json +10 -0
- package/site-templates/shapes/person-service/content/_site.mdx +85 -0
- package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +39 -0
- package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +97 -0
- package/site-templates/shapes/person-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +169 -0
- package/site-templates/shapes/person-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/shapes/person-service/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/shapes/person-service/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/shapes/person-service/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/{simple-service → shapes/person-service}/content/en/ServicesList/services.mdx +16 -16
- package/site-templates/shapes/person-service/provenance.json +4 -0
- package/templates/.claude/settings.json +15 -0
- package/templates/.claude/skills/README.md +10 -9
- package/templates/.claude/skills/{scaffold-auth → add-auth}/SKILL.md +7 -7
- package/templates/.claude/skills/{scaffold-auth → add-auth}/references/env-vars.md +2 -2
- package/templates/.claude/skills/{scaffold-auth → add-auth}/references/oauth-app-setup.md +3 -3
- package/templates/.claude/skills/{scaffold-page → add-page}/SKILL.md +76 -62
- package/templates/.claude/skills/add-page/references/page-types.md +115 -0
- package/templates/.claude/skills/{scaffold-page → add-page}/templates/content.mdx.tmpl +4 -4
- package/templates/.claude/skills/{scaffold-page → add-page}/templates/route.tsx.tmpl +1 -1
- package/templates/.claude/skills/{audit-site → check-site}/SKILL.md +16 -17
- package/templates/.claude/skills/{audit-site → check-site}/references/common-errors.md +3 -3
- package/templates/.claude/skills/{audit-site → check-site}/references/findings-glossary.md +16 -14
- package/templates/.claude/skills/{audit-site → check-site}/references/severity-levels.md +1 -1
- package/templates/.claude/skills/fill-page/SKILL.md +180 -0
- package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +80 -0
- package/templates/.claude/skills/fill-page/references/section-sources.md +41 -0
- package/templates/.claude/skills/setup-database/SKILL.md +156 -0
- package/templates/.claude/skills/setup-database/scripts/verify-inbox.ts +154 -0
- package/templates/.claude/skills/{provision-config → setup-deploy}/SKILL.md +73 -41
- package/templates/.claude/skills/{provision-config → setup-deploy}/references/env-vars-template.md +21 -30
- package/templates/.claude/skills/setup-deploy/references/runbook-template.md +204 -0
- package/templates/.claude/skills/{provision-config → setup-deploy}/references/vercel-json-template.md +1 -1
- package/templates/.claude/skills/upgrade-plan/SKILL.md +117 -0
- package/templates/.claude/skills/upgrade-plan/references/options.md +24 -0
- package/templates/.claude/skills/upgrade-plan/scripts/upgrade-plan.ts +527 -0
- package/templates/.github/workflows/ci.yml +5 -0
- package/templates/CLAUDE.md +8 -2
- package/templates/DESIGN.md +56 -44
- package/templates/README.md +116 -46
- package/templates/apps/api/.env.example +2 -1
- package/templates/apps/api/CLAUDE.md +3 -2
- package/templates/apps/api/package.json +1 -1
- package/templates/apps/api/src/config/__tests__/index.test.ts +146 -10
- package/templates/apps/api/src/config/index.ts +46 -14
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +30 -0
- package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +96 -0
- package/templates/apps/api/src/lib/lead-capture-store.ts +12 -0
- package/templates/apps/api/src/lib/lead-delivery.ts +52 -0
- package/templates/apps/api/src/lib/license-key-store.ts +45 -0
- package/templates/apps/api/src/lib/site.ts +5 -3
- package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +97 -0
- package/templates/apps/api/src/middleware/auth.ts +9 -0
- package/templates/apps/api/src/openapi/spec.ts +63 -12
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +127 -5
- package/templates/apps/api/src/routes/content/get-page.ts +86 -2
- package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +88 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +100 -0
- package/templates/apps/api/src/routes/leads/index.ts +46 -1
- package/templates/apps/api/src/server.ts +13 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +194 -0
- package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +124 -0
- package/templates/apps/api/src/services/lead-routing.ts +140 -30
- package/templates/apps/api/src/services/leads-inbox.ts +48 -11
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +75 -1
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +57 -9
- package/templates/apps/mcp/__tests__/parity.test.ts +5 -4
- package/templates/apps/mcp/package.json +2 -1
- package/templates/apps/mcp/src/index.ts +7 -0
- package/templates/apps/mcp/src/lib/audit-single-page.ts +36 -10
- package/templates/apps/mcp/src/lib/license-key-store.ts +45 -0
- package/templates/apps/mcp/src/tools/create_project.ts +21 -6
- package/templates/apps/web/__tests__/setup.ts +18 -0
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +10 -2
- package/templates/apps/web/app/[locale]/(auth)/layout.tsx +2 -2
- package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +10 -4
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +22 -14
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +26 -18
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +12 -4
- package/templates/apps/web/app/[locale]/[slug]/__tests__/page.test.tsx +35 -4
- package/templates/apps/web/app/[locale]/[slug]/page.tsx +49 -9
- package/templates/apps/web/app/[locale]/book-a-call/page.tsx +50 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +3 -4
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +67 -29
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +94 -11
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-text.test.ts +32 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +129 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +228 -86
- package/templates/apps/web/app/[locale]/contact/contact-form-text.ts +50 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +73 -20
- package/templates/apps/web/app/[locale]/contact/page.tsx +115 -7
- package/templates/apps/web/app/[locale]/contact/site-contact-email.ts +54 -0
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +3 -4
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +4 -5
- package/templates/apps/web/app/[locale]/features/[slug]/page.tsx +64 -0
- package/templates/apps/web/app/[locale]/features/page.tsx +52 -0
- package/templates/apps/web/app/[locale]/glossary/page.tsx +50 -0
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/how-to/page.tsx +25 -15
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/layout.tsx +146 -52
- package/templates/apps/web/app/[locale]/newsletter/__tests__/newsletter.actions.test.ts +75 -0
- package/templates/apps/web/app/[locale]/newsletter/__tests__/page.test.tsx +163 -0
- package/templates/apps/web/app/[locale]/newsletter/newsletter.actions.ts +66 -0
- package/templates/apps/web/app/[locale]/newsletter/page.tsx +142 -0
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +59 -0
- package/templates/apps/web/app/[locale]/portfolio/page.tsx +49 -0
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +4 -5
- package/templates/apps/web/app/[locale]/{cancellation → purchase-policy}/page.tsx +15 -10
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +4 -5
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +14 -1
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/software/page.tsx +25 -15
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/tech-articles/page.tsx +25 -15
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +3 -4
- package/templates/apps/web/app/[locale]/use-cases/[slug]/page.tsx +63 -0
- package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +3 -4
- package/templates/apps/web/app/[locale]/use-cases/page.tsx +15 -2
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/whitepapers/page.tsx +25 -15
- package/templates/apps/web/app/error-fallback.tsx +17 -45
- package/templates/apps/web/app/not-found.tsx +14 -38
- package/templates/apps/web/app/og/route.tsx +6 -0
- package/templates/apps/web/eslint.config.mjs +3 -0
- package/templates/apps/web/instrumentation.ts +14 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +38 -0
- package/templates/apps/web/lib/license-key-store.ts +52 -0
- package/templates/apps/web/lib/nav-config.ts +82 -18
- package/templates/apps/web/lib/prisma-for-auth.ts +9 -6
- package/templates/apps/web/lib/site-brand.tsx +1 -1
- package/templates/apps/web/lib/site-chrome.ts +3 -3
- package/templates/apps/web/lib/site-identity.ts +148 -0
- package/templates/apps/web/lib/site-theme.ts +11 -0
- package/templates/apps/web/messages/en.json +78 -37
- 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 +3 -3
- package/templates/apps/web/public/logomark.svg +6 -3
- package/templates/apps/web/public/logos/ai-launch-kit-light.svg +4 -0
- package/templates/apps/web/public/logos/ai-launch-kit.svg +4 -0
- package/templates/apps/web/public/logos/atomic-agent-light.svg +4 -0
- package/templates/apps/web/public/logos/atomic-agent.svg +4 -0
- package/templates/apps/web/public/logos/salessmyth-light.svg +4 -0
- package/templates/apps/web/public/logos/salessmyth.svg +4 -0
- package/templates/apps/web/public/site.webmanifest +4 -4
- package/templates/apps/web/public/wordmark-light.svg +4 -0
- package/templates/apps/web/public/wordmark.svg +3 -3
- package/templates/apps/web/security-headers.config.ts +5 -1
- package/templates/content/_site.mdx +25 -0
- package/templates/content/en/AboutPage/about.mdx +150 -144
- package/templates/content/en/BlogList/blog.mdx +126 -0
- package/templates/content/en/ContactPage/contact.mdx +21 -92
- package/templates/content/en/FAQPage/faq.mdx +86 -57
- package/templates/content/en/HomePage/home.mdx +268 -217
- package/templates/content/en/PurchasePolicyPage/purchase-policy.mdx +181 -0
- package/templates/content/en/UseCasesList/use-cases.mdx +170 -0
- package/templates/database/CHANGELOG.md +14 -0
- package/templates/database/package.json +1 -1
- package/templates/package.json +3 -1
- package/templates/tools/lint-architecture.ts +315 -0
- package/templates/tools/tsconfig.json +14 -0
- package/versions.json +33 -33
- package/site-templates/simple-service/DESIGN.md +0 -148
- package/site-templates/simple-service/TEMPLATE-MANIFEST.json +0 -240
- package/site-templates/simple-service/TEMPLATE-MANIFEST.md +0 -278
- package/site-templates/simple-service/ailk-template.json +0 -10
- package/site-templates/simple-service/content/en/ContactPage/contact.mdx +0 -67
- package/site-templates/simple-service/content/en/FAQPage/faq.mdx +0 -56
- package/site-templates/simple-service/content/en/HomePage/home.mdx +0 -85
- package/site-templates/simple-service/content/en/Service/landscape-design.mdx +0 -40
- package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +0 -40
- package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +0 -40
- package/site-templates/simple-service/provenance.json +0 -4
- package/templates/.claude/skills/add-schema/SKILL.md +0 -277
- package/templates/.claude/skills/add-schema/references/conflict-handling.md +0 -200
- package/templates/.claude/skills/add-schema/references/file-finding.md +0 -123
- package/templates/.claude/skills/add-schema/references/schema-types.md +0 -234
- package/templates/.claude/skills/provision-config/references/runbook-template.md +0 -248
- package/templates/.claude/skills/scaffold-page/references/page-types.md +0 -169
- package/templates/.claude/skills/suggest-site-pages/SKILL.md +0 -242
- package/templates/.claude/skills/suggest-site-pages/references/categories.md +0 -287
- package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +0 -150
- package/templates/apps/web/app/[locale]/returns/page.tsx +0 -44
- package/templates/apps/web/app/[locale]/shipping/page.tsx +0 -44
- package/templates/content/en/CancellationPolicyPage/cancellation.mdx +0 -108
- package/templates/content/en/LandingPage/blog.mdx +0 -83
- package/templates/content/en/LandingPage/features.mdx +0 -103
- package/templates/content/en/LandingPage/how-it-works.mdx +0 -143
- package/templates/content/en/ReturnsPolicyPage/returns.mdx +0 -108
- package/templates/content/en/ShippingPolicyPage/shipping.mdx +0 -108
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
# File-Finding — Slug → File Resolution
|
|
2
|
-
|
|
3
|
-
The `add-schema` skill resolves a slug like `/pricing` to one or
|
|
4
|
-
more files in the consumer's repo. This file is the source of
|
|
5
|
-
truth for the resolution logic the skill applies in Step 2.
|
|
6
|
-
|
|
7
|
-
## The two locations to scan
|
|
8
|
-
|
|
9
|
-
A slug can map to either (or both) of:
|
|
10
|
-
|
|
11
|
-
1. **App Router route file.**
|
|
12
|
-
- Primary: `apps/web/app/<slug>/page.tsx` (monorepo layout, the
|
|
13
|
-
AILK default).
|
|
14
|
-
- Fallback: `app/<slug>/page.tsx` (standalone Next.js app at
|
|
15
|
-
repo root).
|
|
16
|
-
- Slug supports nested paths: `/products/widget` →
|
|
17
|
-
`app/products/widget/page.tsx`.
|
|
18
|
-
- The `[slug]` dynamic-route convention is also valid: `/blog/foo`
|
|
19
|
-
can map to `app/blog/[slug]/page.tsx`. The skill recognizes
|
|
20
|
-
both static and dynamic route files; for dynamic routes, it
|
|
21
|
-
modifies the route handler itself (not the dynamic instance).
|
|
22
|
-
|
|
23
|
-
2. **MDX content file.**
|
|
24
|
-
- Scan: `content/**/<slug>.mdx`.
|
|
25
|
-
- The frontmatter `slug:` field is **authoritative** when
|
|
26
|
-
present. Filename match is a fallback.
|
|
27
|
-
- Multi-type content folders: a slug can live in
|
|
28
|
-
`content/Product/widget.mdx` or
|
|
29
|
-
`content/BlogPosting/widget.mdx`. The frontmatter `type:`
|
|
30
|
-
field disambiguates.
|
|
31
|
-
|
|
32
|
-
## Match outcomes
|
|
33
|
-
|
|
34
|
-
### Zero matches
|
|
35
|
-
|
|
36
|
-
Refuse with a clear pointer:
|
|
37
|
-
|
|
38
|
-
> "No page exists at `/<slug>`. Use `scaffold-page` (#362) to
|
|
39
|
-
> create one first; come back here once it exists to add
|
|
40
|
-
> additional schema."
|
|
41
|
-
|
|
42
|
-
Do not write anything.
|
|
43
|
-
|
|
44
|
-
### One match
|
|
45
|
-
|
|
46
|
-
Proceed. Show the consumer which file you'll modify in Step 7's
|
|
47
|
-
diff so they can confirm the path before any write.
|
|
48
|
-
|
|
49
|
-
### Multiple matches
|
|
50
|
-
|
|
51
|
-
List and ask. Common multi-match shapes:
|
|
52
|
-
|
|
53
|
-
- **Route + MDX coexistence.** Many AILK pages have both a
|
|
54
|
-
`apps/web/app/<slug>/page.tsx` (renderer) and a
|
|
55
|
-
`content/<Type>/<slug>.mdx` (data). The route renders the MDX —
|
|
56
|
-
schema can attach in either:
|
|
57
|
-
- Attaching in the route puts JSON-LD in JSX.
|
|
58
|
-
- Attaching in the MDX puts JSON-LD inline in content.
|
|
59
|
-
- The canonical AILK pattern emits via the route (the route
|
|
60
|
-
imports `<JsonLd schema={builder(page)}/>` and reads frontmatter
|
|
61
|
-
via the content adapter). When in doubt, modify the route.
|
|
62
|
-
|
|
63
|
-
- **Multiple MDX files for the same slug.** Rare; usually means
|
|
64
|
-
the consumer has organized content by `type/` and the same slug
|
|
65
|
-
appears in different type folders. List all matches with their
|
|
66
|
-
`type:` frontmatter and ask which one the consumer means.
|
|
67
|
-
|
|
68
|
-
- **Static + dynamic route ambiguity.** If both `app/<slug>/page.tsx`
|
|
69
|
-
and `app/<slug>/[child]/page.tsx` exist, only the static
|
|
70
|
-
`<slug>/page.tsx` is the target — the dynamic file handles
|
|
71
|
-
child routes, not the index.
|
|
72
|
-
|
|
73
|
-
Ask the consumer plainly:
|
|
74
|
-
|
|
75
|
-
> "Found multiple files for `/<slug>`:
|
|
76
|
-
>
|
|
77
|
-
> - `apps/web/app/<slug>/page.tsx` — App Router route
|
|
78
|
-
> - `content/Product/<slug>.mdx` — MDX content
|
|
79
|
-
>
|
|
80
|
-
> Where should I attach the schema? (Recommended: route, since
|
|
81
|
-
> JSON-LD belongs in the rendered output.)"
|
|
82
|
-
|
|
83
|
-
Wait for the consumer's choice.
|
|
84
|
-
|
|
85
|
-
## What the skill does NOT touch
|
|
86
|
-
|
|
87
|
-
- **Layout files.** `apps/web/app/layout.tsx` is the right place
|
|
88
|
-
for site-wide identity schema (`Organization` / `Person`). If
|
|
89
|
-
the consumer asks to add identity schema to a leaf page, the
|
|
90
|
-
skill flags this and asks (per `references/schema-types.md`).
|
|
91
|
-
- **`globals.css`, `metadata.ts`, `route.ts`** — these aren't
|
|
92
|
-
where JSON-LD lives. The skill scans only `page.tsx` and
|
|
93
|
-
`*.mdx` for slug-pattern matches.
|
|
94
|
-
- **`packages/schema/`** — read-only at v1 (per the issue scope).
|
|
95
|
-
The skill imports from `@working-theory/schema` but never modifies it.
|
|
96
|
-
|
|
97
|
-
## Edge case — non-MDX content backend
|
|
98
|
-
|
|
99
|
-
If the consumer's project uses a non-MDX adapter (Sanity, Payload,
|
|
100
|
-
or any other), the MDX scan returns nothing. The skill still tries
|
|
101
|
-
the App Router route file. If the route exists, attaching schema
|
|
102
|
-
there works regardless of where the page's content data lives.
|
|
103
|
-
|
|
104
|
-
If the consumer wants schema attached **to content** (not the
|
|
105
|
-
route) and they're on a non-MDX backend, this skill at v1 says:
|
|
106
|
-
|
|
107
|
-
> "Your content backend isn't MDX. JSON-LD attachment in
|
|
108
|
-
> non-MDX backends ships in a future PR. For now, attach the
|
|
109
|
-
> schema to the route file (`app/<slug>/page.tsx`) — that's
|
|
110
|
-
> rendered server-side and works regardless of content adapter."
|
|
111
|
-
|
|
112
|
-
## Validation after resolution
|
|
113
|
-
|
|
114
|
-
Before any write, the skill confirms the resolved file is one of:
|
|
115
|
-
|
|
116
|
-
- `.tsx` (App Router page) — must contain `export default
|
|
117
|
-
function … Page()`.
|
|
118
|
-
- `.mdx` (content file) — must have frontmatter delimiters
|
|
119
|
-
(`---`).
|
|
120
|
-
|
|
121
|
-
If the file at the resolved path doesn't match one of those
|
|
122
|
-
shapes, the skill surfaces the mismatch and stops. Don't write to
|
|
123
|
-
a file you can't recognize.
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
# Schema Types — Primary / Supplementary Catalog
|
|
2
|
-
|
|
3
|
-
The schema.org types `add-schema` recognizes, each tagged
|
|
4
|
-
**primary** (typically one per page) or **supplementary** (stacks
|
|
5
|
-
freely). The skill reads this file to decide replace-vs-append in
|
|
6
|
-
Step 6 of the mechanic.
|
|
7
|
-
|
|
8
|
-
This catalog mirrors `@working-theory/schema`'s exports. When new builders
|
|
9
|
-
ship in `@working-theory/schema`, this file updates in a follow-up PR. Until
|
|
10
|
-
then, unrecognized types fall through to the "ask the consumer"
|
|
11
|
-
path in SKILL.md.
|
|
12
|
-
|
|
13
|
-
## Primary types (one per page; replace on conflict)
|
|
14
|
-
|
|
15
|
-
These name what the page **is about**. Replacing on same-type
|
|
16
|
-
conflict is the usual intent — adding a new `Product` schema
|
|
17
|
-
generally means swapping the existing one.
|
|
18
|
-
|
|
19
|
-
| `@type` | Builder | Aliases | Typical page |
|
|
20
|
-
| ------------------- | ------------------ | ----------------------------- | ------------------------- |
|
|
21
|
-
| `HomePage` | `buildHomePage` | "home" | `/` |
|
|
22
|
-
| `AboutPage` | `buildAboutPage` | "about" | `/about` |
|
|
23
|
-
| `ContactPage` | `buildContactPage` | "contact" | `/contact` |
|
|
24
|
-
| `PrivacyPage` | `buildPrivacyPage` | "privacy" | `/privacy` |
|
|
25
|
-
| `TermsPage` | `buildTermsPage` | "terms" | `/terms` |
|
|
26
|
-
| `Product` | `buildProduct` | "product" | Per-item product page |
|
|
27
|
-
| `Service` | `buildService` | "service", "service offering" | `/pricing`, `/services/*` |
|
|
28
|
-
| `Article` | `buildArticle` | "article" | Editorial piece |
|
|
29
|
-
| `BlogPosting` | `buildBlogPosting` | "blog post", "post" | `/blog/<slug>` |
|
|
30
|
-
| `NewsArticle` | `buildNewsArticle` | "news article" | News piece |
|
|
31
|
-
| `Course` | `buildCourse` | "course" | `/courses/<slug>` |
|
|
32
|
-
| `Event` | `buildEvent` | "event" | Event landing |
|
|
33
|
-
| `JobPosting` | `buildJobPosting` | "job", "career" | `/jobs/<slug>` |
|
|
34
|
-
| `Recipe` | `buildRecipe` | "recipe" | Per-recipe page |
|
|
35
|
-
| `Book` | `buildBook` | "book" | Book detail page |
|
|
36
|
-
| `Movie` | `buildMovie` | "movie", "film" | Movie detail |
|
|
37
|
-
| `MusicAlbum` | `buildMusicAlbum` | "album" | Album page |
|
|
38
|
-
| `RealEstateListing` | _consumer-defined_ | "listing", "property" | `/listings/<slug>` |
|
|
39
|
-
|
|
40
|
-
## Supplementary types (stack freely; always append)
|
|
41
|
-
|
|
42
|
-
These add **dimensions** to a page that already has a primary
|
|
43
|
-
type. Multiple of these can coexist on one page — never replace,
|
|
44
|
-
always append.
|
|
45
|
-
|
|
46
|
-
| `@type` | Builder | Aliases | Use |
|
|
47
|
-
| ----------------- | --------------------- | ----------------------------- | ------------------------------------- |
|
|
48
|
-
| `FAQPage` | _consumer-defined_ | "faq", "FAQ" | Q&A block on any page |
|
|
49
|
-
| `HowTo` | _consumer-defined_ | "how-to", "howto", "tutorial" | Step-by-step instructions |
|
|
50
|
-
| `BreadcrumbList` | `buildBreadcrumbList` | "breadcrumbs" | Site navigation context |
|
|
51
|
-
| `Review` | _consumer-defined_ | "review" | Single review (within Product, etc.) |
|
|
52
|
-
| `AggregateRating` | _consumer-defined_ | "rating", "ratings", "stars" | Aggregate of reviews |
|
|
53
|
-
| `VideoObject` | _consumer-defined_ | "video" | Embedded video metadata |
|
|
54
|
-
| `ImageObject` | _consumer-defined_ | "image" | Image with structured metadata |
|
|
55
|
-
| `AudioObject` | _consumer-defined_ | "audio", "podcast" | Audio embed metadata |
|
|
56
|
-
| `Offer` | _consumer-defined_ | "offer" | Pricing offer (under Product/Service) |
|
|
57
|
-
| `OfferCatalog` | _consumer-defined_ | "catalog", "offer catalog" | Multi-offer container |
|
|
58
|
-
| `MonetaryAmount` | _consumer-defined_ | "monetary amount", "amount" | Used inside Service / Offer |
|
|
59
|
-
|
|
60
|
-
## Identity types (one site-wide; emit on home or in layout)
|
|
61
|
-
|
|
62
|
-
These are **the site's identity**. Typically one per site (not per
|
|
63
|
-
page) and lives in the home page or a layout component. The skill
|
|
64
|
-
treats them as **primary** for the conflict logic but flags the
|
|
65
|
-
consumer if they're trying to add one to a non-home page.
|
|
66
|
-
|
|
67
|
-
| `@type` | Builder | Aliases | Use |
|
|
68
|
-
| --------------- | ------------------- | -------------------------------- | ------------------------- |
|
|
69
|
-
| `Organization` | `buildOrganization` | "org", "organization", "company" | Business identity |
|
|
70
|
-
| `Person` | `buildPerson` | "person", "individual" | Solo individual identity |
|
|
71
|
-
| `LocalBusiness` | _consumer-defined_ | "local business" | Brick-and-mortar business |
|
|
72
|
-
| `Restaurant` | _consumer-defined_ | "restaurant" | Restaurant subtype |
|
|
73
|
-
| `Store` | _consumer-defined_ | "store" | Retail subtype |
|
|
74
|
-
|
|
75
|
-
When adding `Organization` or `Person` to a non-home page, the
|
|
76
|
-
skill should ask:
|
|
77
|
-
|
|
78
|
-
> "`Organization` is typically a site-wide identity emitted in
|
|
79
|
-
> the layout (so it appears on every page). Adding it to one
|
|
80
|
-
> page means only that page surfaces the entity. Continue, or
|
|
81
|
-
> add it to your layout instead?"
|
|
82
|
-
|
|
83
|
-
## Specialty types
|
|
84
|
-
|
|
85
|
-
Less-frequently-used but in the catalog. The skill recognizes
|
|
86
|
-
these by name; conflict handling defaults to **supplementary**
|
|
87
|
-
(append).
|
|
88
|
-
|
|
89
|
-
| `@type` | Builder | Aliases |
|
|
90
|
-
| ----------------------------------- | ------------------ | -------------------------------- |
|
|
91
|
-
| `MedicalCondition` | _consumer-defined_ | "medical condition" |
|
|
92
|
-
| `MedicalProcedure` | _consumer-defined_ | "medical procedure", "procedure" |
|
|
93
|
-
| `Drug` | _consumer-defined_ | "drug", "medication" |
|
|
94
|
-
| `LearningResource` | _consumer-defined_ | "lesson", "learning resource" |
|
|
95
|
-
| `EducationalOccupationalCredential` | _consumer-defined_ | "credential", "certification" |
|
|
96
|
-
| `SoftwareApplication` | _consumer-defined_ | "app", "software" |
|
|
97
|
-
| `MobileApplication` | _consumer-defined_ | "mobile app" |
|
|
98
|
-
| `WebApplication` | _consumer-defined_ | "web app" |
|
|
99
|
-
| `Dataset` | _consumer-defined_ | "dataset" |
|
|
100
|
-
| `ScholarlyArticle` | _consumer-defined_ | "scholarly article", "paper" |
|
|
101
|
-
| `LegislativeBuilding` | _consumer-defined_ | _rare, government use_ |
|
|
102
|
-
|
|
103
|
-
## AILK page types (registry-backed — 60 keys, one builder each)
|
|
104
|
-
|
|
105
|
-
Every key below is an entry in `@working-theory/schema`'s page-type registry
|
|
106
|
-
(`packages/schema/src/registry/entries.ts`) and has a real, exported builder
|
|
107
|
-
reachable via `buildJsonLd({ type: '<Key>', ... })` — this is the complete
|
|
108
|
-
list of scaffoldable AILK page types, as opposed to the smaller general
|
|
109
|
-
schema.org vocabulary tables above (some of which is still
|
|
110
|
-
`_consumer-defined_`, i.e. not yet builder-backed). Several keys share one
|
|
111
|
-
`@type` (e.g. `PrivacyPage` / `TermsPage` / `LandingPage` / `ThankYouPage` all
|
|
112
|
-
emit `WebPage`) — the registry has 60 entries but only 24 distinct `@type`
|
|
113
|
-
values. Re-derive with `pnpm page-type-counts`
|
|
114
|
-
(`scripts/component/page-type-counts.ts` in the `ai-launch-kit-internal`
|
|
115
|
-
source repo) before hand-editing this table.
|
|
116
|
-
|
|
117
|
-
### Core (15)
|
|
118
|
-
|
|
119
|
-
| Key | `@type` |
|
|
120
|
-
| --- | --- |
|
|
121
|
-
| `HomePage` | `HomePage` |
|
|
122
|
-
| `AboutPage` | `AboutPage` |
|
|
123
|
-
| `ContactPage` | `ContactPage` |
|
|
124
|
-
| `PrivacyPage` | `WebPage` |
|
|
125
|
-
| `TermsPage` | `WebPage` |
|
|
126
|
-
| `LandingPage` | `WebPage` |
|
|
127
|
-
| `ThankYouPage` | `WebPage` |
|
|
128
|
-
| `BookCall` | `WebPage` |
|
|
129
|
-
| `NewsletterSignup` | `WebPage` |
|
|
130
|
-
| `DemoRequest` | `WebPage` |
|
|
131
|
-
| `TrialSignup` | `WebPage` |
|
|
132
|
-
| `Waitlist` | `WebPage` |
|
|
133
|
-
| `Assessment` | `WebApplication` |
|
|
134
|
-
| `Calculator` | `WebApplication` |
|
|
135
|
-
| `CampaignLP` | `WebPage` |
|
|
136
|
-
|
|
137
|
-
### Identity (4)
|
|
138
|
-
|
|
139
|
-
`Organization` / `Person` / `BreadcrumbList` / `ContactPoint` — see the
|
|
140
|
-
[Identity types](#identity-types-one-site-wide-emit-on-home-or-in-layout)
|
|
141
|
-
table above; all four are registry-backed.
|
|
142
|
-
|
|
143
|
-
### Canonical-List (17)
|
|
144
|
-
|
|
145
|
-
| Key | `@type` |
|
|
146
|
-
| --- | --- |
|
|
147
|
-
| `ServicesList` | `CollectionPage` |
|
|
148
|
-
| `ProductsList` | `CollectionPage` |
|
|
149
|
-
| `ProjectsList` | `CollectionPage` |
|
|
150
|
-
| `FAQPage` | `FAQPage` |
|
|
151
|
-
| `CareersList` | `CollectionPage` |
|
|
152
|
-
| `UseCasesList` | `CollectionPage` |
|
|
153
|
-
| `TestimonialsList` | `CollectionPage` |
|
|
154
|
-
| `ClientsList` | `CollectionPage` |
|
|
155
|
-
| `DownloadsList` | `CollectionPage` |
|
|
156
|
-
| `EventsList` | `CollectionPage` |
|
|
157
|
-
| `CoursesList` | `CollectionPage` |
|
|
158
|
-
| `TeamList` | `CollectionPage` |
|
|
159
|
-
| `PartnersList` | `CollectionPage` |
|
|
160
|
-
| `IntegrationsList` | `CollectionPage` |
|
|
161
|
-
| `GlossaryList` | `CollectionPage` |
|
|
162
|
-
| `LocationsList` | `CollectionPage` |
|
|
163
|
-
| `DocsList` | `CollectionPage` |
|
|
164
|
-
|
|
165
|
-
### Canonical-Detail (14)
|
|
166
|
-
|
|
167
|
-
| Key | `@type` |
|
|
168
|
-
| --- | --- |
|
|
169
|
-
| `Service` | `Service` |
|
|
170
|
-
| `Product` | `Product` |
|
|
171
|
-
| `Project` | `CreativeWork` |
|
|
172
|
-
| `Event` | `Event` |
|
|
173
|
-
| `Course` | `Course` |
|
|
174
|
-
| `TeamMember` | `ProfilePage` |
|
|
175
|
-
| `Partner` | `AboutPage` |
|
|
176
|
-
| `Integration` | `WebPage` |
|
|
177
|
-
| `JobPosting` | `JobPosting` |
|
|
178
|
-
| `SoftwareProduct` | `WebPage` |
|
|
179
|
-
| `Location` | `Place` |
|
|
180
|
-
| `ServiceAreaPage` | `WebPage` |
|
|
181
|
-
| `UseCase` | `WebPage` |
|
|
182
|
-
| `Pricing` | `WebPage` |
|
|
183
|
-
|
|
184
|
-
### Editorial-List (3)
|
|
185
|
-
|
|
186
|
-
| Key | `@type` |
|
|
187
|
-
| --- | --- |
|
|
188
|
-
| `BlogList` | `Blog` |
|
|
189
|
-
| `ResourcesHub` | `CollectionPage` |
|
|
190
|
-
| `CaseStudiesList` | `CollectionPage` |
|
|
191
|
-
|
|
192
|
-
### Editorial-Detail (7)
|
|
193
|
-
|
|
194
|
-
| Key | `@type` |
|
|
195
|
-
| --- | --- |
|
|
196
|
-
| `BlogPosting` | `BlogPosting` |
|
|
197
|
-
| `CaseStudy` | `Article` |
|
|
198
|
-
| `HowTo` | `HowTo` |
|
|
199
|
-
| `Whitepaper` | `Article` |
|
|
200
|
-
| `ResourceDetail` | `Article` |
|
|
201
|
-
| `TechArticle` | `TechArticle` |
|
|
202
|
-
| `DocsDetail` | `TechArticle` |
|
|
203
|
-
|
|
204
|
-
## Total
|
|
205
|
-
|
|
206
|
-
**Two distinct counts, not one.** The AILK page-type registry — the types
|
|
207
|
-
`add-schema` can scaffold with a real builder — has **60 keys** (24 distinct
|
|
208
|
-
`@type` values; see the family tables above). The general schema.org
|
|
209
|
-
vocabulary tables earlier in this file are a separate, smaller, hand-curated
|
|
210
|
-
list the skill also recognizes by name for non-registry types; several of
|
|
211
|
-
those are still `_consumer-defined_` because `@working-theory/schema` hasn't
|
|
212
|
-
shipped a typed builder for them yet — for those, the skill emits the JSON-LD
|
|
213
|
-
as an inline literal with a comment noting the upstream issue.
|
|
214
|
-
|
|
215
|
-
## When `@working-theory/schema` doesn't yet export the builder
|
|
216
|
-
|
|
217
|
-
Some entries above say `_consumer-defined_` for the builder
|
|
218
|
-
column. The skill's behavior in that case:
|
|
219
|
-
|
|
220
|
-
1. Surface the gap:
|
|
221
|
-
|
|
222
|
-
> "`@working-theory/schema` doesn't export `build<Type>` yet. I can:
|
|
223
|
-
>
|
|
224
|
-
> - Emit the JSON-LD as an inline object literal (less
|
|
225
|
-
> type-safe but works).
|
|
226
|
-
> - Skip — you author it manually using the canonical
|
|
227
|
-
> `<JsonLd schema={...}/>` pattern.
|
|
228
|
-
>
|
|
229
|
-
> Which?"
|
|
230
|
-
|
|
231
|
-
2. Wait for the consumer's choice. Don't fabricate a builder.
|
|
232
|
-
|
|
233
|
-
This matches `scaffold-page` (#362)'s behavior — both skills handle
|
|
234
|
-
the missing-builder case the same way.
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
# `RUNBOOK.md` Template
|
|
2
|
-
|
|
3
|
-
The `provision-config` skill emits this runbook at the consumer's
|
|
4
|
-
project root. It documents pre-deploy steps, the **critical**
|
|
5
|
-
leads-persistence caveat, and the three named upgrade paths.
|
|
6
|
-
|
|
7
|
-
The skill must verify all three named persistence-section headings
|
|
8
|
-
are present after emit (per SKILL.md Step 6 validation). If any is
|
|
9
|
-
missing, the skill has a bug.
|
|
10
|
-
|
|
11
|
-
## Template
|
|
12
|
-
|
|
13
|
-
```markdown
|
|
14
|
-
# RUNBOOK — Production Operations
|
|
15
|
-
|
|
16
|
-
This runbook is generated by the `provision-config` skill. It covers
|
|
17
|
-
what to do before and after deploying to Vercel, plus the
|
|
18
|
-
operational caveats AILK ships with.
|
|
19
|
-
|
|
20
|
-
If you re-run `provision-config`, new sections may be appended at
|
|
21
|
-
the end under "## Added by provision-config." Existing sections are
|
|
22
|
-
not modified by the skill.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Pre-deploy checklist
|
|
27
|
-
|
|
28
|
-
Before you click Deploy in Vercel:
|
|
29
|
-
|
|
30
|
-
- [ ] **Add a Vercel project** pointed at this repo
|
|
31
|
-
(`vercel link` from the CLI, or the dashboard).
|
|
32
|
-
- [ ] **Set environment variables** in Vercel's project dashboard
|
|
33
|
-
(Settings → Environment Variables). Use `.env.example` as the
|
|
34
|
-
contract — every variable listed there should have a value
|
|
35
|
-
set in Vercel before deploy.
|
|
36
|
-
- [ ] **Configure your custom domain** if you have one (Vercel
|
|
37
|
-
Project → Settings → Domains). Vercel handles TLS automatically.
|
|
38
|
-
- [ ] **Pick a leads-persistence backend** — see the three named
|
|
39
|
-
upgrade paths below. **Do not deploy without picking one** if
|
|
40
|
-
your site captures leads. AILK's default `leads.jsonl`
|
|
41
|
-
fallback does not persist on Vercel's ephemeral filesystem.
|
|
42
|
-
- [ ] **Register production OAuth callbacks** if you used
|
|
43
|
-
`scaffold-auth` and activated Google or GitHub. Each provider
|
|
44
|
-
needs the prod callback URL added to its OAuth app settings.
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## Operations — leads.jsonl persistence
|
|
49
|
-
|
|
50
|
-
> **Critical:** AILK's default lead-capture writes to
|
|
51
|
-
> `apps/api/leads.jsonl`. On Vercel's ephemeral filesystem, this
|
|
52
|
-
> file **does not persist** across cold starts. Leads captured
|
|
53
|
-
> during one container's lifetime are lost when that container
|
|
54
|
-
> shuts down.
|
|
55
|
-
|
|
56
|
-
You **must** pick a persistence backend before going live or you
|
|
57
|
-
will lose leads. Pick one of the three sections below based on
|
|
58
|
-
your situation:
|
|
59
|
-
|
|
60
|
-
- Cheapest fix, drop-in, native Vercel — **Vercel KV**
|
|
61
|
-
- One provider for db + auth + storage — **Supabase**
|
|
62
|
-
- Already have Postgres elsewhere — **Postgres via `@working-theory/database`**
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Persistence upgrade — Vercel KV
|
|
67
|
-
|
|
68
|
-
**When to pick:** you want the cheapest fix, no new infra, and
|
|
69
|
-
you're already on Vercel. Vercel KV is Redis-compatible key-value
|
|
70
|
-
storage, native to the Vercel dashboard.
|
|
71
|
-
|
|
72
|
-
**Setup:**
|
|
73
|
-
|
|
74
|
-
1. Vercel Dashboard → Storage → Create Database → KV.
|
|
75
|
-
2. Connect to your project. Vercel auto-populates
|
|
76
|
-
`KV_REST_API_URL` and `KV_REST_API_TOKEN` in your project
|
|
77
|
-
environment.
|
|
78
|
-
3. Pull updated env vars locally: `vercel env pull`.
|
|
79
|
-
4. Switch the lead-capture writer in your code from JSONL to KV
|
|
80
|
-
(`@working-theory/api`'s lead-capture supports a KV adapter — see its
|
|
81
|
-
README for the wiring).
|
|
82
|
-
5. Redeploy.
|
|
83
|
-
|
|
84
|
-
**Trade-offs:** KV is fast and easy but has limits (storage
|
|
85
|
-
ceilings, access patterns). For >10K leads/month or rich querying,
|
|
86
|
-
graduate to Supabase or Postgres.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Persistence upgrade — Supabase
|
|
91
|
-
|
|
92
|
-
**When to pick:** you want one provider for database, auth, and
|
|
93
|
-
storage. You're not committed to NextAuth (Supabase has its own
|
|
94
|
-
auth), or you're fine running NextAuth + Supabase auth in parallel.
|
|
95
|
-
|
|
96
|
-
**Setup:**
|
|
97
|
-
|
|
98
|
-
1. Sign up at <https://supabase.com>.
|
|
99
|
-
2. Create a project.
|
|
100
|
-
3. Go to Settings → API. Copy:
|
|
101
|
-
- `Project URL` → `NEXT_PUBLIC_SUPABASE_URL`
|
|
102
|
-
- `anon public` key → `NEXT_PUBLIC_SUPABASE_ANON_KEY`
|
|
103
|
-
- `service_role` key → `SUPABASE_SERVICE_ROLE_KEY` (server-only)
|
|
104
|
-
4. Set those three env vars in Vercel project settings.
|
|
105
|
-
5. Run the AILK Supabase migration (see `@working-theory/database` Supabase
|
|
106
|
-
adapter README — the migration creates a `leads` table with the
|
|
107
|
-
AILK schema).
|
|
108
|
-
6. Switch the lead-capture writer to use the Supabase adapter.
|
|
109
|
-
7. Redeploy.
|
|
110
|
-
|
|
111
|
-
**Trade-offs:** Supabase is generous on free tier, scales well, and
|
|
112
|
-
its dashboard is excellent. The auth coexistence with NextAuth is
|
|
113
|
-
the only design wrinkle — most consumers either use NextAuth alone
|
|
114
|
-
(treating Supabase as just a Postgres host) or commit to Supabase
|
|
115
|
-
auth and remove NextAuth.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Persistence upgrade — Postgres via `@working-theory/database`
|
|
120
|
-
|
|
121
|
-
**When to pick:** you already have Postgres somewhere — Neon,
|
|
122
|
-
Railway, RDS, self-hosted, anywhere. You don't need a new provider
|
|
123
|
-
relationship.
|
|
124
|
-
|
|
125
|
-
**Setup:**
|
|
126
|
-
|
|
127
|
-
1. Get a Postgres connection string from your provider. Format:
|
|
128
|
-
`postgres://user:password@host:5432/dbname`.
|
|
129
|
-
2. Set `DATABASE_URL` in Vercel project settings.
|
|
130
|
-
3. Install `@working-theory/database`: `pnpm add @working-theory/database`.
|
|
131
|
-
4. Run the migration:
|
|
132
|
-
`pnpm --filter @working-theory/database run migrate:deploy` (or your
|
|
133
|
-
provider's equivalent).
|
|
134
|
-
5. The `@working-theory/database` package exposes a Prisma client tied to the
|
|
135
|
-
AILK schema; switch the lead-capture writer to use it.
|
|
136
|
-
6. Redeploy.
|
|
137
|
-
|
|
138
|
-
**Trade-offs:** most flexible, most setup. You manage the database
|
|
139
|
-
yourself (backups, connection pooling, scaling). For consumers who
|
|
140
|
-
already have Postgres in their stack, this is the natural fit.
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## Custom domain + DNS
|
|
145
|
-
|
|
146
|
-
Vercel handles TLS automatically once a domain is added to your
|
|
147
|
-
project. Two paths:
|
|
148
|
-
|
|
149
|
-
- **Vercel-managed DNS** — let Vercel handle nameservers. Easiest;
|
|
150
|
-
Vercel Dashboard → Project → Settings → Domains → Add → "Manage
|
|
151
|
-
DNS Records."
|
|
152
|
-
- **External DNS** — add an A record (or CNAME for subdomains)
|
|
153
|
-
pointing at Vercel's IP, then add the domain to your project.
|
|
154
|
-
Vercel docs walk through it.
|
|
155
|
-
|
|
156
|
-
For email-sending domains (Resend, magic-link), you'll also need
|
|
157
|
-
to verify the sending domain in Resend's dashboard before
|
|
158
|
-
production magic-link emails will deliver. Resend Dashboard →
|
|
159
|
-
Domains → Add → DNS records → wait for verification.
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Production callbacks for OAuth (if you used `scaffold-auth`)
|
|
164
|
-
|
|
165
|
-
If you activated Google or GitHub OAuth via `scaffold-auth` (#364),
|
|
166
|
-
those activations used dev callback URLs (`localhost:3000`). For
|
|
167
|
-
production, add the prod callback URLs to each OAuth app:
|
|
168
|
-
|
|
169
|
-
### Google
|
|
170
|
-
|
|
171
|
-
1. Open the Google Cloud Console OAuth client you created
|
|
172
|
-
(<https://console.cloud.google.com/apis/credentials>).
|
|
173
|
-
2. Under **Authorized redirect URIs**, add:
|
|
174
|
-
`https://<your-prod-domain>/api/auth/callback/google`
|
|
175
|
-
3. Save.
|
|
176
|
-
|
|
177
|
-
### GitHub
|
|
178
|
-
|
|
179
|
-
1. Open the GitHub OAuth App you created
|
|
180
|
-
(<https://github.com/settings/developers>).
|
|
181
|
-
2. Edit either:
|
|
182
|
-
- The same app's **Authorization callback URL** to add a second
|
|
183
|
-
line for prod (GitHub allows multiple).
|
|
184
|
-
- Or create a separate OAuth App for production.
|
|
185
|
-
3. Update the env vars in Vercel if you created a separate app.
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## When to redeploy
|
|
190
|
-
|
|
191
|
-
- After changing any `NEXT_PUBLIC_*` env var (those bake at build
|
|
192
|
-
time).
|
|
193
|
-
- After running database migrations (data shape changed).
|
|
194
|
-
- After updating `vercel.json` (deploy config changed).
|
|
195
|
-
|
|
196
|
-
You do **not** need to redeploy after:
|
|
197
|
-
|
|
198
|
-
- Adding a non-`NEXT_PUBLIC_*` env var in Vercel's dashboard
|
|
199
|
-
(server-side reads pick it up on next request).
|
|
200
|
-
- Editing MDX content in `content/` and pushing — Vercel rebuilds
|
|
201
|
-
on push.
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
## Troubleshooting
|
|
206
|
-
|
|
207
|
-
- **"My leads disappeared"** → you skipped the leads-persistence
|
|
208
|
-
upgrade. Pick one of Vercel KV / Supabase / Postgres above and
|
|
209
|
-
migrate the writer.
|
|
210
|
-
- **"OAuth login redirects to localhost in production"** → you
|
|
211
|
-
haven't added the production callback URL to the OAuth app
|
|
212
|
-
(see above).
|
|
213
|
-
- **"Magic-link emails aren't arriving in production"** → your
|
|
214
|
-
Resend sender domain isn't verified yet (Resend Dashboard →
|
|
215
|
-
Domains).
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## Section headings the validation must find
|
|
221
|
-
|
|
222
|
-
After emit, the skill must grep for these three headings (verbatim
|
|
223
|
-
match). All three must be present:
|
|
224
|
-
|
|
225
|
-
- `## Persistence upgrade — Vercel KV`
|
|
226
|
-
- `## Persistence upgrade — Supabase`
|
|
227
|
-
- `## Persistence upgrade — Postgres via `@working-theory/database\``
|
|
228
|
-
|
|
229
|
-
If any is missing, the template was edited in a way that broke the
|
|
230
|
-
contract. Surface the failure to the consumer (not silent).
|
|
231
|
-
|
|
232
|
-
## Merge logic
|
|
233
|
-
|
|
234
|
-
If the consumer already has `RUNBOOK.md`, the skill (per SKILL.md
|
|
235
|
-
Step 3) offers merge / overwrite / skip. Merge logic:
|
|
236
|
-
|
|
237
|
-
1. Read the existing file.
|
|
238
|
-
2. Check whether each of the three named persistence section
|
|
239
|
-
headings is already present.
|
|
240
|
-
3. Headings already present → not modified.
|
|
241
|
-
4. Headings missing → append at the end of the existing file under:
|
|
242
|
-
```
|
|
243
|
-
## Added by provision-config
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
The pre-deploy checklist, custom-domain, and OAuth-prod-callbacks
|
|
247
|
-
sections are also appended if missing. Sections that are already
|
|
248
|
-
present (even with different content) are not modified.
|