create-ailk 0.2.0 → 0.3.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 (273) hide show
  1. package/component-catalog.md +50 -53
  2. package/dist/lib/apply-module-patches.d.ts +47 -0
  3. package/dist/lib/apply-module-patches.js +370 -0
  4. package/dist/lib/extract-module-bundle.d.ts +12 -3
  5. package/dist/lib/extract-module-bundle.js +236 -24
  6. package/dist/lib/fetch-module.d.ts +3 -38
  7. package/dist/lib/fetch-module.js +26 -8
  8. package/dist/lib/module-license-gate.d.ts +2 -0
  9. package/dist/lib/module-license-gate.js +1 -0
  10. package/dist/lib/paid-paths.d.ts +16 -0
  11. package/dist/lib/paid-paths.js +90 -0
  12. package/dist/module-architecture.d.ts +139 -23
  13. package/dist/module-architecture.js +668 -25
  14. package/dist/parse-args.d.ts +2 -2
  15. package/dist/parse-args.js +3 -1
  16. package/dist/programmatic.d.ts +2 -1
  17. package/dist/programmatic.js +15 -4
  18. package/dist/surfaces.d.ts +12 -36
  19. package/dist/surfaces.js +35 -5
  20. package/dist/sync-routes.js +31 -1
  21. package/package.json +2 -2
  22. package/templates/.claude/agents/web.md +2 -3
  23. package/templates/.claude/rules/architecture.md +5 -5
  24. package/templates/.claude/skills/README.md +2 -1
  25. package/templates/.env.example +21 -9
  26. package/templates/CONVENTIONS.md +6 -7
  27. package/templates/apps/api/.env.example +9 -0
  28. package/templates/apps/api/CLAUDE.md +33 -5
  29. package/templates/apps/api/package.json +0 -1
  30. package/templates/apps/api/src/__tests__/cors.test.ts +195 -0
  31. package/templates/apps/api/src/__tests__/module-exclusion.test.ts +60 -2
  32. package/templates/apps/api/src/__tests__/vercel-handler.test.ts +159 -0
  33. package/templates/apps/api/src/config/__tests__/modules.test.ts +76 -0
  34. package/templates/apps/api/src/config/index.ts +19 -0
  35. package/templates/apps/api/src/config/modules.ts +12 -14
  36. package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -0
  37. package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +89 -0
  38. package/templates/apps/api/src/lib/slice-load.ts +90 -0
  39. package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +52 -32
  40. package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +182 -0
  41. package/templates/apps/api/src/openapi/__tests__/surface-drift.test.ts +293 -0
  42. package/templates/apps/api/src/openapi/index.ts +9 -3
  43. package/templates/apps/api/src/openapi/spec.ts +505 -65
  44. package/templates/apps/api/src/openapi/surface-drift.ts +195 -0
  45. package/templates/apps/api/src/routes/content/__tests__/create.test.ts +14 -0
  46. package/templates/apps/api/src/routes/content/__tests__/delete.test.ts +14 -0
  47. package/templates/apps/api/src/routes/content/__tests__/update.test.ts +14 -0
  48. package/templates/apps/api/src/routes/content/index.ts +38 -11
  49. package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +17 -0
  50. package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +17 -0
  51. package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +796 -0
  52. package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +10 -0
  53. package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +38 -0
  54. package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +814 -0
  55. package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +10 -0
  56. package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +24 -0
  57. package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +17 -0
  58. package/templates/apps/api/src/routes/project-listings/index.ts +37 -10
  59. package/templates/apps/api/src/routes/project-listings/me.ts +10 -0
  60. package/templates/apps/api/src/routes/project-listings/patch-draft.ts +5 -0
  61. package/templates/apps/api/src/routes/project-listings/public.ts +5 -0
  62. package/templates/apps/api/src/routes/project-listings/respond.ts +11 -0
  63. package/templates/apps/api/src/routes/project-listings/resume-token.ts +5 -0
  64. package/templates/apps/api/src/routes/project-listings/start.ts +30 -0
  65. package/templates/apps/api/src/routes/project-listings/submit.ts +5 -0
  66. package/templates/apps/api/src/routes/project-listings/verify-email.ts +150 -0
  67. package/templates/apps/api/src/server.ts +459 -135
  68. package/templates/apps/api/src/services/deliverable-fulfillment.ts +10 -0
  69. package/templates/apps/api/src/services/listing-config.ts +58 -0
  70. package/templates/apps/api/src/services/project-listing-resume-email.ts +326 -0
  71. package/templates/apps/api/src/services/project-listings.ts +229 -4
  72. package/templates/apps/api/src/vercel-handler.ts +60 -26
  73. package/templates/apps/mcp/.env.example +8 -0
  74. package/templates/apps/mcp/CLAUDE.md +2 -2
  75. package/templates/apps/mcp/__tests__/catalog-drift.test.ts +21 -0
  76. package/templates/apps/mcp/__tests__/config/modules.test.ts +78 -0
  77. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +1 -1
  78. package/templates/apps/mcp/src/config/modules.ts +14 -13
  79. package/templates/apps/mcp/src/server.ts +8 -4
  80. package/templates/apps/mcp/src/tools/index.ts +7 -22
  81. package/templates/apps/web/.env.example +15 -0
  82. package/templates/apps/web/app/[locale]/(authed)/{waitlist/__tests__ → __tests__}/gate.test.tsx +4 -4
  83. package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +2 -1
  84. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +2 -1
  85. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +2 -1
  86. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/flow.actions.test.ts +1 -0
  87. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/two-route-tool.test.tsx +1 -0
  88. package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +2 -1
  89. package/templates/apps/web/app/[locale]/flows/[slug]/page.tsx +1 -0
  90. package/templates/apps/web/app/[locale]/flows/[slug]/start/page.tsx +1 -0
  91. package/templates/apps/web/app/llms.txt/route.ts +12 -9
  92. package/templates/apps/web/jest.config.cjs +14 -13
  93. package/templates/apps/web/next.config.mjs +1 -3
  94. package/templates/apps/web/package.json +0 -6
  95. package/templates/apps/web/public/android-chrome-192x192.png +0 -0
  96. package/templates/apps/web/public/android-chrome-512x512.png +0 -0
  97. package/templates/apps/web/public/apple-touch-icon.png +0 -0
  98. package/templates/apps/web/public/favicon-16x16.png +0 -0
  99. package/templates/apps/web/public/favicon-32x32.png +0 -0
  100. package/templates/apps/web/public/favicon.ico +0 -0
  101. package/templates/apps/web/public/favicon.svg +6 -3
  102. package/templates/apps/web/public/lockup-horizontal.svg +4 -0
  103. package/templates/apps/web/public/logomark.svg +4 -0
  104. package/templates/apps/web/public/site.webmanifest +2 -2
  105. package/templates/apps/web/public/wordmark.svg +4 -0
  106. package/templates/database/CHANGELOG.md +33 -0
  107. package/templates/database/inbox/schema.prisma +67 -0
  108. package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +123 -0
  109. package/templates/database/package.json +1 -1
  110. package/templates/package.json +1 -1
  111. package/templates/.claude/skills/scaffold-commerce/SKILL.md +0 -807
  112. package/templates/.claude/skills/scaffold-commerce/references/lookup-keys-template.md +0 -71
  113. package/templates/.claude/skills/scaffold-commerce/references/marketplace-brand-pages.md +0 -83
  114. package/templates/.claude/skills/scaffold-commerce/templates/checkout-route.template.ts +0 -370
  115. package/templates/.claude/skills/scaffold-commerce/templates/invoice-route.template.ts +0 -376
  116. package/templates/.claude/skills/scaffold-commerce/templates/marketplace-cta-route.tsx.tmpl +0 -72
  117. package/templates/.claude/skills/scaffold-commerce/templates/payment-link-route.template.ts +0 -471
  118. package/templates/.claude/skills/scaffold-commerce/templates/portal-route.template.ts +0 -365
  119. package/templates/.claude/skills/scaffold-commerce/templates/stripe-config.template.ts +0 -60
  120. package/templates/.claude/skills/scaffold-commerce/templates/subscription-route.template.ts +0 -446
  121. package/templates/apps/api/src/__tests__/server.test.ts +0 -253
  122. package/templates/apps/api/src/bin/deliverable-resend.ts +0 -144
  123. package/templates/apps/api/src/bin/deliverable-upload.ts +0 -114
  124. package/templates/apps/api/src/bin/followup-sweep.ts +0 -44
  125. package/templates/apps/api/src/bin/listing-csv-sweep.ts +0 -46
  126. package/templates/apps/api/src/bin/seed-presets.ts +0 -58
  127. package/templates/apps/api/src/bin/seed-waitlist-experiments.ts +0 -104
  128. package/templates/apps/api/src/bin/session-retention-sweep.ts +0 -46
  129. package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -74
  130. package/templates/apps/api/src/lib/stripe.ts +0 -52
  131. package/templates/apps/api/src/lib/tenant-db.ts +0 -225
  132. package/templates/apps/api/src/lib/ws-token.ts +0 -91
  133. package/templates/apps/api/src/middleware/tenant.ts +0 -99
  134. package/templates/apps/api/src/routes/billing/__tests__/portal.test.ts +0 -450
  135. package/templates/apps/api/src/routes/billing/__tests__/read.test.ts +0 -262
  136. package/templates/apps/api/src/routes/billing/__tests__/usage.test.ts +0 -436
  137. package/templates/apps/api/src/routes/billing/index.ts +0 -36
  138. package/templates/apps/api/src/routes/billing/portal.ts +0 -182
  139. package/templates/apps/api/src/routes/billing/read.ts +0 -75
  140. package/templates/apps/api/src/routes/billing/usage.ts +0 -153
  141. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -687
  142. package/templates/apps/api/src/routes/checkout/index.ts +0 -13
  143. package/templates/apps/api/src/routes/checkout/sessions.ts +0 -197
  144. package/templates/apps/api/src/routes/deliverables/__tests__/index.test.ts +0 -393
  145. package/templates/apps/api/src/routes/deliverables/index.ts +0 -200
  146. package/templates/apps/api/src/routes/flow-checkouts/__tests__/index.test.ts +0 -443
  147. package/templates/apps/api/src/routes/flow-checkouts/index.ts +0 -82
  148. package/templates/apps/api/src/routes/flows/README.md +0 -147
  149. package/templates/apps/api/src/routes/flows/__tests__/index.test.ts +0 -752
  150. package/templates/apps/api/src/routes/flows/__tests__/recommender.test.ts +0 -671
  151. package/templates/apps/api/src/routes/flows/index.ts +0 -202
  152. package/templates/apps/api/src/routes/flows/recommender.ts +0 -443
  153. package/templates/apps/api/src/routes/project-listings/__tests__/copy-edit.test.ts +0 -815
  154. package/templates/apps/api/src/routes/project-listings/__tests__/me-route-precedence.test.ts +0 -221
  155. package/templates/apps/api/src/routes/project-listings/__tests__/tenant-isolation.test.ts +0 -566
  156. package/templates/apps/api/src/routes/project-listings/get.ts +0 -70
  157. package/templates/apps/api/src/routes/project-listings/list.ts +0 -47
  158. package/templates/apps/api/src/routes/project-listings/patch.ts +0 -136
  159. package/templates/apps/api/src/routes/schedule/__tests__/index.test.ts +0 -490
  160. package/templates/apps/api/src/routes/schedule/index.ts +0 -249
  161. package/templates/apps/api/src/routes/slack/__tests__/actions.test.ts +0 -385
  162. package/templates/apps/api/src/routes/slack/actions.ts +0 -177
  163. package/templates/apps/api/src/routes/slack/index.ts +0 -38
  164. package/templates/apps/api/src/routes/waitlist-experiments/__tests__/tenant-isolation.test.ts +0 -577
  165. package/templates/apps/api/src/routes/waitlist-experiments/comparison.ts +0 -78
  166. package/templates/apps/api/src/routes/waitlist-experiments/index.ts +0 -41
  167. package/templates/apps/api/src/routes/waitlist-experiments/list.ts +0 -64
  168. package/templates/apps/api/src/routes/waitlist-experiments/respond.ts +0 -42
  169. package/templates/apps/api/src/routes/waitlist-experiments/signup.ts +0 -84
  170. package/templates/apps/api/src/routes/waitlist-experiments/signups.ts +0 -119
  171. package/templates/apps/api/src/routes/waitlist-signups/__tests__/index.test.ts +0 -238
  172. package/templates/apps/api/src/routes/waitlist-signups/index.ts +0 -101
  173. package/templates/apps/api/src/routes/webhooks/README.md +0 -80
  174. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -315
  175. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -247
  176. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -270
  177. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -198
  178. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -633
  179. package/templates/apps/api/src/routes/webhooks/index.ts +0 -41
  180. package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -481
  181. package/templates/apps/api/src/routes/workspaces/__tests__/config-tenant-isolation.test.ts +0 -356
  182. package/templates/apps/api/src/routes/workspaces/__tests__/tenant-isolation.test.ts +0 -671
  183. package/templates/apps/api/src/routes/workspaces/config.ts +0 -125
  184. package/templates/apps/api/src/routes/workspaces/index.ts +0 -194
  185. package/templates/apps/api/src/routes/workspaces/sessions.ts +0 -218
  186. package/templates/apps/api/src/services/__tests__/flow-aggregate.test.ts +0 -425
  187. package/templates/apps/api/src/services/__tests__/flow-engine.test.ts +0 -2840
  188. package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +0 -393
  189. package/templates/apps/api/src/services/__tests__/listing-csv-sweep.test.ts +0 -560
  190. package/templates/apps/api/src/services/__tests__/listing-promotion.test.ts +0 -684
  191. package/templates/apps/api/src/services/__tests__/playbook-compile.test.ts +0 -406
  192. package/templates/apps/api/src/services/__tests__/playbook-render.test.ts +0 -290
  193. package/templates/apps/api/src/services/__tests__/project-listing-decision.test.ts +0 -736
  194. package/templates/apps/api/src/services/__tests__/project-listing-flow.test.ts +0 -475
  195. package/templates/apps/api/src/services/__tests__/project-listing-issue.test.ts +0 -340
  196. package/templates/apps/api/src/services/__tests__/recommender-capture.test.ts +0 -983
  197. package/templates/apps/api/src/services/__tests__/tenant-context-cascade.test.ts +0 -71
  198. package/templates/apps/api/src/services/__tests__/tenant-context.test.ts +0 -379
  199. package/templates/apps/api/src/services/__tests__/usage-metering.test.ts +0 -768
  200. package/templates/apps/api/src/services/__tests__/waitlist-dashboard.test.ts +0 -1314
  201. package/templates/apps/api/src/services/__tests__/waitlist-experiments.test.ts +0 -341
  202. package/templates/apps/api/src/services/__tests__/waitlist-followup.test.ts +0 -567
  203. package/templates/apps/api/src/services/__tests__/waitlist-scoring.test.ts +0 -474
  204. package/templates/apps/api/src/services/__tests__/waitlist-signups.test.ts +0 -354
  205. package/templates/apps/api/src/services/flow-aggregate.ts +0 -232
  206. package/templates/apps/api/src/services/flow-checkouts.ts +0 -123
  207. package/templates/apps/api/src/services/flow-engine.ts +0 -1296
  208. package/templates/apps/api/src/services/lead-promotion.ts +0 -176
  209. package/templates/apps/api/src/services/listing-csv-sweep.ts +0 -455
  210. package/templates/apps/api/src/services/listing-promotion.ts +0 -342
  211. package/templates/apps/api/src/services/playbook-compile.ts +0 -398
  212. package/templates/apps/api/src/services/playbook-render.ts +0 -263
  213. package/templates/apps/api/src/services/project-listing-decision.ts +0 -510
  214. package/templates/apps/api/src/services/project-listing-flow.ts +0 -426
  215. package/templates/apps/api/src/services/project-listing-issue.ts +0 -251
  216. package/templates/apps/api/src/services/recommender-capture.ts +0 -835
  217. package/templates/apps/api/src/services/scheduling/cal-provider.ts +0 -392
  218. package/templates/apps/api/src/services/scheduling/index.ts +0 -63
  219. package/templates/apps/api/src/services/scheduling/types.ts +0 -88
  220. package/templates/apps/api/src/services/tenant-context.ts +0 -451
  221. package/templates/apps/api/src/services/usage-metering.ts +0 -699
  222. package/templates/apps/api/src/services/waitlist-dashboard.ts +0 -947
  223. package/templates/apps/api/src/services/waitlist-experiments.ts +0 -213
  224. package/templates/apps/api/src/services/waitlist-followup.ts +0 -486
  225. package/templates/apps/api/src/services/waitlist-scoring.ts +0 -166
  226. package/templates/apps/api/src/services/waitlist-signups.ts +0 -165
  227. package/templates/apps/mcp/__tests__/schedule_tools.test.ts +0 -242
  228. package/templates/apps/mcp/src/tools/create_booking.ts +0 -58
  229. package/templates/apps/mcp/src/tools/get_event_meta.ts +0 -55
  230. package/templates/apps/mcp/src/tools/get_flow.ts +0 -61
  231. package/templates/apps/mcp/src/tools/list_availability.ts +0 -67
  232. package/templates/apps/mcp/src/tools/submit_flow_step.ts +0 -83
  233. package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/page.tsx +0 -309
  234. package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/signups/[leadId]/page.tsx +0 -149
  235. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/comparison.test.tsx +0 -273
  236. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/list.test.tsx +0 -171
  237. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/signup.test.tsx +0 -179
  238. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ExperimentsTable.tsx +0 -116
  239. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/OfferFunnelTable.tsx +0 -66
  240. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/RollupTicker.tsx +0 -61
  241. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ScoreTrace.tsx +0 -114
  242. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/SignupsTable.tsx +0 -139
  243. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/WaitlistComparisonTabs.tsx +0 -85
  244. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/status-badges.tsx +0 -67
  245. package/templates/apps/web/app/[locale]/(authed)/waitlist/page.tsx +0 -179
  246. package/templates/apps/web/app/[locale]/blog/[[...slug]]/page.tsx +0 -178
  247. package/templates/apps/web/app/[locale]/dev/purchase/__tests__/actions.test.ts +0 -160
  248. package/templates/apps/web/app/[locale]/dev/purchase/error.tsx +0 -25
  249. package/templates/apps/web/app/[locale]/dev/purchase/page.tsx +0 -117
  250. package/templates/apps/web/app/[locale]/dev/purchase/purchase.actions.ts +0 -58
  251. package/templates/apps/web/app/[locale]/docs/[[...slug]]/page.tsx +0 -119
  252. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/checkout.actions.test.ts +0 -287
  253. package/templates/apps/web/app/[locale]/flows/[slug]/checkout.actions.ts +0 -254
  254. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsClient.tsx +0 -532
  255. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsEmailStep.tsx +0 -121
  256. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/ResultsClient.checkout.test.tsx +0 -457
  257. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/page.test.tsx +0 -396
  258. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/page.tsx +0 -114
  259. package/templates/apps/web/app/[locale]/projects/apply/ListingApplicationClient.tsx +0 -110
  260. package/templates/apps/web/app/[locale]/projects/apply/__tests__/ListingApplicationClient.test.tsx +0 -96
  261. package/templates/apps/web/app/[locale]/schedule/__tests__/page.test.tsx +0 -117
  262. package/templates/apps/web/app/[locale]/schedule/confirmed/__tests__/page.test.tsx +0 -96
  263. package/templates/apps/web/app/[locale]/schedule/confirmed/page.tsx +0 -92
  264. package/templates/apps/web/app/[locale]/schedule/page.tsx +0 -82
  265. package/templates/apps/web/content/en/blog/README.txt +0 -25
  266. package/templates/apps/web/content/en/docs/index.mdx +0 -28
  267. package/templates/apps/web/lib/__mocks__/source-server.js +0 -31
  268. package/templates/apps/web/lib/blog-list-data.ts +0 -95
  269. package/templates/apps/web/lib/blog-post-data.ts +0 -79
  270. package/templates/apps/web/lib/source.ts +0 -34
  271. package/templates/apps/web/public/logomark-dark.svg +0 -4
  272. package/templates/apps/web/public/logomark-light.svg +0 -4
  273. package/templates/apps/web/source.config.ts +0 -78
