create-ailk 0.4.0 → 0.6.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 +55 -8
- package/component-catalog.json +12248 -0
- package/component-catalog.md +193 -68
- package/dist/cli.js +29 -1
- package/dist/derive-architecture.js +5 -2
- package/dist/lib/api-boot-assertion.d.ts +46 -0
- package/dist/lib/api-boot-assertion.js +70 -0
- package/dist/lib/extract-module-bundle.d.ts +50 -2
- package/dist/lib/extract-module-bundle.js +223 -15
- package/dist/lib/fetch-guard.d.ts +28 -0
- package/dist/lib/fetch-guard.js +101 -0
- package/dist/lib/fetch-module.js +4 -0
- package/dist/lib/fetch-template.js +4 -0
- package/dist/lib/import-graph.d.ts +29 -0
- package/dist/lib/import-graph.js +140 -0
- package/dist/module-architecture.d.ts +60 -8
- package/dist/module-architecture.js +587 -242
- package/dist/parse-args.js +6 -2
- package/dist/programmatic.d.ts +10 -0
- package/dist/programmatic.js +134 -19
- package/dist/site-chrome.d.ts +80 -0
- package/dist/site-chrome.js +135 -0
- package/dist/surfaces.d.ts +21 -6
- package/dist/surfaces.js +209 -36
- package/dist/template-manifest.d.ts +88 -3
- package/dist/template-manifest.js +281 -29
- package/dist/template-names.d.ts +1 -1
- package/dist/template-names.js +2 -0
- package/package.json +10 -2
- package/site-templates/_base/ailk-template.json +6 -0
- package/site-templates/_base/content/en/Pricing/pricing.mdx +169 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +351 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +400 -0
- package/site-templates/marketing-site/ailk-template.json +11 -0
- package/site-templates/marketing-site/content/en/blog/05-this-vc-morning-routine-will-make-you-super-annoying.mdx +36 -0
- package/site-templates/marketing-site/provenance.json +4 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +288 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +286 -0
- package/site-templates/marketing-site-free/ailk-template.json +2 -1
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +279 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +336 -0
- package/site-templates/minimalism-site/ailk-template.json +22 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-1.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-2.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-3.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-4.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-5.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-6.svg +7 -0
- package/site-templates/minimalism-site/assets/hero-backdrop.svg +17 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-1.svg +6 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-2.svg +6 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-3.svg +6 -0
- package/site-templates/minimalism-site/assets/wordmark-placeholder.svg +28 -0
- package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +110 -0
- package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +68 -0
- package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +57 -0
- package/site-templates/minimalism-site/content/en/HomePage/home.mdx +244 -0
- package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +77 -0
- package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +73 -0
- package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +52 -0
- package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +73 -0
- package/site-templates/minimalism-site/flows/referral.flow.json +71 -0
- package/site-templates/minimalism-site/provenance.json +4 -0
- package/site-templates/saas-product/TEMPLATE-MANIFEST.md +61 -0
- package/site-templates/saas-product/ailk-template.json +16 -0
- package/site-templates/saas-product/provenance.json +10 -0
- package/site-templates/simple-service/TEMPLATE-MANIFEST.json +240 -0
- package/site-templates/simple-service/TEMPLATE-MANIFEST.md +278 -0
- package/site-templates/simple-service/ailk-template.json +10 -0
- package/site-templates/simple-service/content/en/AboutPage/about.mdx +38 -0
- package/site-templates/simple-service/content/en/ContactPage/contact.mdx +67 -0
- package/site-templates/simple-service/content/en/FAQPage/faq.mdx +56 -0
- package/site-templates/simple-service/content/en/HomePage/home.mdx +85 -0
- package/site-templates/simple-service/content/en/Service/landscape-design.mdx +40 -0
- package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +40 -0
- package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +40 -0
- package/site-templates/simple-service/content/en/ServicesList/services.mdx +72 -0
- package/site-templates/simple-service/provenance.json +4 -0
- package/templates/.claude/skills/README.md +16 -25
- package/templates/.env.example +102 -12
- package/templates/.github/workflows/ci.yml +48 -0
- package/templates/README.md +3 -1
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +8 -0
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +12 -0
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +12 -0
- package/templates/apps/api/.env.example +13 -0
- package/templates/apps/api/CLAUDE.md +29 -2
- package/templates/apps/api/eslint.config.mjs +69 -0
- package/templates/apps/api/jest.config.cjs +3 -0
- package/templates/apps/api/package.json +7 -2
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +407 -0
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +89 -9
- package/templates/apps/api/src/__tests__/review-surface-registration.test.ts +167 -0
- package/templates/apps/api/src/__tests__/server.test.ts +471 -0
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +45 -0
- package/templates/apps/api/src/__tests__/workspace-module-registration.test.ts +10 -1
- package/templates/apps/api/src/config/index.ts +62 -0
- package/templates/apps/api/src/config/modules.ts +7 -3
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +241 -2
- package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +143 -0
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +23 -0
- package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +125 -0
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +20 -0
- package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +317 -0
- package/templates/apps/api/src/lib/__tests__/site.test.ts +238 -0
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +75 -0
- package/templates/apps/api/src/lib/auth-email-budget.ts +160 -0
- package/templates/apps/api/src/lib/content-adapter.ts +57 -31
- package/templates/apps/api/src/lib/deliverable-asset-store.ts +76 -0
- package/templates/apps/api/src/lib/error-serializer.ts +23 -3
- package/templates/apps/api/src/lib/outbound-http.ts +7 -2
- package/templates/apps/api/src/lib/require-commerce-claim.ts +250 -0
- package/templates/apps/api/src/lib/site.ts +208 -9
- package/templates/apps/api/src/lib/stripe.ts +66 -0
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +521 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +150 -0
- package/templates/apps/api/src/middleware/default-tenant.ts +136 -0
- package/templates/apps/api/src/middleware/rate-limit.ts +7 -1
- package/templates/apps/api/src/openapi/spec.ts +543 -2
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +48 -0
- package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +309 -0
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +123 -0
- package/templates/apps/api/src/routes/auth/transactional-email.ts +273 -0
- package/templates/apps/api/src/routes/auth/user.ts +61 -0
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +434 -0
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +888 -0
- package/templates/apps/api/src/routes/checkout/index.ts +34 -0
- package/templates/apps/api/src/routes/checkout/session.ts +139 -0
- package/templates/apps/api/src/routes/checkout/sessions.ts +197 -0
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +554 -0
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +108 -0
- package/templates/apps/api/src/routes/content/__tests__/search.test.ts +450 -0
- package/templates/apps/api/src/routes/content/get-page.ts +94 -12
- package/templates/apps/api/src/routes/content/index.ts +13 -73
- package/templates/apps/api/src/routes/content/list-pages.ts +15 -3
- package/templates/apps/api/src/routes/content/rate-limit.ts +15 -6
- package/templates/apps/api/src/routes/content/search.ts +129 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +447 -31
- package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +171 -0
- package/templates/apps/api/src/routes/leads/index.ts +100 -13
- package/templates/apps/api/src/routes/leads/list.ts +104 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +351 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +5 -2
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +4 -1
- package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +58 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +107 -6
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +87 -2
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/start.ts +5 -1
- package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +686 -0
- package/templates/apps/api/src/routes/requests/confirm.ts +601 -0
- package/templates/apps/api/src/routes/requests/index.ts +54 -0
- package/templates/apps/api/src/routes/webhooks/README.md +265 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +749 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +330 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +262 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +285 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +213 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +301 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +648 -0
- package/templates/apps/api/src/routes/webhooks/index.ts +89 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +1399 -0
- package/templates/apps/api/src/server.ts +521 -55
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +39 -0
- package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +217 -40
- package/templates/apps/api/src/services/__tests__/audit-log.test.ts +620 -0
- package/templates/apps/api/src/services/__tests__/consent.test.ts +2 -0
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +300 -5
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +20 -0
- package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +368 -0
- package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +408 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +160 -0
- package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +329 -0
- package/templates/apps/api/src/services/__tests__/listing-config.test.ts +166 -0
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +154 -0
- package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +137 -0
- package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +444 -0
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +238 -0
- package/templates/apps/api/src/services/__tests__/verified-email.test.ts +78 -0
- package/templates/apps/api/src/services/abandon-email.ts +8 -2
- package/templates/apps/api/src/services/aeo-score.ts +49 -12
- package/templates/apps/api/src/services/audit-log.ts +668 -0
- package/templates/apps/api/src/services/consent.ts +18 -0
- package/templates/apps/api/src/services/default-tenant.ts +300 -0
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +141 -13
- package/templates/apps/api/src/services/dunning-policy.ts +294 -0
- package/templates/apps/api/src/services/entitlements.ts +80 -0
- package/templates/apps/api/src/services/lead-promotion.ts +160 -0
- package/templates/apps/api/src/services/lead-routing.ts +161 -2
- package/templates/apps/api/src/services/leads-inbox.ts +284 -0
- package/templates/apps/api/src/services/listing-config.ts +27 -9
- package/templates/apps/api/src/services/owner-workspaces.ts +132 -0
- package/templates/apps/api/src/services/project-listings.ts +201 -6
- package/templates/apps/api/src/services/public-site-resolver.ts +106 -0
- package/templates/apps/api/src/services/request-confirm.ts +646 -0
- package/templates/apps/api/src/services/revalidation.ts +173 -0
- package/templates/apps/api/src/services/verified-email.ts +71 -0
- package/templates/apps/api/src/vercel-handler.ts +75 -35
- package/templates/apps/mcp/.env.example +17 -0
- package/templates/apps/mcp/CLAUDE.md +58 -25
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +6 -0
- package/templates/apps/mcp/__tests__/audit.test.ts +137 -8
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +79 -36
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +111 -2
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +82 -2
- package/templates/apps/mcp/__tests__/http-transport.test.ts +541 -2
- package/templates/apps/mcp/__tests__/index.test.ts +39 -0
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +143 -0
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +111 -0
- package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +65 -0
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +188 -0
- package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +165 -0
- package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +124 -0
- package/templates/apps/mcp/__tests__/list_pages.test.ts +116 -0
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +7 -1
- package/templates/apps/mcp/__tests__/parity.test.ts +12 -9
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +89 -22
- package/templates/apps/mcp/__tests__/read_content.test.ts +322 -1
- package/templates/apps/mcp/__tests__/search_content.test.ts +105 -2
- package/templates/apps/mcp/__tests__/server.test.ts +67 -14
- package/templates/apps/mcp/__tests__/start_purchase.test.ts +252 -0
- package/templates/apps/mcp/__tests__/tools/{scaffold.test.ts → create_project.test.ts} +23 -23
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +300 -123
- package/templates/apps/mcp/eslint.config.mjs +69 -0
- package/templates/apps/mcp/jest.config.cjs +13 -0
- package/templates/apps/mcp/package.json +8 -2
- package/templates/apps/mcp/src/abuse/index.ts +159 -24
- package/templates/apps/mcp/src/config/modules.ts +10 -5
- package/templates/apps/mcp/src/http-transport.ts +102 -29
- package/templates/apps/mcp/src/index.ts +73 -11
- package/templates/apps/mcp/src/lib/audit-single-page.ts +90 -3
- package/templates/apps/mcp/src/lib/commerce-claim.ts +94 -0
- package/templates/apps/mcp/src/lib/content-adapter.ts +113 -0
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +139 -0
- package/templates/apps/mcp/src/lib/prisma.ts +39 -0
- package/templates/apps/mcp/src/lib/public-workspace.ts +133 -0
- package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +59 -0
- package/templates/apps/mcp/src/server.ts +61 -37
- package/templates/apps/mcp/src/tools/audit.ts +26 -2
- package/templates/apps/mcp/src/tools/{scaffold.ts → create_project.ts} +3 -3
- package/templates/apps/mcp/src/tools/get_business_hours.ts +4 -3
- package/templates/apps/mcp/src/tools/get_faq.ts +4 -3
- package/templates/apps/mcp/src/tools/get_locations.ts +5 -3
- package/templates/apps/mcp/src/tools/get_offerings.ts +16 -4
- package/templates/apps/mcp/src/tools/get_pricing.ts +25 -6
- package/templates/apps/mcp/src/tools/get_site_info.ts +4 -3
- package/templates/apps/mcp/src/tools/index.ts +9 -7
- package/templates/apps/mcp/src/tools/list_pages.ts +4 -3
- package/templates/apps/mcp/src/tools/purchase.ts +128 -45
- package/templates/apps/mcp/src/tools/read_content.ts +20 -6
- package/templates/apps/mcp/src/tools/search_content.ts +11 -4
- package/templates/apps/web/.env.example +74 -8
- package/templates/apps/web/CLAUDE.md +46 -0
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +18 -2
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +11 -3
- package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +282 -0
- package/templates/apps/web/app/[locale]/(auth)/__tests__/password-reset.test.tsx +515 -0
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +89 -0
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/page.tsx +109 -0
- package/templates/apps/web/app/[locale]/(auth)/layout.tsx +92 -0
- package/templates/apps/web/app/[locale]/(auth)/reset-password/page.tsx +135 -0
- package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +109 -0
- package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/page.test.tsx +48 -2
- package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/page.tsx +20 -6
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +125 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +96 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +101 -0
- package/templates/apps/web/app/[locale]/(auth)/use-auth-card-flow.ts +102 -0
- package/templates/apps/web/app/[locale]/(auth)/verify-email/page.tsx +87 -0
- package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +20 -10
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +84 -0
- package/templates/apps/web/app/[locale]/(authed)/account/actions.ts +58 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +67 -14
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +19 -2
- package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +181 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/components/LeadsTable.tsx +137 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +111 -0
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +1 -1
- package/templates/apps/web/app/[locale]/[slug]/__tests__/page.test.tsx +111 -0
- package/templates/apps/web/app/[locale]/[slug]/page.tsx +65 -0
- package/templates/apps/web/app/[locale]/cancellation/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +6 -5
- package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +1 -1
- package/templates/apps/web/app/[locale]/layout.tsx +308 -65
- package/templates/apps/web/app/[locale]/purchase/__tests__/cancel.test.tsx +162 -0
- package/templates/apps/web/app/[locale]/purchase/__tests__/module-scope.test.ts +68 -0
- package/templates/apps/web/app/[locale]/purchase/__tests__/success.test.tsx +361 -0
- package/templates/apps/web/app/[locale]/purchase/cancel/page.tsx +115 -0
- package/templates/apps/web/app/[locale]/purchase/success/page.tsx +307 -0
- package/templates/apps/web/app/[locale]/returns/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/shipping/page.tsx +44 -0
- package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +670 -0
- package/templates/apps/web/app/api/revalidate/route.ts +194 -0
- package/templates/apps/web/auth.ts +407 -8
- package/templates/apps/web/components/google-analytics.tsx +18 -1
- package/templates/apps/web/eslint.config.mjs +69 -0
- package/templates/apps/web/jest.config.cjs +15 -19
- package/templates/apps/web/lib/__tests__/auth-email.test.ts +214 -0
- package/templates/apps/web/lib/__tests__/auth-routes.test.ts +74 -0
- package/templates/apps/web/lib/__tests__/meeting-slugs.test.ts +72 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +50 -6
- package/templates/apps/web/lib/auth-email.ts +318 -0
- package/templates/apps/web/lib/auth-env.ts +85 -0
- package/templates/apps/web/lib/auth-routes.ts +55 -0
- package/templates/apps/web/lib/meeting-slugs.ts +53 -0
- package/templates/apps/web/lib/nav-config.ts +27 -7
- package/templates/apps/web/lib/server-api.ts +1 -1
- package/templates/apps/web/lib/site-chrome.ts +29 -0
- package/templates/apps/web/lib/telemetry-scrub.ts +50 -0
- package/templates/apps/web/messages/en.json +216 -2
- package/templates/apps/web/next.config.mjs +20 -0
- package/templates/apps/web/package.json +8 -3
- package/templates/apps/web/sentry.client.config.ts +131 -0
- package/templates/apps/web/sentry.edge.config.ts +72 -0
- package/templates/apps/web/sentry.server.config.ts +72 -0
- package/templates/apps/web/src/lib/commerce-claim.ts +33 -0
- package/templates/apps/web/src/lib/commerce-sections.ts +61 -0
- package/templates/apps/web/src/lib/routes.ts +13 -18
- package/templates/brand_assets/README.md +24 -0
- package/templates/content/en/AboutPage/about.mdx +160 -15
- package/templates/content/en/CancellationPolicyPage/cancellation.mdx +108 -0
- package/templates/content/en/ContactPage/contact.mdx +90 -13
- package/templates/content/en/FAQPage/faq.mdx +62 -22
- package/templates/content/en/HomePage/home.mdx +244 -20
- package/templates/content/en/LandingPage/blog.mdx +83 -0
- package/templates/content/en/LandingPage/features.mdx +103 -0
- package/templates/content/en/LandingPage/how-it-works.mdx +143 -0
- package/templates/content/en/ReturnsPolicyPage/returns.mdx +108 -0
- package/templates/content/en/ShippingPolicyPage/shipping.mdx +108 -0
- package/templates/database/CHANGELOG.md +149 -0
- package/templates/database/README.md +10 -3
- package/templates/database/__tests__/appointment.db.test.ts +106 -0
- package/templates/database/__tests__/artifact-content-store.db.test.ts +316 -0
- package/templates/database/__tests__/composite-fence.db.test.ts +206 -0
- package/templates/database/__tests__/fence-fan-out.db.test.ts +711 -0
- package/templates/database/__tests__/fixtures/appointment-create-probe.ts +79 -0
- package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +100 -0
- package/templates/database/__tests__/flow-workspace-key.db.test.ts +263 -0
- package/templates/database/__tests__/prefixed-ids.db.test.ts +85 -9
- package/templates/database/__tests__/project-listing-consent-at.db.test.ts +111 -0
- package/templates/database/__tests__/seed.test.ts +1 -1
- package/templates/database/__tests__/tenancy.test.ts +141 -0
- package/templates/database/config/schema.prisma +79 -2
- package/templates/database/content/schema.prisma +87 -11
- package/templates/database/eslint.config.mjs +69 -0
- package/templates/database/inbox/schema.prisma +452 -9
- package/templates/database/jest.config.cjs +5 -3
- package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +15 -0
- package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +158 -0
- package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +40 -0
- package/templates/database/migrations/20260918120000_add_appointment/migration.sql +67 -0
- package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +70 -0
- package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +181 -0
- package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +172 -0
- package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +41 -0
- package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +185 -0
- package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +70 -0
- package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +57 -0
- package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +68 -0
- package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +1067 -0
- package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +210 -0
- package/templates/database/package.json +7 -3
- package/templates/database/seed.ts +1 -1
- package/templates/database/tenancy.ts +86 -1
- package/templates/database/tsconfig.json +1 -0
- package/templates/package.json +1 -14
- package/versions.json +52 -0
- package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +0 -103
- package/templates/apps/api/src/routes/content/__tests__/create.test.ts +0 -253
- package/templates/apps/api/src/routes/content/__tests__/delete.test.ts +0 -215
- package/templates/apps/api/src/routes/content/__tests__/update.test.ts +0 -266
- package/templates/apps/api/src/routes/content/create.ts +0 -115
- package/templates/apps/api/src/routes/content/delete.ts +0 -82
- package/templates/apps/api/src/routes/content/update.ts +0 -112
- package/templates/apps/mcp/__tests__/create_page.test.ts +0 -202
- package/templates/apps/mcp/__tests__/delete_page.test.ts +0 -177
- package/templates/apps/mcp/__tests__/update_page.test.ts +0 -196
- package/templates/apps/mcp/src/tools/create_page.ts +0 -96
- package/templates/apps/mcp/src/tools/delete_page.ts +0 -74
- package/templates/apps/mcp/src/tools/update_page.ts +0 -92
- package/templates/apps/web/app/[locale]/sign-in/sign-in-card.tsx +0 -123
- /package/site-templates/{marketing-site-free → _base}/content/en/PrivacyPage/privacy.mdx +0 -0
- /package/site-templates/{marketing-site-free → _base}/content/en/TermsPage/terms.mdx +0 -0
- /package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/next-path.test.ts +0 -0
- /package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/next-path.ts +0 -0
- /package/templates/apps/web/{src/components → components}/SiteNav.tsx +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "FAQPage"
|
|
3
|
+
slug: "faq"
|
|
4
|
+
title: "FAQ"
|
|
5
|
+
description: "The questions people ask before they book. Placeholder copy — replace every answer before you launch."
|
|
6
|
+
sections:
|
|
7
|
+
[
|
|
8
|
+
{
|
|
9
|
+
"id": "faq",
|
|
10
|
+
"type": "faq",
|
|
11
|
+
"data":
|
|
12
|
+
{
|
|
13
|
+
"headline": "Questions",
|
|
14
|
+
"variant": "centered",
|
|
15
|
+
"initialOpen": "first",
|
|
16
|
+
"items":
|
|
17
|
+
[
|
|
18
|
+
{
|
|
19
|
+
"question": "{Which areas do you cover?}",
|
|
20
|
+
"answer": "{Name the towns, the radius or the postcodes. A reader outside them should know it here.}",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"question": "{How often do you visit?}",
|
|
24
|
+
"answer": "{Give the real cadence for the recurring job, and say what happens in winter.}",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"question": "{What does it cost?}",
|
|
28
|
+
"answer": "{The three service pages carry the prices. Say here what moves them — yard size, access, waste removal.}",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"question": "{How do I pay?}",
|
|
32
|
+
"answer": "{Say when payment is taken and how. Checkout runs on your own Stripe account; the card details never touch this site.}",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"question": "{What if I need to cancel?}",
|
|
36
|
+
"answer": "{Point at the cancellation policy and give the notice period in one line.}",
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
"supportLink":
|
|
40
|
+
{ "label": "Still stuck? Get in touch", "href": "/contact" },
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "closing",
|
|
45
|
+
"type": "cta",
|
|
46
|
+
"data":
|
|
47
|
+
{
|
|
48
|
+
"variant": "minimal",
|
|
49
|
+
"headline": "Still have a question?",
|
|
50
|
+
"primaryCta": { "label": "Contact us →", "href": "/contact" },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
]
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
Placeholder copy. Replace every answer before you launch.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "HomePage"
|
|
3
|
+
slug: "home"
|
|
4
|
+
title: "Your Company"
|
|
5
|
+
description: "Placeholder home for the simple-service template — a lawn-care site that books a visit and takes the payment. Replace every line before you launch."
|
|
6
|
+
sections:
|
|
7
|
+
[
|
|
8
|
+
{
|
|
9
|
+
"id": "hero",
|
|
10
|
+
"type": "hero",
|
|
11
|
+
"data":
|
|
12
|
+
{
|
|
13
|
+
"variant": "centered",
|
|
14
|
+
"eyebrow": "{Your service area}",
|
|
15
|
+
"headline": "{Lawn care that turns up when it says it will}",
|
|
16
|
+
"subheadline": "{One line on who you serve and what they get. Name the street, the town or the county — a local reader is looking for their own.}",
|
|
17
|
+
"primaryCta": { "label": "Book a visit →", "href": "/meet" },
|
|
18
|
+
"secondaryCta":
|
|
19
|
+
{
|
|
20
|
+
"label": "See services",
|
|
21
|
+
"href": "/services",
|
|
22
|
+
"variant": "outline",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "services",
|
|
28
|
+
"type": "items",
|
|
29
|
+
"data":
|
|
30
|
+
{
|
|
31
|
+
"headline": "What we do",
|
|
32
|
+
"columns": 3,
|
|
33
|
+
"items":
|
|
34
|
+
[
|
|
35
|
+
{
|
|
36
|
+
"title": "{Lawn maintenance}",
|
|
37
|
+
"description": "{One line on the recurring visit — what it includes and how often it runs.}",
|
|
38
|
+
"link":
|
|
39
|
+
{
|
|
40
|
+
"label": "Read more",
|
|
41
|
+
"href": "/services/lawn-maintenance",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"title": "{Seasonal cleanup}",
|
|
46
|
+
"description": "{One line on the spring and autumn clear-down.}",
|
|
47
|
+
"link":
|
|
48
|
+
{
|
|
49
|
+
"label": "Read more",
|
|
50
|
+
"href": "/services/seasonal-cleanup",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"title": "{Landscape design}",
|
|
55
|
+
"description": "{One line on the design-and-plant job, and what a customer ends up with.}",
|
|
56
|
+
"link":
|
|
57
|
+
{
|
|
58
|
+
"label": "Read more",
|
|
59
|
+
"href": "/services/landscape-design",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "closing",
|
|
67
|
+
"type": "cta",
|
|
68
|
+
"data":
|
|
69
|
+
{
|
|
70
|
+
"variant": "minimal",
|
|
71
|
+
"headline": "Ready for a tidier yard?",
|
|
72
|
+
"description": "{One line inviting the reader to pick a time rather than fill in a form.}",
|
|
73
|
+
"primaryCta": { "label": "Book a visit →", "href": "/meet" },
|
|
74
|
+
"secondaryCta":
|
|
75
|
+
{
|
|
76
|
+
"label": "Ask a question",
|
|
77
|
+
"href": "/contact",
|
|
78
|
+
"variant": "outline",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
]
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
Placeholder copy. Every headline, every line of body copy and every price on this site is a placeholder — replace them before you launch.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "Service"
|
|
3
|
+
slug: "landscape-design"
|
|
4
|
+
title: "{Landscape design}"
|
|
5
|
+
description: "{One line on what this job is and who it suits. Replace before you launch.}"
|
|
6
|
+
price: 1250
|
|
7
|
+
priceCurrency: "USD"
|
|
8
|
+
provider:
|
|
9
|
+
name: "{Your Company}"
|
|
10
|
+
schema:
|
|
11
|
+
serviceType: "{Landscape design}"
|
|
12
|
+
areaServed: "{Your service area}"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# \{Landscape design\}
|
|
16
|
+
|
|
17
|
+
\{Open with the situation a reader is in when they come looking for this. Two or
|
|
18
|
+
three sentences, no more — the detail belongs under the headings below.\}
|
|
19
|
+
|
|
20
|
+
## What it covers
|
|
21
|
+
|
|
22
|
+
- \{The first thing you actually do\}
|
|
23
|
+
- \{The second thing you actually do\}
|
|
24
|
+
- \{The third thing you actually do\}
|
|
25
|
+
|
|
26
|
+
## How it runs
|
|
27
|
+
|
|
28
|
+
\{One paragraph on the shape of the visit: how it is scheduled, how long it
|
|
29
|
+
takes, who turns up, and what you need from the customer beforehand.\}
|
|
30
|
+
|
|
31
|
+
## What you end up with
|
|
32
|
+
|
|
33
|
+
\{One paragraph on the result. Be concrete — describe the yard when the crew
|
|
34
|
+
drives away.\}
|
|
35
|
+
|
|
36
|
+
## What it costs
|
|
37
|
+
|
|
38
|
+
\{The price in this page's frontmatter is a PLACEHOLDER. It is what the site
|
|
39
|
+
publishes as a schema.org `Offer`, so an agent reading this page quotes it —
|
|
40
|
+
replace it with your real number before you launch.\}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "Service"
|
|
3
|
+
slug: "lawn-maintenance"
|
|
4
|
+
title: "{Lawn maintenance}"
|
|
5
|
+
description: "{One line on what this job is and who it suits. Replace before you launch.}"
|
|
6
|
+
price: 149
|
|
7
|
+
priceCurrency: "USD"
|
|
8
|
+
provider:
|
|
9
|
+
name: "{Your Company}"
|
|
10
|
+
schema:
|
|
11
|
+
serviceType: "{Lawn maintenance}"
|
|
12
|
+
areaServed: "{Your service area}"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# \{Lawn maintenance\}
|
|
16
|
+
|
|
17
|
+
\{Open with the situation a reader is in when they come looking for this. Two or
|
|
18
|
+
three sentences, no more — the detail belongs under the headings below.\}
|
|
19
|
+
|
|
20
|
+
## What it covers
|
|
21
|
+
|
|
22
|
+
- \{The first thing you actually do\}
|
|
23
|
+
- \{The second thing you actually do\}
|
|
24
|
+
- \{The third thing you actually do\}
|
|
25
|
+
|
|
26
|
+
## How it runs
|
|
27
|
+
|
|
28
|
+
\{One paragraph on the shape of the visit: how it is scheduled, how long it
|
|
29
|
+
takes, who turns up, and what you need from the customer beforehand.\}
|
|
30
|
+
|
|
31
|
+
## What you end up with
|
|
32
|
+
|
|
33
|
+
\{One paragraph on the result. Be concrete — describe the yard when the crew
|
|
34
|
+
drives away.\}
|
|
35
|
+
|
|
36
|
+
## What it costs
|
|
37
|
+
|
|
38
|
+
\{The price in this page's frontmatter is a PLACEHOLDER. It is what the site
|
|
39
|
+
publishes as a schema.org `Offer`, so an agent reading this page quotes it —
|
|
40
|
+
replace it with your real number before you launch.\}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "Service"
|
|
3
|
+
slug: "seasonal-cleanup"
|
|
4
|
+
title: "{Seasonal cleanup}"
|
|
5
|
+
description: "{One line on what this job is and who it suits. Replace before you launch.}"
|
|
6
|
+
price: 289
|
|
7
|
+
priceCurrency: "USD"
|
|
8
|
+
provider:
|
|
9
|
+
name: "{Your Company}"
|
|
10
|
+
schema:
|
|
11
|
+
serviceType: "{Seasonal cleanup}"
|
|
12
|
+
areaServed: "{Your service area}"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# \{Seasonal cleanup\}
|
|
16
|
+
|
|
17
|
+
\{Open with the situation a reader is in when they come looking for this. Two or
|
|
18
|
+
three sentences, no more — the detail belongs under the headings below.\}
|
|
19
|
+
|
|
20
|
+
## What it covers
|
|
21
|
+
|
|
22
|
+
- \{The first thing you actually do\}
|
|
23
|
+
- \{The second thing you actually do\}
|
|
24
|
+
- \{The third thing you actually do\}
|
|
25
|
+
|
|
26
|
+
## How it runs
|
|
27
|
+
|
|
28
|
+
\{One paragraph on the shape of the visit: how it is scheduled, how long it
|
|
29
|
+
takes, who turns up, and what you need from the customer beforehand.\}
|
|
30
|
+
|
|
31
|
+
## What you end up with
|
|
32
|
+
|
|
33
|
+
\{One paragraph on the result. Be concrete — describe the yard when the crew
|
|
34
|
+
drives away.\}
|
|
35
|
+
|
|
36
|
+
## What it costs
|
|
37
|
+
|
|
38
|
+
\{The price in this page's frontmatter is a PLACEHOLDER. It is what the site
|
|
39
|
+
publishes as a schema.org `Offer`, so an agent reading this page quotes it —
|
|
40
|
+
replace it with your real number before you launch.\}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "ServicesList"
|
|
3
|
+
slug: "services"
|
|
4
|
+
title: "Services"
|
|
5
|
+
description: "The three jobs {your company} does, each with its own price. Placeholder copy — replace before you launch."
|
|
6
|
+
sections:
|
|
7
|
+
[
|
|
8
|
+
{
|
|
9
|
+
"id": "hero",
|
|
10
|
+
"type": "hero",
|
|
11
|
+
"data":
|
|
12
|
+
{
|
|
13
|
+
"variant": "centered",
|
|
14
|
+
"eyebrow": "Services",
|
|
15
|
+
"headline": "Three jobs, three prices",
|
|
16
|
+
"subheadline": "{One line on how to choose between them. Name the question a reader is actually asking.}",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "jobs",
|
|
21
|
+
"type": "items",
|
|
22
|
+
"data":
|
|
23
|
+
{
|
|
24
|
+
"headline": "What we do",
|
|
25
|
+
"columns": 3,
|
|
26
|
+
"items":
|
|
27
|
+
[
|
|
28
|
+
{
|
|
29
|
+
"title": "{Lawn maintenance}",
|
|
30
|
+
"description": "{One line on the recurring visit — what it includes and how often it runs.}",
|
|
31
|
+
"link":
|
|
32
|
+
{
|
|
33
|
+
"label": "Read more",
|
|
34
|
+
"href": "/services/lawn-maintenance",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"title": "{Seasonal cleanup}",
|
|
39
|
+
"description": "{One line on the spring and autumn clear-down.}",
|
|
40
|
+
"link":
|
|
41
|
+
{
|
|
42
|
+
"label": "Read more",
|
|
43
|
+
"href": "/services/seasonal-cleanup",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"title": "{Landscape design}",
|
|
48
|
+
"description": "{One line on the design-and-plant job, and what a customer ends up with.}",
|
|
49
|
+
"link":
|
|
50
|
+
{
|
|
51
|
+
"label": "Read more",
|
|
52
|
+
"href": "/services/landscape-design",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "closing",
|
|
60
|
+
"type": "cta",
|
|
61
|
+
"data":
|
|
62
|
+
{
|
|
63
|
+
"variant": "minimal",
|
|
64
|
+
"headline": "Not sure which one?",
|
|
65
|
+
"description": "{One line inviting the reader to book the visit instead of guessing.}",
|
|
66
|
+
"primaryCta": { "label": "Book a visit →", "href": "/meet" },
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
]
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
Placeholder copy. The three detail pages under `content/en/Service/` carry the long form and the price; this page is the chooser.
|
|
@@ -4,41 +4,32 @@ Skills are reusable Claude Code workflows scoped to this project. Each
|
|
|
4
4
|
lives in its own subdirectory with a `SKILL.md` describing when to use
|
|
5
5
|
it and how it works.
|
|
6
6
|
|
|
7
|
-
The
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
20
|
-
| `scaffold-auth` | Wire up an auth flow against `@working-theory/auth-client` | coming soon — issue #364 (working-theory-labs/ai-launch-kit) |
|
|
21
|
-
| `audit-site` | Run `ailk audit` and explain the results | coming soon — issue #365 (working-theory-labs/ai-launch-kit) |
|
|
22
|
-
| `add-schema` | Add Product / Service / FAQ schema to an existing page | coming soon — issue #366 (working-theory-labs/ai-launch-kit) |
|
|
23
|
-
| `provision-config` | Generate `vercel.json` and environment templates | coming soon — issue #367 (working-theory-labs/ai-launch-kit) |
|
|
7
|
+
The six skills below ship with this project. Claude Code discovers
|
|
8
|
+
them automatically at session start — nothing to install or enable.
|
|
9
|
+
|
|
10
|
+
## Available skills
|
|
11
|
+
|
|
12
|
+
| Skill | Purpose |
|
|
13
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
14
|
+
| `suggest-site-pages` | Recommend a starter set of pages — each tagged with a schema.org type — from a free-text business description. |
|
|
15
|
+
| `scaffold-page` | Generate a new page: App Router route + MDX content stub + typed JSON-LD, in one confirm-before-write pass. |
|
|
16
|
+
| `add-schema` | Add or replace schema.org JSON-LD on a page that already exists. |
|
|
17
|
+
| `scaffold-auth` | Activate auth providers — magic-link via Resend, Google OAuth, GitHub OAuth. |
|
|
18
|
+
| `provision-config` | Emit deploy configuration — `vercel.json`, `.env.example`, and `RUNBOOK.md` — for a Vercel deploy. |
|
|
19
|
+
| `audit-site` | Run `ailk-audit --json` and explain the score and findings in plain language. |
|
|
24
20
|
|
|
25
21
|
`scaffold-commerce` is delivered with the commerce module (`--modules commerce`, licensed).
|
|
26
22
|
|
|
27
|
-
## How a skill
|
|
23
|
+
## How a skill works
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
subdirectory of the same name, each holding:
|
|
25
|
+
Each subdirectory holds:
|
|
31
26
|
|
|
32
27
|
- `SKILL.md` — when to invoke, what it produces, what it requires.
|
|
33
28
|
- Any supporting prompt fragments, code templates, or reference
|
|
34
29
|
files the skill loads at runtime.
|
|
35
30
|
|
|
36
|
-
Until then, the workflows the skills will perform can still be done
|
|
37
|
-
by hand or by asking Claude Code directly.
|
|
38
|
-
|
|
39
31
|
## Adding your own
|
|
40
32
|
|
|
41
33
|
To add a project-specific skill, create a folder here with a
|
|
42
34
|
`SKILL.md` describing it. Claude Code will discover it automatically
|
|
43
|
-
on session start. See the
|
|
44
|
-
of the format.
|
|
35
|
+
on session start. See the skills above for examples of the format.
|
package/templates/.env.example
CHANGED
|
@@ -23,13 +23,20 @@ STEALTH=true
|
|
|
23
23
|
# hide the Blog link. Set BLOG_ENABLED=true and redeploy to launch the blog.
|
|
24
24
|
# BLOG_ENABLED=true
|
|
25
25
|
|
|
26
|
-
# ── Content
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
|
|
26
|
+
# ── Content adapter ──────────────────────────────────────────────────────────
|
|
27
|
+
# Which content adapter every consumer resolves: mdx (default, reads
|
|
28
|
+
# /content/*.mdx at the repo root) | projection (compiled manifest) | database
|
|
29
|
+
# (the Artifact store — needs a workspaceId).
|
|
30
|
+
CONTENT_ADAPTER=mdx
|
|
31
|
+
# CONTENT_BACKEND is deprecated — read for one release, then removed.
|
|
31
32
|
# Override the content directory (default: <repo-root>/content). Useful for tests.
|
|
32
33
|
# AILK_CONTENT_ROOT=
|
|
34
|
+
# Publish revalidation (#5851) — where apps/api POSTs on publish/unpublish so
|
|
35
|
+
# the site purges the affected tag, and the HMAC-SHA256 key it signs the body
|
|
36
|
+
# with. Required only under CONTENT_ADAPTER=database; with the URL unset the
|
|
37
|
+
# webhook is a logged no-op.
|
|
38
|
+
# CONTENT_REVALIDATE_URL=https://example.com/api/revalidate
|
|
39
|
+
# CONTENT_REVALIDATE_SECRET=
|
|
33
40
|
|
|
34
41
|
# ── Database (optional in standalone mode) ───────────────────────────────────
|
|
35
42
|
# DATABASE_URL=postgres://user:pass@host:5432/db
|
|
@@ -50,16 +57,51 @@ CONTENT_BACKEND=mdx
|
|
|
50
57
|
# BETTER_AUTH_URL=http://localhost:3000
|
|
51
58
|
# BETTER_AUTH_SECRET=
|
|
52
59
|
|
|
53
|
-
# ── Single-tenant operator pin (
|
|
60
|
+
# ── Single-tenant operator pin (apps/api) ────────────────────────────────────
|
|
61
|
+
# REQUIRED on a build WITHOUT the multi-tenant module — for the submissions
|
|
62
|
+
# review dashboard AND for the `workspace` module's settings surface.
|
|
63
|
+
# OPTIONAL with the multi-tenant module.
|
|
64
|
+
#
|
|
54
65
|
# On a single-tenant deployment (the default Workspace exists and is the ONLY
|
|
55
66
|
# Workspace) the FIRST authenticated user to resolve a tenant context is
|
|
56
67
|
# bound as the sole owner (TOFU — trust on first use); every subsequent
|
|
57
|
-
# caller is denied. AILK_OPERATOR_EMAIL
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
68
|
+
# caller is denied. AILK_OPERATOR_EMAIL pins that binding to one email
|
|
69
|
+
# address instead of "whoever logs in first". Case-insensitive, trimmed.
|
|
70
|
+
#
|
|
71
|
+
# WITHOUT the multi-tenant module it is MANDATORY and unset fails CLOSED:
|
|
72
|
+
# the review routes (/v1/waitlist-experiments/*, the tenant-scoped
|
|
73
|
+
# /v1/project-listings/*) answer 403 to everyone, including you. That is
|
|
74
|
+
# deliberate. Those routes can widen to an unfiltered, every-site read for an
|
|
75
|
+
# owner of the default Organization, so an unpinned deployment must not seat
|
|
76
|
+
# whoever authenticates first — on a site with public sign-ups that is not
|
|
77
|
+
# necessarily you. The pinned account's email must also be VERIFIED.
|
|
78
|
+
#
|
|
79
|
+
# The same MANDATORY-and-fail-closed rule covers a `--modules workspace`
|
|
80
|
+
# deployment (#5371, #5515 item 1). The Pro workspace module registers
|
|
81
|
+
# /v1/workspaces/:workspaceId/{theme,identity,seo,general,members} behind the
|
|
82
|
+
# same guard, so on a workspace-only build the module's Admin pages (/admin)
|
|
83
|
+
# answer 403 to everyone until this is set — and, because the guard refuses
|
|
84
|
+
# BEFORE resolving, the first account to load the settings page cannot bind
|
|
85
|
+
# ITSELF as the sole owner off a plain GET. Set this before you hand the site
|
|
86
|
+
# to its owner.
|
|
87
|
+
#
|
|
88
|
+
# If your own dashboard returns 403, this variable is the first thing to
|
|
89
|
+
# check. With the multi-tenant module present, resolution comes from the
|
|
90
|
+
# session's active workspace and this stays optional, exactly as before.
|
|
61
91
|
# AILK_OPERATOR_EMAIL=
|
|
62
92
|
#
|
|
93
|
+
# ── Site id (apps/api, apps/web) ─────────────────────────────────────────────
|
|
94
|
+
# The scope captured rows are stamped with. Lead, WaitlistExperiment and
|
|
95
|
+
# ProjectListing carry `siteId`, which defaults to the literal "default"
|
|
96
|
+
# (apps/api/src/lib/site.ts), while tenancy scopes reads by WORKSPACE id.
|
|
97
|
+
# A single-tenant deployment should set this to the default workspace
|
|
98
|
+
# sentinel so the two agree:
|
|
99
|
+
# AILK_SITE_ID=wksp_00000000-0000-7000-8000-000000000001
|
|
100
|
+
#
|
|
101
|
+
# Leaving them disagreeing is why a correctly pinned owner can still open the
|
|
102
|
+
# review dashboard and see nothing: the rows exist, but under a different
|
|
103
|
+
# scope key than the one their session resolves.
|
|
104
|
+
#
|
|
63
105
|
# Belt-and-suspenders: the owner-pin denies any non-operator account at
|
|
64
106
|
# tenant resolution regardless, but for a single-tenant deployment you should
|
|
65
107
|
# also disable open sign-up / configure an OAuth allowlist on your identity
|
|
@@ -98,6 +140,45 @@ CONTENT_BACKEND=mdx
|
|
|
98
140
|
# default.
|
|
99
141
|
# RESEND_AUDIENCE_ID=
|
|
100
142
|
#
|
|
143
|
+
# Request-and-confirm (#5970) — the callback request a site owner confirms by
|
|
144
|
+
# an emailed link, which mints a Stripe Payment Link for the customer to pay
|
|
145
|
+
# on. Off by default: with the flag unset the callback route behaves exactly as
|
|
146
|
+
# it always has.
|
|
147
|
+
#
|
|
148
|
+
# Set to "true" to turn it on. Anything else (including absent) is off, and TO,
|
|
149
|
+
# FROM and AILK_PUBLIC_API_URL must ALSO resolve or the path stays off — a flag
|
|
150
|
+
# with no recipient would write a credential nobody is sent.
|
|
151
|
+
#
|
|
152
|
+
# SINGLE-TENANT ONLY. On a build carrying the multi-tenant module this flag is
|
|
153
|
+
# ignored and the callback route behaves exactly as it does with the feature
|
|
154
|
+
# off. Every value here is process-wide, as is STRIPE_SECRET_KEY, so on a
|
|
155
|
+
# multi-tenant deployment one tenant's customer would pay into the
|
|
156
|
+
# deployment's own Stripe account. Lighting it up there means resolving these
|
|
157
|
+
# per site, which is a separate piece of work.
|
|
158
|
+
# AILK_REQUEST_CONFIRM_ENABLED=
|
|
159
|
+
#
|
|
160
|
+
# Where the confirm link is sent — the site owner's own address. Optional:
|
|
161
|
+
# falls back to AILK_LEAD_NOTIFICATION_TO when unset. This message SUPERSEDES
|
|
162
|
+
# the generic lead notification for a callback, so the owner still receives
|
|
163
|
+
# exactly one email; it just carries more (the request's details, plus the
|
|
164
|
+
# link).
|
|
165
|
+
# AILK_REQUEST_CONFIRM_TO=
|
|
166
|
+
#
|
|
167
|
+
# The verified sender for both the owner's confirm email and the customer's
|
|
168
|
+
# payment-link email. Optional — falls back to AILK_LEAD_NOTIFICATION_FROM.
|
|
169
|
+
# AILK_REQUEST_CONFIRM_FROM=
|
|
170
|
+
#
|
|
171
|
+
# The confirm form's default currency, lowercase ISO-4217. Optional; defaults
|
|
172
|
+
# to usd.
|
|
173
|
+
# AILK_REQUEST_CONFIRM_CURRENCY=
|
|
174
|
+
#
|
|
175
|
+
# The most the confirm form will price a job at, in MINOR units (cents).
|
|
176
|
+
# Optional; defaults to 1000000 — ten thousand dollars at two decimal places.
|
|
177
|
+
# High enough not to obstruct a real job, low enough that a typo with three
|
|
178
|
+
# extra zeroes is refused rather than charged. A value that does not parse as a
|
|
179
|
+
# positive integer falls back to the default rather than becoming unbounded.
|
|
180
|
+
# AILK_REQUEST_CONFIRM_MAX_MINOR=
|
|
181
|
+
#
|
|
101
182
|
# The public base URL this API is reachable at, e.g. https://api.example.com
|
|
102
183
|
# (no trailing slash). This is the API's OWN origin — distinct from
|
|
103
184
|
# FRONTEND_URL (the site the browser loads) and from `_site.mdx`'s `baseUrl`
|
|
@@ -112,6 +193,11 @@ CONTENT_BACKEND=mdx
|
|
|
112
193
|
# 2. The OpenAPI `servers` block (#5306). Unset degrades to a single
|
|
113
194
|
# document-relative server (`/`), which an agent resolves against the
|
|
114
195
|
# origin it fetched the spec from — correct, just less explicit.
|
|
196
|
+
# 3. The request-and-confirm link (#5970):
|
|
197
|
+
# `${AILK_PUBLIC_API_URL}/v1/requests/:id/confirm?token=…`. The confirm
|
|
198
|
+
# route is on this API, so this is the right base and no second
|
|
199
|
+
# base-URL variable exists. Unset means the confirm email is skipped
|
|
200
|
+
# (logged, with the row still written and the 201 unchanged).
|
|
115
201
|
# AILK_PUBLIC_API_URL=
|
|
116
202
|
#
|
|
117
203
|
# The apps/api origin @working-theory/api-client calls from
|
|
@@ -288,12 +374,16 @@ CONTENT_BACKEND=mdx
|
|
|
288
374
|
# booking page. Full notes in apps/api/.env.example.
|
|
289
375
|
# CAL_API_KEY=cal_live_xxx
|
|
290
376
|
# CAL_API_BASE_URL=https://api.cal.com
|
|
377
|
+
# HMAC-SHA256 key POST /v1/webhooks/calcom verifies the x-cal-signature-256
|
|
378
|
+
# header against (#6085). Unset makes the receiver answer 503 and accept
|
|
379
|
+
# nothing — the same fail-closed posture an unset STRIPE_WEBHOOK_SECRET has.
|
|
380
|
+
# CAL_WEBHOOK_SECRET=
|
|
291
381
|
# SCHEDULING_PUBLIC_BASE_URL=https://cal.com
|
|
292
382
|
# SCHEDULING_PROVIDER=cal
|
|
293
383
|
#
|
|
294
|
-
# Which event the /
|
|
384
|
+
# Which event the /meet page books, as "<owner>/<event-slug>" (the path of
|
|
295
385
|
# the provider's own public booking page). Read server-side by apps/web; unset
|
|
296
|
-
# means the /
|
|
386
|
+
# means the /meet route 404s, exactly as if the scheduling module were not
|
|
297
387
|
# installed. Deliberately NOT a NEXT_PUBLIC_ variable — the whole scheduling
|
|
298
388
|
# config surface is server-read.
|
|
299
389
|
# SCHEDULING_CAL_LINK=owner/event-slug
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
ci:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v4
|
|
11
|
+
|
|
12
|
+
- uses: pnpm/action-setup@v4
|
|
13
|
+
|
|
14
|
+
# A fresh scaffold ships no pnpm-lock.yaml — it is generated by the
|
|
15
|
+
# customer's own first `pnpm install`. actions/setup-node's built-in
|
|
16
|
+
# pnpm cache globs for cache-dependency-path and errors the step
|
|
17
|
+
# outright when nothing matches, so a PR opened before that first
|
|
18
|
+
# install would fail here before `pnpm install` below even runs. This
|
|
19
|
+
# placeholder only stands in for the glob; `pnpm install` still
|
|
20
|
+
# generates (or refreshes) the real lockfile every run.
|
|
21
|
+
- run: test -f pnpm-lock.yaml || touch pnpm-lock.yaml
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: 20
|
|
26
|
+
cache: pnpm
|
|
27
|
+
cache-dependency-path: pnpm-lock.yaml
|
|
28
|
+
|
|
29
|
+
# Not --frozen-lockfile: the scaffold ships no pnpm-lock.yaml (it is
|
|
30
|
+
# generated fresh by the customer's own first `pnpm install`, and the
|
|
31
|
+
# placeholder step above is a cache-key stand-in, not a real lockfile),
|
|
32
|
+
# so a --frozen install would fail outright on any PR opened before a
|
|
33
|
+
# real lockfile has been committed.
|
|
34
|
+
- run: pnpm install
|
|
35
|
+
|
|
36
|
+
# Prisma's generated client (database/generated/) is a build artifact,
|
|
37
|
+
# not part of the scaffold — type-check/build/test all resolve
|
|
38
|
+
# `@working-theory/database`'s generated types, and `prisma generate` needs
|
|
39
|
+
# no DATABASE_URL (it reads only the schema file, no live DB).
|
|
40
|
+
- run: pnpm db:generate
|
|
41
|
+
|
|
42
|
+
- run: pnpm type-check
|
|
43
|
+
|
|
44
|
+
- run: pnpm lint
|
|
45
|
+
|
|
46
|
+
- run: pnpm test
|
|
47
|
+
|
|
48
|
+
- run: pnpm build
|
package/templates/README.md
CHANGED
|
@@ -103,7 +103,9 @@ If you need to override a section component, swap its registration in the sectio
|
|
|
103
103
|
|
|
104
104
|
## License & contributing
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
This is your code — `{{PROJECT_NAME}}`, owned by {{COMPANY_NAME}} ({{COMPANY_DOMAIN}}). The root `package.json`'s `license` field ships set to `UNLICENSED` as a neutral placeholder; it's yours to change to whatever license suits your project (or to remove entirely if the repo is private).
|
|
107
|
+
|
|
108
|
+
The `LICENSE` files under `apps/*/` and `database/` are the exception — they stay **Apache 2.0** because those directories are snapshots of `@working-theory/*` packages' own source, not code you authored.
|
|
107
109
|
|
|
108
110
|
The AI Launch Kit framework upstream is **Apache 2.0** — see <https://github.com/working-theory-labs/ai-launch-kit/blob/main/LICENSE>. Contributions are welcome at the upstream repo; start with the [contributing guide](https://github.com/working-theory-labs/ai-launch-kit/blob/main/CONTRIBUTING.md).
|
|
109
111
|
|
package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "fallback-1789916253842-b52659e9",
|
|
3
|
+
"siteId": "wksp_00000000-0000-7000-8000-000000000001",
|
|
4
|
+
"source": "flow:get-a-quote",
|
|
5
|
+
"email": "abandoner@example.com",
|
|
6
|
+
"payload": {
|
|
7
|
+
"email": "abandoner@example.com",
|
|
8
|
+
"flowSlug": "get-a-quote",
|
|
9
|
+
"locale": "en"
|
|
10
|
+
},
|
|
11
|
+
"createdAt": "2026-09-20T14:57:33.840Z"
|
|
12
|
+
}
|
package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "fallback-1789916253845-6b266f8c",
|
|
3
|
+
"siteId": "default",
|
|
4
|
+
"source": "flow:get-a-quote",
|
|
5
|
+
"email": "abandoner@example.com",
|
|
6
|
+
"payload": {
|
|
7
|
+
"email": "abandoner@example.com",
|
|
8
|
+
"flowSlug": "get-a-quote",
|
|
9
|
+
"locale": "en"
|
|
10
|
+
},
|
|
11
|
+
"createdAt": "2026-09-20T14:57:33.844Z"
|
|
12
|
+
}
|