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,114 @@
1
+ #!/usr/bin/env node
2
+ /* istanbul ignore file -- CLI bootstrap; mirrors abandon-sweep.ts's coverage-ignore
3
+ rationale — real entry-point semantics run the compiled dist directly, and
4
+ the DB write it performs (prisma.deliverableAsset.upsert) is exercised
5
+ through the same mocked-prisma double the service-layer tests already use
6
+ (apps/api/src/lib/__mocks__/prisma.ts § deliverableAsset). This file is a
7
+ thin entry: parse args, read the file, refuse the size cap, upsert. */
8
+ /**
9
+ * Deliverable-asset upload CLI (#3961 D6).
10
+ *
11
+ * Dev: `pnpm --filter @working-theory/api deliverable:upload -- --site <siteId>
12
+ * --key <key> --file <path> [--content-type <ct>] [--filename <name>]`.
13
+ * Production: `node dist/bin/deliverable-upload.js <same flags>`.
14
+ *
15
+ * No HTTP upload route exists (spec §2.2) — this CLI is the sole write path
16
+ * for `DeliverableAsset` rows, run by the operator on their own machine/CI,
17
+ * never by a customer or agent request. Re-upload (same siteId + key)
18
+ * REPLACES the stored bytes (upsert) — the config's `assetKey` reference
19
+ * never changes, so a content update is a re-run of this command.
20
+ *
21
+ * The 20 MB cap is a CLI guard, not a schema constraint (Postgres `bytea`
22
+ * has no practical limit at launch volumes) — it keeps the DB-storage
23
+ * choice (D1) honest until the blob-storage upgrade path is taken.
24
+ */
25
+ import { readFileSync, statSync } from "node:fs";
26
+ import { basename } from "node:path";
27
+
28
+ import { prisma } from "../lib/prisma.js";
29
+
30
+ const MAX_BYTES = 20 * 1024 * 1024; // 20 MB (D6)
31
+ const DEFAULT_CONTENT_TYPE = "application/octet-stream";
32
+
33
+ type ParsedArgs = {
34
+ siteId?: string | undefined;
35
+ key?: string | undefined;
36
+ file?: string | undefined;
37
+ contentType?: string | undefined;
38
+ filename?: string | undefined;
39
+ };
40
+
41
+ /** Minimal `--flag value` parser — no external dependency for a 5-flag CLI. */
42
+ function parseArgs(argv: string[]): ParsedArgs {
43
+ const out: ParsedArgs = {};
44
+ for (let i = 0; i < argv.length; i += 1) {
45
+ const flag = argv[i];
46
+ const value = argv[i + 1];
47
+ if (flag === "--site") out.siteId = value;
48
+ else if (flag === "--key") out.key = value;
49
+ else if (flag === "--file") out.file = value;
50
+ else if (flag === "--content-type") out.contentType = value;
51
+ else if (flag === "--filename") out.filename = value;
52
+ else continue;
53
+ i += 1;
54
+ }
55
+ return out;
56
+ }
57
+
58
+ async function main(): Promise<void> {
59
+ const args = parseArgs(process.argv.slice(2));
60
+
61
+ if (!args.siteId || !args.key || !args.file) {
62
+ console.error(
63
+ "[deliverable-upload] usage: --site <siteId> --key <key> --file <path> " +
64
+ "[--content-type <ct>] [--filename <name>]",
65
+ );
66
+ process.exitCode = 1;
67
+ return;
68
+ }
69
+
70
+ const stat = statSync(args.file);
71
+ if (stat.size > MAX_BYTES) {
72
+ console.error(
73
+ `[deliverable-upload] refused: ${args.file} is ${stat.size} bytes, ` +
74
+ `exceeds the ${MAX_BYTES}-byte (20 MB) cap`,
75
+ );
76
+ process.exitCode = 1;
77
+ return;
78
+ }
79
+
80
+ const bytes = readFileSync(args.file);
81
+ const filename = args.filename ?? basename(args.file);
82
+ const contentType = args.contentType ?? DEFAULT_CONTENT_TYPE;
83
+
84
+ const row = await prisma.deliverableAsset.upsert({
85
+ where: { siteId_key: { siteId: args.siteId, key: args.key } },
86
+ create: {
87
+ siteId: args.siteId,
88
+ key: args.key,
89
+ filename,
90
+ contentType,
91
+ bytes,
92
+ size: stat.size,
93
+ },
94
+ update: {
95
+ filename,
96
+ contentType,
97
+ bytes,
98
+ size: stat.size,
99
+ },
100
+ select: { key: true },
101
+ });
102
+
103
+ console.log(`[deliverable-upload] uploaded key="${row.key}"`);
104
+ }
105
+
106
+ main().catch((err: unknown) => {
107
+ // Belt-and-suspenders (mirrors abandon-sweep.ts) — main() has no
108
+ // internal catch of its own, so an unexpected throw (a bad DB
109
+ // connection, a filesystem error mid-read) still exits non-zero with a
110
+ // structured message rather than an unhandled-rejection crash.
111
+ const message = err instanceof Error ? err.message : "Unknown error";
112
+ console.error(`[deliverable-upload] unexpected_error: ${message}`);
113
+ process.exitCode = 1;
114
+ });
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ /* istanbul ignore file -- CLI bootstrap; the underlying
3
+ runWaitlistFollowUpSweep logic is unit-tested in
4
+ services/__tests__/waitlist-followup.test.ts. Mirrors abandon-sweep.ts's
5
+ coverage-ignore rationale — real entry-point semantics run the compiled
6
+ dist directly, on the operator's own cron/scheduler cadence (D1: no
7
+ queue/timer infrastructure in this repo — an external scheduler runs this
8
+ command on whatever cadence the deployment chooses). */
9
+ /**
10
+ * Waitlist follow-up sweep CLI entry (#4732 D1).
11
+ *
12
+ * Dev: `pnpm --filter @working-theory/api followup:sweep` (tsx, this file).
13
+ * Production: `node dist/bin/followup-sweep.js` (the compiled entry, run by
14
+ * any external scheduler — Vercel Cron, GitHub Actions cron, plain crontab).
15
+ * The sweep is stateless and idempotent (the `waitlist_followup_sends`
16
+ * `@@unique([leadId, followUpKey])` guarantee), so overlap or a missed tick
17
+ * is harmless — the offset window is data, not a timer.
18
+ */
19
+ import { runWaitlistFollowUpSweep } from "../services/waitlist-followup.js";
20
+
21
+ async function main(): Promise<void> {
22
+ const result = await runWaitlistFollowUpSweep();
23
+
24
+ if (!result.ok) {
25
+ console.error(
26
+ `[followup-sweep] ${result.error.kind}: ${result.error.message}`,
27
+ );
28
+ process.exitCode = 1;
29
+ return;
30
+ }
31
+
32
+ console.log(`[followup-sweep] ${JSON.stringify(result.summary)}`);
33
+ }
34
+
35
+ main().catch((err: unknown) => {
36
+ // Belt-and-suspenders (mirrors abandon-sweep.ts): runWaitlistFollowUpSweep
37
+ // already catches internally and returns a structured `unexpected_error`
38
+ // result, so this path is unreachable in practice — it exists only to
39
+ // prevent a bare unhandled-rejection crash if `main` itself ever throws
40
+ // before/around that call.
41
+ const message = err instanceof Error ? err.message : "Unknown error";
42
+ console.error(`[followup-sweep] unexpected_error: ${message}`);
43
+ process.exitCode = 1;
44
+ });
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ /* istanbul ignore file -- CLI bootstrap; the underlying runListingCsvSweep
3
+ logic is unit-tested in services/__tests__/listing-csv-sweep.test.ts.
4
+ Mirrors followup-sweep.ts's coverage-ignore rationale — real entry-point
5
+ semantics run the compiled dist directly, on the operator's own
6
+ cron/scheduler cadence (D1: no queue/timer infrastructure in this repo —
7
+ an external scheduler runs this command on whatever cadence the deployment
8
+ chooses). */
9
+ /**
10
+ * Weekly founder-CSV sweep CLI entry (#5001).
11
+ *
12
+ * Dev: `pnpm --filter @working-theory/api listing-csv:sweep` (tsx, this file).
13
+ * Production: `node dist/bin/listing-csv-sweep.js` (the compiled entry, run by
14
+ * any external scheduler — Vercel Cron, GitHub Actions cron, plain crontab).
15
+ * The consumer schedules this WEEKLY; this repo adds no cron of its own.
16
+ *
17
+ * The sweep is stateless and idempotent: a listing with no `WaitlistScore`
18
+ * newer than its last `ListingCsvSend` sends nothing, so an extra tick is a
19
+ * no-op and a missed tick simply widens the next CSV's window.
20
+ */
21
+ import { runListingCsvSweep } from "../services/listing-csv-sweep.js";
22
+
23
+ async function main(): Promise<void> {
24
+ const result = await runListingCsvSweep();
25
+
26
+ if (!result.ok) {
27
+ console.error(
28
+ `[listing-csv-sweep] ${result.error.kind}: ${result.error.message}`,
29
+ );
30
+ process.exitCode = 1;
31
+ return;
32
+ }
33
+
34
+ console.log(`[listing-csv-sweep] ${JSON.stringify(result.summary)}`);
35
+ }
36
+
37
+ main().catch((err: unknown) => {
38
+ // Belt-and-suspenders (mirrors followup-sweep.ts): runListingCsvSweep
39
+ // already catches internally and returns a structured `unexpected_error`
40
+ // result, so this path is unreachable in practice — it exists only to
41
+ // prevent a bare unhandled-rejection crash if `main` itself ever throws
42
+ // before/around that call.
43
+ const message = err instanceof Error ? err.message : "Unknown error";
44
+ console.error(`[listing-csv-sweep] unexpected_error: ${message}`);
45
+ process.exitCode = 1;
46
+ });
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+ /* istanbul ignore file -- CLI bootstrap; the underlying seedFlowPresets logic
3
+ is unit-tested in services/__tests__/flow-engine.test.ts. Mirrors
4
+ bin/abandon-sweep.ts's coverage-ignore rationale — real entry-point
5
+ semantics run the compiled dist directly. */
6
+ /**
7
+ * Flow-preset seed CLI entry (#3958 §3.3).
8
+ *
9
+ * Writes the three static capture presets (form, waitlist, lead-magnet —
10
+ * `@working-theory/database/flows/presets`) through the existing validated
11
+ * `upsertFlowDefinition` path, for the current site (`currentSiteId()`,
12
+ * `lib/site.ts`) — the same site id the `/v1/flows/*` routes resolve against,
13
+ * so a preset is never written somewhere the routes can't find it.
14
+ *
15
+ * Dev: `pnpm --filter @working-theory/api seed:presets` (tsx, this file).
16
+ * Production: `node dist/bin/seed-presets.js` (the compiled entry, run once
17
+ * per site by the operator — idempotent: `upsertFlowDefinition` upserts on
18
+ * `[siteId, slug]`, so a re-run overwrites cleanly rather than duplicating).
19
+ *
20
+ * This entry point is the placement chosen for #3958's operator-facing
21
+ * invocation (spec §3.3 / §7 item 1 — the implementer's choice, both
22
+ * placements bounded and reversible): `apps/api/src/bin/` already hosts
23
+ * exactly this shape of one-off operator command (`abandon-sweep.ts`), so it
24
+ * is the closer fit to "the existing apps/api CLI surface" than adding
25
+ * argv-verb parsing to `cli.ts`, which today does nothing but bootstrap the
26
+ * long-running server.
27
+ */
28
+ import { FLOW_PRESETS } from "@working-theory/database/flows/presets";
29
+
30
+ import { currentSiteId } from "../lib/site.js";
31
+ import { seedFlowPresets } from "../services/flow-engine.js";
32
+
33
+ async function main(): Promise<void> {
34
+ const siteId = currentSiteId();
35
+ const result = await seedFlowPresets(siteId, FLOW_PRESETS);
36
+
37
+ if (!result.ok) {
38
+ console.error(
39
+ `[seed-presets] ${result.error.kind}: ${result.error.message} (seeded before failure: ${result.seeded.join(", ") || "none"})`,
40
+ );
41
+ process.exitCode = 1;
42
+ return;
43
+ }
44
+
45
+ console.log(
46
+ `[seed-presets] seeded for site "${siteId}": ${result.seeded.join(", ")}`,
47
+ );
48
+ }
49
+
50
+ main().catch((err: unknown) => {
51
+ // Belt-and-suspenders, mirroring abandon-sweep.ts: seedFlowPresets already
52
+ // returns a structured failure rather than throwing, so this path exists
53
+ // only to prevent a bare unhandled-rejection crash if `main` itself ever
54
+ // throws before/around that call.
55
+ const message = err instanceof Error ? err.message : "Unknown error";
56
+ console.error(`[seed-presets] unexpected_error: ${message}`);
57
+ process.exitCode = 1;
58
+ });
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+ /* istanbul ignore file -- CLI bootstrap; the underlying seedWaitlistExperiments
3
+ logic is unit-tested in services/__tests__/waitlist-experiments.test.ts.
4
+ Mirrors bin/seed-presets.ts's coverage-ignore rationale. */
5
+ /**
6
+ * Waitlist-experiment seed CLI entry (#4661 D5).
7
+ *
8
+ * Reads one or more experiment-config JSON paths from argv, resolves any
9
+ * `questionSetRef` / `scoringRef` / `sourceTrackingRef` path (relative to the
10
+ * config file) into the embedded objects, and writes them through the
11
+ * existing validated `seedWaitlistExperiments` path, for the current site
12
+ * (`currentSiteId()`, `lib/site.ts`) — the same bootstrap shape as
13
+ * `seed-presets.ts`.
14
+ *
15
+ * `seedWaitlistExperiments` does MORE than write `waitlist_experiments`
16
+ * (#4726): for each config it also compiles + upserts one `flow_definitions`
17
+ * row per `waitlists[]` entry (`materializeWaitlistFlows`,
18
+ * `waitlist-experiments.ts`) — the step `GET /v1/flows/:flowSlug`
19
+ * (`serveFlow`, `flow-engine.ts`) actually reads. A single run of this bin
20
+ * is therefore sufficient to make every declared waitlist servable; a
21
+ * compile failure (`unknown_waitlist` / `unsupported_by_engine`) or a
22
+ * `flow_definitions` write failure exits this process non-zero, naming the
23
+ * failing waitlist key, and writes no `flow_definitions` row for it.
24
+ *
25
+ * Dev: `pnpm --filter @working-theory/api tsx src/bin/seed-waitlist-experiments.ts <config.json>...`
26
+ * Production: `node dist/bin/seed-waitlist-experiments.js <config.json>...` —
27
+ * idempotent (`upsertWaitlistExperiment` upserts on `[siteId, key]`;
28
+ * `upsertFlowDefinition` upserts on `[siteId, slug]`).
29
+ */
30
+ import { readFileSync } from "node:fs";
31
+ import { dirname, resolve } from "node:path";
32
+
33
+ import { currentSiteId } from "../lib/site.js";
34
+ import { seedWaitlistExperiments } from "../services/waitlist-experiments.js";
35
+
36
+ /**
37
+ * A `*Ref` field on the config is a path RELATIVE to the config file (D5),
38
+ * mapped to the embedded field name `waitlistExperimentConfigSchema`
39
+ * actually declares. An EXPLICIT map, not a `Ref$` suffix strip —
40
+ * `sourceTrackingRef` embeds as `tracking` (not `sourceTracking`), which a
41
+ * generic strip gets wrong (code-review finding, #4661).
42
+ */
43
+ const REF_FIELD_MAP: Record<string, string> = {
44
+ questionSetRef: "questionSet",
45
+ scoringRef: "scoring",
46
+ sourceTrackingRef: "tracking",
47
+ };
48
+
49
+ function readJson(path: string): unknown {
50
+ return JSON.parse(readFileSync(path, "utf8"));
51
+ }
52
+
53
+ /**
54
+ * Resolve every `*Ref` path on a raw config object relative to `configPath`
55
+ * into the embedded object it names, mirroring the site-plan projection's
56
+ * config-time `*Ref` convention (D5/D7) — the runtime never reads these
57
+ * paths; this bin resolves them once, at seed time.
58
+ */
59
+ function resolveConfigRefs(raw: unknown, configPath: string): unknown {
60
+ if (typeof raw !== "object" || raw === null) return raw;
61
+ const resolved: Record<string, unknown> = { ...(raw as Record<string, unknown>) };
62
+ const base = dirname(configPath);
63
+ for (const [field, embeddedField] of Object.entries(REF_FIELD_MAP)) {
64
+ const value = resolved[field];
65
+ if (typeof value === "string") {
66
+ resolved[embeddedField] = readJson(resolve(base, value));
67
+ delete resolved[field];
68
+ }
69
+ }
70
+ return resolved;
71
+ }
72
+
73
+ async function main(): Promise<void> {
74
+ const configPaths = process.argv.slice(2);
75
+ if (configPaths.length === 0) {
76
+ console.error("[seed-waitlist-experiments] usage: <config.json>...");
77
+ process.exitCode = 1;
78
+ return;
79
+ }
80
+
81
+ const siteId = currentSiteId();
82
+ const configs = configPaths.map((path) =>
83
+ resolveConfigRefs(readJson(path), path),
84
+ );
85
+ const result = await seedWaitlistExperiments(siteId, configs);
86
+
87
+ if (!result.ok) {
88
+ console.error(
89
+ `[seed-waitlist-experiments] ${result.error.kind}: ${result.error.message} (seeded before failure: ${result.seeded.join(", ") || "none"})`,
90
+ );
91
+ process.exitCode = 1;
92
+ return;
93
+ }
94
+
95
+ console.log(
96
+ `[seed-waitlist-experiments] seeded for site "${siteId}": ${result.seeded.join(", ")}`,
97
+ );
98
+ }
99
+
100
+ main().catch((err: unknown) => {
101
+ const message = err instanceof Error ? err.message : "Unknown error";
102
+ console.error(`[seed-waitlist-experiments] unexpected_error: ${message}`);
103
+ process.exitCode = 1;
104
+ });
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ /* istanbul ignore file -- CLI bootstrap; the underlying cleanupAbandonedSessions
3
+ logic is unit-tested in services/__tests__/flow-engine.test.ts. Mirrors
4
+ abandon-sweep.ts's coverage-ignore rationale — real entry-point semantics
5
+ run the compiled dist directly, on the operator's own cron/scheduler
6
+ cadence (no queue/timer infrastructure in this repo — an external
7
+ scheduler runs this command on whatever cadence the deployment
8
+ chooses). */
9
+ /**
10
+ * FlowSession retention/cleanup sweep CLI entry (#3974 AC3).
11
+ *
12
+ * Dev: `pnpm --filter @working-theory/api retention:sweep` (tsx, this file).
13
+ * Production: `node dist/bin/session-retention-sweep.js` (the compiled
14
+ * entry, run by any external scheduler — Vercel Cron, GitHub Actions cron,
15
+ * plain crontab). Deletes abandoned FlowSession rows past the retention
16
+ * window (default 90 days) — see `cleanupAbandonedSessions`'s own doc
17
+ * comment in ../services/flow-engine.ts for the full policy + its #3962
18
+ * abandon-email coordination.
19
+ */
20
+ import { cleanupAbandonedSessions } from "../services/flow-engine.js";
21
+
22
+ async function main(): Promise<void> {
23
+ const result = await cleanupAbandonedSessions();
24
+
25
+ if (!result.ok) {
26
+ console.error(
27
+ `[session-retention-sweep] ${result.error.kind}: ${result.error.message}`,
28
+ );
29
+ process.exitCode = 1;
30
+ return;
31
+ }
32
+
33
+ console.log(`[session-retention-sweep] deleted=${result.deleted}`);
34
+ }
35
+
36
+ main().catch((err: unknown) => {
37
+ // cleanupAbandonedSessions only returns a structured error for the
38
+ // DB-not-configured case (requireDb's guard) — a genuine prisma/DB
39
+ // exception propagates as a rejected promise, exactly like every other
40
+ // flow-engine.ts function (none of them wrap unexpected DB errors
41
+ // internally). This is that failure's landing spot, so it degrades to a
42
+ // clean process-exit rather than a bare unhandled-rejection crash.
43
+ const message = err instanceof Error ? err.message : "Unknown error";
44
+ console.error(`[session-retention-sweep] unexpected_error: ${message}`);
45
+ process.exitCode = 1;
46
+ });
@@ -15,16 +15,10 @@ import { start } from './index.js';
15
15
  // Only start if this is the main module
