create-ailk 0.7.0 → 0.9.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 (310) hide show
  1. package/README.md +112 -10
  2. package/component-catalog.json +798 -49
  3. package/component-catalog.md +9 -6
  4. package/dist/add-module.d.ts +20 -0
  5. package/dist/add-module.js +43 -7
  6. package/dist/add-route.d.ts +56 -0
  7. package/dist/add-route.js +286 -0
  8. package/dist/apply-design-md.d.ts +7 -0
  9. package/dist/apply-design-md.js +50 -0
  10. package/dist/apply-design.d.ts +64 -0
  11. package/dist/apply-design.js +273 -0
  12. package/dist/claude-md.d.ts +111 -0
  13. package/dist/claude-md.js +334 -0
  14. package/dist/cli.js +114 -28
  15. package/dist/derive-architecture.js +41 -36
  16. package/dist/design-compile.d.ts +71 -0
  17. package/dist/design-compile.js +98 -0
  18. package/dist/design-package.d.ts +83 -0
  19. package/dist/design-package.js +468 -0
  20. package/dist/design-presets.d.ts +86 -0
  21. package/dist/design-presets.js +642 -0
  22. package/dist/design-scaffold.d.ts +76 -0
  23. package/dist/design-scaffold.js +220 -0
  24. package/dist/index.d.ts +2 -1
  25. package/dist/index.js +4 -1
  26. package/dist/legacy-nav-renderers.d.ts +45 -0
  27. package/dist/legacy-nav-renderers.js +545 -0
  28. package/dist/lib/auth-secret-file.d.ts +19 -0
  29. package/dist/lib/auth-secret-file.js +112 -0
  30. package/dist/lib/design-checks.d.ts +78 -0
  31. package/dist/lib/design-checks.js +174 -0
  32. package/dist/lib/extract-module-bundle.js +5 -1
  33. package/dist/lib/license-key-files.d.ts +9 -0
  34. package/dist/lib/license-key-files.js +2 -2
  35. package/dist/lib/module-license-gate.d.ts +89 -0
  36. package/dist/lib/module-license-gate.js +171 -12
  37. package/dist/lib/module-tier.d.ts +45 -16
  38. package/dist/lib/module-tier.js +76 -0
  39. package/dist/lib/pro-callout.js +10 -2
  40. package/dist/lib/render-verdict.d.ts +52 -0
  41. package/dist/lib/render-verdict.js +77 -0
  42. package/dist/lib/scaffold-render-sweep.d.ts +105 -0
  43. package/dist/lib/scaffold-render-sweep.js +236 -0
  44. package/dist/module-architecture.d.ts +19 -16
  45. package/dist/module-architecture.js +64 -21
  46. package/dist/parse-args.d.ts +88 -10
  47. package/dist/parse-args.js +272 -21
  48. package/dist/programmatic.d.ts +66 -12
  49. package/dist/programmatic.js +361 -34
  50. package/dist/site-chrome.d.ts +19 -9
  51. package/dist/site-chrome.js +23 -13
  52. package/dist/site-manifest.d.ts +25 -0
  53. package/dist/site-manifest.js +254 -0
  54. package/dist/site-roster.d.ts +41 -0
  55. package/dist/site-roster.js +149 -11
  56. package/dist/starter-grid.d.ts +232 -0
  57. package/dist/starter-grid.js +545 -0
  58. package/dist/surfaces.d.ts +41 -9
  59. package/dist/surfaces.js +268 -92
  60. package/dist/template-manifest.d.ts +65 -29
  61. package/dist/template-manifest.js +161 -382
  62. package/dist/template-names.d.ts +14 -12
  63. package/dist/template-names.js +13 -17
  64. package/package.json +5 -4
  65. package/site-templates/_base/content/en/Feature/feature-1.mdx +69 -0
  66. package/site-templates/_base/content/en/Feature/feature-2.mdx +69 -0
  67. package/site-templates/_base/content/en/Feature/feature-3.mdx +69 -0
  68. package/site-templates/_base/content/en/FeaturesList/features.mdx +91 -0
  69. package/site-templates/_base/content/en/GlossaryList/glossary.mdx +0 -1
  70. package/site-templates/_base/content/en/NewsletterSignup/newsletter.mdx +0 -1
  71. package/site-templates/_base/content/en/PortfolioItem/sample-four.mdx +105 -0
  72. package/site-templates/_base/content/en/PortfolioItem/sample-one.mdx +34 -0
  73. package/site-templates/_base/content/en/PortfolioItem/sample-three.mdx +94 -0
  74. package/site-templates/_base/content/en/PortfolioItem/sample-two.mdx +45 -0
  75. package/site-templates/_base/content/en/PortfolioList/portfolio.mdx +169 -0
  76. package/site-templates/_base/content/en/PrivacyPage/privacy.mdx +15 -0
  77. package/site-templates/_base/content/en/UseCase/persona-1.mdx +70 -0
  78. package/site-templates/_base/content/en/UseCase/persona-2.mdx +70 -0
  79. package/site-templates/_base/content/en/UseCase/persona-3.mdx +70 -0
  80. package/site-templates/{minimalism-site/TEMPLATE-MANIFEST.json → aliases/minimalism-site.TEMPLATE-MANIFEST.json} +72 -40
  81. package/site-templates/designs/minimalism/DESIGN.md +98 -6
  82. package/site-templates/designs/minimalism/sample/README.md +48 -0
  83. package/site-templates/designs/standard/DESIGN.md +103 -6
  84. package/site-templates/marketing-site/DESIGN.md +103 -6
  85. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +144 -47
  86. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +82 -41
  87. package/site-templates/marketing-site-free/DESIGN.md +103 -6
  88. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +150 -48
  89. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +114 -67
  90. package/site-templates/marketing-site-free/ailk-template.json +1 -1
  91. package/site-templates/marketing-site-free/content/en/NewsletterSignup/newsletter.mdx +59 -0
  92. package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +199 -0
  93. package/site-templates/saas-product/DESIGN.md +103 -6
  94. package/site-templates/saas-product/TEMPLATE-MANIFEST.md +9 -1
  95. package/site-templates/{simple-service → shapes/local-business-service}/TEMPLATE-MANIFEST.json +210 -81
  96. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +356 -0
  97. package/site-templates/shapes/local-business-service/ailk-template.json +10 -0
  98. package/site-templates/{simple-service → shapes/local-business-service}/content/en/AboutPage/about.mdx +4 -4
  99. package/site-templates/shapes/local-business-service/content/en/HomePage/home.mdx +70 -0
  100. package/site-templates/shapes/local-business-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
  101. package/site-templates/shapes/local-business-service/content/en/PortfolioList/portfolio.mdx +171 -0
  102. package/site-templates/{minimalism-site → shapes/local-business-service}/content/en/PurchasePolicyPage/purchase-policy.mdx +7 -8
  103. package/site-templates/shapes/local-business-service/content/en/Service/first-job.mdx +39 -0
  104. package/site-templates/shapes/local-business-service/content/en/Service/second-job.mdx +39 -0
  105. package/site-templates/shapes/local-business-service/content/en/Service/third-job.mdx +39 -0
  106. package/site-templates/shapes/local-business-service/content/en/ServicesList/services.mdx +61 -0
  107. package/site-templates/shapes/local-business-service/provenance.json +4 -0
  108. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +471 -0
  109. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +354 -0
  110. package/site-templates/shapes/organization-service/ailk-template.json +10 -0
  111. package/site-templates/shapes/organization-service/content/en/AboutPage/about.mdx +38 -0
  112. package/site-templates/shapes/organization-service/content/en/HomePage/home.mdx +85 -0
  113. package/site-templates/shapes/organization-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
  114. package/site-templates/shapes/organization-service/content/en/PortfolioList/portfolio.mdx +171 -0
  115. package/site-templates/shapes/organization-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
  116. package/site-templates/{minimalism-site → shapes/organization-service}/content/en/ServicesList/services.mdx +3 -4
  117. package/site-templates/shapes/organization-service/provenance.json +4 -0
  118. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +478 -0
  119. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +353 -0
  120. package/site-templates/shapes/person-service/ailk-template.json +10 -0
  121. package/site-templates/shapes/person-service/content/_site.mdx +85 -0
  122. package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +39 -0
  123. package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +97 -0
  124. package/site-templates/shapes/person-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
  125. package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +171 -0
  126. package/site-templates/{simple-service → shapes/person-service}/content/en/PurchasePolicyPage/purchase-policy.mdx +10 -11
  127. package/site-templates/shapes/person-service/content/en/Service/first-engagement.mdx +38 -0
  128. package/site-templates/shapes/person-service/content/en/Service/second-engagement.mdx +38 -0
  129. package/site-templates/shapes/person-service/content/en/Service/third-engagement.mdx +38 -0
  130. package/site-templates/{simple-service → shapes/person-service}/content/en/ServicesList/services.mdx +16 -16
  131. package/site-templates/shapes/person-service/provenance.json +4 -0
  132. package/templates/.claude/rules/architecture.md +7 -0
  133. package/templates/.claude/skills/README.md +5 -3
  134. package/templates/.claude/skills/add-auth/references/env-vars.md +22 -15
  135. package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +3 -2
  136. package/templates/.claude/skills/add-page/SKILL.md +241 -238
  137. package/templates/.claude/skills/add-page/references/page-types.md +85 -72
  138. package/templates/.claude/skills/add-page/scripts/site-pages.mjs +87 -0
  139. package/templates/.claude/skills/add-page/templates/comparison-page.mdx.tmpl +99 -0
  140. package/templates/.claude/skills/add-page/templates/content.mdx.tmpl +8 -18
  141. package/templates/.claude/skills/add-page/templates/flow-landing-page.mdx.tmpl +43 -0
  142. package/templates/.claude/skills/add-page/templates/report-page.mdx.tmpl +52 -0
  143. package/templates/.claude/skills/add-page/templates/reports-list.mdx.tmpl +38 -0
  144. package/templates/.claude/skills/check-site/SKILL.md +23 -0
  145. package/templates/.claude/skills/fill-page/SKILL.md +26 -7
  146. package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +1 -1
  147. package/templates/.claude/skills/setup-database/SKILL.md +156 -0
  148. package/templates/.claude/skills/setup-database/scripts/verify-inbox.ts +154 -0
  149. package/templates/.claude/skills/setup-deploy/SKILL.md +64 -32
  150. package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +44 -36
  151. package/templates/.claude/skills/setup-deploy/references/runbook-template.md +58 -102
  152. package/templates/.claude/skills/update-page/SKILL.md +117 -0
  153. package/templates/.claude/skills/update-page/scripts/update-page.ts +640 -0
  154. package/templates/.claude/skills/update-page/templates/redirects.mjs.tmpl +31 -0
  155. package/templates/.claude/skills/upgrade-plan/SKILL.md +12 -8
  156. package/templates/.github/workflows/ci.yml +4 -0
  157. package/templates/.prettierignore +1 -0
  158. package/templates/CLAUDE.md +146 -103
  159. package/templates/DESIGN.md +103 -6
  160. package/templates/README.md +63 -43
  161. package/templates/apps/api/.env.example +2 -1
  162. package/templates/apps/api/CLAUDE.md +3 -2
  163. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +2 -0
  164. package/templates/apps/api/src/__tests__/server.test.ts +116 -0
  165. package/templates/apps/api/src/config/__tests__/index.test.ts +115 -14
  166. package/templates/apps/api/src/config/index.ts +35 -16
  167. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +30 -0
  168. package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +96 -0
  169. package/templates/apps/api/src/lib/lead-capture-store.ts +12 -0
  170. package/templates/apps/api/src/lib/lead-delivery.ts +52 -0
  171. package/templates/apps/api/src/lib/stripe.ts +9 -0
  172. package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +140 -0
  173. package/templates/apps/api/src/middleware/auth.ts +54 -0
  174. package/templates/apps/api/src/openapi/spec.ts +63 -12
  175. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +5 -2
  176. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +628 -0
  177. package/templates/apps/api/src/routes/checkout/sessions.ts +222 -24
  178. package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +88 -0
  179. package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +100 -0
  180. package/templates/apps/api/src/routes/leads/index.ts +46 -1
  181. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +1 -1
  182. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +5 -1
  183. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +521 -20
  184. package/templates/apps/api/src/routes/webhooks/stripe.ts +124 -32
  185. package/templates/apps/api/src/server.ts +35 -0
  186. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +194 -0
  187. package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +124 -0
  188. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +90 -15
  189. package/templates/apps/api/src/services/checkout-buyer.ts +72 -0
  190. package/templates/apps/api/src/services/lead-routing.ts +140 -30
  191. package/templates/apps/api/src/services/leads-inbox.ts +48 -11
  192. package/templates/apps/api/src/services/revalidation.ts +60 -15
  193. package/templates/apps/mcp/__tests__/parity.test.ts +5 -4
  194. package/templates/apps/mcp/__tests__/tools/create_project.test.ts +30 -24
  195. package/templates/apps/mcp/src/tools/create_project.ts +21 -6
  196. package/templates/apps/mcp/src/tools/purchase.ts +4 -2
  197. package/templates/apps/web/.env.example +13 -0
  198. package/templates/apps/web/CLAUDE.md +22 -28
  199. package/templates/apps/web/app/[locale]/(auth)/layout.tsx +1 -1
  200. package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +24 -0
  201. package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +17 -6
  202. package/templates/apps/web/app/[locale]/[slug]/[detail]/__tests__/page.test.tsx +110 -0
  203. package/templates/apps/web/app/[locale]/[slug]/[detail]/page.tsx +60 -0
  204. package/templates/apps/web/app/[locale]/[slug]/page.tsx +1 -1
  205. package/templates/apps/web/app/[locale]/alternatives/__tests__/page.test.tsx +161 -0
  206. package/templates/apps/web/app/[locale]/alternatives/page.tsx +104 -0
  207. package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +14 -6
  208. package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +10 -9
  209. package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-text.test.ts +32 -0
  210. package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +129 -0
  211. package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +227 -84
  212. package/templates/apps/web/app/[locale]/contact/contact-form-text.ts +50 -0
  213. package/templates/apps/web/app/[locale]/contact/contact.actions.ts +73 -20
  214. package/templates/apps/web/app/[locale]/contact/page.tsx +105 -15
  215. package/templates/apps/web/app/[locale]/contact/site-contact-email.ts +54 -0
  216. package/templates/apps/web/app/[locale]/features/[slug]/page.tsx +64 -0
  217. package/templates/apps/web/app/[locale]/features/page.tsx +52 -0
  218. package/templates/apps/web/app/[locale]/{use-cases → for}/[slug]/page.tsx +21 -5
  219. package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +73 -0
  220. package/templates/apps/web/app/[locale]/{use-cases → for}/page.tsx +8 -7
  221. package/templates/apps/web/app/[locale]/glossary/page.tsx +1 -1
  222. package/templates/apps/web/app/[locale]/layout.tsx +65 -17
  223. package/templates/apps/web/app/[locale]/newsletter/__tests__/newsletter.actions.test.ts +75 -0
  224. package/templates/apps/web/app/[locale]/newsletter/__tests__/page.test.tsx +163 -0
  225. package/templates/apps/web/app/[locale]/newsletter/newsletter.actions.ts +66 -0
  226. package/templates/apps/web/app/[locale]/newsletter/page.tsx +106 -14
  227. package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +59 -0
  228. package/templates/apps/web/app/[locale]/{book-a-call → portfolio}/page.tsx +12 -13
  229. package/templates/apps/web/app/[locale]/vs/[slug]/__tests__/page.test.tsx +112 -0
  230. package/templates/apps/web/app/[locale]/vs/[slug]/page.tsx +70 -0
  231. package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +236 -44
  232. package/templates/apps/web/app/api/revalidate/route.ts +78 -36
  233. package/templates/apps/web/lib/__tests__/site-brand.test.ts +79 -0
  234. package/templates/apps/web/lib/__tests__/site-theme.test.ts +104 -11
  235. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +21 -4
  236. package/templates/apps/web/lib/locale-guard.ts +18 -0
  237. package/templates/apps/web/lib/meet-placeholder.ts +5 -0
  238. package/templates/apps/web/lib/nav-config.ts +50 -37
  239. package/templates/apps/web/lib/site-brand.tsx +13 -9
  240. package/templates/apps/web/lib/site-identity.ts +14 -0
  241. package/templates/apps/web/lib/site-logo.tsx +36 -0
  242. package/templates/apps/web/lib/site-theme.ts +46 -26
  243. package/templates/apps/web/messages/en.json +45 -5
  244. package/templates/apps/web/middleware.ts +28 -4
  245. package/templates/content/_site.mdx +4 -2
  246. package/templates/content/en/BlogList/blog.mdx +37 -16
  247. package/templates/content/en/BookCall/book-a-call.mdx +80 -0
  248. package/templates/content/en/BookCall/onsite-estimate.mdx +56 -0
  249. package/templates/content/en/BookCall/onsite-service.mdx +56 -0
  250. package/templates/content/en/BookCall/start-project.mdx +56 -0
  251. package/templates/content/en/ContactPage/contact.mdx +43 -34
  252. package/templates/content/en/HomePage/home.mdx +10 -22
  253. package/templates/content/en/LandingPage/meet.mdx +59 -0
  254. package/templates/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -1
  255. package/templates/content/en/UseCasesList/{use-cases.mdx → for.mdx} +19 -18
  256. package/templates/database/CHANGELOG.md +14 -0
  257. package/templates/database/package.json +1 -1
  258. package/templates/package.json +2 -1
  259. package/templates/tools/check-claude-md.ts +128 -0
  260. package/versions.json +33 -33
  261. package/site-templates/_base/content/en/BookCall/book-call.mdx +0 -53
  262. package/site-templates/_base/content/en/UseCase/first-use-case.mdx +0 -23
  263. package/site-templates/_base/content/en/UseCase/second-use-case.mdx +0 -23
  264. package/site-templates/_base/content/en/UseCase/third-use-case.mdx +0 -23
  265. package/site-templates/minimalism-site/DESIGN.md +0 -162
  266. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +0 -470
  267. package/site-templates/minimalism-site/ailk-template.json +0 -23
  268. package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +0 -110
  269. package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +0 -53
  270. package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +0 -34
  271. package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +0 -57
  272. package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +0 -77
  273. package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +0 -73
  274. package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +0 -52
  275. package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +0 -52
  276. package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +0 -52
  277. package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +0 -52
  278. package/site-templates/minimalism-site/flows/referral.flow.json +0 -71
  279. package/site-templates/minimalism-site/provenance.json +0 -4
  280. package/site-templates/simple-service/DESIGN.md +0 -162
  281. package/site-templates/simple-service/TEMPLATE-MANIFEST.md +0 -333
  282. package/site-templates/simple-service/ailk-template.json +0 -11
  283. package/site-templates/simple-service/content/en/BookCall/book-call.mdx +0 -53
  284. package/site-templates/simple-service/content/en/ContactPage/contact.mdx +0 -32
  285. package/site-templates/simple-service/content/en/FAQPage/faq.mdx +0 -56
  286. package/site-templates/simple-service/content/en/HomePage/home.mdx +0 -85
  287. package/site-templates/simple-service/content/en/Service/landscape-design.mdx +0 -40
  288. package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +0 -40
  289. package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +0 -40
  290. package/site-templates/simple-service/provenance.json +0 -4
  291. package/templates/.claude/skills/add-page/templates/route.tsx.tmpl +0 -28
  292. package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +0 -211
  293. package/templates/apps/web/app/[locale]/contact/__tests__/ContactForm.test.tsx +0 -96
  294. package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +0 -72
  295. package/templates/content/en/SoftwareProduct/product.mdx +0 -175
  296. /package/site-templates/{minimalism-site → designs/minimalism/sample}/content/en/HomePage/home.mdx +0 -0
  297. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-1.svg +0 -0
  298. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-2.svg +0 -0
  299. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-3.svg +0 -0
  300. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-4.svg +0 -0
  301. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-5.svg +0 -0
  302. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-6.svg +0 -0
  303. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/hero-backdrop.svg +0 -0
  304. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-1.svg +0 -0
  305. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-2.svg +0 -0
  306. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-3.svg +0 -0
  307. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/wordmark-placeholder.svg +0 -0
  308. /package/site-templates/{minimalism-site → shapes/organization-service}/content/en/Service/first-engagement.mdx +0 -0
  309. /package/site-templates/{minimalism-site → shapes/organization-service}/content/en/Service/second-engagement.mdx +0 -0
  310. /package/site-templates/{minimalism-site → shapes/organization-service}/content/en/Service/third-engagement.mdx +0 -0
