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.
Files changed (248) hide show
  1. package/README.md +44 -5
  2. package/component-catalog.json +146 -21
  3. package/component-catalog.md +9 -6
  4. package/dist/add-module-core.d.ts +22 -0
  5. package/dist/add-module-core.js +50 -0
  6. package/dist/add-module.d.ts +89 -0
  7. package/dist/add-module.js +334 -0
  8. package/dist/category-profile.d.ts +126 -0
  9. package/dist/category-profile.js +262 -0
  10. package/dist/cli.js +124 -13
  11. package/dist/copy.d.ts +14 -0
  12. package/dist/copy.js +38 -1
  13. package/dist/index.d.ts +4 -2
  14. package/dist/index.js +6 -1
  15. package/dist/lib/extract-module-bundle.d.ts +76 -2
  16. package/dist/lib/extract-module-bundle.js +219 -8
  17. package/dist/lib/license-key-files.d.ts +15 -0
  18. package/dist/lib/license-key-files.js +102 -0
  19. package/dist/lib/module-license-gate.d.ts +6 -1
  20. package/dist/lib/module-license-gate.js +6 -1
  21. package/dist/lib/pro-callout.d.ts +16 -10
  22. package/dist/lib/pro-callout.js +27 -4
  23. package/dist/license-set.d.ts +34 -0
  24. package/dist/license-set.js +194 -0
  25. package/dist/module-architecture.d.ts +20 -0
  26. package/dist/module-architecture.js +77 -19
  27. package/dist/modules/commerce/0.6.0.tar.gz +0 -0
  28. package/dist/modules/commerce/0.6.1.tar.gz +0 -0
  29. package/dist/modules/docs-blog/0.6.0.tar.gz +0 -0
  30. package/dist/modules/docs-blog/0.6.1.tar.gz +0 -0
  31. package/dist/modules/marketing-site/0.6.1.tar.gz +0 -0
  32. package/dist/modules/minimalism-site/0.6.1.tar.gz +0 -0
  33. package/dist/modules/multi-tenant/0.6.0.tar.gz +0 -0
  34. package/dist/modules/multi-tenant/0.6.1.tar.gz +0 -0
  35. package/dist/modules/saas-product/0.6.1.tar.gz +0 -0
  36. package/dist/modules/scheduling/0.6.0.tar.gz +0 -0
  37. package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
  38. package/dist/modules/signal-collectors/0.6.0.tar.gz +0 -0
  39. package/dist/modules/signal-collectors/0.6.1.tar.gz +0 -0
  40. package/dist/modules/simple-service/0.6.1.tar.gz +0 -0
  41. package/dist/modules/workspace/0.6.0.tar.gz +0 -0
  42. package/dist/modules/workspace/0.6.1.tar.gz +0 -0
  43. package/dist/parse-args.d.ts +7 -0
  44. package/dist/parse-args.js +23 -1
  45. package/dist/programmatic.d.ts +46 -0
  46. package/dist/programmatic.js +144 -19
  47. package/dist/site-chrome.d.ts +18 -7
  48. package/dist/site-chrome.js +32 -14
  49. package/dist/site-roster.d.ts +127 -0
  50. package/dist/site-roster.js +494 -0
  51. package/dist/surfaces.d.ts +20 -7
  52. package/dist/surfaces.js +149 -28
  53. package/dist/sync-routes.d.ts +9 -0
  54. package/dist/sync-routes.js +2 -2
  55. package/dist/template-manifest.d.ts +58 -2
  56. package/dist/template-manifest.js +196 -69
  57. package/package.json +6 -4
  58. package/site-templates/_base/content/en/BookCall/book-call.mdx +53 -0
  59. package/site-templates/_base/content/en/GlossaryList/glossary.mdx +66 -0
  60. package/site-templates/_base/content/en/NewsletterSignup/newsletter.mdx +68 -0
  61. package/site-templates/_base/content/en/Pricing/pricing.mdx +71 -62
  62. package/site-templates/_base/content/en/PrivacyPage/privacy.mdx +2 -3
  63. package/site-templates/_base/content/en/TermsPage/terms.mdx +2 -3
  64. package/site-templates/_base/content/en/UseCase/first-use-case.mdx +23 -0
  65. package/site-templates/_base/content/en/UseCase/second-use-case.mdx +23 -0
  66. package/site-templates/_base/content/en/UseCase/third-use-case.mdx +23 -0
  67. package/site-templates/designs/minimalism/DESIGN.md +162 -0
  68. package/site-templates/designs/standard/DESIGN.md +162 -0
  69. package/site-templates/marketing-site/DESIGN.md +162 -0
  70. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +312 -57
  71. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +209 -90
  72. package/site-templates/marketing-site/ailk-template.json +1 -0
  73. package/site-templates/marketing-site-free/DESIGN.md +162 -0
  74. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +260 -66
  75. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +294 -114
  76. package/site-templates/marketing-site-free/ailk-template.json +3 -2
  77. package/site-templates/minimalism-site/DESIGN.md +162 -0
  78. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +246 -19
  79. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +185 -51
  80. package/site-templates/minimalism-site/ailk-template.json +3 -2
  81. package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +53 -0
  82. package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +3 -37
  83. package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +124 -0
  84. package/site-templates/saas-product/DESIGN.md +162 -0
  85. package/site-templates/simple-service/DESIGN.md +162 -0
  86. package/site-templates/simple-service/TEMPLATE-MANIFEST.json +135 -26
  87. package/site-templates/simple-service/TEMPLATE-MANIFEST.md +114 -59
  88. package/site-templates/simple-service/ailk-template.json +4 -3
  89. package/site-templates/simple-service/content/en/BookCall/book-call.mdx +53 -0
  90. package/site-templates/simple-service/content/en/ContactPage/contact.mdx +1 -36
  91. package/site-templates/simple-service/content/en/PurchasePolicyPage/purchase-policy.mdx +124 -0
  92. package/templates/.claude/settings.json +15 -0
  93. package/templates/.claude/skills/README.md +8 -8
  94. package/templates/.claude/skills/{scaffold-auth → add-auth}/SKILL.md +7 -7
  95. package/templates/.claude/skills/{scaffold-auth → add-auth}/references/env-vars.md +2 -2
  96. package/templates/.claude/skills/{scaffold-auth → add-auth}/references/oauth-app-setup.md +3 -3
  97. package/templates/.claude/skills/{scaffold-page → add-page}/SKILL.md +76 -62
  98. package/templates/.claude/skills/add-page/references/page-types.md +111 -0
  99. package/templates/.claude/skills/{scaffold-page → add-page}/templates/content.mdx.tmpl +4 -4
  100. package/templates/.claude/skills/{scaffold-page → add-page}/templates/route.tsx.tmpl +1 -1
  101. package/templates/.claude/skills/{audit-site → check-site}/SKILL.md +16 -17
  102. package/templates/.claude/skills/{audit-site → check-site}/references/common-errors.md +3 -3
  103. package/templates/.claude/skills/{audit-site → check-site}/references/findings-glossary.md +16 -14
  104. package/templates/.claude/skills/{audit-site → check-site}/references/severity-levels.md +1 -1
  105. package/templates/.claude/skills/fill-page/SKILL.md +180 -0
  106. package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +80 -0
  107. package/templates/.claude/skills/fill-page/references/section-sources.md +41 -0
  108. package/templates/.claude/skills/{provision-config → setup-deploy}/SKILL.md +8 -8
  109. package/templates/.claude/skills/{provision-config → setup-deploy}/references/env-vars-template.md +2 -2
  110. package/templates/.claude/skills/{provision-config → setup-deploy}/references/runbook-template.md +8 -8
  111. package/templates/.claude/skills/{provision-config → setup-deploy}/references/vercel-json-template.md +1 -1
  112. package/templates/.claude/skills/upgrade-plan/SKILL.md +117 -0
  113. package/templates/.claude/skills/upgrade-plan/references/options.md +24 -0
  114. package/templates/.claude/skills/upgrade-plan/scripts/upgrade-plan.ts +527 -0
  115. package/templates/.github/workflows/ci.yml +5 -0
  116. package/templates/CLAUDE.md +10 -5
  117. package/templates/DESIGN.md +162 -0
  118. package/templates/README.md +134 -38
  119. package/templates/apps/api/.env.example +2 -1
  120. package/templates/apps/api/package.json +1 -1
  121. package/templates/apps/api/src/config/__tests__/index.test.ts +37 -2
  122. package/templates/apps/api/src/config/index.ts +19 -6
  123. package/templates/apps/api/src/lib/license-key-store.ts +45 -0
  124. package/templates/apps/api/src/lib/site.ts +5 -3
  125. package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +97 -0
  126. package/templates/apps/api/src/middleware/auth.ts +9 -0
  127. package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +127 -5
  128. package/templates/apps/api/src/routes/content/get-page.ts +86 -2
  129. package/templates/apps/api/src/server.ts +6 -0
  130. package/templates/apps/mcp/__tests__/audit-single-page.test.ts +75 -1
  131. package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +57 -9
  132. package/templates/apps/mcp/package.json +2 -1
  133. package/templates/apps/mcp/src/index.ts +7 -0
  134. package/templates/apps/mcp/src/lib/audit-single-page.ts +36 -10
  135. package/templates/apps/mcp/src/lib/license-key-store.ts +45 -0
  136. package/templates/apps/web/PRODUCT.md +86 -0
  137. package/templates/apps/web/__tests__/setup.ts +18 -0
  138. package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +10 -2
  139. package/templates/apps/web/app/[locale]/(auth)/layout.tsx +2 -2
  140. package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +10 -4
  141. package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +22 -14
  142. package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +26 -18
  143. package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +12 -4
  144. package/templates/apps/web/app/[locale]/[slug]/__tests__/page.test.tsx +35 -4
  145. package/templates/apps/web/app/[locale]/[slug]/page.tsx +49 -9
  146. package/templates/apps/web/app/[locale]/book-a-call/page.tsx +50 -0
  147. package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +3 -3
  148. package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +3 -3
  149. package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +3 -4
  150. package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +94 -33
  151. package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +53 -23
  152. package/templates/apps/web/app/[locale]/contact/__tests__/ContactForm.test.tsx +96 -0
  153. package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +84 -2
  154. package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +5 -6
  155. package/templates/apps/web/app/[locale]/contact/page.tsx +25 -7
  156. package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +3 -3
  157. package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +3 -4
  158. package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +4 -5
  159. package/templates/apps/web/app/[locale]/glossary/page.tsx +50 -0
  160. package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
  161. package/templates/apps/web/app/[locale]/how-to/page.tsx +25 -15
  162. package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +3 -3
  163. package/templates/apps/web/app/[locale]/layout.tsx +113 -51
  164. package/templates/apps/web/app/[locale]/newsletter/page.tsx +50 -0
  165. package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +3 -3
  166. package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +3 -3
  167. package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +4 -5
  168. package/templates/apps/web/app/[locale]/{shipping → purchase-policy}/page.tsx +15 -10
  169. package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +4 -5
  170. package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +3 -3
  171. package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +14 -1
  172. package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
  173. package/templates/apps/web/app/[locale]/software/page.tsx +25 -15
  174. package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
  175. package/templates/apps/web/app/[locale]/tech-articles/page.tsx +25 -15
  176. package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +3 -4
  177. package/templates/apps/web/app/[locale]/use-cases/[slug]/page.tsx +48 -0
  178. package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +3 -4
  179. package/templates/apps/web/app/[locale]/use-cases/page.tsx +15 -2
  180. package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
  181. package/templates/apps/web/app/[locale]/whitepapers/page.tsx +25 -15
  182. package/templates/apps/web/app/error-fallback.tsx +17 -45
  183. package/templates/apps/web/app/not-found.tsx +14 -38
  184. package/templates/apps/web/app/og/route.tsx +6 -0
  185. package/templates/apps/web/eslint.config.mjs +3 -0
  186. package/templates/apps/web/instrumentation.ts +14 -0
  187. package/templates/apps/web/lib/__tests__/site-theme.test.ts +135 -20
  188. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +38 -0
  189. package/templates/apps/web/lib/license-key-store.ts +52 -0
  190. package/templates/apps/web/lib/nav-config.ts +64 -12
  191. package/templates/apps/web/lib/prisma-for-auth.ts +9 -6
  192. package/templates/apps/web/lib/site-brand.tsx +4 -8
  193. package/templates/apps/web/lib/site-chrome.ts +3 -3
  194. package/templates/apps/web/lib/site-identity.ts +134 -0
  195. package/templates/apps/web/lib/site-theme.ts +11 -0
  196. package/templates/apps/web/messages/en.json +52 -37
  197. package/templates/apps/web/middleware.ts +1 -1
  198. package/templates/apps/web/public/android-chrome-192x192.png +0 -0
  199. package/templates/apps/web/public/android-chrome-512x512.png +0 -0
  200. package/templates/apps/web/public/apple-touch-icon.png +0 -0
  201. package/templates/apps/web/public/favicon-16x16.png +0 -0
  202. package/templates/apps/web/public/favicon-32x32.png +0 -0
  203. package/templates/apps/web/public/favicon.ico +0 -0
  204. package/templates/apps/web/public/favicon.svg +3 -3
  205. package/templates/apps/web/public/logomark.svg +6 -3
  206. package/templates/apps/web/public/logos/ai-launch-kit-light.svg +4 -0
  207. package/templates/apps/web/public/logos/ai-launch-kit.svg +4 -0
  208. package/templates/apps/web/public/logos/atomic-agent-light.svg +4 -0
  209. package/templates/apps/web/public/logos/atomic-agent.svg +4 -0
  210. package/templates/apps/web/public/logos/salessmyth-light.svg +4 -0
  211. package/templates/apps/web/public/logos/salessmyth.svg +4 -0
  212. package/templates/apps/web/public/site.webmanifest +4 -4
  213. package/templates/apps/web/public/wordmark-light.svg +4 -0
  214. package/templates/apps/web/public/wordmark.svg +3 -3
  215. package/templates/apps/web/security-headers.config.ts +5 -1
  216. package/templates/apps/web/src/lib/commerce-sections.ts +35 -3
  217. package/templates/content/_site.mdx +41 -3
  218. package/templates/content/en/AboutPage/about.mdx +150 -144
  219. package/templates/content/en/BlogList/blog.mdx +105 -0
  220. package/templates/content/en/ContactPage/contact.mdx +44 -85
  221. package/templates/content/en/FAQPage/faq.mdx +86 -57
  222. package/templates/content/en/HomePage/home.mdx +276 -217
  223. package/templates/content/en/PurchasePolicyPage/purchase-policy.mdx +182 -0
  224. package/templates/content/en/SoftwareProduct/product.mdx +175 -0
  225. package/templates/content/en/UseCasesList/use-cases.mdx +170 -0
  226. package/templates/database/CHANGELOG.md +14 -0
  227. package/templates/database/package.json +3 -2
  228. package/templates/package.json +3 -1
  229. package/templates/tools/lint-architecture.ts +315 -0
  230. package/templates/tools/tsconfig.json +14 -0
  231. package/versions.json +33 -33
  232. package/templates/.claude/skills/add-schema/SKILL.md +0 -277
  233. package/templates/.claude/skills/add-schema/references/conflict-handling.md +0 -200
  234. package/templates/.claude/skills/add-schema/references/file-finding.md +0 -123
  235. package/templates/.claude/skills/add-schema/references/schema-types.md +0 -234
  236. package/templates/.claude/skills/scaffold-page/references/page-types.md +0 -169
  237. package/templates/.claude/skills/suggest-site-pages/SKILL.md +0 -242
  238. package/templates/.claude/skills/suggest-site-pages/references/categories.md +0 -287
  239. package/templates/apps/web/app/[locale]/cancellation/page.tsx +0 -44
  240. package/templates/apps/web/app/[locale]/returns/page.tsx +0 -44
  241. package/templates/apps/web/public/logo-dark.svg +0 -21
  242. package/templates/apps/web/public/logo-light.svg +0 -21
  243. package/templates/content/en/CancellationPolicyPage/cancellation.mdx +0 -108
  244. package/templates/content/en/LandingPage/blog.mdx +0 -83
  245. package/templates/content/en/LandingPage/features.mdx +0 -103
  246. package/templates/content/en/LandingPage/how-it-works.mdx +0 -143
  247. package/templates/content/en/ReturnsPolicyPage/returns.mdx +0 -108
  248. package/templates/content/en/ShippingPolicyPage/shipping.mdx +0 -108
