create-ailk 0.8.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 (211) hide show
  1. package/README.md +68 -0
  2. package/component-catalog.json +279 -45
  3. package/dist/add-module.d.ts +20 -0
  4. package/dist/add-module.js +43 -7
  5. package/dist/add-route.d.ts +56 -0
  6. package/dist/add-route.js +286 -0
  7. package/dist/apply-design-md.d.ts +7 -0
  8. package/dist/apply-design-md.js +50 -0
  9. package/dist/apply-design.d.ts +64 -0
  10. package/dist/apply-design.js +273 -0
  11. package/dist/claude-md.d.ts +111 -0
  12. package/dist/claude-md.js +334 -0
  13. package/dist/cli.js +92 -4
  14. package/dist/derive-architecture.js +41 -36
  15. package/dist/design-compile.d.ts +71 -0
  16. package/dist/design-compile.js +98 -0
  17. package/dist/design-package.d.ts +83 -0
  18. package/dist/design-package.js +468 -0
  19. package/dist/design-presets.d.ts +86 -0
  20. package/dist/design-presets.js +642 -0
  21. package/dist/design-scaffold.d.ts +76 -0
  22. package/dist/design-scaffold.js +220 -0
  23. package/dist/index.d.ts +2 -1
  24. package/dist/index.js +4 -1
  25. package/dist/legacy-nav-renderers.d.ts +45 -0
  26. package/dist/legacy-nav-renderers.js +545 -0
  27. package/dist/lib/auth-secret-file.d.ts +19 -0
  28. package/dist/lib/auth-secret-file.js +112 -0
  29. package/dist/lib/design-checks.d.ts +78 -0
  30. package/dist/lib/design-checks.js +174 -0
  31. package/dist/lib/license-key-files.d.ts +9 -0
  32. package/dist/lib/license-key-files.js +2 -2
  33. package/dist/lib/module-license-gate.d.ts +19 -9
  34. package/dist/lib/module-license-gate.js +19 -8
  35. package/dist/lib/render-verdict.d.ts +52 -0
  36. package/dist/lib/render-verdict.js +77 -0
  37. package/dist/lib/scaffold-render-sweep.d.ts +105 -0
  38. package/dist/lib/scaffold-render-sweep.js +236 -0
  39. package/dist/module-architecture.d.ts +19 -16
  40. package/dist/module-architecture.js +64 -21
  41. package/dist/parse-args.d.ts +12 -2
  42. package/dist/parse-args.js +74 -13
  43. package/dist/programmatic.d.ts +30 -6
  44. package/dist/programmatic.js +206 -17
  45. package/dist/site-chrome.d.ts +19 -9
  46. package/dist/site-chrome.js +23 -13
  47. package/dist/site-manifest.d.ts +25 -0
  48. package/dist/site-manifest.js +254 -0
  49. package/dist/site-roster.d.ts +41 -0
  50. package/dist/site-roster.js +141 -8
  51. package/dist/starter-grid.d.ts +32 -16
  52. package/dist/starter-grid.js +129 -33
  53. package/dist/surfaces.d.ts +41 -9
  54. package/dist/surfaces.js +200 -83
  55. package/dist/template-manifest.d.ts +30 -13
  56. package/dist/template-manifest.js +49 -24
  57. package/package.json +5 -4
  58. package/site-templates/_base/content/en/UseCase/persona-1.mdx +7 -6
  59. package/site-templates/_base/content/en/UseCase/persona-2.mdx +7 -6
  60. package/site-templates/_base/content/en/UseCase/persona-3.mdx +7 -6
  61. package/site-templates/{minimalism-site/TEMPLATE-MANIFEST.json → aliases/minimalism-site.TEMPLATE-MANIFEST.json} +72 -40
  62. package/site-templates/designs/minimalism/DESIGN.md +98 -6
  63. package/site-templates/designs/minimalism/sample/README.md +48 -0
  64. package/site-templates/designs/standard/DESIGN.md +98 -6
  65. package/site-templates/marketing-site/DESIGN.md +98 -6
  66. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +60 -27
  67. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +50 -30
  68. package/site-templates/marketing-site-free/DESIGN.md +98 -6
  69. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +60 -24
  70. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +44 -27
  71. package/site-templates/marketing-site-free/ailk-template.json +1 -1
  72. package/site-templates/saas-product/DESIGN.md +98 -6
  73. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +127 -18
  74. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +74 -20
  75. package/site-templates/shapes/local-business-service/ailk-template.json +1 -1
  76. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +127 -18
  77. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +74 -20
  78. package/site-templates/shapes/organization-service/ailk-template.json +1 -1
  79. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +127 -18
  80. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +75 -21
  81. package/site-templates/shapes/person-service/ailk-template.json +1 -1
  82. package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +1 -1
  83. package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +2 -2
  84. package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +4 -2
  85. package/site-templates/shapes/person-service/content/en/ServicesList/services.mdx +1 -1
  86. package/templates/.claude/rules/architecture.md +7 -0
  87. package/templates/.claude/skills/README.md +3 -2
  88. package/templates/.claude/skills/add-auth/references/env-vars.md +22 -15
  89. package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +3 -2
  90. package/templates/.claude/skills/add-page/SKILL.md +241 -238
  91. package/templates/.claude/skills/add-page/references/page-types.md +85 -76
  92. package/templates/.claude/skills/add-page/scripts/site-pages.mjs +87 -0
  93. package/templates/.claude/skills/add-page/templates/comparison-page.mdx.tmpl +99 -0
  94. package/templates/.claude/skills/add-page/templates/content.mdx.tmpl +8 -18
  95. package/templates/.claude/skills/add-page/templates/flow-landing-page.mdx.tmpl +43 -0
  96. package/templates/.claude/skills/add-page/templates/report-page.mdx.tmpl +52 -0
  97. package/templates/.claude/skills/add-page/templates/reports-list.mdx.tmpl +38 -0
  98. package/templates/.claude/skills/check-site/SKILL.md +23 -0
  99. package/templates/.claude/skills/fill-page/SKILL.md +26 -7
  100. package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +1 -1
  101. package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +28 -11
  102. package/templates/.claude/skills/update-page/SKILL.md +117 -0
  103. package/templates/.claude/skills/update-page/scripts/update-page.ts +640 -0
  104. package/templates/.claude/skills/update-page/templates/redirects.mjs.tmpl +31 -0
  105. package/templates/.claude/skills/upgrade-plan/SKILL.md +12 -8
  106. package/templates/.github/workflows/ci.yml +4 -0
  107. package/templates/.prettierignore +1 -0
  108. package/templates/CLAUDE.md +146 -103
  109. package/templates/DESIGN.md +98 -6
  110. package/templates/README.md +50 -38
  111. package/templates/apps/api/.env.example +2 -1
  112. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +2 -0
  113. package/templates/apps/api/src/__tests__/server.test.ts +116 -0
  114. package/templates/apps/api/src/lib/stripe.ts +9 -0
  115. package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +140 -0
  116. package/templates/apps/api/src/middleware/auth.ts +54 -0
  117. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +5 -2
  118. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +628 -0
  119. package/templates/apps/api/src/routes/checkout/sessions.ts +222 -24
  120. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +1 -1
  121. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +5 -1
  122. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +521 -20
  123. package/templates/apps/api/src/routes/webhooks/stripe.ts +124 -32
  124. package/templates/apps/api/src/server.ts +28 -0
  125. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +90 -15
  126. package/templates/apps/api/src/services/checkout-buyer.ts +72 -0
  127. package/templates/apps/api/src/services/revalidation.ts +60 -15
  128. package/templates/apps/mcp/__tests__/tools/create_project.test.ts +30 -24
  129. package/templates/apps/mcp/src/tools/purchase.ts +4 -2
  130. package/templates/apps/web/.env.example +13 -0
  131. package/templates/apps/web/CLAUDE.md +22 -28
  132. package/templates/apps/web/app/[locale]/(auth)/layout.tsx +1 -1
  133. package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +24 -0
  134. package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +17 -6
  135. package/templates/apps/web/app/[locale]/[slug]/[detail]/__tests__/page.test.tsx +110 -0
  136. package/templates/apps/web/app/[locale]/[slug]/[detail]/page.tsx +60 -0
  137. package/templates/apps/web/app/[locale]/[slug]/page.tsx +1 -1
  138. package/templates/apps/web/app/[locale]/alternatives/__tests__/page.test.tsx +161 -0
  139. package/templates/apps/web/app/[locale]/alternatives/page.tsx +104 -0
  140. package/templates/apps/web/app/[locale]/{use-cases → for}/[slug]/page.tsx +4 -3
  141. package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +73 -0
  142. package/templates/apps/web/app/[locale]/{use-cases → for}/page.tsx +8 -7
  143. package/templates/apps/web/app/[locale]/glossary/page.tsx +1 -1
  144. package/templates/apps/web/app/[locale]/layout.tsx +35 -19
  145. package/templates/apps/web/app/[locale]/newsletter/page.tsx +1 -1
  146. package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +1 -1
  147. package/templates/apps/web/app/[locale]/portfolio/page.tsx +1 -1
  148. package/templates/apps/web/app/[locale]/vs/[slug]/__tests__/page.test.tsx +112 -0
  149. package/templates/apps/web/app/[locale]/vs/[slug]/page.tsx +70 -0
  150. package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +236 -44
  151. package/templates/apps/web/app/api/revalidate/route.ts +78 -36
  152. package/templates/apps/web/lib/__tests__/site-brand.test.ts +79 -0
  153. package/templates/apps/web/lib/__tests__/site-theme.test.ts +104 -11
  154. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +21 -4
  155. package/templates/apps/web/lib/locale-guard.ts +18 -0
  156. package/templates/apps/web/lib/meet-placeholder.ts +5 -0
  157. package/templates/apps/web/lib/nav-config.ts +14 -13
  158. package/templates/apps/web/lib/site-brand.tsx +13 -9
  159. package/templates/apps/web/lib/site-logo.tsx +36 -0
  160. package/templates/apps/web/lib/site-theme.ts +46 -26
  161. package/templates/apps/web/messages/en.json +23 -9
  162. package/templates/apps/web/middleware.ts +28 -4
  163. package/templates/content/en/BookCall/book-a-call.mdx +80 -0
  164. package/templates/content/en/BookCall/onsite-estimate.mdx +56 -0
  165. package/templates/content/en/BookCall/onsite-service.mdx +56 -0
  166. package/templates/content/en/BookCall/start-project.mdx +56 -0
  167. package/templates/content/en/ContactPage/contact.mdx +40 -1
  168. package/templates/content/en/HomePage/home.mdx +2 -6
  169. package/templates/content/en/LandingPage/meet.mdx +59 -0
  170. package/templates/content/en/UseCasesList/{use-cases.mdx → for.mdx} +19 -18
  171. package/templates/database/CHANGELOG.md +7 -0
  172. package/templates/database/package.json +1 -1
  173. package/templates/package.json +2 -1
  174. package/templates/tools/check-claude-md.ts +128 -0
  175. package/versions.json +33 -33
  176. package/site-templates/_base/content/en/BookCall/book-call.mdx +0 -52
  177. package/site-templates/minimalism-site/DESIGN.md +0 -162
  178. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +0 -458
  179. package/site-templates/minimalism-site/ailk-template.json +0 -23
  180. package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +0 -110
  181. package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +0 -52
  182. package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +0 -34
  183. package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +0 -57
  184. package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +0 -77
  185. package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +0 -73
  186. package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -123
  187. package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +0 -52
  188. package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +0 -52
  189. package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +0 -52
  190. package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +0 -52
  191. package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +0 -38
  192. package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +0 -38
  193. package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +0 -38
  194. package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +0 -73
  195. package/site-templates/minimalism-site/flows/referral.flow.json +0 -71
  196. package/site-templates/minimalism-site/provenance.json +0 -4
  197. package/templates/.claude/skills/add-page/templates/route.tsx.tmpl +0 -28
  198. package/templates/apps/web/app/[locale]/book-a-call/page.tsx +0 -50
  199. package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +0 -72
  200. /package/site-templates/{minimalism-site → designs/minimalism/sample}/content/en/HomePage/home.mdx +0 -0
  201. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-1.svg +0 -0
  202. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-2.svg +0 -0
  203. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-3.svg +0 -0
  204. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-4.svg +0 -0
  205. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-5.svg +0 -0
  206. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-6.svg +0 -0
  207. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/hero-backdrop.svg +0 -0
  208. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-1.svg +0 -0
  209. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-2.svg +0 -0
  210. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-3.svg +0 -0
  211. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/wordmark-placeholder.svg +0 -0