16
16
  // Check if executed file matches current file using import.meta.url
17
17
  if (process.argv[1]) {
18
- const isEntryPoint = process.argv[1].endsWith('dist/cli.js') ||
19
- process.argv[1].endsWith('cli.js');
20
-
21
- if (isEntryPoint) {
22
- // ESM-accurate verification using import.meta.url
23
- const currentFileUrl = import.meta.url;
24
- const executedFileUrl = pathToFileURL(process.argv[1]).href;
25
-
26
- if (currentFileUrl === executedFileUrl) {
27
- void start();
28
- }
18
+ const currentFileUrl = import.meta.url;
19
+ const executedFileUrl = pathToFileURL(process.argv[1]).href;
20
+
21
+ if (currentFileUrl === executedFileUrl) {
22
+ void start();
29
23
  }
30
24
  }
@@ -21,6 +21,24 @@ export interface Config {
21
21
  // Stripe — consumed by apps/api/src/lib/stripe.ts via @working-theory/stripe-client wrapper
22
22
  STRIPE_SECRET_KEY?: string;
23
23
  STRIPE_WEBHOOK_SECRET?: string;
24
+
25
+ // Slack — the project-listings approve/reject workflow (#4999). Consumed
26
+ // by services/slack-notify.ts (bot token + channel) and
27
+ // routes/slack/actions.ts (signing secret, for X-Slack-Signature
28
+ // verification). All three optional; absent means "Slack off" — a create
29
+ // still succeeds, it just skips the notification.
30
+ AILK_SLACK_BOT_TOKEN?: string;
31
+ AILK_SLACK_SIGNING_SECRET?: string;
32
+ AILK_SLACK_CHANNEL_ID?: string;
33
+
34
+ // GitHub issue filing — the approve-time build-issue workflow (#5000).
35
+ // Consumed by services/project-listing-issue.ts: AILK_GITHUB_REPO is the
36
+ // site's own `owner/name` (never this repo); AILK_GITHUB_TOKEN is a
37
+ // fine-grained token scoped to `issues:write` on that one repo. Both
38
+ // optional; absent means "filing off" — approve still succeeds, and the
39
+ // row's issueUrl stays null for a later retry via the PATCH route.
40
+ AILK_GITHUB_REPO?: string;
41
+ AILK_GITHUB_TOKEN?: string;
24
42
  }
25
43
 
26
44
  function validateConfig(): Config {
@@ -50,6 +68,23 @@ function validateConfig(): Config {
50
68
  ...(process.env.STRIPE_WEBHOOK_SECRET !== undefined && {
51
69
  STRIPE_WEBHOOK_SECRET: process.env.STRIPE_WEBHOOK_SECRET,
52
70
  }),
71
+
72
+ ...(process.env.AILK_SLACK_BOT_TOKEN !== undefined && {
73
+ AILK_SLACK_BOT_TOKEN: process.env.AILK_SLACK_BOT_TOKEN,
74
+ }),
75
+ ...(process.env.AILK_SLACK_SIGNING_SECRET !== undefined && {
76
+ AILK_SLACK_SIGNING_SECRET: process.env.AILK_SLACK_SIGNING_SECRET,
77
+ }),
78
+ ...(process.env.AILK_SLACK_CHANNEL_ID !== undefined && {
79
+ AILK_SLACK_CHANNEL_ID: process.env.AILK_SLACK_CHANNEL_ID,
80
+ }),
81
+
82
+ ...(process.env.AILK_GITHUB_REPO !== undefined && {
83
+ AILK_GITHUB_REPO: process.env.AILK_GITHUB_REPO,
84
+ }),
85
+ ...(process.env.AILK_GITHUB_TOKEN !== undefined && {
86
+ AILK_GITHUB_TOKEN: process.env.AILK_GITHUB_TOKEN,
87
+ }),
53
88
  };
54
89
  }
55
90
 
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Paid-module presence — the registration-grain signal used by `server.ts`
3
+ * to decide whether a paid module's routes (and their imports) are wired
4
+ * into this build (S1, #5088).
5
+ *
6
+ * `AILK_ENABLED_MODULES` is a comma-separated allowlist (e.g.
7
+ * `"multi-tenant,scheduling"`). Unset means "every module on" — today's
8
+ * behavior, unchanged for every existing deployment; an explicit empty
9
+ * string (`""`) means "no paid modules" (the OSS-strip build target). This
10
+ * mirrors `shouldMountTestAuth()`'s fail-open-by-default / explicit-opt-in
11
+ * shape elsewhere in this file's sibling config.
12
+ *
13
+ * Recognized module keys: `docs`, `multi-tenant`, `scheduling` (the
14
+ * `ModuleName` vocabulary `packages/create-ailk/src/module-architecture.ts`
15
+ * already models via `MODULE_SLICES`) plus `content-write` — the Pro
16
+ * content-write surface (`create`/`update`/`delete` under
17
+ * `apps/api/src/routes/content/`). `content-write` is intentionally NOT a
18
+ * `MODULE_SLICES` entry: it is not (yet) a `create-ailk --modules`
19
+ * selector — a customer never opts into it at scaffold time, it is a
20
+ * license-tier line drawn inside the single `apps/api` app — so it stays a
21
+ * local registration flag here rather than widening the create-ailk module
22
+ * vocabulary. This function does not validate its input against that list;
23
+ * it is a thin string-set reader so `apps/api` has no reason to import
24
+ * create-ailk's module types (outside its package allowlist anyway).
25
+ */
26
+
27
+ function enabledModules(): Set<string> | undefined {
28
+ const raw = process.env.AILK_ENABLED_MODULES;
29
+ if (raw === undefined) return undefined; // undefined sentinel = "all enabled"
30
+ return new Set(
31
+ raw
32
+ .split(',')
33
+ .map((m) => m.trim())
34
+ .filter(Boolean),
35
+ );
36
+ }
37
+
38
+ /** Whether the named paid module's routes should register on this build/boot. */
39
+ export function isModuleEnabled(moduleName: string): boolean {
40
+ const enabled = enabledModules();
41
+ if (enabled === undefined) return true;
42
+ return enabled.has(moduleName);
43
+ }
@@ -10,6 +10,17 @@ const MockPrismaClient = jest.fn().mockImplementation((options) => ({
10
10
  userData: {},
11
11
  }));
12
12
 
13
+ // #4663 D6 — flow-engine.ts imports the real `Prisma` runtime namespace (a
14
+ // VALUE, not just a type) to write the `Prisma.JsonNull` sentinel on a
15
+ // nullable Json column reset. Real distinct sentinel objects, matching the
16
+ // generated client's own runtime shape closely enough for identity checks
17
+ // (`toBe(Prisma.JsonNull)`) in tests.
18
+ const Prisma = {
19
+ JsonNull: Symbol("Prisma.JsonNull"),
20
+ DbNull: Symbol("Prisma.DbNull"),
21
+ };
22
+
13
23
  module.exports = {
14
24
  PrismaClient: MockPrismaClient,
25
+ Prisma,
15
26
  };