@@ -1,6 +1,6 @@
1
1
  # Template manifest — `simple-service`
2
2
 
3
- > The T1 lawn-care template (#6087, Epic #5778) — the first site shape that composes `scheduling` and `commerce`: three priced services, a booker, a checkout return pair and the three #5947 policy pages. Generated file: the regions between `<!-- generated:begin <id> -->` and `<!-- generated:end -->` are produced by `scripts/build-template-manifest.mjs --template simple-service` from the composed layer stack (this tree → its required modules → `_base` → the always-copied overlay), each roster row's MDX `sections[]`, and `component-catalog.json`. Everything outside the markers is written by hand.
3
+ > The T1 lawn-care template (#6087, Epic #5778) — the first site shape that composes `scheduling` and `commerce`: three priced services, a booker, a checkout return pair and a purchase policy (cancellation and refunds, #6646). Generated file: the regions between `<!-- generated:begin <id> -->` and `<!-- generated:end -->` are produced by `scripts/build-template-manifest.mjs --template simple-service` from the composed layer stack (this tree → its required modules → `_base` → the always-copied overlay), each roster row's MDX `sections[]`, and `component-catalog.json`. Everything outside the markers is written by hand.
4
4
 
5
5
  | Field | Value |
6
6
  | ---------------------- | ------------------------------------------------------------------------------------------------------------------------- |
@@ -25,11 +25,44 @@ The template's `layout` block — resolved with `resolveSiteChrome`, defaults fi
25
25
  | -------------------- | --------- |
26
26
  | `nav` | `full` |
27
27
  | `footer` | `columns` |
28
- | `announcementBanner` | `true` |
28
+ | `announcementBanner` | `false` |
29
29
  | `home` | `default` |
30
30
 
31
31
  <!-- generated:end -->
32
32
 
33
+ ### Theme (locked)
34
+
35
+ The template's `theme:` block as `_site.mdx` declares it — the shape knobs and the colour overlay. Generated, so a change to a locked template's look is a red `manifest:check`, not a silent drift (starter-template contract R3.5).
36
+
37
+ <!-- generated:begin theme -->
38
+
39
+ | Setting | Value |
40
+ | ------------------------ | ---------- |
41
+ | `corners` | `square` |
42
+ | `eyebrowCase` | `sentence` |
43
+ | `placeholders` | `fill` |
44
+ | `checkmarks` | `plain` |
45
+ | `colors.light.bg` | `#ffffff` |
46
+ | `colors.light.bgMuted` | `#ffffff` |
47
+ | `colors.light.surface` | `#ffffff` |
48
+ | `colors.light.border` | `#000000` |
49
+ | `colors.light.text` | `#000000` |
50
+ | `colors.light.textMuted` | `#333333` |
51
+ | `colors.light.primary` | `#000000` |
52
+ | `colors.light.primaryFg` | `#ffffff` |
53
+ | `colors.light.accent` | `#000000` |
54
+ | `colors.dark.bg` | `#000000` |
55
+ | `colors.dark.bgMuted` | `#000000` |
56
+ | `colors.dark.surface` | `#000000` |
57
+ | `colors.dark.border` | `#ffffff` |
58
+ | `colors.dark.text` | `#ffffff` |
59
+ | `colors.dark.textMuted` | `#cccccc` |
60
+ | `colors.dark.primary` | `#ffffff` |
61
+ | `colors.dark.primaryFg` | `#000000` |
62
+ | `colors.dark.accent` | `#ffffff` |
63
+
64
+ <!-- generated:end -->
65
+
33
66
  ## 2. The money path
34
67
 
35
68
  The whole point of this template is the first roster that takes a booking **and** the payment for it:
@@ -40,7 +73,7 @@ The whole point of this template is the first roster that takes a booking **and*
40
73
  | Booking | `/meet`, `/meet/<slug>`, `/meet/confirmed` — the `scheduling` module's own contributed rows; `/appointments` is the site owner's own list (#6086). |
41
74
  | Payment | a provider-hosted page on the seller's own Stripe account. Nothing on this site renders a card form. |
42
75
  | Return | `/purchase/success` and `/purchase/cancel` — base tree under #6084 D12's shape-2 disposition, gated at request time on the `commerce` licence claim. |
43
- | Policies | `/returns`, `/cancellation`, `/shipping` (#5947) — their seed rides the always-copied overlay. |
76
+ | Policies | `/purchase-policy` (#6646) — cancellation and refunds sections, this template's service-shape override of the overlay's product-shape seed. |
44
77
 
45
78
  ## 3. Pages
46
79
 
@@ -53,7 +86,7 @@ One `page=<route>` region per roster row, generated from the seed file the compo
53
86
  | # | Section | Component | Copy (first line) |
54
87
  | --- | ---------------------------------------------------------- | --------- | ---------------------------------------------- |
55
88
  | 1 | `hero` (centered · eyebrow "{Your service area}" · 2 CTAs) | `Hero` | {Lawn care that turns up when it says it will} |
56
- | 2 | `items` (items ×3) | `Items` | What we do |
89
+ | 2 | `items` (columns=3 · items ×3) | `Items` | What we do |
57
90
  | 3 | `cta` (minimal · 2 CTAs) | `CTA` | Ready for a tidier yard? |
58
91
 
59
92
  <!-- generated:end -->
@@ -65,7 +98,7 @@ One `page=<route>` region per roster row, generated from the seed file the compo
65
98
  | # | Section | Component | Copy (first line) |
66
99
  | --- | -------------------------------------- | --------- | ------------------------ |
67
100
  | 1 | `hero` (centered · eyebrow "Services") | `Hero` | Three jobs, three prices |
68
- | 2 | `items` (items ×3) | `Items` | What we do |
101
+ | 2 | `items` (columns=3 · items ×3) | `Items` | What we do |
69
102
  | 3 | `cta` (minimal · 1 CTA) | `CTA` | Not sure which one? |
70
103
 
71
104
  <!-- generated:end -->
@@ -74,7 +107,7 @@ One `page=<route>` region per roster row, generated from the seed file the compo
74
107
 
75
108
  <!-- generated:begin page=/services/[slug] -->
76
109
 
77
- _Code route — no content, no sections._
110
+ _Detail route over `content/en/Service/` — 3 seed pages: `landscape-design.mdx`, `lawn-maintenance.mdx`, `seasonal-cleanup.mdx`._
78
111
  <!-- generated:end -->
79
112
 
80
113
  `/about`:
@@ -92,11 +125,10 @@ _Code route — no content, no sections._
92
125
 
93
126
  <!-- generated:begin page=/contact -->
94
127
 
95
- | # | Section | Component | Copy (first line) |
96
- | --- | ------------------------------------- | ------------- | -------------------------------- |
97
- | 1 | `hero` (centered · eyebrow "Contact") | `Hero` | Tell us about the yard |
98
- | 2 | `contact-form` (card · fields ×3) | `ContactForm` | Name · Email · What needs doing? |
99
- | 3 | `cta` (minimal · 1 CTA) | `CTA` | Would a visit be faster? |
128
+ | # | Section | Component | Copy (first line) |
129
+ | --- | ------------------------------------- | --------- | ------------------------ |
130
+ | 1 | `hero` (centered · eyebrow "Contact") | `Hero` | Tell us about the yard |
131
+ | 2 | `cta` (minimal · 1 CTA) | `CTA` | Would a visit be faster? |
100
132
 
101
133
  <!-- generated:end -->
102
134
 
@@ -111,33 +143,45 @@ _Code route — no content, no sections._
111
143
 
112
144
  <!-- generated:end -->
113
145
 
114
- `/returns`:
146
+ `/glossary`, `/newsletter` (base-layer seeds every starter carries, #6658 D5):
115
147
 
116
- <!-- generated:begin page=/returns -->
148
+ <!-- generated:begin page=/glossary -->
117
149
 
118
- | # | Section | Component | Copy (first line) |
119
- | --- | ------------------ | ----------------- | ----------------- |
120
- | 1 | `document-chassis` | `DocumentChassis` | Returns & Refunds |
150
+ | # | Section | Component | Copy (first line) |
151
+ | --- | ----------------------------------- | --------------- | -------------------------------------------- |
152
+ | 1 | `hero` (eyebrow "Glossary" · 1 CTA) | `Hero` | {Glossary: the terms your customers look up} |
153
+ | 2 | `glossary-index` (columns) | `GlossaryIndex` | {Terms, A to Z} |
121
154
 
122
155
  <!-- generated:end -->
123
156
 
124
- `/cancellation`:
157
+ <!-- generated:begin page=/newsletter -->
158
+
159
+ | # | Section | Component | Copy (first line) |
160
+ | --- | ------------------------------------- | ------------ | ------------------------------------------------ |
161
+ | 1 | `hero` (eyebrow "Newsletter" · 1 CTA) | `Hero` | {Newsletter: what subscribers get and how often} |
162
+ | 2 | `newsletter` | `Newsletter` | Subscribe |
163
+ | 3 | `faq` (expanded · items ×3) | `FAQ` | FAQs |
164
+
165
+ <!-- generated:end -->
125
166
 
126
- <!-- generated:begin page=/cancellation -->
167
+ `/book-a-call` (this template's own override of the base seed — the call to action opens the `/meet` booker the scheduling module supplies, not `/contact`):
127
168
 
128
- | # | Section | Component | Copy (first line) |
129
- | --- | ------------------ | ----------------- | ------------------- |
130
- | 1 | `document-chassis` | `DocumentChassis` | Cancellation Policy |
169
+ <!-- generated:begin page=/book-a-call -->
170
+
171
+ | # | Section | Component | Copy (first line) |
172
+ | --- | -------------------------------------- | --------- | ------------------------------------------ |
173
+ | 1 | `hero` (eyebrow "Book a call" · 1 CTA) | `Hero` | {Book a call: what a visitor gets from it} |
174
+ | 2 | `items` (columns=3 · items ×3) | `Items` | What happens on the call? |
131
175
 
132
176
  <!-- generated:end -->
133
177
 
134
- `/shipping`:
178
+ `/purchase-policy`:
135
179
 
136
- <!-- generated:begin page=/shipping -->
180
+ <!-- generated:begin page=/purchase-policy -->
137
181
 
138
- | # | Section | Component | Copy (first line) |
139
- | --- | ------------------ | ----------------- | ----------------- |
140
- | 1 | `document-chassis` | `DocumentChassis` | Shipping Policy |
182
+ | # | Section | Component | Copy (first line) |
183
+ | --- | ----------------------------------- | ----------------- | ----------------- |
184
+ | 1 | `document-chassis` (layout=article) | `DocumentChassis` | Purchase Policy |
141
185
 
142
186
  <!-- generated:end -->
143
187
 
@@ -145,9 +189,9 @@ _Code route — no content, no sections._
145
189
 
146
190
  <!-- generated:begin page=/privacy -->
147
191
 
148
- | # | Section | Component | Copy (first line) |
149
- | --- | ------------------------------------------------------------------ | ----------------- | ----------------- |
150
- | 1 | `document-chassis` (eyebrow "PLACEHOLDER — REPLACE BEFORE LAUNCH") | `DocumentChassis` | Privacy Policy |
192
+ | # | Section | Component | Copy (first line) |
193
+ | --- | ----------------------------------- | ----------------- | ----------------- |
194
+ | 1 | `document-chassis` (layout=article) | `DocumentChassis` | Privacy Policy |
151
195
 
152
196
  <!-- generated:end -->
153
197
 
@@ -155,9 +199,9 @@ _Code route — no content, no sections._
155
199
 
156
200
  <!-- generated:begin page=/terms -->
157
201
 
158
- | # | Section | Component | Copy (first line) |
159
- | --- | ------------------------------------------------------------------ | ----------------- | ----------------- |
160
- | 1 | `document-chassis` (eyebrow "PLACEHOLDER — REPLACE BEFORE LAUNCH") | `DocumentChassis` | Terms of Service |
202
+ | # | Section | Component | Copy (first line) |
203
+ | --- | ----------------------------------- | ----------------- | ----------------- |
204
+ | 1 | `document-chassis` (layout=article) | `DocumentChassis` | Terms of Service |
161
205
 
162
206
  <!-- generated:end -->
163
207
 
@@ -182,6 +226,13 @@ _Code route — no content, no sections._
182
226
  _Code route — no content, no sections._
183
227
  <!-- generated:end -->
184
228
 
229
+ `/thanks/[slug]`:
230
+
231
+ <!-- generated:begin page=/thanks/[slug] -->
232
+
233
+ _Code route — no content, no sections._
234
+ <!-- generated:end -->
235
+
185
236
  `/meet`:
186
237
 
187
238
  <!-- generated:begin page=/meet -->
@@ -212,7 +263,7 @@ _Code route — no content, no sections._
212
263
 
213
264
  ## 4. Roster, as the registry declares it
214
265
 
215
- `simple-service` is the second declared template that does not reuse `TEMPLATE_BASE_ROSTER`: a lawn-care site sells three named services from `/services`, not from a pricing table, so `/how-it-works`, `/features` and `/pricing` are not pages this site has. `/pricing`'s absence is not a missing file — the `_base` layer still lands `content/en/Pricing/pricing.mdx`; the roster is what the template IS, so an unrostered page simply has no route directory copied. The merged roster, as the registry composes it:
266
+ `simple-service` is the second declared template that does not reuse `TEMPLATE_BASE_ROSTER`: a lawn-care site sells three named services from `/services`, not from a pricing table, so `/how-it-works`, the product page (`/software/product`) and `/pricing` are not pages this site has. The roster is what the template IS, so an unrostered page has neither a route directory nor its seed: `scaffold()` installs a `_base` or overlay seed only for a row that names it (#6646), so `content/en/Pricing/pricing.mdx` does not land. The merged roster, as the registry composes it:
216
267
 
217
268
  <!-- generated:begin roster -->
218
269
 
@@ -220,25 +271,29 @@ _Code route — no content, no sections._
220
271
  simple-service:
221
272
  requires: [marketing, scheduling, commerce]
222
273
  categories: [landscaping]
274
+ shape: local-business-service
275
+ design: standard
223
276
  roster:
224
- - { route: "/", content: ["content/en/HomePage/home.mdx"] }
225
- - { route: "/services", content: ["content/en/ServicesList/services.mdx"] }
226
- - { route: "/services/[slug]" }
227
- - { route: "/about", content: ["content/en/AboutPage/about.mdx"] }
228
- - { route: "/contact", content: ["content/en/ContactPage/contact.mdx"] }
229
- - { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] }
230
- - { route: "/returns", content: ["content/en/ReturnsPolicyPage/returns.mdx"] }
231
- - { route: "/cancellation", content: ["content/en/CancellationPolicyPage/cancellation.mdx"] }
232
- - { route: "/shipping", content: ["content/en/ShippingPolicyPage/shipping.mdx"] }
233
- - { route: "/privacy", content: ["content/en/PrivacyPage/privacy.mdx"] }
234
- - { route: "/terms", content: ["content/en/TermsPage/terms.mdx"] }
235
- - { route: "/account" }
236
- - { route: "/purchase/success" }
237
- - { route: "/purchase/cancel" }
238
- - { route: "/meet" }
239
- - { route: "/meet/[slug]" }
240
- - { route: "/meet/confirmed" }
241
- - { route: "/appointments" }
277
+ - { route: "/", kind: page, content: ["content/en/HomePage/home.mdx"] }
278
+ - { route: "/services", kind: page, content: ["content/en/ServicesList/services.mdx"] }
279
+ - { route: "/services/[slug]", kind: page, contentDir: "content/en/Service" }
280
+ - { route: "/about", kind: page, content: ["content/en/AboutPage/about.mdx"] }
281
+ - { route: "/contact", kind: page, content: ["content/en/ContactPage/contact.mdx"] }
282
+ - { route: "/faq", kind: page, content: ["content/en/FAQPage/faq.mdx"] }
283
+ - { route: "/glossary", kind: page, content: ["content/en/GlossaryList/glossary.mdx"] }
284
+ - { route: "/newsletter", kind: page, content: ["content/en/NewsletterSignup/newsletter.mdx"] }
285
+ - { route: "/book-a-call", kind: page, content: ["content/en/BookCall/book-call.mdx"] }
286
+ - { route: "/purchase-policy", kind: page, content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"] }
287
+ - { route: "/privacy", kind: page, content: ["content/en/PrivacyPage/privacy.mdx"] }
288
+ - { route: "/terms", kind: page, content: ["content/en/TermsPage/terms.mdx"] }
289
+ - { route: "/account", kind: route }
290
+ - { route: "/purchase/success", kind: route }
291
+ - { route: "/purchase/cancel", kind: route }
292
+ - { route: "/thanks/[slug]", kind: route }
293
+ - { route: "/meet", kind: route }
294
+ - { route: "/meet/[slug]", kind: route }
295
+ - { route: "/meet/confirmed", kind: route }
296
+ - { route: "/appointments", kind: route }
242
297
  ```
243
298
 
244
299
  <!-- generated:end -->
@@ -247,14 +302,14 @@ By source:
247
302
 
248
303
  ```
249
304
  template: / · /services · /services/<slug> · /about · /contact · /faq
250
- /returns · /cancellation · /shipping · /privacy · /terms · /account
251
- /purchase/success · /purchase/cancel
305
+ /purchase-policy · /privacy · /terms · /account
306
+ /purchase/success · /purchase/cancel · /thanks/<slug>
252
307
  scheduling: /meet · /meet/<slug> · /meet/confirmed · /appointments
253
308
  ```
254
309
 
255
310
  **Why the two `/purchase/*` rows are the TEMPLATE's and not the `commerce` module's.** #6084 landed the checkout return pair under the operator's shape-2 disposition (#6084 D12): `CORE_ROUTE_DIRS` carries `[locale]/purchase`, and neither `GATEABLE_SURFACES` nor `MODULE_SURFACES.commerce` gained an entry, so `MODULE_SLICES.commerce` contributes **no** `pageContributions` at all. Nothing else claims the two routes, so declaring them here trips no both-claimants refusal — and the issue's AC-1 requires the merged roster to carry them. The four scheduling rows, by contrast, **are** the module's, and declaring one here would make `mergeRoster` refuse this template outright.
256
311
 
257
- `/account` and the three policy routes carry no `GATEABLE_SURFACES` entry and need none: `(authed)` ships unconditionally, and `/returns`, `/cancellation` and `/shipping` have no gateable surface at all, so they are always copied. The three module-less surfaces this roster enables are `privacy`, `services` and `terms`.
312
+ `/account` and `/purchase-policy` carry no `GATEABLE_SURFACES` entry and need none: `(authed)` ships unconditionally, and `/purchase-policy` has no gateable surface at all, so it is always copied. The six module-less surfaces this roster enables are `book-a-call`, `glossary`, `newsletter`, `privacy`, `services` and `terms`.
258
313
 
259
314
  ## 5. Component inventory
260
315
 
@@ -262,11 +317,11 @@ Every component the roster rows' seed content composes today (generated):
262
317
 
263
318
  <!-- generated:begin inventory -->
264
319
 
265
- | Tier | Used by this template |
266
- | -------- | ------------------------------------------------------------------------------- |
267
- | Shell | `MarketingShell` |
268
- | Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`) |
269
- | Sections | `ContactForm`, `ContentBlock`, `CTA`, `DocumentChassis`, `FAQ`, `Hero`, `Items` |
320
+ | Tier | Used by this template |
321
+ | -------- | ----------------------------------------------------------------------------------------------- |
322
+ | Shell | `MarketingShell` |
323
+ | Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`) |
324
+ | Sections | `ContentBlock`, `CTA`, `DocumentChassis`, `FAQ`, `GlossaryIndex`, `Hero`, `Items`, `Newsletter` |
270
325
 
271
326
  <!-- generated:end -->
272
327
 
@@ -2,9 +2,10 @@
2
2
  "name": "simple-service",
3
3
  "requires": ["marketing", "scheduling", "commerce"],
4
4
  "extends": "_base",
5
- "$comment": "The T1 lawn-care template (#6087, Epic #5778) — the first site shape that composes scheduling and commerce. Composed base -> modules -> template: /pricing (unrostered), /privacy and /terms arrive with the _base layer this extends; /meet, /meet/<slug>, /meet/confirmed and /appointments with the scheduling bundle; /purchase/success and /purchase/cancel are BASE TREE (#6084 D12 shape 2 — CORE_ROUTE_DIRS carries [locale]/purchase and the commerce licence claim, not the scaffold, decides whether they serve); /returns, /cancellation, /shipping, /how-it-works, /features, /sign-in and the Free about/contact/faq compositions with the always-copied overlay, which this template's own /about, /contact and /faq files then override. This tree holds ONLY its own compositions and its placeholder copy. It declares no layout block — the default marketing-site chrome is what this template renders with, and the code registry (TEMPLATE_MANIFESTS) is authoritative for a template create-ailk ships, so a duplicate block here would be a second authority for one fact. installMap: bundle-relative source -> scaffold-relative destination; the stager reads only installMap/postInstall/patches. Unmapped content/en/** lands at the scaffold root's content/, exactly as marketing-site-free's does.",
5
+ "$comment": "The T1 lawn-care template (#6087, Epic #5778) — the first site shape that composes scheduling and commerce. Composed base -> modules -> template: /privacy and /terms arrive with the _base layer this extends (its unrostered /pricing seed does not install, #6646), and /purchase-policy is this tree's own service-shape override of the overlay's product-shape seed (#6646 — cancellation and refunds sections); /meet, /meet/<slug>, /meet/confirmed and /appointments with the scheduling bundle; /purchase/success and /purchase/cancel are BASE TREE (#6084 D12 shape 2 — CORE_ROUTE_DIRS carries [locale]/purchase and the commerce licence claim, not the scaffold, decides whether they serve); the Free about/contact/faq compositions with the overlay, which this template's own /about, /contact and /faq files then override; the overlay's other seeds (/use-cases, the /software/product page, the /blog teaser) are unrostered here and do not install (#6646). This tree holds ONLY its own compositions and its placeholder copy. It declares no layout block — the default marketing-site chrome is what this template renders with, and the code registry (TEMPLATE_MANIFESTS) is authoritative for a template create-ailk ships, so a duplicate block here would be a second authority for one fact. installMap: bundle-relative source -> scaffold-relative destination; the stager reads only installMap/postInstall/patches. Unmapped content/en/** lands at the scaffold root's content/, exactly as marketing-site-free's does.",
6
6
  "installMap": {
7
- "provenance.json": ".ailk-template.json"
7
+ "provenance.json": ".ailk-template.json",
8
+ "TEMPLATE-MANIFEST.json": ".ailk-site-manifest.json"
8
9
  },
9
- "postInstall": "Template simple-service installed. This is the lawn-care shape: three priced services at /services (content/en/Service/), a booker at /meet from the scheduling module, the site owner's own list at /appointments, and the checkout return pair at /purchase/success and /purchase/cancel. /privacy and /terms came with the base layer; /returns, /cancellation and /shipping came with the overlay. This template adds the home page, /services and its three detail pages, /about, /contact and /faq. THE THREE PRICES ARE PLACEHOLDERS AND THEY ARE PUBLISHED: each service page's top-level price and priceCurrency become a schema.org Offer in that page's JSON-LD, which is what an agent reading your site quotes back to a buyer — replace all three, and the provider name with them, before you launch. Taking money needs the commerce licence claim and your own Stripe account: without the claim the return pages 404 by design. EVERY line of copy on this site is a placeholder too — replace it before you launch."
10
+ "postInstall": "Template simple-service installed. This is the lawn-care shape: three priced services at /services (content/en/Service/), a booker at /meet from the scheduling module, the site owner's own list at /appointments, and the checkout return pair at /purchase/success and /purchase/cancel. /privacy, /terms, /glossary and /newsletter came with the base layer, and /book-a-call is this template's own override of the base seed, its call to action opening the /meet booker. This template adds the home page, /services and its three detail pages, /about, /contact, /faq and /purchase-policy (cancellation and refunds). THE THREE PRICES ARE PLACEHOLDERS AND THEY ARE PUBLISHED: each service page's top-level price and priceCurrency become a schema.org Offer in that page's JSON-LD, which is what an agent reading your site quotes back to a buyer — replace all three, and the provider name with them, before you launch. Taking money needs the commerce licence claim and your own Stripe account: without the claim the return pages 404 by design. EVERY line of copy on this site is a placeholder too — replace it before you launch."
10
11
  }
@@ -0,0 +1,53 @@
1
+ ---
2
+ type: "BookCall"
3
+ slug: "book-call"
4
+ title: "{Book a call: what a visitor gets from it}"
5
+ description: "{One sentence on who the call is for and what they leave with}"
6
+ placeholder: true
7
+ schema:
8
+ mainEntity:
9
+ "@type": "Offer"
10
+ name: "{Your call name}"
11
+ price: 0
12
+ priceCurrency: "USD"
13
+ sections:
14
+ [
15
+ {
16
+ "id": "hero",
17
+ "type": "hero",
18
+ "data":
19
+ {
20
+ "eyebrow": "Book a call",
21
+ "headline": "{Book a call: what a visitor gets from it}",
22
+ "subheadline": "{One sentence on who the call is for and what they leave with}",
23
+ "primaryCta": { "label": "Book a time", "href": "/meet" },
24
+ },
25
+ },
26
+ {
27
+ "id": "what-happens-on-the-call",
28
+ "type": "items",
29
+ "data":
30
+ {
31
+ "headline": "What happens on the call?",
32
+ "columns": 3,
33
+ "items":
34
+ [
35
+ {
36
+ "title": "{The first thing you cover}",
37
+ "description": "{One or two sentences on what the visitor learns or decides here}",
38
+ },
39
+ {
40
+ "title": "{The second thing you cover}",
41
+ "description": "{One or two sentences on what the visitor learns or decides here}",
42
+ },
43
+ {
44
+ "title": "{The next step you agree}",
45
+ "description": "{One or two sentences on what happens after the call}",
46
+ },
47
+ ],
48
+ },
49
+ },
50
+ ]
51
+ ---
52
+
53
+ {/* Rendered from frontmatter `sections[]` by the /book-a-call route. This template carries the scheduling module, so the call to action opens the /meet booker. It overrides the base layer's copy, which points at /contact. The `schema:` Offer is the page's JSON-LD main entity — a free call. Placeholder copy — replace every {brace} with your own words before you launch. */}
@@ -16,41 +16,6 @@ sections:
16
16
  "subheadline": "{One line on what happens after you send this, and how long it takes. If a call is faster, say so.}",
17
17
  },
18
18
  },
19
- {
20
- "id": "contact-form",
21
- "type": "contact-form",
22
- "data":
23
- {
24
- "variant": "card",
25
- "source": "contact",
26
- "fields":
27
- [
28
- {
29
- "name": "name",
30
- "label": "Name",
31
- "type": "text",
32
- "required": true,
33
- },
34
- {
35
- "name": "email",
36
- "label": "Email",
37
- "type": "email",
38
- "required": true,
39
- },
40
- {
41
- "name": "message",
42
- "label": "What needs doing?",
43
- "type": "textarea",
44
- "required": true,
45
- },
46
- ],
47
- "submitLabel": "Send →",
48
- "consentText": "I accept the Terms",
49
- "consentLink": { "label": "Terms", "href": "/terms" },
50
- "successMessage": "Thank you — your message is in. You will hear back within {time amount}.",
51
- "action": "/v1/leads/submit",
52
- },
53
- },
54
19
  {
55
20
  "id": "closing",
56
21
  "type": "cta",
@@ -64,4 +29,4 @@ sections:
64
29
  ]
65
30
  ---
66
31
 
67
- The form posts to the site's own API (`/v1/leads/submit`) and confirms inline — no redirect, no thank-you page. Placeholder copy.
32
+ The /contact route mounts the page's one contact surface — the guided intake, with its fallback form — which posts to the site's own API (`/v1/leads/submit`) and confirms inline. Placeholder copy.
@@ -0,0 +1,124 @@
1
+ ---
2
+ type: "PurchasePolicyPage"
3
+ slug: "purchase-policy"
4
+ title: "Purchase Policy"
5
+ description: "How cancellations, reschedules and refunds work for bookings made on this site. Placeholder policy — replace every section before you launch."
6
+ placeholder: true
7
+ sections:
8
+ [
9
+ {
10
+ "id": "purchase-policy-document",
11
+ "type": "document-chassis",
12
+ "data":
13
+ {
14
+ "headline": "Purchase Policy",
15
+ "layout": "article",
16
+ "updated": "Last updated {Month Day, Year}",
17
+ "navGroupLabel": "Contents",
18
+ "sections":
19
+ [
20
+ {
21
+ "id": "cancellation",
22
+ "heading": "Cancellation",
23
+ "blocks":
24
+ [
25
+ {
26
+ "kind": "paragraph",
27
+ "text": "This page is starter content that shipped with your site. It is not a purchase policy, it makes no commitment on behalf of Your Company, and it is not legal advice. Replace every section with the policy you actually operate, and have someone qualified read it before you publish.",
28
+ },
29
+ {
30
+ "kind": "paragraph",
31
+ "text": "This section explains how cancellations and reschedules work for bookings made on this site. The headings are the ones a customer and an agent both look for, so keep them and fill in your own terms.",
32
+ },
33
+ ],
34
+ "subsections":
35
+ [
36
+ {
37
+ "id": "notice",
38
+ "heading": "How much notice is required",
39
+ "blocks":
40
+ [
41
+ {
42
+ "kind": "paragraph",
43
+ "text": "State the notice period in hours before the appointment, and say how it is measured. A customer reading at midnight should be able to work out, without arithmetic you have not shown them, whether they are still inside it.",
44
+ },
45
+ ],
46
+ },
47
+ {
48
+ "id": "how-to-cancel",
49
+ "heading": "How to cancel or reschedule",
50
+ "blocks":
51
+ [
52
+ {
53
+ "kind": "paragraph",
54
+ "text": "Give one route to cancel and one to reschedule, and say whether a reschedule inside the notice period counts as a cancellation. If a booking confirmation carries a self-service link, name it here.",
55
+ },
56
+ ],
57
+ },
58
+ {
59
+ "id": "fees",
60
+ "heading": "Late cancellations and no-shows",
61
+ "blocks":
62
+ [
63
+ {
64
+ "kind": "paragraph",
65
+ "text": "Say what a late cancellation costs and what a no-show costs, as a figure or a share of the booking, and when each is charged. If you hold a deposit, say what happens to it in each case.",
66
+ },
67
+ ],
68
+ },
69
+ {
70
+ "id": "our-cancellations",
71
+ "heading": "If we cancel",
72
+ "blocks":
73
+ [
74
+ {
75
+ "kind": "paragraph",
76
+ "text": "Set out what a customer gets if you cancel or move an appointment — a full refund, a rebooking, or both — and how quickly you tell them. A policy that only binds one side reads as one.",
77
+ },
78
+ ],
79
+ },
80
+ {
81
+ "id": "exceptions",
82
+ "heading": "Exceptions",
83
+ "blocks":
84
+ [
85
+ {
86
+ "kind": "paragraph",
87
+ "text": "Name the circumstances in which you waive a fee — illness, bereavement, severe weather — and say what you need from the customer to apply the waiver. Vague discretion is worse for you than a short written list.",
88
+ },
89
+ ],
90
+ },
91
+ ],
92
+ },
93
+ {
94
+ "id": "refunds",
95
+ "heading": "Refunds",
96
+ "blocks":
97
+ [
98
+ {
99
+ "kind": "paragraph",
100
+ "text": "Say what a customer gets back after a cancellation — the booking price, the deposit, or both, and how long the refund takes to reach the payment method it came from. If you offer store credit or a rebooking instead, describe when each applies.",
101
+ },
102
+ ],
103
+ "subsections":
104
+ [
105
+ {
106
+ "id": "questions",
107
+ "heading": "Questions about a refund",
108
+ "blocks":
109
+ [
110
+ {
111
+ "kind": "paragraph",
112
+ "text": "Point to the one place a customer should write, and say roughly how quickly you answer. A policy nobody can ask a question about is a policy that generates disputes.",
113
+ },
114
+ ],
115
+ },
116
+ ],
117
+ },
118
+ ],
119
+ },
120
+ },
121
+ ]
122
+ ---
123
+
124
+ {/* Rendered from frontmatter `sections[]`; the MDX body is not read by the section-catalog renderer. Service shape (#6646): cancellation and refunds — this template's override of the `_base` product-shape seed. The JSON-LD — a WebPage, wrapping a MerchantReturnPolicy when a returns section is present — is emitted by `buildPurchasePolicyPage` (#6646), not hand-rolled here. */}
@@ -0,0 +1,15 @@
1
+ {
2
+ "hooks": {
3
+ "PostToolUse": [
4
+ {
5
+ "matcher": "Edit|Write",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "cd \"$CLAUDE_PROJECT_DIR\" && [ -x node_modules/.bin/tsx ] || exit 0; pnpm --silent architecture >&2 || exit 2"
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -9,14 +9,14 @@ them automatically at session start — nothing to install or enable.
9
9
 
10
10
  ## Available skills
11
11
 
12
- | Skill | Purpose |
13
- | ---------------------- | -------------------------------------------------------------------------------------------------------- |
14
- | `suggest-site-pages` | Recommend a starter set of pages — each tagged with a schema.org type — from a free-text business description. |
15
- | `scaffold-page` | Generate a new page: App Router route + MDX content stub + typed JSON-LD, in one confirm-before-write pass. |
16
- | `add-schema` | Add or replace schema.org JSON-LD on a page that already exists. |
17
- | `scaffold-auth` | Activate auth providers — magic-link via Resend, Google OAuth, GitHub OAuth. |
18
- | `provision-config` | Emit deploy configuration — `vercel.json`, `.env.example`, and `RUNBOOK.md` — for a Vercel deploy. |
19
- | `audit-site` | Run `ailk-audit --json` and explain the score and findings in plain language. |
12
+ | Skill | Purpose |
13
+ | -------------- | -------------------------------------------------------------------------------------------------------------- |
14
+ | `add-page` | Generate a new page: App Router route + MDX content stub + typed JSON-LD, in one confirm-before-write pass. Also documents the `schema:` frontmatter override for adding supplementary structured data to a page that already exists. |
15
+ | `add-auth` | Activate auth providers — magic-link via Resend, Google OAuth, GitHub OAuth. |
16
+ | `setup-deploy` | Emit deploy configuration — `vercel.json`, `.env.example`, and `RUNBOOK.md` — for a Vercel deploy. |
17
+ | `check-site` | Run `ailk-audit --json` and explain the score and findings in plain language. |
18
+ | `fill-page` | Fill one page's section content from a category profile: labelled sample content (tier 1) or your own first draft from a short intake (tier 2). |
19
+ | `upgrade-plan` | Compare Free, Pro, Pro Plus, Agency and the commerce add-on side by side, with the prices the public pricing page publishes right now, and recommend one option for this site with a reason. |
20
20
 
21
21
  `scaffold-commerce` is delivered with the commerce module (`--modules commerce`, licensed).
22
22