@@ -1,10 +1,13 @@
1
1
  /**
2
- * The three pages every starter carries whatever its shape (#6658 D5,
3
- * `docs/decisions/starter-roster-page-set.md` D4/D7): a glossary, a newsletter
4
- * signup and a book-a-call page. Each is a module-less `GATEABLE_SURFACES`
5
- * entry the roster enables, with its seed in `_base`. A template carrying the
6
- * scheduling module overrides `BookCall/book-call.mdx` in its own tree, so the
7
- * call to action opens `/meet` rather than `/contact`.
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.
8
11
  */
9
12
  const SHAPE_INDEPENDENT_ROWS = [
10
13
  { route: "/glossary", content: ["content/en/GlossaryList/glossary.mdx"] },
@@ -12,7 +15,37 @@ const SHAPE_INDEPENDENT_ROWS = [
12
15
  route: "/newsletter",
13
16
  content: ["content/en/NewsletterSignup/newsletter.mdx"],
14
17
  },
15
- { route: "/book-a-call", content: ["content/en/BookCall/book-call.mdx"] },
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
+ },
16
49
  ];
17
50
  /**
18
51
  * The rows every `organization-product` template brings itself — one declared
@@ -26,17 +59,17 @@ const SHAPE_INDEPENDENT_ROWS = [
26
59
  *
27
60
  * Two layers, one roster:
28
61
  *
29
- * - `/`, `/software/[slug]`, `/use-cases`, `/about`, `/faq`, `/contact` and
62
+ * - `/`, `/software/[slug]`, `/for`, `/about`, `/faq`, `/contact` and
30
63
  * `/purchase-policy` take their content from the overlay
31
64
  * (`template-overlay/content/en/**`, copied whole into `templates/` by
32
65
  * `build-templates.mjs`). `/features` is the FeaturesList hub over one
33
66
  * Feature page per feature at `/features/[slug]` (#6721, reversing the
34
67
  * single `/software/product` page of #6658 D3); both ride the `features`
35
68
  * surface the roster enables.
36
- * `/use-cases` lists the three UseCase pages at `/use-cases/[slug]`
69
+ * `/for` lists the three UseCase pages at `/for/[slug]`
37
70
  * (#6658 D4).
38
71
  * - `/pricing`, `/privacy`, `/terms`, `/glossary`, `/newsletter`,
39
- * `/book-a-call` and the three UseCase pages take their content from the
72
+ * and the three UseCase pages take their content from the
40
73
  * base layer (`site-templates/_base/content/**`, #5618 D1), which every
41
74
  * template reaches by declaring `extends` — installed before the module
42
75
  * bundles and the template's own tree, so a template may override a base
@@ -70,10 +103,11 @@ const TEMPLATE_BASE_ROSTER = [
70
103
  { route: "/features", content: ["content/en/FeaturesList/features.mdx"] },
71
104
  { route: "/features/[slug]", contentDir: "content/en/Feature" },
72
105
  {
73
- route: "/use-cases",
74
- content: ["content/en/UseCasesList/use-cases.mdx"],
106
+ // #6878 D7 — the persona hub, renamed from /use-cases.
107
+ route: "/for",
108
+ content: ["content/en/UseCasesList/for.mdx"],
75
109
  },
76
- { route: "/use-cases/[slug]", contentDir: "content/en/UseCase" },
110
+ { route: "/for/[slug]", contentDir: "content/en/UseCase" },
77
111
  { route: "/pricing", content: ["content/en/Pricing/pricing.mdx"] },
78
112
  { route: "/about", content: ["content/en/AboutPage/about.mdx"] },
79
113
  { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
@@ -128,7 +162,7 @@ const SIGNAL_COLLECTORS_SAMPLE_ROWS = [
128
162
  * 2026-09-25, reversing #6687's "Pro and up"): every shape roster below
129
163
  * carries them, and an alias sheds them only by an explicit `drop`. The seeds
130
164
  * live in the `_base` layer under `content/en/PortfolioItem/`; the detail
131
- * row's `contentDir` installs them (#6646 D1), exactly as `/use-cases/[slug]`
165
+ * row's `contentDir` installs them (#6646 D1), exactly as `/for/[slug]`
132
166
  * serves `content/en/UseCase`.
133
167
  */
