create-ailk 0.1.0 → 0.2.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 (620) hide show
  1. package/README.md +124 -3
  2. package/component-catalog.md +456 -0
  3. package/dist/cli.js +92 -16
  4. package/dist/component-catalog.d.ts +11 -0
  5. package/dist/component-catalog.js +39 -0
  6. package/dist/copy.d.ts +7 -0
  7. package/dist/copy.js +24 -0
  8. package/dist/derive-architecture.d.ts +13 -0
  9. package/dist/derive-architecture.js +238 -0
  10. package/dist/index.d.ts +7 -2
  11. package/dist/index.js +19 -2
  12. package/dist/lib/extract-module-bundle.d.ts +16 -0
  13. package/dist/lib/extract-module-bundle.js +184 -0
  14. package/dist/lib/fetch-module.d.ts +55 -0
  15. package/dist/lib/fetch-module.js +125 -0
  16. package/dist/lib/module-license-gate.d.ts +48 -0
  17. package/dist/lib/module-license-gate.js +67 -0
  18. package/dist/lib/module-tier.d.ts +35 -0
  19. package/dist/lib/module-tier.js +37 -0
  20. package/dist/module-architecture.d.ts +175 -0
  21. package/dist/module-architecture.js +663 -0
  22. package/dist/parse-args.d.ts +47 -1
  23. package/dist/parse-args.js +143 -2
  24. package/dist/programmatic.d.ts +160 -3
  25. package/dist/programmatic.js +196 -7
  26. package/dist/surfaces.d.ts +211 -0
  27. package/dist/surfaces.js +532 -0
  28. package/dist/sync-routes.d.ts +92 -0
  29. package/dist/sync-routes.js +350 -0
  30. package/package.json +12 -5
  31. package/templates/.claude/rules/architecture.md +6 -2
  32. package/templates/.claude/skills/README.md +9 -9
  33. package/templates/.claude/skills/add-schema/SKILL.md +14 -7
  34. package/templates/.claude/skills/add-schema/references/schema-types.md +109 -6
  35. package/templates/.claude/skills/provision-config/SKILL.md +1 -1
  36. package/templates/.claude/skills/scaffold-commerce/SKILL.md +498 -1
  37. package/templates/.claude/skills/scaffold-commerce/templates/checkout-route.template.ts +370 -0
  38. package/templates/.claude/skills/scaffold-commerce/templates/invoice-route.template.ts +376 -0
  39. package/templates/.claude/skills/scaffold-commerce/templates/payment-link-route.template.ts +471 -0
  40. package/templates/.claude/skills/scaffold-commerce/templates/portal-route.template.ts +365 -0
  41. package/templates/.claude/skills/scaffold-commerce/templates/stripe-config.template.ts +60 -0
  42. package/templates/.claude/skills/scaffold-commerce/templates/subscription-route.template.ts +446 -0
  43. package/templates/.claude/skills/suggest-site-pages/references/categories.md +4 -4
  44. package/templates/.env.example +126 -2
  45. package/templates/CLAUDE.md +11 -5
  46. package/templates/README.md +1 -1
  47. package/templates/apps/api/.env.example +38 -0
  48. package/templates/apps/api/CLAUDE.md +78 -1
  49. package/templates/apps/api/LICENSE +201 -0
  50. package/templates/apps/api/api/index.ts +6 -141
  51. package/templates/apps/api/jest.config.cjs +16 -0
  52. package/templates/apps/api/package.json +22 -6
  53. package/templates/apps/api/src/__tests__/module-exclusion.test.ts +141 -0
  54. package/templates/apps/api/src/__tests__/server.test.ts +46 -0
  55. package/templates/apps/api/src/__tests__/vercel-handler.test.ts +211 -0
  56. package/templates/apps/api/src/bin/abandon-sweep.ts +42 -0
  57. package/templates/apps/api/src/bin/deliverable-resend.ts +144 -0
  58. package/templates/apps/api/src/bin/deliverable-upload.ts +114 -0
  59. package/templates/apps/api/src/bin/followup-sweep.ts +44 -0
  60. package/templates/apps/api/src/bin/listing-csv-sweep.ts +46 -0
  61. package/templates/apps/api/src/bin/seed-presets.ts +58 -0
  62. package/templates/apps/api/src/bin/seed-waitlist-experiments.ts +104 -0
  63. package/templates/apps/api/src/bin/session-retention-sweep.ts +46 -0
  64. package/templates/apps/api/src/cli.ts +5 -11
  65. package/templates/apps/api/src/config/index.ts +35 -0
  66. package/templates/apps/api/src/config/modules.ts +43 -0
  67. package/templates/apps/api/src/lib/__mocks__/prisma-client.js +11 -0
  68. package/templates/apps/api/src/lib/__mocks__/prisma.ts +241 -0
  69. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +2 -2
  70. package/templates/apps/api/src/lib/site.ts +16 -0
  71. package/templates/apps/api/src/lib/stripe.ts +22 -0
  72. package/templates/apps/api/src/lib/tenant-db.ts +225 -0
  73. package/templates/apps/api/src/lib/ws-token.ts +91 -0
  74. package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +7 -1
  75. package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +7 -1
  76. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +91 -4
  77. package/templates/apps/api/src/middleware/auth.ts +43 -8
  78. package/templates/apps/api/src/middleware/rate-limit.ts +78 -3
  79. package/templates/apps/api/src/middleware/tenant.ts +99 -0
  80. package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +92 -0
  81. package/templates/apps/api/src/openapi/spec.ts +312 -3
  82. package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +175 -0
  83. package/templates/apps/api/src/routes/aeo/index.ts +107 -0
  84. package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +5 -2
  85. package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +22 -3
  86. package/templates/apps/api/src/routes/auth/tokens.ts +13 -1
  87. package/templates/apps/api/src/routes/billing/__tests__/portal.test.ts +450 -0
  88. package/templates/apps/api/src/routes/billing/__tests__/read.test.ts +262 -0
  89. package/templates/apps/api/src/routes/billing/__tests__/usage.test.ts +436 -0
  90. package/templates/apps/api/src/routes/billing/index.ts +36 -0
  91. package/templates/apps/api/src/routes/billing/portal.ts +182 -0
  92. package/templates/apps/api/src/routes/billing/read.ts +75 -0
  93. package/templates/apps/api/src/routes/billing/usage.ts +153 -0
  94. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +99 -0
  95. package/templates/apps/api/src/routes/checkout/sessions.ts +20 -8
  96. package/templates/apps/api/src/routes/content/create.ts +1 -0
  97. package/templates/apps/api/src/routes/content/delete.ts +1 -0
  98. package/templates/apps/api/src/routes/content/index.ts +42 -6
  99. package/templates/apps/api/src/routes/content/update.ts +1 -0
  100. package/templates/apps/api/src/routes/deliverables/__tests__/index.test.ts +393 -0
  101. package/templates/apps/api/src/routes/deliverables/index.ts +200 -0
  102. package/templates/apps/api/src/routes/flow-checkouts/__tests__/index.test.ts +443 -0
  103. package/templates/apps/api/src/routes/flow-checkouts/index.ts +82 -0
  104. package/templates/apps/api/src/routes/flows/README.md +147 -0
  105. package/templates/apps/api/src/routes/flows/__tests__/index.test.ts +752 -0
  106. package/templates/apps/api/src/routes/flows/__tests__/recommender.test.ts +671 -0
  107. package/templates/apps/api/src/routes/flows/index.ts +202 -0
  108. package/templates/apps/api/src/routes/flows/recommender.ts +443 -0
  109. package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +438 -31
  110. package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +10 -10
  111. package/templates/apps/api/src/routes/leads/index.ts +43 -9
  112. package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +558 -0
  113. package/templates/apps/api/src/routes/project-listings/__tests__/copy-edit.test.ts +815 -0
  114. package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +869 -0
  115. package/templates/apps/api/src/routes/project-listings/__tests__/me-route-precedence.test.ts +221 -0
  116. package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +468 -0
  117. package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +424 -0
  118. package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +707 -0
  119. package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +375 -0
  120. package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +467 -0
  121. package/templates/apps/api/src/routes/project-listings/__tests__/tenant-isolation.test.ts +566 -0
  122. package/templates/apps/api/src/routes/project-listings/get.ts +70 -0
  123. package/templates/apps/api/src/routes/project-listings/index.ts +120 -0
  124. package/templates/apps/api/src/routes/project-listings/list.ts +47 -0
  125. package/templates/apps/api/src/routes/project-listings/me.ts +76 -0
  126. package/templates/apps/api/src/routes/project-listings/patch-copy.ts +222 -0
  127. package/templates/apps/api/src/routes/project-listings/patch-draft.ts +97 -0
  128. package/templates/apps/api/src/routes/project-listings/patch.ts +136 -0
  129. package/templates/apps/api/src/routes/project-listings/public.ts +52 -0
  130. package/templates/apps/api/src/routes/project-listings/respond.ts +37 -0
  131. package/templates/apps/api/src/routes/project-listings/resume-token.ts +22 -0
  132. package/templates/apps/api/src/routes/project-listings/start.ts +106 -0
  133. package/templates/apps/api/src/routes/project-listings/submit.ts +122 -0
  134. package/templates/apps/api/src/routes/schedule/__tests__/index.test.ts +490 -0
  135. package/templates/apps/api/src/routes/schedule/index.ts +249 -0
  136. package/templates/apps/api/src/routes/slack/__tests__/actions.test.ts +385 -0
  137. package/templates/apps/api/src/routes/slack/actions.ts +177 -0
  138. package/templates/apps/api/src/routes/slack/index.ts +38 -0
  139. package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +16 -6
  140. package/templates/apps/api/src/routes/test/auth/session.ts +8 -6
  141. package/templates/apps/api/src/routes/waitlist-experiments/__tests__/tenant-isolation.test.ts +577 -0
  142. package/templates/apps/api/src/routes/waitlist-experiments/comparison.ts +78 -0
  143. package/templates/apps/api/src/routes/waitlist-experiments/index.ts +41 -0
  144. package/templates/apps/api/src/routes/waitlist-experiments/list.ts +64 -0
  145. package/templates/apps/api/src/routes/waitlist-experiments/respond.ts +42 -0
  146. package/templates/apps/api/src/routes/waitlist-experiments/signup.ts +84 -0
  147. package/templates/apps/api/src/routes/waitlist-experiments/signups.ts +119 -0
  148. package/templates/apps/api/src/routes/waitlist-signups/__tests__/index.test.ts +238 -0
  149. package/templates/apps/api/src/routes/waitlist-signups/index.ts +101 -0
  150. package/templates/apps/api/src/routes/webhooks/README.md +35 -12
  151. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +315 -0
  152. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +270 -0
  153. package/templates/apps/api/src/routes/webhooks/stripe.ts +248 -20
  154. package/templates/apps/api/src/routes/workspaces/__tests__/config-tenant-isolation.test.ts +356 -0
  155. package/templates/apps/api/src/routes/workspaces/__tests__/tenant-isolation.test.ts +671 -0
  156. package/templates/apps/api/src/routes/workspaces/config.ts +125 -0
  157. package/templates/apps/api/src/routes/workspaces/index.ts +194 -0
  158. package/templates/apps/api/src/routes/workspaces/sessions.ts +218 -0
  159. package/templates/apps/api/src/server.ts +307 -7
  160. package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +489 -0
  161. package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +475 -0
  162. package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +132 -0
  163. package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +65 -0
  164. package/templates/apps/api/src/services/__tests__/consent.test.ts +282 -0
  165. package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +523 -0
  166. package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +359 -0
  167. package/templates/apps/api/src/services/__tests__/entitlements.test.ts +142 -0
  168. package/templates/apps/api/src/services/__tests__/flow-aggregate.test.ts +425 -0
  169. package/templates/apps/api/src/services/__tests__/flow-engine.test.ts +2840 -0
  170. package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +393 -0
  171. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +8 -8
  172. package/templates/apps/api/src/services/__tests__/listing-csv-sweep.test.ts +560 -0
  173. package/templates/apps/api/src/services/__tests__/listing-promotion.test.ts +684 -0
  174. package/templates/apps/api/src/services/__tests__/playbook-compile.test.ts +406 -0
  175. package/templates/apps/api/src/services/__tests__/playbook-render.test.ts +290 -0
  176. package/templates/apps/api/src/services/__tests__/project-listing-decision.test.ts +736 -0
  177. package/templates/apps/api/src/services/__tests__/project-listing-flow.test.ts +475 -0
  178. package/templates/apps/api/src/services/__tests__/project-listing-issue.test.ts +340 -0
  179. package/templates/apps/api/src/services/__tests__/recommender-capture.test.ts +983 -0
  180. package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +278 -0
  181. package/templates/apps/api/src/services/__tests__/tenant-context-cascade.test.ts +71 -0
  182. package/templates/apps/api/src/services/__tests__/tenant-context.test.ts +379 -0
  183. package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +941 -0
  184. package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +588 -0
  185. package/templates/apps/api/src/services/__tests__/usage-metering.test.ts +768 -0
  186. package/templates/apps/api/src/services/__tests__/waitlist-dashboard.test.ts +1314 -0
  187. package/templates/apps/api/src/services/__tests__/waitlist-experiments.test.ts +341 -0
  188. package/templates/apps/api/src/services/__tests__/waitlist-followup.test.ts +567 -0
  189. package/templates/apps/api/src/services/__tests__/waitlist-scoring.test.ts +474 -0
  190. package/templates/apps/api/src/services/__tests__/waitlist-signups.test.ts +354 -0
  191. package/templates/apps/api/src/services/abandon-email.ts +307 -0
  192. package/templates/apps/api/src/services/aeo-score.ts +288 -0
  193. package/templates/apps/api/src/services/answer-distributions.ts +138 -0
  194. package/templates/apps/api/src/services/consent.ts +236 -0
  195. package/templates/apps/api/src/services/deliverable-fulfillment.ts +523 -0
  196. package/templates/apps/api/src/services/entitlements.ts +102 -0
  197. package/templates/apps/api/src/services/flow-aggregate.ts +232 -0
  198. package/templates/apps/api/src/services/flow-checkouts.ts +123 -0
  199. package/templates/apps/api/src/services/flow-engine.ts +1296 -0
  200. package/templates/apps/api/src/services/lead-promotion.ts +176 -0
  201. package/templates/apps/api/src/services/lead-routing.ts +3 -3
  202. package/templates/apps/api/src/services/listing-config.ts +102 -0
  203. package/templates/apps/api/src/services/listing-csv-sweep.ts +455 -0
  204. package/templates/apps/api/src/services/listing-promotion.ts +342 -0
  205. package/templates/apps/api/src/services/playbook-compile.ts +398 -0
  206. package/templates/apps/api/src/services/playbook-render.ts +263 -0
  207. package/templates/apps/api/src/services/project-listing-decision.ts +510 -0
  208. package/templates/apps/api/src/services/project-listing-flow.ts +426 -0
  209. package/templates/apps/api/src/services/project-listing-issue.ts +251 -0
  210. package/templates/apps/api/src/services/project-listings.ts +1472 -0
  211. package/templates/apps/api/src/services/recommender-capture.ts +835 -0
  212. package/templates/apps/api/src/services/scheduling/cal-provider.ts +392 -0
  213. package/templates/apps/api/src/services/scheduling/index.ts +63 -0
  214. package/templates/apps/api/src/services/scheduling/types.ts +88 -0
  215. package/templates/apps/api/src/services/slack-notify.ts +240 -0
  216. package/templates/apps/api/src/services/tenant-context.ts +451 -0
  217. package/templates/apps/api/src/services/usage-aggregation.ts +516 -0
  218. package/templates/apps/api/src/services/usage-credits.ts +340 -0
  219. package/templates/apps/api/src/services/usage-metering.ts +699 -0
  220. package/templates/apps/api/src/services/waitlist-dashboard.ts +947 -0
  221. package/templates/apps/api/src/services/waitlist-experiments.ts +213 -0
  222. package/templates/apps/api/src/services/waitlist-followup.ts +486 -0
  223. package/templates/apps/api/src/services/waitlist-scoring.ts +166 -0
  224. package/templates/apps/api/src/services/waitlist-signups.ts +165 -0
  225. package/templates/apps/api/src/vercel-handler.ts +165 -0
  226. package/templates/apps/api/tsconfig.json +0 -12
  227. package/templates/apps/mcp/CLAUDE.md +19 -9
  228. package/templates/apps/mcp/LICENSE +201 -0
  229. package/templates/apps/mcp/__tests__/create_page.test.ts +1 -0
  230. package/templates/apps/mcp/__tests__/delete_page.test.ts +1 -0
  231. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +105 -0
  232. package/templates/apps/mcp/__tests__/parity.test.ts +70 -6
  233. package/templates/apps/mcp/__tests__/request_callback.test.ts +4 -4
  234. package/templates/apps/mcp/__tests__/schedule_tools.test.ts +242 -0
  235. package/templates/apps/mcp/__tests__/submit_lead.test.ts +4 -4
  236. package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +4 -4
  237. package/templates/apps/mcp/__tests__/tools/purchase.test.ts +47 -0
  238. package/templates/apps/mcp/__tests__/update_page.test.ts +1 -0
  239. package/templates/apps/mcp/package.json +6 -4
  240. package/templates/apps/mcp/src/config/modules.ts +37 -0
  241. package/templates/apps/mcp/src/server.ts +109 -18
  242. package/templates/apps/mcp/src/tools/capture_lead.ts +1 -1
  243. package/templates/apps/mcp/src/tools/create_booking.ts +58 -0
  244. package/templates/apps/mcp/src/tools/create_page.ts +1 -0
  245. package/templates/apps/mcp/src/tools/delete_page.ts +1 -0
  246. package/templates/apps/mcp/src/tools/get_event_meta.ts +55 -0
  247. package/templates/apps/mcp/src/tools/get_flow.ts +61 -0
  248. package/templates/apps/mcp/src/tools/index.ts +25 -0
  249. package/templates/apps/mcp/src/tools/list_availability.ts +67 -0
  250. package/templates/apps/mcp/src/tools/purchase.ts +3 -0
  251. package/templates/apps/mcp/src/tools/submit_flow_step.ts +83 -0
  252. package/templates/apps/mcp/src/tools/update_page.ts +1 -0
  253. package/templates/apps/mcp/tsconfig.json +1 -9
  254. package/templates/apps/web/.env.example +44 -0
  255. package/templates/apps/web/CLAUDE.md +28 -0
  256. package/templates/apps/web/LICENSE +201 -0
  257. package/templates/apps/web/__tests__/__mocks__/code-highlight.jest-stub.ts +24 -0
  258. package/templates/apps/web/__tests__/__mocks__/next-intl-server.ts +33 -0
  259. package/templates/apps/web/__tests__/__mocks__/next-intl.ts +18 -0
  260. package/templates/apps/web/__tests__/__mocks__/server-only.ts +13 -0
  261. package/templates/apps/web/__tests__/__mocks__/style-mock.js +4 -0
  262. package/templates/apps/web/__tests__/__mocks__/vercel-analytics-server.ts +9 -0
  263. package/templates/apps/web/__tests__/jest-support/import-meta-transformer.cjs +90 -0
  264. package/templates/apps/web/__tests__/setup.ts +22 -32
  265. package/templates/apps/web/app/.well-known/ai-plugin.json/route.ts +6 -3
  266. package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +8 -2
  267. package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +260 -0
  268. package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +263 -0
  269. package/templates/apps/web/app/[locale]/(authed)/account/sign-out-button.tsx +39 -0
  270. package/templates/apps/web/app/[locale]/(authed)/layout.tsx +54 -0
  271. package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +96 -0
  272. package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/page.tsx +309 -0
  273. package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/signups/[leadId]/page.tsx +149 -0
  274. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/comparison.test.tsx +273 -0
  275. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/gate.test.tsx +172 -0
  276. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/list.test.tsx +171 -0
  277. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/signup.test.tsx +179 -0
  278. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ExperimentsTable.tsx +116 -0
  279. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ForbiddenState.tsx +24 -0
  280. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/OfferFunnelTable.tsx +66 -0
  281. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/RollupTicker.tsx +61 -0
  282. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ScoreTrace.tsx +114 -0
  283. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/SignupsTable.tsx +139 -0
  284. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/WaitlistComparisonTabs.tsx +85 -0
  285. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/status-badges.tsx +67 -0
  286. package/templates/apps/web/app/[locale]/(authed)/waitlist/format.ts +111 -0
  287. package/templates/apps/web/app/[locale]/(authed)/waitlist/page.tsx +179 -0
  288. package/templates/apps/web/app/[locale]/about/page.tsx +10 -1
  289. package/templates/apps/web/app/[locale]/blog/[[...slug]]/page.tsx +6 -1
  290. package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +9 -0
  291. package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +3 -3
  292. package/templates/apps/web/app/[locale]/careers/page.tsx +9 -1
  293. package/templates/apps/web/app/[locale]/case-studies/[slug]/page.tsx +9 -0
  294. package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +3 -3
  295. package/templates/apps/web/app/[locale]/case-studies/page.tsx +13 -1
  296. package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +11 -1
  297. package/templates/apps/web/app/[locale]/clients/page.tsx +9 -1
  298. package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +21 -1
  299. package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +188 -0
  300. package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +242 -0
  301. package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +29 -0
  302. package/templates/apps/web/app/[locale]/contact/__tests__/intake-analytics.test.ts +51 -0
  303. package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +39 -15
  304. package/templates/apps/web/app/[locale]/contact/contact.actions.ts +21 -3
  305. package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +49 -0
  306. package/templates/apps/web/app/[locale]/contact/intake-script.ts +66 -0
  307. package/templates/apps/web/app/[locale]/contact/page.tsx +14 -4
  308. package/templates/apps/web/app/[locale]/courses/[slug]/page.tsx +13 -1
  309. package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +3 -3
  310. package/templates/apps/web/app/[locale]/courses/page.tsx +9 -1
  311. package/templates/apps/web/app/[locale]/docs/[[...slug]]/page.tsx +1 -0
  312. package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +11 -1
  313. package/templates/apps/web/app/[locale]/downloads/page.tsx +13 -1
  314. package/templates/apps/web/app/[locale]/events/[slug]/page.tsx +9 -0
  315. package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +12 -2
  316. package/templates/apps/web/app/[locale]/events/page.tsx +9 -1
  317. package/templates/apps/web/app/[locale]/faq/page.tsx +10 -1
  318. package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +265 -0
  319. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +445 -0
  320. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +341 -0
  321. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/checkout.actions.test.ts +287 -0
  322. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/flow.actions.test.ts +302 -0
  323. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/two-route-tool.test.tsx +128 -0
  324. package/templates/apps/web/app/[locale]/flows/[slug]/checkout.actions.ts +254 -0
  325. package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +144 -0
  326. package/templates/apps/web/app/[locale]/flows/[slug]/page.tsx +108 -0
  327. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsClient.tsx +532 -0
  328. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsEmailStep.tsx +121 -0
  329. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/ResultsClient.checkout.test.tsx +457 -0
  330. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/page.test.tsx +396 -0
  331. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/page.tsx +114 -0
  332. package/templates/apps/web/app/[locale]/flows/[slug]/start/page.tsx +52 -0
  333. package/templates/apps/web/app/[locale]/how-to/[slug]/page.tsx +13 -1
  334. package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
  335. package/templates/apps/web/app/[locale]/integrations/[slug]/page.tsx +9 -0
  336. package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +3 -3
  337. package/templates/apps/web/app/[locale]/integrations/page.tsx +13 -1
  338. package/templates/apps/web/app/[locale]/launch-service/page.tsx +14 -1
  339. package/templates/apps/web/app/[locale]/layout.tsx +127 -16
  340. package/templates/apps/web/app/[locale]/page.tsx +10 -1
  341. package/templates/apps/web/app/[locale]/partners/[slug]/page.tsx +9 -0
  342. package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +3 -3
  343. package/templates/apps/web/app/[locale]/partners/page.tsx +9 -1
  344. package/templates/apps/web/app/[locale]/products/[slug]/page.tsx +9 -0
  345. package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +3 -3
  346. package/templates/apps/web/app/[locale]/products/page.tsx +9 -1
  347. package/templates/apps/web/app/[locale]/projects/[slug]/page.tsx +13 -1
  348. package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +10 -0
  349. package/templates/apps/web/app/[locale]/projects/apply/ListingApplicationClient.tsx +110 -0
  350. package/templates/apps/web/app/[locale]/projects/apply/__tests__/ListingApplicationClient.test.tsx +96 -0
  351. package/templates/apps/web/app/[locale]/projects/page.tsx +13 -1
  352. package/templates/apps/web/app/[locale]/resources/[slug]/page.tsx +9 -0
  353. package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +12 -2
  354. package/templates/apps/web/app/[locale]/resources/page.tsx +13 -1
  355. package/templates/apps/web/app/[locale]/schedule/__tests__/page.test.tsx +117 -0
  356. package/templates/apps/web/app/[locale]/schedule/confirmed/__tests__/page.test.tsx +96 -0
  357. package/templates/apps/web/app/[locale]/schedule/confirmed/page.tsx +92 -0
  358. package/templates/apps/web/app/[locale]/schedule/page.tsx +82 -0
  359. package/templates/apps/web/app/[locale]/services/[slug]/page.tsx +9 -0
  360. package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +3 -3
  361. package/templates/apps/web/app/[locale]/services/page.tsx +9 -1
  362. package/templates/apps/web/app/[locale]/sign-in/__tests__/next-path.test.ts +31 -0
  363. package/templates/apps/web/app/[locale]/sign-in/__tests__/page.test.tsx +152 -0
  364. package/templates/apps/web/app/[locale]/sign-in/next-path.ts +0 -0
  365. package/templates/apps/web/app/[locale]/sign-in/page.tsx +83 -0
  366. package/templates/apps/web/app/[locale]/sign-in/sign-in-card.tsx +123 -0
  367. package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +13 -1
  368. package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
  369. package/templates/apps/web/app/[locale]/tech-articles/[slug]/page.tsx +13 -1
  370. package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
  371. package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +11 -1
  372. package/templates/apps/web/app/[locale]/testimonials/page.tsx +13 -1
  373. package/templates/apps/web/app/[locale]/thanks/[slug]/__tests__/page.test.tsx +93 -0
  374. package/templates/apps/web/app/[locale]/thanks/[slug]/page.tsx +48 -0
  375. package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +11 -1
  376. package/templates/apps/web/app/[locale]/use-cases/page.tsx +13 -1
  377. package/templates/apps/web/app/[locale]/whitepapers/[slug]/page.tsx +13 -1
  378. package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
  379. package/templates/apps/web/app/globals.css +35 -0
  380. package/templates/apps/web/app/llms.txt/route.ts +2 -1
  381. package/templates/apps/web/app/og/route.tsx +10 -2
  382. package/templates/apps/web/auth.ts +8 -0
  383. package/templates/apps/web/components/sign-out-trigger.tsx +42 -0
  384. package/templates/apps/web/content/en/blog/README.txt +25 -0
  385. package/templates/apps/web/content/en/docs/index.mdx +28 -0
  386. package/templates/apps/web/jest.config.cjs +90 -27
  387. package/templates/apps/web/lib/__tests__/site-brand.test.ts +119 -0
  388. package/templates/apps/web/lib/__tests__/site-theme.test.ts +112 -0
  389. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +499 -0
  390. package/templates/apps/web/lib/account-config.ts +13 -0
  391. package/templates/apps/web/lib/server-api.ts +85 -0
  392. package/templates/apps/web/lib/site-brand.tsx +121 -0
  393. package/templates/apps/web/lib/site-theme.ts +74 -0
  394. package/templates/apps/web/messages/en.json +275 -7
  395. package/templates/apps/web/middleware.ts +11 -3
  396. package/templates/apps/web/next.config.mjs +8 -2
  397. package/templates/apps/web/package.json +17 -7
  398. package/templates/apps/web/postcss.config.mjs +23 -0
  399. package/templates/apps/web/public/.well-known/security.txt +3 -3
  400. package/templates/apps/web/src/lib/routes.ts +15 -2
  401. package/templates/apps/web/tsconfig.json +1 -16
  402. package/templates/content/_site.mdx +36 -25
  403. package/templates/content/en/AboutPage/about.mdx +24 -14
  404. package/templates/content/en/ContactPage/contact.mdx +23 -14
  405. package/templates/content/en/FAQPage/faq.mdx +10 -392
  406. package/templates/content/en/HomePage/home.mdx +14 -285
  407. package/templates/database/CHANGELOG.md +443 -0
  408. package/templates/database/LICENSE +201 -0
  409. package/templates/database/README.md +3 -1
  410. package/templates/database/__tests__/flows-listing-diagnostic.test.ts +392 -0
  411. package/templates/database/__tests__/flows-presets.test.ts +173 -0
  412. package/templates/database/__tests__/prefixed-ids.db.test.ts +146 -0
  413. package/templates/database/__tests__/seed.test.ts +88 -0
  414. package/templates/database/__tests__/user-cascade.test.ts +19 -4
  415. package/templates/database/auth/schema.prisma +521 -0
  416. package/templates/database/config/schema.prisma +234 -0
  417. package/templates/database/content/schema.prisma +263 -0
  418. package/templates/database/flows/listing-diagnostic.ts +182 -0
  419. package/templates/database/flows/presets.ts +315 -0
  420. package/templates/database/inbox/__tests__/schema.test.ts +4 -0
  421. package/templates/database/inbox/schema.prisma +574 -3
  422. package/templates/database/jest.config.cjs +8 -0
  423. package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +201 -0
  424. package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +67 -0
  425. package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +46 -0
  426. package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +25 -0
  427. package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +49 -0
  428. package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +197 -0
  429. package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +32 -0
  430. package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +22 -0
  431. package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +151 -0
  432. package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +223 -0
  433. package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +22 -0
  434. package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +32 -0
  435. package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +40 -0
  436. package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +4 -0
  437. package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +2 -0
  438. package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +2 -0
  439. package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +29 -0
  440. package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +6 -0
  441. package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +39 -0
  442. package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +24 -0
  443. package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +3 -0
  444. package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +33 -0
  445. package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +30 -0
  446. package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +47 -0
  447. package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +16 -0
  448. package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +47 -0
  449. package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +10 -0
  450. package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +26 -0
  451. package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +90 -0
  452. package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +174 -0
  453. package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +14 -0
  454. package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +25 -0
  455. package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +32 -0
  456. package/templates/database/migrations/20260911180000_consent_grants/migration.sql +71 -0
  457. package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +30 -0
  458. package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +49 -0
  459. package/templates/database/ops/schema.prisma +27 -0
  460. package/templates/database/package.json +42 -4
  461. package/templates/database/prisma.config.ts +1 -1
  462. package/templates/database/schema.prisma +19 -435
  463. package/templates/database/seed-test.ts +14 -4
  464. package/templates/database/seed.ts +148 -0
  465. package/templates/database/tenancy.ts +45 -0
  466. package/templates/database/tsconfig.flows.json +15 -0
  467. package/templates/database/tsconfig.json +7 -1
  468. package/templates/database/tsconfig.tenancy.json +14 -0
  469. package/templates/package.json +30 -55
  470. package/templates/pnpm-workspace.yaml +0 -3
  471. package/templates/project.yaml +1 -1
  472. package/templates/tsconfig.json +1 -37
  473. package/templates/apps/web/__tests__/auth/adversarial/cookie-attributes.test.ts +0 -94
  474. package/templates/apps/web/__tests__/auth/adversarial/oauth-state-parameter.test.ts +0 -75
  475. package/templates/apps/web/__tests__/auth/adversarial/redirect-uri-allowlist.test.ts +0 -82
  476. package/templates/apps/web/__tests__/auth/env-helpers.test.ts +0 -168
  477. package/templates/apps/web/__tests__/authority-list-routes.test.tsx +0 -208
  478. package/templates/apps/web/__tests__/better-stack.test.ts +0 -66
  479. package/templates/apps/web/__tests__/blog-dir-resolution.test.ts +0 -87
  480. package/templates/apps/web/__tests__/blog-source-populated.test.ts +0 -130
  481. package/templates/apps/web/__tests__/data-testid-coverage.test.tsx +0 -60
  482. package/templates/apps/web/__tests__/google-analytics.test.tsx +0 -104
  483. package/templates/apps/web/__tests__/i18n/middleware.test.ts +0 -119
  484. package/templates/apps/web/__tests__/i18n/routing.test.ts +0 -114
  485. package/templates/apps/web/__tests__/i18n/translations.test.ts +0 -191
  486. package/templates/apps/web/__tests__/json-ld.test.ts +0 -98
  487. package/templates/apps/web/__tests__/knowledge-events-routes.test.tsx +0 -580
  488. package/templates/apps/web/__tests__/layout-stealth.test.ts +0 -39
  489. package/templates/apps/web/__tests__/lighthouse-fixtures/improvement-image-shrink.tsx +0 -103
  490. package/templates/apps/web/__tests__/lighthouse-fixtures/override-fixture.md +0 -114
  491. package/templates/apps/web/__tests__/lighthouse-fixtures/regression-bloat.tsx +0 -94
  492. package/templates/apps/web/__tests__/page.test.tsx +0 -230
  493. package/templates/apps/web/__tests__/products-services-phase1.test.tsx +0 -321
  494. package/templates/apps/web/__tests__/projects-routes.test.tsx +0 -392
  495. package/templates/apps/web/__tests__/resources-downloads-integrations-phase2.test.tsx +0 -475
  496. package/templates/apps/web/__tests__/routes/ai-plugin-json.test.ts +0 -53
  497. package/templates/apps/web/__tests__/routes/blog-route.test.tsx +0 -191
  498. package/templates/apps/web/__tests__/routes/llms-txt.test.ts +0 -123
  499. package/templates/apps/web/__tests__/routes/robots-txt.test.ts +0 -52
  500. package/templates/apps/web/__tests__/routes/sitemap-xml.test.ts +0 -78
  501. package/templates/apps/web/__tests__/routes/well-known-mcp.test.ts +0 -203
  502. package/templates/apps/web/__tests__/section-routes.test.tsx +0 -693
  503. package/templates/apps/web/__tests__/security-headers.test.ts +0 -201
  504. package/templates/apps/web/__tests__/sentry-config.test.ts +0 -116
  505. package/templates/apps/web/__tests__/sitemap-locales.test.ts +0 -415
  506. package/templates/apps/web/__tests__/standalone-informational-routes.test.tsx +0 -844
  507. package/templates/apps/web/app/[locale]/__tests__/layout.test.tsx +0 -120
  508. package/templates/apps/web/app/[locale]/__tests__/page-renderer-migration.test.tsx +0 -202
  509. package/templates/apps/web/app/__tests__/error-boundaries.test.tsx +0 -152
  510. package/templates/apps/web/content/en/blog/index.mdx +0 -15
  511. package/templates/apps/web/content/en/blog/launching-ailk.mdx +0 -20
  512. package/templates/apps/web/content/en/docs/getting-started.mdx +0 -30
  513. package/templates/content/.gitkeep +0 -0
  514. package/templates/content/CLAUDE.md +0 -85
  515. package/templates/content/ar/HomePage/home.mdx +0 -123
  516. package/templates/content/ar/_site.mdx +0 -35
  517. package/templates/content/de/_site.mdx +0 -29
  518. package/templates/content/en/.gitkeep +0 -0
  519. package/templates/content/en/AboutPage/about.schema.json +0 -82
  520. package/templates/content/en/BookCall/book-call.mdx +0 -19
  521. package/templates/content/en/BookCall/book-call.schema.json +0 -121
  522. package/templates/content/en/BreadcrumbList/site-breadcrumbs.mdx +0 -20
  523. package/templates/content/en/CareersList/careers.mdx +0 -24
  524. package/templates/content/en/CaseStudiesList/case-studies.mdx +0 -22
  525. package/templates/content/en/CaseStudiesList/showcase.mdx +0 -8
  526. package/templates/content/en/CaseStudy/ailk-aeo-rollout.mdx +0 -32
  527. package/templates/content/en/CaseStudy/schema-builder-migration.mdx +0 -41
  528. package/templates/content/en/ClientsList/clients.mdx +0 -38
  529. package/templates/content/en/ContactPage/contact.schema.json +0 -100
  530. package/templates/content/en/ContactPoint/primary.mdx +0 -14
  531. package/templates/content/en/Course/aeo-fundamentals.mdx +0 -37
  532. package/templates/content/en/Course/schema-builder-workshop.mdx +0 -62
  533. package/templates/content/en/CoursesList/courses.mdx +0 -22
  534. package/templates/content/en/DownloadsList/downloads.mdx +0 -22
  535. package/templates/content/en/Event/aeo-office-hours-may-2026.mdx +0 -39
  536. package/templates/content/en/Event/ailk-launch-day-2026.mdx +0 -35
  537. package/templates/content/en/EventsList/events.mdx +0 -26
  538. package/templates/content/en/FAQPage/faq.schema.json +0 -231
  539. package/templates/content/en/GlossaryList/glossary.mdx +0 -19
  540. package/templates/content/en/GlossaryList/glossary.schema.json +0 -300
  541. package/templates/content/en/HomePage/home.schema.json +0 -88
  542. package/templates/content/en/HomePage/launch-service.mdx +0 -475
  543. package/templates/content/en/HomePage/launch-service.schema.json +0 -138
  544. package/templates/content/en/HowTo/add-mdx-content.mdx +0 -38
  545. package/templates/content/en/HowTo/configure-aeo-scoring.mdx +0 -35
  546. package/templates/content/en/HowTo/set-up-json-ld.mdx +0 -36
  547. package/templates/content/en/Integration/github-actions.mdx +0 -31
  548. package/templates/content/en/Integration/openai-api.mdx +0 -26
  549. package/templates/content/en/Integration/vercel.mdx +0 -32
  550. package/templates/content/en/IntegrationsList/integrations.mdx +0 -22
  551. package/templates/content/en/JobPosting/content-strategist.mdx +0 -46
  552. package/templates/content/en/JobPosting/developer-advocate.mdx +0 -47
  553. package/templates/content/en/JobPosting/senior-fullstack-engineer.mdx +0 -57
  554. package/templates/content/en/LandingPage/aeo-audit.mdx +0 -19
  555. package/templates/content/en/LandingPage/aeo-audit.schema.json +0 -92
  556. package/templates/content/en/LandingPage/agency-waitlist.mdx +0 -340
  557. package/templates/content/en/LandingPage/agency-waitlist.schema.json +0 -152
  558. package/templates/content/en/LandingPage/developers.mdx +0 -19
  559. package/templates/content/en/LandingPage/developers.schema.json +0 -109
  560. package/templates/content/en/LandingPage/for-agencies.mdx +0 -390
  561. package/templates/content/en/LandingPage/for-agencies.schema.json +0 -107
  562. package/templates/content/en/LandingPage/for-ai-search-agencies.mdx +0 -417
  563. package/templates/content/en/LandingPage/for-ai-search-agencies.schema.json +0 -105
  564. package/templates/content/en/LandingPage/for-businesses.mdx +0 -19
  565. package/templates/content/en/LandingPage/for-businesses.schema.json +0 -96
  566. package/templates/content/en/LandingPage/platform.mdx +0 -369
  567. package/templates/content/en/LandingPage/platform.schema.json +0 -166
  568. package/templates/content/en/LandingPage/vs-ai-website-builders.mdx +0 -19
  569. package/templates/content/en/LandingPage/vs-ai-website-builders.schema.json +0 -102
  570. package/templates/content/en/LandingPage/vs-wordpress.mdx +0 -19
  571. package/templates/content/en/LandingPage/vs-wordpress.schema.json +0 -53
  572. package/templates/content/en/NewsletterSignup/newsletter.mdx +0 -236
  573. package/templates/content/en/NewsletterSignup/newsletter.schema.json +0 -91
  574. package/templates/content/en/Organization/site-owner.mdx +0 -16
  575. package/templates/content/en/Partner/prisma.mdx +0 -31
  576. package/templates/content/en/Partner/supabase.mdx +0 -30
  577. package/templates/content/en/Partner/vercel.mdx +0 -28
  578. package/templates/content/en/PartnersList/partners.mdx +0 -22
  579. package/templates/content/en/Person/founder.mdx +0 -18
  580. package/templates/content/en/Pricing/pricing.mdx +0 -538
  581. package/templates/content/en/Pricing/pricing.schema.json +0 -209
  582. package/templates/content/en/PrivacyPage/privacy.mdx +0 -165
  583. package/templates/content/en/PrivacyPage/privacy.schema.json +0 -64
  584. package/templates/content/en/Product/ailk.mdx +0 -19
  585. package/templates/content/en/Product/ailk.schema.json +0 -94
  586. package/templates/content/en/Product/api-launch-kit.mdx +0 -26
  587. package/templates/content/en/Product/launch-kit.mdx +0 -28
  588. package/templates/content/en/ProductsList/products.mdx +0 -26
  589. package/templates/content/en/Project/ailk-phase-2.mdx +0 -54
  590. package/templates/content/en/ProjectsList/projects.mdx +0 -25
  591. package/templates/content/en/ResourceDetail/aeo-scoring-guide.mdx +0 -27
  592. package/templates/content/en/ResourceDetail/content-model-whitepaper.mdx +0 -28
  593. package/templates/content/en/ResourceDetail/schema-org-quick-reference.mdx +0 -39
  594. package/templates/content/en/ResourcesHub/resources.mdx +0 -22
  595. package/templates/content/en/Service/consulting.mdx +0 -22
  596. package/templates/content/en/Service/implementation.mdx +0 -30
  597. package/templates/content/en/Service/launch-service.mdx +0 -232
  598. package/templates/content/en/Service/launch.mdx +0 -228
  599. package/templates/content/en/ServicesList/services.mdx +0 -84
  600. package/templates/content/en/SoftwareProduct/ailk-aeo.mdx +0 -44
  601. package/templates/content/en/SoftwareProduct/ailk-content-adapters.mdx +0 -47
  602. package/templates/content/en/SoftwareProduct/ailk-schema.mdx +0 -49
  603. package/templates/content/en/TeamList/team.mdx +0 -63
  604. package/templates/content/en/TeamMember/founder.mdx +0 -72
  605. package/templates/content/en/TermsPage/terms.mdx +0 -19
  606. package/templates/content/en/TermsPage/terms.schema.json +0 -99
  607. package/templates/content/en/TestimonialsList/testimonials.mdx +0 -44
  608. package/templates/content/en/UseCasesList/use-cases.mdx +0 -30
  609. package/templates/content/en/Whitepaper/ax-first-product-development.mdx +0 -27
  610. package/templates/content/en/Whitepaper/open-core-commercial-strategy.mdx +0 -27
  611. package/templates/content/en/Whitepaper/structured-data-for-answer-engines.mdx +0 -31
  612. package/templates/content/en-XA/AboutPage/about.mdx +0 -8
  613. package/templates/content/en-XA/FAQPage/faq.mdx +0 -8
  614. package/templates/content/en-XA/HomePage/home.mdx +0 -8
  615. package/templates/content/es/_site.mdx +0 -30
  616. package/templates/content/fr/_site.mdx +0 -30
  617. package/templates/content/ja/_site.mdx +0 -30
  618. package/templates/content/pt-BR/AboutPage/about.mdx +0 -8
  619. package/templates/content/pt-BR/FAQPage/faq.mdx +0 -8
  620. package/templates/content/pt-BR/HomePage/home.mdx +0 -23
