create-ailk 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -14
- package/component-catalog.json +735 -95
- package/component-catalog.md +13 -7
- package/dist/add-module-core.d.ts +22 -0
- package/dist/add-module-core.js +50 -0
- package/dist/add-module.d.ts +89 -0
- package/dist/add-module.js +334 -0
- package/dist/category-profile.d.ts +126 -0
- package/dist/category-profile.js +262 -0
- package/dist/cli.js +89 -29
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -1
- package/dist/lib/extract-module-bundle.d.ts +56 -1
- package/dist/lib/extract-module-bundle.js +170 -14
- package/dist/lib/license-key-files.d.ts +15 -0
- package/dist/lib/license-key-files.js +102 -0
- package/dist/lib/module-license-gate.d.ts +79 -0
- package/dist/lib/module-license-gate.js +160 -12
- package/dist/lib/module-tier.d.ts +45 -16
- package/dist/lib/module-tier.js +76 -0
- package/dist/lib/pro-callout.d.ts +16 -10
- package/dist/lib/pro-callout.js +34 -3
- package/dist/license-set.d.ts +34 -0
- package/dist/license-set.js +194 -0
- package/dist/module-architecture.d.ts +20 -0
- package/dist/module-architecture.js +77 -19
- package/dist/modules/commerce/0.6.1.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.1.tar.gz +0 -0
- package/dist/modules/marketing-site/0.6.1.tar.gz +0 -0
- package/dist/modules/minimalism-site/0.6.1.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.1.tar.gz +0 -0
- package/dist/modules/saas-product/0.6.1.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.1.tar.gz +0 -0
- package/dist/modules/simple-service/0.6.1.tar.gz +0 -0
- package/dist/modules/workspace/0.6.1.tar.gz +0 -0
- package/dist/parse-args.d.ts +85 -10
- package/dist/parse-args.js +227 -15
- package/dist/programmatic.d.ts +81 -5
- package/dist/programmatic.js +291 -32
- package/dist/site-chrome.d.ts +18 -7
- package/dist/site-chrome.js +32 -14
- package/dist/site-roster.d.ts +127 -0
- package/dist/site-roster.js +499 -0
- package/dist/starter-grid.d.ts +216 -0
- package/dist/starter-grid.js +449 -0
- package/dist/surfaces.d.ts +20 -7
- package/dist/surfaces.js +204 -24
- package/dist/sync-routes.d.ts +9 -0
- package/dist/sync-routes.js +2 -2
- package/dist/template-manifest.d.ts +94 -19
- package/dist/template-manifest.js +170 -289
- package/dist/template-names.d.ts +14 -12
- package/dist/template-names.js +13 -17
- package/package.json +6 -4
- package/site-templates/_base/content/en/BookCall/book-call.mdx +52 -0
- package/site-templates/_base/content/en/Feature/feature-1.mdx +69 -0
- package/site-templates/_base/content/en/Feature/feature-2.mdx +69 -0
- package/site-templates/_base/content/en/Feature/feature-3.mdx +69 -0
- package/site-templates/_base/content/en/FeaturesList/features.mdx +91 -0
- package/site-templates/_base/content/en/GlossaryList/glossary.mdx +65 -0
- package/site-templates/_base/content/en/NewsletterSignup/newsletter.mdx +67 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-four.mdx +105 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-one.mdx +34 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-three.mdx +94 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-two.mdx +45 -0
- package/site-templates/_base/content/en/PortfolioList/portfolio.mdx +169 -0
- package/site-templates/_base/content/en/Pricing/pricing.mdx +71 -62
- package/site-templates/_base/content/en/PrivacyPage/privacy.mdx +17 -3
- package/site-templates/_base/content/en/TermsPage/terms.mdx +2 -3
- package/site-templates/_base/content/en/UseCase/persona-1.mdx +69 -0
- package/site-templates/_base/content/en/UseCase/persona-2.mdx +69 -0
- package/site-templates/_base/content/en/UseCase/persona-3.mdx +69 -0
- package/site-templates/designs/minimalism/DESIGN.md +162 -0
- package/site-templates/designs/standard/DESIGN.md +167 -0
- package/site-templates/marketing-site/DESIGN.md +59 -40
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +376 -57
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +230 -90
- package/site-templates/marketing-site/ailk-template.json +1 -0
- package/site-templates/marketing-site-free/DESIGN.md +59 -40
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +323 -63
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +323 -113
- package/site-templates/marketing-site-free/ailk-template.json +3 -2
- package/site-templates/marketing-site-free/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +199 -0
- package/site-templates/minimalism-site/DESIGN.md +54 -40
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +246 -19
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +173 -51
- package/site-templates/minimalism-site/ailk-template.json +3 -2
- package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +3 -37
- package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/saas-product/DESIGN.md +59 -40
- package/site-templates/saas-product/TEMPLATE-MANIFEST.md +9 -1
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +369 -0
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +302 -0
- package/site-templates/shapes/local-business-service/ailk-template.json +10 -0
- package/site-templates/{simple-service → shapes/local-business-service}/content/en/AboutPage/about.mdx +4 -4
- package/site-templates/shapes/local-business-service/content/en/HomePage/home.mdx +70 -0
- package/site-templates/shapes/local-business-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/local-business-service/content/en/PortfolioList/portfolio.mdx +171 -0
- package/site-templates/shapes/local-business-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/shapes/local-business-service/content/en/Service/first-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/Service/second-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/Service/third-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/ServicesList/services.mdx +61 -0
- package/site-templates/shapes/local-business-service/provenance.json +4 -0
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +362 -0
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +300 -0
- package/site-templates/shapes/organization-service/ailk-template.json +10 -0
- package/site-templates/shapes/organization-service/content/en/AboutPage/about.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/HomePage/home.mdx +85 -0
- package/site-templates/shapes/organization-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/organization-service/content/en/PortfolioList/portfolio.mdx +171 -0
- package/site-templates/shapes/organization-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/shapes/organization-service/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/ServicesList/services.mdx +72 -0
- package/site-templates/shapes/organization-service/provenance.json +4 -0
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +369 -0
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +299 -0
- package/site-templates/shapes/person-service/ailk-template.json +10 -0
- package/site-templates/shapes/person-service/content/_site.mdx +85 -0
- package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +39 -0
- package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +97 -0
- package/site-templates/shapes/person-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +169 -0
- package/site-templates/shapes/person-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/shapes/person-service/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/shapes/person-service/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/shapes/person-service/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/{simple-service → shapes/person-service}/content/en/ServicesList/services.mdx +16 -16
- package/site-templates/shapes/person-service/provenance.json +4 -0
- package/templates/.claude/settings.json +15 -0
- package/templates/.claude/skills/README.md +10 -9
- package/templates/.claude/skills/{scaffold-auth → add-auth}/SKILL.md +7 -7
- package/templates/.claude/skills/{scaffold-auth → add-auth}/references/env-vars.md +2 -2
- package/templates/.claude/skills/{scaffold-auth → add-auth}/references/oauth-app-setup.md +3 -3
- package/templates/.claude/skills/{scaffold-page → add-page}/SKILL.md +76 -62
- package/templates/.claude/skills/add-page/references/page-types.md +115 -0
- package/templates/.claude/skills/{scaffold-page → add-page}/templates/content.mdx.tmpl +4 -4
- package/templates/.claude/skills/{scaffold-page → add-page}/templates/route.tsx.tmpl +1 -1
- package/templates/.claude/skills/{audit-site → check-site}/SKILL.md +16 -17
- package/templates/.claude/skills/{audit-site → check-site}/references/common-errors.md +3 -3
- package/templates/.claude/skills/{audit-site → check-site}/references/findings-glossary.md +16 -14
- package/templates/.claude/skills/{audit-site → check-site}/references/severity-levels.md +1 -1
- package/templates/.claude/skills/fill-page/SKILL.md +180 -0
- package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +80 -0
- package/templates/.claude/skills/fill-page/references/section-sources.md +41 -0
- package/templates/.claude/skills/setup-database/SKILL.md +156 -0
- package/templates/.claude/skills/setup-database/scripts/verify-inbox.ts +154 -0
- package/templates/.claude/skills/{provision-config → setup-deploy}/SKILL.md +73 -41
- package/templates/.claude/skills/{provision-config → setup-deploy}/references/env-vars-template.md +21 -30
- package/templates/.claude/skills/setup-deploy/references/runbook-template.md +204 -0
- package/templates/.claude/skills/{provision-config → setup-deploy}/references/vercel-json-template.md +1 -1
- package/templates/.claude/skills/upgrade-plan/SKILL.md +117 -0
- package/templates/.claude/skills/upgrade-plan/references/options.md +24 -0
- package/templates/.claude/skills/upgrade-plan/scripts/upgrade-plan.ts +527 -0
- package/templates/.github/workflows/ci.yml +5 -0
- package/templates/CLAUDE.md +8 -2
- package/templates/DESIGN.md +56 -44
- package/templates/README.md +116 -46
- package/templates/apps/api/.env.example +2 -1
- package/templates/apps/api/CLAUDE.md +3 -2
- package/templates/apps/api/package.json +1 -1
- package/templates/apps/api/src/config/__tests__/index.test.ts +146 -10
- package/templates/apps/api/src/config/index.ts +46 -14
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +30 -0
- package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +96 -0
- package/templates/apps/api/src/lib/lead-capture-store.ts +12 -0
- package/templates/apps/api/src/lib/lead-delivery.ts +52 -0
- package/templates/apps/api/src/lib/license-key-store.ts +45 -0
- package/templates/apps/api/src/lib/site.ts +5 -3
- package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +97 -0
- package/templates/apps/api/src/middleware/auth.ts +9 -0
- package/templates/apps/api/src/openapi/spec.ts +63 -12
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +127 -5
- package/templates/apps/api/src/routes/content/get-page.ts +86 -2
- package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +88 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +100 -0
- package/templates/apps/api/src/routes/leads/index.ts +46 -1
- package/templates/apps/api/src/server.ts +13 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +194 -0
- package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +124 -0
- package/templates/apps/api/src/services/lead-routing.ts +140 -30
- package/templates/apps/api/src/services/leads-inbox.ts +48 -11
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +75 -1
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +57 -9
- package/templates/apps/mcp/__tests__/parity.test.ts +5 -4
- package/templates/apps/mcp/package.json +2 -1
- package/templates/apps/mcp/src/index.ts +7 -0
- package/templates/apps/mcp/src/lib/audit-single-page.ts +36 -10
- package/templates/apps/mcp/src/lib/license-key-store.ts +45 -0
- package/templates/apps/mcp/src/tools/create_project.ts +21 -6
- package/templates/apps/web/__tests__/setup.ts +18 -0
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +10 -2
- package/templates/apps/web/app/[locale]/(auth)/layout.tsx +2 -2
- package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +10 -4
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +22 -14
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +26 -18
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +12 -4
- package/templates/apps/web/app/[locale]/[slug]/__tests__/page.test.tsx +35 -4
- package/templates/apps/web/app/[locale]/[slug]/page.tsx +49 -9
- package/templates/apps/web/app/[locale]/book-a-call/page.tsx +50 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +3 -4
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +67 -29
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +94 -11
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-text.test.ts +32 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +129 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +228 -86
- package/templates/apps/web/app/[locale]/contact/contact-form-text.ts +50 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +73 -20
- package/templates/apps/web/app/[locale]/contact/page.tsx +115 -7
- package/templates/apps/web/app/[locale]/contact/site-contact-email.ts +54 -0
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +3 -4
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +4 -5
- package/templates/apps/web/app/[locale]/features/[slug]/page.tsx +64 -0
- package/templates/apps/web/app/[locale]/features/page.tsx +52 -0
- package/templates/apps/web/app/[locale]/glossary/page.tsx +50 -0
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/how-to/page.tsx +25 -15
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/layout.tsx +146 -52
- package/templates/apps/web/app/[locale]/newsletter/__tests__/newsletter.actions.test.ts +75 -0
- package/templates/apps/web/app/[locale]/newsletter/__tests__/page.test.tsx +163 -0
- package/templates/apps/web/app/[locale]/newsletter/newsletter.actions.ts +66 -0
- package/templates/apps/web/app/[locale]/newsletter/page.tsx +142 -0
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +59 -0
- package/templates/apps/web/app/[locale]/portfolio/page.tsx +49 -0
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +4 -5
- package/templates/apps/web/app/[locale]/{cancellation → purchase-policy}/page.tsx +15 -10
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +4 -5
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +14 -1
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/software/page.tsx +25 -15
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/tech-articles/page.tsx +25 -15
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +3 -4
- package/templates/apps/web/app/[locale]/use-cases/[slug]/page.tsx +63 -0
- package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +3 -4
- package/templates/apps/web/app/[locale]/use-cases/page.tsx +15 -2
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/whitepapers/page.tsx +25 -15
- package/templates/apps/web/app/error-fallback.tsx +17 -45
- package/templates/apps/web/app/not-found.tsx +14 -38
- package/templates/apps/web/app/og/route.tsx +6 -0
- package/templates/apps/web/eslint.config.mjs +3 -0
- package/templates/apps/web/instrumentation.ts +14 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +38 -0
- package/templates/apps/web/lib/license-key-store.ts +52 -0
- package/templates/apps/web/lib/nav-config.ts +82 -18
- package/templates/apps/web/lib/prisma-for-auth.ts +9 -6
- package/templates/apps/web/lib/site-brand.tsx +1 -1
- package/templates/apps/web/lib/site-chrome.ts +3 -3
- package/templates/apps/web/lib/site-identity.ts +148 -0
- package/templates/apps/web/lib/site-theme.ts +11 -0
- package/templates/apps/web/messages/en.json +78 -37
- package/templates/apps/web/public/android-chrome-192x192.png +0 -0
- package/templates/apps/web/public/android-chrome-512x512.png +0 -0
- package/templates/apps/web/public/apple-touch-icon.png +0 -0
- package/templates/apps/web/public/favicon-16x16.png +0 -0
- package/templates/apps/web/public/favicon-32x32.png +0 -0
- package/templates/apps/web/public/favicon.ico +0 -0
- package/templates/apps/web/public/favicon.svg +3 -3
- package/templates/apps/web/public/logomark.svg +6 -3
- package/templates/apps/web/public/logos/ai-launch-kit-light.svg +4 -0
- package/templates/apps/web/public/logos/ai-launch-kit.svg +4 -0
- package/templates/apps/web/public/logos/atomic-agent-light.svg +4 -0
- package/templates/apps/web/public/logos/atomic-agent.svg +4 -0
- package/templates/apps/web/public/logos/salessmyth-light.svg +4 -0
- package/templates/apps/web/public/logos/salessmyth.svg +4 -0
- package/templates/apps/web/public/site.webmanifest +4 -4
- package/templates/apps/web/public/wordmark-light.svg +4 -0
- package/templates/apps/web/public/wordmark.svg +3 -3
- package/templates/apps/web/security-headers.config.ts +5 -1
- package/templates/content/_site.mdx +25 -0
- package/templates/content/en/AboutPage/about.mdx +150 -144
- package/templates/content/en/BlogList/blog.mdx +126 -0
- package/templates/content/en/ContactPage/contact.mdx +21 -92
- package/templates/content/en/FAQPage/faq.mdx +86 -57
- package/templates/content/en/HomePage/home.mdx +268 -217
- package/templates/content/en/PurchasePolicyPage/purchase-policy.mdx +181 -0
- package/templates/content/en/UseCasesList/use-cases.mdx +170 -0
- package/templates/database/CHANGELOG.md +14 -0
- package/templates/database/package.json +1 -1
- package/templates/package.json +3 -1
- package/templates/tools/lint-architecture.ts +315 -0
- package/templates/tools/tsconfig.json +14 -0
- package/versions.json +33 -33
- package/site-templates/simple-service/DESIGN.md +0 -148
- package/site-templates/simple-service/TEMPLATE-MANIFEST.json +0 -240
- package/site-templates/simple-service/TEMPLATE-MANIFEST.md +0 -278
- package/site-templates/simple-service/ailk-template.json +0 -10
- package/site-templates/simple-service/content/en/ContactPage/contact.mdx +0 -67
- package/site-templates/simple-service/content/en/FAQPage/faq.mdx +0 -56
- package/site-templates/simple-service/content/en/HomePage/home.mdx +0 -85
- package/site-templates/simple-service/content/en/Service/landscape-design.mdx +0 -40
- package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +0 -40
- package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +0 -40
- package/site-templates/simple-service/provenance.json +0 -4
- package/templates/.claude/skills/add-schema/SKILL.md +0 -277
- package/templates/.claude/skills/add-schema/references/conflict-handling.md +0 -200
- package/templates/.claude/skills/add-schema/references/file-finding.md +0 -123
- package/templates/.claude/skills/add-schema/references/schema-types.md +0 -234
- package/templates/.claude/skills/provision-config/references/runbook-template.md +0 -248
- package/templates/.claude/skills/scaffold-page/references/page-types.md +0 -169
- package/templates/.claude/skills/suggest-site-pages/SKILL.md +0 -242
- package/templates/.claude/skills/suggest-site-pages/references/categories.md +0 -287
- package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +0 -150
- package/templates/apps/web/app/[locale]/returns/page.tsx +0 -44
- package/templates/apps/web/app/[locale]/shipping/page.tsx +0 -44
- package/templates/content/en/CancellationPolicyPage/cancellation.mdx +0 -108
- package/templates/content/en/LandingPage/blog.mdx +0 -83
- package/templates/content/en/LandingPage/features.mdx +0 -103
- package/templates/content/en/LandingPage/how-it-works.mdx +0 -143
- package/templates/content/en/ReturnsPolicyPage/returns.mdx +0 -108
- package/templates/content/en/ShippingPolicyPage/shipping.mdx +0 -108
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { FetchModuleError, fetchModule } from "./fetch-module.js";
|
|
2
|
+
import { assertLicenseKeyShape } from "./license-key-files.js";
|
|
3
|
+
import { ADD_ONS, LEVEL_LABEL, LEVEL_MODULES, OPT_IN_MODULES, PAID_MODULES, classifyModules, composeModuleSet, levelOf, } from "./module-tier.js";
|
|
2
4
|
/**
|
|
3
5
|
* Where a refused run sends the buyer. `/pricing`, not `/pro`: there is no
|
|
4
6
|
* `/pro` route and there will not be one (#6439, operator decision OD-2) —
|
|
@@ -17,6 +19,53 @@ export class LicenseRequiredError extends Error {
|
|
|
17
19
|
this.name = "LicenseRequiredError";
|
|
18
20
|
}
|
|
19
21
|
}
|
|
22
|
+
/** Designs every level renders (#6760 D1). Anything else in `STARTER_DESIGNS` is Pro and up. */
|
|
23
|
+
export const FREE_DESIGNS = ["standard"];
|
|
24
|
+
/** Levels that render any design (#6760 D1) — an allow-list: an unknown level is not in it. */
|
|
25
|
+
export const DESIGN_LEVELS = ["pro", "pro-plus"];
|
|
26
|
+
/**
|
|
27
|
+
* Refuse a non-`standard` design at a level below Pro (#6760 D1, D6). Pure
|
|
28
|
+
* and synchronous — takes the level `deriveLevel`/`resolveModuleSet` already
|
|
29
|
+
* resolved; never reads a key or derives a level itself (D2, fail-closed:
|
|
30
|
+
* both checks below are allow-lists, so an unrecognized `level` refuses
|
|
31
|
+
* rather than granting it).
|
|
32
|
+
*/
|
|
33
|
+
export function assertDesignAllowed(design, level) {
|
|
34
|
+
if (design === undefined || FREE_DESIGNS.includes(design))
|
|
35
|
+
return;
|
|
36
|
+
if (DESIGN_LEVELS.includes(level))
|
|
37
|
+
return;
|
|
38
|
+
throw new LicenseRequiredError(`design "${design}" is a Pro feature — this run's licence level is ${LEVEL_LABEL[level]}; pass --license <key> or set AILK_LICENSE_KEY with a Pro or Pro Plus key → ${CONVERSION_HINT_URL}`);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The message phrase for one module (D5): what level includes it, or that it
|
|
42
|
+
* is an add-on. Pure — derived from `levelOf`, never from the current run's
|
|
43
|
+
* own derived level.
|
|
44
|
+
*/
|
|
45
|
+
export function levelPhrase(m) {
|
|
46
|
+
const level = levelOf(m);
|
|
47
|
+
if (level === "add-on") {
|
|
48
|
+
return `"${m}" is an add-on, bought on top of Pro or Pro Plus`;
|
|
49
|
+
}
|
|
50
|
+
if (level === "free") {
|
|
51
|
+
return `"${m}" is included at ${LEVEL_LABEL.free}`;
|
|
52
|
+
}
|
|
53
|
+
return `"${m}" is included at ${LEVEL_LABEL[level]}`;
|
|
54
|
+
}
|
|
55
|
+
/** M1 / M1t (D5): the no-key refusal, with or without a named template. */
|
|
56
|
+
function noKeyMessage(paidModules, templateName) {
|
|
57
|
+
const phrases = paidModules.map((m) => levelPhrase(m)).join("; ");
|
|
58
|
+
const intro = templateName !== undefined
|
|
59
|
+
? `template "${templateName}" needs a licence: ${phrases}`
|
|
60
|
+
: `no licence key, so this is a Free scaffold: ${phrases}`;
|
|
61
|
+
return `${intro} — set AILK_LICENSE_KEY first → ${CONVERSION_HINT_URL}`;
|
|
62
|
+
}
|
|
63
|
+
/** M2 (D5): a key the registry rejected for one module. */
|
|
64
|
+
function licenseErrorMessage(err, moduleName, templateName, level) {
|
|
65
|
+
const templateSuffix = templateName !== undefined ? ` (required by template "${templateName}")` : "";
|
|
66
|
+
const levelSuffix = level !== undefined ? ` — your licence is at ${LEVEL_LABEL[level]}` : "";
|
|
67
|
+
return `${err.message}; ${levelPhrase(moduleName)}${templateSuffix}${levelSuffix} → ${CONVERSION_HINT_URL}`;
|
|
68
|
+
}
|
|
20
69
|
/**
|
|
21
70
|
* Resolve every requested paid module to its fetched bundle bytes, or throw
|
|
22
71
|
* `LicenseRequiredError` naming exactly why the run cannot proceed. Never
|
|
@@ -33,8 +82,11 @@ export async function resolvePaidModules(options) {
|
|
|
33
82
|
}
|
|
34
83
|
const token = options.licenseKey ?? process.env["AILK_LICENSE_KEY"];
|
|
35
84
|
if (token === undefined || token.length === 0) {
|
|
36
|
-
throw new LicenseRequiredError(
|
|
85
|
+
throw new LicenseRequiredError(noKeyMessage(paidModules, options.templateName));
|
|
37
86
|
}
|
|
87
|
+
// SEC-2 — the `--license` flag and the env var are validated alike,
|
|
88
|
+
// whichever source this token came from, before it reaches a request.
|
|
89
|
+
assertLicenseKeyShape(token);
|
|
38
90
|
const bundles = new Map();
|
|
39
91
|
for (const moduleName of paidModules) {
|
|
40
92
|
try {
|
|
@@ -55,11 +107,9 @@ export async function resolvePaidModules(options) {
|
|
|
55
107
|
if (err instanceof FetchModuleError) {
|
|
56
108
|
if (err.isLicenseError) {
|
|
57
109
|
// DD5 row 2: the mapped 401/403 already names the module the key
|
|
58
|
-
// does not cover; the template
|
|
59
|
-
// WHICH of the things they asked for needs it.
|
|
60
|
-
throw new LicenseRequiredError(options.templateName
|
|
61
|
-
? `${err.message}, required by template "${options.templateName}" → ${CONVERSION_HINT_URL}`
|
|
62
|
-
: `${err.message} → ${CONVERSION_HINT_URL}`);
|
|
110
|
+
// does not cover; the template and level are appended so the buyer
|
|
111
|
+
// can see WHICH of the things they asked for needs it.
|
|
112
|
+
throw new LicenseRequiredError(licenseErrorMessage(err, moduleName, options.templateName, options.level));
|
|
63
113
|
}
|
|
64
114
|
// Not a license-gating signal (e.g. 404 "not yet available", or the
|
|
65
115
|
// registry unreachable) — a generic failure, not the honest-denial
|
|
@@ -72,10 +122,108 @@ export async function resolvePaidModules(options) {
|
|
|
72
122
|
}
|
|
73
123
|
return bundles;
|
|
74
124
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
?
|
|
79
|
-
:
|
|
80
|
-
|
|
125
|
+
function forward(options) {
|
|
126
|
+
return {
|
|
127
|
+
...(options.registryUrl !== undefined ? { registryUrl: options.registryUrl } : {}),
|
|
128
|
+
...(options.version !== undefined ? { version: options.version } : {}),
|
|
129
|
+
...(options.fetchImpl !== undefined ? { fetchImpl: options.fetchImpl } : {}),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Derive the key's level from what the registry actually answers (D4) — the
|
|
134
|
+
* level only chooses which modules to ASK FOR; every byte is still
|
|
135
|
+
* authorized by the registry per module. Nothing client-side is an
|
|
136
|
+
* entitlement claim: the JWT is never parsed here.
|
|
137
|
+
*
|
|
138
|
+
* No key ⟹ `"free"`, zero network. A present key is shape-checked first,
|
|
139
|
+
* whichever source it came from (SEC-2). Then: probe every paid member of
|
|
140
|
+
* `LEVEL_MODULES.pro`, in order — a licence error on any of them is refused
|
|
141
|
+
* (a key that does not unlock all of Pro is not silently downgraded); any
|
|
142
|
+
* other failure (404, 5xx, unreachable) is wrapped so the caller sees it
|
|
143
|
+
* could not determine the level, and is told the escape hatch (`--modules`).
|
|
144
|
+
* Then probe `multi-tenant` (what Pro Plus adds beyond Pro): a licence error
|
|
145
|
+
* there is the expected "this key is Pro, not Pro Plus" answer, not a
|
|
146
|
+
* refusal.
|
|
147
|
+
*/
|
|
148
|
+
export async function deriveLevel(options) {
|
|
149
|
+
const token = options.licenseKey ?? process.env["AILK_LICENSE_KEY"];
|
|
150
|
+
if (token === undefined || token.length === 0) {
|
|
151
|
+
return { level: "free", bundles: new Map() };
|
|
152
|
+
}
|
|
153
|
+
assertLicenseKeyShape(token);
|
|
154
|
+
const bundles = new Map();
|
|
155
|
+
const proModules = LEVEL_MODULES.pro.filter((m) => PAID_MODULES.includes(m));
|
|
156
|
+
for (const moduleName of proModules) {
|
|
157
|
+
try {
|
|
158
|
+
const bytes = await fetchModule({ moduleName, token, ...forward(options) });
|
|
159
|
+
bundles.set(moduleName, bytes);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
if (err instanceof FetchModuleError) {
|
|
163
|
+
if (err.isLicenseError) {
|
|
164
|
+
throw new LicenseRequiredError(licenseErrorMessage(err, moduleName));
|
|
165
|
+
}
|
|
166
|
+
throw new FetchModuleError(`could not determine your licence level: ${err.message} — name the modules you want with --modules`);
|
|
167
|
+
}
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const bytes = await fetchModule({
|
|
173
|
+
moduleName: "multi-tenant",
|
|
174
|
+
token,
|
|
175
|
+
...forward(options),
|
|
176
|
+
});
|
|
177
|
+
bundles.set("multi-tenant", bytes);
|
|
178
|
+
return { level: "pro-plus", bundles };
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
if (err instanceof FetchModuleError) {
|
|
182
|
+
if (err.isLicenseError) {
|
|
183
|
+
return { level: "pro", bundles };
|
|
184
|
+
}
|
|
185
|
+
throw new FetchModuleError(`could not determine your licence level: ${err.message} — name the modules you want with --modules`);
|
|
186
|
+
}
|
|
187
|
+
throw err;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* The one entry point that turns `--modules` + the key into the effective
|
|
192
|
+
* module set and its resolved bundles (D5) — `programmatic.ts`'s `scaffold()`
|
|
193
|
+
* calls this for every run except a named `--template` alias (NFR-4).
|
|
194
|
+
*
|
|
195
|
+
* A named list with a non-addition (the KEEP branch, D2) resolves it exactly
|
|
196
|
+
* as today, with no level derived and no extra request (NFR-2). Otherwise the
|
|
197
|
+
* level is derived first, the set composed from it, and any named addition
|
|
198
|
+
* not already fetched during the level probe is resolved on top.
|
|
199
|
+
*/
|
|
200
|
+
export async function resolveModuleSet(options) {
|
|
201
|
+
const namedList = options.named ?? [];
|
|
202
|
+
const additions = [...ADD_ONS, ...OPT_IN_MODULES];
|
|
203
|
+
const isKeep = namedList.some((m) => !additions.includes(m));
|
|
204
|
+
if (isKeep) {
|
|
205
|
+
const modules = composeModuleSet(namedList, "free");
|
|
206
|
+
const { paid } = classifyModules(modules);
|
|
207
|
+
const bundles = await resolvePaidModules({
|
|
208
|
+
paidModules: paid,
|
|
209
|
+
licenseKey: options.licenseKey,
|
|
210
|
+
...forward(options),
|
|
211
|
+
});
|
|
212
|
+
return { modules, bundles };
|
|
213
|
+
}
|
|
214
|
+
const { level, bundles } = await deriveLevel(options);
|
|
215
|
+
const modules = composeModuleSet(namedList, level);
|
|
216
|
+
const { paid } = classifyModules(modules);
|
|
217
|
+
const missing = paid.filter((m) => !bundles.has(m));
|
|
218
|
+
if (missing.length > 0) {
|
|
219
|
+
const extra = await resolvePaidModules({
|
|
220
|
+
paidModules: missing,
|
|
221
|
+
licenseKey: options.licenseKey,
|
|
222
|
+
level,
|
|
223
|
+
...forward(options),
|
|
224
|
+
});
|
|
225
|
+
for (const [k, v] of extra)
|
|
226
|
+
bundles.set(k, v);
|
|
227
|
+
}
|
|
228
|
+
return { modules, bundles, level };
|
|
81
229
|
}
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Free vs paid module classification (K1, #5089 — REL-015.3 "AI Launch Kit —
|
|
3
|
-
* Commercial line", D-17 "Flavor 3").
|
|
4
|
-
*
|
|
5
|
-
* The commercial line is decided: the paid modules do NOT ship on public npm
|
|
6
|
-
* — delivery itself is the gate. `create-ailk` scaffolds Free's modules from
|
|
7
|
-
* `templates/` with no key (today's path, unchanged); a paid module is
|
|
8
|
-
* FETCHED from the internal module distribution when `AILK_LICENSE_KEY`
|
|
9
|
-
* verifies (see `fetch-module.ts` + `module-license-gate.ts`).
|
|
10
|
-
*
|
|
11
|
-
* `FREE_MODULES` is the one hand-authored list (today just `marketing`, the
|
|
12
|
-
* always-available default). `PAID_MODULES` is derived from it — every other
|
|
13
|
-
* `RECOGNIZED_MODULES` entry — so adding a new module to the vocabulary
|
|
14
|
-
* (`parse-args.ts`) defaults it to "paid" until someone deliberately adds it
|
|
15
|
-
* to `FREE_MODULES`, rather than silently shipping it free.
|
|
16
|
-
*/
|
|
17
1
|
import { type ModuleName } from "../parse-args.js";
|
|
18
2
|
/** Modules scaffolded from `templates/` with no license — today's free path. */
|
|
19
3
|
export declare const FREE_MODULES: readonly ModuleName[];
|
|
@@ -24,6 +8,51 @@ export declare const FREE_MODULES: readonly ModuleName[];
|
|
|
24
8
|
* from `RECOGNIZED_MODULES` silently.
|
|
25
9
|
*/
|
|
26
10
|
export declare const PAID_MODULES: readonly ModuleName[];
|
|
11
|
+
/**
|
|
12
|
+
* The levels a key can be at (#6759 D2). A value, never read from a flag, a
|
|
13
|
+
* manifest or a key claim — it is always DERIVED, by `deriveLevel`
|
|
14
|
+
* (`module-license-gate.ts`), from what the registry actually answers.
|
|
15
|
+
*/
|
|
16
|
+
export declare const LEVELS: readonly ["free", "pro", "pro-plus"];
|
|
17
|
+
export type Level = (typeof LEVELS)[number];
|
|
18
|
+
export declare const LEVEL_LABEL: Readonly<Record<Level, string>>;
|
|
19
|
+
/**
|
|
20
|
+
* Bought per site on top of a paid level — never switched on BY a level
|
|
21
|
+
* (OFFERINGS §4a). Naming one in `--modules` adds it without trimming
|
|
22
|
+
* (`composeModuleSet`), and it is refused below Pro naming the level it is
|
|
23
|
+
* an add-on ON TOP of.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ADD_ONS: readonly ModuleName[];
|
|
26
|
+
/**
|
|
27
|
+
* Included at Pro and above (the licence manifest's `pro` tier), but not
|
|
28
|
+
* switched on by default at any level (D1) — an authed app surface
|
|
29
|
+
* contributing no PUBLIC page to a marketing site. Naming it in `--modules`
|
|
30
|
+
* adds it without trimming, exactly like an add-on.
|
|
31
|
+
*/
|
|
32
|
+
export declare const OPT_IN_MODULES: readonly ModuleName[];
|
|
33
|
+
/**
|
|
34
|
+
* What a key at each level switches on with no `--modules` (D2). Derived —
|
|
35
|
+
* every list is `RECOGNIZED_MODULES.filter(...)`, so declaration order is
|
|
36
|
+
* preserved and a module added to the vocabulary later lands in `pro` by
|
|
37
|
+
* derivation (loud: `module-tier.test.ts`'s table test pins the exact sets).
|
|
38
|
+
*/
|
|
39
|
+
export declare const LEVEL_MODULES: Readonly<Record<Level, readonly ModuleName[]>>;
|
|
40
|
+
/**
|
|
41
|
+
* Which level (or add-on status) a module belongs to (D2). `"free"` for
|
|
42
|
+
* `FREE_MODULES`, `"add-on"` for `ADD_ONS`, `"pro-plus"` for
|
|
43
|
+
* `PRO_PLUS_MODULES`, else `"pro"` (`workspace` included — D1). Pure.
|
|
44
|
+
*/
|
|
45
|
+
export declare function levelOf(m: ModuleName): Level | "add-on";
|
|
46
|
+
/**
|
|
47
|
+
* The pure core of FR-2/FR-3 (D2): compose the effective module set from
|
|
48
|
+
* what `--modules` named and the key's derived level. Naming any module that
|
|
49
|
+
* is not an addition (`ADDITIONS`) is a KEEP — it names exactly the set,
|
|
50
|
+
* unchanged from today (NFR-2), and the level plays no part. Naming only
|
|
51
|
+
* additions (or nothing) takes the level's default plus those additions.
|
|
52
|
+
* Never refuses — refusals belong to the gate (`resolveModuleSet`), because
|
|
53
|
+
* whether a named module is covered is a registry answer, not a table lookup.
|
|
54
|
+
*/
|
|
55
|
+
export declare function composeModuleSet(named: readonly ModuleName[] | undefined, level: Level): ModuleName[];
|
|
27
56
|
export interface ModuleClassification {
|
|
28
57
|
free: ModuleName[];
|
|
29
58
|
paid: ModuleName[];
|
package/dist/lib/module-tier.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* (`parse-args.ts`) defaults it to "paid" until someone deliberately adds it
|
|
15
15
|
* to `FREE_MODULES`, rather than silently shipping it free.
|
|
16
16
|
*/
|
|
17
|
+
import { normalizeModules } from "../module-architecture.js";
|
|
17
18
|
import { RECOGNIZED_MODULES } from "../parse-args.js";
|
|
18
19
|
/** Modules scaffolded from `templates/` with no license — today's free path. */
|
|
19
20
|
export const FREE_MODULES = ["marketing"];
|
|
@@ -24,6 +25,81 @@ export const FREE_MODULES = ["marketing"];
|
|
|
24
25
|
* from `RECOGNIZED_MODULES` silently.
|
|
25
26
|
*/
|
|
26
27
|
export const PAID_MODULES = RECOGNIZED_MODULES.filter((m) => !FREE_MODULES.includes(m));
|
|
28
|
+
/**
|
|
29
|
+
* The levels a key can be at (#6759 D2). A value, never read from a flag, a
|
|
30
|
+
* manifest or a key claim — it is always DERIVED, by `deriveLevel`
|
|
31
|
+
* (`module-license-gate.ts`), from what the registry actually answers.
|
|
32
|
+
*/
|
|
33
|
+
export const LEVELS = ["free", "pro", "pro-plus"];
|
|
34
|
+
export const LEVEL_LABEL = {
|
|
35
|
+
free: "Free",
|
|
36
|
+
pro: "Pro",
|
|
37
|
+
"pro-plus": "Pro Plus",
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Bought per site on top of a paid level — never switched on BY a level
|
|
41
|
+
* (OFFERINGS §4a). Naming one in `--modules` adds it without trimming
|
|
42
|
+
* (`composeModuleSet`), and it is refused below Pro naming the level it is
|
|
43
|
+
* an add-on ON TOP of.
|
|
44
|
+
*/
|
|
45
|
+
export const ADD_ONS = ["commerce"];
|
|
46
|
+
/**
|
|
47
|
+
* Included at Pro and above (the licence manifest's `pro` tier), but not
|
|
48
|
+
* switched on by default at any level (D1) — an authed app surface
|
|
49
|
+
* contributing no PUBLIC page to a marketing site. Naming it in `--modules`
|
|
50
|
+
* adds it without trimming, exactly like an add-on.
|
|
51
|
+
*/
|
|
52
|
+
export const OPT_IN_MODULES = ["workspace"];
|
|
53
|
+
/** The Pro Plus membership: what Pro Plus switches on beyond Pro. */
|
|
54
|
+
const PRO_PLUS_MODULES = ["multi-tenant"];
|
|
55
|
+
/** Named modules that never trim the level default when composing a set (D2). */
|
|
56
|
+
const ADDITIONS = [...ADD_ONS, ...OPT_IN_MODULES];
|
|
57
|
+
const PRO_EXCLUDED = new Set([...ADDITIONS, ...PRO_PLUS_MODULES]);
|
|
58
|
+
/**
|
|
59
|
+
* What a key at each level switches on with no `--modules` (D2). Derived —
|
|
60
|
+
* every list is `RECOGNIZED_MODULES.filter(...)`, so declaration order is
|
|
61
|
+
* preserved and a module added to the vocabulary later lands in `pro` by
|
|
62
|
+
* derivation (loud: `module-tier.test.ts`'s table test pins the exact sets).
|
|
63
|
+
*/
|
|
64
|
+
export const LEVEL_MODULES = Object.freeze({
|
|
65
|
+
free: [...FREE_MODULES],
|
|
66
|
+
pro: RECOGNIZED_MODULES.filter((m) => FREE_MODULES.includes(m) ||
|
|
67
|
+
(PAID_MODULES.includes(m) && !PRO_EXCLUDED.has(m))),
|
|
68
|
+
"pro-plus": RECOGNIZED_MODULES.filter((m) => FREE_MODULES.includes(m) ||
|
|
69
|
+
(PAID_MODULES.includes(m) && !ADDITIONS.includes(m))),
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* Which level (or add-on status) a module belongs to (D2). `"free"` for
|
|
73
|
+
* `FREE_MODULES`, `"add-on"` for `ADD_ONS`, `"pro-plus"` for
|
|
74
|
+
* `PRO_PLUS_MODULES`, else `"pro"` (`workspace` included — D1). Pure.
|
|
75
|
+
*/
|
|
76
|
+
export function levelOf(m) {
|
|
77
|
+
if (FREE_MODULES.includes(m))
|
|
78
|
+
return "free";
|
|
79
|
+
if (ADD_ONS.includes(m))
|
|
80
|
+
return "add-on";
|
|
81
|
+
if (PRO_PLUS_MODULES.includes(m))
|
|
82
|
+
return "pro-plus";
|
|
83
|
+
return "pro";
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The pure core of FR-2/FR-3 (D2): compose the effective module set from
|
|
87
|
+
* what `--modules` named and the key's derived level. Naming any module that
|
|
88
|
+
* is not an addition (`ADDITIONS`) is a KEEP — it names exactly the set,
|
|
89
|
+
* unchanged from today (NFR-2), and the level plays no part. Naming only
|
|
90
|
+
* additions (or nothing) takes the level's default plus those additions.
|
|
91
|
+
* Never refuses — refusals belong to the gate (`resolveModuleSet`), because
|
|
92
|
+
* whether a named module is covered is a registry answer, not a table lookup.
|
|
93
|
+
*/
|
|
94
|
+
export function composeModuleSet(named, level) {
|
|
95
|
+
const namedList = [...(named ?? [])];
|
|
96
|
+
const keep = namedList.filter((m) => !ADDITIONS.includes(m));
|
|
97
|
+
if (keep.length > 0) {
|
|
98
|
+
return normalizeModules(namedList);
|
|
99
|
+
}
|
|
100
|
+
const add = namedList.filter((m) => ADDITIONS.includes(m));
|
|
101
|
+
return normalizeModules([...LEVEL_MODULES[level], ...add]);
|
|
102
|
+
}
|
|
27
103
|
/**
|
|
28
104
|
* Split a requested (already-validated, `ModuleName`) module set into its
|
|
29
105
|
* free and paid subsets, each preserving the input's relative order.
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
export declare function proCallout(): string;
|
|
2
|
+
/** The closing prerequisites note on a free install (#6440 AC4). */
|
|
3
|
+
export declare const FREE_PREREQUISITES_NOTE = "No database, no licence key and no vendor API key are needed to run or build this site.";
|
|
1
4
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Wording is locked in `docs/internal/specs/ailk-onboard-site-spec.md` §2.1 and
|
|
6
|
-
* `docs/internal/specs/ailk-onboard-site-spec.md` §5.1 (Sam-verifiable AC).
|
|
7
|
-
*
|
|
8
|
-
* The message is always shown — no flags, no env gating. Free-tier users
|
|
9
|
-
* see it as a discovery surface for Pro; Pro users see it as a reminder
|
|
10
|
-
* of the `/onboard-site` skill they can install.
|
|
5
|
+
* The same note on a licensed install (#6480): it drops the licence-key claim,
|
|
6
|
+
* which would contradict the key the customer just installed with.
|
|
11
7
|
*/
|
|
12
|
-
export declare
|
|
8
|
+
export declare const LICENSED_PREREQUISITES_NOTE = "No database and no vendor API key are needed to run or build this site.";
|
|
9
|
+
/**
|
|
10
|
+
* Whether an install delivered paid content — any paid module in the effective
|
|
11
|
+
* module set, `union(template.requires, --modules)`, the same union
|
|
12
|
+
* `scaffold()` gates on. A paid template is covered by that union too:
|
|
13
|
+
* `templateDelivery` derives "paid" from `requires` alone.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isLicensedInstall(opts: {
|
|
16
|
+
template?: string;
|
|
17
|
+
modules?: string[];
|
|
18
|
+
}): boolean;
|
package/dist/lib/pro-callout.js
CHANGED
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
* Wording is locked in `docs/internal/specs/ailk-onboard-site-spec.md` §2.1 and
|
|
6
6
|
* `docs/internal/specs/ailk-onboard-site-spec.md` §5.1 (Sam-verifiable AC).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* of the `/onboard-site` skill they can install.
|
|
8
|
+
* Shown on a free install only (#6480): it is a discovery surface for Pro,
|
|
9
|
+
* and a licensed install already owns the tier it pitches.
|
|
11
10
|
*/
|
|
11
|
+
import { normalizeModules } from "../module-architecture.js";
|
|
12
|
+
import { SHAPE_STARTERS, resolveTemplate } from "../template-manifest.js";
|
|
13
|
+
import { classifyModules } from "./module-tier.js";
|
|
12
14
|
export function proCallout() {
|
|
13
15
|
return [
|
|
14
16
|
"Want AI-guided setup? Pro's `/onboard-site` interviews you about",
|
|
@@ -18,3 +20,32 @@ export function proCallout() {
|
|
|
18
20
|
"free scaffolders one at a time → ailaunchkit.ai/pricing",
|
|
19
21
|
].join("\n");
|
|
20
22
|
}
|
|
23
|
+
/** The closing prerequisites note on a free install (#6440 AC4). */
|
|
24
|
+
export const FREE_PREREQUISITES_NOTE = "No database, no licence key and no vendor API key are needed to run or build this site.";
|
|
25
|
+
/**
|
|
26
|
+
* The same note on a licensed install (#6480): it drops the licence-key claim,
|
|
27
|
+
* which would contradict the key the customer just installed with.
|
|
28
|
+
*/
|
|
29
|
+
export const LICENSED_PREREQUISITES_NOTE = "No database and no vendor API key are needed to run or build this site.";
|
|
30
|
+
/**
|
|
31
|
+
* Whether an install delivered paid content — any paid module in the effective
|
|
32
|
+
* module set, `union(template.requires, --modules)`, the same union
|
|
33
|
+
* `scaffold()` gates on. A paid template is covered by that union too:
|
|
34
|
+
* `templateDelivery` derives "paid" from `requires` alone.
|
|
35
|
+
*/
|
|
36
|
+
export function isLicensedInstall(opts) {
|
|
37
|
+
// #6757 D6 row 4 — a bare-shape starter's name (the shape itself, passed
|
|
38
|
+
// here after #6754 D4 item 3 resolves it) is looked up through
|
|
39
|
+
// SHAPE_STARTERS first; `resolveTemplate` alone throws `unknown template`
|
|
40
|
+
// for one (NFR-3).
|
|
41
|
+
const requires = opts.template !== undefined
|
|
42
|
+
? Object.prototype.hasOwnProperty.call(SHAPE_STARTERS, opts.template)
|
|
43
|
+
? SHAPE_STARTERS[opts.template].requires
|
|
44
|
+
: resolveTemplate(opts.template).requires
|
|
45
|
+
: [];
|
|
46
|
+
const modules = normalizeModules([
|
|
47
|
+
...requires,
|
|
48
|
+
...(opts.modules ?? ["marketing"]),
|
|
49
|
+
]);
|
|
50
|
+
return classifyModules(modules).paid.length > 0;
|
|
51
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface LicenseSetRunResult {
|
|
2
|
+
/** Exit status; null when the process never ran or was killed. */
|
|
3
|
+
status: number | null;
|
|
4
|
+
/** Set when the process could not be spawned (e.g. `ENOENT`). */
|
|
5
|
+
error?: NodeJS.ErrnoException;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Runs `vercel <args>`. The command itself is fixed — a runner is never
|
|
9
|
+
* handed one to run, per the package's hard-coded-command invariant
|
|
10
|
+
* (security.test.ts).
|
|
11
|
+
* `input`, when given, is written to the child's stdin.
|
|
12
|
+
*/
|
|
13
|
+
export type LicenseSetRunner = (args: readonly string[], options: {
|
|
14
|
+
cwd: string;
|
|
15
|
+
input?: string;
|
|
16
|
+
}) => LicenseSetRunResult;
|
|
17
|
+
export interface LicenseSetIO {
|
|
18
|
+
/** Resolves a relative or absent `[dir]`. */
|
|
19
|
+
cwd: string;
|
|
20
|
+
stdout: (text: string) => void;
|
|
21
|
+
stderr: (text: string) => void;
|
|
22
|
+
/** Reads all of stdin — used only by the `-` form. */
|
|
23
|
+
readStdin: () => string;
|
|
24
|
+
/** Defaults to `spawnSync` with `shell: false` (see `defaultRunner`). */
|
|
25
|
+
runner?: LicenseSetRunner;
|
|
26
|
+
}
|
|
27
|
+
export declare const LICENSE_SET_HELP = "create-ailk license set \u2014 put your licence key into an existing site.\n\nUsage:\n pnpm create ailk@latest license set <key> [<target-dir>]\n pnpm create ailk@latest license set - [<target-dir>] < key.txt\n\nArguments:\n <key> Your licence key, or `-` to read it from stdin\n (keeps it out of your shell history).\n <target-dir> An already-scaffolded repo (contains\n architecture.yaml). Defaults to the current dir.\n\nWrites the key to ailk.key and apps/api/.env (owner-only, gitignored). When the\nsite (or apps/api, or apps/web) is linked to Vercel, it also replaces the\nproduction AILK_LICENSE_KEY variable and redeploys.\n";
|
|
28
|
+
/** `spawnSync`, never through a shell; stdin piped only when there is input. */
|
|
29
|
+
export declare const defaultRunner: LicenseSetRunner;
|
|
30
|
+
/**
|
|
31
|
+
* Run `license set` with `argv` = everything after the `license set` words.
|
|
32
|
+
* Returns the process exit code; never throws for an expected failure.
|
|
33
|
+
*/
|
|
34
|
+
export declare function runLicenseSet(argv: string[], io: LicenseSetIO): number;
|