134
168
  // NO_HAND_IMPLEMENT_OK: /build-starter operator-directed live pass (#6687).
@@ -148,12 +182,24 @@ const PORTFOLIO_ROWS = [
148
182
  */
149
183
  const REPORTS_ROW = {
150
184
  route: "/reports",
151
- content: ["content/en/LandingPage/reports.mdx"],
185
+ content: ["content/en/ReportsList/reports.mdx"],
152
186
  };
153
187
  const REFERRAL_ROW = {
154
188
  route: "/referral",
155
189
  content: ["content/en/LandingPage/referral.mdx"],
156
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
+ ];
157
203
  /**
158
204
  * `organization-service`'s own rows (#6757 D1), derived from
159
205
  * `derive-roster.py --shape organization-service --primary-goal generate-leads
@@ -168,9 +214,19 @@ const ORGANIZATION_SERVICE_ROWS = [
168
214
  { route: "/about", content: ["content/en/AboutPage/about.mdx"] },
169
215
  { route: "/services", content: ["content/en/ServicesList/services.mdx"] },
170
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" },
171
225
  { route: "/contact", content: ["content/en/ContactPage/contact.mdx"] },
172
226
  { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
173
227
  ...SHAPE_INDEPENDENT_ROWS,
228
+ { route: "/sign-in" },
229
+ { route: "/sign-up" },
174
230
  { route: "/privacy", content: ["content/en/PrivacyPage/privacy.mdx"] },
175
231
  { route: "/terms", content: ["content/en/TermsPage/terms.mdx"] },
176
232
  {
@@ -187,10 +243,18 @@ const LOCAL_BUSINESS_SERVICE_ROWS = [
187
243
  { route: "/", content: ["content/en/HomePage/home.mdx"] },
188
244
  { route: "/services", content: ["content/en/ServicesList/services.mdx"] },
189
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" },
190
252
  { route: "/about", content: ["content/en/AboutPage/about.mdx"] },
191
253
  { route: "/contact", content: ["content/en/ContactPage/contact.mdx"] },
192
254
  { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
193
255
  ...SHAPE_INDEPENDENT_ROWS,
256
+ { route: "/sign-in" },
257
+ { route: "/sign-up" },
194
258
  {
195
259
  route: "/purchase-policy",
196
260
  content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"],
@@ -214,10 +278,18 @@ const PERSON_SERVICE_ROWS = [
214
278
  { route: "/", content: ["content/en/HomePage/home.mdx"] },
215
279
  { route: "/services", content: ["content/en/ServicesList/services.mdx"] },
216
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" },
217
287
  { route: "/about", content: ["content/en/AboutPage/about.mdx"] },
218
288
  { route: "/contact", content: ["content/en/ContactPage/contact.mdx"] },
219
289
  { route: "/faq", content: ["content/en/FAQPage/faq.mdx"] },
220
290
  ...SHAPE_INDEPENDENT_ROWS,
291
+ { route: "/sign-in" },
292
+ { route: "/sign-up" },
221
293
  {
222
294
  route: "/purchase-policy",
223
295
  content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"],
@@ -232,27 +304,33 @@ const PERSON_SERVICE_ROWS = [
232
304
  * `organization-product` is today's base roster, the `/blog` teaser and the
233
305
  * portfolio pair. `organization-service`, `local-business-service` (#6757)
234
306
  * and `person-service` (#6758, roadmap § 6 Phase 2) are each their own rows,
235
- * the `/blog` teaser and the portfolio pair.
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.
236
310
  */
237
311
  export const SHAPE_ROSTERS = Object.freeze({
238
312
  "organization-product": [
239
313
  ...TEMPLATE_BASE_ROSTER,
240
314
  FREE_BLOG_TEASER_ROW,
315
+ ...FREE_MEET_PLACEHOLDER_ROWS,
241
316
  ...PORTFOLIO_ROWS,
242
317
  ],
243
318
  "organization-service": [
244
319
  ...ORGANIZATION_SERVICE_ROWS,
245
320
  FREE_BLOG_TEASER_ROW,
321
+ ...FREE_MEET_PLACEHOLDER_ROWS,
246
322
  ...PORTFOLIO_ROWS,
247
323
  ],
248
324
  "local-business-service": [
249
325
  ...LOCAL_BUSINESS_SERVICE_ROWS,
250
326
  FREE_BLOG_TEASER_ROW,
327
+ ...FREE_MEET_PLACEHOLDER_ROWS,
251
328
  ...PORTFOLIO_ROWS,
252
329
  ],
253
330
  "person-service": [
254
331
  ...PERSON_SERVICE_ROWS,
255
332
  FREE_BLOG_TEASER_ROW,
333
+ ...FREE_MEET_PLACEHOLDER_ROWS,
256
334
  ...PORTFOLIO_ROWS,
257
335
  ],
258
336
  });
@@ -320,8 +398,8 @@ export const ALIASES = Object.freeze({
320
398
  "medical-specialty",
321
399
  ],
322
400
  differences: {
323
- drop: ["/blog"],
324
- add: SIGNAL_COLLECTORS_SAMPLE_ROWS,
401
+ drop: ["/blog", "/meet", "/meet/[slug]"],
402
+ add: [...SIGNAL_COLLECTORS_SAMPLE_ROWS, ...SIGNAL_COLLECTORS_REPORT_ROWS],
325
403
  before: "/portfolio",
326
404
  },
327
405
  },
@@ -346,8 +424,8 @@ export const ALIASES = Object.freeze({
346
424
  ],
347
425
  categories: ["technology", "medical-specialty"],
348
426
  differences: {
349
- drop: ["/blog"],
350
- add: SIGNAL_COLLECTORS_SAMPLE_ROWS,
427
+ drop: ["/blog", "/meet", "/meet/[slug]"],
428
+ add: [...SIGNAL_COLLECTORS_SAMPLE_ROWS, ...SIGNAL_COLLECTORS_REPORT_ROWS],
351
429
  before: "/portfolio",
352
430
  },
353
431
  },
@@ -367,17 +445,19 @@ export const ALIASES = Object.freeze({
367
445
  * (`rosterSurfaces`) nor its `_base`/overlay seed (#6646 D1).
368
446
  *
369
447
  * It declares NO `layout` block (#6638): the deck home, mark-only nav and
370
- * centered footer are the `minimalism` design's, supplied by
371
- * `DESIGN_LAYOUTS` from `design:` — the look any shape can wear. The
372
- * roster rows the `organization-service` shape does not derive
373
- * (`/reports`, `/referral`) are recorded with their reasons in this
374
- * template's TEMPLATE-MANIFEST.md § 3a.
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`.
375
453
  *
376
- * `/reports` and `/referral` carry no `GATEABLE_SURFACES` entry and need
377
- * none: both are single-segment `LandingPage` slugs served by the generic
378
- * `[slug]` route (#5469 D2), the same mechanism Free's `/how-it-works`
379
- * uses. `/reports/[slug]` (the reader) is the signal-collectors module's
380
- * own contributed row.
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.
381
461
  *
382
462
  * `/services/[slug]` declares its seed DIRECTORY as `contentDir`
383
463
  * (`content/en/Service`, as `routes-map.ts` records it). The three
@@ -386,8 +466,10 @@ export const ALIASES = Object.freeze({
386
466
  * Since #6757, `organization-service` carries a real standard roster
387
467
  * (D1), so this alias's `differences` is additions and drops only: it
388
468
  * drops the `/blog` teaser (a Pro alias does not upsell its own level,
389
- * D8) and the portfolio pair (the reports are the proof, not a
390
- * portfolio), adds the signal-collectors samples, and INSERTS its two own
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
391
473
  * rows — `/reports` before `/about`, `/referral` before `/faq` (D7) — to
392
474
  * reproduce its pre-#6757 row order (§ 1.2) exactly.
393
475
  */
@@ -396,8 +478,22 @@ export const ALIASES = Object.freeze({
396
478
  design: "minimalism",
397
479
  modules: ["marketing", "scheduling", "signal-collectors"],
398
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,
399
487
  differences: {
400
- drop: ["/blog", "/portfolio", "/portfolio/[slug]"],
488
+ drop: [
489
+ "/sign-in",
490
+ "/sign-up",
491
+ "/blog",
492
+ "/meet",
493
+ "/meet/[slug]",
494
+ "/portfolio",
495
+ "/portfolio/[slug]",
496
+ ],
401
497
  add: SIGNAL_COLLECTORS_SAMPLE_ROWS,
402
498
  insert: [
403
499
  { before: "/about", rows: [REPORTS_ROW] },
@@ -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 in two columns (Features · Use Cases, #6721), then Blog,
196
- * Pricing and About. The feature and use-case links ride the `features` and
197
- * `use-cases` surfaces; `/blog` is always linked (the teaser or the docs-blog
198
- * module serves it). Pricing is 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;