@@ -124,27 +124,12 @@ export {
124
124
  type ScaffoldOutput,
125
125
  } from "./scaffold.js";
126
126
 
127
- export {
128
- getFlowInputSchema,
129
- getFlowOutputSchema,
130
- ailkGetFlow,
131
- type GetFlowInput,
132
- type AilkGetFlowOutput,
133
- } from "./get_flow.js";
134
-
135
- export {
136
- submitFlowStepInputSchemaForTool,
137
- submitFlowStepOutputSchema,
138
- ailkSubmitFlowStep,
139
- type SubmitFlowStepInput,
140
- type AilkSubmitFlowStepOutput,
141
- } from "./submit_flow_step.js";
142
-
143
- // The scheduling tools (list_availability, get_event_meta, create_booking) are
144
- // deliberately NOT re-exported here, and neither are the content-write tools
145
- // (create_page, update_page, delete_page). Both groups are module-conditional
146
- // slice files (#5182): a re-export from this barrel is a static path into a
147
- // file the OSS strip removes, which reds the public tree's type-check. They are
148
- // reached only through `createMcpServer`'s per-module loader in ../server.ts.
127
+ // The scheduling tools (list_availability, get_event_meta, create_booking),
128
+ // the content-write tools (create_page, update_page, delete_page), and the
129
+ // signal-collectors flow tools (get_flow, submit_flow_step) are deliberately
130
+ // NOT re-exported here. All three groups are module-conditional slice files
131
+ // (#5182): a re-export from this barrel is a static path into a file the OSS
132
+ // strip removes, which reds the public tree's type-check. They are reached
133
+ // only through `createMcpServer`'s per-module loader in ../server.ts.
149
134
  // The rule this barrel now follows: it re-exports exactly the tools no module