@@ -0,0 +1,545 @@
1
+ /**
2
+ * The two pages every starter carries whatever its shape (#6658 D5,
3
+ * `docs/decisions/starter-roster-page-set.md` D4/D7): a glossary and a
4
+ * newsletter signup. Each is a module-less `GATEABLE_SURFACES` entry the
5
+ * roster enables, with its seed in `_base`.
6
+ *
7
+ * The third — `/book-a-call` — was retired by #6897 D10: every scaffold's
8
+ * former `/book-a-call` link now points at `/meet/book-a-call`, served by
9
+ * `FREE_MEET_PLACEHOLDER_ROWS` below (a Free placeholder) or by the
10
+ * scheduling module's own live `/meet/[slug]` page.
11
+ */
12
+ const SHAPE_INDEPENDENT_ROWS = [
13
+ { route: "/glossary", content: ["content/en/GlossaryList/glossary.mdx"] },
14
+ {
15
+ route: "/newsletter",
16
+ content: ["content/en/NewsletterSignup/newsletter.mdx"],
17
+ },
18
+ ];
19
+ /**
20
+ * The Free `/meet` placeholder pages (#6897 D5) — a meeting-types hub
21
+ * (`LandingPage`, served by the generic `[slug]` route) and its four
22
+ * `BookCall` detail seeds (served by the `[slug]/[detail]` route, D2). Both
23
+ * ship in the always-copied overlay, beside `FREE_BLOG_TEASER_ROW`, so a
24
+ * template-less scaffold's Contact tiles (which link `/meet/*` too) reach
25
+ * real pages. The second row uses an explicit `content` list, not
26
+ * `contentDir`, because only a `content`-list row is removed by
27
+ * `planRosterAppend`'s add-module supersede (F4's add-module half,
28
+ * `site-roster.ts`).
29
+ *
30
+ * Every alias that takes the `scheduling` module drops `"/meet"` and
31
+ * `"/meet/[slug]"` (D5) — otherwise `mergeRoster` refuses the duplicate
32
+ * route the module's own rows also contribute. The ROWS go; the SEEDS stay
33
+ * (#6942, operator 2026-09-28, partly reversing D5): until
34
+ * `SCHEDULING_CAL_LINK` is configured the module's pages hand off to the Free
35
+ * placeholder routes, which serve these seeds. `withMeetPlaceholderSeeds`
36
+ * (`site-roster.ts`) folds them onto the module's rows.
37
+ */
38
+ const FREE_MEET_PLACEHOLDER_ROWS = [
39
+ { route: "/meet", content: ["content/en/LandingPage/meet.mdx"] },
40
+ {
41
+ route: "/meet/[slug]",
42
+ content: [
43
+ "content/en/BookCall/book-a-call.mdx",
44
+ "content/en/BookCall/onsite-estimate.mdx",
45
+ "content/en/BookCall/start-project.mdx",
46
+ "content/en/BookCall/onsite-service.mdx",
47
+ ],
48
+ },
49
+ ];
50
+ /**
51
+ * The rows every `organization-product` template brings itself — one declared
52
+ * page set, whichever layer carries each seed. Re-derived by #6658 from the
53
+ * standard (`derive-roster.py --entity-type software --offering-type software
54
+ * --primary-goal convert --scale global`, the `--shape organization-product`
55
+ * equivalent), edited only by the deviations the Free manifest's § 3a records
56
+ * with their reasons. With a template named, `scaffold()` keeps a `_base` or
57
+ * overlay seed only when a merged roster row names it (#6646 D1): the roster
58
+ * decides what installs, and the manifest generator's `--check` proves it.
59
+ *
60
+ * Two layers, one roster:
61
+ *
62
+ * - `/`, `/software/[slug]`, `/for`, `/about`, `/faq`, `/contact` and
63
+ * `/purchase-policy` take their content from the overlay
64
+ * (`template-overlay/content/en/**`, copied whole into `templates/` by
65
+ * `build-templates.mjs`). `/features` is the FeaturesList hub over one
66
+ * Feature page per feature at `/features/[slug]` (#6721, reversing the
67
+ * single `/software/product` page of #6658 D3); both ride the `features`
68
+ * surface the roster enables.
69
+ * `/for` lists the three UseCase pages at `/for/[slug]`
70
+ * (#6658 D4).
71
+ * - `/pricing`, `/privacy`, `/terms`, `/glossary`, `/newsletter`,
72
+ * and the three UseCase pages take their content from the
73
+ * base layer (`site-templates/_base/content/**`, #5618 D1), which every
74
+ * template reaches by declaring `extends` — installed before the module
75
+ * bundles and the template's own tree, so a template may override a base
76
+ * page by shipping the same path. Their surfaces are module-less by
77
+ * construction (parent § D16, #6658 D5): a template enables them by
78
+ * NAMING them in its roster — `scaffold()` selects their
79
+ * `GATEABLE_SURFACES` entries from the merged roster's routes (#5469 D10).
80
+ *
81
+ * `/software`, `/sign-in` and `/sign-up` carry no `content`: they are code
82
+ * routes (the SoftwareProduct listing, the SignInCard island, the sign-up
83
+ * form), like the API-backed rows the scheduling module contributes — listed
84
+ * so the manifest is a complete install record, where the generator marks
85
+ * them `kind: route` (#6646 D2).
86
+ *
87
+ * `/purchase-policy` is the product-shape purchase policy (#6646 D3): its
88
+ * overlay seed carries returns, shipping and refunds sections — the overlay,
89
+ * not `_base`, because the route is core and a scaffold naming no template
90
+ * serves it too. A service-shape template overrides that seed with its own
91
+ * cancellation and refunds file.
92
+ *
93
+ * `/blog` is deliberately NOT here (#5469 D3): the docs-blog module
94
+ * contributes its own `/blog` row, so a base row would make `mergeRoster`
95
+ * refuse every template that takes that module. The teaser row is an
96
+ * `organization-product` shape row instead (#6753 D3), which the two aliases
97
+ * taking docs-blog drop.
98
+ */
99
+ const TEMPLATE_BASE_ROSTER = [
100
+ { route: "/", content: ["content/en/HomePage/home.mdx"] },
101
+ // #6721 — the product's features: a FeaturesList hub over one Feature page
102
+ // per feature (replaces the single /software/product page, #6658 D3).
103
+ { route: "/features", content: ["content/en/FeaturesList/features.mdx"] },
104
+ { route: "/features/[slug]", contentDir: "content/en/Feature" },
105
+ {
106
+ // #6878 D7 — the persona hub, renamed from /use-cases.
107
+ route: "/for",
108
+ content: ["content/en/UseCasesList/for.mdx"],
109
+ },
110
+ { route: "/for/[slug]", contentDir: "content/en/UseCase" },
111
+ { route: "/pricing", content: ["content/en/Pricing/pricing.mdx"] },
112
+ { route: "/about", content: ["content/en/AboutPage/about.mdx"] },
113
+ { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
114
+ { route: "/contact", content: ["content/en/ContactPage/contact.mdx"] },
115
+ ...SHAPE_INDEPENDENT_ROWS,
116
+ { route: "/sign-in" },
117
+ { route: "/sign-up" },
118
+ { route: "/privacy", content: ["content/en/PrivacyPage/privacy.mdx"] },
119
+ { route: "/terms", content: ["content/en/TermsPage/terms.mdx"] },
120
+ {
121
+ route: "/purchase-policy",
122
+ content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"],
123
+ },
124
+ ];
125
+ /**
126
+ * The Free `/blog` teaser (#5469 D3) — one static BlogList page (schema `Blog`
127
+ * with an empty `ItemList`; the correct page type, not a LandingPage) that
128
+ * says what the Pro docs-blog module gives you. It is served by the generic
129
+ * `[slug]` route — which probes `LandingPage` first, then `BlogList` — over
130
+ * `content/en/BlogList/blog.mdx`, which ships in the always-copied overlay. `/blog` degrades by DIRECTORY PRECEDENCE, not
131
+ * by a module gate: in a keyed docs-blog scaffold the module's own
132
+ * `blog/[[...slug]]/page.tsx` directory exists and Next.js resolves the static
133
+ * segment first, so the teaser file is inert; keyless, no `blog/` directory
134
+ * exists and the teaser renders. An `organization-product` shape row
135
+ * (#6753 D3): the aliases taking docs-blog drop it, so on `marketing-site`
136
+ * the docs-blog contribution claims the route.
137
+ */
138
+ const FREE_BLOG_TEASER_ROW = {
139
+ route: "/blog",
140
+ content: ["content/en/BlogList/blog.mdx"],
141
+ };
142
+ /**
143
+ * The rows for the `signal-collectors` bundle's six sample pages (#6646
144
+ * disposition (a)) — the project listing, its two project pages and the
145
+ * three thank-you pages its `installMap` lands. The module contributes no
146
+ * row for any of these routes (`module-architecture.ts`'s installMap
147
+ * comment), so a template that takes the module declares them, and the
148
+ * roster names every page the scaffold installs. `/projects` is a
149
+ * module-less `GATEABLE_SURFACES` entry, so naming it here also copies the
150
+ * route directory the samples render through (`rosterSurfaces`).
151
+ */
152
+ const SIGNAL_COLLECTORS_SAMPLE_ROWS = [
153
+ { route: "/projects", content: ["content/en/ProjectsList/projects.mdx"] },
154
+ { route: "/projects/[slug]", contentDir: "content/en/Project" },
155
+ { route: "/thanks/[slug]", contentDir: "content/en/ThankYouPage" },
156
+ ];
157
+ /**
158
+ * The portfolio pages (#6687) — before/after project comparisons: a
159
+ * PortfolioList hub on the /alternatives stack and one PortfolioItem page per
160
+ * comparison, each one `before-after` section carrying its header band and
161
+ * pager. They belong to the SHAPE, Free included (roadmap § 4, operator
162
+ * 2026-09-25, reversing #6687's "Pro and up"): every shape roster below
163
+ * carries them, and an alias sheds them only by an explicit `drop`. The seeds
164
+ * live in the `_base` layer under `content/en/PortfolioItem/`; the detail
165
+ * row's `contentDir` installs them (#6646 D1), exactly as `/for/[slug]`
166
+ * serves `content/en/UseCase`.
167
+ */
168
+ // NO_HAND_IMPLEMENT_OK: /build-starter operator-directed live pass (#6687).
169
+ const PORTFOLIO_ROWS = [
170
+ { route: "/portfolio", content: ["content/en/PortfolioList/portfolio.mdx"] },
171
+ { route: "/portfolio/[slug]", contentDir: "content/en/PortfolioItem" },
172
+ ];
173
+ /**
174
+ * `minimalism-site`'s two OWN rows (#5589, shrunk from its own 17-row roster
175
+ * by #6757 once the `organization-service` shape carried a standard roster of
176
+ * its own): the deck's two `LandingPage` slugs, positioned by `insert` (D7)
177
+ * at the two points this alias interleaves them into the shape's row order
178
+ * (§ 1.2) — `/reports` before `/about`, `/referral` before `/faq`. Neither
179
+ * carries a `GATEABLE_SURFACES` entry: both are single-segment slugs served
180
+ * by the generic `[slug]` route (#5469 D2), the same mechanism Free's
181
+ * `/how-it-works` used.
182
+ */
183
+ const REPORTS_ROW = {
184
+ route: "/reports",
185
+ content: ["content/en/ReportsList/reports.mdx"],
186
+ };
187
+ const REFERRAL_ROW = {
188
+ route: "/referral",
189
+ content: ["content/en/LandingPage/referral.mdx"],
190
+ };
191
+ /**
192
+ * The signal-collectors module's report/referral sample rows (spec 6892 D3):
193
+ * `/reports`, a `ReportsList` hub over the module's four `ReportPage` seeds,
194
+ * and `/referral`, a sample flow landing page. `marketing-site` and
195
+ * `saas-product` add these before `/portfolio`, alongside
196
+ * `SIGNAL_COLLECTORS_SAMPLE_ROWS`; `minimalism-site` keeps its own two
197
+ * `insert` groups instead (its pre-existing row order, D1).
198
+ */
199
+ const SIGNAL_COLLECTORS_REPORT_ROWS = [
200
+ REPORTS_ROW,
201
+ REFERRAL_ROW,
202
+ ];
203
+ /**
204
+ * `organization-service`'s own rows (#6757 D1), derived from
205
+ * `derive-roster.py --shape organization-service --primary-goal generate-leads
206
+ * --registry packages/schema/src/registry/entries.ts` at harness commit
207
+ * `7bdaf148e1b0e639cd90a80008955e55cc4aa2b5`, edited only by the deviations
208
+ * `site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md` § 3a
209
+ * records with their reasons. Row order matches `minimalism-site`'s (D3), so
210
+ * that alias's `differences` are additions and drops only.
211
+ */
212
+ const ORGANIZATION_SERVICE_ROWS = [
213
+ { route: "/", content: ["content/en/HomePage/home.mdx"] },
214
+ { route: "/about", content: ["content/en/AboutPage/about.mdx"] },
215
+ { route: "/services", content: ["content/en/ServicesList/services.mdx"] },
216
+ { route: "/services/[slug]", contentDir: "content/en/Service" },
217
+ // #6878 D7 — every shape carries the /for family now, service shapes
218
+ // included: the seeds are shape-neutral (D7), so no per-shape override is
219
+ // needed.
220
+ {
221
+ route: "/for",
222
+ content: ["content/en/UseCasesList/for.mdx"],
223
+ },
224
+ { route: "/for/[slug]", contentDir: "content/en/UseCase" },
225
+ { route: "/contact", content: ["content/en/ContactPage/contact.mdx"] },
226
+ { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
227
+ ...SHAPE_INDEPENDENT_ROWS,
228
+ { route: "/sign-in" },
229
+ { route: "/sign-up" },
230
+ { route: "/privacy", content: ["content/en/PrivacyPage/privacy.mdx"] },
231
+ { route: "/terms", content: ["content/en/TermsPage/terms.mdx"] },
232
+ {
233
+ route: "/purchase-policy",
234
+ content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"],
235
+ },
236
+ ];
237
+ /**
238
+ * `local-business-service`'s own rows (#6757 D1), derived the same way with
239
+ * `--shape local-business-service`. It has no `--template` alias of its own
240
+ * since #6789 retired the one alias that composed it; `--shape` is its only entry.
241
+ */
242
+ const LOCAL_BUSINESS_SERVICE_ROWS = [
243
+ { route: "/", content: ["content/en/HomePage/home.mdx"] },
244
+ { route: "/services", content: ["content/en/ServicesList/services.mdx"] },
245
+ { route: "/services/[slug]", contentDir: "content/en/Service" },
246
+ // #6878 D7 — every shape carries the /for family now (D7 shape-neutral seeds).
247
+ {
248
+ route: "/for",
249
+ content: ["content/en/UseCasesList/for.mdx"],
250
+ },
251
+ { route: "/for/[slug]", contentDir: "content/en/UseCase" },
252
+ { route: "/about", content: ["content/en/AboutPage/about.mdx"] },
253
+ { route: "/contact", content: ["content/en/ContactPage/contact.mdx"] },
254
+ { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
255
+ ...SHAPE_INDEPENDENT_ROWS,
256
+ { route: "/sign-in" },
257
+ { route: "/sign-up" },
258
+ {
259
+ route: "/purchase-policy",
260
+ content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"],
261
+ },
262
+ { route: "/privacy", content: ["content/en/PrivacyPage/privacy.mdx"] },
263
+ { route: "/terms", content: ["content/en/TermsPage/terms.mdx"] },
264
+ ];
265
+ /**
266
+ * `person-service`'s own rows (#6758 D1, D3), derived from
267
+ * `derive-roster.py --shape person-service --primary-goal generate-leads
268
+ * --registry packages/schema/src/registry/entries.ts` at harness commit
269
+ * `7bdaf148e1b0e639cd90a80008955e55cc4aa2b5` (the vendored equivalent:
270
+ * `--entity-type person --offering-type services --primary-goal
271
+ * generate-leads --scale global`), edited only by the deviations
272
+ * `site-templates/shapes/person-service/TEMPLATE-MANIFEST.md` § 3a records
273
+ * with their reasons. Row order matches `local-business-service`'s (D3):
274
+ * services before about, because a consultant is hired for an engagement
275
+ * first.
276
+ */
277
+ const PERSON_SERVICE_ROWS = [
278
+ { route: "/", content: ["content/en/HomePage/home.mdx"] },
279
+ { route: "/services", content: ["content/en/ServicesList/services.mdx"] },
280
+ { route: "/services/[slug]", contentDir: "content/en/Service" },
281
+ // #6878 D7 — every shape carries the /for family now (D7 shape-neutral seeds).
282
+ {
283
+ route: "/for",
284
+ content: ["content/en/UseCasesList/for.mdx"],
285
+ },
286
+ { route: "/for/[slug]", contentDir: "content/en/UseCase" },
287
+ { route: "/about", content: ["content/en/AboutPage/about.mdx"] },
288
+ { route: "/contact", content: ["content/en/ContactPage/contact.mdx"] },
289
+ { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
290
+ ...SHAPE_INDEPENDENT_ROWS,
291
+ { route: "/sign-in" },
292
+ { route: "/sign-up" },
293
+ {
294
+ route: "/purchase-policy",
295
+ content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"],
296
+ },
297
+ { route: "/privacy", content: ["content/en/PrivacyPage/privacy.mdx"] },
298
+ { route: "/terms", content: ["content/en/TermsPage/terms.mdx"] },
299
+ ];
300
+ /**
301
+ * Each buildable shape's standard roster (#6753 D3) — the rows an alias starts
302
+ * from before its `differences` apply.
303
+ *
304
+ * `organization-product` is today's base roster, the `/blog` teaser and the
305
+ * portfolio pair. `organization-service`, `local-business-service` (#6757)
306
+ * and `person-service` (#6758, roadmap § 6 Phase 2) are each their own rows,
307
+ * the `/blog` teaser and the portfolio pair. Every shape's own rows carry
308
+ * `/sign-in` and `/sign-up` (#6797): the locale layout's header links both on
309
+ * every shape, so the roster of record lists them as code routes.
310
+ */
311
+ export const SHAPE_ROSTERS = Object.freeze({
312
+ "organization-product": [
313
+ ...TEMPLATE_BASE_ROSTER,
314
+ FREE_BLOG_TEASER_ROW,
315
+ ...FREE_MEET_PLACEHOLDER_ROWS,
316
+ ...PORTFOLIO_ROWS,
317
+ ],
318
+ "organization-service": [
319
+ ...ORGANIZATION_SERVICE_ROWS,
320
+ FREE_BLOG_TEASER_ROW,
321
+ ...FREE_MEET_PLACEHOLDER_ROWS,
322
+ ...PORTFOLIO_ROWS,
323
+ ],
324
+ "local-business-service": [
325
+ ...LOCAL_BUSINESS_SERVICE_ROWS,
326
+ FREE_BLOG_TEASER_ROW,
327
+ ...FREE_MEET_PLACEHOLDER_ROWS,
328
+ ...PORTFOLIO_ROWS,
329
+ ],
330
+ "person-service": [
331
+ ...PERSON_SERVICE_ROWS,
332
+ FREE_BLOG_TEASER_ROW,
333
+ ...FREE_MEET_PLACEHOLDER_ROWS,
334
+ ...PORTFOLIO_ROWS,
335
+ ],
336
+ });
337
+ /**
338
+ * The `--template` names and the grid coordinates each stands for (#6753) —
339
+ * the one table `TEMPLATE_MANIFESTS` and `RECOGNIZED_TEMPLATES` derive from,
340
+ * in the declaration order both keep. The plain name is the Pro one: it is
341
+ * the flagship and the demo (Sam, 2026-09-14, parent § D12).
342
+ *
343
+ * `workspace` appears in no module list. It is a Pro module, but an authed app
344
+ * surface contributing no PUBLIC page to a marketing site, and `modules` names
345
+ * what the roster uses (parent § D15). A Pro key unlocks it regardless of any
346
+ * template.
347
+ *
348
+ * `commerce` is a per-site add-on available at any level, so no alias exists
349
+ * FOR it (parent § D13); it still contributes rows to whichever alias takes
350
+ * it, through `mergeRoster`.
351
+ *
352
+ * Frozen (#5507): the registry composed from this table is also the issuer's
353
+ * authorization allowlist (spec 5480 § C7). A test needing a different table
354
+ * passes its own to `resolveTemplate(name, aliases)` rather than mutating
355
+ * this one.
356
+ */
357
+ export const ALIASES = Object.freeze({
358
+ /**
359
+ * The Free template, and the mechanism's own proof (parent § D11): it
360
+ * requires only `marketing`, so the keyless merge path is exercised by a
361
+ * template we ship anyway rather than by a throwaway fixture. The bare
362
+ * `organization-product` shape — no differences at all.
363
+ */
364
+ "marketing-site-free": {
365
+ shape: "organization-product",
366
+ design: "standard",
367
+ modules: ["marketing"],
368
+ categories: ["accounting", "legal", "technology"],
369
+ // The demo site carries the "Get started with this template" banner
370
+ // (operator ruling 2026-09-23); every other layout knob keeps its default.
371
+ layout: { announcementBanner: true },
372
+ },
373
+ /**
374
+ * The Pro flagship. Its module list is OFFERINGS § 4 offering 3's tiers line
375
+ * — "docs, scheduling and flows modules" — where "flows" is
376
+ * `signal-collectors` (`MODULE_SURFACES` maps it to `["flows"]`). It drops
377
+ * the shape's `/blog` teaser because docs-blog contributes the real `/blog`,
378
+ * and adds the signal-collectors sample rows ahead of the portfolio pair.
379
+ */
380
+ "marketing-site": {
381
+ shape: "organization-product",
382
+ design: "standard",
383
+ modules: ["marketing", "docs-blog", "scheduling", "signal-collectors"],
384
+ // The flagship is the general-purpose template: it carries the whole
385
+ // registry, so every group tile on the hub has at least one template.
386
+ categories: [
387
+ "accounting",
388
+ "legal",
389
+ "consulting",
390
+ "hvac",
391
+ "roofing",
392
+ "plumbing",
393
+ "electrical",
394
+ "landscaping",
395
+ "auto-repair",
396
+ "real-estate",
397
+ "technology",
398
+ "medical-specialty",
399
+ ],
400
+ differences: {
401
+ drop: ["/blog", "/meet", "/meet/[slug]"],
402
+ add: [...SIGNAL_COLLECTORS_SAMPLE_ROWS, ...SIGNAL_COLLECTORS_REPORT_ROWS],
403
+ before: "/portfolio",
404
+ },
405
+ },
406
+ /**
407
+ * Pro Plus — the Pro list plus `multi-tenant`, which is correctly in the
408
+ * list because it DOES contribute pages (the org and workspace surfaces).
409
+ * Its `pageContributions` is nonetheless unset today, deferred to its own
410
+ * instance, so this template's merged roster carries the same contributed
411
+ * rows as `marketing-site`'s and no more. That is a module which has
412
+ * declared no rows yet — visible in the diff — not a merge that dropped
413
+ * declared rows.
414
+ */
415
+ "saas-product": {
416
+ shape: "organization-product",
417
+ design: "standard",
418
+ modules: [
419
+ "marketing",
420
+ "docs-blog",
421
+ "scheduling",
422
+ "signal-collectors",
423
+ "multi-tenant",
424
+ ],
425
+ categories: ["technology", "medical-specialty"],
426
+ differences: {
427
+ drop: ["/blog", "/meet", "/meet/[slug]"],
428
+ add: [...SIGNAL_COLLECTORS_SAMPLE_ROWS, ...SIGNAL_COLLECTORS_REPORT_ROWS],
429
+ before: "/portfolio",
430
+ },
431
+ },
432
+ /**
433
+ * The second Pro template (#5589) — the reports-first, scroll-snap deck
434
+ * site. NOT `marketing-site` plus a module: its `modules` omit `docs-blog`,
435
+ * so the two Pro templates are siblings under `_base` (#5618 D2), never a
436
+ * lineage. Level still derives from `modules`: `scheduling` and
437
+ * `signal-collectors` are paid, so `templateDelivery` returns `"paid"`
438
+ * exactly as it does for `marketing-site`.
439
+ *
440
+ * It composes the `organization-service` shape roster (#6757) rather than
441
+ * the organization-product one: the deck home replaces the document-scroll
442
+ * home, and `/how-it-works`, the product page, `/pricing` and `/sign-in`
443
+ * are not pages this site has. The roster is what the
444
+ * template IS, so an unrostered page has neither a route directory
445
+ * (`rosterSurfaces`) nor its `_base`/overlay seed (#6646 D1).
446
+ *
447
+ * It declares NO `layout` block (#6638): the deck home, mark-only nav and
448
+ * centered footer are the `minimalism` design's own `layout` (its
449
+ * `DESIGN.md`, resolved by `resolveDesign` off `design:` — #6813 D4) — the
450
+ * look any shape can wear. This alias ships no tree of its own (`ownTree:
451
+ * false`, spec 6892 D1); its GENERATED roster record (no narrative `.md`,
452
+ * D5) lives at `site-templates/aliases/minimalism-site.TEMPLATE-MANIFEST.json`.
453
+ *
454
+ * `/reports` (a `ReportsList` hub over `ReportPage`) and `/referral` (a
455
+ * flow landing page) are signal-collectors module samples (spec 6892 D3);
456
+ * neither carries a `GATEABLE_SURFACES` entry: `/referral` is a
457
+ * single-segment `LandingPage` slug served by the generic `[slug]` route
458
+ * (#5469 D2), the same mechanism Free's `/how-it-works` uses, and `/reports`
459
+ * is its own routes-map row. `/reports/[slug]` (the reader) is the
460
+ * signal-collectors module's own contributed row.
461
+ *
462
+ * `/services/[slug]` declares its seed DIRECTORY as `contentDir`
463
+ * (`content/en/Service`, as `routes-map.ts` records it). The three
464
+ * samples ride the template tree unmapped, landing at that directory.
465
+ *
466
+ * Since #6757, `organization-service` carries a real standard roster
467
+ * (D1), so this alias's `differences` is additions and drops only: it
468
+ * drops the `/blog` teaser (a Pro alias does not upsell its own level,
469
+ * D8), the portfolio pair (the reports are the proof, not a
470
+ * portfolio) and the two auth code routes the shape rosters (#6797 —
471
+ * this site has no `/sign-in`, above), adds the signal-collectors
472
+ * samples, and INSERTS its two own
473
+ * rows — `/reports` before `/about`, `/referral` before `/faq` (D7) — to
474
+ * reproduce its pre-#6757 row order (§ 1.2) exactly.
475
+ */
476
+ "minimalism-site": {
477
+ shape: "organization-service",
478
+ design: "minimalism",
479
+ modules: ["marketing", "scheduling", "signal-collectors"],
480
+ categories: ["real-estate", "technology", "legal"],
481
+ // Spec 6892 D1 — this alias ships no `site-templates/minimalism-site/`
482
+ // tree of its own: it resolves purely from the grid. Its seed layer is
483
+ // its shape's tree (`templateTreeDir`), its deck home + SVGs are a
484
+ // sample the `minimalism` design installs (D4), and its `/reports` +
485
+ // `/referral` rows are signal-collectors module samples (D3).
486
+ ownTree: false,
487
+ differences: {
488
+ drop: [
489
+ "/sign-in",
490
+ "/sign-up",
491
+ "/blog",
492
+ "/meet",
493
+ "/meet/[slug]",
494
+ "/portfolio",
495
+ "/portfolio/[slug]",
496
+ ],
497
+ add: SIGNAL_COLLECTORS_SAMPLE_ROWS,
498
+ insert: [
499
+ { before: "/about", rows: [REPORTS_ROW] },
500
+ { before: "/faq", rows: [REFERRAL_ROW] },
501
+ ],
502
+ },
503
+ },
504
+ });
505
+ /**
506
+ * The coordinates a keyless `--shape S` builds (#6757 D5) — the composed
507
+ * FREE manifest per shape, for a shape with no `--template` alias of its
508
+ * own. Frozen and `Partial`; `organization-product` needs none — its
509
+ * keyless tree is `marketing-site-free`'s (#6754 AC-2).
510
+ *
511
+ * No `differences` (a bare shape is its standard roster, D1) and no
512
+ * `layout`. Every category is a leaf of `packages/schema/src/categories.ts`,
513
+ * as `TemplateManifest.categories` requires. `person-service`'s single
514
+ * `consulting` category is the operator's disposition (2026-09-26,
515
+ * ai-launch-kit-internal#6758): the leaf did not exist when #6758's spec was
516
+ * written, and adding it replaced that spec's `["accounting", "legal",
517
+ * "technology"]` author-pick stand-in.
518
+ */
519
+ export const SHAPE_STARTER_ALIASES = Object.freeze({
520
+ "organization-service": {
521
+ shape: "organization-service",
522
+ design: "standard",
523
+ modules: ["marketing"],
524
+ categories: ["accounting", "legal", "real-estate"],
525
+ },
526
+ "local-business-service": {
527
+ shape: "local-business-service",
528
+ design: "standard",
529
+ modules: ["marketing"],
530
+ categories: [
531
+ "hvac",
532
+ "roofing",
533
+ "plumbing",
534
+ "electrical",
535
+ "landscaping",
536
+ "auto-repair",
537
+ ],
538
+ },
539
+ "person-service": {
540
+ shape: "person-service",
541
+ design: "standard",
542
+ modules: ["marketing"],
543
+ categories: ["consulting"],
544
+ },
545
+ });
@@ -181,6 +181,33 @@ export declare const ROUTE_DEPENDENCIES: Readonly<Record<string, readonly string
181
181
  export declare const ROUTE_MESSAGE_NAMESPACES: Readonly<Record<string, readonly string[]>>;
182
182
  /** Template-relative path of the generated site-nav registry. */
183
183
  export declare const NAV_CONFIG_PATH = "apps/web/lib/nav-config.ts";
184
+ /**
185
+ * Verify a rendered nav's self-hashing stamp (#6908 D1/F1–F2): `"valid"` when
186
+ * the first line's hash matches every byte after it, `"invalid"` when a
187
+ * stamp line is present but the hash fails (an edited, still-stamped nav),
188
+ * `"absent"` when there is no stamp line at all. A stamp that verifies proves
189
+ * the file unedited whatever generator wrote it — the check needs only the
190
+ * file, never the generator's code.
191
+ */
192
+ export declare function readNavConfigStamp(text: string): "valid" | "invalid" | "absent";
193
+ /**
194
+ * Every byte after a nav's stamp line, or `text` unchanged when it carries
195
+ * none. The one place the D1 stamp-line shape is matched outside
196
+ * `readNavConfigStamp` itself, so a test simulating an edit below the stamp
197
+ * (or a bare pre-D1 body) never re-derives `NAV_STAMP_RE`'s pattern by hand.
198
+ */
199
+ export declare function stripNavConfigStamp(text: string): string;
200
+ /** Options for `renderNavConfig` (#6878 D6). */
201
+ export interface RenderNavConfigOptions {
202
+ /**
203
+ * Service page slugs — the basenames, minus `.mdx`, of a site's
204
+ * `content/en/Service/*.mdx` — for the Services flyout column on a
205
+ * service shape. Sorted, then cut to the first three. Absent/empty →
206
+ * the offering column emits no Services links even when the `services`
207
+ * surface is on (there is nothing to link yet).
208
+ */
209
+ serviceSlugs?: readonly string[];
210
+ }
184
211
  /**
185
212
  * Render `apps/web/lib/nav-config.ts` for an enabled surface set.
186
213
  *
@@ -191,14 +218,19 @@ export declare const NAV_CONFIG_PATH = "apps/web/lib/nav-config.ts";
191
218
  * surface set for the same reason the route tree does.
192
219
  *
193
220
  * The base items are the Free marketing-site chrome (#5469 D5, the approved
194
- * chrome diff recorded on that card, re-pointed by #6658 D8):
195
- * a Product flyout (Use cases · Features · FAQ), then Use cases, Blog, Pricing
196
- * and About. Features links the product's own page (`/software/product`), a
197
- * core route like `/faq` and `/about`; `/blog` is always linked (the teaser or
198
- * the docs-blog module serves it). Use cases and Pricing are gateable
199
- * surfaces: each item is emitted only when its surface is enabled (a template
200
- * roster enables it, #5469 D10), so the nav still never links a page the
201
- * scaffold does not carry.
221
+ * chrome diff recorded on that card, re-pointed by #6658 D8, then by #6878 D6):
222
+ * ONE flyout rule for every shape — an offering column (Features on product
223
+ * shapes, Services on service shapes) beside a Customers column linking the
224
+ * /for persona pages — then Blog, Pricing and About. `/blog` is always linked
225
+ * (the teaser or the docs-blog module serves it). Pricing and every other
226
+ * gateable surface: each item is emitted only when its surface is enabled (a
227
+ * template roster enables it, #5469 D10), so the nav still never links a page
228
+ * the scaffold does not carry. Portfolio is never a flyout link (D6): on a
229
+ * service shape it is a plain top-level link directly after the Services
230
+ * flyout, and every shape's footer Site pages column links it (#6895), both
231
+ * under the `portfolio` surface's gate. No empty flyout is ever emitted: with
232
+ * neither column non-empty, no flyout item is emitted at all (closes #6766's
233
+ * AC-1).
202
234
  *
203
235
  * Only gateable surfaces carrying a `navLabelKey` are linked after the base
204
236
  * items, because a nav entry needs a translated label. Emitting an entry whose
@@ -212,4 +244,4 @@ export declare const NAV_CONFIG_PATH = "apps/web/lib/nav-config.ts";
212
244
  * Deterministic: gateable entries follow GATEABLE_SURFACES order (alphabetical
213
245
  * by id), after the fixed base items.
214
246
  */
215
- export declare function renderNavConfig(enabled: string[]): string;
247
+ export declare function renderNavConfig(enabled: string[], options?: RenderNavConfigOptions): string;