create-ailk 0.1.0 → 0.2.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 +124 -3
- package/component-catalog.md +456 -0
- package/dist/cli.js +92 -16
- package/dist/component-catalog.d.ts +11 -0
- package/dist/component-catalog.js +39 -0
- package/dist/copy.d.ts +7 -0
- package/dist/copy.js +24 -0
- package/dist/derive-architecture.d.ts +13 -0
- package/dist/derive-architecture.js +238 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +19 -2
- package/dist/lib/extract-module-bundle.d.ts +16 -0
- package/dist/lib/extract-module-bundle.js +184 -0
- package/dist/lib/fetch-module.d.ts +55 -0
- package/dist/lib/fetch-module.js +125 -0
- package/dist/lib/module-license-gate.d.ts +48 -0
- package/dist/lib/module-license-gate.js +67 -0
- package/dist/lib/module-tier.d.ts +35 -0
- package/dist/lib/module-tier.js +37 -0
- package/dist/module-architecture.d.ts +175 -0
- package/dist/module-architecture.js +663 -0
- package/dist/parse-args.d.ts +47 -1
- package/dist/parse-args.js +143 -2
- package/dist/programmatic.d.ts +160 -3
- package/dist/programmatic.js +196 -7
- package/dist/surfaces.d.ts +211 -0
- package/dist/surfaces.js +532 -0
- package/dist/sync-routes.d.ts +92 -0
- package/dist/sync-routes.js +350 -0
- package/package.json +12 -5
- package/templates/.claude/rules/architecture.md +6 -2
- package/templates/.claude/skills/README.md +9 -9
- package/templates/.claude/skills/add-schema/SKILL.md +14 -7
- package/templates/.claude/skills/add-schema/references/schema-types.md +109 -6
- package/templates/.claude/skills/provision-config/SKILL.md +1 -1
- package/templates/.claude/skills/scaffold-commerce/SKILL.md +498 -1
- package/templates/.claude/skills/scaffold-commerce/templates/checkout-route.template.ts +370 -0
- package/templates/.claude/skills/scaffold-commerce/templates/invoice-route.template.ts +376 -0
- package/templates/.claude/skills/scaffold-commerce/templates/payment-link-route.template.ts +471 -0
- package/templates/.claude/skills/scaffold-commerce/templates/portal-route.template.ts +365 -0
- package/templates/.claude/skills/scaffold-commerce/templates/stripe-config.template.ts +60 -0
- package/templates/.claude/skills/scaffold-commerce/templates/subscription-route.template.ts +446 -0
- package/templates/.claude/skills/suggest-site-pages/references/categories.md +4 -4
- package/templates/.env.example +126 -2
- package/templates/CLAUDE.md +11 -5
- package/templates/README.md +1 -1
- package/templates/apps/api/.env.example +38 -0
- package/templates/apps/api/CLAUDE.md +78 -1
- package/templates/apps/api/LICENSE +201 -0
- package/templates/apps/api/api/index.ts +6 -141
- package/templates/apps/api/jest.config.cjs +16 -0
- package/templates/apps/api/package.json +22 -6
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +141 -0
- package/templates/apps/api/src/__tests__/server.test.ts +46 -0
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +211 -0
- package/templates/apps/api/src/bin/abandon-sweep.ts +42 -0
- package/templates/apps/api/src/bin/deliverable-resend.ts +144 -0
- package/templates/apps/api/src/bin/deliverable-upload.ts +114 -0
- package/templates/apps/api/src/bin/followup-sweep.ts +44 -0
- package/templates/apps/api/src/bin/listing-csv-sweep.ts +46 -0
- package/templates/apps/api/src/bin/seed-presets.ts +58 -0
- package/templates/apps/api/src/bin/seed-waitlist-experiments.ts +104 -0
- package/templates/apps/api/src/bin/session-retention-sweep.ts +46 -0
- package/templates/apps/api/src/cli.ts +5 -11
- package/templates/apps/api/src/config/index.ts +35 -0
- package/templates/apps/api/src/config/modules.ts +43 -0
- package/templates/apps/api/src/lib/__mocks__/prisma-client.js +11 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +241 -0
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +2 -2
- package/templates/apps/api/src/lib/site.ts +16 -0
- package/templates/apps/api/src/lib/stripe.ts +22 -0
- package/templates/apps/api/src/lib/tenant-db.ts +225 -0
- package/templates/apps/api/src/lib/ws-token.ts +91 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +7 -1
- package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +7 -1
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +91 -4
- package/templates/apps/api/src/middleware/auth.ts +43 -8
- package/templates/apps/api/src/middleware/rate-limit.ts +78 -3
- package/templates/apps/api/src/middleware/tenant.ts +99 -0
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +92 -0
- package/templates/apps/api/src/openapi/spec.ts +312 -3
- package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +175 -0
- package/templates/apps/api/src/routes/aeo/index.ts +107 -0
- package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +5 -2
- package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +22 -3
- package/templates/apps/api/src/routes/auth/tokens.ts +13 -1
- package/templates/apps/api/src/routes/billing/__tests__/portal.test.ts +450 -0
- package/templates/apps/api/src/routes/billing/__tests__/read.test.ts +262 -0
- package/templates/apps/api/src/routes/billing/__tests__/usage.test.ts +436 -0
- package/templates/apps/api/src/routes/billing/index.ts +36 -0
- package/templates/apps/api/src/routes/billing/portal.ts +182 -0
- package/templates/apps/api/src/routes/billing/read.ts +75 -0
- package/templates/apps/api/src/routes/billing/usage.ts +153 -0
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +99 -0
- package/templates/apps/api/src/routes/checkout/sessions.ts +20 -8
- package/templates/apps/api/src/routes/content/create.ts +1 -0
- package/templates/apps/api/src/routes/content/delete.ts +1 -0
- package/templates/apps/api/src/routes/content/index.ts +42 -6
- package/templates/apps/api/src/routes/content/update.ts +1 -0
- package/templates/apps/api/src/routes/deliverables/__tests__/index.test.ts +393 -0
- package/templates/apps/api/src/routes/deliverables/index.ts +200 -0
- package/templates/apps/api/src/routes/flow-checkouts/__tests__/index.test.ts +443 -0
- package/templates/apps/api/src/routes/flow-checkouts/index.ts +82 -0
- package/templates/apps/api/src/routes/flows/README.md +147 -0
- package/templates/apps/api/src/routes/flows/__tests__/index.test.ts +752 -0
- package/templates/apps/api/src/routes/flows/__tests__/recommender.test.ts +671 -0
- package/templates/apps/api/src/routes/flows/index.ts +202 -0
- package/templates/apps/api/src/routes/flows/recommender.ts +443 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +438 -31
- package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +10 -10
- package/templates/apps/api/src/routes/leads/index.ts +43 -9
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +558 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/copy-edit.test.ts +815 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +869 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/me-route-precedence.test.ts +221 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +468 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +424 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +707 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +375 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +467 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/tenant-isolation.test.ts +566 -0
- package/templates/apps/api/src/routes/project-listings/get.ts +70 -0
- package/templates/apps/api/src/routes/project-listings/index.ts +120 -0
- package/templates/apps/api/src/routes/project-listings/list.ts +47 -0
- package/templates/apps/api/src/routes/project-listings/me.ts +76 -0
- package/templates/apps/api/src/routes/project-listings/patch-copy.ts +222 -0
- package/templates/apps/api/src/routes/project-listings/patch-draft.ts +97 -0
- package/templates/apps/api/src/routes/project-listings/patch.ts +136 -0
- package/templates/apps/api/src/routes/project-listings/public.ts +52 -0
- package/templates/apps/api/src/routes/project-listings/respond.ts +37 -0
- package/templates/apps/api/src/routes/project-listings/resume-token.ts +22 -0
- package/templates/apps/api/src/routes/project-listings/start.ts +106 -0
- package/templates/apps/api/src/routes/project-listings/submit.ts +122 -0
- package/templates/apps/api/src/routes/schedule/__tests__/index.test.ts +490 -0
- package/templates/apps/api/src/routes/schedule/index.ts +249 -0
- package/templates/apps/api/src/routes/slack/__tests__/actions.test.ts +385 -0
- package/templates/apps/api/src/routes/slack/actions.ts +177 -0
- package/templates/apps/api/src/routes/slack/index.ts +38 -0
- package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +16 -6
- package/templates/apps/api/src/routes/test/auth/session.ts +8 -6
- package/templates/apps/api/src/routes/waitlist-experiments/__tests__/tenant-isolation.test.ts +577 -0
- package/templates/apps/api/src/routes/waitlist-experiments/comparison.ts +78 -0
- package/templates/apps/api/src/routes/waitlist-experiments/index.ts +41 -0
- package/templates/apps/api/src/routes/waitlist-experiments/list.ts +64 -0
- package/templates/apps/api/src/routes/waitlist-experiments/respond.ts +42 -0
- package/templates/apps/api/src/routes/waitlist-experiments/signup.ts +84 -0
- package/templates/apps/api/src/routes/waitlist-experiments/signups.ts +119 -0
- package/templates/apps/api/src/routes/waitlist-signups/__tests__/index.test.ts +238 -0
- package/templates/apps/api/src/routes/waitlist-signups/index.ts +101 -0
- package/templates/apps/api/src/routes/webhooks/README.md +35 -12
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +315 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +270 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +248 -20
- package/templates/apps/api/src/routes/workspaces/__tests__/config-tenant-isolation.test.ts +356 -0
- package/templates/apps/api/src/routes/workspaces/__tests__/tenant-isolation.test.ts +671 -0
- package/templates/apps/api/src/routes/workspaces/config.ts +125 -0
- package/templates/apps/api/src/routes/workspaces/index.ts +194 -0
- package/templates/apps/api/src/routes/workspaces/sessions.ts +218 -0
- package/templates/apps/api/src/server.ts +307 -7
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +489 -0
- package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +475 -0
- package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +132 -0
- package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +65 -0
- package/templates/apps/api/src/services/__tests__/consent.test.ts +282 -0
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +523 -0
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +359 -0
- package/templates/apps/api/src/services/__tests__/entitlements.test.ts +142 -0
- package/templates/apps/api/src/services/__tests__/flow-aggregate.test.ts +425 -0
- package/templates/apps/api/src/services/__tests__/flow-engine.test.ts +2840 -0
- package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +393 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +8 -8
- package/templates/apps/api/src/services/__tests__/listing-csv-sweep.test.ts +560 -0
- package/templates/apps/api/src/services/__tests__/listing-promotion.test.ts +684 -0
- package/templates/apps/api/src/services/__tests__/playbook-compile.test.ts +406 -0
- package/templates/apps/api/src/services/__tests__/playbook-render.test.ts +290 -0
- package/templates/apps/api/src/services/__tests__/project-listing-decision.test.ts +736 -0
- package/templates/apps/api/src/services/__tests__/project-listing-flow.test.ts +475 -0
- package/templates/apps/api/src/services/__tests__/project-listing-issue.test.ts +340 -0
- package/templates/apps/api/src/services/__tests__/recommender-capture.test.ts +983 -0
- package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +278 -0
- package/templates/apps/api/src/services/__tests__/tenant-context-cascade.test.ts +71 -0
- package/templates/apps/api/src/services/__tests__/tenant-context.test.ts +379 -0
- package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +941 -0
- package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +588 -0
- package/templates/apps/api/src/services/__tests__/usage-metering.test.ts +768 -0
- package/templates/apps/api/src/services/__tests__/waitlist-dashboard.test.ts +1314 -0
- package/templates/apps/api/src/services/__tests__/waitlist-experiments.test.ts +341 -0
- package/templates/apps/api/src/services/__tests__/waitlist-followup.test.ts +567 -0
- package/templates/apps/api/src/services/__tests__/waitlist-scoring.test.ts +474 -0
- package/templates/apps/api/src/services/__tests__/waitlist-signups.test.ts +354 -0
- package/templates/apps/api/src/services/abandon-email.ts +307 -0
- package/templates/apps/api/src/services/aeo-score.ts +288 -0
- package/templates/apps/api/src/services/answer-distributions.ts +138 -0
- package/templates/apps/api/src/services/consent.ts +236 -0
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +523 -0
- package/templates/apps/api/src/services/entitlements.ts +102 -0
- package/templates/apps/api/src/services/flow-aggregate.ts +232 -0
- package/templates/apps/api/src/services/flow-checkouts.ts +123 -0
- package/templates/apps/api/src/services/flow-engine.ts +1296 -0
- package/templates/apps/api/src/services/lead-promotion.ts +176 -0
- package/templates/apps/api/src/services/lead-routing.ts +3 -3
- package/templates/apps/api/src/services/listing-config.ts +102 -0
- package/templates/apps/api/src/services/listing-csv-sweep.ts +455 -0
- package/templates/apps/api/src/services/listing-promotion.ts +342 -0
- package/templates/apps/api/src/services/playbook-compile.ts +398 -0
- package/templates/apps/api/src/services/playbook-render.ts +263 -0
- package/templates/apps/api/src/services/project-listing-decision.ts +510 -0
- package/templates/apps/api/src/services/project-listing-flow.ts +426 -0
- package/templates/apps/api/src/services/project-listing-issue.ts +251 -0
- package/templates/apps/api/src/services/project-listings.ts +1472 -0
- package/templates/apps/api/src/services/recommender-capture.ts +835 -0
- package/templates/apps/api/src/services/scheduling/cal-provider.ts +392 -0
- package/templates/apps/api/src/services/scheduling/index.ts +63 -0
- package/templates/apps/api/src/services/scheduling/types.ts +88 -0
- package/templates/apps/api/src/services/slack-notify.ts +240 -0
- package/templates/apps/api/src/services/tenant-context.ts +451 -0
- package/templates/apps/api/src/services/usage-aggregation.ts +516 -0
- package/templates/apps/api/src/services/usage-credits.ts +340 -0
- package/templates/apps/api/src/services/usage-metering.ts +699 -0
- package/templates/apps/api/src/services/waitlist-dashboard.ts +947 -0
- package/templates/apps/api/src/services/waitlist-experiments.ts +213 -0
- package/templates/apps/api/src/services/waitlist-followup.ts +486 -0
- package/templates/apps/api/src/services/waitlist-scoring.ts +166 -0
- package/templates/apps/api/src/services/waitlist-signups.ts +165 -0
- package/templates/apps/api/src/vercel-handler.ts +165 -0
- package/templates/apps/api/tsconfig.json +0 -12
- package/templates/apps/mcp/CLAUDE.md +19 -9
- package/templates/apps/mcp/LICENSE +201 -0
- package/templates/apps/mcp/__tests__/create_page.test.ts +1 -0
- package/templates/apps/mcp/__tests__/delete_page.test.ts +1 -0
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +105 -0
- package/templates/apps/mcp/__tests__/parity.test.ts +70 -6
- package/templates/apps/mcp/__tests__/request_callback.test.ts +4 -4
- package/templates/apps/mcp/__tests__/schedule_tools.test.ts +242 -0
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +4 -4
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +4 -4
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +47 -0
- package/templates/apps/mcp/__tests__/update_page.test.ts +1 -0
- package/templates/apps/mcp/package.json +6 -4
- package/templates/apps/mcp/src/config/modules.ts +37 -0
- package/templates/apps/mcp/src/server.ts +109 -18
- package/templates/apps/mcp/src/tools/capture_lead.ts +1 -1
- package/templates/apps/mcp/src/tools/create_booking.ts +58 -0
- package/templates/apps/mcp/src/tools/create_page.ts +1 -0
- package/templates/apps/mcp/src/tools/delete_page.ts +1 -0
- package/templates/apps/mcp/src/tools/get_event_meta.ts +55 -0
- package/templates/apps/mcp/src/tools/get_flow.ts +61 -0
- package/templates/apps/mcp/src/tools/index.ts +25 -0
- package/templates/apps/mcp/src/tools/list_availability.ts +67 -0
- package/templates/apps/mcp/src/tools/purchase.ts +3 -0
- package/templates/apps/mcp/src/tools/submit_flow_step.ts +83 -0
- package/templates/apps/mcp/src/tools/update_page.ts +1 -0
- package/templates/apps/mcp/tsconfig.json +1 -9
- package/templates/apps/web/.env.example +44 -0
- package/templates/apps/web/CLAUDE.md +28 -0
- package/templates/apps/web/LICENSE +201 -0
- package/templates/apps/web/__tests__/__mocks__/code-highlight.jest-stub.ts +24 -0
- package/templates/apps/web/__tests__/__mocks__/next-intl-server.ts +33 -0
- package/templates/apps/web/__tests__/__mocks__/next-intl.ts +18 -0
- package/templates/apps/web/__tests__/__mocks__/server-only.ts +13 -0
- package/templates/apps/web/__tests__/__mocks__/style-mock.js +4 -0
- package/templates/apps/web/__tests__/__mocks__/vercel-analytics-server.ts +9 -0
- package/templates/apps/web/__tests__/jest-support/import-meta-transformer.cjs +90 -0
- package/templates/apps/web/__tests__/setup.ts +22 -32
- package/templates/apps/web/app/.well-known/ai-plugin.json/route.ts +6 -3
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +8 -2
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +260 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +263 -0
- package/templates/apps/web/app/[locale]/(authed)/account/sign-out-button.tsx +39 -0
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +54 -0
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +96 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/page.tsx +309 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/signups/[leadId]/page.tsx +149 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/comparison.test.tsx +273 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/gate.test.tsx +172 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/list.test.tsx +171 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/signup.test.tsx +179 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ExperimentsTable.tsx +116 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ForbiddenState.tsx +24 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/OfferFunnelTable.tsx +66 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/RollupTicker.tsx +61 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ScoreTrace.tsx +114 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/SignupsTable.tsx +139 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/WaitlistComparisonTabs.tsx +85 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/status-badges.tsx +67 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/format.ts +111 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/page.tsx +179 -0
- package/templates/apps/web/app/[locale]/about/page.tsx +10 -1
- package/templates/apps/web/app/[locale]/blog/[[...slug]]/page.tsx +6 -1
- package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/careers/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/case-studies/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/case-studies/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/clients/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +21 -1
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +188 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +242 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +29 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/intake-analytics.test.ts +51 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +39 -15
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +21 -3
- package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +49 -0
- package/templates/apps/web/app/[locale]/contact/intake-script.ts +66 -0
- package/templates/apps/web/app/[locale]/contact/page.tsx +14 -4
- package/templates/apps/web/app/[locale]/courses/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/courses/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/docs/[[...slug]]/page.tsx +1 -0
- package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/downloads/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/events/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +12 -2
- package/templates/apps/web/app/[locale]/events/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/faq/page.tsx +10 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +265 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +445 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +341 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/checkout.actions.test.ts +287 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/flow.actions.test.ts +302 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/two-route-tool.test.tsx +128 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/checkout.actions.ts +254 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +144 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/page.tsx +108 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsClient.tsx +532 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsEmailStep.tsx +121 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/ResultsClient.checkout.test.tsx +457 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/page.test.tsx +396 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/page.tsx +114 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/start/page.tsx +52 -0
- package/templates/apps/web/app/[locale]/how-to/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/integrations/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/integrations/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/launch-service/page.tsx +14 -1
- package/templates/apps/web/app/[locale]/layout.tsx +127 -16
- package/templates/apps/web/app/[locale]/page.tsx +10 -1
- package/templates/apps/web/app/[locale]/partners/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/partners/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/products/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/products/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/projects/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +10 -0
- package/templates/apps/web/app/[locale]/projects/apply/ListingApplicationClient.tsx +110 -0
- package/templates/apps/web/app/[locale]/projects/apply/__tests__/ListingApplicationClient.test.tsx +96 -0
- package/templates/apps/web/app/[locale]/projects/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/resources/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +12 -2
- package/templates/apps/web/app/[locale]/resources/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/schedule/__tests__/page.test.tsx +117 -0
- package/templates/apps/web/app/[locale]/schedule/confirmed/__tests__/page.test.tsx +96 -0
- package/templates/apps/web/app/[locale]/schedule/confirmed/page.tsx +92 -0
- package/templates/apps/web/app/[locale]/schedule/page.tsx +82 -0
- package/templates/apps/web/app/[locale]/services/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/services/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/sign-in/__tests__/next-path.test.ts +31 -0
- package/templates/apps/web/app/[locale]/sign-in/__tests__/page.test.tsx +152 -0
- package/templates/apps/web/app/[locale]/sign-in/next-path.ts +0 -0
- package/templates/apps/web/app/[locale]/sign-in/page.tsx +83 -0
- package/templates/apps/web/app/[locale]/sign-in/sign-in-card.tsx +123 -0
- package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/tech-articles/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/testimonials/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/thanks/[slug]/__tests__/page.test.tsx +93 -0
- package/templates/apps/web/app/[locale]/thanks/[slug]/page.tsx +48 -0
- package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/use-cases/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/whitepapers/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/globals.css +35 -0
- package/templates/apps/web/app/llms.txt/route.ts +2 -1
- package/templates/apps/web/app/og/route.tsx +10 -2
- package/templates/apps/web/auth.ts +8 -0
- package/templates/apps/web/components/sign-out-trigger.tsx +42 -0
- package/templates/apps/web/content/en/blog/README.txt +25 -0
- package/templates/apps/web/content/en/docs/index.mdx +28 -0
- package/templates/apps/web/jest.config.cjs +90 -27
- package/templates/apps/web/lib/__tests__/site-brand.test.ts +119 -0
- package/templates/apps/web/lib/__tests__/site-theme.test.ts +112 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +499 -0
- package/templates/apps/web/lib/account-config.ts +13 -0
- package/templates/apps/web/lib/server-api.ts +85 -0
- package/templates/apps/web/lib/site-brand.tsx +121 -0
- package/templates/apps/web/lib/site-theme.ts +74 -0
- package/templates/apps/web/messages/en.json +275 -7
- package/templates/apps/web/middleware.ts +11 -3
- package/templates/apps/web/next.config.mjs +8 -2
- package/templates/apps/web/package.json +17 -7
- package/templates/apps/web/postcss.config.mjs +23 -0
- package/templates/apps/web/public/.well-known/security.txt +3 -3
- package/templates/apps/web/src/lib/routes.ts +15 -2
- package/templates/apps/web/tsconfig.json +1 -16
- package/templates/content/_site.mdx +36 -25
- package/templates/content/en/AboutPage/about.mdx +24 -14
- package/templates/content/en/ContactPage/contact.mdx +23 -14
- package/templates/content/en/FAQPage/faq.mdx +10 -392
- package/templates/content/en/HomePage/home.mdx +14 -285
- package/templates/database/CHANGELOG.md +443 -0
- package/templates/database/LICENSE +201 -0
- package/templates/database/README.md +3 -1
- package/templates/database/__tests__/flows-listing-diagnostic.test.ts +392 -0
- package/templates/database/__tests__/flows-presets.test.ts +173 -0
- package/templates/database/__tests__/prefixed-ids.db.test.ts +146 -0
- package/templates/database/__tests__/seed.test.ts +88 -0
- package/templates/database/__tests__/user-cascade.test.ts +19 -4
- package/templates/database/auth/schema.prisma +521 -0
- package/templates/database/config/schema.prisma +234 -0
- package/templates/database/content/schema.prisma +263 -0
- package/templates/database/flows/listing-diagnostic.ts +182 -0
- package/templates/database/flows/presets.ts +315 -0
- package/templates/database/inbox/__tests__/schema.test.ts +4 -0
- package/templates/database/inbox/schema.prisma +574 -3
- package/templates/database/jest.config.cjs +8 -0
- package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +201 -0
- package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +67 -0
- package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +46 -0
- package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +25 -0
- package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +49 -0
- package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +197 -0
- package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +32 -0
- package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +22 -0
- package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +151 -0
- package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +223 -0
- package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +22 -0
- package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +32 -0
- package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +40 -0
- package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +4 -0
- package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +2 -0
- package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +2 -0
- package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +29 -0
- package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +6 -0
- package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +39 -0
- package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +24 -0
- package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +3 -0
- package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +33 -0
- package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +30 -0
- package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +47 -0
- package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +16 -0
- package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +47 -0
- package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +10 -0
- package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +26 -0
- package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +90 -0
- package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +174 -0
- package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +14 -0
- package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +25 -0
- package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +32 -0
- package/templates/database/migrations/20260911180000_consent_grants/migration.sql +71 -0
- package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +30 -0
- package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +49 -0
- package/templates/database/ops/schema.prisma +27 -0
- package/templates/database/package.json +42 -4
- package/templates/database/prisma.config.ts +1 -1
- package/templates/database/schema.prisma +19 -435
- package/templates/database/seed-test.ts +14 -4
- package/templates/database/seed.ts +148 -0
- package/templates/database/tenancy.ts +45 -0
- package/templates/database/tsconfig.flows.json +15 -0
- package/templates/database/tsconfig.json +7 -1
- package/templates/database/tsconfig.tenancy.json +14 -0
- package/templates/package.json +30 -55
- package/templates/pnpm-workspace.yaml +0 -3
- package/templates/project.yaml +1 -1
- package/templates/tsconfig.json +1 -37
- package/templates/apps/web/__tests__/auth/adversarial/cookie-attributes.test.ts +0 -94
- package/templates/apps/web/__tests__/auth/adversarial/oauth-state-parameter.test.ts +0 -75
- package/templates/apps/web/__tests__/auth/adversarial/redirect-uri-allowlist.test.ts +0 -82
- package/templates/apps/web/__tests__/auth/env-helpers.test.ts +0 -168
- package/templates/apps/web/__tests__/authority-list-routes.test.tsx +0 -208
- package/templates/apps/web/__tests__/better-stack.test.ts +0 -66
- package/templates/apps/web/__tests__/blog-dir-resolution.test.ts +0 -87
- package/templates/apps/web/__tests__/blog-source-populated.test.ts +0 -130
- package/templates/apps/web/__tests__/data-testid-coverage.test.tsx +0 -60
- package/templates/apps/web/__tests__/google-analytics.test.tsx +0 -104
- package/templates/apps/web/__tests__/i18n/middleware.test.ts +0 -119
- package/templates/apps/web/__tests__/i18n/routing.test.ts +0 -114
- package/templates/apps/web/__tests__/i18n/translations.test.ts +0 -191
- package/templates/apps/web/__tests__/json-ld.test.ts +0 -98
- package/templates/apps/web/__tests__/knowledge-events-routes.test.tsx +0 -580
- package/templates/apps/web/__tests__/layout-stealth.test.ts +0 -39
- package/templates/apps/web/__tests__/lighthouse-fixtures/improvement-image-shrink.tsx +0 -103
- package/templates/apps/web/__tests__/lighthouse-fixtures/override-fixture.md +0 -114
- package/templates/apps/web/__tests__/lighthouse-fixtures/regression-bloat.tsx +0 -94
- package/templates/apps/web/__tests__/page.test.tsx +0 -230
- package/templates/apps/web/__tests__/products-services-phase1.test.tsx +0 -321
- package/templates/apps/web/__tests__/projects-routes.test.tsx +0 -392
- package/templates/apps/web/__tests__/resources-downloads-integrations-phase2.test.tsx +0 -475
- package/templates/apps/web/__tests__/routes/ai-plugin-json.test.ts +0 -53
- package/templates/apps/web/__tests__/routes/blog-route.test.tsx +0 -191
- package/templates/apps/web/__tests__/routes/llms-txt.test.ts +0 -123
- package/templates/apps/web/__tests__/routes/robots-txt.test.ts +0 -52
- package/templates/apps/web/__tests__/routes/sitemap-xml.test.ts +0 -78
- package/templates/apps/web/__tests__/routes/well-known-mcp.test.ts +0 -203
- package/templates/apps/web/__tests__/section-routes.test.tsx +0 -693
- package/templates/apps/web/__tests__/security-headers.test.ts +0 -201
- package/templates/apps/web/__tests__/sentry-config.test.ts +0 -116
- package/templates/apps/web/__tests__/sitemap-locales.test.ts +0 -415
- package/templates/apps/web/__tests__/standalone-informational-routes.test.tsx +0 -844
- package/templates/apps/web/app/[locale]/__tests__/layout.test.tsx +0 -120
- package/templates/apps/web/app/[locale]/__tests__/page-renderer-migration.test.tsx +0 -202
- package/templates/apps/web/app/__tests__/error-boundaries.test.tsx +0 -152
- package/templates/apps/web/content/en/blog/index.mdx +0 -15
- package/templates/apps/web/content/en/blog/launching-ailk.mdx +0 -20
- package/templates/apps/web/content/en/docs/getting-started.mdx +0 -30
- package/templates/content/.gitkeep +0 -0
- package/templates/content/CLAUDE.md +0 -85
- package/templates/content/ar/HomePage/home.mdx +0 -123
- package/templates/content/ar/_site.mdx +0 -35
- package/templates/content/de/_site.mdx +0 -29
- package/templates/content/en/.gitkeep +0 -0
- package/templates/content/en/AboutPage/about.schema.json +0 -82
- package/templates/content/en/BookCall/book-call.mdx +0 -19
- package/templates/content/en/BookCall/book-call.schema.json +0 -121
- package/templates/content/en/BreadcrumbList/site-breadcrumbs.mdx +0 -20
- package/templates/content/en/CareersList/careers.mdx +0 -24
- package/templates/content/en/CaseStudiesList/case-studies.mdx +0 -22
- package/templates/content/en/CaseStudiesList/showcase.mdx +0 -8
- package/templates/content/en/CaseStudy/ailk-aeo-rollout.mdx +0 -32
- package/templates/content/en/CaseStudy/schema-builder-migration.mdx +0 -41
- package/templates/content/en/ClientsList/clients.mdx +0 -38
- package/templates/content/en/ContactPage/contact.schema.json +0 -100
- package/templates/content/en/ContactPoint/primary.mdx +0 -14
- package/templates/content/en/Course/aeo-fundamentals.mdx +0 -37
- package/templates/content/en/Course/schema-builder-workshop.mdx +0 -62
- package/templates/content/en/CoursesList/courses.mdx +0 -22
- package/templates/content/en/DownloadsList/downloads.mdx +0 -22
- package/templates/content/en/Event/aeo-office-hours-may-2026.mdx +0 -39
- package/templates/content/en/Event/ailk-launch-day-2026.mdx +0 -35
- package/templates/content/en/EventsList/events.mdx +0 -26
- package/templates/content/en/FAQPage/faq.schema.json +0 -231
- package/templates/content/en/GlossaryList/glossary.mdx +0 -19
- package/templates/content/en/GlossaryList/glossary.schema.json +0 -300
- package/templates/content/en/HomePage/home.schema.json +0 -88
- package/templates/content/en/HomePage/launch-service.mdx +0 -475
- package/templates/content/en/HomePage/launch-service.schema.json +0 -138
- package/templates/content/en/HowTo/add-mdx-content.mdx +0 -38
- package/templates/content/en/HowTo/configure-aeo-scoring.mdx +0 -35
- package/templates/content/en/HowTo/set-up-json-ld.mdx +0 -36
- package/templates/content/en/Integration/github-actions.mdx +0 -31
- package/templates/content/en/Integration/openai-api.mdx +0 -26
- package/templates/content/en/Integration/vercel.mdx +0 -32
- package/templates/content/en/IntegrationsList/integrations.mdx +0 -22
- package/templates/content/en/JobPosting/content-strategist.mdx +0 -46
- package/templates/content/en/JobPosting/developer-advocate.mdx +0 -47
- package/templates/content/en/JobPosting/senior-fullstack-engineer.mdx +0 -57
- package/templates/content/en/LandingPage/aeo-audit.mdx +0 -19
- package/templates/content/en/LandingPage/aeo-audit.schema.json +0 -92
- package/templates/content/en/LandingPage/agency-waitlist.mdx +0 -340
- package/templates/content/en/LandingPage/agency-waitlist.schema.json +0 -152
- package/templates/content/en/LandingPage/developers.mdx +0 -19
- package/templates/content/en/LandingPage/developers.schema.json +0 -109
- package/templates/content/en/LandingPage/for-agencies.mdx +0 -390
- package/templates/content/en/LandingPage/for-agencies.schema.json +0 -107
- package/templates/content/en/LandingPage/for-ai-search-agencies.mdx +0 -417
- package/templates/content/en/LandingPage/for-ai-search-agencies.schema.json +0 -105
- package/templates/content/en/LandingPage/for-businesses.mdx +0 -19
- package/templates/content/en/LandingPage/for-businesses.schema.json +0 -96
- package/templates/content/en/LandingPage/platform.mdx +0 -369
- package/templates/content/en/LandingPage/platform.schema.json +0 -166
- package/templates/content/en/LandingPage/vs-ai-website-builders.mdx +0 -19
- package/templates/content/en/LandingPage/vs-ai-website-builders.schema.json +0 -102
- package/templates/content/en/LandingPage/vs-wordpress.mdx +0 -19
- package/templates/content/en/LandingPage/vs-wordpress.schema.json +0 -53
- package/templates/content/en/NewsletterSignup/newsletter.mdx +0 -236
- package/templates/content/en/NewsletterSignup/newsletter.schema.json +0 -91
- package/templates/content/en/Organization/site-owner.mdx +0 -16
- package/templates/content/en/Partner/prisma.mdx +0 -31
- package/templates/content/en/Partner/supabase.mdx +0 -30
- package/templates/content/en/Partner/vercel.mdx +0 -28
- package/templates/content/en/PartnersList/partners.mdx +0 -22
- package/templates/content/en/Person/founder.mdx +0 -18
- package/templates/content/en/Pricing/pricing.mdx +0 -538
- package/templates/content/en/Pricing/pricing.schema.json +0 -209
- package/templates/content/en/PrivacyPage/privacy.mdx +0 -165
- package/templates/content/en/PrivacyPage/privacy.schema.json +0 -64
- package/templates/content/en/Product/ailk.mdx +0 -19
- package/templates/content/en/Product/ailk.schema.json +0 -94
- package/templates/content/en/Product/api-launch-kit.mdx +0 -26
- package/templates/content/en/Product/launch-kit.mdx +0 -28
- package/templates/content/en/ProductsList/products.mdx +0 -26
- package/templates/content/en/Project/ailk-phase-2.mdx +0 -54
- package/templates/content/en/ProjectsList/projects.mdx +0 -25
- package/templates/content/en/ResourceDetail/aeo-scoring-guide.mdx +0 -27
- package/templates/content/en/ResourceDetail/content-model-whitepaper.mdx +0 -28
- package/templates/content/en/ResourceDetail/schema-org-quick-reference.mdx +0 -39
- package/templates/content/en/ResourcesHub/resources.mdx +0 -22
- package/templates/content/en/Service/consulting.mdx +0 -22
- package/templates/content/en/Service/implementation.mdx +0 -30
- package/templates/content/en/Service/launch-service.mdx +0 -232
- package/templates/content/en/Service/launch.mdx +0 -228
- package/templates/content/en/ServicesList/services.mdx +0 -84
- package/templates/content/en/SoftwareProduct/ailk-aeo.mdx +0 -44
- package/templates/content/en/SoftwareProduct/ailk-content-adapters.mdx +0 -47
- package/templates/content/en/SoftwareProduct/ailk-schema.mdx +0 -49
- package/templates/content/en/TeamList/team.mdx +0 -63
- package/templates/content/en/TeamMember/founder.mdx +0 -72
- package/templates/content/en/TermsPage/terms.mdx +0 -19
- package/templates/content/en/TermsPage/terms.schema.json +0 -99
- package/templates/content/en/TestimonialsList/testimonials.mdx +0 -44
- package/templates/content/en/UseCasesList/use-cases.mdx +0 -30
- package/templates/content/en/Whitepaper/ax-first-product-development.mdx +0 -27
- package/templates/content/en/Whitepaper/open-core-commercial-strategy.mdx +0 -27
- package/templates/content/en/Whitepaper/structured-data-for-answer-engines.mdx +0 -31
- package/templates/content/en-XA/AboutPage/about.mdx +0 -8
- package/templates/content/en-XA/FAQPage/faq.mdx +0 -8
- package/templates/content/en-XA/HomePage/home.mdx +0 -8
- package/templates/content/es/_site.mdx +0 -30
- package/templates/content/fr/_site.mdx +0 -30
- package/templates/content/ja/_site.mdx +0 -30
- package/templates/content/pt-BR/AboutPage/about.mdx +0 -8
- package/templates/content/pt-BR/FAQPage/faq.mdx +0 -8
- package/templates/content/pt-BR/HomePage/home.mdx +0 -23
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `create-ailk sync-routes` — bring an already-scaffolded site's route tree up
|
|
3
|
+
* to the template's (#4986).
|
|
4
|
+
*
|
|
5
|
+
* A site scaffolded from an older create-ailk lacks the route directories the
|
|
6
|
+
* template gained since (the recommender routes of #4891, say). This command
|
|
7
|
+
* names them — with the `@working-theory/*` release line that first carried
|
|
8
|
+
* each, from `ROUTE_SINCE` in surfaces.ts — and, with `--apply`, copies them
|
|
9
|
+
* in through the SAME copier a scaffold uses, so a synced route is
|
|
10
|
+
* byte-identical to a freshly scaffolded one.
|
|
11
|
+
*
|
|
12
|
+
* Three rules shape it:
|
|
13
|
+
*
|
|
14
|
+
* - Scope follows the registry. Every core route dir is checked; a gateable
|
|
15
|
+
* surface's route dirs are checked only when the site carries that surface
|
|
16
|
+
* (any of its `routes` exists as a directory). A surface gated off at
|
|
17
|
+
* scaffold time is deliberate absence, not drift — it is reported as
|
|
18
|
+
* skipped, never as missing.
|
|
19
|
+
* - Expected bytes are what `copyTemplate` would write. The copier's
|
|
20
|
+
* text/binary + marker rules are NOT re-implemented here: the template's
|
|
21
|
+
* route root is copied once into a scratch dir and compared from there.
|
|
22
|
+
* - Never overwrite, never delete. A route dir the site has changed is
|
|
23
|
+
* reported as modified and left alone; `--apply` only creates directories
|
|
24
|
+
* that do not exist, so a second run is a no-op.
|
|
25
|
+
*
|
|
26
|
+
* Pure module: no `import.meta.url`, so jest can import it directly. The
|
|
27
|
+
* package's own `templates/` dir is supplied by programmatic.ts.
|
|
28
|
+
*/
|
|
29
|
+
import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
30
|
+
import { tmpdir } from "node:os";
|
|
31
|
+
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
32
|
+
import { parseArgs } from "node:util";
|
|
33
|
+
import { copyTemplate } from "./copy.js";
|
|
34
|
+
import { substituteMarkers } from "./substitute.js";
|
|
35
|
+
import { GATEABLE_SURFACES, NON_ROUTE_DIRS, ROUTE_DEPENDENCIES, ROUTE_MESSAGE_NAMESPACES, ROUTE_SINCE, surfaceForRouteDir, } from "./surfaces.js";
|
|
36
|
+
/** Template-relative prefix every `apps/web` route directory sits under. */
|
|
37
|
+
const ROUTE_ROOT = "apps/web/app/[locale]";
|
|
38
|
+
/**
|
|
39
|
+
* The template's route directories, ROUTE_ROOT-relative and sorted.
|
|
40
|
+
*
|
|
41
|
+
* A route directory is a directory under ROUTE_ROOT (not the root itself)
|
|
42
|
+
* that directly holds at least one regular file, is not inside a
|
|
43
|
+
* `NON_ROUTE_DIRS` tree (`__tests__`, `components`), and whose top segment
|
|
44
|
+
* the registry recognizes (`surfaceForRouteDir`).
|
|
45
|
+
*/
|
|
46
|
+
export function listTemplateRouteDirs(templatesDir) {
|
|
47
|
+
const root = join(templatesDir, ROUTE_ROOT);
|
|
48
|
+
const out = [];
|
|
49
|
+
const stack = [""];
|
|
50
|
+
while (stack.length > 0) {
|
|
51
|
+
const rel = stack.pop();
|
|
52
|
+
if (rel === undefined)
|
|
53
|
+
break;
|
|
54
|
+
let hasFile = false;
|
|
55
|
+
for (const entry of readdirSync(join(root, rel), { withFileTypes: true })) {
|
|
56
|
+
if (entry.isFile()) {
|
|
57
|
+
hasFile = true;
|
|
58
|
+
}
|
|
59
|
+
else if (entry.isDirectory() && !NON_ROUTE_DIRS.has(entry.name)) {
|
|
60
|
+
stack.push(rel === "" ? entry.name : `${rel}/${entry.name}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (rel !== "" && hasFile && surfaceForRouteDir(rel) !== undefined) {
|
|
64
|
+
out.push(rel);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return out.sort();
|
|
68
|
+
}
|
|
69
|
+
/** Build the report entry for a route dir, insisting on a manifest entry. */
|
|
70
|
+
function reportFor(route) {
|
|
71
|
+
const since = ROUTE_SINCE[route];
|
|
72
|
+
if (since === undefined) {
|
|
73
|
+
throw new Error(`template route dir "${route}" has no ROUTE_SINCE entry — add one in src/surfaces.ts`);
|
|
74
|
+
}
|
|
75
|
+
// Every listed route dir has a recognized top segment by construction.
|
|
76
|
+
return {
|
|
77
|
+
route,
|
|
78
|
+
surface: surfaceForRouteDir(route) ?? "core",
|
|
79
|
+
since,
|
|
80
|
+
dependencies: ROUTE_DEPENDENCIES[route] ?? [],
|
|
81
|
+
messageNamespaces: ROUTE_MESSAGE_NAMESPACES[route] ?? [],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Whether any DIRECT file of the expected route dir is absent from, or differs
|
|
86
|
+
* byte-for-byte in, the target's copy. Non-recursive: nested directories are
|
|
87
|
+
* route dirs of their own, or `__tests__`.
|
|
88
|
+
*/
|
|
89
|
+
function isModified(expectedDir, targetDir) {
|
|
90
|
+
for (const entry of readdirSync(expectedDir, { withFileTypes: true })) {
|
|
91
|
+
if (!entry.isFile())
|
|
92
|
+
continue;
|
|
93
|
+
const targetFile = join(targetDir, entry.name);
|
|
94
|
+
if (!existsSync(targetFile))
|
|
95
|
+
return true;
|
|
96
|
+
const expected = readFileSync(join(expectedDir, entry.name));
|
|
97
|
+
if (!expected.equals(readFileSync(targetFile)))
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Compare an already-scaffolded repo's route tree with the template's and,
|
|
104
|
+
* when `apply` is set, copy in the route dirs it is missing.
|
|
105
|
+
*
|
|
106
|
+
* Throws Error on a missing target, a non-directory target, a directory with
|
|
107
|
+
* no `architecture.yaml`, or a template route dir without a `ROUTE_SINCE`
|
|
108
|
+
* entry; the CLI's top-level catch turns that into a `[create-ailk] <message>`
|
|
109
|
+
* stderr write + exit 1.
|
|
110
|
+
*/
|
|
111
|
+
export function syncRoutes(opts) {
|
|
112
|
+
const targetAbs = resolve(opts.targetDir);
|
|
113
|
+
if (!existsSync(targetAbs)) {
|
|
114
|
+
throw new Error(`sync target does not exist: ${targetAbs}. Point sync-routes at an already-scaffolded repo.`);
|
|
115
|
+
}
|
|
116
|
+
if (!statSync(targetAbs).isDirectory()) {
|
|
117
|
+
throw new Error(`sync target is not a directory: ${targetAbs}`);
|
|
118
|
+
}
|
|
119
|
+
if (!existsSync(join(targetAbs, "architecture.yaml"))) {
|
|
120
|
+
throw new Error(`not a scaffolded repo: no architecture.yaml at ${targetAbs}. Run \`create-ailk <target-dir>\` to scaffold first.`);
|
|
121
|
+
}
|
|
122
|
+
// Presence of any of a surface's route dirs means the site carries it.
|
|
123
|
+
const carried = new Set();
|
|
124
|
+
const skippedSurfaces = [];
|
|
125
|
+
for (const surface of GATEABLE_SURFACES) {
|
|
126
|
+
const present = surface.routes.some((r) => {
|
|
127
|
+
const p = join(targetAbs, r);
|
|
128
|
+
return existsSync(p) && statSync(p).isDirectory();
|
|
129
|
+
});
|
|
130
|
+
if (present)
|
|
131
|
+
carried.add(surface.id);
|
|
132
|
+
else
|
|
133
|
+
skippedSurfaces.push(surface.id);
|
|
134
|
+
}
|
|
135
|
+
skippedSurfaces.sort();
|
|
136
|
+
const inScope = listTemplateRouteDirs(opts.templatesDir)
|
|
137
|
+
.map(reportFor)
|
|
138
|
+
// "authed" (#5014): the `(authed)` route group ships unconditionally in
|
|
139
|
+
// every scaffold today, the same as "core" — it is checked regardless of
|
|
140
|
+
// `carried`, which only tracks GATEABLE_SURFACES opt-in.
|
|
141
|
+
.filter((r) => r.surface === "core" || r.surface === "authed" || carried.has(r.surface));
|
|
142
|
+
// Identical to scaffoldSync's defaults, so a synced route matches a fresh
|
|
143
|
+
// scaffold of the same target byte-for-byte.
|
|
144
|
+
const markers = {
|
|
145
|
+
PROJECT_NAME: basename(targetAbs),
|
|
146
|
+
COMPANY_NAME: "Your Company",
|
|
147
|
+
COMPANY_DOMAIN: "example.com",
|
|
148
|
+
};
|
|
149
|
+
const templateRouteRoot = join(opts.templatesDir, ROUTE_ROOT);
|
|
150
|
+
const targetRouteRoot = join(targetAbs, ROUTE_ROOT);
|
|
151
|
+
const missing = [];
|
|
152
|
+
const modified = [];
|
|
153
|
+
const scratch = mkdtempSync(join(tmpdir(), "ailk-sync-routes-"));
|
|
154
|
+
try {
|
|
155
|
+
copyTemplate({
|
|
156
|
+
templatesDir: templateRouteRoot,
|
|
157
|
+
targetDir: scratch,
|
|
158
|
+
versions: opts.versions,
|
|
159
|
+
markers,
|
|
160
|
+
});
|
|
161
|
+
for (const report of inScope) {
|
|
162
|
+
const targetRoute = join(targetRouteRoot, report.route);
|
|
163
|
+
if (!existsSync(targetRoute)) {
|
|
164
|
+
missing.push(report);
|
|
165
|
+
}
|
|
166
|
+
else if (isModified(join(scratch, report.route), targetRoute)) {
|
|
167
|
+
modified.push(report);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
173
|
+
}
|
|
174
|
+
// #5014 third clause: a route's ROUTE_DEPENDENCIES files must exist in the
|
|
175
|
+
// target too, or `--apply` leaves a route that cannot compile. Computed
|
|
176
|
+
// from `missing` only — a route already present is assumed to already have
|
|
177
|
+
// brought its own dependencies along (or the site owner has otherwise
|
|
178
|
+
// satisfied them); re-checking every IN-SCOPE route's dependencies on every
|
|
179
|
+
// run would report a pre-existing, unrelated gap as if this sync caused it.
|
|
180
|
+
const missingDependencies = [
|
|
181
|
+
...new Set(missing.flatMap((r) => r.dependencies.filter((dep) => !existsSync(join(targetAbs, dep))))),
|
|
182
|
+
].sort();
|
|
183
|
+
const missingMessageNamespaces = [
|
|
184
|
+
...new Set(missing.flatMap((r) => r.messageNamespaces.filter((ns) => !hasMessageNamespace(targetAbs, ns)))),
|
|
185
|
+
].sort();
|
|
186
|
+
const applied = [];
|
|
187
|
+
const appliedDependencies = [];
|
|
188
|
+
if (opts.apply === true) {
|
|
189
|
+
const missingRoutes = missing.map((r) => r.route);
|
|
190
|
+
for (const route of missingRoutes) {
|
|
191
|
+
applied.push(route);
|
|
192
|
+
// An ancestor route dir's subtree copy already brings this one.
|
|
193
|
+
if (missingRoutes.some((m) => route.startsWith(m + "/")))
|
|
194
|
+
continue;
|
|
195
|
+
const dst = resolve(join(targetRouteRoot, route));
|
|
196
|
+
if (!dst.startsWith(targetAbs + sep)) {
|
|
197
|
+
throw new Error(`refusing to write outside target dir: ${dst}`);
|
|
198
|
+
}
|
|
199
|
+
copyTemplate({
|
|
200
|
+
templatesDir: join(templateRouteRoot, route),
|
|
201
|
+
targetDir: dst,
|
|
202
|
+
versions: opts.versions,
|
|
203
|
+
markers,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
for (const dep of missingDependencies) {
|
|
207
|
+
const dst = resolve(join(targetAbs, dep));
|
|
208
|
+
if (!dst.startsWith(targetAbs + sep)) {
|
|
209
|
+
throw new Error(`refusing to write outside target dir: ${dst}`);
|
|
210
|
+
}
|
|
211
|
+
copyDependencyFile(join(opts.templatesDir, dep), dst, markers);
|
|
212
|
+
appliedDependencies.push(dep);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
targetDir: targetAbs,
|
|
217
|
+
checked: inScope.length,
|
|
218
|
+
missing,
|
|
219
|
+
modified,
|
|
220
|
+
applied,
|
|
221
|
+
missingDependencies,
|
|
222
|
+
appliedDependencies,
|
|
223
|
+
missingMessageNamespaces,
|
|
224
|
+
skippedSurfaces,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Whether `apps/web/messages/en.json` in `targetAbs` already declares
|
|
229
|
+
* `namespace` (a dot-path, e.g. `"waitlistDashboard.gate"`). Missing or
|
|
230
|
+
* unparseable `messages/en.json` reads as "namespace absent" rather than
|
|
231
|
+
* throwing — a sync check should report a gap, not crash on one.
|
|
232
|
+
*/
|
|
233
|
+
function hasMessageNamespace(targetAbs, namespace) {
|
|
234
|
+
const messagesPath = join(targetAbs, "apps/web/messages/en.json");
|
|
235
|
+
if (!existsSync(messagesPath))
|
|
236
|
+
return false;
|
|
237
|
+
try {
|
|
238
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- arbitrary consumer JSON
|
|
239
|
+
let node = JSON.parse(readFileSync(messagesPath, "utf8"));
|
|
240
|
+
for (const key of namespace.split(".")) {
|
|
241
|
+
if (node === null || typeof node !== "object" || !(key in node)) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
node = node[key];
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Copy one dependency file from the template into the target, applying the
|
|
254
|
+
* same marker substitution `copyTemplate` applies to text files — every
|
|
255
|
+
* `ROUTE_DEPENDENCIES` entry is `.ts`/`.tsx`, always text. Never overwrites:
|
|
256
|
+
* the caller (`syncRoutes`) only calls this for a path already confirmed
|
|
257
|
+
* absent from the target, but the check is repeated here so this helper is
|
|
258
|
+
* safe to call on its own.
|
|
259
|
+
*/
|
|
260
|
+
function copyDependencyFile(src, dst, markers) {
|
|
261
|
+
if (existsSync(dst))
|
|
262
|
+
return;
|
|
263
|
+
mkdirSync(dirname(dst), { recursive: true });
|
|
264
|
+
const text = readFileSync(src, "utf8");
|
|
265
|
+
writeFileSync(dst, substituteMarkers(text, markers));
|
|
266
|
+
}
|
|
267
|
+
/** Render the report the CLI prints after a run. Ends with a newline. */
|
|
268
|
+
export function formatSyncRoutesReport(result, apply) {
|
|
269
|
+
const lines = [`[create-ailk] sync-routes: ${result.targetDir}`];
|
|
270
|
+
const entry = (r) => ` ${r.route} (surface: ${r.surface}, added in ${r.since})`;
|
|
271
|
+
if (result.missing.length === 0) {
|
|
272
|
+
// A site with local edits is not "in sync" — say precisely what holds.
|
|
273
|
+
lines.push(result.modified.length === 0
|
|
274
|
+
? `[create-ailk] Routes in sync with the template (${result.checked} route(s) checked).`
|
|
275
|
+
: `[create-ailk] No template routes missing (${result.checked} route(s) checked).`);
|
|
276
|
+
}
|
|
277
|
+
else if (apply) {
|
|
278
|
+
lines.push(`[create-ailk] Copied ${result.applied.length} route(s):`);
|
|
279
|
+
lines.push(...result.missing.map(entry));
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
lines.push(`[create-ailk] ${result.missing.length} template route(s) missing:`);
|
|
283
|
+
lines.push(...result.missing.map(entry));
|
|
284
|
+
}
|
|
285
|
+
if (result.modified.length > 0) {
|
|
286
|
+
lines.push(`[create-ailk] ${result.modified.length} template route(s) modified locally (left as-is):`);
|
|
287
|
+
lines.push(...result.modified.map((r) => ` ${r.route} (surface: ${r.surface})`));
|
|
288
|
+
}
|
|
289
|
+
if (result.skippedSurfaces.length > 0) {
|
|
290
|
+
lines.push(`[create-ailk] Surfaces this site does not carry (skipped): ${result.skippedSurfaces.join(", ")}`);
|
|
291
|
+
}
|
|
292
|
+
// #5014 third clause: the routes/messages/lib a synced route needs to
|
|
293
|
+
// compile, reported (and, for lib files, applied) alongside the route.
|
|
294
|
+
if (result.missingDependencies.length > 0) {
|
|
295
|
+
lines.push(apply
|
|
296
|
+
? `[create-ailk] Also copied ${result.appliedDependencies.length} dependency file(s) the above route(s) import:`
|
|
297
|
+
: `[create-ailk] Also required — ${result.missingDependencies.length} file(s) the above route(s) import:`);
|
|
298
|
+
lines.push(...result.missingDependencies.map((dep) => ` ${dep}`));
|
|
299
|
+
}
|
|
300
|
+
if (result.missingMessageNamespaces.length > 0) {
|
|
301
|
+
lines.push(`[create-ailk] Also required — message namespace(s) not found in apps/web/messages/en.json (add manually, not auto-merged):`);
|
|
302
|
+
lines.push(...result.missingMessageNamespaces.map((ns) => ` ${ns}`));
|
|
303
|
+
}
|
|
304
|
+
if (result.missing.length > 0 && !apply) {
|
|
305
|
+
lines.push("Run `create-ailk sync-routes <target> --apply` to copy the missing routes.");
|
|
306
|
+
}
|
|
307
|
+
return lines.join("\n") + "\n";
|
|
308
|
+
}
|
|
309
|
+
export const SYNC_ROUTES_HELP = `create-ailk sync-routes — copy template routes an existing site is missing.
|
|
310
|
+
|
|
311
|
+
Usage:
|
|
312
|
+
create-ailk sync-routes [<target-dir>] [--apply]
|
|
313
|
+
|
|
314
|
+
Arguments:
|
|
315
|
+
<target-dir> An already-scaffolded repo (contains
|
|
316
|
+
architecture.yaml). Defaults to the current dir.
|
|
317
|
+
|
|
318
|
+
Options:
|
|
319
|
+
--apply Copy the missing route directories into the target.
|
|
320
|
+
Without it the command only reports: exit 1 when a
|
|
321
|
+
route is missing, 0 when in sync.
|
|
322
|
+
--help, -h Print this message.
|
|
323
|
+
|
|
324
|
+
Checks every core route plus the routes of each surface the site carries; a
|
|
325
|
+
surface gated off at scaffold time is skipped, not drift. A route the site has
|
|
326
|
+
changed locally is reported and never overwritten. Nothing is ever deleted.
|
|
327
|
+
`;
|
|
328
|
+
/**
|
|
329
|
+
* Parse the argv AFTER the `sync-routes` word. Strict `node:util` parseArgs,
|
|
330
|
+
* like `parseCliArgs`; at most one positional.
|
|
331
|
+
*/
|
|
332
|
+
export function parseSyncRoutesArgs(argv) {
|
|
333
|
+
const parsed = parseArgs({
|
|
334
|
+
args: argv,
|
|
335
|
+
strict: true,
|
|
336
|
+
allowPositionals: true,
|
|
337
|
+
options: {
|
|
338
|
+
apply: { type: "boolean", default: false },
|
|
339
|
+
help: { type: "boolean", default: false, short: "h" },
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
if (parsed.positionals.length > 1) {
|
|
343
|
+
throw new Error(`expected at most one target directory, got ${parsed.positionals.length}`);
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
target: parsed.positionals[0],
|
|
347
|
+
apply: parsed.values.apply === true,
|
|
348
|
+
help: parsed.values.help === true,
|
|
349
|
+
};
|
|
350
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ailk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
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",
|
|
@@ -11,20 +11,24 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
13
13
|
"templates",
|
|
14
|
+
"component-catalog.md",
|
|
14
15
|
"README.md",
|
|
15
16
|
"LICENSE"
|
|
16
17
|
],
|
|
17
18
|
"publishConfig": {
|
|
18
19
|
"access": "public"
|
|
19
20
|
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"tar": "^7.5.21"
|
|
23
|
+
},
|
|
20
24
|
"repository": {
|
|
21
25
|
"type": "git",
|
|
22
|
-
"url": "git+https://github.com/
|
|
26
|
+
"url": "git+https://github.com/working-theory-labs/ai-launch-kit.git",
|
|
23
27
|
"directory": "packages/create-ailk"
|
|
24
28
|
},
|
|
25
|
-
"homepage": "https://github.com/
|
|
29
|
+
"homepage": "https://github.com/working-theory-labs/ai-launch-kit/tree/main/packages/create-ailk#readme",
|
|
26
30
|
"bugs": {
|
|
27
|
-
"url": "https://github.com/
|
|
31
|
+
"url": "https://github.com/working-theory-labs/ai-launch-kit/issues"
|
|
28
32
|
},
|
|
29
33
|
"engines": {
|
|
30
34
|
"node": ">=20.0.0"
|
|
@@ -37,11 +41,14 @@
|
|
|
37
41
|
],
|
|
38
42
|
"license": "Apache-2.0",
|
|
39
43
|
"scripts": {
|
|
44
|
+
"lint": "tsx ../../scripts/lint-package.ts",
|
|
40
45
|
"build": "tsc -b",
|
|
41
46
|
"type-check": "tsc --noEmit",
|
|
42
47
|
"test": "tsc -b && node scripts/build-templates.mjs && jest",
|
|
43
48
|
"test:watch": "jest --watch",
|
|
44
49
|
"test:coverage": "jest --coverage",
|
|
45
|
-
"build-templates": "node scripts/build-templates.mjs"
|
|
50
|
+
"build-templates": "node scripts/build-templates.mjs",
|
|
51
|
+
"build-catalog": "node scripts/build-component-catalog.mjs",
|
|
52
|
+
"check-catalog": "node scripts/build-component-catalog.mjs --check"
|
|
46
53
|
}
|
|
47
54
|
}
|
|
@@ -19,7 +19,7 @@ other.
|
|
|
19
19
|
|
|
20
20
|
- Need to share code between apps? Find an existing `@working-theory/*` package
|
|
21
21
|
that fits, or open an issue upstream at
|
|
22
|
-
<https://github.com/
|
|
22
|
+
<https://github.com/working-theory-labs/ai-launch-kit> requesting a new one.
|
|
23
23
|
Do not vendor a copy.
|
|
24
24
|
- Need types shared across apps? Use `@working-theory/validation` (Zod schemas)
|
|
25
25
|
or `@working-theory/schema` (schema.org types).
|
|
@@ -55,7 +55,11 @@ better than a quiet violation.
|
|
|
55
55
|
|
|
56
56
|
These never appear in source code:
|
|
57
57
|
|
|
58
|
-
-
|
|
58
|
+
- Any Stripe key that is not a test-mode key. The runtime guard is an
|
|
59
|
+
ALLOW-LIST — it accepts `sk_test_`, `pk_test_`, `rk_test_` and refuses
|
|
60
|
+
everything else, so every live key is refused, restricted (`rk_live_`)
|
|
61
|
+
and future prefixes included, by being absent from the list rather than
|
|
62
|
+
by being named on a ban-list. Live keys live in your deployment
|
|
59
63
|
platform's secrets store, never in source files or `.env`.
|
|
60
64
|
- Direct vendor SDK imports outside the wrapper packages
|
|
61
65
|
(`import 'stripe'` outside `@working-theory/stripe-client`, etc.).
|
|
@@ -6,22 +6,22 @@ it and how it works.
|
|
|
6
6
|
|
|
7
7
|
The seven OSS skills below are the canonical AI Launch Kit workflows.
|
|
8
8
|
Their status reflects what's available at the upstream
|
|
9
|
-
<https://github.com/
|
|
9
|
+
<https://github.com/working-theory-labs/ai-launch-kit> repository today. Issue
|
|
10
10
|
numbers in the table refer to that upstream repo (the
|
|
11
|
-
`
|
|
11
|
+
`working-theory-labs/ai-launch-kit#N` form makes the link explicit), not your
|
|
12
12
|
local project's issues.
|
|
13
13
|
|
|
14
14
|
## Status
|
|
15
15
|
|
|
16
16
|
| Skill | Purpose | Status |
|
|
17
17
|
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------- |
|
|
18
|
-
| `suggest-site-pages` | Generic page-type suggestions by category | coming soon — issue #361 (
|
|
19
|
-
| `scaffold-page` | Generate a page with the appropriate schema.org type | coming soon — issue #362 (
|
|
20
|
-
| `scaffold-commerce` | Sell stuff: external store link or direct payments | coming soon — issue #363 (
|
|
21
|
-
| `scaffold-auth` | Wire up an auth flow against `@working-theory/auth-client` | coming soon — issue #364 (
|
|
22
|
-
| `audit-site` | Run `ailk audit` and explain the results | coming soon — issue #365 (
|
|
23
|
-
| `add-schema` | Add Product / Service / FAQ schema to an existing page | coming soon — issue #366 (
|
|
24
|
-
| `provision-config` | Generate `vercel.json` and environment templates | coming soon — issue #367 (
|
|
18
|
+
| `suggest-site-pages` | Generic page-type suggestions by category | coming soon — issue #361 (working-theory-labs/ai-launch-kit) |
|
|
19
|
+
| `scaffold-page` | Generate a page with the appropriate schema.org type | coming soon — issue #362 (working-theory-labs/ai-launch-kit) |
|
|
20
|
+
| `scaffold-commerce` | Sell stuff: external store link or direct payments | coming soon — issue #363 (working-theory-labs/ai-launch-kit) |
|
|
21
|
+
| `scaffold-auth` | Wire up an auth flow against `@working-theory/auth-client` | coming soon — issue #364 (working-theory-labs/ai-launch-kit) |
|
|
22
|
+
| `audit-site` | Run `ailk audit` and explain the results | coming soon — issue #365 (working-theory-labs/ai-launch-kit) |
|
|
23
|
+
| `add-schema` | Add Product / Service / FAQ schema to an existing page | coming soon — issue #366 (working-theory-labs/ai-launch-kit) |
|
|
24
|
+
| `provision-config` | Generate `vercel.json` and environment templates | coming soon — issue #367 (working-theory-labs/ai-launch-kit) |
|
|
25
25
|
|
|
26
26
|
## How a skill ships
|
|
27
27
|
|
|
@@ -170,8 +170,13 @@ new builder if not already imported.
|
|
|
170
170
|
|
|
171
171
|
### Step 6 — Type-aware classification
|
|
172
172
|
|
|
173
|
-
`references/schema-types.md` tags
|
|
174
|
-
|
|
173
|
+
`references/schema-types.md` tags the general schema.org vocabulary
|
|
174
|
+
it curates as **primary** or **supplementary**; the AILK page-type
|
|
175
|
+
registry (60 keys, all builder-backed in `@working-theory/schema`) is
|
|
176
|
+
listed separately in that file's "AILK page types" section and is
|
|
177
|
+
treated as **primary** for conflict handling — a registry page type
|
|
178
|
+
names what the whole page IS about, and replacing on same-type
|
|
179
|
+
conflict is the usual intent:
|
|
175
180
|
|
|
176
181
|
- **Primary** types are typically one-per-page: `HomePage`,
|
|
177
182
|
`AboutPage`, `BlogPosting`, `Product`, `Service`. A page rarely
|
|
@@ -235,22 +240,24 @@ If parse succeeds, print a closing summary:
|
|
|
235
240
|
|
|
236
241
|
## Type-by-name recognition
|
|
237
242
|
|
|
238
|
-
The skill recognizes all
|
|
243
|
+
The skill recognizes all 60 AILK page types in `@working-theory/schema` by
|
|
244
|
+
name, plus a smaller general schema.org vocabulary for non-registry types.
|
|
239
245
|
Common aliases (e.g., "FAQ" → `FAQPage`, "how-to" → `HowTo`,
|
|
240
246
|
"review" → `Review`) are handled in `references/schema-types.md`.
|
|
241
247
|
If the consumer asks for a type not in the catalog, surface and
|
|
242
248
|
ask:
|
|
243
249
|
|
|
244
|
-
> "I don't see `<requested type>` in the v1 schema catalog. The
|
|
250
|
+
> "I don't see `<requested type>` in the v1 schema catalog. The
|
|
245
251
|
> recognized types are listed in `references/schema-types.md` —
|
|
246
252
|
> closest matches are `<X>` and `<Y>`. Use one of those, or hand-
|
|
247
253
|
> author the JSON-LD inline if you need a less-common type."
|
|
248
254
|
|
|
249
255
|
## References
|
|
250
256
|
|
|
251
|
-
- `references/schema-types.md` — the
|
|
252
|
-
`@working-theory/schema`,
|
|
253
|
-
human-friendly
|
|
257
|
+
- `references/schema-types.md` — the 60 registry-backed AILK page types
|
|
258
|
+
from `@working-theory/schema`, plus a smaller general schema.org
|
|
259
|
+
vocabulary tagged primary or supplementary, with human-friendly
|
|
260
|
+
aliases.
|
|
254
261
|
- `references/file-finding.md` — slug-to-file resolution rules
|
|
255
262
|
(App Router + MDX).
|
|
256
263
|
- `references/conflict-handling.md` — full decision tree for
|
|
@@ -100,14 +100,117 @@ these by name; conflict handling defaults to **supplementary**
|
|
|
100
100
|
| `ScholarlyArticle` | _consumer-defined_ | "scholarly article", "paper" |
|
|
101
101
|
| `LegislativeBuilding` | _consumer-defined_ | _rare, government use_ |
|
|
102
102
|
|
|
103
|
+
## AILK page types (registry-backed — 60 keys, one builder each)
|
|
104
|
+
|
|
105
|
+
Every key below is an entry in `@working-theory/schema`'s page-type registry
|
|
106
|
+
(`packages/schema/src/registry/entries.ts`) and has a real, exported builder
|
|
107
|
+
reachable via `buildJsonLd({ type: '<Key>', ... })` — this is the complete
|
|
108
|
+
list of scaffoldable AILK page types, as opposed to the smaller general
|
|
109
|
+
schema.org vocabulary tables above (some of which is still
|
|
110
|
+
`_consumer-defined_`, i.e. not yet builder-backed). Several keys share one
|
|
111
|
+
`@type` (e.g. `PrivacyPage` / `TermsPage` / `LandingPage` / `ThankYouPage` all
|
|
112
|
+
emit `WebPage`) — the registry has 60 entries but only 24 distinct `@type`
|
|
113
|
+
values. Re-derive with `pnpm page-type-counts`
|
|
114
|
+
(`scripts/component/page-type-counts.ts` in the `ai-launch-kit-internal`
|
|
115
|
+
source repo) before hand-editing this table.
|
|
116
|
+
|
|
117
|
+
### Core (15)
|
|
118
|
+
|
|
119
|
+
| Key | `@type` |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| `HomePage` | `HomePage` |
|
|
122
|
+
| `AboutPage` | `AboutPage` |
|
|
123
|
+
| `ContactPage` | `ContactPage` |
|
|
124
|
+
| `PrivacyPage` | `WebPage` |
|
|
125
|
+
| `TermsPage` | `WebPage` |
|
|
126
|
+
| `LandingPage` | `WebPage` |
|
|
127
|
+
| `ThankYouPage` | `WebPage` |
|
|
128
|
+
| `BookCall` | `WebPage` |
|
|
129
|
+
| `NewsletterSignup` | `WebPage` |
|
|
130
|
+
| `DemoRequest` | `WebPage` |
|
|
131
|
+
| `TrialSignup` | `WebPage` |
|
|
132
|
+
| `Waitlist` | `WebPage` |
|
|
133
|
+
| `Assessment` | `WebApplication` |
|
|
134
|
+
| `Calculator` | `WebApplication` |
|
|
135
|
+
| `CampaignLP` | `WebPage` |
|
|
136
|
+
|
|
137
|
+
### Identity (4)
|
|
138
|
+
|
|
139
|
+
`Organization` / `Person` / `BreadcrumbList` / `ContactPoint` — see the
|
|
140
|
+
[Identity types](#identity-types-one-site-wide-emit-on-home-or-in-layout)
|
|
141
|
+
table above; all four are registry-backed.
|
|
142
|
+
|
|
143
|
+
### Canonical-List (17)
|
|
144
|
+
|
|
145
|
+
| Key | `@type` |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `ServicesList` | `CollectionPage` |
|
|
148
|
+
| `ProductsList` | `CollectionPage` |
|
|
149
|
+
| `ProjectsList` | `CollectionPage` |
|
|
150
|
+
| `FAQPage` | `FAQPage` |
|
|
151
|
+
| `CareersList` | `CollectionPage` |
|
|
152
|
+
| `UseCasesList` | `CollectionPage` |
|
|
153
|
+
| `TestimonialsList` | `CollectionPage` |
|
|
154
|
+
| `ClientsList` | `CollectionPage` |
|
|
155
|
+
| `DownloadsList` | `CollectionPage` |
|
|
156
|
+
| `EventsList` | `CollectionPage` |
|
|
157
|
+
| `CoursesList` | `CollectionPage` |
|
|
158
|
+
| `TeamList` | `CollectionPage` |
|
|
159
|
+
| `PartnersList` | `CollectionPage` |
|
|
160
|
+
| `IntegrationsList` | `CollectionPage` |
|
|
161
|
+
| `GlossaryList` | `CollectionPage` |
|
|
162
|
+
| `LocationsList` | `CollectionPage` |
|
|
163
|
+
| `DocsList` | `CollectionPage` |
|
|
164
|
+
|
|
165
|
+
### Canonical-Detail (14)
|
|
166
|
+
|
|
167
|
+
| Key | `@type` |
|
|
168
|
+
| --- | --- |
|
|
169
|
+
| `Service` | `Service` |
|
|
170
|
+
| `Product` | `Product` |
|
|
171
|
+
| `Project` | `CreativeWork` |
|
|
172
|
+
| `Event` | `Event` |
|
|
173
|
+
| `Course` | `Course` |
|
|
174
|
+
| `TeamMember` | `ProfilePage` |
|
|
175
|
+
| `Partner` | `AboutPage` |
|
|
176
|
+
| `Integration` | `WebPage` |
|
|
177
|
+
| `JobPosting` | `JobPosting` |
|
|
178
|
+
| `SoftwareProduct` | `WebPage` |
|
|
179
|
+
| `Location` | `Place` |
|
|
180
|
+
| `ServiceAreaPage` | `WebPage` |
|
|
181
|
+
| `UseCase` | `WebPage` |
|
|
182
|
+
| `Pricing` | `WebPage` |
|
|
183
|
+
|
|
184
|
+
### Editorial-List (3)
|
|
185
|
+
|
|
186
|
+
| Key | `@type` |
|
|
187
|
+
| --- | --- |
|
|
188
|
+
| `BlogList` | `Blog` |
|
|
189
|
+
| `ResourcesHub` | `CollectionPage` |
|
|
190
|
+
| `CaseStudiesList` | `CollectionPage` |
|
|
191
|
+
|
|
192
|
+
### Editorial-Detail (7)
|
|
193
|
+
|
|
194
|
+
| Key | `@type` |
|
|
195
|
+
| --- | --- |
|
|
196
|
+
| `BlogPosting` | `BlogPosting` |
|
|
197
|
+
| `CaseStudy` | `Article` |
|
|
198
|
+
| `HowTo` | `HowTo` |
|
|
199
|
+
| `Whitepaper` | `Article` |
|
|
200
|
+
| `ResourceDetail` | `Article` |
|
|
201
|
+
| `TechArticle` | `TechArticle` |
|
|
202
|
+
| `DocsDetail` | `TechArticle` |
|
|
203
|
+
|
|
103
204
|
## Total
|
|
104
205
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
the
|
|
110
|
-
|
|
206
|
+
**Two distinct counts, not one.** The AILK page-type registry — the types
|
|
207
|
+
`add-schema` can scaffold with a real builder — has **60 keys** (24 distinct
|
|
208
|
+
`@type` values; see the family tables above). The general schema.org
|
|
209
|
+
vocabulary tables earlier in this file are a separate, smaller, hand-curated
|
|
210
|
+
list the skill also recognizes by name for non-registry types; several of
|
|
211
|
+
those are still `_consumer-defined_` because `@working-theory/schema` hasn't
|
|
212
|
+
shipped a typed builder for them yet — for those, the skill emits the JSON-LD
|
|
213
|
+
as an inline literal with a comment noting the upstream issue.
|
|
111
214
|
|
|
112
215
|
## When `@working-theory/schema` doesn't yet export the builder
|
|
113
216
|
|
|
@@ -66,7 +66,7 @@ platform, respond:
|
|
|
66
66
|
|
|
67
67
|
> "`provision-config` is Vercel-only at v1. Netlify / Cloudflare /
|
|
68
68
|
> Render / Fly / self-host support are tracked at the upstream repo —
|
|
69
|
-
> file an issue at <https://github.com/
|
|
69
|
+
> file an issue at <https://github.com/working-theory-labs/ai-launch-kit/issues>
|
|
70
70
|
> if your platform is missing.
|
|
71
71
|
>
|
|
72
72
|
> Cloudflare is deferred entirely (deploy target + KV/D1/R2 data
|