150
135
  // gate can remove.
@@ -26,6 +26,21 @@ CONTENT_BACKEND=mdx
26
26
  # Same convention as apps/workspace/lib/client-api.ts's identically-named var.
27
27
  # Should be apps/api's origin with NO trailing slash (a single trailing
28
28
  # slash is stripped before joining, but keep this clean regardless).
29
+ #
30
+ # THIS IS THE ONE BROWSER-SIDE NAME (#5397). All three browser readers of the
31
+ # apps/api origin resolve it from this variable: resolveSubmitUrl
32
+ # (packages/ui, the form blocks above), apps/workspace's client-api, and
33
+ # @working-theory/api-client's getApiBase() — which runs in the browser
34
+ # wherever a "use client" component binds it, e.g. the founder application's
35
+ # ListingApplicationClient. getApiBase() previously read NEXT_PUBLIC_API_URL,
36
+ # a name this file never documented, so a site configured exactly per these
37
+ # docs sent its browser traffic to http://localhost:3001. That name is still
38
+ # honoured as a deprecated fallback; do not set it in a new deployment.
39
+ #
40
+ # The server-side counterpart is AILK_API_URL (see the repo-root .env.example)
41
+ # — deliberately NOT NEXT_PUBLIC_, and it still wins over this one when both
42
+ # are set, so an RSC/Server-Action call can target an internal origin the
43
+ # browser never sees.
29
44
  # NEXT_PUBLIC_AILK_API_URL=http://localhost:3002
30
45
 
31
46
  # =============================================================================