@@ -0,0 +1,532 @@
1
+ /**
2
+ * Route-surface registry — which public routes a scaffolded site carries.
3
+ *
4
+ * A SURFACE is one public route surface of the presentation tier (see
5
+ * architecture.yaml `composition_model`): a hub route plus the detail route and
6
+ * content directories that feed it. The registry is the single source of the
7
+ * surface vocabulary, in the same spirit as `module-architecture.ts` is the
8
+ * single source of the module→architecture-slice mapping — a code registry, not
9
+ * N hand-maintained template trees.
10
+ *
11
+ * Two tiers:
12
+ *
13
+ * - CORE_SURFACE_PATHS — the routes every AILK site has regardless of what
14
+ * the business is (`/`, `/about`, `/contact`, `/faq`, `/thanks/{slug}`).
15
+ * Always scaffolded, never gateable.
16
+ * - GATEABLE_SURFACES — everything else. A surface is scaffolded ONLY when
17
+ * the declared architecture carries it; otherwise its route directories are
18
+ * skipped by `copyTemplate` and the routes are ABSENT from the scaffold,
19
+ * not present-and-placeholdering (spec #4154 D1).
20
+ *
21
+ * The default (`--modules marketing`) enables NO gateable surface: every one of
22
+ * them is a claim about the business that the scaffolder cannot make. The path
23
+ * from there is the `suggest-site-pages` → `scaffold-page` skill pair that
24
+ * already ships in `templates/.claude/skills/`.
25
+ *
26
+ * Zero runtime dependencies — create-ailk is a published, standalone CLI.
27
+ *
28
+ * Deliberately imports nothing from `parse-args.ts`: that module imports THIS
29
+ * one (for the `--surfaces` vocabulary in its help text), so a back-import
30
+ * would close a cycle. The module vocabulary is re-stated here as the keys of
31
+ * `MODULE_SURFACES`, and `__tests__/surface-gating.test.ts` asserts those keys
32
+ * equal `RECOGNIZED_MODULES` so the two cannot drift.
33
+ */
34
+ /** Template-relative prefix every `apps/web` route directory sits under. */
35
+ const ROUTE_ROOT = "apps/web/app/[locale]";
36
+ /**
37
+ * Route paths (site-relative, for the record written into `architecture.yaml`)
38
+ * that every scaffold carries.
39
+ *
40
+ * `/thanks/{slug}` is a DETAIL route only — `app/[locale]/thanks/` holds just
41
+ * `[slug]/page.tsx`, there is no `/thanks` hub — and it is the completion target
42
+ * `/contact`'s forms hand off to, so it travels with core rather than standing
43
+ * alone as a gateable surface. It ships no starter content: a confirmation page
44
+ * is authored per form, when the form exists.
45
+ */
46
+ export const CORE_SURFACE_PATHS = [
47
+ "/",
48
+ "/about",
49
+ "/contact",
50
+ "/faq",
51
+ "/thanks/{slug}",
52
+ ];
53
+ /** Template-relative route directories that are always copied. */
54
+ export const CORE_ROUTE_DIRS = [
55
+ `${ROUTE_ROOT}/about`,
56
+ `${ROUTE_ROOT}/contact`,
57
+ `${ROUTE_ROOT}/faq`,
58
+ `${ROUTE_ROOT}/thanks`,
59
+ // #5014 — ships unconditionally in every scaffold today (SNAPSHOT_DIRS
60
+ // copies all of apps/web verbatim, no `--surfaces` gating on this route),
61
+ // so joining CORE_ROUTE_DIRS only makes the REGISTRY match what already
62
+ // ships — it does not change what a fresh scaffold carries.
63
+ `${ROUTE_ROOT}/sign-in`,
64
+ ];
65
+ /**
66
+ * Directory names skipped by `listTemplateRouteDirs`'s walker even though they
67
+ * hold direct files — co-located helper trees, never routes of their own.
68
+ * `__tests__` is the original member; `components` is `#5014`'s addition
69
+ * (`(authed)/waitlist/components/`) — a route dir's own subtree copy already
70
+ * brings either kind along, so registering them as independent syncable units
71
+ * would be both redundant and, for `components`, unresolvable (no page/route
72
+ * file, so no `ROUTE_SINCE` entry would ever be correct for it).
73
+ */
74
+ export const NON_ROUTE_DIRS = new Set([
75
+ "__tests__",
76
+ "components",
77
+ ]);
78
+ /**
79
+ * The gateable surface vocabulary, sorted by id (the sort IS the emitted
80
+ * `available:` order — keep it alphabetical so the derivation stays
81
+ * byte-deterministic).
82
+ */
83
+ export const GATEABLE_SURFACES = [
84
+ {
85
+ id: "blog",
86
+ routes: [`${ROUTE_ROOT}/blog`],
87
+ content: ["apps/web/content/<locale>/blog"],
88
+ navLabelKey: "blog",
89
+ },
90
+ {
91
+ id: "careers",
92
+ routes: [`${ROUTE_ROOT}/careers`],
93
+ content: ["content/<locale>/CareersList", "content/<locale>/JobPosting"],
94
+ },
95
+ {
96
+ id: "case-studies",
97
+ routes: [`${ROUTE_ROOT}/case-studies`],
98
+ content: [
99
+ "content/<locale>/CaseStudiesList",
100
+ "content/<locale>/CaseStudy",
101
+ ],
102
+ },
103
+ {
104
+ id: "clients",
105
+ routes: [`${ROUTE_ROOT}/clients`],
106
+ content: ["content/<locale>/ClientsList"],
107
+ },
108
+ {
109
+ id: "courses",
110
+ routes: [`${ROUTE_ROOT}/courses`],
111
+ content: ["content/<locale>/CoursesList", "content/<locale>/Course"],
112
+ },
113
+ {
114
+ // Dev-only Server-Action ↔ MCP parity harness (`/dev/purchase`). Explicitly
115
+ // not customer-visible navigation; it has no place in a scaffold by default.
116
+ id: "dev",
117
+ routes: [`${ROUTE_ROOT}/dev`],
118
+ content: [],
119
+ },
120
+ {
121
+ id: "docs",
122
+ routes: [`${ROUTE_ROOT}/docs`],
123
+ content: ["apps/web/content/<locale>/docs"],
124
+ navLabelKey: "docs",
125
+ },
126
+ {
127
+ id: "downloads",
128
+ routes: [`${ROUTE_ROOT}/downloads`],
129
+ content: ["content/<locale>/DownloadsList"],
130
+ },
131
+ {
132
+ id: "events",
133
+ routes: [`${ROUTE_ROOT}/events`],
134
+ content: ["content/<locale>/EventsList", "content/<locale>/Event"],
135
+ },
136
+ {
137
+ // API-backed (the flow engine); no MDX of its own.
138
+ id: "flows",
139
+ routes: [`${ROUTE_ROOT}/flows`],
140
+ content: [],
141
+ },
142
+ {
143
+ id: "how-to",
144
+ routes: [`${ROUTE_ROOT}/how-to`],
145
+ content: ["content/<locale>/HowTo"],
146
+ },
147
+ {
148
+ id: "integrations",
149
+ routes: [`${ROUTE_ROOT}/integrations`],
150
+ content: [
151
+ "content/<locale>/IntegrationsList",
152
+ "content/<locale>/Integration",
153
+ ],
154
+ },
155
+ {
156
+ // A single HomePage-typed landing (`HomePage/launch-service.mdx` upstream);
157
+ // no content directory of its own.
158
+ id: "launch-service",
159
+ routes: [`${ROUTE_ROOT}/launch-service`],
160
+ content: [],
161
+ },
162
+ {
163
+ id: "partners",
164
+ routes: [`${ROUTE_ROOT}/partners`],
165
+ content: ["content/<locale>/PartnersList", "content/<locale>/Partner"],
166
+ },
167
+ {
168
+ id: "products",
169
+ routes: [`${ROUTE_ROOT}/products`],
170
+ content: ["content/<locale>/ProductsList", "content/<locale>/Product"],
171
+ },
172
+ {
173
+ id: "projects",
174
+ routes: [`${ROUTE_ROOT}/projects`],
175
+ content: ["content/<locale>/ProjectsList", "content/<locale>/Project"],
176
+ },
177
+ {
178
+ id: "resources",
179
+ routes: [`${ROUTE_ROOT}/resources`],
180
+ content: [
181
+ "content/<locale>/ResourcesHub",
182
+ "content/<locale>/ResourceDetail",
183
+ ],
184
+ },
185
+ {
186
+ // The `scheduling` MODULE's presentation tier — the booking page and the
187
+ // confirmation page the module OWNS (`/schedule` + `/schedule/confirmed`,
188
+ // one directory, so one entry gates both). API-backed like `flows`: the
189
+ // booker reads its slots from apps/api's `/v1/schedule/*` routes and the
190
+ // event name from `SCHEDULING_CAL_LINK`, so there is no MDX of its own.
191
+ id: "schedule",
192
+ routes: [`${ROUTE_ROOT}/schedule`],
193
+ content: [],
194
+ navLabelKey: "schedule",
195
+ },
196
+ {
197
+ id: "services",
198
+ routes: [`${ROUTE_ROOT}/services`],
199
+ content: ["content/<locale>/ServicesList", "content/<locale>/Service"],
200
+ },
201
+ {
202
+ id: "software",
203
+ routes: [`${ROUTE_ROOT}/software`],
204
+ content: ["content/<locale>/SoftwareProduct"],
205
+ },
206
+ {
207
+ id: "tech-articles",
208
+ routes: [`${ROUTE_ROOT}/tech-articles`],
209
+ content: ["content/<locale>/TechArticle"],
210
+ },
211
+ {
212
+ id: "testimonials",
213
+ routes: [`${ROUTE_ROOT}/testimonials`],
214
+ content: ["content/<locale>/TestimonialsList"],
215
+ },
216
+ {
217
+ id: "use-cases",
218
+ routes: [`${ROUTE_ROOT}/use-cases`],
219
+ content: ["content/<locale>/UseCasesList"],
220
+ },
221
+ {
222
+ id: "whitepapers",
223
+ routes: [`${ROUTE_ROOT}/whitepapers`],
224
+ content: ["content/<locale>/Whitepaper"],
225
+ },
226
+ ];
227
+ /** The recognized `--surfaces` vocabulary, sorted. */
228
+ export const RECOGNIZED_SURFACES = GATEABLE_SURFACES.map((s) => s.id);
229
+ /**
230
+ * Surfaces each recognized module contributes.
231
+ *
232
+ * `marketing` (the default) contributes NONE — a default scaffold is core-only.
233
+ * `docs` mounts the Fumadocs presentation surface; `multi-tenant` brings the
234
+ * flow-stepper surface with its API-backed engine; `scheduling` brings the
235
+ * booking page and the confirmation page the module owns.
236
+ */
237
+ export const MODULE_SURFACES = {
238
+ marketing: [],
239
+ docs: ["docs"],
240
+ "multi-tenant": ["flows"],
241
+ scheduling: ["schedule"],
242
+ };
243
+ /** Thrown on an unrecognized surface id. Mirrors parse-args' ParseError shape. */
244
+ export class SurfaceError extends Error {
245
+ constructor(message) {
246
+ super(message);
247
+ this.name = "SurfaceError";
248
+ }
249
+ }
250
+ /**
251
+ * Parse a surface CSV (the `--surfaces` value) into a validated, normalized,
252
+ * sorted, deduped list.
253
+ *
254
+ * Splits on `,`, trims + lowercases each entry, drops empties, and validates
255
+ * each against RECOGNIZED_SURFACES. An absent flag (or an all-empty value)
256
+ * yields the empty list — the caller composes it with the module-derived set.
257
+ *
258
+ * @throws SurfaceError on an unrecognized surface id, naming the vocabulary.
259
+ */
260
+ export function parseSurfaces(raw) {
261
+ if (raw === undefined)
262
+ return [];
263
+ const requested = raw
264
+ .split(",")
265
+ .map((s) => s.trim().toLowerCase())
266
+ .filter(Boolean);
267
+ for (const s of requested) {
268
+ if (!RECOGNIZED_SURFACES.includes(s)) {
269
+ throw new SurfaceError(`unknown surface "${s}". Recognized: ${RECOGNIZED_SURFACES.join(", ")}`);
270
+ }
271
+ }
272
+ return [...new Set(requested)].sort();
273
+ }
274
+ /**
275
+ * Resolve the enabled gateable-surface set from the selected modules plus any
276
+ * explicitly requested surfaces.
277
+ *
278
+ * The result is a sorted, deduped set — the same (modules, explicit) input
279
+ * always yields the same output, so both the copied tree and the derived
280
+ * `architecture.yaml` stay byte-deterministic.
281
+ */
282
+ export function resolveSurfaces(modules = ["marketing"], explicit = []) {
283
+ const set = new Set();
284
+ for (const m of modules) {
285
+ const contributed = MODULE_SURFACES[m.trim().toLowerCase()];
286
+ // Defensive: parse-args rejects an unknown module first. Skip rather than
287
+ // throw a second, differently-worded error for the same bad input.
288
+ if (contributed === undefined)
289
+ continue;
290
+ for (const s of contributed)
291
+ set.add(s);
292
+ }
293
+ for (const s of explicit) {
294
+ if (!RECOGNIZED_SURFACES.includes(s)) {
295
+ throw new SurfaceError(`unknown surface "${s}". Recognized: ${RECOGNIZED_SURFACES.join(", ")}`);
296
+ }
297
+ set.add(s);
298
+ }
299
+ return [...set].sort();
300
+ }
301
+ /**
302
+ * The template-relative route directories to SKIP when copying the template —
303
+ * every gateable surface not in `enabled`.
304
+ *
305
+ * Paths are emitted with forward slashes (the template tree's own separator);
306
+ * `copy.ts` normalizes the walked path before matching so the comparison holds
307
+ * on Windows too.
308
+ */
309
+ export function excludedRoutePaths(enabled) {
310
+ const on = new Set(enabled);
311
+ const out = [];
312
+ for (const surface of GATEABLE_SURFACES) {
313
+ if (on.has(surface.id))
314
+ continue;
315
+ out.push(...surface.routes);
316
+ }
317
+ return out.sort();
318
+ }
319
+ /**
320
+ * The content directories belonging to gateable surfaces that are NOT enabled,
321
+ * with `<locale>` left in place for the caller to expand.
322
+ *
323
+ * Consumed by the sync-mode drift report so an already-scaffolded site is told
324
+ * about orphan content as well as orphan routes — orphan content is not inert:
325
+ * `/sitemap.xml` and `/llms.txt` enumerate the content adapter, so content whose
326
+ * route has been removed would advertise URLs that 404.
327
+ */
328
+ export function excludedContentPaths(enabled) {
329
+ const on = new Set(enabled);
330
+ const out = [];
331
+ for (const surface of GATEABLE_SURFACES) {
332
+ if (on.has(surface.id))
333
+ continue;
334
+ out.push(...surface.content);
335
+ }
336
+ return out.sort();
337
+ }
338
+ /**
339
+ * Route manifest (#4986): every template route directory, keyed relative to
340
+ * ROUTE_ROOT (`apps/web/app/[locale]`), → the `@working-theory/*` fixed-group
341
+ * release line (`.changeset/config.json` `fixed`) that first carried it — the
342
+ * version a consumer pins, so `sync-routes` can say "added in 0.14.0".
343
+ * create-ailk's own version is changesets-ignored and is NOT the axis.
344
+ *
345
+ * A route directory is a directory under ROUTE_ROOT that directly holds at
346
+ * least one file, excluding `__tests__` trees, whose top segment the registry
347
+ * recognizes (CORE_ROUTE_DIRS or a gateable surface's `routes`). Adding a
348
+ * route directory to the template REQUIRES an entry here —
349
+ * `__tests__/sync-routes.test.ts` fails otherwise.
350
+ *
351
+ * `0.0.0` = predates the manifest; the first release that carried it is not
352
+ * recoverable (history was squashed, no tags). Only the recommender routes
353
+ * (#4891, 0.14.0) are attributable.
354
+ */
355
+ export const ROUTE_SINCE = {
356
+ about: "0.0.0",
357
+ "blog/[[...slug]]": "0.0.0",
358
+ careers: "0.0.0",
359
+ "careers/[slug]": "0.0.0",
360
+ "case-studies": "0.0.0",
361
+ "case-studies/[slug]": "0.0.0",
362
+ clients: "0.0.0",
363
+ contact: "0.0.0",
364
+ courses: "0.0.0",
365
+ "courses/[slug]": "0.0.0",
366
+ "dev/purchase": "0.0.0",
367
+ "docs/[[...slug]]": "0.0.0",
368
+ downloads: "0.0.0",
369
+ events: "0.0.0",
370
+ "events/[slug]": "0.0.0",
371
+ faq: "0.0.0",
372
+ "flows/[slug]": "0.0.0",
373
+ "flows/[slug]/results/[payload]": "0.14.0",
374
+ "flows/[slug]/start": "0.18.0",
375
+ "how-to": "0.0.0",
376
+ "how-to/[slug]": "0.0.0",
377
+ integrations: "0.0.0",
378
+ "integrations/[slug]": "0.0.0",
379
+ "launch-service": "0.0.0",
380
+ partners: "0.0.0",
381
+ "partners/[slug]": "0.0.0",
382
+ products: "0.0.0",
383
+ "products/[slug]": "0.0.0",
384
+ projects: "0.0.0",
385
+ "projects/[slug]": "0.0.0",
386
+ // #5048 — the founder-application reference mount. It carries the client
387
+ // wrapper only and no `page.tsx`: a route needs a question set, and a
388
+ // question set is the SITE's content. A scaffolded site adds its own route
389
+ // beside this file and passes its own config.
390
+ "projects/apply": "0.18.0",
391
+ resources: "0.0.0",
392
+ "resources/[slug]": "0.0.0",
393
+ schedule: "0.0.0",
394
+ "schedule/confirmed": "0.0.0",
395
+ services: "0.0.0",
396
+ "services/[slug]": "0.0.0",
397
+ software: "0.0.0",
398
+ "software/[slug]": "0.0.0",
399
+ "tech-articles": "0.0.0",
400
+ "tech-articles/[slug]": "0.0.0",
401
+ testimonials: "0.0.0",
402
+ "thanks/[slug]": "0.14.0",
403
+ "use-cases": "0.0.0",
404
+ whitepapers: "0.0.0",
405
+ "whitepapers/[slug]": "0.0.0",
406
+ // #5014 — the (authed) route GROUP: layout.tsx + sign-in-gate.tsx sit
407
+ // directly under "(authed)" (a Next.js route group — its parens are not a
408
+ // URL segment); account/ and waitlist/ are its two syncable sub-trees.
409
+ // None of these are attributable to a historical release the way the
410
+ // "0.0.0 = predates the manifest" entries above are, but they are also not
411
+ // genuinely new at HEAD — this run resolves them to the CURRENT fixed-group
412
+ // version (0.18.0) per the correction recorded on Epic #5076 (the issue's
413
+ // own text cites a stale 0.15.0), the same "attach at today's version"
414
+ // choice #5048's "projects/apply" entry already made for the same reason.
415
+ "(authed)": "0.18.0",
416
+ "(authed)/account": "0.18.0",
417
+ "(authed)/waitlist": "0.18.0",
418
+ "(authed)/waitlist/[experimentId]": "0.18.0",
419
+ "(authed)/waitlist/[experimentId]/signups/[leadId]": "0.18.0",
420
+ "sign-in": "0.18.0",
421
+ };
422
+ /**
423
+ * Surface id of the registry that owns `routeDir` (ROUTE_ROOT-relative): the
424
+ * string `"core"` for CORE_ROUTE_DIRS, `"authed"` for the `(authed)` route
425
+ * GROUP (#5014 — syncable like core, but reported under its own identity
426
+ * rather than conflated with CORE_ROUTE_DIRS's always-copied set, since it is
427
+ * a route GROUP rather than a route directory of its own), a gateable
428
+ * surface's id, or undefined when the top segment is outside the registry
429
+ * entirely.
430
+ */
431
+ export function surfaceForRouteDir(routeDir) {
432
+ const topSegment = routeDir.split("/")[0];
433
+ if (topSegment === "(authed)")
434
+ return "authed";
435
+ const top = `${ROUTE_ROOT}/${topSegment}`;
436
+ if (CORE_ROUTE_DIRS.includes(top))
437
+ return "core";
438
+ return GATEABLE_SURFACES.find((s) => s.routes.includes(top))?.id;
439
+ }
440
+ /**
441
+ * Non-route consumer-side files a route's own source imports, that a sync
442
+ * must ALSO bring along so `--apply` never leaves a route that cannot
443
+ * compile (#5014's third clause). Template-relative, `/`-separated, keyed by
444
+ * the same route string `ROUTE_SINCE` uses. `sync-routes` copies a listed
445
+ * file only when the target does not already have it — it never overwrites,
446
+ * the same rule routes themselves follow.
447
+ *
448
+ * `(authed)/account` depending on two files INSIDE `(authed)/waitlist`
449
+ * (`ForbiddenState.tsx`, `format.ts`) is real, found by reading the account
450
+ * page's own imports, not guessed from the issue text: the account page
451
+ * renders a shared "forbidden" empty state and shared count/date formatters
452
+ * that the waitlist dashboard also uses, rather than duplicating them.
453
+ */
454
+ export const ROUTE_DEPENDENCIES = {
455
+ "sign-in": ["apps/web/lib/auth-env.ts", "apps/web/lib/site-brand.tsx"],
456
+ "(authed)": ["apps/web/auth.ts", "apps/web/lib/auth-env.ts"],
457
+ "(authed)/account": [
458
+ "apps/web/lib/account-config.ts",
459
+ "apps/web/lib/server-api.ts",
460
+ `${ROUTE_ROOT}/(authed)/waitlist/components/ForbiddenState.tsx`,
461
+ `${ROUTE_ROOT}/(authed)/waitlist/format.ts`,
462
+ ],
463
+ "(authed)/waitlist": ["apps/web/lib/server-api.ts"],
464
+ };
465
+ /**
466
+ * i18n message namespaces (dot-path into `apps/web/messages/<locale>.json`) a
467
+ * route needs (#5014's third clause). CHECK-ONLY: a consumer's `messages/`
468
+ * file already exists in every scaffold (it is not itself route-gated) and
469
+ * may carry the site owner's own edits, so `sync-routes` reports a missing
470
+ * namespace rather than attempting to merge JSON keys into it — a blind merge
471
+ * risks corrupting hand-authored translations. Adding the namespace is left
472
+ * to the site owner, same as any other reported gap.
473
+ */
474
+ export const ROUTE_MESSAGE_NAMESPACES = {
475
+ "sign-in": ["signIn"],
476
+ "(authed)/account": ["account"],
477
+ "(authed)/waitlist": ["waitlistDashboard.gate"],
478
+ };
479
+ /** Template-relative path of the generated site-nav registry. */
480
+ export const NAV_CONFIG_PATH = "apps/web/lib/nav-config.ts";
481
+ /**
482
+ * Render `apps/web/lib/nav-config.ts` for an enabled surface set.
483
+ *
484
+ * The site nav is NOT content-derived — it is a static list the layout renders
485
+ * into the header and the footer. Left as the template ships it, a gated
486
+ * scaffold would link `/docs` and `/blog` on every page while neither route
487
+ * exists: two dead links, sitewide, by default. So the nav follows the declared
488
+ * surface set for the same reason the route tree does.
489
+ *
490
+ * Only surfaces carrying a `navLabelKey` are linked, because a nav entry needs
491
+ * a translated label and the template's `nav` namespace ships keys for exactly
492
+ * `home`, `docs`, and `blog`. Emitting an entry whose `labelKey` has no
493
+ * translation would trade a dead link for a missing-message error.
494
+ *
495
+ * Deterministic: entries follow GATEABLE_SURFACES order (alphabetical by id),
496
+ * after the always-present home entry.
497
+ */
498
+ export function renderNavConfig(enabled) {
499
+ const on = new Set(enabled);
500
+ const linked = GATEABLE_SURFACES.filter((s) => s.navLabelKey !== undefined && on.has(s.id));
501
+ const entries = [
502
+ ' { labelKey: "home", path: "/" },',
503
+ ...linked.map((s) => ` { labelKey: "${s.navLabelKey}", path: "/${s.id}" },`),
504
+ ];
505
+ // The emitted file imports the consumer's `NavItem` type from the UI package.
506
+ // Assembled from fragments so THIS source file never contains the literal
507
+ // import string: `tools/lint-architecture.ts` matches on source text, so a
508
+ // literal would read as create-ailk importing @working-theory/ui and fail the
509
+ // boundary lint. Same technique module-architecture.ts uses for its own
510
+ // forbidden-pattern data (NO_UPSTREAM_IMPORT_PATTERN).
511
+ const navItemImport = [
512
+ "import type { NavItem } ",
513
+ "from ",
514
+ '"@working-theory/ui";',
515
+ ].join("");
516
+ return `// nav-config.ts — site-nav registry.
517
+ //
518
+ // GENERATED by create-ailk from the declared route surfaces. Every entry here
519
+ // points at a route this site actually carries — the nav is regenerated with
520
+ // the surface set so it can never link a page that was not scaffolded.
521
+ //
522
+ // Adding a link: scaffold the page (the \`scaffold-page\` skill), then add an
523
+ // entry below with a \`labelKey\` that exists in the \`nav\` namespace of
524
+ // \`apps/web/messages/<locale>.json\`. Paths are locale-agnostic — Nav prefixes
525
+ // them with the active locale at render.
526
+ ${navItemImport}
527
+
528
+ export const navItems: NavItem[] = [
529
+ ${entries.join("\n")}
530
+ ];
531
+ `;
532
+ }
@@ -0,0 +1,92 @@
1
+ import type { WorkspaceVersionMap } from "./substitute.js";
2
+ export interface SyncRoutesOptions {
3
+ /**
4
+ * The already-scaffolded repo (absolute or relative). Must exist, be a
5
+ * directory, and contain `architecture.yaml` — the same validation as
6
+ * `syncArchitectureSync`.
7
+ */
8
+ targetDir: string;
9
+ /** The template tree to sync FROM (the package's `templates/` dir). */
10
+ templatesDir: string;
11
+ /**
12
+ * Workspace version map for `copyTemplate`. Route dirs carry no package.json,
13
+ * so it never applies; passed for fidelity with the scaffold path.
14
+ */
15
+ versions: WorkspaceVersionMap;
16
+ /** Copy the missing routes into the target. Default false = check only. */
17
+ apply?: boolean;
18
+ }
19
+ /** One route directory the report names. */
20
+ export interface RouteReport {
21
+ /** ROUTE_ROOT-relative, `/`-separated. */
22
+ route: string;
23
+ /** `"core"`, `"authed"` (the `(authed)` route group, #5014), or a gateable surface's id. */
24
+ surface: string;
25
+ /** The `ROUTE_SINCE` release line that first carried the route. */
26
+ since: string;
27
+ /** `ROUTE_DEPENDENCIES[route]`, when declared — see that export for the contract. */
28
+ dependencies: readonly string[];
29
+ /** `ROUTE_MESSAGE_NAMESPACES[route]`, when declared. */
30
+ messageNamespaces: readonly string[];
31
+ }
32
+ export interface SyncRoutesResult {
33
+ /** Resolved absolute path to the synced directory. */
34
+ targetDir: string;
35
+ /** In-scope template route dirs examined. */
36
+ checked: number;
37
+ /** Template route dirs absent from the target, sorted by route. */
38
+ missing: RouteReport[];
39
+ /** Route dirs present but with a direct file absent or changed, sorted. */
40
+ modified: RouteReport[];
41
+ /** Route dirs copied this run (the missing list when applying, else empty). */
42
+ applied: string[];
43
+ /**
44
+ * `ROUTE_DEPENDENCIES` files, of any route in `missing`, absent from the
45
+ * target — copied when `apply` is set (never overwriting), else reported
46
+ * only. Sorted, deduplicated.
47
+ */
48
+ missingDependencies: string[];
49
+ /** Dependency files copied this run. Sorted. */
50
+ appliedDependencies: string[];
51
+ /**
52
+ * `ROUTE_MESSAGE_NAMESPACES` dot-paths, of any route in `missing`, absent
53
+ * from the target's `messages/en.json`. CHECK-ONLY — never copied (see
54
+ * `ROUTE_MESSAGE_NAMESPACES`'s own doc for why). Sorted, deduplicated.
55
+ */
56
+ missingMessageNamespaces: string[];
57
+ /** Gateable surface ids the target does not carry, sorted. */
58
+ skippedSurfaces: string[];
59
+ }
60
+ /**
61
+ * The template's route directories, ROUTE_ROOT-relative and sorted.
62
+ *
63
+ * A route directory is a directory under ROUTE_ROOT (not the root itself)
64
+ * that directly holds at least one regular file, is not inside a
65
+ * `NON_ROUTE_DIRS` tree (`__tests__`, `components`), and whose top segment
66
+ * the registry recognizes (`surfaceForRouteDir`).
67
+ */
68
+ export declare function listTemplateRouteDirs(templatesDir: string): string[];
69
+ /**
70
+ * Compare an already-scaffolded repo's route tree with the template's and,
71
+ * when `apply` is set, copy in the route dirs it is missing.
72
+ *
73
+ * Throws Error on a missing target, a non-directory target, a directory with
74
+ * no `architecture.yaml`, or a template route dir without a `ROUTE_SINCE`
75
+ * entry; the CLI's top-level catch turns that into a `[create-ailk] <message>`
76
+ * stderr write + exit 1.
77
+ */
78
+ export declare function syncRoutes(opts: SyncRoutesOptions): SyncRoutesResult;
79
+ /** Render the report the CLI prints after a run. Ends with a newline. */
80
+ export declare function formatSyncRoutesReport(result: SyncRoutesResult, apply: boolean): string;
81
+ export interface SyncRoutesArgs {
82
+ /** Positional target directory; undefined = the caller's cwd. */
83
+ target: string | undefined;
84
+ apply: boolean;
85
+ help: boolean;
86
+ }
87
+ export declare const SYNC_ROUTES_HELP = "create-ailk sync-routes \u2014 copy template routes an existing site is missing.\n\nUsage:\n create-ailk sync-routes [<target-dir>] [--apply]\n\nArguments:\n <target-dir> An already-scaffolded repo (contains\n architecture.yaml). Defaults to the current dir.\n\nOptions:\n --apply Copy the missing route directories into the target.\n Without it the command only reports: exit 1 when a\n route is missing, 0 when in sync.\n --help, -h Print this message.\n\nChecks every core route plus the routes of each surface the site carries; a\nsurface gated off at scaffold time is skipped, not drift. A route the site has\nchanged locally is reported and never overwritten. Nothing is ever deleted.\n";
88
+ /**
89
+ * Parse the argv AFTER the `sync-routes` word. Strict `node:util` parseArgs,
90
+ * like `parseCliArgs`; at most one positional.
91
+ */
92
+ export declare function parseSyncRoutesArgs(argv: string[]): SyncRoutesArgs;