create-ailk 0.5.0 → 0.6.1
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 +336 -27
- package/component-catalog.md +25 -12
- package/dist/cli.js +54 -5
- package/dist/copy.d.ts +14 -0
- package/dist/copy.js +38 -1
- 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 +20 -1
- package/dist/lib/extract-module-bundle.js +64 -5
- package/dist/lib/import-graph.d.ts +29 -0
- package/dist/lib/import-graph.js +140 -0
- package/dist/lib/module-license-gate.d.ts +6 -1
- package/dist/lib/module-license-gate.js +6 -1
- package/dist/lib/pro-callout.js +1 -1
- package/dist/module-architecture.d.ts +1 -0
- package/dist/module-architecture.js +253 -127
- package/dist/modules/commerce/0.6.0.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.0.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.0.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.0.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.0.tar.gz +0 -0
- package/dist/modules/workspace/0.6.0.tar.gz +0 -0
- package/dist/programmatic.js +14 -10
- package/dist/surfaces.js +105 -7
- package/dist/template-manifest.d.ts +33 -0
- package/dist/template-manifest.js +99 -16
- package/dist/template-names.d.ts +1 -1
- package/dist/template-names.js +1 -0
- package/package.json +3 -2
- package/site-templates/marketing-site/DESIGN.md +148 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +22 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +9 -2
- package/site-templates/marketing-site/ailk-template.json +1 -1
- package/site-templates/marketing-site-free/DESIGN.md +148 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +2 -2
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +1 -0
- package/site-templates/minimalism-site/DESIGN.md +148 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +10 -2
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +47 -35
- package/site-templates/minimalism-site/ailk-template.json +2 -1
- package/site-templates/minimalism-site/assets/wordmark-placeholder.svg +28 -0
- package/site-templates/minimalism-site/content/en/HomePage/home.mdx +49 -19
- package/site-templates/saas-product/DESIGN.md +148 -0
- package/site-templates/simple-service/DESIGN.md +148 -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/.env.example +72 -7
- package/templates/CLAUDE.md +2 -3
- package/templates/DESIGN.md +155 -0
- package/templates/README.md +42 -8
- 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 +26 -2
- package/templates/apps/api/jest.config.cjs +3 -0
- package/templates/apps/api/package.json +1 -0
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +407 -0
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +83 -7
- 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 +2 -0
- 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 +238 -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 +182 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +42 -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/index.ts +100 -13
- 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 +439 -49
- 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-routing.test.ts +160 -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 +70 -31
- 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 +13 -14
- package/templates/apps/api/src/services/lead-routing.ts +161 -2
- package/templates/apps/api/src/services/leads-inbox.ts +23 -2
- package/templates/apps/api/src/services/listing-config.ts +27 -9
- 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 +57 -24
- 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 +10 -7
- 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/purchase.test.ts +300 -123
- package/templates/apps/mcp/jest.config.cjs +13 -0
- package/templates/apps/mcp/package.json +2 -0
- 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 +59 -35
- package/templates/apps/mcp/src/tools/audit.ts +26 -2
- 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 +6 -4
- 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 +71 -5
- package/templates/apps/web/CLAUDE.md +44 -0
- package/templates/apps/web/PRODUCT.md +86 -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 +63 -8
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +18 -1
- package/templates/apps/web/app/[locale]/cancellation/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/layout.tsx +133 -87
- 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/jest.config.cjs +8 -4
- 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__/site-theme.test.ts +135 -20
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +18 -1
- 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/site-brand.tsx +4 -8
- package/templates/apps/web/lib/telemetry-scrub.ts +5 -1
- package/templates/apps/web/messages/en.json +187 -0
- package/templates/apps/web/middleware.ts +1 -1
- package/templates/apps/web/package.json +2 -1
- package/templates/apps/web/src/lib/commerce-claim.ts +33 -0
- package/templates/apps/web/src/lib/commerce-sections.ts +93 -0
- package/templates/content/_site.mdx +18 -3
- package/templates/content/en/CancellationPolicyPage/cancellation.mdx +108 -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__/tenancy.test.ts +141 -0
- package/templates/database/config/schema.prisma +79 -2
- package/templates/database/content/schema.prisma +87 -11
- 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 +3 -2
- package/templates/database/tenancy.ts +86 -1
- package/templates/database/tsconfig.json +1 -0
- package/versions.json +34 -34
- 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/templates/apps/web/public/logo-dark.svg +0 -21
- package/templates/apps/web/public/logo-light.svg +0 -21
- /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/dist/surfaces.js
CHANGED
|
@@ -66,12 +66,32 @@ export const CORE_ROUTE_DIRS = [
|
|
|
66
66
|
// copies all of apps/web verbatim, no `--surfaces` gating on this route),
|
|
67
67
|
// so joining CORE_ROUTE_DIRS only makes the REGISTRY match what already
|
|
68
68
|
// ships — it does not change what a fresh scaffold carries.
|
|
69
|
-
|
|
69
|
+
//
|
|
70
|
+
// #5963 moved `sign-in` INTO the `(auth)` route group and added four
|
|
71
|
+
// siblings, so the group is what is listed now. It stays CORE rather than
|
|
72
|
+
// taking its own surface id the way `(authed)` did: `(authed)` is gated
|
|
73
|
+
// authed-app surface reported under its own identity, whereas these five
|
|
74
|
+
// are the public auth entry points that have always shipped ungated —
|
|
75
|
+
// registering the group keeps `sign-in`'s existing `core` identity exactly.
|
|
76
|
+
`${ROUTE_ROOT}/(auth)`,
|
|
70
77
|
// #5469 D2 — always copied: it is what serves the Free template's
|
|
71
78
|
// /how-it-works, /features and /blog pages, and it is inert for every slug
|
|
72
79
|
// that has no LandingPage MDX (notFound), so a scaffold carrying it and no
|
|
73
80
|
// content is byte-for-byte a scaffold with three more 404s, nothing else.
|
|
74
81
|
`${ROUTE_ROOT}/[slug]`,
|
|
82
|
+
// #6084 D12 (the operator's shape-2 disposition) — the checkout return
|
|
83
|
+
// pair. The launchers pointing at them (`apps/mcp/src/tools/purchase.ts`,
|
|
84
|
+
// `apps/web/.../dev/purchase/purchase.actions.ts`) are ALREADY
|
|
85
|
+
// unconditional base-tree code under D-64, so gating the return pages
|
|
86
|
+
// behind a scaffold-time surface would leave a licence-added commerce
|
|
87
|
+
// site with a working checkout and a 404 return page — the exact defect
|
|
88
|
+
// this issue exists to close. `CORE_ROUTE_DIRS` is the right home for the
|
|
89
|
+
// same reason `[slug]` immediately above is: inert (a request-time
|
|
90
|
+
// `notFound()`, `src/lib/commerce-claim.ts`) for every scaffold that never
|
|
91
|
+
// buys the `commerce` claim, so carrying it costs nothing beyond two more
|
|
92
|
+
// 404s. Neither `GATEABLE_SURFACES` nor `MODULE_SURFACES.commerce` gains
|
|
93
|
+
// an entry — the claim decides whether the pages serve, not the scaffold.
|
|
94
|
+
`${ROUTE_ROOT}/purchase`,
|
|
75
95
|
];
|
|
76
96
|
/**
|
|
77
97
|
* Directory names skipped by `listTemplateRouteDirs`'s walker even though they
|
|
@@ -482,6 +502,11 @@ export const ROUTE_SINCE = {
|
|
|
482
502
|
// question set is the SITE's content. A scaffolded site adds its own route
|
|
483
503
|
// beside this file and passes its own config.
|
|
484
504
|
"projects/apply": "0.18.0",
|
|
505
|
+
// #6084 — two genuinely new route directories, attaching at today's
|
|
506
|
+
// fixed-group version, the same "attach at today's version" rule #5977,
|
|
507
|
+
// #5678, #5479, #5371 and #5048 applied.
|
|
508
|
+
"purchase/success": "0.24.0",
|
|
509
|
+
"purchase/cancel": "0.24.0",
|
|
485
510
|
resources: "0.0.0",
|
|
486
511
|
"resources/[slug]": "0.0.0",
|
|
487
512
|
services: "0.0.0",
|
|
@@ -524,10 +549,36 @@ export const ROUTE_SINCE = {
|
|
|
524
549
|
"(authed)/admin": "0.22.1",
|
|
525
550
|
"(authed)/admin/site": "0.22.1",
|
|
526
551
|
"(authed)/admin/team": "0.22.1",
|
|
552
|
+
// #5977 — the Pro content host's editor routes (spec 5872 FR1/FR2), added
|
|
553
|
+
// to apps/web by #5957. Genuinely new route directories, so they attach at
|
|
554
|
+
// today's fixed-group version, the same "attach at today's version" rule
|
|
555
|
+
// #5678, #5479, #5371 and #5048 applied.
|
|
556
|
+
//
|
|
557
|
+
// They are registered here but do NOT ship in a scaffold: the pair is
|
|
558
|
+
// excluded from the template snapshot by `EXCLUDE_TEMPLATE_DIRS` in
|
|
559
|
+
// `scripts/build-templates.mjs` (see that entry for the two spec-5872-D11
|
|
560
|
+
// constraints behind the choice). The entries are kept because ROUTE_SINCE
|
|
561
|
+
// is the route registry for `apps/web`, not a mirror of what the snapshot
|
|
562
|
+
// happens to carry — sync-routes' AC-5 coverage test knows the exclusion
|
|
563
|
+
// and treats the absence as justified.
|
|
564
|
+
"(authed)/edit": "0.24.0",
|
|
565
|
+
"(authed)/edit/[type]/[slug]": "0.24.0",
|
|
527
566
|
"(authed)/waitlist": "0.18.0",
|
|
528
567
|
"(authed)/waitlist/[experimentId]": "0.18.0",
|
|
529
568
|
"(authed)/waitlist/[experimentId]/signups/[leadId]": "0.18.0",
|
|
530
|
-
|
|
569
|
+
// #5963 — the `(auth)` route group. `sign-in` keeps its ORIGINAL version
|
|
570
|
+
// under its new key: ROUTE_SINCE tracks when a route was introduced, not
|
|
571
|
+
// when it was moved, exactly as the #5637 workspace -> admin rename above
|
|
572
|
+
// left `(authed)/admin` at 0.22.1. The group's own layout and the four new
|
|
573
|
+
// pages are genuinely new route directories, so they attach at today's
|
|
574
|
+
// fixed-group version — the same rule #5977, #5678, #5479, #5371 and #5048
|
|
575
|
+
// applied.
|
|
576
|
+
"(auth)": "0.24.0",
|
|
577
|
+
"(auth)/sign-in": "0.18.0",
|
|
578
|
+
"(auth)/sign-up": "0.24.0",
|
|
579
|
+
"(auth)/forgot-password": "0.24.0",
|
|
580
|
+
"(auth)/reset-password": "0.24.0",
|
|
581
|
+
"(auth)/verify-email": "0.24.0",
|
|
531
582
|
// #5469 D2 — the generic `[slug]` content route. A genuinely new route
|
|
532
583
|
// directory, so it attaches at today's fixed-group version, the same rule
|
|
533
584
|
// #5479, #5371 and #5048 applied.
|
|
@@ -566,7 +617,17 @@ export function surfaceForRouteDir(routeDir) {
|
|
|
566
617
|
* that the waitlist dashboard also uses, rather than duplicating them.
|
|
567
618
|
*/
|
|
568
619
|
export const ROUTE_DEPENDENCIES = {
|
|
569
|
-
|
|
620
|
+
// #5963 — the (auth) group's layout renders the brand mark through
|
|
621
|
+
// `siteLogo()`, and the LOCALE layout above it branches on
|
|
622
|
+
// `isAuthPath()` to drop the marketing chrome for these five paths: without
|
|
623
|
+
// `auth-routes.ts` a synced group renders inside the Nav + Footer it exists
|
|
624
|
+
// to replace. The sign-in page no longer imports `site-brand` — the mark is
|
|
625
|
+
// the shell's since #5963 — so its own list is just the env reader.
|
|
626
|
+
"(auth)": ["apps/web/lib/site-brand.tsx", "apps/web/lib/auth-routes.ts"],
|
|
627
|
+
"(auth)/sign-in": ["apps/web/lib/auth-env.ts"],
|
|
628
|
+
"(auth)/sign-up": ["apps/web/lib/auth-env.ts"],
|
|
629
|
+
"(auth)/forgot-password": ["apps/web/lib/auth-env.ts"],
|
|
630
|
+
"(auth)/reset-password": ["apps/web/lib/auth-env.ts"],
|
|
570
631
|
"(authed)": ["apps/web/auth.ts", "apps/web/lib/auth-env.ts"],
|
|
571
632
|
"(authed)/account": [
|
|
572
633
|
"apps/web/lib/account-config.ts",
|
|
@@ -574,11 +635,37 @@ export const ROUTE_DEPENDENCIES = {
|
|
|
574
635
|
`${ROUTE_ROOT}/(authed)/waitlist/components/ForbiddenState.tsx`,
|
|
575
636
|
`${ROUTE_ROOT}/(authed)/waitlist/format.ts`,
|
|
576
637
|
],
|
|
577
|
-
"(authed)/admin": [
|
|
638
|
+
"(authed)/admin": [
|
|
639
|
+
"apps/web/lib/server-api.ts",
|
|
640
|
+
`${ROUTE_ROOT}/(authed)/waitlist/components/ForbiddenState.tsx`,
|
|
641
|
+
],
|
|
578
642
|
"(authed)/leads": ["apps/web/lib/server-api.ts"],
|
|
579
|
-
|
|
580
|
-
|
|
643
|
+
// #5977 — the editor routes' own imports, read from their sources: both
|
|
644
|
+
// pages call `forwardedCookieInit`/`unwrapApiResult` from `lib/server-api`
|
|
645
|
+
// and render the shared `ForbiddenState` on the tenant guard's 403, the
|
|
646
|
+
// same pair `(authed)/admin` already declares. Declared for registry
|
|
647
|
+
// completeness; inert in practice while the routes are excluded from the
|
|
648
|
+
// snapshot (see ROUTE_SINCE above).
|
|
649
|
+
"(authed)/edit": [
|
|
650
|
+
"apps/web/lib/server-api.ts",
|
|
651
|
+
`${ROUTE_ROOT}/(authed)/waitlist/components/ForbiddenState.tsx`,
|
|
652
|
+
],
|
|
653
|
+
"(authed)/edit/[type]/[slug]": [
|
|
654
|
+
"apps/web/lib/server-api.ts",
|
|
655
|
+
`${ROUTE_ROOT}/(authed)/waitlist/components/ForbiddenState.tsx`,
|
|
656
|
+
],
|
|
657
|
+
"(authed)/admin/site": [
|
|
658
|
+
"apps/web/lib/server-api.ts",
|
|
659
|
+
`${ROUTE_ROOT}/(authed)/waitlist/components/ForbiddenState.tsx`,
|
|
660
|
+
],
|
|
661
|
+
"(authed)/admin/team": [
|
|
662
|
+
"apps/web/lib/server-api.ts",
|
|
663
|
+
`${ROUTE_ROOT}/(authed)/waitlist/components/ForbiddenState.tsx`,
|
|
664
|
+
],
|
|
581
665
|
"(authed)/waitlist": ["apps/web/lib/server-api.ts"],
|
|
666
|
+
// #6183 S9b D5 — both /meet pages call the shared enabled-slug read.
|
|
667
|
+
meet: ["apps/web/lib/meeting-slugs.ts"],
|
|
668
|
+
"meet/[slug]": ["apps/web/lib/meeting-slugs.ts"],
|
|
582
669
|
};
|
|
583
670
|
/**
|
|
584
671
|
* i18n message namespaces (dot-path into `apps/web/messages/<locale>.json`) a
|
|
@@ -590,10 +677,21 @@ export const ROUTE_DEPENDENCIES = {
|
|
|
590
677
|
* to the site owner, same as any other reported gap.
|
|
591
678
|
*/
|
|
592
679
|
export const ROUTE_MESSAGE_NAMESPACES = {
|
|
593
|
-
|
|
680
|
+
// #5963 — `signIn` is untouched and still the sign-in page's namespace; the
|
|
681
|
+
// group's layout and the four new pages read the new `auth` namespace.
|
|
682
|
+
"(auth)": ["auth"],
|
|
683
|
+
"(auth)/sign-in": ["signIn"],
|
|
684
|
+
"(auth)/sign-up": ["auth"],
|
|
685
|
+
"(auth)/forgot-password": ["auth"],
|
|
686
|
+
"(auth)/reset-password": ["auth"],
|
|
687
|
+
"(auth)/verify-email": ["auth"],
|
|
594
688
|
"(authed)/account": ["account"],
|
|
595
689
|
"(authed)/admin": ["admin"],
|
|
596
690
|
"(authed)/leads": ["leadsInbox"],
|
|
691
|
+
// #5977 — every string on both editor routes comes from the `edit`
|
|
692
|
+
// namespace (spec 5872 D10).
|
|
693
|
+
"(authed)/edit": ["edit"],
|
|
694
|
+
"(authed)/edit/[type]/[slug]": ["edit"],
|
|
597
695
|
"(authed)/admin/site": ["admin"],
|
|
598
696
|
"(authed)/admin/team": ["admin"],
|
|
599
697
|
"(authed)/waitlist": ["waitlistDashboard.gate"],
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site-template registry, and the roster merge that composes a template with
|
|
3
|
+
* the modules it takes (spec 5478, unit A of the site-templates mechanism;
|
|
4
|
+
* design record docs/specs/5462-site-templates-module-bundles-spec.md).
|
|
5
|
+
*
|
|
6
|
+
* A site template is DATA AND CONTENT, NOT CODE: a page roster, seed content
|
|
7
|
+
* and config — never a `page.tsx` (parent § D16). This file declares what a
|
|
8
|
+
* template IS. It declares no delivery channel, reads no licence, and touches
|
|
9
|
+
* no disk: the `--template` flag, the bundle fetch and the landing order are
|
|
10
|
+
* #5481's, and `GET /v1/templates/:name/:version` is #5480's.
|
|
11
|
+
*
|
|
12
|
+
* A CODE registry, not per-template JSON (parent § D2): in TypeScript,
|
|
13
|
+
* `requires` is checked against `RECOGNIZED_MODULES` at compile time, and this
|
|
14
|
+
* package already twice records that a fixed template FILE is the drift a
|
|
15
|
+
* registry removes.
|
|
16
|
+
*/
|
|
17
|
+
import type { CategorySlug } from "@working-theory/schema/categories";
|
|
1
18
|
import { type PageRosterRow } from "./module-architecture.js";
|
|
2
19
|
import type { ModuleName } from "./parse-args.js";
|
|
3
20
|
import type { TemplateLayout } from "./site-chrome.js";
|
|
@@ -24,6 +41,22 @@ export interface TemplateManifest {
|
|
|
24
41
|
* unrecognized name fails type-check rather than a runtime validation.
|
|
25
42
|
*/
|
|
26
43
|
requires: readonly ModuleName[];
|
|
44
|
+
/**
|
|
45
|
+
* The business categories this template is FOR — one or more LEAF slugs from
|
|
46
|
+
* the site-category registry (`@working-theory/schema/categories`, #5830),
|
|
47
|
+
* shared with content's frontmatter `categories`. Required, and typed against
|
|
48
|
+
* `CategorySlug`, for the same reason `requires` is typed against
|
|
49
|
+
* `ModuleName`: an unrecognized name fails type-check rather than a runtime
|
|
50
|
+
* validation, and every template must be findable under at least one
|
|
51
|
+
* category on the hub's "Browse by business" band.
|
|
52
|
+
*
|
|
53
|
+
* LEAVES ONLY. A group slug (`professional-services`, `home-and-trades`, …)
|
|
54
|
+
* is never a valid value: the group is DERIVED through `groupOf`, so a
|
|
55
|
+
* template that fits "professional services" names `accounting` and `legal`.
|
|
56
|
+
* Where a leaf is genuinely missing, the operator adds a leaf to the
|
|
57
|
+
* registry — never a group here.
|
|
58
|
+
*/
|
|
59
|
+
categories: readonly CategorySlug[];
|
|
27
60
|
/**
|
|
28
61
|
* The template this one EXTENDS — its lineage, never its level (#5618 D2).
|
|
29
62
|
* A single parent, not a list: "later layers win file by file" needs a
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Site-template registry, and the roster merge that composes a template with
|
|
3
|
-
* the modules it takes (spec 5478, unit A of the site-templates mechanism;
|
|
4
|
-
* design record docs/specs/5462-site-templates-module-bundles-spec.md).
|
|
5
|
-
*
|
|
6
|
-
* A site template is DATA AND CONTENT, NOT CODE: a page roster, seed content
|
|
7
|
-
* and config — never a `page.tsx` (parent § D16). This file declares what a
|
|
8
|
-
* template IS. It declares no delivery channel, reads no licence, and touches
|
|
9
|
-
* no disk: the `--template` flag, the bundle fetch and the landing order are
|
|
10
|
-
* #5481's, and `GET /v1/templates/:name/:version` is #5480's.
|
|
11
|
-
*
|
|
12
|
-
* A CODE registry, not per-template JSON (parent § D2): in TypeScript,
|
|
13
|
-
* `requires` is checked against `RECOGNIZED_MODULES` at compile time, and this
|
|
14
|
-
* package already twice records that a fixed template FILE is the drift a
|
|
15
|
-
* registry removes.
|
|
16
|
-
*/
|
|
17
1
|
import { classifyModules } from "./lib/module-tier.js";
|
|
18
2
|
import { MODULE_SLICES, normalizeModules, } from "./module-architecture.js";
|
|
19
3
|
/**
|
|
@@ -125,6 +109,60 @@ const MINIMALISM_ROSTER = [
|
|
|
125
109
|
{ route: "/privacy", content: ["content/en/PrivacyPage/privacy.mdx"] },
|
|
126
110
|
{ route: "/terms", content: ["content/en/TermsPage/terms.mdx"] },
|
|
127
111
|
];
|
|
112
|
+
/**
|
|
113
|
+
* `simple-service`'s own rows (#6087) — the T1 lawn-care roster of Epic #5778.
|
|
114
|
+
* The second declared template that does not reuse `TEMPLATE_BASE_ROSTER`: a
|
|
115
|
+
* lawn-care site sells three named services from `/services`, not from a
|
|
116
|
+
* pricing table, so `/how-it-works`, `/features` and `/pricing` are absent —
|
|
117
|
+
* `/pricing`'s `_base` seed still lands on disk, it simply has no rostered
|
|
118
|
+
* route, exactly as it does for `minimalism-site`.
|
|
119
|
+
*
|
|
120
|
+
* `/meet`, `/meet/[slug]`, `/meet/confirmed` and `/appointments` are absent
|
|
121
|
+
* here on purpose: they are the `scheduling` module's own
|
|
122
|
+
* `pageContributions`, merged in by `mergeRoster`. Declaring one here would
|
|
123
|
+
* make that merge refuse the template outright (§ D8's both-claimants
|
|
124
|
+
* refusal).
|
|
125
|
+
*
|
|
126
|
+
* `/purchase/success` and `/purchase/cancel` ARE declared here, and that is a
|
|
127
|
+
* documented divergence from spec § D3. The spec was written at a pin where
|
|
128
|
+
* #6084 was expected to add the pair to `MODULE_SLICES.commerce`'s
|
|
129
|
+
* `pageContributions`. It did not: the operator's shape-2 disposition
|
|
130
|
+
* (#6084 D12) ships the return pair BASE TREE — `CORE_ROUTE_DIRS` carries
|
|
131
|
+
* `[locale]/purchase`, and neither `GATEABLE_SURFACES` nor
|
|
132
|
+
* `MODULE_SURFACES.commerce` gained an entry — so the `commerce` slice
|
|
133
|
+
* contributes no rows at all and nothing else claims these two routes. The
|
|
134
|
+
* issue's AC-1 requires the merged roster to carry them; with no module
|
|
135
|
+
* claimant, the template's own roster is the only place that can declare
|
|
136
|
+
* them, and doing so trips no collision.
|
|
137
|
+
*
|
|
138
|
+
* `/account` carries no `content`: it is a code route (the `(authed)` group),
|
|
139
|
+
* like `/sign-in` on the base roster and like the API-backed rows the
|
|
140
|
+
* scheduling module contributes. `/services/[slug]` likewise declares none —
|
|
141
|
+
* its seed is a whole DIRECTORY (`content/en/Service`), and a roster row's
|
|
142
|
+
* `content` names files the manifest generator reads frontmatter from.
|
|
143
|
+
*/
|
|
144
|
+
const SIMPLE_SERVICE_ROSTER = [
|
|
145
|
+
{ route: "/", content: ["content/en/HomePage/home.mdx"] },
|
|
146
|
+
{ route: "/services", content: ["content/en/ServicesList/services.mdx"] },
|
|
147
|
+
{ route: "/services/[slug]" },
|
|
148
|
+
{ route: "/about", content: ["content/en/AboutPage/about.mdx"] },
|
|
149
|
+
{ route: "/contact", content: ["content/en/ContactPage/contact.mdx"] },
|
|
150
|
+
{ route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
|
|
151
|
+
{ route: "/returns", content: ["content/en/ReturnsPolicyPage/returns.mdx"] },
|
|
152
|
+
{
|
|
153
|
+
route: "/cancellation",
|
|
154
|
+
content: ["content/en/CancellationPolicyPage/cancellation.mdx"],
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
route: "/shipping",
|
|
158
|
+
content: ["content/en/ShippingPolicyPage/shipping.mdx"],
|
|
159
|
+
},
|
|
160
|
+
{ route: "/privacy", content: ["content/en/PrivacyPage/privacy.mdx"] },
|
|
161
|
+
{ route: "/terms", content: ["content/en/TermsPage/terms.mdx"] },
|
|
162
|
+
{ route: "/account" },
|
|
163
|
+
{ route: "/purchase/success" },
|
|
164
|
+
{ route: "/purchase/cancel" },
|
|
165
|
+
];
|
|
128
166
|
/**
|
|
129
167
|
* The three settled templates and their fixed `requires` lists — settled by
|
|
130
168
|
* Sam, 2026-09-14 (parent § D12). The plain name is the Pro one: it is the
|
|
@@ -156,6 +194,7 @@ export const TEMPLATE_MANIFESTS = Object.freeze({
|
|
|
156
194
|
"marketing-site-free": {
|
|
157
195
|
name: "marketing-site-free",
|
|
158
196
|
requires: ["marketing"],
|
|
197
|
+
categories: ["accounting", "legal", "technology"],
|
|
159
198
|
extends: BASE_LAYER_DIR,
|
|
160
199
|
roster: [...TEMPLATE_BASE_ROSTER, FREE_BLOG_TEASER_ROW],
|
|
161
200
|
},
|
|
@@ -167,6 +206,21 @@ export const TEMPLATE_MANIFESTS = Object.freeze({
|
|
|
167
206
|
"marketing-site": {
|
|
168
207
|
name: "marketing-site",
|
|
169
208
|
requires: ["marketing", "docs-blog", "scheduling", "signal-collectors"],
|
|
209
|
+
// The flagship is the general-purpose template: it carries the whole
|
|
210
|
+
// registry, so every group tile on the hub has at least one template.
|
|
211
|
+
categories: [
|
|
212
|
+
"accounting",
|
|
213
|
+
"legal",
|
|
214
|
+
"hvac",
|
|
215
|
+
"roofing",
|
|
216
|
+
"plumbing",
|
|
217
|
+
"electrical",
|
|
218
|
+
"landscaping",
|
|
219
|
+
"auto-repair",
|
|
220
|
+
"real-estate",
|
|
221
|
+
"technology",
|
|
222
|
+
"medical-specialty",
|
|
223
|
+
],
|
|
170
224
|
extends: BASE_LAYER_DIR,
|
|
171
225
|
roster: TEMPLATE_BASE_ROSTER,
|
|
172
226
|
},
|
|
@@ -188,6 +242,7 @@ export const TEMPLATE_MANIFESTS = Object.freeze({
|
|
|
188
242
|
"signal-collectors",
|
|
189
243
|
"multi-tenant",
|
|
190
244
|
],
|
|
245
|
+
categories: ["technology", "medical-specialty"],
|
|
191
246
|
extends: BASE_LAYER_DIR,
|
|
192
247
|
roster: TEMPLATE_BASE_ROSTER,
|
|
193
248
|
},
|
|
@@ -222,6 +277,7 @@ export const TEMPLATE_MANIFESTS = Object.freeze({
|
|
|
222
277
|
"minimalism-site": {
|
|
223
278
|
name: "minimalism-site",
|
|
224
279
|
requires: ["marketing", "scheduling", "signal-collectors"],
|
|
280
|
+
categories: ["real-estate", "technology", "legal"],
|
|
225
281
|
extends: BASE_LAYER_DIR,
|
|
226
282
|
roster: MINIMALISM_ROSTER,
|
|
227
283
|
layout: {
|
|
@@ -231,6 +287,33 @@ export const TEMPLATE_MANIFESTS = Object.freeze({
|
|
|
231
287
|
home: "deck",
|
|
232
288
|
},
|
|
233
289
|
},
|
|
290
|
+
/**
|
|
291
|
+
* The T1 lawn-care template (#6087, Epic #5778) — the first site shape
|
|
292
|
+
* that composes `scheduling` and `commerce`: three priced services, a
|
|
293
|
+
* booker, a checkout return pair and the three #5947 policy pages.
|
|
294
|
+
*
|
|
295
|
+
* `requires` lists `marketing` for the registry convention every other
|
|
296
|
+
* manifest keeps: it is free (`module-tier.ts`'s `FREE_MODULES`), so it
|
|
297
|
+
* cannot change `templateDelivery`'s verdict, and listing it keeps the
|
|
298
|
+
* template's own declaration — not `DEFAULT_MODULES` — the authority for
|
|
299
|
+
* what a bare `--template simple-service` run installs. The order is
|
|
300
|
+
* `RECOGNIZED_MODULES` order, which is also `normalizeModules`' output
|
|
301
|
+
* order, so the declared list and the merge order read the same.
|
|
302
|
+
*
|
|
303
|
+
* `scheduling` and `commerce` are both paid, so `templateDelivery`
|
|
304
|
+
* returns `"paid"` from either one alone.
|
|
305
|
+
*
|
|
306
|
+
* It declares NO `layout` block: the default marketing-site chrome is the
|
|
307
|
+
* one a lawn-care site wants, and the issue's STOP boundary excludes
|
|
308
|
+
* layout knobs the spec does not name.
|
|
309
|
+
*/
|
|
310
|
+
"simple-service": {
|
|
311
|
+
name: "simple-service",
|
|
312
|
+
requires: ["marketing", "scheduling", "commerce"],
|
|
313
|
+
categories: ["landscaping"],
|
|
314
|
+
extends: BASE_LAYER_DIR,
|
|
315
|
+
roster: SIMPLE_SERVICE_ROSTER,
|
|
316
|
+
},
|
|
234
317
|
});
|
|
235
318
|
/** Look up a declared template. @throws TemplateError on an undeclared name. */
|
|
236
319
|
export function resolveTemplate(name) {
|
package/dist/template-names.d.ts
CHANGED
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
* is consumed as a plain array across the package.
|
|
38
38
|
*/
|
|
39
39
|
/** The declared site templates, in `TEMPLATE_MANIFESTS` declaration order. */
|
|
40
|
-
export declare const RECOGNIZED_TEMPLATES: readonly ["marketing-site-free", "marketing-site", "saas-product", "minimalism-site"];
|
|
40
|
+
export declare const RECOGNIZED_TEMPLATES: readonly ["marketing-site-free", "marketing-site", "saas-product", "minimalism-site", "simple-service"];
|
|
41
41
|
export type TemplateName = (typeof RECOGNIZED_TEMPLATES)[number];
|
package/dist/template-names.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ailk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Scaffolder for AI Launch Kit — `pnpm create ailk@latest <dir>` produces a starter repo consuming @working-theory/* from npm (per ADR 0007).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"tar": "^7.5.21"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@working-theory/
|
|
28
|
+
"@working-theory/schema": "0.26.0",
|
|
29
|
+
"@working-theory/templates": "0.26.0"
|
|
29
30
|
},
|
|
30
31
|
"repository": {
|
|
31
32
|
"type": "git",
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Marketing site (Pro) — marketing-site
|
|
3
|
+
description: The Pro flagship: the Standard marketing pages plus blog, docs, booking and signal-collector pages, on the base foundation.
|
|
4
|
+
colors:
|
|
5
|
+
bg: "#ffffff"
|
|
6
|
+
fg: "#000000"
|
|
7
|
+
surface: "#ffffff"
|
|
8
|
+
surface-secondary: "#ffffff"
|
|
9
|
+
border: "#000000"
|
|
10
|
+
text-muted: "#333333"
|
|
11
|
+
brand: "#000000"
|
|
12
|
+
fg-on-brand: "#ffffff"
|
|
13
|
+
accent: "#000000"
|
|
14
|
+
bg-dark: "#000000"
|
|
15
|
+
fg-dark: "#ffffff"
|
|
16
|
+
border-dark: "#ffffff"
|
|
17
|
+
brand-dark: "#ffffff"
|
|
18
|
+
typography:
|
|
19
|
+
display:
|
|
20
|
+
fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, sans-serif"
|
|
21
|
+
fontSize: "6rem"
|
|
22
|
+
fontWeight: 400
|
|
23
|
+
lineHeight: 1
|
|
24
|
+
letterSpacing: "-0.05em"
|
|
25
|
+
heading-section:
|
|
26
|
+
fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, sans-serif"
|
|
27
|
+
fontSize: "2.25rem"
|
|
28
|
+
fontWeight: 400
|
|
29
|
+
lineHeight: 1.25
|
|
30
|
+
letterSpacing: "-0.05em"
|
|
31
|
+
heading-item:
|
|
32
|
+
fontSize: "1.25rem"
|
|
33
|
+
fontWeight: 600
|
|
34
|
+
lineHeight: 1.375
|
|
35
|
+
body:
|
|
36
|
+
fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, sans-serif"
|
|
37
|
+
fontSize: "1.125rem"
|
|
38
|
+
fontWeight: 400
|
|
39
|
+
lineHeight: 1.5
|
|
40
|
+
eyebrow:
|
|
41
|
+
fontSize: "0.875rem"
|
|
42
|
+
fontWeight: 600
|
|
43
|
+
lineHeight: 1.4
|
|
44
|
+
letterSpacing: "0.05em"
|
|
45
|
+
rounded:
|
|
46
|
+
button: "0.25rem"
|
|
47
|
+
card: "0.75rem"
|
|
48
|
+
spacing:
|
|
49
|
+
section: "4rem"
|
|
50
|
+
card: "1.5rem"
|
|
51
|
+
grid: "1.5rem"
|
|
52
|
+
container: "1280px"
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
<!--
|
|
56
|
+
Source template: marketing-site
|
|
57
|
+
Version: create-ailk {{CREATE_AILK_VERSION}}
|
|
58
|
+
Extends: _base — installing this template replaces the base scaffold's
|
|
59
|
+
DESIGN.md with this file. Its tokens are the base foundation's, unchanged:
|
|
60
|
+
this template carries no theme of its own.
|
|
61
|
+
|
|
62
|
+
The tokens above describe what the site RENDERS today. Colours come from
|
|
63
|
+
content/_site.mdx (`theme.colors`); type, radius and spacing are platform
|
|
64
|
+
defaults a site cannot override yet — see "Where this is heading" below.
|
|
65
|
+
-->
|
|
66
|
+
|
|
67
|
+
# Marketing site (Pro)
|
|
68
|
+
|
|
69
|
+
## Overview
|
|
70
|
+
|
|
71
|
+
The Pro flagship template. It carries the same nine-beat home and marketing pages as Standard (Free), and adds the pages its four Pro modules bring: the blog, the docs, the booking pages under `/meet`, and the signal-collector surfaces. It runs on the base foundation unchanged.
|
|
72
|
+
|
|
73
|
+
## Colors
|
|
74
|
+
|
|
75
|
+
### Primary
|
|
76
|
+
|
|
77
|
+
**Black** (`brand` `#000000`) fills the primary button; its label is white. The secondary button is white with a black hairline and black label.
|
|
78
|
+
|
|
79
|
+
### Neutral
|
|
80
|
+
|
|
81
|
+
Pure white ground (`bg` `#ffffff`), pure black ink for headings (`fg` `#000000`), and near-black `#333333` for body copy — well above AA on white. **Borders are black** (`#000000`): card outlines, the rule under the navigation, the rules between sections and the rule above the footer are all 1px black lines. Cards are white, not tinted (`surface-secondary` is white too). There is no accent colour — `accent` is black.
|
|
82
|
+
|
|
83
|
+
Dark mode inverts: black ground, white ink, white rules, white primary button with black label.
|
|
84
|
+
|
|
85
|
+
### Named Rules
|
|
86
|
+
|
|
87
|
+
- **Rules, not fills.** A container is drawn with a black hairline on the white ground. Grey fills are reserved for image placeholders.
|
|
88
|
+
|
|
89
|
+
## Typography
|
|
90
|
+
|
|
91
|
+
System sans throughout; no web font.
|
|
92
|
+
|
|
93
|
+
### Hierarchy
|
|
94
|
+
|
|
95
|
+
| Role | Size | Weight | Notes |
|
|
96
|
+
| --------------- | -------- | ------ | --------------------------------------------------------------------------- |
|
|
97
|
+
| Hero headline | 6rem | 400 | Tracking -0.05em, line-height 1 |
|
|
98
|
+
| Section heading | 2.25rem | 400 | Tracking -0.05em — light and tight, not bold |
|
|
99
|
+
| Item heading | 1.25rem | 600 | Card, feature and step titles |
|
|
100
|
+
| Body | 1.125rem | 400 | `#333333`, line-height 1.5 |
|
|
101
|
+
| Section label | 0.875rem | 600 | Uppercase, +0.05em tracking today — the small label above a section heading |
|
|
102
|
+
|
|
103
|
+
Measured from the rendered scaffold (1440px wide), not transcribed from tokens.
|
|
104
|
+
|
|
105
|
+
The small label above a section heading is **kept** as part of this foundation's voice (operator-disposed 2026-09-22) and is headed toward the treatment below.
|
|
106
|
+
|
|
107
|
+
## Layout
|
|
108
|
+
|
|
109
|
+
Full navigation with the announcement banner; a multi-column footer; the default home. Every page and its sections are listed in `TEMPLATE-MANIFEST.md` in this directory. Shared foundation: a 1280px container, sections at 4rem, card grids at 1.5rem, breakpoints 320 / 768 / 1024 / 1440.
|
|
110
|
+
|
|
111
|
+
## Shapes
|
|
112
|
+
|
|
113
|
+
Two radii today: buttons at 0.25rem, cards and outlined boxes at 0.75rem. Headed toward square corners — see below.
|
|
114
|
+
|
|
115
|
+
## Components
|
|
116
|
+
|
|
117
|
+
### Buttons
|
|
118
|
+
|
|
119
|
+
Primary: black fill, white label, 0.25rem corners. Secondary: transparent with a black 1px outline and black label. Both are the library `Button`.
|
|
120
|
+
|
|
121
|
+
### Cards / Containers
|
|
122
|
+
|
|
123
|
+
White panels with a black 1px outline, 0.75rem corners, `card` (1.5rem) padding. The one exception today: the "how it works" steps render as dark filled cards (see below).
|
|
124
|
+
|
|
125
|
+
### Navigation
|
|
126
|
+
|
|
127
|
+
Full navigation: wordmark left, page links, an outlined and a filled button at the far right, the announcement banner above. A black hairline separates it from the page.
|
|
128
|
+
|
|
129
|
+
## Where this is heading
|
|
130
|
+
|
|
131
|
+
The foundation's pinned direction is the pacing of a classic wireframe marketing kit — `standardissue.webflow.io` is the reference for rhythm, type scale, spacing density and section pacing only; no image, copy or code is taken from it. Six parts of that direction cannot be expressed through a site's theme today, so they wait on a platform change rather than being hand-coded. Until they land, this file describes the rendered site above, not these targets.
|
|
132
|
+
|
|
133
|
+
| Target | Reference value | Blocked by |
|
|
134
|
+
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
135
|
+
| Square corners on buttons, cards and inputs | radius 0 | A site's `theme:` block accepts colours only — no radius |
|
|
136
|
+
| Bold, tighter headings | hero ~3.6rem and section headings ~2.9rem, both at weight 700 with tracking about -0.02em (today 6rem and 2.25rem at weight 400) | No per-site type-role override |
|
|
137
|
+
| Generous section pacing | about 10rem between sections, not 4rem | No per-site section-spacing override; `spacious` (6rem) is not author-selectable |
|
|
138
|
+
| Section label in sentence case, bold, no tracking | "Core Features", not "CORE FEATURES" | The eyebrow role bakes in uppercase and tracking |
|
|
139
|
+
| Whitespace between sections, not rules | no rule between bands | Section dividers share the one `border` colour with card outlines, so black outlines make black dividers |
|
|
140
|
+
| Outlined steps in "how it works" | three plain outlined columns | The steps section renders dark filled cards; no outlined variant |
|
|
141
|
+
|
|
142
|
+
## Do's and Don'ts
|
|
143
|
+
|
|
144
|
+
- **Do** keep every page built from registered sections. If a section you need does not exist, request it rather than writing one-off markup.
|
|
145
|
+
- **Do** change colours in `content/_site.mdx` `theme.colors`; they reach every section.
|
|
146
|
+
- **Don't** add a colour accent. The foundation's one idea is black on white; a brand pass adds colour deliberately, through the theme.
|
|
147
|
+
- **Don't** replace a black rule with a shadow or a grey fill.
|
|
148
|
+
- **Don't** hard-code the "heading toward" values above into a page. They arrive through the platform, or not at all.
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"template": "marketing-site",
|
|
3
3
|
"requires": ["marketing", "docs-blog", "scheduling", "signal-collectors"],
|
|
4
|
-
"
|
|
5
|
-
|
|
4
|
+
"categories": [
|
|
5
|
+
"accounting",
|
|
6
|
+
"legal",
|
|
7
|
+
"hvac",
|
|
8
|
+
"roofing",
|
|
9
|
+
"plumbing",
|
|
10
|
+
"electrical",
|
|
11
|
+
"landscaping",
|
|
12
|
+
"auto-repair",
|
|
13
|
+
"real-estate",
|
|
14
|
+
"technology",
|
|
15
|
+
"medical-specialty"
|
|
16
|
+
],
|
|
17
|
+
"generatedHash": "7ac1901833c4607d7b1a5f7f8531d18618ecdc4a3e810480635d3d6b5eb3be83",
|
|
6
18
|
"layout": {
|
|
7
19
|
"nav": "full",
|
|
8
20
|
"footer": "columns",
|
|
@@ -295,6 +307,14 @@
|
|
|
295
307
|
"chrome": "on",
|
|
296
308
|
"sections": []
|
|
297
309
|
},
|
|
310
|
+
{
|
|
311
|
+
"route": "/appointments",
|
|
312
|
+
"pageType": null,
|
|
313
|
+
"schema": null,
|
|
314
|
+
"shell": "MarketingShell",
|
|
315
|
+
"chrome": "on",
|
|
316
|
+
"sections": []
|
|
317
|
+
},
|
|
298
318
|
{
|
|
299
319
|
"route": "/flows/[slug]",
|
|
300
320
|
"pageType": null,
|
|
@@ -250,6 +250,13 @@ Target composition (deferred to **#5670**, same as `/meet` above):
|
|
|
250
250
|
_Code route — no content, no sections._
|
|
251
251
|
<!-- generated:end -->
|
|
252
252
|
|
|
253
|
+
`/appointments`:
|
|
254
|
+
|
|
255
|
+
<!-- generated:begin page=/appointments -->
|
|
256
|
+
|
|
257
|
+
_Code route — no content, no sections._
|
|
258
|
+
<!-- generated:end -->
|
|
259
|
+
|
|
253
260
|
### `/flows/<slug>` — InstrumentEntryPage · schema `WebPage` · signal-collectors
|
|
254
261
|
|
|
255
262
|
The signal collector's landing (sample: a 5-question fit check). Sections: `hero` · `feature` · `step-flow` (preview) · `cta` · `faq`.
|
|
@@ -322,6 +329,7 @@ Everything in the Free manifest § 2a applies. Pro adds:
|
|
|
322
329
|
```
|
|
323
330
|
marketing-site:
|
|
324
331
|
requires: [marketing, docs-blog, scheduling, signal-collectors]
|
|
332
|
+
categories: [accounting, legal, hvac, roofing, plumbing, electrical, landscaping, auto-repair, real-estate, technology, medical-specialty]
|
|
325
333
|
roster:
|
|
326
334
|
- { route: "/", content: ["content/en/HomePage/home.mdx"] }
|
|
327
335
|
- { route: "/how-it-works", content: ["content/en/LandingPage/how-it-works.mdx"] }
|
|
@@ -338,6 +346,7 @@ marketing-site:
|
|
|
338
346
|
- { route: "/meet" }
|
|
339
347
|
- { route: "/meet/[slug]" }
|
|
340
348
|
- { route: "/meet/confirmed" }
|
|
349
|
+
- { route: "/appointments" }
|
|
341
350
|
- { route: "/flows/[slug]" }
|
|
342
351
|
- { route: "/flows/[slug]/start" }
|
|
343
352
|
- { route: "/flows/[slug]/results/[payload]" }
|
|
@@ -382,8 +391,6 @@ Every component the roster rows' seed content composes today (generated):
|
|
|
382
391
|
|
|
383
392
|
| Gap | Issue |
|
|
384
393
|
| ------------------------------------------------------------------- | ---------- |
|
|
385
|
-
| `/meet` rename | #5563 |
|
|
386
|
-
| `ReportPage` + `/reports/<slug>` | #5562 |
|
|
387
394
|
| Module bundles carry no LICENSE | #5552 |
|
|
388
395
|
| Strip ignores `commercial_tier` (paid dirs still under `packages/`) | #5475 |
|
|
389
396
|
| The Pro demo host `marketing-site.ailaunchkit.ai` — provisioning | #5464 body |
|
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
"provenance.json": ".ailk-template.json",
|
|
8
8
|
"content/en/blog/05-this-vc-morning-routine-will-make-you-super-annoying.mdx": "apps/web/content/en/blog/launching-ailk.mdx"
|
|
9
9
|
},
|
|
10
|
-
"postInstall": "Template marketing-site installed: its module samples - the Pro blog (5 posts) and docs (3 pages) from docs-blog, the projects (2 + listing), thank-you pages (contact, newsletter, apply), fit-check flow definition, waitlist experiment and sample report PDF under apps/web/public/reports/ from signal-collectors - arrived with those module bundles, and /pricing, /privacy and /terms with the base layer
|
|
10
|
+
"postInstall": "Template marketing-site installed: its module samples - the Pro blog (5 posts) and docs (3 pages) from docs-blog, the booking pages at /meet, /meet/<slug> and /meet/confirmed from scheduling, the projects (2 + listing), thank-you pages (contact, newsletter, apply), fit-check flow definition, waitlist experiment, the report reader at /reports/<slug> and its sample report PDF under apps/web/public/reports/ from signal-collectors - arrived with those module bundles, and /pricing, /privacy and /terms with the base layer. This template adds one copy override (blog post 05) - every sample is placeholder copy to replace before you launch."
|
|
11
11
|
}
|