@@ -24,14 +24,14 @@ jest.mock("next/headers", () => ({
24
24
 
25
25
  const mockGetSession = jest.fn();
26
26
  // eslint-disable-next-line no-restricted-syntax -- #507: mock-internal rewrite pending; auth.ts's lazy Better-Auth singleton has no HTTP/DB boundary a unit test of the session-branch can mock without standing up Prisma.
27
- jest.mock("../../../../../auth", () => ({
27
+ jest.mock("../../../../auth", () => ({
28
28
  __esModule: true,
29
29
  auth: { api: { getSession: (...args: unknown[]) => mockGetSession(...args) } },
30
30
  }));
31
31
 
32
32
  const mockGetActiveProviderIds = jest.fn();
33
33
  // eslint-disable-next-line no-restricted-syntax -- #507: mock-internal rewrite pending; auth-env.ts is a pure env-introspection module with no external boundary to mock instead.
34
- jest.mock("../../../../../lib/auth-env", () => ({
34
+ jest.mock("../../../../lib/auth-env", () => ({
35
35
  __esModule: true,
36
36
  getActiveProviderIds: () => mockGetActiveProviderIds(),
37
37
  }));
@@ -48,8 +48,8 @@ jest.mock("better-auth/react", () => ({
48
48
  createAuthClient: () => ({ signIn: { social: mockSignInSocial } }),
49
49
  }));
50
50
 
51
- import AuthedLayout from "../../layout";
52
- import { SignInGate } from "../../sign-in-gate";
51
+ import AuthedLayout from "../layout";
52
+ import { SignInGate } from "../sign-in-gate";
53
53
 
54
54
  describe("AuthedLayout — the (authed) session guard", () => {
55
55
  beforeEach(() => {
@@ -1,3 +1,4 @@
1
+ // oss: false
1
2
  "use client";
2
3
 
3
4
  /**
@@ -53,7 +54,7 @@ import {
53
54
  type FlowStepperMessages,
54
55
  type FlowStepSubmitPayload,
55
56
  type FlowStepSubmitResult,
56
- } from "@working-theory/ui";
57
+ } from "@working-theory/ui/slices/signal-collectors";
57
58
  import type { AeoScoreResult, FlowConfig, FlowState } from "@working-theory/validation";
58
59
  import {
59
60
  deriveFlags,
@@ -1,3 +1,4 @@
1
+ // oss: false
1
2
  /**
2
3
  * Tests for FlowStepperClient's permalink completion redirect on a
3
4
  * `mode:"recommending"` flow (#4770 D1/D7/D12).
@@ -64,7 +65,7 @@ interface MockFlowStepperProps {
64
65
 
65
66
  let captured: MockFlowStepperProps | undefined;
66
67
 
67
- jest.mock("@working-theory/ui", () => ({
68
+ jest.mock("@working-theory/ui/slices/signal-collectors", () => ({
68
69
  FlowStepper: (props: MockFlowStepperProps) => {
69
70
  captured = props;
70
71
  return require("react").createElement("div", {
@@ -1,3 +1,4 @@
1
+ // oss: false
1
2
  /**
2
3
  * Tests for FlowStepperClient's segment-keyed completion redirect (#3960 D5).
3
4
  *
@@ -68,7 +69,7 @@ const PII_PAYLOAD = {
68
69
 
69
70
  let capturedOnCompleted: MockFlowStepperProps["onCompleted"];
70
71
 
71
- jest.mock("@working-theory/ui", () => ({
72
+ jest.mock("@working-theory/ui/slices/signal-collectors", () => ({
72
73
  FlowStepper: (props: MockFlowStepperProps) => {
73
74
  capturedOnCompleted = props.onCompleted;
74
75
  async function handleSubmit(): Promise<void> {
@@ -1,3 +1,4 @@
1
+ // oss: false
1
2
  /**
2
3
  * Tests for submitFlowStepAction Server Action (#3957 D8).
3
4
  *
@@ -1,3 +1,4 @@
1
+ // oss: false
1
2
  /**
2
3
  * #5053 — an interactive tool is two routes.
3
4
  *
@@ -1,3 +1,4 @@
1
+ // oss: false
1
2
  "use server";
2
3
 
3
4
  /**
@@ -29,7 +30,7 @@
29
30
  */
30
31
 
31
32
  import { flows } from "@working-theory/api-client";
32
- import type { FlowStepSubmitResult } from "@working-theory/ui";
33
+ import type { FlowStepSubmitResult } from "@working-theory/ui/slices/signal-collectors";
33
34
  import {
34
35
  flowSlugSchema,
35
36
  submitFlowStepInputSchema,
@@ -1,3 +1,4 @@
1
+ // oss: false
1
2
  /**
2
3
  * /[locale]/flows/[slug] — the tool's LANDING route (#5053 D3/D5).
3
4
  *
@@ -1,3 +1,4 @@
1
+ // oss: false
1
2
  /**
2
3
  * /[locale]/flows/[slug]/start — the flow half of the two-route tool
3
4
  * (#5053 D3/D5). Moved here from `../page.tsx`, which is now the indexed
@@ -4,9 +4,11 @@
4
4
  * Returns a plain-text index of AILK's content surface for LLM consumption,
5
5
  * following the llms.txt convention (https://llmstxt.org).
6
6
  *
7
- * Aggregates two surfaces:
8
- * 1. Section-catalog (MDX seeds in content/) via @working-theory/content-adapters
9
- * 2. Fumadocs blog corpus via blogSource.getPages()
7
+ * Indexes the section catalog (MDX seeds in content/) via
8
+ * @working-theory/content-adapters. Nothing is gated: a Free site has no blog
9
+ * (D-46), so there is no blog corpus to omit — `getBlogPages` defaults to an
10
+ * empty list and the docs + blog module ships its own variant of this route
11
+ * that reads `blogSource` (#5365 D9).
10
12
  *
11
13
  * Format per entry:
12
14
  * - Title: <title>
@@ -14,8 +16,9 @@
14
16
  * Description: <description>
15
17
  *
16
18
  * DI note: `createLlmsHandler` accepts optional `getContentAdapter` and
17
- * `getBlogPages` deps for testing — tests inject stubs to avoid mocking
18
- * internal modules. The exported `GET` uses the real implementations.
19
+ * `getBlogPages` deps — tests inject stubs, and the module's variant of this
20
+ * route supplies the real `blogSource` reader. The exported `GET` is
21
+ * unchanged either way.
19
22
  */
20
23
 
21
24
  import { SCHEMA_ORG_TYPES } from "@working-theory/content-adapters";
@@ -23,7 +26,6 @@ import type { ContentAdapter, SchemaOrgType } from "@working-theory/content-adap
23
26
  import { getContentAdapter as defaultGetContentAdapter } from "@working-theory/page-renderer";
24
27
 
25
28
  import { SITE_NAME } from "../../lib/site-brand";
26
- import { blogSource as defaultBlogSource } from "../../lib/source";
27
29
  import { resolveBaseUrl, slugToPath } from "../../src/lib/routes";
28
30
 
29
31
  export interface LlmsHandlerDeps {
@@ -33,8 +35,9 @@ export interface LlmsHandlerDeps {
33
35
  */
34
36
  getContentAdapter?: () => ContentAdapter;
35
37
  /**
36
- * Blog pages getter. Defaults to the real blogSource.getPages().
37
- * Override in tests to inject stub pages without mocking lib/source.
38
+ * Blog pages getter. Defaults to none Free has no blog (D-46, #5365 D9).
39
+ * The docs + blog module's own copy of this route reads `blogSource`.
40
+ * Override in tests to inject stub pages.
38
41
  */
39
42
  getBlogPages?: () => Array<{ url: string; data: { title: string; description?: string } }>;
40
43
  }
@@ -45,7 +48,7 @@ export interface LlmsHandlerDeps {
45
48
  */
46
49
  export function createLlmsHandler(deps: LlmsHandlerDeps = {}) {
47
50
  const resolveAdapter = deps.getContentAdapter ?? defaultGetContentAdapter;
48
- const resolveBlogPages = deps.getBlogPages ?? (() => defaultBlogSource.getPages() as Array<{ url: string; data: { title: string; description?: string } }>);
51
+ const resolveBlogPages = deps.getBlogPages ?? (() => []);
49
52
 
50
53
  return async function llmsGET(): Promise<Response> {
51
54
  const adapter = resolveAdapter();
@@ -11,11 +11,11 @@ module.exports = {
11
11
  ],
12
12
  testMatch: ["**/__tests__/**/*.test.ts", "**/__tests__/**/*.test.tsx"],
13
13
  testPathIgnorePatterns: ["/node_modules/", "/.next/", "/dist/"],
14
- // Ignore node_modules except fumadocs-* (ESM-only packages loaded via lib/source.ts → fumadocs-core/source).
14
+ // Ignore node_modules except @working-theory/* (their dist is ESM).
15
15
  // Mirrors the canonical jose carve-out used in apps/api, apps/mcp, and apps-paid/license-issuer.
16
16
  // Added: issue #1077
17
17
  transformIgnorePatterns: [
18
- "/node_modules/(?!(\\.pnpm/)?(fumadocs-[^/]*?@?[^/]*?|@working-theory(?:\\+[^/]*?@?[^/]*?|/[^/]+))(/|$))",
18
+ "/node_modules/(?!(\\.pnpm/)?@working-theory(?:\\+[^/]*?@?[^/]*?|/[^/]+)(/|$))",
19
19
  ],
20
20
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
21
21
  // Workspace packages publish ESM in dist/, but ts-jest runs in CommonJS.
@@ -27,12 +27,6 @@ module.exports = {
27
27
  // Map all *.css to an empty stub — layout.tsx imports ./globals.css (#4090 item 1)
28
28
  // and CSS is not parseable by ts-jest's CommonJS transform (apps-paid/marketing-web precedent, #1531).
29
29
  "\\.css$": "<rootDir>/__tests__/__mocks__/style-mock.js",
30
- // Fumadocs codegen output — produced by `pnpm --filter @working-theory/web build` into .source/
31
- // The server entry uses top-level await + ESM-only fumadocs-mdx/runtime/server;
32
- // map to a CJS stub so ts-jest can load modules that import lib/source.ts. (#1077)
33
- // Stub lives in lib/__mocks__/ (committed) not .source/__mocks__/ (gitignored).
34
- "^@/\\.source/server$": "<rootDir>/lib/__mocks__/source-server.js",
35
- "^@/\\.source$": "<rootDir>/.source/index.ts",
36
30
  "^@working-theory/page-renderer/testing$":
37
31
  "<rootDir>/node_modules/@working-theory/page-renderer/dist/testing.js",
38
32
  "^@working-theory/page-renderer$":
@@ -51,8 +45,6 @@ module.exports = {
51
45
  "^@working-theory/api-client$": "<rootDir>/node_modules/@working-theory/api-client/dist/index.js",
52
46
  "^@working-theory/content-adapters$":
53
47
  "<rootDir>/node_modules/@working-theory/content-adapters/dist/index.js",
54
- "^@working-theory/fumadocs-schema$":
55
- "<rootDir>/node_modules/@working-theory/fumadocs-schema/dist/index.js",
56
48
  "^@working-theory/license$": "<rootDir>/node_modules/@working-theory/license/dist/index.js",
57
49
  "^@working-theory/jsonld$": "<rootDir>/node_modules/@working-theory/jsonld/dist/index.js",
58
50
  "^@working-theory/metadata$": "<rootDir>/node_modules/@working-theory/metadata/dist/index.js",
@@ -66,6 +58,7 @@ module.exports = {
66
58
  "<rootDir>/node_modules/@working-theory/schema-validator/dist/index.js",
67
59
  "^@working-theory/sections-registry$":
68
60
  "<rootDir>/node_modules/@working-theory/sections-registry/dist/index.js",
61
+
69
62
  "^@working-theory/templates/shells$":
70
63
  "<rootDir>/node_modules/@working-theory/templates/dist/shells/index.js",
71
64
  "^@working-theory/templates$": "<rootDir>/node_modules/@working-theory/templates/dist/index.js",
@@ -82,6 +75,14 @@ module.exports = {
82
75
  // tree, where nothing imports it, so the unused mapping is inert there.
83
76
  "^@working-theory/ui/slices/scheduling$":
84
77
  "<rootDir>/node_modules/@working-theory/ui/dist/sections/slices/scheduling.js",
78
+ // #5366: the signal-collectors slice's re-export subpath. Same reasoning
79
+ // as the scheduling mapping above.
80
+ "^@working-theory/ui/slices/signal-collectors$":
81
+ "<rootDir>/node_modules/@working-theory/ui/dist/sections/slices/signal-collectors.js",
82
+ // #5364: the commerce slice's renderer-registration + CheckoutPriceCard
83
+ // re-export subpath. Same reasoning as the scheduling mapping above.
84
+ "^@working-theory/ui/slices/commerce$":
85
+ "<rootDir>/node_modules/@working-theory/ui/dist/sections/slices/commerce.js",
85
86
  "^@working-theory/theme$": "<rootDir>/node_modules/@working-theory/theme/dist/index.js",
86
87
  // site-config publishes ESM in dist/; map to source so ts-jest compiles it
87
88
  // through the same transformer as every sibling above. Only the
@@ -126,9 +127,9 @@ module.exports = {
126
127
  },
127
128
  setupFilesAfterEnv: ["<rootDir>/__tests__/setup.ts"],
128
129
  transform: {
129
- // fumadocs-core (16.10.6+) ships `import.meta.env` in its dist JS
130
- // (e.g. dist/url-*.js), which the transformIgnorePatterns carve-out
131
- // above lets reach a transformer instead of being required raw.
130
+ // Some `@working-theory/*` dist JS ships `import.meta`, which the
131
+ // transformIgnorePatterns carve-out above lets reach a transformer
132
+ // instead of being required raw.
132
133
  // `import.meta` has no CJS form, so it must run through the shared
133
134
  // import.meta -> {} rewrite BEFORE ts-jest — ts-jest's own
134
135
  // astTransformers hook never fires for a node_modules JS file (see the
@@ -3,7 +3,6 @@ import { join } from "node:path";
3
3
  import { parse as parseYaml } from "yaml";
4
4
  import bundleAnalyzer from "@next/bundle-analyzer";
5
5
  import { withSentryConfig } from "@sentry/nextjs";
6
- import { createMDX } from "fumadocs-mdx/next";
7
6
  import createNextIntlPlugin from "next-intl/plugin";
8
7
 
9
8
  // @next/bundle-analyzer — enabled when ANALYZE=true (set by ci-bundle.yml).
@@ -110,7 +109,6 @@ const nextConfig = {
110
109
  "@working-theory/analytics",
111
110
  "@working-theory/api-client",
112
111
  "@working-theory/content-adapters",
113
- "@working-theory/fumadocs-schema",
114
112
  "@working-theory/jsonld",
115
113
  "@working-theory/metadata",
116
114
  "@working-theory/page-renderer",
@@ -168,6 +166,6 @@ const sentryBuildOptions = {
168
166
  };
169
167
 
170
168
  export default withSentryConfig(
171
- withBundleAnalyzer(withNextIntl(createMDX()(nextConfig))),
169
+ withBundleAnalyzer(withNextIntl(nextConfig)),
172
170
  sentryBuildOptions,
173
171
  );
@@ -6,14 +6,11 @@
6
6
  "license": "Apache-2.0",
7
7
  "scripts": {
8
8
  "dev": "next dev",
9
- "prebuild": "fumadocs-mdx",
10
9
  "build": "next build --webpack",
11
10
  "postbuild": "tsx scripts/assert-content-bundled.ts",
12
11
  "start": "next start",
13
- "pretypecheck": "fumadocs-mdx",
14
12
  "type-check": "tsc --noEmit",
15
13
  "lint": "next lint",
16
- "pretest": "fumadocs-mdx",
17
14
  "test": "jest",
18
15
  "test:watch": "jest --watch"
19
16
  },
@@ -24,7 +21,6 @@
24
21
  "@working-theory/api-client": "workspace:*",
25
22
  "@working-theory/content-adapters": "workspace:*",
26
23
  "@working-theory/database": "workspace:*",
27
- "@working-theory/fumadocs-schema": "workspace:*",
28
24
  "@working-theory/jsonld": "workspace:*",
29
25
  "@working-theory/metadata": "workspace:*",
30
26
  "@working-theory/page-renderer": "workspace:*",
@@ -38,8 +34,6 @@
38
34
  "@working-theory/validation": "workspace:*",
39
35
  "@working-theory/web-i18n": "workspace:*",
40
36
  "better-auth": "1.6.22",
41
- "fumadocs-core": "^16.10.4",
42
- "fumadocs-mdx": "^15.0.12",
43
37
  "lucide-react": "^0.577.0",
44
38
  "next": "^16.3.3",
45
39
  "next-intl": "^3.26.3",
@@ -1,4 +1,7 @@
1
- <svg width="1080" height="1080" viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <rect width="1080" height="1080" rx="190" fill="#F0B100"/>
3
- <path d="M127.624 704.255C127.624 704.255 303.232 444.079 606.336 428.823C606.336 428.823 827.464 405.543 824.36 645.295C824.36 645.295 824.344 832.999 659.872 916.079C507.8 992.887 380.56 892.023 383.664 757.023C386.552 631.327 467.136 458.695 824.392 199.167L792.552 155.463L952.384 137.359L893.416 288.399L861.864 246.503C861.864 246.503 529.792 463.231 475.216 676.335C475.216 676.335 432.544 848.583 558.992 852.527C689.056 856.591 794.88 637.543 696.856 535.383C613.632 448.639 369.888 498.079 163.504 733.167L127.616 704.263L127.624 704.255Z" fill="white"/>
1
+ <svg width="1520" height="1520" viewBox="0 0 1520 1520" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="AI Launch Kit loop logomark">
2
+ <title>AI Launch Kit favicon (the loop logomark on the #0656E9 tile)</title>
3
+ <rect x="0" y="0" width="1520" height="1520" rx="267" fill="#0656E9"/>
4
+ <svg x="258.4" y="270.1" width="1003.2" height="979.9" viewBox="127.6 137.2 824.8 805.6" fill="#FFFFFF">
5
+ <path d="M127.624 704.255C127.624 704.255 303.232 444.079 606.336 428.823C606.336 428.823 827.464 405.543 824.36 645.295C824.36 645.295 824.344 832.999 659.872 916.079C507.8 992.887 380.56 892.023 383.664 757.023C386.552 631.327 467.136 458.695 824.392 199.167L792.552 155.463L952.384 137.359L893.416 288.399L861.864 246.503C861.864 246.503 529.792 463.231 475.216 676.335C475.216 676.335 432.544 848.583 558.992 852.527C689.056 856.591 794.88 637.543 696.856 535.383C613.632 448.639 369.888 498.079 163.504 733.167L127.616 704.263L127.624 704.255Z" fill="#FFFFFF"/>
6
+ </svg>
4
7
  </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-196.50 -128.00 1248.00 143.50" width="1248" height="144">
2
+ <!-- AI Launch Kit — horizontal lockup from the portfolio logo builder (mark: loop; wordmark: custom lettering). -->
3
+ <g transform="scale(100)" fill="#2F2E2F"><g transform="translate(-1.9050 -1.2206) scale(0.0016343825665859565) translate(-127.0 -137.0)"><path d="M127.624 704.255C127.624 704.255 303.232 444.079 606.336 428.823C606.336 428.823 827.464 405.543 824.36 645.295C824.36 645.295 824.344 832.999 659.872 916.079C507.8 992.887 380.56 892.023 383.664 757.023C386.552 631.327 467.136 458.695 824.392 199.167L792.552 155.463L952.384 137.359L893.416 288.399L861.864 246.503C861.864 246.503 529.792 463.231 475.216 676.335C475.216 676.335 432.544 848.583 558.992 852.527C689.056 856.591 794.88 637.543 696.856 535.383C613.632 448.639 369.888 498.079 163.504 733.167L127.616 704.263L127.624 704.255Z" fill="#2F2E2F"/></g><g><g transform="translate(0.0000 0) scale(1.12)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -4.7020750267431675 -1.4599045865638782)"><path d="M 2017.5 402.472656 L 2069.75 282.953125 L 2117.78125 403.007812 Z M 2058.75 183.148438 L 1880.675781 584.136719 L 1942.238281 584.136719 L 2008.234375 422.691406 L 2125.605469 423.199219 L 2190.234375 584.136719 L 2271.277344 584.136719 L 2099.449219 183.226562 Z M 2058.75 183.148438 "/></g></g><g transform="translate(1.2171 0) scale(1.12)"><g transform="matrix(0.00437188995905497 0 0 0.00437188995905497 -7.51705209867612 -1.835802888450144)"><path d="M1740.19 194.304L1719.36 191.411V202.211V419.908H1760.75V202.211V191.411L1740.19 194.304Z"/></g></g><g transform="translate(2.0699 0) scale(1.12)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -5.830939525076691 -1.4599045865638782)"><path d="M 2402.425781 183.285156 C 2396.121094 184.144531 2381.960938 186.203125 2370.179688 188.808594 L 2369.75 188.917969 L 2369.320312 188.871094 C 2368.386719 188.792969 2347.890625 187.152344 2332.242188 182.320312 L 2332.367188 584.121094 L 2560.800781 582.847656 L 2560.800781 553.59375 L 2403.714844 559.222656 Z M 2402.425781 183.285156 "/></g></g><g transform="translate(2.7492 0) scale(1)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -4.7020750267431675 -1.4599045865638782)"><path d="M 2017.5 402.472656 L 2069.75 282.953125 L 2117.78125 403.007812 Z M 2058.75 183.148438 L 1880.675781 584.136719 L 1942.238281 584.136719 L 2008.234375 422.691406 L 2125.605469 423.199219 L 2190.234375 584.136719 L 2271.277344 584.136719 L 2099.449219 183.226562 Z M 2058.75 183.148438 "/></g></g><g transform="translate(3.8551 0) scale(1)"><g transform="matrix(0.008439053643785967 0 0 0.008439053643785967 -4.32856421446149 -1.661401981511421)"><path d="M588.43 79.8509L582.5 78.3809H582.4V152.431C582.4 170.651 578.49 184.301 560.57 185.691C535.83 187.611 534.33 168.701 534.33 152.431V78.3809H512.93V154.271C512.93 180.851 526.97 196.901 553.55 196.901C580.13 196.901 594.34 180.851 594.34 154.271V78.3809H594.29L588.43 79.8509Z"/></g></g><g transform="translate(4.7219 0) scale(1)"><g transform="matrix(0.00437188995905497 0 0 0.00437188995905497 -8.030530574367127 -1.835802888450144)"><path d="M2004.42 193.996L1983.67 191.122V201.903V362.052H1981.67L1873.96 191.064H1836.85V419.909H1878.31V249.847H1880.2L1988.03 419.909H2024.9V201.903V191.122L2004.42 193.996Z"/></g></g><g transform="translate(5.7438 0) scale(1)"><g transform="matrix(0.008439053643785967 0 0 0.008439053643785967 -6.325890417670046 -1.661401981511421)"><path d="M836.41 164.341C835.23 168.751 829.47 176.661 826.1 179.451C821.03 183.641 815.16 185.671 808.28 185.381C799.06 185.021 790.21 178.941 786.62 175.401C774.31 163.261 763.42 126.371 785.6 101.151C790.38 95.7213 799.06 90.4313 808.28 90.0713C815.16 89.7813 821.04 91.8113 826.1 96.0013C829.47 98.8013 835.23 106.701 836.41 111.111L850.58 110.991L856.37 95.5913C854.69 93.3213 842.2 80.1513 813.29 78.3613H811.99C806.12 78.3613 800.73 78.8913 795.85 79.7713C774.34 83.6413 757.22 100.051 752.05 121.281C750.58 127.301 749.55 133.771 749.57 140.021C749.57 141.261 749.62 142.501 749.71 143.731C751.72 171.321 773.66 193.211 801.13 196.451C802.11 196.571 803.52 196.671 805.04 196.751C814.56 197.281 824.14 196.051 833.09 192.741C847.38 187.471 854.38 179.421 855.59 177.781L850.57 164.441L836.4 164.321L836.41 164.341Z"/></g></g><g transform="translate(6.8247 0) scale(1)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -7.397806839178519 -1.4599045865638782)"><path d="M 3259.496094 184.34375 L 3259.21875 356.253906 L 3141.863281 363.183594 L 3028.496094 355.238281 L 3028.773438 185.34375 L 2994.425781 190.695312 L 2959.082031 185.328125 L 2959.082031 584.074219 L 2991.449219 583.722656 L 3028.789062 584.074219 L 3029.003906 381.808594 L 3142.355469 380.472656 L 3258.726562 381.808594 L 3259.496094 583.109375 L 3293.84375 582.753906 L 3329.21875 583.109375 L 3329.21875 184.359375 L 3294.855469 189.714844 Z M 3259.496094 184.34375 "/></g></g><g transform="translate(8.3998 0) scale(1.12)"><g transform="matrix(0.00437188995905497 0 0 0.00437188995905497 -6.531551848288504 -1.835802888450144)"><path d="M1582.59 274.514L1651.05 192.742H1636.78L1536.82 312.159V192.761L1515.7 195.828L1493.99 192.742V419.909H1536.82V329.69L1553.7 309.247L1614.7 419.909H1664.03L1582.59 274.514Z"/></g></g><g transform="translate(9.3625 0) scale(1)"><g transform="matrix(0.00437188995905497 0 0 0.00437188995905497 -7.51705209867612 -1.835802888450144)"><path d="M1740.19 194.304L1719.36 191.411V202.211V419.908H1760.75V202.211V191.411L1740.19 194.304Z"/></g></g><g transform="translate(9.6336 0) scale(1)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -6.402239906111586 -1.4599045865638782)"><path d="M 2691.488281 583.628906 L 2758.25 583.628906 L 2758.25 204.410156 L 2888.722656 218.15625 L 2888.832031 183.714844 L 2560.910156 183.714844 L 2560.800781 217.679688 L 2691.488281 204.425781 Z M 2691.488281 583.628906 "/></g></g></g></g>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
2
+ <!-- loop logomark in the portfolio square frame (fills 90% of the side) -->
3
+ <g transform="translate(5.000 6.090) scale(0.108959) translate(-127.0 -137.0)" fill="#2F2E2F"><path d="M127.624 704.255C127.624 704.255 303.232 444.079 606.336 428.823C606.336 428.823 827.464 405.543 824.36 645.295C824.36 645.295 824.344 832.999 659.872 916.079C507.8 992.887 380.56 892.023 383.664 757.023C386.552 631.327 467.136 458.695 824.392 199.167L792.552 155.463L952.384 137.359L893.416 288.399L861.864 246.503C861.864 246.503 529.792 463.231 475.216 676.335C475.216 676.335 432.544 848.583 558.992 852.527C689.056 856.591 794.88 637.543 696.856 535.383C613.632 448.639 369.888 498.079 163.504 733.167L127.616 704.263L127.624 704.255Z" fill="#2F2E2F"/></g>
4
+ </svg>
@@ -13,7 +13,7 @@
13
13
  "type": "image/png"
14
14
  }
15
15
  ],
16
- "theme_color": "#F0B100",
17
- "background_color": "#ffffff",
16
+ "theme_color": "#0656E9",
17
+ "background_color": "#0656E9",
18
18
  "display": "standalone"
19
19
  }
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-6.00 -118.50 1057.50 124.50" width="1058" height="125">
2
+ <!-- AI Launch Kit — wordmark from the portfolio logo builder (custom lettering). -->
3
+ <g transform="scale(100)" fill="#2F2E2F"><g><g transform="translate(0.0000 0) scale(1.12)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -4.7020750267431675 -1.4599045865638782)"><path d="M 2017.5 402.472656 L 2069.75 282.953125 L 2117.78125 403.007812 Z M 2058.75 183.148438 L 1880.675781 584.136719 L 1942.238281 584.136719 L 2008.234375 422.691406 L 2125.605469 423.199219 L 2190.234375 584.136719 L 2271.277344 584.136719 L 2099.449219 183.226562 Z M 2058.75 183.148438 "/></g></g><g transform="translate(1.2171 0) scale(1.12)"><g transform="matrix(0.00437188995905497 0 0 0.00437188995905497 -7.51705209867612 -1.835802888450144)"><path d="M1740.19 194.304L1719.36 191.411V202.211V419.908H1760.75V202.211V191.411L1740.19 194.304Z"/></g></g><g transform="translate(2.0699 0) scale(1.12)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -5.830939525076691 -1.4599045865638782)"><path d="M 2402.425781 183.285156 C 2396.121094 184.144531 2381.960938 186.203125 2370.179688 188.808594 L 2369.75 188.917969 L 2369.320312 188.871094 C 2368.386719 188.792969 2347.890625 187.152344 2332.242188 182.320312 L 2332.367188 584.121094 L 2560.800781 582.847656 L 2560.800781 553.59375 L 2403.714844 559.222656 Z M 2402.425781 183.285156 "/></g></g><g transform="translate(2.7492 0) scale(1)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -4.7020750267431675 -1.4599045865638782)"><path d="M 2017.5 402.472656 L 2069.75 282.953125 L 2117.78125 403.007812 Z M 2058.75 183.148438 L 1880.675781 584.136719 L 1942.238281 584.136719 L 2008.234375 422.691406 L 2125.605469 423.199219 L 2190.234375 584.136719 L 2271.277344 584.136719 L 2099.449219 183.226562 Z M 2058.75 183.148438 "/></g></g><g transform="translate(3.8551 0) scale(1)"><g transform="matrix(0.008439053643785967 0 0 0.008439053643785967 -4.32856421446149 -1.661401981511421)"><path d="M588.43 79.8509L582.5 78.3809H582.4V152.431C582.4 170.651 578.49 184.301 560.57 185.691C535.83 187.611 534.33 168.701 534.33 152.431V78.3809H512.93V154.271C512.93 180.851 526.97 196.901 553.55 196.901C580.13 196.901 594.34 180.851 594.34 154.271V78.3809H594.29L588.43 79.8509Z"/></g></g><g transform="translate(4.7219 0) scale(1)"><g transform="matrix(0.00437188995905497 0 0 0.00437188995905497 -8.030530574367127 -1.835802888450144)"><path d="M2004.42 193.996L1983.67 191.122V201.903V362.052H1981.67L1873.96 191.064H1836.85V419.909H1878.31V249.847H1880.2L1988.03 419.909H2024.9V201.903V191.122L2004.42 193.996Z"/></g></g><g transform="translate(5.7438 0) scale(1)"><g transform="matrix(0.008439053643785967 0 0 0.008439053643785967 -6.325890417670046 -1.661401981511421)"><path d="M836.41 164.341C835.23 168.751 829.47 176.661 826.1 179.451C821.03 183.641 815.16 185.671 808.28 185.381C799.06 185.021 790.21 178.941 786.62 175.401C774.31 163.261 763.42 126.371 785.6 101.151C790.38 95.7213 799.06 90.4313 808.28 90.0713C815.16 89.7813 821.04 91.8113 826.1 96.0013C829.47 98.8013 835.23 106.701 836.41 111.111L850.58 110.991L856.37 95.5913C854.69 93.3213 842.2 80.1513 813.29 78.3613H811.99C806.12 78.3613 800.73 78.8913 795.85 79.7713C774.34 83.6413 757.22 100.051 752.05 121.281C750.58 127.301 749.55 133.771 749.57 140.021C749.57 141.261 749.62 142.501 749.71 143.731C751.72 171.321 773.66 193.211 801.13 196.451C802.11 196.571 803.52 196.671 805.04 196.751C814.56 197.281 824.14 196.051 833.09 192.741C847.38 187.471 854.38 179.421 855.59 177.781L850.57 164.441L836.4 164.321L836.41 164.341Z"/></g></g><g transform="translate(6.8247 0) scale(1)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -7.397806839178519 -1.4599045865638782)"><path d="M 3259.496094 184.34375 L 3259.21875 356.253906 L 3141.863281 363.183594 L 3028.496094 355.238281 L 3028.773438 185.34375 L 2994.425781 190.695312 L 2959.082031 185.328125 L 2959.082031 584.074219 L 2991.449219 583.722656 L 3028.789062 584.074219 L 3029.003906 381.808594 L 3142.355469 380.472656 L 3258.726562 381.808594 L 3259.496094 583.109375 L 3293.84375 582.753906 L 3329.21875 583.109375 L 3329.21875 184.359375 L 3294.855469 189.714844 Z M 3259.496094 184.34375 "/></g></g><g transform="translate(8.3998 0) scale(1.12)"><g transform="matrix(0.00437188995905497 0 0 0.00437188995905497 -6.531551848288504 -1.835802888450144)"><path d="M1582.59 274.514L1651.05 192.742H1636.78L1536.82 312.159V192.761L1515.7 195.828L1493.99 192.742V419.909H1536.82V329.69L1553.7 309.247L1614.7 419.909H1664.03L1582.59 274.514Z"/></g></g><g transform="translate(9.3625 0) scale(1)"><g transform="matrix(0.00437188995905497 0 0 0.00437188995905497 -7.51705209867612 -1.835802888450144)"><path d="M1740.19 194.304L1719.36 191.411V202.211V419.908H1760.75V202.211V191.411L1740.19 194.304Z"/></g></g><g transform="translate(9.6336 0) scale(1)"><g transform="matrix(0.002500025961207091 0 0 0.002500025961207091 -6.402239906111586 -1.4599045865638782)"><path d="M 2691.488281 583.628906 L 2758.25 583.628906 L 2758.25 204.410156 L 2888.722656 218.15625 L 2888.832031 183.714844 L 2560.910156 183.714844 L 2560.800781 217.679688 L 2691.488281 204.425781 Z M 2691.488281 583.628906 "/></g></g></g></g>
4
+ </svg>
@@ -1,5 +1,38 @@
1
1
  # @working-theory/database
2
2
 
3
+ ## 0.22.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#5412](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/pull/5412) [`e94f08c`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/e94f08cccfe6cb9d096b6746a092c1b6921677cf) Thanks [@claudio-planck](https://github.com/claudio-planck)! - The founder application collects first name, last name and phone on step one, and records email verification when the emailed resume link is opened ([#5407](https://github.com/working-theory-labs/ai-launch-kit-internal/issues/5407)).
8
+
9
+ **Migration: `20260914120000_listing_founder_identity`.** Five nullable columns on `project_listings` — `founder_first_name`, `founder_last_name`, `founder_phone`, `email_verify_nonce_hash` and `email_verified_at` — with no backfill and no change to any existing column. `founder_name` stays NOT NULL and stays the single-line DISPLAY name every existing reader reads; the parts sit beside it, exactly as [#5279](https://github.com/working-theory-labs/ai-launch-kit-internal/issues/5279) put the six address parts beside `address`. Composition runs one way only, so no existing row's `founder_name` is split by guessing.
10
+
11
+ The platform's default contact screen now asks first name, last name, email, phone and consent. Phone is required by default and a site relaxes it with `questions: [{ id: "founder_phone", required: false }]`. A site that still asks for one "Your name" line keeps parsing untouched: the required `founderName` contract row is satisfied either by a question writing it or by the two parts that compose it.
12
+
13
+ `POST /v1/project-listings` accepts `founderFirstName` / `founderLastName` / `founderPhone` and composes `founder_name` server-side; a body carrying only `founderName`, as every caller before this release sends, is accepted unchanged.
14
+
15
+ New anonymous, credential-gated route `POST /v1/project-listings/drafts/:id/verify-email`, reached from `projectListings.verifyEmail(id, resumeToken, verifyNonce)`. It takes two credentials, and only the second carries the proof: the resume token is in `start`'s own 201 body, so it says only that you opened the draft, while the verification NONCE is minted at `start`, stored as a digest, and handed to nothing but the resume-email builder — it reaches the outside world only as the `?verify=` parameter of the emailed link. The route stamps `email_verified_at` write-once by compare-and-swap, so repeat openings answer the first stamp; a wrong token, a wrong nonce and an unknown draft all return the same `404 not_found` the other token-gated routes return.
16
+
17
+ `ListingApplicationFlow` calls it once when it mounts with a `resume.verifyNonce`, and a failure never blocks the founder. A resume link with no nonce still resumes the draft and records nothing — which is also what a site that has not switched the resume email on gets, permanently, since no nonce is ever delivered there.
18
+
19
+ `start`'s request and response shapes are unchanged: the nonce is never in a response body and never in a log line.
20
+
21
+ `founder_phone` and `email_verified_at` are omitted from the public listing read. The operator sees both on the tenant dashboard row and in the decision/review payload, and the weekly CSV sweep's outcome log now says whether the address it mailed had been proved.
22
+
23
+ ### Patch Changes
24
+
25
+ - Updated dependencies [[`941db5d`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/941db5d317b7332c3c5bb4134d0cc18f80678781), [`cbe99c2`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/cbe99c228200b4720b2f36af50c822a4bcca2275), [`e94f08c`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/e94f08cccfe6cb9d096b6746a092c1b6921677cf), [`f42b96b`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/f42b96b7489b5dae503b6c32e2045a14f382c583), [`4d28c33`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/4d28c33978dde5cd33540813ec6317436a42a877)]:
26
+ - @working-theory/ids@0.7.0
27
+ - @working-theory/validation@0.22.0
28
+
29
+ ## 0.21.0
30
+
31
+ ### Patch Changes
32
+
33
+ - Updated dependencies []:
34
+ - @working-theory/validation@0.21.0
35
+
3
36
  ## 0.20.0
4
37
 
5
38
  ### Minor Changes
@@ -501,8 +501,75 @@ model ProjectListing {
501
501
  // `operator-only` answer reaches the dashboard and the review payload and
502
502
  // stops there.
503
503
  siteAnswers Json? @map("site_answers")
504
+ // #5407 — still the single-line DISPLAY name, and still NOT NULL: `start`
505
+ // has always required one and every reader below expects one. Where the two
506
+ // part columns beside it are written, this is COMPOSED from them
507
+ // server-side (`startProjectListingDraft`); where they are not, it is the
508
+ // line the founder typed, verbatim.
509
+ //
510
+ // Read by: the submit-time slug fallback, the approve/reject email's
511
+ // greeting, the Slack review card's Founder row, the build issue, and the
512
+ // `routeLead` identity. None of them changes.
504
513
  founderName String @map("founder_name")
514
+ // #5407 — the structured parts of the display name above, beside it rather
515
+ // than instead of it, exactly as #5279 put the six address parts beside
516
+ // `address`. Nullable for the #5036 D1 reason and one more: a row written
517
+ // before #5407 has no parts, and none may ever be GUESSED from its
518
+ // `founder_name`. "First Last" composes one way only; a name does not
519
+ // decompose (a two-word split mangles "van der Berg", "Maria del Carmen"
520
+ // and every mononym), so the migration backfills nothing and a null part
521
+ // stays null for the life of the row.
522
+ founderFirstName String? @map("founder_first_name")
523
+ founderLastName String? @map("founder_last_name")
505
524
  founderEmail String @map("founder_email")
525
+ // #5407 — the founder's phone, collected on the default contact screen
526
+ // alongside the email (samhenry spec 316 D1). Nullable at rest for the
527
+ // #5036 D1 reason AND permanently: a row written before #5407 has none, and
528
+ // a site may declare the question optional through its own config.
529
+ //
530
+ // NEVER on the public read: `projectListingPublicSchema` omits it beside
531
+ // `founderEmail`. The address on this row is a legal control a visitor is
532
+ // owed; a phone number is a contact detail nobody outside the operator is.
533
+ founderPhone String? @map("founder_phone")
534
+ // #5407 — sha-256 of the EMAIL VERIFICATION NONCE, never the nonce itself.
535
+ //
536
+ // A second credential beside `resumeTokenHash`, and the reason
537
+ // `emailVerifiedAt` below means what its name says. The resume token is
538
+ // returned to WHOEVER POSTED `start`'s FORM, so presenting it proves only
539
+ // that you opened the draft. This nonce is minted at `start`, digested
540
+ // here, and handed to nothing except the resume-email builder
541
+ // (`services/project-listing-resume-email.ts`): it is never in a response
542
+ // body, never in a log, and never in the browser that filled the form. The
543
+ // only way to hold it is to have read mail sent to `founder_email`.
544
+ //
545
+ // Null on every row written before #5407, and on every row whose site has
546
+ // not switched the resume email on — there the nonce exists and is simply
547
+ // never delivered, so nothing can verify, which is the correct outcome.
548
+ // Cleared at `submit` beside `resumeTokenHash`, for the same reason: a
549
+ // credential that leaks after the draft stops being a draft is inert twice
550
+ // over.
551
+ emailVerifyNonceHash String? @unique @map("email_verify_nonce_hash")
552
+ // #5407 — when the founder proved control of `founder_email`, by opening
553
+ // the link mailed to it.
554
+ //
555
+ // WRITE-ONCE. `verifyProjectListingDraftEmail` sets it only where it is
556
+ // still null, so a founder who opens the link five times is stamped with
557
+ // the FIRST opening rather than the latest.
558
+ //
559
+ // WHAT IT PROVES, and its exact limit. The stamp requires the nonce above,
560
+ // which left this server only inside the email. So it says the holder can
561
+ // read mail sent to `founder_email` — which is the whole of what "email
562
+ // verified" claims. It says nothing about WHO they are: `owner_user_id`
563
+ // (#5295) is the column that carries an identity claim, and it still needs
564
+ // a signed-in user whose own address the auth system verified. A row can
565
+ // carry either, both, or neither.
566
+ //
567
+ // Permanently nullable, and NOT a backfill target. Every row written before
568
+ // #5407 predates the stamp; asserting verification on one would assert
569
+ // exactly the thing nobody proved. Null means "not verified", never
570
+ // "verification failed", and it is also what a site running no resume email
571
+ // reads forever.
572
+ emailVerifiedAt DateTime? @map("email_verified_at")
506
573
  founderCompany String? @map("founder_company")
507
574
  status String
508
575
  // #5036 D1/D6 — when the founder ticked step one's consent box. Never null: