create-ailk 0.6.0 → 0.7.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 +44 -5
- package/component-catalog.json +146 -21
- package/component-catalog.md +9 -6
- 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 +124 -13
- package/dist/copy.d.ts +14 -0
- package/dist/copy.js +38 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -1
- package/dist/lib/extract-module-bundle.d.ts +76 -2
- package/dist/lib/extract-module-bundle.js +219 -8
- 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 +6 -1
- package/dist/lib/module-license-gate.js +6 -1
- package/dist/lib/pro-callout.d.ts +16 -10
- package/dist/lib/pro-callout.js +27 -4
- 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.0.tar.gz +0 -0
- package/dist/modules/commerce/0.6.1.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.0.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.0.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.0.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.0.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.0.tar.gz +0 -0
- package/dist/modules/workspace/0.6.1.tar.gz +0 -0
- package/dist/parse-args.d.ts +7 -0
- package/dist/parse-args.js +23 -1
- package/dist/programmatic.d.ts +46 -0
- package/dist/programmatic.js +144 -19
- 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 +494 -0
- package/dist/surfaces.d.ts +20 -7
- package/dist/surfaces.js +149 -28
- package/dist/sync-routes.d.ts +9 -0
- package/dist/sync-routes.js +2 -2
- package/dist/template-manifest.d.ts +58 -2
- package/dist/template-manifest.js +196 -69
- package/package.json +6 -4
- package/site-templates/_base/content/en/BookCall/book-call.mdx +53 -0
- package/site-templates/_base/content/en/GlossaryList/glossary.mdx +66 -0
- package/site-templates/_base/content/en/NewsletterSignup/newsletter.mdx +68 -0
- package/site-templates/_base/content/en/Pricing/pricing.mdx +71 -62
- package/site-templates/_base/content/en/PrivacyPage/privacy.mdx +2 -3
- package/site-templates/_base/content/en/TermsPage/terms.mdx +2 -3
- package/site-templates/_base/content/en/UseCase/first-use-case.mdx +23 -0
- package/site-templates/_base/content/en/UseCase/second-use-case.mdx +23 -0
- package/site-templates/_base/content/en/UseCase/third-use-case.mdx +23 -0
- package/site-templates/designs/minimalism/DESIGN.md +162 -0
- package/site-templates/designs/standard/DESIGN.md +162 -0
- package/site-templates/marketing-site/DESIGN.md +162 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +312 -57
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +209 -90
- package/site-templates/marketing-site/ailk-template.json +1 -0
- package/site-templates/marketing-site-free/DESIGN.md +162 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +260 -66
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +294 -114
- package/site-templates/marketing-site-free/ailk-template.json +3 -2
- package/site-templates/minimalism-site/DESIGN.md +162 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +246 -19
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +185 -51
- package/site-templates/minimalism-site/ailk-template.json +3 -2
- package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +53 -0
- package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +3 -37
- package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +124 -0
- package/site-templates/saas-product/DESIGN.md +162 -0
- package/site-templates/simple-service/DESIGN.md +162 -0
- package/site-templates/simple-service/TEMPLATE-MANIFEST.json +135 -26
- package/site-templates/simple-service/TEMPLATE-MANIFEST.md +114 -59
- package/site-templates/simple-service/ailk-template.json +4 -3
- package/site-templates/simple-service/content/en/BookCall/book-call.mdx +53 -0
- package/site-templates/simple-service/content/en/ContactPage/contact.mdx +1 -36
- package/site-templates/simple-service/content/en/PurchasePolicyPage/purchase-policy.mdx +124 -0
- package/templates/.claude/settings.json +15 -0
- package/templates/.claude/skills/README.md +8 -8
- 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 +111 -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/{provision-config → setup-deploy}/SKILL.md +8 -8
- package/templates/.claude/skills/{provision-config → setup-deploy}/references/env-vars-template.md +2 -2
- package/templates/.claude/skills/{provision-config → setup-deploy}/references/runbook-template.md +8 -8
- 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 +10 -5
- package/templates/DESIGN.md +162 -0
- package/templates/README.md +134 -38
- package/templates/apps/api/.env.example +2 -1
- package/templates/apps/api/package.json +1 -1
- package/templates/apps/api/src/config/__tests__/index.test.ts +37 -2
- package/templates/apps/api/src/config/index.ts +19 -6
- 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/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/server.ts +6 -0
- 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/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/web/PRODUCT.md +86 -0
- 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/ContactForm.tsx +94 -33
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +53 -23
- package/templates/apps/web/app/[locale]/contact/__tests__/ContactForm.test.tsx +96 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +84 -2
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +5 -6
- package/templates/apps/web/app/[locale]/contact/page.tsx +25 -7
- 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]/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 +113 -51
- package/templates/apps/web/app/[locale]/newsletter/page.tsx +50 -0
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +3 -3
- 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]/{shipping → 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 +48 -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__/site-theme.test.ts +135 -20
- 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 +64 -12
- package/templates/apps/web/lib/prisma-for-auth.ts +9 -6
- package/templates/apps/web/lib/site-brand.tsx +4 -8
- package/templates/apps/web/lib/site-chrome.ts +3 -3
- package/templates/apps/web/lib/site-identity.ts +134 -0
- package/templates/apps/web/lib/site-theme.ts +11 -0
- package/templates/apps/web/messages/en.json +52 -37
- package/templates/apps/web/middleware.ts +1 -1
- 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/apps/web/src/lib/commerce-sections.ts +35 -3
- package/templates/content/_site.mdx +41 -3
- package/templates/content/en/AboutPage/about.mdx +150 -144
- package/templates/content/en/BlogList/blog.mdx +105 -0
- package/templates/content/en/ContactPage/contact.mdx +44 -85
- package/templates/content/en/FAQPage/faq.mdx +86 -57
- package/templates/content/en/HomePage/home.mdx +276 -217
- package/templates/content/en/PurchasePolicyPage/purchase-policy.mdx +182 -0
- package/templates/content/en/SoftwareProduct/product.mdx +175 -0
- package/templates/content/en/UseCasesList/use-cases.mdx +170 -0
- package/templates/database/CHANGELOG.md +14 -0
- package/templates/database/package.json +3 -2
- 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/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/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]/cancellation/page.tsx +0 -44
- package/templates/apps/web/app/[locale]/returns/page.tsx +0 -44
- package/templates/apps/web/public/logo-dark.svg +0 -21
- package/templates/apps/web/public/logo-light.svg +0 -21
- 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
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fill-page
|
|
3
|
+
description: Fill one existing page's section content from a category profile. Tier 1 writes realistic, labelled sample content for the category (a plumber's home page, say). Tier 2 asks the owner the profile's questions and writes the company's own first draft from their answers and `_site.mdx`. Use when the user says "fill this page", "fill the home page for a plumber", "write sample content for my services page", or "write my real copy from what I tell you". It never creates a page, never changes a page's section stack, and never edits `_site.mdx`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# fill-page
|
|
7
|
+
|
|
8
|
+
Replace one page's `{brace}` instructions with content, reading the
|
|
9
|
+
content from a **category profile** (`profiles/<slug>.yaml` beside this
|
|
10
|
+
file). A profile is the data for one business type: the schema.org
|
|
11
|
+
subtype, the typical offerings, the proof buyers expect, the buyer's own
|
|
12
|
+
words, and the questions to ask the owner.
|
|
13
|
+
|
|
14
|
+
Two tiers:
|
|
15
|
+
|
|
16
|
+
| Tier | Source | Result | `placeholder` |
|
|
17
|
+
| ---- | -------------------------------------------------------- | ------------------------------------------ | ------------- |
|
|
18
|
+
| 1 | the profile | realistic sample content for the category | `true` |
|
|
19
|
+
| 2 | `_site.mdx` + the owner's answers (`content/_intake.yaml`) | the company's own first draft | by the rule in Step 2.4 |
|
|
20
|
+
|
|
21
|
+
`placeholder: true` in a page's frontmatter makes the site render a
|
|
22
|
+
**PLACEHOLDER — REPLACE BEFORE LAUNCH** label at the top of the page.
|
|
23
|
+
The label is for people. Structured data reaches agents without it, so
|
|
24
|
+
tier-1 content must be safe to publish by itself (see the never-invent
|
|
25
|
+
list).
|
|
26
|
+
|
|
27
|
+
## Inputs
|
|
28
|
+
|
|
29
|
+
- **The page file** — `content/<locale>/<Type>/<slug>.mdx`. It must
|
|
30
|
+
already exist; `add-page` creates pages.
|
|
31
|
+
- **The page type** — the frontmatter `type`.
|
|
32
|
+
- **The profile slug** — a file under `profiles/` (e.g. `plumbing`).
|
|
33
|
+
Ask if the user did not name one. If there is no profile for their
|
|
34
|
+
category, say so and stop.
|
|
35
|
+
- **The tier** — 1 unless the user asks for their own copy.
|
|
36
|
+
|
|
37
|
+
## What never changes
|
|
38
|
+
|
|
39
|
+
- The page's **section stack**: every section's `id` and `type`, in
|
|
40
|
+
order. Never add, remove or reorder a section. The starter's manifest
|
|
41
|
+
records each page's sections, and a changed stack fails its check.
|
|
42
|
+
- Each section's **layout options** that are already present:
|
|
43
|
+
`variant`, `columns`, `layout`, `initialOpen`, `size` and the like.
|
|
44
|
+
They are the site's locked look.
|
|
45
|
+
- Link targets (`href`) that are already present, except a link to a
|
|
46
|
+
Service page, which follows that page's slug (Step 1.3).
|
|
47
|
+
- `{/* … */}` comments in the MDX body.
|
|
48
|
+
- `_site.mdx`. Identity strings (the company name) are read from it,
|
|
49
|
+
never written to it.
|
|
50
|
+
|
|
51
|
+
## Never invent (tier 1)
|
|
52
|
+
|
|
53
|
+
At tier 1, write none of these. Remove any you find in the page:
|
|
54
|
+
|
|
55
|
+
- `price`, `priceCurrency`, `availability` or `stripe` — each feeds the
|
|
56
|
+
schema.org `Offer` an agent quotes as the company's price.
|
|
57
|
+
- A person's name or another company's name.
|
|
58
|
+
- A phone number, a street address, or a licence or registration number.
|
|
59
|
+
- A town, a county, or a distance: the service area is a company fact.
|
|
60
|
+
- Testimonials: `author` is the literal `Sample customer`; no `company`,
|
|
61
|
+
`rating` or `avatar`.
|
|
62
|
+
- Statistics a reader would take as measured (a count of jobs, a years
|
|
63
|
+
figure). Use the profile's `proof[]` labels as words, not numbers.
|
|
64
|
+
|
|
65
|
+
The company name is the one identity string tier 1 may write, and it
|
|
66
|
+
comes from `_site.mdx` `siteIdentity.name`.
|
|
67
|
+
|
|
68
|
+
## Step 0 — Read
|
|
69
|
+
|
|
70
|
+
1. Read the profile: `profiles/<slug>.yaml`.
|
|
71
|
+
2. Read `content/_site.mdx` for `siteIdentity.name`.
|
|
72
|
+
3. Read the page file. Note its stack (`sections[].type` in order).
|
|
73
|
+
4. For each section type in the stack, read its data schema: the
|
|
74
|
+
`<Type>SectionDataSchema` (or `<Type>DataSchema`) export in the
|
|
75
|
+
installed `@working-theory/validation`'s `schemas/page-sections`. Fill
|
|
76
|
+
only fields the schema declares. Every field a section renders from
|
|
77
|
+
copy gets content; a field the source page did not use stays unused.
|
|
78
|
+
5. Find the route that renders this page type under `apps/web/app/[locale]/`
|
|
79
|
+
and read its `bodyMode`. When it is `"mdx-body"`, the MDX body is
|
|
80
|
+
rendered and must be filled too. Otherwise the body is a short note,
|
|
81
|
+
and you rewrite it as one plain sentence that names no braces.
|
|
82
|
+
|
|
83
|
+
`references/section-sources.md` maps each section type to the profile
|
|
84
|
+
fields and intake answers that fill it.
|
|
85
|
+
|
|
86
|
+
## Step 1 — Tier 1: sample content
|
|
87
|
+
|
|
88
|
+
1. **Sections.** For each section, in place, write every copy field from
|
|
89
|
+
the profile using `references/section-sources.md`:
|
|
90
|
+
- offerings → `items` entries (`title` = the offering `name`,
|
|
91
|
+
`description` = its `job`, `link.href` = `/services/<kebab name>`);
|
|
92
|
+
- vocabulary → headlines, eyebrows and FAQ questions (the buyer's own
|
|
93
|
+
words: the `problem` list for what went wrong, `outcome` for what
|
|
94
|
+
they get);
|
|
95
|
+
- proof → `stats` labels and `testimonials` quotes, under the
|
|
96
|
+
never-invent list.
|
|
97
|
+
Keep `id`, `type` and every layout option.
|
|
98
|
+
2. **Frontmatter.** Rewrite `title` and `description` without braces.
|
|
99
|
+
Use the company name from `_site.mdx` where the page names the
|
|
100
|
+
company. On a page that carries `provider.name`, set it to the company
|
|
101
|
+
name. Drop `schema.areaServed`; set `schema.serviceType` to the
|
|
102
|
+
offering name. Remove every key the never-invent list names.
|
|
103
|
+
3. **Service pages.** A `Service` page is one offering. The user names
|
|
104
|
+
the offering, or you take the first profile offering that no other
|
|
105
|
+
Service page carries yet. Set `title` and `schema.serviceType` to the
|
|
106
|
+
offering `name`, and `slug` and the file name to its name in kebab
|
|
107
|
+
case (`Drain clearing` → `drain-clearing`): rename the file, never
|
|
108
|
+
copy it. To give every offering a page, the user first adds one
|
|
109
|
+
Service page per offering (`add-page`, or a copy of an existing one),
|
|
110
|
+
then runs this skill on each.
|
|
111
|
+
4. **Body.** When the route renders `mdx-body`, rewrite each paragraph
|
|
112
|
+
and list item under the page's existing headings in the category's
|
|
113
|
+
words. Keep the headings, keep the order, keep the comments. Drop
|
|
114
|
+
every `\{…\}` instruction. Under a price heading, say how the job is
|
|
115
|
+
priced (the offering's `pricing`: `quote`, `fixed`, `hourly`,
|
|
116
|
+
`subscription`) in words, with no figure.
|
|
117
|
+
5. **Label.** Set `placeholder: true` in the frontmatter.
|
|
118
|
+
6. **Check** (below).
|
|
119
|
+
|
|
120
|
+
## Step 2 — Tier 2: the company's own draft
|
|
121
|
+
|
|
122
|
+
1. **Ask.** Ask each `intake[]` question from the profile, in order, one
|
|
123
|
+
at a time. Record the answers in `content/_intake.yaml`:
|
|
124
|
+
|
|
125
|
+
```yaml
|
|
126
|
+
answers:
|
|
127
|
+
offerings: [Drain clearing, Emergency call-out]
|
|
128
|
+
service_area: "…"
|
|
129
|
+
faq: null # unanswered
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
A list answer stays a list. An unanswered or skipped question is
|
|
133
|
+
`null`. Offerings are named exactly as the profile names them.
|
|
134
|
+
2. **Fill.** Fill the page as in Step 1, but from `_site.mdx` and the
|
|
135
|
+
answers first; the profile fills only what the answers leave open.
|
|
136
|
+
- A profile offering the owner does not offer appears on no page:
|
|
137
|
+
remove its `items` entries, and ask before deleting its Service
|
|
138
|
+
page (the one file this skill may delete).
|
|
139
|
+
- A price appears only when the owner gave one, with `priceCurrency`.
|
|
140
|
+
- The company name appears in each page's frontmatter (`title` or
|
|
141
|
+
`description`), and the service area in the home hero when given.
|
|
142
|
+
- A section whose sources have no answer keeps its tier-1 sample
|
|
143
|
+
content.
|
|
144
|
+
3. **Never invent** still holds for everything the owner did not give.
|
|
145
|
+
Testimonials stay `Sample customer` unless the owner supplies a
|
|
146
|
+
customer's name with permission to publish it.
|
|
147
|
+
4. **Label.** Set `placeholder: false` only when every section is filled
|
|
148
|
+
from company facts:
|
|
149
|
+
- every section type in the stack appears in the `fills` of at least
|
|
150
|
+
one intake item whose answer is not empty, and
|
|
151
|
+
- when the stack has a `hero` or `cta`, `_site.mdx` has
|
|
152
|
+
`siteIdentity.name`.
|
|
153
|
+
|
|
154
|
+
A page with no sections is judged on its body: a `Service` page is
|
|
155
|
+
cleared only when the `offerings` answer names its offering; any
|
|
156
|
+
other page with no sections keeps `placeholder: true`. In every other
|
|
157
|
+
case, keep `placeholder: true`.
|
|
158
|
+
5. **Check** (below).
|
|
159
|
+
|
|
160
|
+
## The check
|
|
161
|
+
|
|
162
|
+
Run the site's own structured-data check. It reads every content page
|
|
163
|
+
through the same frontmatter and section schemas the site renders with,
|
|
164
|
+
and validates each page's JSON-LD:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
pnpm --filter web test -- lib/__tests__/structured-data.test.tsx
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Then search the filled file for a `{` or `}` in any frontmatter string or
|
|
171
|
+
in the body outside `{/* … */}` comments. Fix everything either reports
|
|
172
|
+
and run both again. Stop only when both are clean.
|
|
173
|
+
|
|
174
|
+
## What this skill does not do
|
|
175
|
+
|
|
176
|
+
- Tier 3 (the Messaging Canvas through the content pipeline).
|
|
177
|
+
- Create a page — use `add-page`.
|
|
178
|
+
- Edit `_site.mdx`, the nav or the page roster. A profile's `roster` and
|
|
179
|
+
`nav` entries are declared for a later step and are not applied here.
|
|
180
|
+
- Write a price, a name or an address the owner did not give.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Category profile — Local Plumbing (#6640; starter-template contract § D).
|
|
2
|
+
# Read by the `fill-page` skill: tier 1 fills a page with labelled sample
|
|
3
|
+
# content from this file; tier 2 asks `intake[]` and fills from the answers.
|
|
4
|
+
# Twin: templates/.claude/skills/fill-page/profiles/plumbing.yaml (byte-identical).
|
|
5
|
+
slug: plumbing
|
|
6
|
+
shape: local-business-service
|
|
7
|
+
subtype: Plumber
|
|
8
|
+
secondary: Person
|
|
9
|
+
offerings:
|
|
10
|
+
- name: Drain clearing
|
|
11
|
+
job: Clears blocked sinks, showers, toilets and main drains, and says what caused the blockage.
|
|
12
|
+
pricing: quote
|
|
13
|
+
- name: Water heater installation
|
|
14
|
+
job: Removes the old tank or boiler and fits, tests and registers a new water heater.
|
|
15
|
+
pricing: fixed
|
|
16
|
+
- name: Emergency call-out
|
|
17
|
+
job: A plumber at the door the same day for a burst pipe, a flood or no water at all.
|
|
18
|
+
pricing: hourly
|
|
19
|
+
- name: Leak detection and repair
|
|
20
|
+
job: Finds the hidden leak behind a wall or under a floor and fixes it with the least damage.
|
|
21
|
+
pricing: quote
|
|
22
|
+
proof:
|
|
23
|
+
- kind: credential
|
|
24
|
+
label: Licensed and insured
|
|
25
|
+
- kind: reviews
|
|
26
|
+
label: Reviews from local customers
|
|
27
|
+
- kind: response-time
|
|
28
|
+
label: Same-day response on emergency calls
|
|
29
|
+
- kind: guarantee
|
|
30
|
+
label: Workmanship guaranteed
|
|
31
|
+
vocabulary:
|
|
32
|
+
problem:
|
|
33
|
+
- burst pipe
|
|
34
|
+
- blocked drain
|
|
35
|
+
- no hot water
|
|
36
|
+
- leaking tap
|
|
37
|
+
- low water pressure
|
|
38
|
+
- water stain on the ceiling
|
|
39
|
+
service:
|
|
40
|
+
- drain clearing
|
|
41
|
+
- water heater install
|
|
42
|
+
- emergency call-out
|
|
43
|
+
- leak repair
|
|
44
|
+
- pipe replacement
|
|
45
|
+
outcome:
|
|
46
|
+
- same-day fix
|
|
47
|
+
- hot water back on
|
|
48
|
+
- no water damage
|
|
49
|
+
- upfront quote
|
|
50
|
+
- tidy job, nothing left behind
|
|
51
|
+
roster:
|
|
52
|
+
- op: add
|
|
53
|
+
route: /emergency
|
|
54
|
+
pageType: BookCall
|
|
55
|
+
reason: Emergency jobs book a call, not a form.
|
|
56
|
+
- op: drop
|
|
57
|
+
route: /pricing
|
|
58
|
+
reason: Most plumbing work is quote-priced, so a price table misleads.
|
|
59
|
+
nav:
|
|
60
|
+
Services: Plumbing services
|
|
61
|
+
content_posture: sample
|
|
62
|
+
intake:
|
|
63
|
+
- id: offerings
|
|
64
|
+
ask: Which of these jobs do you take on, and is there one you do not list? (Drain clearing, water heater installation, emergency call-out, leak detection and repair.)
|
|
65
|
+
fills: [hero, items]
|
|
66
|
+
- id: service_area
|
|
67
|
+
ask: Which towns, postcodes or radius do you cover?
|
|
68
|
+
fills: [hero, cta]
|
|
69
|
+
- id: about
|
|
70
|
+
ask: How did the business start, who does the work, and what will you not take on?
|
|
71
|
+
fills: [content-block]
|
|
72
|
+
- id: proof
|
|
73
|
+
ask: What can a customer check — your licence, your insurance, your reviews, your response time, your guarantee?
|
|
74
|
+
fills: [stats, testimonials, social-proof]
|
|
75
|
+
- id: faq
|
|
76
|
+
ask: What do customers ask before they book, and what do you tell them?
|
|
77
|
+
fills: [faq]
|
|
78
|
+
- id: contact
|
|
79
|
+
ask: How should a customer reach you — phone, form or booking — and how fast do you reply?
|
|
80
|
+
fills: [cta]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Section sources
|
|
2
|
+
|
|
3
|
+
Where each section's copy comes from. **Profile** is tier 1's source;
|
|
4
|
+
**Intake** lists the `intake[]` answers that fill the section at tier 2
|
|
5
|
+
(the same ids appear in each question's `fills`). Fields not named here
|
|
6
|
+
are layout options: keep them as they are.
|
|
7
|
+
|
|
8
|
+
| Section type | Copy fields | Profile (tier 1) | Intake (tier 2) |
|
|
9
|
+
| --------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
|
|
10
|
+
| `hero` | `eyebrow`, `headline`, `subheadline`, `primaryCta.label`, `secondaryCta.label` | `vocabulary.problem` + `vocabulary.outcome` for the headline; the category name for the eyebrow | `offerings`, `service_area` |
|
|
11
|
+
| `items` | `headline`, `description`, `items[].title`, `items[].description`, `items[].link` | one item per `offerings[]` entry: `title` = `name`, `description` = `job`, `link.href` = `/services/<kebab name>` | `offerings` |
|
|
12
|
+
| `cta` | `headline`, `description`, `primaryCta.label`, `secondaryCta.label` | `vocabulary.outcome` | `service_area`, `contact` |
|
|
13
|
+
| `content-block` | `eyebrow`, `headline`, `body` | `proof[].label` and `vocabulary.service`, with no names, places or numbers | `about` |
|
|
14
|
+
| `faq` | `headline`, `items[].question`, `items[].answer` | questions in `vocabulary.problem` words; answers from `offerings[].pricing` and `proof[]` | `faq` |
|
|
15
|
+
| `stats` | `headline`, `items[].label`, `items[].value` | `proof[].label` as the label; a value only when it is not a measurement (e.g. `Same day`) | `proof` |
|
|
16
|
+
| `testimonials` | `headline`, `items[].quote`, `items[].author` | quotes in `vocabulary.outcome` words; `author: Sample customer`; no `company`, `rating` or `avatar` | `proof` |
|
|
17
|
+
| `social-proof` | `headline`, labels | `proof[].label` | `proof` |
|
|
18
|
+
|
|
19
|
+
A section type not in this table: fill its copy fields from the profile's
|
|
20
|
+
`vocabulary` and leave its data otherwise as it was. At tier 2 no intake
|
|
21
|
+
answer fills it, so a page carrying it keeps `placeholder: true`.
|
|
22
|
+
|
|
23
|
+
## Frontmatter
|
|
24
|
+
|
|
25
|
+
| Key | Tier 1 | Tier 2 |
|
|
26
|
+
| ---------------------- | -------------------------------------------------- | ------------------------------------------- |
|
|
27
|
+
| `title`, `description` | the category's words; the company name from `_site.mdx` where the page names the company | the company name and the owner's answers |
|
|
28
|
+
| `provider.name` | `siteIdentity.name` | `siteIdentity.name` |
|
|
29
|
+
| `schema.serviceType` | the offering `name` | the offering `name` |
|
|
30
|
+
| `schema.areaServed` | removed | the `service_area` answer |
|
|
31
|
+
| `price`, `priceCurrency`, `availability`, `stripe` | removed | only a price the owner gave, with its currency |
|
|
32
|
+
| `placeholder` | `true` | by the rule in `SKILL.md` Step 2.4 |
|
|
33
|
+
|
|
34
|
+
## Pricing words (Service bodies, FAQ answers)
|
|
35
|
+
|
|
36
|
+
| `pricing` | Say |
|
|
37
|
+
| -------------- | ------------------------------------------------------------------- |
|
|
38
|
+
| `quote` | priced after a look at the job; the quote is given before work starts |
|
|
39
|
+
| `fixed` | one fixed price for the job, agreed before work starts |
|
|
40
|
+
| `hourly` | charged by the hour on site, with the call-out rate stated up front |
|
|
41
|
+
| `subscription` | a regular plan, billed on a schedule |
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: setup-deploy
|
|
3
3
|
description: Emit deploy configuration for an AILK consumer site — `vercel.json`, `.env.example`, and `RUNBOOK.md`. Vercel-only at v1; other platforms reject with a clear "not yet supported" message. Use when the user asks "set up Vercel", "provision deploy config", "what env vars do I need for production?", "I'm ready to ship to Vercel", or otherwise asks about pre-deploy file setup. The RUNBOOK includes the three named persistence-upgrade paths for leads.jsonl (Vercel KV / Supabase / Postgres-via-`@working-theory/database`).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# setup-deploy
|
|
7
7
|
|
|
8
8
|
Emit `vercel.json`, `.env.example`, and `RUNBOOK.md` at the consumer's
|
|
9
9
|
project root, ready for a Vercel deploy. Vercel is the only valid
|
|
@@ -64,7 +64,7 @@ Skip this skill when:
|
|
|
64
64
|
Default platform is `vercel`. If the consumer asks for any other
|
|
65
65
|
platform, respond:
|
|
66
66
|
|
|
67
|
-
> "`
|
|
67
|
+
> "`setup-deploy` is Vercel-only at v1. Netlify / Cloudflare /
|
|
68
68
|
> Render / Fly / self-host support are tracked at the upstream repo —
|
|
69
69
|
> file an issue at <https://github.com/working-theory-labs/ai-launch-kit/issues>
|
|
70
70
|
> if your platform is missing.
|
|
@@ -100,7 +100,7 @@ Wait for the consumer's choice per file. Do not blindly overwrite.
|
|
|
100
100
|
**Merge logic — `.env.example`:** if a var listed in
|
|
101
101
|
`references/env-vars-template.md` is **missing** from the existing
|
|
102
102
|
file, append it (with comment) at the bottom under a "## Added by
|
|
103
|
-
|
|
103
|
+
setup-deploy" section. Vars already present are not modified.
|
|
104
104
|
|
|
105
105
|
**Merge logic — `RUNBOOK.md`:** if any of the three named
|
|
106
106
|
persistence sections (Vercel KV, Supabase,
|
|
@@ -144,7 +144,7 @@ NextAuth secrets.
|
|
|
144
144
|
After write, count the declared vars and confirm the count matches
|
|
145
145
|
the template's expected count. If a var the consumer's site uses
|
|
146
146
|
(grep `process.env.X` from a quick scan) is missing from the
|
|
147
|
-
template, add it under "## Added by
|
|
147
|
+
template, add it under "## Added by setup-deploy" — never silently
|
|
148
148
|
omit a var the consumer needs.
|
|
149
149
|
|
|
150
150
|
### Step 6 — Emit `RUNBOOK.md`
|
|
@@ -168,7 +168,7 @@ runbook has these sections:
|
|
|
168
168
|
RDS). When to pick.
|
|
169
169
|
6. **Custom domain + DNS** — pointer at Vercel's domain docs.
|
|
170
170
|
7. **Production callbacks for OAuth** — for consumers who used
|
|
171
|
-
`
|
|
171
|
+
`add-auth` and need to register prod redirect URIs.
|
|
172
172
|
|
|
173
173
|
After write, grep the RUNBOOK for the three named persistence
|
|
174
174
|
section headings (Vercel KV, Supabase,
|
|
@@ -214,7 +214,7 @@ If any check fails, surface the failure to the consumer (not silent).
|
|
|
214
214
|
`vercel deploy`'s job.
|
|
215
215
|
- That env-var values in the consumer's Vercel dashboard are
|
|
216
216
|
correct or live. The skill never reads dashboard state.
|
|
217
|
-
- That OAuth callback URLs in `
|
|
217
|
+
- That OAuth callback URLs in `add-auth`'s RUNBOOK are
|
|
218
218
|
registered in production OAuth apps. That's the consumer's job
|
|
219
219
|
pre-launch.
|
|
220
220
|
|
|
@@ -228,7 +228,7 @@ If any check fails, surface the failure to the consumer (not silent).
|
|
|
228
228
|
|
|
229
229
|
## Coordination
|
|
230
230
|
|
|
231
|
-
- **`
|
|
231
|
+
- **`add-auth`** — produces its own `RUNBOOK.md`
|
|
232
232
|
sections for OAuth setup (dev callback URLs). This skill's
|
|
233
233
|
RUNBOOK adds production callback URLs and merges with any
|
|
234
234
|
existing runbook content (not blindly overwrites).
|
package/templates/.claude/skills/{provision-config → setup-deploy}/references/env-vars-template.md
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `.env.example` Template
|
|
2
2
|
|
|
3
|
-
The structure the `
|
|
3
|
+
The structure the `setup-deploy` skill emits at the consumer's
|
|
4
4
|
project root. Placeholder values only — the skill never echoes a
|
|
5
5
|
real secret.
|
|
6
6
|
|
|
@@ -177,7 +177,7 @@ Step 3) offers merge / overwrite / skip. Merge logic:
|
|
|
177
177
|
4. Vars **missing** are appended at the end of the existing file
|
|
178
178
|
under a new section:
|
|
179
179
|
```
|
|
180
|
-
# ── Added by
|
|
180
|
+
# ── Added by setup-deploy ────────────────────────────────
|
|
181
181
|
```
|
|
182
182
|
|
|
183
183
|
This avoids duplicating vars while still surfacing additions the
|
package/templates/.claude/skills/{provision-config → setup-deploy}/references/runbook-template.md
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `RUNBOOK.md` Template
|
|
2
2
|
|
|
3
|
-
The `
|
|
3
|
+
The `setup-deploy` skill emits this runbook at the consumer's
|
|
4
4
|
project root. It documents pre-deploy steps, the **critical**
|
|
5
5
|
leads-persistence caveat, and the three named upgrade paths.
|
|
6
6
|
|
|
@@ -13,12 +13,12 @@ missing, the skill has a bug.
|
|
|
13
13
|
```markdown
|
|
14
14
|
# RUNBOOK — Production Operations
|
|
15
15
|
|
|
16
|
-
This runbook is generated by the `
|
|
16
|
+
This runbook is generated by the `setup-deploy` skill. It covers
|
|
17
17
|
what to do before and after deploying to Vercel, plus the
|
|
18
18
|
operational caveats AILK ships with.
|
|
19
19
|
|
|
20
|
-
If you re-run `
|
|
21
|
-
the end under "## Added by
|
|
20
|
+
If you re-run `setup-deploy`, new sections may be appended at
|
|
21
|
+
the end under "## Added by setup-deploy." Existing sections are
|
|
22
22
|
not modified by the skill.
|
|
23
23
|
|
|
24
24
|
---
|
|
@@ -40,7 +40,7 @@ Before you click Deploy in Vercel:
|
|
|
40
40
|
your site captures leads. AILK's default `leads.jsonl`
|
|
41
41
|
fallback does not persist on Vercel's ephemeral filesystem.
|
|
42
42
|
- [ ] **Register production OAuth callbacks** if you used
|
|
43
|
-
`
|
|
43
|
+
`add-auth` and activated Google or GitHub. Each provider
|
|
44
44
|
needs the prod callback URL added to its OAuth app settings.
|
|
45
45
|
|
|
46
46
|
---
|
|
@@ -160,9 +160,9 @@ Domains → Add → DNS records → wait for verification.
|
|
|
160
160
|
|
|
161
161
|
---
|
|
162
162
|
|
|
163
|
-
## Production callbacks for OAuth (if you used `
|
|
163
|
+
## Production callbacks for OAuth (if you used `add-auth`)
|
|
164
164
|
|
|
165
|
-
If you activated Google or GitHub OAuth via `
|
|
165
|
+
If you activated Google or GitHub OAuth via `add-auth`,
|
|
166
166
|
those activations used dev callback URLs (`localhost:3000`). For
|
|
167
167
|
production, add the prod callback URLs to each OAuth app:
|
|
168
168
|
|
|
@@ -240,7 +240,7 @@ Step 3) offers merge / overwrite / skip. Merge logic:
|
|
|
240
240
|
3. Headings already present → not modified.
|
|
241
241
|
4. Headings missing → append at the end of the existing file under:
|
|
242
242
|
```
|
|
243
|
-
## Added by
|
|
243
|
+
## Added by setup-deploy
|
|
244
244
|
```
|
|
245
245
|
|
|
246
246
|
The pre-deploy checklist, custom-domain, and OAuth-prod-callbacks
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `vercel.json` Template
|
|
2
2
|
|
|
3
|
-
The minimal viable Vercel config the `
|
|
3
|
+
The minimal viable Vercel config the `setup-deploy` skill emits.
|
|
4
4
|
Customization beyond this template is the consumer's responsibility —
|
|
5
5
|
the skill's job is to ship the consumer with a working baseline.
|
|
6
6
|
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upgrade-plan
|
|
3
|
+
description: Explain the AI Launch Kit options — Free, Pro, Pro Plus, Agency and the commerce add-on's three rungs (Commerce, SaaS, SaaS with Usage) — side by side, with the prices the public pricing page publishes right now, read this site's own modules and shape, and recommend exactly one option with a reason. Use when the user asks "what does Pro get me?", "should I upgrade?", "compare plans", "which plan do I need?", "how much is commerce?", or types /upgrade-plan. The skill reads and explains only — it never buys, never installs, and never states a price from memory.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# upgrade-plan
|
|
7
|
+
|
|
8
|
+
Answer "what does a paid level get me, and which one should I buy?" from two
|
|
9
|
+
live sources: the public pricing page (for prices) and this repository (for
|
|
10
|
+
what the site actually uses). A bundled helper does the reading and the
|
|
11
|
+
choosing; this skill runs it and explains the result in plain words.
|
|
12
|
+
|
|
13
|
+
## When to use
|
|
14
|
+
|
|
15
|
+
- "what does Pro get me?" / "what's in Pro Plus?"
|
|
16
|
+
- "should I upgrade?" / "which plan do I need?"
|
|
17
|
+
- "compare the plans" / "how does Agency work?"
|
|
18
|
+
- "can I sell things on my site?" / "how much is the commerce add-on?"
|
|
19
|
+
- `/upgrade-plan`
|
|
20
|
+
|
|
21
|
+
Skip this skill when the user wants to actually buy or install something —
|
|
22
|
+
this skill explains and recommends; the purchase happens on the pricing
|
|
23
|
+
page, and installing a module is a separate step (see "What happens next").
|
|
24
|
+
|
|
25
|
+
## The mechanic
|
|
26
|
+
|
|
27
|
+
### Step 1 — Map the user's stated need (optional)
|
|
28
|
+
|
|
29
|
+
If the user said what they want to do, map it to one `--need` value:
|
|
30
|
+
|
|
31
|
+
| The user says… | `--need` |
|
|
32
|
+
| ------------------------------------------------- | -------------- |
|
|
33
|
+
| "I build sites for clients" | `agency` |
|
|
34
|
+
| "I want to sell / take payments" | `sell` |
|
|
35
|
+
| "my product bills its own customers on plans" | `saas` |
|
|
36
|
+
| "I bill my customers by usage / credits" | `usage` |
|
|
37
|
+
| "I need docs or a blog" | `docs` |
|
|
38
|
+
| "I need booking / scheduling" | `scheduling` |
|
|
39
|
+
| "I need organizations / teams / many workspaces" | `multi-tenant` |
|
|
40
|
+
|
|
41
|
+
If the need maps to none of these, omit `--need`, and tell the user which
|
|
42
|
+
need you could not map — the recommendation then comes from the site alone.
|
|
43
|
+
|
|
44
|
+
### Step 2 — Run the helper
|
|
45
|
+
|
|
46
|
+
From the project root:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm exec tsx .claude/skills/upgrade-plan/scripts/upgrade-plan.ts [--need <value>]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
It prints one JSON object:
|
|
53
|
+
|
|
54
|
+
- `pricing.status` — `ok` (the page published prices), `unpublished` (the
|
|
55
|
+
page loaded but carries no machine-readable offers) or `unreachable`
|
|
56
|
+
(network error, timeout or error status). `pricing.url` is the link to give
|
|
57
|
+
the user.
|
|
58
|
+
- `options[]` — the seven options, always all seven, each with `adds`,
|
|
59
|
+
`requires`, and `prices[]` (empty, with `status: "not published on the
|
|
60
|
+
pricing page"`, when the page does not price it).
|
|
61
|
+
- `alsoPublished[]` — other offers on the pricing page that are none of the
|
|
62
|
+
seven (for example a one-off service), with their published price.
|
|
63
|
+
- `site` — this site's `modules`, `template`, `shape`, `design`, whether it
|
|
64
|
+
already prices something (`sellsSomething`), whether commerce is installed,
|
|
65
|
+
and whether `AILK_LICENSE_KEY` is set in this shell (`licenseKeySet` —
|
|
66
|
+
presence only, never the value).
|
|
67
|
+
- `recommendation` — one `option`, its `reason`, and its `link`.
|
|
68
|
+
|
|
69
|
+
Exit status 0 in all three pricing states. Exit 2 is a usage error — re-run
|
|
70
|
+
without the argument it names.
|
|
71
|
+
|
|
72
|
+
### Step 3 — Explain it
|
|
73
|
+
|
|
74
|
+
Answer in this order, in plain words:
|
|
75
|
+
|
|
76
|
+
1. **Your site.** State the shape and the modules from `site`, the template
|
|
77
|
+
and design when recorded, whether it already prices anything, and whether
|
|
78
|
+
a licence key is set in this shell. A `null` field is "not recorded —
|
|
79
|
+
scaffolded without `--template`"; never guess a shape. If the key is not
|
|
80
|
+
set, say "not set in this shell" (a key kept only in `.env` reads that way).
|
|
81
|
+
2. **The options, side by side.** A table of all seven options: name, what it
|
|
82
|
+
adds, what it requires, and its price exactly as `prices[]` gives it
|
|
83
|
+
(figure, currency and unit text). An option with no price reads
|
|
84
|
+
"not published on the pricing page — see https://ailaunchkit.ai/pricing".
|
|
85
|
+
Then list `alsoPublished` under "Also on the pricing page".
|
|
86
|
+
3. **The recommendation.** Exactly one option — `recommendation.option` —
|
|
87
|
+
with its reason, naming the module or need that decided it. Do not offer a
|
|
88
|
+
second recommendation; you may say what would change it (for example "if
|
|
89
|
+
you add multi-tenant later, that moves you to Pro Plus").
|
|
90
|
+
4. **What happens next.** Link `recommendation.link`. After purchase the
|
|
91
|
+
licence key arrives by email; set it as `AILK_LICENSE_KEY` in your
|
|
92
|
+
environment. To install the module(s): run
|
|
93
|
+
`pnpm dlx create-ailk@latest --help`, and name `add-module` only if that
|
|
94
|
+
output lists it. Otherwise say: re-run `create-ailk` with
|
|
95
|
+
`--modules <module>` and the key set, into a new directory, and move your
|
|
96
|
+
content across.
|
|
97
|
+
|
|
98
|
+
## Hard rules
|
|
99
|
+
|
|
100
|
+
- **Never state a price that is not in the helper's output for this run.**
|
|
101
|
+
Not from memory, not from an earlier run, not from another page, not as an
|
|
102
|
+
estimate or a range. A price appears in your answer only if it appears in
|
|
103
|
+
this run's `options[].prices` or `alsoPublished`.
|
|
104
|
+
- **Unreachable means no prices.** When `pricing.status` is `unreachable`,
|
|
105
|
+
say the pricing page could not be reached, give no price for any option,
|
|
106
|
+
and link https://ailaunchkit.ai/pricing. Still show the site and the
|
|
107
|
+
recommendation — neither depends on a price.
|
|
108
|
+
- **Unpublished means no prices.** When `pricing.status` is `unpublished`,
|
|
109
|
+
say the pricing page does not publish machine-readable prices yet and link
|
|
110
|
+
https://ailaunchkit.ai/pricing.
|
|
111
|
+
- **Read-only.** Write no file and install nothing. The only outside command
|
|
112
|
+
besides the helper is the `--help` probe in step 3.
|
|
113
|
+
- **Never print the licence key.** Report only whether it is set.
|
|
114
|
+
|
|
115
|
+
## References
|
|
116
|
+
|
|
117
|
+
- `references/options.md` — the seven options in plain words.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# The options
|
|
2
|
+
|
|
3
|
+
What each option adds and what it requires, in plain words. Names and
|
|
4
|
+
structure only — prices come from https://ailaunchkit.ai/pricing at run time,
|
|
5
|
+
never from this file.
|
|
6
|
+
|
|
7
|
+
Source: the AI Launch Kit product vocabulary (Commerce; Packaging and
|
|
8
|
+
delivery). Levels are Free, Pro and Pro Plus; Agency is an agreement, not a
|
|
9
|
+
level; Commerce, SaaS and SaaS with Usage are the three rungs of the one
|
|
10
|
+
commerce add-on, bought on top of a level.
|
|
11
|
+
|
|
12
|
+
| Option | What it adds | Requires |
|
|
13
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------- |
|
|
14
|
+
| **Free** | The open-source base: the website, its API and MCP server, and the marketing module. Every site is agent-discoverable at this level. | Nothing — no licence key |
|
|
15
|
+
| **Pro** | The paid modules for one site — docs and blog, scheduling, signal collectors, the Admin app — kept current. | A licence key for the site |
|
|
16
|
+
| **Pro Plus** | Everything in Pro, plus the multi-tenant module: organizations, workspaces and members. | A licence key for the site |
|
|
17
|
+
| **Agency** | A reseller agreement for building sites for clients. Not a bigger level. | Each client site is licensed Pro or Pro Plus |
|
|
18
|
+
| **Commerce** | Checkout, payment links, hosted invoices, subscriptions and the customer portal, through your own Stripe account. | Any paid level (Pro or Pro Plus) |
|
|
19
|
+
| **SaaS** | Commerce plus plans, trials, coupons and entitlements mapped to feature flags — for a product that bills its tenants. | Pro Plus |
|
|
20
|
+
| **SaaS with Usage** | SaaS plus usage metering, prepaid credits, overage and spend limits. | Pro Plus |
|
|
21
|
+
|
|
22
|
+
Payment always happens on a Stripe-hosted page; the site never renders a card
|
|
23
|
+
form. Paid bookings (deposits, no-show holds) belong to the scheduling module,
|
|
24
|
+
not to Commerce.
|