create-ailk 0.24.0 → 0.26.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 (638) hide show
  1. package/README.md +53 -22
  2. package/component-catalog.json +3 -3
  3. package/component-catalog.md +3 -3
  4. package/dist/add-module.js +4 -2
  5. package/dist/add-route.d.ts +12 -1
  6. package/dist/add-route.js +31 -3
  7. package/dist/cli.js +12 -7
  8. package/dist/derive-architecture.d.ts +3 -4
  9. package/dist/derive-architecture.js +65 -29
  10. package/dist/lib/design-checks.d.ts +9 -4
  11. package/dist/lib/design-checks.js +13 -7
  12. package/dist/lib/extract-module-bundle.js +29 -2
  13. package/dist/lib/fetch-template-snapshot.d.ts +2 -1
  14. package/dist/lib/fetch-template-snapshot.js +8 -3
  15. package/dist/lib/import-graph.d.ts +1 -1
  16. package/dist/lib/import-graph.js +4 -4
  17. package/dist/lib/module-license-gate.d.ts +12 -1
  18. package/dist/lib/module-license-gate.js +36 -15
  19. package/dist/lib/module-tier.d.ts +2 -8
  20. package/dist/lib/module-tier.js +13 -12
  21. package/dist/module-architecture.d.ts +20 -3
  22. package/dist/module-architecture.js +129 -552
  23. package/dist/paid-sections.d.ts +25 -1
  24. package/dist/paid-sections.js +88 -3
  25. package/dist/starter-grid.d.ts +6 -6
  26. package/dist/starter-grid.js +12 -5
  27. package/dist/surfaces.js +39 -2
  28. package/dist/template-record.d.ts +21 -3
  29. package/dist/template-record.js +38 -7
  30. package/dist/topology.d.ts +16 -3
  31. package/dist/topology.js +54 -23
  32. package/dist/update.d.ts +10 -1
  33. package/dist/update.js +715 -21
  34. package/package.json +3 -3
  35. package/release-scope.json +2 -2
  36. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +8 -2
  37. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +2 -2
  38. package/site-templates/marketing-site/ailk-template.json +7 -1
  39. package/site-templates/marketing-site/provenance.json +7 -1
  40. package/site-templates/saas-product/ailk-template.json +2 -1
  41. package/site-templates/saas-product/provenance.json +1 -0
  42. package/templates/.claude/cloudparity-repo-hooks.json +5 -0
  43. package/templates/.claude/hooks/template-guard.sh +137 -0
  44. package/templates/.claude/rules/extending.md +106 -0
  45. package/templates/.claude/rules/loop-contract.md +2 -2
  46. package/templates/.claude/settings.json +11 -0
  47. package/templates/.env.example +20 -5
  48. package/templates/.github/workflows/ci.yml +7 -4
  49. package/templates/CLAUDE.md +11 -1
  50. package/templates/CONVENTIONS.md +8 -10
  51. package/templates/README.md +14 -13
  52. package/templates/apps/api/.env.example +23 -2
  53. package/templates/apps/api/CLAUDE.md +119 -83
  54. package/templates/apps/api/jest.config.cjs +15 -5
  55. package/templates/apps/api/package.json +16 -20
  56. package/templates/apps/api/src/__tests__/trusted-origins.server.test.ts +2 -2
  57. package/templates/apps/api/src/__tests__/vercel-handler.test.ts +4 -4
  58. package/templates/apps/api/src/index.ts +1 -1
  59. package/templates/apps/api/src/lib/__mocks__/prisma-client.js +16 -0
  60. package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -3
  61. package/templates/apps/api/src/modules/commerce.ts +10 -0
  62. package/templates/apps/api/src/modules/content-write.ts +10 -0
  63. package/templates/apps/api/src/modules/multi-tenant.ts +10 -0
  64. package/templates/apps/api/src/modules/scheduling.ts +10 -0
  65. package/templates/apps/api/src/modules/signal-collectors.ts +10 -0
  66. package/templates/apps/api/src/modules/workspace.ts +10 -0
  67. package/templates/apps/api/src/server.ts +117 -1882
  68. package/templates/apps/api/vercel.json +2 -2
  69. package/templates/apps/mcp/CLAUDE.md +90 -26
  70. package/templates/apps/mcp/__tests__/app-entry.test.ts +4 -254
  71. package/templates/apps/mcp/__tests__/boot-file.test.ts +92 -0
  72. package/templates/apps/mcp/jest.config.cjs +6 -1
  73. package/templates/apps/mcp/package.json +5 -13
  74. package/templates/apps/mcp/src/app.ts +8 -7
  75. package/templates/apps/mcp/src/index.ts +6 -34
  76. package/templates/apps/mcp/src/lib/paid-tools.generated.ts +10 -0
  77. package/templates/apps/mcp/src/lib/topology.generated.ts +2 -2
  78. package/templates/apps/mcp/src/site.ts +12 -0
  79. package/templates/apps/web/.env.example +1 -1
  80. package/templates/apps/web/CLAUDE.md +31 -3
  81. package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
  82. package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +43 -4
  83. package/templates/apps/web/app/[locale]/(auth)/legal-footnote.tsx +35 -0
  84. package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +117 -8
  85. package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +14 -37
  86. package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +6 -6
  87. package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-text.ts +20 -35
  88. package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/page.test.tsx +108 -0
  89. package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +111 -5
  90. package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +78 -16
  91. package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +132 -12
  92. package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +53 -1
  93. package/templates/apps/web/app/[locale]/(authed)/account/__tests__/billing.test.tsx +38 -0
  94. package/templates/apps/web/app/[locale]/(authed)/account/billing/page.tsx +4 -2
  95. package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +47 -24
  96. package/templates/apps/web/app/[locale]/(authed)/signed-out-gate.generated.tsx +23 -4
  97. package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
  98. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +22 -1
  99. package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +7 -3
  100. package/templates/apps/web/app/[locale]/layout.tsx +33 -13
  101. package/templates/apps/web/app/[locale]/meet/confirmed/BookingHandOff.tsx +128 -0
  102. package/templates/apps/web/app/[locale]/meet/confirmed/__tests__/BookingHandOff.test.tsx +126 -0
  103. package/templates/apps/web/app/[locale]/pricing/__tests__/unconnected.test.tsx +43 -0
  104. package/templates/apps/web/app/[locale]/pricing/page.tsx +7 -3
  105. package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/__tests__/route.test.ts +222 -0
  106. package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +10 -3
  107. package/templates/apps/web/app/api/revalidate/route.ts +3 -3
  108. package/templates/apps/web/auth.ts +10 -6
  109. package/templates/apps/web/i18n/request.ts +49 -1
  110. package/templates/apps/web/jest.config.cjs +1 -0
  111. package/templates/apps/web/lib/__tests__/account-config.test.ts +7 -0
  112. package/templates/apps/web/lib/__tests__/auth-email.test.ts +276 -0
  113. package/templates/apps/web/lib/auth-email.ts +103 -21
  114. package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +72 -23
  115. package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +94 -70
  116. package/templates/apps/web/lib/prisma-for-auth.ts +5 -2
  117. package/templates/apps/web/lib/relay.ts +2 -2
  118. package/templates/apps/web/lib/release-scope.ts +47 -0
  119. package/templates/apps/web/lib/server-api.ts +1 -1
  120. package/templates/apps/web/lib/sign-up-agreements.ts +291 -28
  121. package/templates/apps/web/lib/site-contributions.ts +18 -0
  122. package/templates/apps/web/messages/en.json +186 -20
  123. package/templates/apps/web/messages/site/en.json +1 -0
  124. package/templates/apps/web/src/lib/commerce-claim.ts +1 -1
  125. package/templates/customizations.yaml +37 -0
  126. package/templates/database/prisma.config.ts +10 -14
  127. package/templates/database/seed-test.ts +2 -2
  128. package/templates/database/seed.ts +5 -5
  129. package/templates/package.json +12 -6
  130. package/templates/pnpm-workspace.yaml +0 -1
  131. package/templates/project.yaml +16 -8
  132. package/templates/tools/jest/reporters.cjs +65 -0
  133. package/templates/tools/lint-architecture.ts +553 -7
  134. package/templates/tsconfig.json +1 -2
  135. package/versions.json +49 -36
  136. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +0 -409
  137. package/templates/apps/api/src/__tests__/factories/agent-caller.ts +0 -102
  138. package/templates/apps/api/src/__tests__/factories/content-fixture.ts +0 -138
  139. package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +0 -441
  140. package/templates/apps/api/src/__tests__/factories/index.ts +0 -70
  141. package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +0 -82
  142. package/templates/apps/api/src/__tests__/leads-forwarded-rate-limit.test.ts +0 -135
  143. package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +0 -126
  144. package/templates/apps/api/src/__tests__/stripe-boot.test.ts +0 -132
  145. package/templates/apps/api/src/__tests__/support/hub-sign-in-fake-db.ts +0 -362
  146. package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +0 -184
  147. package/templates/apps/api/src/bin/abandon-sweep.ts +0 -42
  148. package/templates/apps/api/src/bin/rate-limit-probe.ts +0 -53
  149. package/templates/apps/api/src/bin/spokes.ts +0 -198
  150. package/templates/apps/api/src/bin/stripe-connections-rekey.ts +0 -45
  151. package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +0 -196
  152. package/templates/apps/api/src/config/__tests__/index.test.ts +0 -233
  153. package/templates/apps/api/src/config/__tests__/modules.test.ts +0 -76
  154. package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +0 -185
  155. package/templates/apps/api/src/config/__tests__/trusted-origins.test.ts +0 -238
  156. package/templates/apps/api/src/config/index.ts +0 -596
  157. package/templates/apps/api/src/config/modules.ts +0 -83
  158. package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +0 -581
  159. package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +0 -143
  160. package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +0 -237
  161. package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +0 -353
  162. package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +0 -201
  163. package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +0 -224
  164. package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +0 -120
  165. package/templates/apps/api/src/lib/__tests__/errors.test.ts +0 -94
  166. package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +0 -144
  167. package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +0 -8
  168. package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +0 -149
  169. package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +0 -116
  170. package/templates/apps/api/src/lib/__tests__/hub-sign-in-store.test.ts +0 -209
  171. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +0 -257
  172. package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +0 -96
  173. package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +0 -125
  174. package/templates/apps/api/src/lib/__tests__/prisma.test.ts +0 -165
  175. package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +0 -317
  176. package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +0 -129
  177. package/templates/apps/api/src/lib/__tests__/site.test.ts +0 -308
  178. package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +0 -89
  179. package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +0 -202
  180. package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +0 -217
  181. package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -82
  182. package/templates/apps/api/src/lib/agent-store.ts +0 -613
  183. package/templates/apps/api/src/lib/auth-email-budget.ts +0 -161
  184. package/templates/apps/api/src/lib/consent-store.ts +0 -363
  185. package/templates/apps/api/src/lib/content-adapter.ts +0 -112
  186. package/templates/apps/api/src/lib/deliverable-asset-store.ts +0 -96
  187. package/templates/apps/api/src/lib/error-serializer.ts +0 -164
  188. package/templates/apps/api/src/lib/errors.ts +0 -95
  189. package/templates/apps/api/src/lib/file-fallback.ts +0 -87
  190. package/templates/apps/api/src/lib/flow-completion-store.ts +0 -136
  191. package/templates/apps/api/src/lib/hub-sign-in-store.ts +0 -455
  192. package/templates/apps/api/src/lib/lead-capture-store.ts +0 -122
  193. package/templates/apps/api/src/lib/lead-delivery.ts +0 -52
  194. package/templates/apps/api/src/lib/license-key-store.ts +0 -45
  195. package/templates/apps/api/src/lib/locales.ts +0 -201
  196. package/templates/apps/api/src/lib/outbound-http.ts +0 -127
  197. package/templates/apps/api/src/lib/prisma.ts +0 -21
  198. package/templates/apps/api/src/lib/proposal-paid-store.ts +0 -66
  199. package/templates/apps/api/src/lib/rate-limit-probe.ts +0 -165
  200. package/templates/apps/api/src/lib/rate-limit-store.ts +0 -142
  201. package/templates/apps/api/src/lib/require-commerce-claim.ts +0 -250
  202. package/templates/apps/api/src/lib/require-paid-tier.ts +0 -53
  203. package/templates/apps/api/src/lib/site.ts +0 -257
  204. package/templates/apps/api/src/lib/slice-load.ts +0 -90
  205. package/templates/apps/api/src/lib/spoke-store.ts +0 -180
  206. package/templates/apps/api/src/lib/stripe.ts +0 -321
  207. package/templates/apps/api/src/lib/webhook-idempotency.ts +0 -156
  208. package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +0 -111
  209. package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +0 -172
  210. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +0 -119
  211. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +0 -138
  212. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-trusted-origins.test.ts +0 -142
  213. package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +0 -155
  214. package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +0 -139
  215. package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +0 -562
  216. package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +0 -76
  217. package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +0 -220
  218. package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +0 -97
  219. package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +0 -557
  220. package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +0 -72
  221. package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +0 -140
  222. package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +0 -721
  223. package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +0 -220
  224. package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +0 -430
  225. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +0 -1409
  226. package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +0 -174
  227. package/templates/apps/api/src/middleware/auth.ts +0 -864
  228. package/templates/apps/api/src/middleware/default-tenant.ts +0 -166
  229. package/templates/apps/api/src/middleware/rate-limit.ts +0 -983
  230. package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +0 -391
  231. package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +0 -182
  232. package/templates/apps/api/src/openapi/index.ts +0 -18
  233. package/templates/apps/api/src/openapi/spec.ts +0 -2148
  234. package/templates/apps/api/src/openapi/surface-drift.ts +0 -195
  235. package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +0 -175
  236. package/templates/apps/api/src/routes/aeo/index.ts +0 -107
  237. package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +0 -196
  238. package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +0 -249
  239. package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +0 -532
  240. package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +0 -313
  241. package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +0 -413
  242. package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +0 -609
  243. package/templates/apps/api/src/routes/auth/hub-sign-in.ts +0 -242
  244. package/templates/apps/api/src/routes/auth/tokens.ts +0 -211
  245. package/templates/apps/api/src/routes/auth/transactional-email.ts +0 -301
  246. package/templates/apps/api/src/routes/auth/user.ts +0 -305
  247. package/templates/apps/api/src/routes/billing/plan-checkout.ts +0 -332
  248. package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +0 -178
  249. package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +0 -1426
  250. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +0 -448
  251. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -1742
  252. package/templates/apps/api/src/routes/checkout/index.ts +0 -34
  253. package/templates/apps/api/src/routes/checkout/session.ts +0 -171
  254. package/templates/apps/api/src/routes/checkout/sessions.ts +0 -540
  255. package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +0 -386
  256. package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +0 -160
  257. package/templates/apps/api/src/routes/consent/account.ts +0 -268
  258. package/templates/apps/api/src/routes/consent/cookie.ts +0 -90
  259. package/templates/apps/api/src/routes/consent/index.ts +0 -26
  260. package/templates/apps/api/src/routes/consent/unsubscribe.ts +0 -127
  261. package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +0 -853
  262. package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +0 -230
  263. package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +0 -44
  264. package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +0 -118
  265. package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +0 -731
  266. package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +0 -753
  267. package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +0 -51
  268. package/templates/apps/api/src/routes/content/__tests__/search.test.ts +0 -450
  269. package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +0 -762
  270. package/templates/apps/api/src/routes/content/get-page.ts +0 -183
  271. package/templates/apps/api/src/routes/content/index.ts +0 -49
  272. package/templates/apps/api/src/routes/content/list-pages.ts +0 -74
  273. package/templates/apps/api/src/routes/content/list-types.ts +0 -19
  274. package/templates/apps/api/src/routes/content/offerings.ts +0 -184
  275. package/templates/apps/api/src/routes/content/pricing.ts +0 -176
  276. package/templates/apps/api/src/routes/content/rate-limit.ts +0 -22
  277. package/templates/apps/api/src/routes/content/search.ts +0 -100
  278. package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
  279. package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +0 -88
  280. package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +0 -171
  281. package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +0 -515
  282. package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +0 -392
  283. package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +0 -165
  284. package/templates/apps/api/src/routes/leads/index.ts +0 -639
  285. package/templates/apps/api/src/routes/leads/list.ts +0 -104
  286. package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +0 -626
  287. package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +0 -1268
  288. package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +0 -847
  289. package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +0 -491
  290. package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -476
  291. package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +0 -872
  292. package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +0 -1022
  293. package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +0 -484
  294. package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +0 -535
  295. package/templates/apps/api/src/routes/project-listings/index.ts +0 -164
  296. package/templates/apps/api/src/routes/project-listings/me.ts +0 -87
  297. package/templates/apps/api/src/routes/project-listings/patch-copy.ts +0 -224
  298. package/templates/apps/api/src/routes/project-listings/patch-draft.ts +0 -102
  299. package/templates/apps/api/src/routes/project-listings/public.ts +0 -98
  300. package/templates/apps/api/src/routes/project-listings/respond.ts +0 -48
  301. package/templates/apps/api/src/routes/project-listings/resume-token.ts +0 -27
  302. package/templates/apps/api/src/routes/project-listings/start.ts +0 -140
  303. package/templates/apps/api/src/routes/project-listings/submit.ts +0 -130
  304. package/templates/apps/api/src/routes/project-listings/verify-email.ts +0 -150
  305. package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +0 -686
  306. package/templates/apps/api/src/routes/requests/confirm.ts +0 -601
  307. package/templates/apps/api/src/routes/requests/index.ts +0 -54
  308. package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +0 -306
  309. package/templates/apps/api/src/routes/test/auth/session.ts +0 -143
  310. package/templates/apps/api/src/routes/webhooks/README.md +0 -398
  311. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +0 -649
  312. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +0 -749
  313. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -449
  314. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -264
  315. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +0 -159
  316. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +0 -158
  317. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +0 -814
  318. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -301
  319. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +0 -369
  320. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -215
  321. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +0 -301
  322. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +0 -809
  323. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -1155
  324. package/templates/apps/api/src/routes/webhooks/index.ts +0 -141
  325. package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +0 -384
  326. package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -2028
  327. package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -645
  328. package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +0 -132
  329. package/templates/apps/api/src/services/__tests__/audit-log.test.ts +0 -1028
  330. package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +0 -313
  331. package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +0 -503
  332. package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +0 -65
  333. package/templates/apps/api/src/services/__tests__/consent.test.ts +0 -299
  334. package/templates/apps/api/src/services/__tests__/default-tenant.test.ts +0 -147
  335. package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +0 -877
  336. package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +0 -379
  337. package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +0 -368
  338. package/templates/apps/api/src/services/__tests__/entitlements.test.ts +0 -142
  339. package/templates/apps/api/src/services/__tests__/hub-sign-in.test.ts +0 -854
  340. package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +0 -234
  341. package/templates/apps/api/src/services/__tests__/lead-accept-user.test.ts +0 -251
  342. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +0 -2660
  343. package/templates/apps/api/src/services/__tests__/listing-config.test.ts +0 -166
  344. package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +0 -389
  345. package/templates/apps/api/src/services/__tests__/person.test.ts +0 -1204
  346. package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -450
  347. package/templates/apps/api/src/services/__tests__/project-listings.counts.test.ts +0 -202
  348. package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -151
  349. package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +0 -137
  350. package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +0 -531
  351. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +0 -372
  352. package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +0 -348
  353. package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +0 -660
  354. package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +0 -941
  355. package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +0 -588
  356. package/templates/apps/api/src/services/__tests__/verified-email.test.ts +0 -78
  357. package/templates/apps/api/src/services/abandon-email.ts +0 -336
  358. package/templates/apps/api/src/services/aeo-score.ts +0 -325
  359. package/templates/apps/api/src/services/answer-distributions.ts +0 -138
  360. package/templates/apps/api/src/services/audit-log.ts +0 -961
  361. package/templates/apps/api/src/services/checkout-buyer.ts +0 -168
  362. package/templates/apps/api/src/services/consent.ts +0 -834
  363. package/templates/apps/api/src/services/default-tenant.ts +0 -416
  364. package/templates/apps/api/src/services/deliverable-fulfillment.ts +0 -750
  365. package/templates/apps/api/src/services/dunning-policy.ts +0 -294
  366. package/templates/apps/api/src/services/enrichment-shim.ts +0 -53
  367. package/templates/apps/api/src/services/entitlements.ts +0 -338
  368. package/templates/apps/api/src/services/hub-sign-in.ts +0 -472
  369. package/templates/apps/api/src/services/lead-accept-user.ts +0 -126
  370. package/templates/apps/api/src/services/lead-promotion.ts +0 -160
  371. package/templates/apps/api/src/services/lead-routing.ts +0 -1372
  372. package/templates/apps/api/src/services/leads-inbox.ts +0 -312
  373. package/templates/apps/api/src/services/listing-config.ts +0 -178
  374. package/templates/apps/api/src/services/magnet-completion.ts +0 -242
  375. package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +0 -348
  376. package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +0 -268
  377. package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +0 -975
  378. package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +0 -416
  379. package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +0 -400
  380. package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -685
  381. package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
  382. package/templates/apps/api/src/services/offerings/catalog.ts +0 -318
  383. package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -403
  384. package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
  385. package/templates/apps/api/src/services/offerings/connection.ts +0 -1083
  386. package/templates/apps/api/src/services/offerings/index.ts +0 -614
  387. package/templates/apps/api/src/services/offerings/source.ts +0 -140
  388. package/templates/apps/api/src/services/offerings/store.ts +0 -150
  389. package/templates/apps/api/src/services/owner-workspaces.ts +0 -132
  390. package/templates/apps/api/src/services/person.ts +0 -1211
  391. package/templates/apps/api/src/services/plan-offerings.ts +0 -125
  392. package/templates/apps/api/src/services/project-listing-resume-email.ts +0 -326
  393. package/templates/apps/api/src/services/project-listings.ts +0 -2085
  394. package/templates/apps/api/src/services/public-site-resolver.ts +0 -396
  395. package/templates/apps/api/src/services/request-confirm.ts +0 -698
  396. package/templates/apps/api/src/services/revalidation.ts +0 -235
  397. package/templates/apps/api/src/services/slack-notify.ts +0 -291
  398. package/templates/apps/api/src/services/usage-aggregation.ts +0 -516
  399. package/templates/apps/api/src/services/usage-credits.ts +0 -340
  400. package/templates/apps/api/src/services/verified-email.ts +0 -71
  401. package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +0 -52
  402. package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +0 -46
  403. package/templates/apps/mcp/__tests__/abuse/guard.test.ts +0 -198
  404. package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +0 -36
  405. package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +0 -54
  406. package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +0 -116
  407. package/templates/apps/mcp/__tests__/audit-single-page.test.ts +0 -299
  408. package/templates/apps/mcp/__tests__/boot.test.ts +0 -280
  409. package/templates/apps/mcp/__tests__/catalog-drift.test.ts +0 -359
  410. package/templates/apps/mcp/__tests__/config/modules.test.ts +0 -78
  411. package/templates/apps/mcp/__tests__/get_business_hours.test.ts +0 -82
  412. package/templates/apps/mcp/__tests__/get_faq.test.ts +0 -80
  413. package/templates/apps/mcp/__tests__/get_locations.test.ts +0 -65
  414. package/templates/apps/mcp/__tests__/get_offerings.test.ts +0 -557
  415. package/templates/apps/mcp/__tests__/get_pricing.test.ts +0 -524
  416. package/templates/apps/mcp/__tests__/get_site_info.test.ts +0 -81
  417. package/templates/apps/mcp/__tests__/http-transport.test.ts +0 -1232
  418. package/templates/apps/mcp/__tests__/index.test.ts +0 -195
  419. package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +0 -191
  420. package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +0 -531
  421. package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +0 -70
  422. package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -162
  423. package/templates/apps/mcp/__tests__/lib/content-root.test.ts +0 -93
  424. package/templates/apps/mcp/__tests__/lib/errors.test.ts +0 -75
  425. package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +0 -180
  426. package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
  427. package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -268
  428. package/templates/apps/mcp/__tests__/locale.test.ts +0 -120
  429. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +0 -175
  430. package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +0 -101
  431. package/templates/apps/mcp/__tests__/rate-limit-write.test.ts +0 -189
  432. package/templates/apps/mcp/__tests__/read_content.test.ts +0 -511
  433. package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -160
  434. package/templates/apps/mcp/__tests__/search_content.test.ts +0 -271
  435. package/templates/apps/mcp/__tests__/server.test.ts +0 -388
  436. package/templates/apps/mcp/__tests__/start_purchase.test.ts +0 -448
  437. package/templates/apps/mcp/__tests__/submit_lead.test.ts +0 -222
  438. package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -152
  439. package/templates/apps/mcp/__tests__/tools/create_project.test.ts +0 -243
  440. package/templates/apps/mcp/__tests__/tools/purchase.test.ts +0 -451
  441. package/templates/apps/mcp/src/abuse/daily-cap.ts +0 -47
  442. package/templates/apps/mcp/src/abuse/email-validator.ts +0 -25
  443. package/templates/apps/mcp/src/abuse/honeypot.ts +0 -21
  444. package/templates/apps/mcp/src/abuse/index.ts +0 -349
  445. package/templates/apps/mcp/src/abuse/user-agent-deny.ts +0 -58
  446. package/templates/apps/mcp/src/boot.ts +0 -167
  447. package/templates/apps/mcp/src/config/modules.ts +0 -43
  448. package/templates/apps/mcp/src/http-transport.ts +0 -564
  449. package/templates/apps/mcp/src/lib/audit-single-page.ts +0 -308
  450. package/templates/apps/mcp/src/lib/commerce-claim.ts +0 -263
  451. package/templates/apps/mcp/src/lib/content-adapter.ts +0 -116
  452. package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -140
  453. package/templates/apps/mcp/src/lib/errors.ts +0 -61
  454. package/templates/apps/mcp/src/lib/license-key-store.ts +0 -45
  455. package/templates/apps/mcp/src/lib/locales.ts +0 -171
  456. package/templates/apps/mcp/src/lib/prisma.ts +0 -39
  457. package/templates/apps/mcp/src/lib/public-workspace.ts +0 -133
  458. package/templates/apps/mcp/src/lib/resolve-locale.ts +0 -30
  459. package/templates/apps/mcp/src/lib/shown-offerings.ts +0 -105
  460. package/templates/apps/mcp/src/lib/site-config.ts +0 -53
  461. package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +0 -59
  462. package/templates/apps/mcp/src/request-context.ts +0 -52
  463. package/templates/apps/mcp/src/server.ts +0 -343
  464. package/templates/apps/mcp/src/serverless-app.ts +0 -88
  465. package/templates/apps/mcp/src/tools/audit.ts +0 -127
  466. package/templates/apps/mcp/src/tools/capture_lead.ts +0 -66
  467. package/templates/apps/mcp/src/tools/create_project.ts +0 -134
  468. package/templates/apps/mcp/src/tools/get_business_hours.ts +0 -68
  469. package/templates/apps/mcp/src/tools/get_faq.ts +0 -71
  470. package/templates/apps/mcp/src/tools/get_locations.ts +0 -88
  471. package/templates/apps/mcp/src/tools/get_offerings.ts +0 -96
  472. package/templates/apps/mcp/src/tools/get_pricing.ts +0 -94
  473. package/templates/apps/mcp/src/tools/get_site_info.ts +0 -86
  474. package/templates/apps/mcp/src/tools/index.ts +0 -138
  475. package/templates/apps/mcp/src/tools/list_pages.ts +0 -68
  476. package/templates/apps/mcp/src/tools/person_notes.ts +0 -25
  477. package/templates/apps/mcp/src/tools/proposals.ts +0 -27
  478. package/templates/apps/mcp/src/tools/purchase.ts +0 -205
  479. package/templates/apps/mcp/src/tools/read_content.ts +0 -81
  480. package/templates/apps/mcp/src/tools/request_callback.ts +0 -52
  481. package/templates/apps/mcp/src/tools/search_content.ts +0 -63
  482. package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -54
  483. package/templates/apps/mcp/src/workspace-server.ts +0 -224
  484. package/templates/database/CHANGELOG.md +0 -981
  485. package/templates/database/LICENSE +0 -202
  486. package/templates/database/NOTICE +0 -2
  487. package/templates/database/README.md +0 -243
  488. package/templates/database/__tests__/agents.db.test.ts +0 -320
  489. package/templates/database/__tests__/appointment.db.test.ts +0 -106
  490. package/templates/database/__tests__/artifact-content-store.db.test.ts +0 -316
  491. package/templates/database/__tests__/composite-fence.db.test.ts +0 -206
  492. package/templates/database/__tests__/consent-ledger.db.test.ts +0 -345
  493. package/templates/database/__tests__/consent-source-checkout-migration.test.ts +0 -79
  494. package/templates/database/__tests__/fence-fan-out.db.test.ts +0 -715
  495. package/templates/database/__tests__/fixtures/appointment-create-probe.ts +0 -79
  496. package/templates/database/__tests__/fixtures/person-backfill.json +0 -264
  497. package/templates/database/__tests__/fixtures/person-contact-backfill.json +0 -182
  498. package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +0 -100
  499. package/templates/database/__tests__/flow-completion-migration.test.ts +0 -115
  500. package/templates/database/__tests__/flow-completion.db.test.ts +0 -136
  501. package/templates/database/__tests__/flow-workspace-key.db.test.ts +0 -263
  502. package/templates/database/__tests__/flows-listing-diagnostic.test.ts +0 -392
  503. package/templates/database/__tests__/flows-presets.test.ts +0 -173
  504. package/templates/database/__tests__/in-page-magnets-migration.test.ts +0 -161
  505. package/templates/database/__tests__/lead-idempotency-key.db.test.ts +0 -92
  506. package/templates/database/__tests__/member-area.db.test.ts +0 -257
  507. package/templates/database/__tests__/member-contract-migration.test.ts +0 -85
  508. package/templates/database/__tests__/member-contract.db.test.ts +0 -413
  509. package/templates/database/__tests__/offerings-checkout-session.db.test.ts +0 -270
  510. package/templates/database/__tests__/offerings-migration.test.ts +0 -197
  511. package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +0 -86
  512. package/templates/database/__tests__/offerings.db.test.ts +0 -303
  513. package/templates/database/__tests__/outbound-message-action.db.test.ts +0 -80
  514. package/templates/database/__tests__/person-contact.db.test.ts +0 -563
  515. package/templates/database/__tests__/person-notes.db.test.ts +0 -249
  516. package/templates/database/__tests__/person.db.test.ts +0 -586
  517. package/templates/database/__tests__/piece-kind-migration.test.ts +0 -67
  518. package/templates/database/__tests__/piece-kind.db.test.ts +0 -208
  519. package/templates/database/__tests__/prefixed-ids.db.test.ts +0 -222
  520. package/templates/database/__tests__/project-listing-consent-at.db.test.ts +0 -111
  521. package/templates/database/__tests__/seed.test.ts +0 -272
  522. package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
  523. package/templates/database/__tests__/tenancy.test.ts +0 -141
  524. package/templates/database/__tests__/trial-magnet-migration.test.ts +0 -186
  525. package/templates/database/__tests__/user-cascade.test.ts +0 -140
  526. package/templates/database/_gitignore +0 -8
  527. package/templates/database/auth/.gitkeep +0 -0
  528. package/templates/database/auth/schema.prisma +0 -641
  529. package/templates/database/config/.gitkeep +0 -0
  530. package/templates/database/config/schema.prisma +0 -441
  531. package/templates/database/content/.gitkeep +0 -0
  532. package/templates/database/content/schema.prisma +0 -339
  533. package/templates/database/eslint.config.mjs +0 -69
  534. package/templates/database/flows/listing-diagnostic.ts +0 -182
  535. package/templates/database/flows/presets.ts +0 -315
  536. package/templates/database/inbox/.gitkeep +0 -0
  537. package/templates/database/inbox/README.md +0 -3
  538. package/templates/database/inbox/__tests__/schema.test.ts +0 -44
  539. package/templates/database/inbox/schema.prisma +0 -1447
  540. package/templates/database/jest.config.cjs +0 -36
  541. package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +0 -328
  542. package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +0 -100
  543. package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +0 -28
  544. package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +0 -25
  545. package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +0 -42
  546. package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +0 -67
  547. package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +0 -21
  548. package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +0 -201
  549. package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +0 -67
  550. package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +0 -46
  551. package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +0 -25
  552. package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +0 -49
  553. package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +0 -197
  554. package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +0 -32
  555. package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +0 -22
  556. package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +0 -151
  557. package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +0 -223
  558. package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +0 -22
  559. package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +0 -32
  560. package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +0 -40
  561. package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +0 -4
  562. package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +0 -2
  563. package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +0 -2
  564. package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +0 -29
  565. package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +0 -6
  566. package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +0 -39
  567. package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +0 -24
  568. package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +0 -3
  569. package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +0 -33
  570. package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +0 -30
  571. package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +0 -47
  572. package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +0 -16
  573. package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +0 -47
  574. package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +0 -10
  575. package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +0 -26
  576. package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +0 -90
  577. package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +0 -174
  578. package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +0 -14
  579. package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +0 -25
  580. package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +0 -32
  581. package/templates/database/migrations/20260911180000_consent_grants/migration.sql +0 -71
  582. package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +0 -30
  583. package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +0 -49
  584. package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +0 -123
  585. package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +0 -15
  586. package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +0 -158
  587. package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +0 -40
  588. package/templates/database/migrations/20260918120000_add_appointment/migration.sql +0 -67
  589. package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +0 -70
  590. package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +0 -181
  591. package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +0 -172
  592. package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +0 -41
  593. package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +0 -185
  594. package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +0 -70
  595. package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +0 -57
  596. package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +0 -68
  597. package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +0 -1067
  598. package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +0 -210
  599. package/templates/database/migrations/20261003120000_spoke_registry/migration.sql +0 -80
  600. package/templates/database/migrations/20261003130000_scheduling_connection/migration.sql +0 -49
  601. package/templates/database/migrations/20261005120000_agents/migration.sql +0 -84
  602. package/templates/database/migrations/20261008120000_user_last_workspace/migration.sql +0 -35
  603. package/templates/database/migrations/20261008130000_lead_idempotency_key/migration.sql +0 -20
  604. package/templates/database/migrations/20261009120000_agent_grants/migration.sql +0 -33
  605. package/templates/database/migrations/20261010120000_person/migration.sql +0 -106
  606. package/templates/database/migrations/20261010121000_person_backfill/migration.sql +0 -132
  607. package/templates/database/migrations/20261010130000_agent_grants_people_read/migration.sql +0 -20
  608. package/templates/database/migrations/20261011120000_member_area/migration.sql +0 -158
  609. package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql +0 -21
  610. package/templates/database/migrations/20261012120000_member_contract/migration.sql +0 -192
  611. package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +0 -20
  612. package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +0 -122
  613. package/templates/database/migrations/20261014120000_person_contact/migration.sql +0 -231
  614. package/templates/database/migrations/20261015120000_person_notes/migration.sql +0 -77
  615. package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +0 -43
  616. package/templates/database/migrations/20261016120000_piece_kind/migration.sql +0 -95
  617. package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +0 -30
  618. package/templates/database/migrations/20261018120000_flow_completion/migration.sql +0 -52
  619. package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +0 -27
  620. package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +0 -146
  621. package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +0 -77
  622. package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +0 -45
  623. package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +0 -47
  624. package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +0 -16
  625. package/templates/database/migrations/20261025120000_trial_magnet/migration.sql +0 -28
  626. package/templates/database/migrations/20261026120000_trial_magnet_proof_line/migration.sql +0 -23
  627. package/templates/database/migrations/migration_lock.toml +0 -3
  628. package/templates/database/ops/.gitkeep +0 -0
  629. package/templates/database/ops/schema.prisma +0 -43
  630. package/templates/database/package.json +0 -89
  631. package/templates/database/schema.prisma +0 -71
  632. package/templates/database/scripts/db-generate-locked.sh +0 -80
  633. package/templates/database/scripts/person-backfill.sql +0 -132
  634. package/templates/database/tenancy.ts +0 -183
  635. package/templates/database/tsconfig.build.json +0 -16
  636. package/templates/database/tsconfig.flows.json +0 -15
  637. package/templates/database/tsconfig.json +0 -16
  638. package/templates/database/tsconfig.tenancy.json +0 -14
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 2,
3
- "ignoreCommand": "[ -n \"$VERCEL_GIT_PREVIOUS_SHA\" ] && cd ../.. && git diff --quiet \"$VERCEL_GIT_PREVIOUS_SHA\" HEAD -- apps/api packages database pnpm-lock.yaml package.json pnpm-workspace.yaml turbo.json 'tsconfig*.json' || exit 1",
4
- "buildCommand": "cd ../.. && pnpm run --filter @working-theory/api build:vercel",
3
+ "ignoreCommand": "[ -n \"$VERCEL_GIT_PREVIOUS_SHA\" ] && cd ../.. && git diff --quiet \"$VERCEL_GIT_PREVIOUS_SHA\" HEAD -- apps/api packages packages-paid database pnpm-lock.yaml package.json pnpm-workspace.yaml turbo.json 'tsconfig*.json' || exit 1",
4
+ "buildCommand": "cd ../.. && pnpm run --filter @working-theory/app-api build:vercel",
5
5
  "installCommand": "cd ../.. && pnpm install --frozen-lockfile",
6
6
  "outputDirectory": "public",
7
7
  "framework": null,
@@ -8,10 +8,37 @@ Inherits root `CLAUDE.md`. This file adds MCP-specific rules.
8
8
  - Transport: stdio at launch
9
9
  - Discovery: `/.well-known/mcp.json` published from `apps/web`
10
10
 
11
+ ## The server is a package; this app is a boot set (#9460)
12
+
13
+ The server — the transports, the boot sequence, the abuse guard and the 15 free tools — is
14
+ `@working-theory/mcp-server` (`packages/mcp-server`), with two entry points: `.` and `./hub`.
15
+ Each paid module's tools ride that module's own package (`packages-paid/mcp-scheduling`,
16
+ `mcp-signal-collectors`, `mcp-workspace`), which base code reaches only through the generated
17
+ registry below. A version bump of those packages is the whole of taking an MCP change.
18
+
19
+ `src/` holds exactly five files, and nothing else may be added to it (`__tests__/boot-file.test.ts`
20
+ ships to every scaffold and fails on any other import):
21
+
22
+ - **`index.ts`** and **`app.ts`** — the two deployment entries (next section).
23
+ - **`site.ts`** — builds the `McpSite` the package runs for: `{ topology, paidToolPacks }`.
24
+ - **`lib/topology.generated.ts`** — the topology seam create-ailk renders (hub or spoke).
25
+ - **`lib/paid-tools.generated.ts`** — the paid MCP packs this site carries, one bundled
26
+ `import()` each, rendered by create-ailk from `MODULE_SLICES` (`paidMcpToolPackages`) and
27
+ `apps/mcp/package.json`; `// oss: false` on line 1 exactly when a pack is present. The
28
+ monorepo copy carries all three. A module-gated or signed-in tool resolves from the union of
29
+ the loaded packs at call time; a registered tool whose pack a site does not carry answers the
30
+ tool error `MCP slice drift: no installed package serves '<name>'`.
31
+
32
+ The suites that stay here are the composition root's: `api-parity`, `pro-tool-call-gate`,
33
+ `workspace-surface`, `write-tool-guard` and `create-booking-guard` (they call paid handlers through
34
+ the real `site.ts`), `app-entry` (the Vercel entry's source text) and `boot-file`. Everything else
35
+ runs in the package. Paths in the sections below that name `src/<file>` other than the five above
36
+ now mean `packages/mcp-server/src/<file>`.
37
+
11
38
  ## Two entrypoints, one boot (#8070)
12
39
 
13
40
  - **`src/index.ts`** — run locally: stdio (the default), or HTTP on `MCP_HTTP_PORT` with
14
- `MCP_TRANSPORT=http`.
41
+ `MCP_TRANSPORT=http`. It is `await runMcp(site)`; the transport branch is the package's `run.ts`.
15
42
  - **`src/app.ts`** — the Vercel entry. A Vercel project whose root directory is `apps/mcp`
16
43
  detects it (it imports Fastify) and calls its default export, `serverlessHandler(app)`: a
17
44
  `(req, res)` function, the shape Vercel's Node runtime runs — a bare Fastify instance is not
@@ -22,18 +49,30 @@ Inherits root `CLAUDE.md`. This file adds MCP-specific rules.
22
49
  reads it by static analysis). `tsconfig.json` names `module` and `moduleResolution` itself:
23
50
  Vercel's type-check edits the entry's nearest `tsconfig.json` as raw JSON before `extends`,
24
51
  and without its own `module` it switches `strict` off, which fails 11 narrowing sites.
25
- - Both call `bootMcp()` in `src/boot.ts` before building a transport, and read the HTTP
26
- configuration through `httpTransportConfigFromEnv()` there. Add a boot step to `bootMcp()`,
27
- never to one entry. `src/app.ts` stays thin; what a test needs is in `src/serverless-app.ts`.
52
+ - Both call the package's `bootMcp(site)` before building a transport, and the package reads the
53
+ HTTP configuration through `httpTransportConfigFromEnv()` (`packages/mcp-server/src/boot.ts`).
54
+ Add a boot step to `bootMcp()`, never to one entry. `src/app.ts` stays thin; what a test needs
55
+ is in the package's `serverless-app.ts`.
28
56
  - **`MCP_HTTP_STATELESS`** picks the transport mode: `true`/`1` stateless (no sessions; any
29
57
  instance answers), `false`/`0` stateful (sessions in one process's memory). Unset, the
30
58
  Vercel entry is stateless and `src/index.ts` is stateful. Any other value fails the boot.
31
59
  The Vercel entry needs stateless: a session kept in one instance is lost on the next.
32
60
  - **Content root.** Every content tool and `audit` take their root from `mcpContentRoot()`
33
61
  (`lib/content-adapter.ts`): `AILK_CONTENT_ROOT`, else `<cwd>/content`, else
34
- `<cwd>/../../content`. Never build a content path from `process.cwd()` in a tool.
62
+ `<cwd>/../../content`. Never build a content path from `process.cwd()` in a tool — the one
63
+ standing exception is `create_project`, whose `resolveCliBin()` has always spawned
64
+ `<cwd>/packages/create-ailk/dist/cli.js`; its release-scope read shares that root (next).
35
65
  - **`create_project`** is not served on a spoke: the generated seam's `UNSERVED_MCP_TOOLS`
36
- keeps it out of registration, and the web manifest drops the same list.
66
+ keeps it out of registration, and the web manifest drops the same list. It is also not
67
+ served while the Free level is held (#9534): it spawns a keyless scaffold, so
68
+ `isFreeLevelReleased()` (`tools/create_project.ts`) registers it only when
69
+ `<cwd>/packages/create-ailk/release-scope.json` marks `levels.free` released, and re-applies
70
+ that at call time. The contract that implies: the tool exists only in a monorepo checkout
71
+ started from the repo root — anywhere else the file is absent and so is the tool, where it
72
+ could not run anyway (no `dist/cli.js`). The scope FILE alone decides — a release-scope
73
+ decision, never a licence check, and the CLI's `AILK_RELEASE_SCOPE=ignore` bypass is not
74
+ honoured; a missing or unreadable file fails closed with one stderr line. apps/web's
75
+ `/.well-known/mcp.json` drops it on the same read (`apps/web/lib/release-scope.ts`).
37
76
 
38
77
  ### What a spoke's MCP host on Vercel enforces
39
78
 
@@ -81,21 +120,24 @@ Every tool maps 1:1 to an `apps/api` endpoint. When you change a tool, change th
81
120
  **Flow (2):** `get_flow`, `submit_flow_step` — module-gated (`module: "signal-collectors"`, D-48, #5366) and licence-feature-tagged (`feature: "flows-deliverables"`, #7136): identity-blind like every tool in this list, registered only when the signal-collectors module is present, and gated on the deployment's `flows-deliverables` licence feature under `MCP_FEATURE_GATE_MODE`, the same shape Booking below has. `submit_flow_step` takes the HTTP write branch (its own daily cap, `MCP_ABUSE_SUBMIT_FLOW_STEP_DAILY_CAP`, default 50 — #8071)
82
121
  **Booking (4):** `list_availability`, `get_event_meta`, `list_meetings`, `create_booking` — module-gated (`module: "scheduling"`) and licence-feature-tagged (`feature: "scheduling"`, #7136), gated on the deployment's `scheduling` licence feature under `MCP_FEATURE_GATE_MODE`. `create_booking` takes the HTTP write branch (its own daily cap, `MCP_ABUSE_CREATE_BOOKING_DAILY_CAP`, default 20, and an `attendee.email` format check — #8071). `list_meetings` (#8843 D5) twins `GET /v1/schedule/meetings`: it takes no argument and returns the site's Live meetings — slug, visibility, position and whether each can be booked, plus a bookable one's calLink, title, length, description and price; `private` means unlisted, not secret
83
122
 
84
- ### Why the parity test counts 21 and a keyless server registers 20
123
+ ### Why the parity test counts 21 and a keyless server registers 19 (20 once Free is released)
85
124
 
86
125
  - **21 in the `TOOLS` array / parity test**: the `TOOLS` array in
87
126
  `packages/metadata/src/mcp-tool-catalog.ts` defines 21 anonymous tools; the
88
- parity test counts that full array. It also holds the eighteen signed-in
127
+ parity test counts that full array. It also holds the thirty-one signed-in
89
128
  workspace tools (#3591), which no anonymous view returns — see § The
90
129
  signed-in workspace surface below.
91
- - **20 registered on a KEYLESS deployment, 21 on a commerce-claimed one**
92
- (#5971): `createMcpServer` (`apps/mcp/src/server.ts`) registers
93
- `getMcpToolRegistrations()` minus `OSS_DISABLED_TOOLS` (now empty), minus
94
- module-gated tools whose module is off, minus any `addon`-tagged tool whose
95
- claim this deployment does not hold. `start_purchase` carries
96
- `addon: "commerce"`, so it is the one entry whose presence depends on the
97
- licence — 20 without the claim, 21 with it.
98
- - **20 free anonymous tools**: since #5853 retired the three content-write
130
+ - **19 registered on a KEYLESS deployment, 20 on a commerce-claimed one,
131
+ while the Free level is held — 20 and 21 once it is released**
132
+ (#5971, #9534): `createMcpServer` (`apps/mcp/src/server.ts`) registers
133
+ `getMcpToolRegistrations()` minus the topology seam's `UNSERVED_MCP_TOOLS`,
134
+ minus `create_project` while create-ailk's `release-scope.json` holds
135
+ `levels.free` (the release-scope filter, #9534), minus `OSS_DISABLED_TOOLS`
136
+ (now empty), minus module-gated tools whose module is off, minus any
137
+ `addon`-tagged tool whose claim this deployment does not hold.
138
+ `start_purchase` carries `addon: "commerce"`, so it is the one entry whose
139
+ presence depends on the licence — one fewer without the claim.
140
+ - **19 free anonymous tools while Free is held (20 released)**: since #5853 retired the three content-write
99
141
  tools, every registered tool remains anonymous — call-time gating checks a
100
142
  licence claim, never an identity. The six carrying `tier: "pro"`
101
143
  (`get_flow`, `submit_flow_step`, `list_availability`, `get_event_meta`,
@@ -128,28 +170,38 @@ here. Spec: `docs/specs/3591-tenant-scoped-agent-auth-secure-spec.md` D13–D16.
128
170
  - **apps/mcp checks only the key's shape.** The key is attached as the SDK's `req.auth` for that
129
171
  request alone and reaches a tool as `extra.authInfo.token`. apps/api is the one place it is
130
172
  checked, and its tenant guard and the caller's clamped role decide every answer.
131
- - **Eighteen tools, each a `twin`.** The catalog rows carry `surface: "workspace"`, `tier: "pro"`
173
+ - **Thirty-one tools, each a `twin`.** The catalog rows carry `surface: "workspace"`, `tier: "pro"`
132
174
  and `modulesAnyOf` (the modules any one of which registers the tool — its twin route's gate):
133
- `get_agent_context`, the four message tools, the three submission tools, the three
175
+ `get_agent_context`, (#9683) `get_workspace_knowledge` — twin of `GET
176
+ /v1/workspaces/:workspaceId/knowledge`: the business's shown offerings, live magnets, listed
177
+ meeting types, sites served and strategy documents, read with the `people-read` or
178
+ `people-memory-propose` grant — the five message tools (#9686 added `list_inbox_threads`, twin of
179
+ `GET …/messages/threads`: the inbox's threads, 25 to a page with a count per view; Done now
180
+ archives the message's thread and accept no longer marks it done, and an agent reaches any
181
+ inbox tool only with the `inbox-act` grant), the three submission tools, the three
134
182
  listing application tools (#9137: `list_listing_applications`, `get_listing_application`,
135
183
  `decide_listing_application` — a `ProjectListing` row, never a job application, which is a Job
136
184
  application magnet's submission; the pre-rename `list_inbox_applications`,
137
185
  `get_inbox_application` and `decide_inbox_application` stay registered for one release as
138
- deprecated aliases of the same handlers, each description opening `Deprecated: use …`) and (#8514) the two People notes tools, `get_person_notes` and
186
+ deprecated aliases of the same handlers, each description opening `Deprecated: use …`) and (#9714) `list_people` — twin of `GET /v1/workspaces/:workspaceId/people` in both its modes: newest-first pages by `cursor`, or with `changedSince` the clients whose thread gained an inbound item since then, oldest first with `more`, needing the `people-read` grant — and (#8514) the two People notes tools, `get_person_notes` and
139
187
  `set_person_notes` — the team's private note on one client, which an agent reads and writes
140
188
  only with the `member-pieces-manage` grant; `set_person_notes` requires the `ifUpdatedAt` it
141
189
  read and is refused `notes_changed` when someone saved since — and (#8516) the two proposals
142
190
  tools, `list_proposals` and `create_proposal`, twinning `GET`/`POST
143
191
  /v1/workspaces/:workspaceId/people/:personId/proposals` with the same grant: a proposal is
144
192
  private to one client, `payments` says whether approval leads to a Stripe page, and an agent's
145
- price is refused `proposal_needs_person` (a person prices). Each takes its route's params, query and body and returns the route's
193
+ price is refused `proposal_needs_person` (a person prices) — and (#9681) the four person-thread tools, `get_person_thread`, `set_person_thread_state`, `list_external_threads` and `add_external_thread`, twinning `GET`/`PATCH …/people/:personId/thread` and `GET`/`POST …/people/:personId/external-threads`: a client's whole thread page by page with its read/archived/resolved state, and pointers to email and Slack threads (never message text); reading needs the `people-read` grant, writing also `inbox-act`, and the client erasure route has no tool, by decision — and (#9682) the three person-memory tools, `list_person_memories`, `get_person_memory` and `propose_person_memory`, twinning `GET …/people/:personId/memories`, `GET …/memories/:path` and `POST …/memories`: an agent reads only live, unexpired memories (confirmed by a person, read within 180 days) and its proposal is never live — a new path is a draft, a confirmed one gets a pending version — needing the `people-read` or `people-memory-propose` grant to read and `people-memory-propose` to propose; the six person-only memory routes (edit, delete, confirm, redact, the versions list, restore) have no tool, by decision — and (#9749) `get_slack_connection_status`, twin of `GET /v1/workspaces/:workspaceId/slack-connection` (registered with `workspace`/`multi-tenant`, its route's `TENANCY` row: whether the Organization's Slack is connected, its team name and the date, never a credential; connect and disconnect are a person's act and have no tool, by decision), and `get_prospect_channel_settings` / `set_prospect_channel_settings`, twins of `GET`/`PUT …/prospect-channel` (registered with `scheduling`, their routes' module): the update replaces every field, needs the `meeting-types-manage` grant, is refused `slack_not_connected` while the Organization has no Slack connection, and an agent may change only `enabled`, `channelPrefix` and `archiveDays` — a change to `memberIds` or `welcomeTemplate` is refused `prospect_channel_needs_person`. Each takes its route's params, query and body and returns the route's
146
194
  `data`. They are in the parity guard like every other tool, and never in
147
195
  `/.well-known/mcp.json`.
148
- - **Handlers forward, nothing else.** `workspace-server.ts` resolves each tool to a paid-slice
149
- handler file (`tools/agent_context.ts`, `inbox_messages.ts`, `inbox_submissions.ts`,
150
- `inbox_applications.ts`, `person_notes.ts`, `proposals.ts`, all `// oss: false`) through a
151
- specifier table, as `server.ts` does. Each calls `@working-theory/api-client`'s `inbox` surface
152
- (the notes and proposals tools, its `people` surface) with the key. A refusal from the
196
+ - **Handlers forward, nothing else.** `workspace-server.ts` resolves each tool from
197
+ `@working-theory/mcp-workspace`'s `workspaceTools` (`agent_context.ts`, `knowledge.ts`, `inbox_messages.ts`,
198
+ `inbox_submissions.ts`, `inbox_applications.ts`, `people_list.ts`, `person_notes.ts`, `person_thread.ts`, `person_memory.ts`, `proposals.ts`, `slack_connection.ts`, all
199
+ `// oss: false`) and, for the two prospect-channel settings tools, `@working-theory/mcp-scheduling`'s
200
+ `workspaceTools` (`prospect_channel_settings.ts`, #9749 — the pack the scheduling module carries, so a
201
+ scheduling-only build serves what it lists), loaded through the site's generated registry, as `server.ts` resolves the
202
+ module-gated tools from their packs (#9460). Each calls `@working-theory/api-client`'s `inbox` surface
203
+ (the people-list, notes, person-thread, person-memory and proposals tools, its `people` surface; the
204
+ Slack status and prospect-channel tools, its `slack` surface) with the key. A refusal from the
153
205
  route is an MCP tool error naming the route's `error.code` and HTTP status only.
154
206
  - **Never log or return the key.** Don't log or serialise `extra`, `extra.authInfo` or
155
207
  `extra.requestInfo` — the SDK puts the raw `authorization` header there.
@@ -225,7 +277,19 @@ Example (lead routing):
225
277
  - Don't add a tool without the matching `apps/api` endpoint.
226
278
  - Don't put business logic in tool handlers — they're adapters.
227
279
 
228
- Last updated: 2026-10-20 — #7171, #7172, #7173: the three lead writes adopted their routes' bodies and 201 results and are parity `twin`s — the Conversion-write line records the adopted shapes — verified against `apps/mcp/src/tools/{capture_lead,subscribe_newsletter,request_callback}.ts`, `packages/validation/src/schemas/leads.ts` and `tests/parity/api-parity/kinds/site.ts`.
280
+ Last updated: 2026-10-24 — #9749: `get_slack_connection_status` (`mcp-workspace`'s `slack_connection.ts`) and `get_prospect_channel_settings` / `set_prospect_channel_settings` (`mcp-scheduling`'s `prospect_channel_settings.ts`, the first signed-in handlers outside `mcp-workspace`) twin the Slack status read and the prospect-channel settings pair — the signed-in workspace surface is thirty-one tools — verified against `packages/metadata/src/mcp-tool-catalog.ts`, `packages-paid/mcp-workspace/src/index.ts`, `packages-paid/mcp-scheduling/src/index.ts` and `tests/parity/api-parity/kinds/site.ts`.
281
+
282
+ Prior: 2026-10-24 — #9714: `list_people` (`people_list.ts`) twins `GET /v1/workspaces/:workspaceId/people` in both its modes — the signed-in workspace surface is twenty-eight tools — verified against `packages/metadata/src/mcp-tool-catalog.ts`, `packages-paid/mcp-workspace/src/index.ts` and `tests/parity/api-parity/kinds/site.ts`.
283
+
284
+ Prior: 2026-10-24 — #9686: `list_inbox_threads` (`inbox_messages.ts`) twins `GET /v1/workspaces/:workspaceId/messages/threads` — the signed-in workspace surface is twenty-seven tools — verified against `packages/metadata/src/mcp-tool-catalog.ts`, `packages-paid/mcp-workspace/src/index.ts` and `tests/parity/api-parity/kinds/site.ts`.
285
+
286
+ Prior: 2026-10-24 — #9683: `get_workspace_knowledge` (`knowledge.ts`) twins `GET /v1/workspaces/:workspaceId/knowledge` — the signed-in workspace surface is twenty-three tools; the inbox write twins forward no agent-session header — verified against `packages/metadata/src/mcp-tool-catalog.ts`, `packages-paid/mcp-workspace/src/index.ts` and `tests/parity/api-parity/kinds/site.ts`.
287
+
288
+ Prior: 2026-10-22 — #9460: the server is `@working-theory/mcp-server` and the paid tools ride `packages-paid/mcp-*`; `src/` is the five-file boot set, `lib/paid-tools.generated.ts` is the one door to a paid MCP package, and the specifier tables are gone — verified against `packages/mcp-server/src/{server,workspace-server,boot,run,site}.ts`, `apps/mcp/src/{index,app,site}.ts` and `packages/create-ailk/src/paid-sections.ts`.
289
+
290
+ Prior: 2026-10-22 — #9534: `create_project` registers only while create-ailk's `release-scope.json` marks the Free level released (the release-scope filter in `shouldRegister`, re-applied at call time) — 19 registered keyless and 20 claimed while Free is held — and the content-root rule names the tool's `<cwd>/packages/create-ailk` root as its standing exception — verified against `apps/mcp/src/tools/create_project.ts`, `apps/mcp/src/server.ts` and `apps/web/app/.well-known/mcp.json/route.ts`.
291
+
292
+ Prior: 2026-10-20 — #7171, #7172, #7173: the three lead writes adopted their routes' bodies and 201 results and are parity `twin`s — the Conversion-write line records the adopted shapes — verified against `apps/mcp/src/tools/{capture_lead,subscribe_newsletter,request_callback}.ts`, `packages/validation/src/schemas/leads.ts` and `tests/parity/api-parity/kinds/site.ts`.
229
293
 
230
294
  Prior: 2026-10-20 — #7167, #7168, #7169: the three content reads adopted their routes' arguments and results and are parity `twin`s — the Read line records the adopted shapes — verified against `apps/mcp/src/tools/{search_content,list_pages,read_content}.ts`, `packages/validation/src/schemas/content-reads.ts`, `packages/content-adapters/src/content-reads.ts` and `tests/parity/api-parity/kinds/site.ts`.
231
295
 
@@ -24,124 +24,8 @@
24
24
  */
25
25
 
26
26
  import { existsSync, readFileSync } from "node:fs";
27
- import { createServer, type Server } from "node:http";
28
- import type { AddressInfo } from "node:net";
29
27
  import { resolve } from "node:path";
30
28
 
31
- import Fastify, { type FastifyInstance } from "fastify";
32
-
33
- import { buildHttpTransportApp } from "../src/http-transport.js";
34
- import {
35
- configureServerlessApp,
36
- SERVERLESS_FASTIFY_OPTIONS,
37
- serverlessHandler,
38
- trustOneHop,
39
- } from "../src/serverless-app.js";
40
-
41
- // The hub call capture_lead makes after the guard is stubbed, as
42
- // http-transport.test.ts stubs checkout: only the guard's verdict is asserted.
43
- jest.mock("@working-theory/api-client", () => {
44
- const actual = jest.requireActual("@working-theory/api-client");
45
- return {
46
- ...actual,
47
- apiClient: {
48
- ...actual.apiClient,
49
- leads: {
50
- ...actual.apiClient.leads,
51
- submit: jest.fn().mockResolvedValue({
52
- ok: true,
53
- body: {
54
- id: "lead_00000000-0000-7000-8000-000000008070",
55
- persisted: "db",
56
- },
57
- }),
58
- },
59
- },
60
- };
61
- });
62
-
63
- const VARS = [
64
- "MCP_HTTP_STATELESS",
65
- "MCP_ABUSE_CAPTURE_LEAD_DAILY_CAP",
66
- "MCP_CORS_WRITE_ALLOWED_ORIGINS",
67
- ] as const;
68
-
69
- const saved: Partial<Record<(typeof VARS)[number], string | undefined>> = {};
70
-
71
- beforeEach(() => {
72
- for (const name of VARS) {
73
- saved[name] = process.env[name];
74
- delete process.env[name];
75
- }
76
- });
77
-
78
- afterEach(() => {
79
- for (const name of VARS) {
80
- const value = saved[name];
81
- if (value === undefined) delete process.env[name];
82
- else process.env[name] = value;
83
- }
84
- });
85
-
86
- async function mcpPost(
87
- port: number,
88
- payload: object,
89
- headers: Record<string, string> = {},
90
- ): Promise<Response> {
91
- return fetch(`http://127.0.0.1:${port}/mcp`, {
92
- method: "POST",
93
- body: JSON.stringify(payload),
94
- headers: {
95
- "content-type": "application/json",
96
- accept: "application/json, text/event-stream",
97
- ...headers,
98
- },
99
- });
100
- }
101
-
102
- async function listen(app: FastifyInstance): Promise<number> {
103
- await app.listen({ host: "127.0.0.1", port: 0 });
104
- return (app.server.address() as AddressInfo).port;
105
- }
106
-
107
- /** The app src/app.ts builds, minus the boot and the default export. */
108
- async function serverlessApp(): Promise<FastifyInstance> {
109
- const app = Fastify(SERVERLESS_FASTIFY_OPTIONS);
110
- await configureServerlessApp(app);
111
- await app.ready();
112
- return app;
113
- }
114
-
115
- /** Serve the app through the exact function Vercel's Node runtime calls. */
116
- async function serveHandler(
117
- app: FastifyInstance,
118
- ): Promise<{ server: Server; port: number }> {
119
- const server = createServer(serverlessHandler(app));
120
- await new Promise<void>((done) => server.listen(0, "127.0.0.1", done));
121
- return { server, port: (server.address() as AddressInfo).port };
122
- }
123
-
124
- async function stop(server: Server | undefined): Promise<void> {
125
- if (!server) return;
126
- await new Promise<void>((done) => server.close(() => done()));
127
- }
128
-
129
- function captureLead(id: number, name: string): object {
130
- return {
131
- jsonrpc: "2.0",
132
- id,
133
- method: "tools/call",
134
- params: {
135
- name: "capture_lead",
136
- arguments: {
137
- source: "mcp",
138
- email: `${name.toLowerCase()}@example.com`,
139
- payload: { name, message: "Interested in your services." },
140
- },
141
- },
142
- };
143
- }
144
-
145
29
  describe("AC-4 — src/app.ts, read as source text", () => {
146
30
  const src = readFileSync(resolve(__dirname, "../src/app.ts"), "utf-8");
147
31
 
@@ -150,17 +34,17 @@ describe("AC-4 — src/app.ts, read as source text", () => {
150
34
  });
151
35
 
152
36
  it("awaits the shared boot, builds Fastify from the serverless options and configures it", () => {
153
- expect(src).toContain("await bootMcp()");
37
+ expect(src).toContain("await bootMcp(site)");
154
38
  expect(src).toContain("Fastify(SERVERLESS_FASTIFY_OPTIONS)");
155
- expect(src).toContain("configureServerlessApp(app)");
39
+ expect(src).toContain("configureServerlessApp(app, site)");
156
40
  });
157
41
 
158
42
  it("boots before it builds the app, and readies it before it exports", () => {
159
- expect(src.indexOf("await bootMcp()")).toBeLessThan(
43
+ expect(src.indexOf("await bootMcp(site)")).toBeLessThan(
160
44
  src.indexOf("Fastify(SERVERLESS_FASTIFY_OPTIONS)"),
161
45
  );
162
46
  expect(src).toContain("await app.ready()");
163
- expect(src.indexOf("configureServerlessApp(app)")).toBeLessThan(
47
+ expect(src.indexOf("configureServerlessApp(app, site)")).toBeLessThan(
164
48
  src.indexOf("await app.ready()"),
165
49
  );
166
50
  });
@@ -189,137 +73,3 @@ describe("AC-13 — Vercel's type-check keeps strict", () => {
189
73
  expect(existsSync(resolve(__dirname, "../vercel.json"))).toBe(false);
190
74
  });
191
75
  });
192
-
193
- describe("AC-4 — the serverless options and the configured app", () => {
194
- let app: FastifyInstance | undefined;
195
- let server: Server | undefined;
196
- let port = 0;
197
-
198
- afterEach(async () => {
199
- await stop(server);
200
- await app?.close();
201
- app = undefined;
202
- server = undefined;
203
- });
204
-
205
- it("SERVERLESS_FASTIFY_OPTIONS is { logger: false, trustProxy: trustOneHop }", () => {
206
- expect(SERVERLESS_FASTIFY_OPTIONS).toEqual({
207
- logger: false,
208
- trustProxy: trustOneHop,
209
- });
210
- });
211
-
212
- it("trustOneHop trusts the immediate peer (hop 0) and nothing behind it, whatever its address", () => {
213
- expect(trustOneHop("127.0.0.1", 0)).toBe(true);
214
- expect(trustOneHop("10.0.0.1", 0)).toBe(true);
215
- expect(trustOneHop("9.9.9.9", 1)).toBe(false);
216
- expect(trustOneHop("1.1.1.1", 2)).toBe(false);
217
- });
218
-
219
- it("why not trustProxy: 1 — this Fastify treats a numeric hop count as trust-nothing", async () => {
220
- const numeric = Fastify({ logger: false, trustProxy: 1 });
221
- numeric.get("/ip", async (request) => ({ ip: request.ip }));
222
- const res = await numeric.inject({
223
- url: "/ip",
224
- remoteAddress: "127.0.0.1",
225
- headers: { "x-forwarded-for": "3.3.3.3, 8.8.8.8" },
226
- });
227
- await numeric.close();
228
-
229
- // Every caller would key on the edge's address.
230
- expect(res.json()).toEqual({ ip: "127.0.0.1" });
231
- });
232
-
233
- it("serverlessHandler(app) is a (req, res) function", async () => {
234
- app = await serverlessApp();
235
- expect(typeof serverlessHandler(app)).toBe("function");
236
- });
237
-
238
- it("with MCP_HTTP_STATELESS unset, an http.createServer serving serverlessHandler(app) answers initialize and then a session-less tools/list", async () => {
239
- app = await serverlessApp();
240
- ({ server, port } = await serveHandler(app));
241
-
242
- const init = await mcpPost(port, {
243
- jsonrpc: "2.0",
244
- id: 1,
245
- method: "initialize",
246
- params: {
247
- protocolVersion: "2025-03-26",
248
- capabilities: {},
249
- clientInfo: { name: "app-entry-test", version: "1.0.0" },
250
- },
251
- });
252
- expect(init.status).toBe(200);
253
- const initBody = (await init.json()) as {
254
- result?: { serverInfo?: { name?: string } };
255
- };
256
- expect(initBody.result?.serverInfo).toMatchObject({ name: "ailk" });
257
-
258
- const list = await mcpPost(port, {
259
- jsonrpc: "2.0",
260
- id: 2,
261
- method: "tools/list",
262
- params: {},
263
- });
264
- expect(list.status).toBe(200);
265
- });
266
- });
267
-
268
- describe("AC-5 — the daily cap keys on the last X-Forwarded-For hop", () => {
269
- let app: FastifyInstance | undefined;
270
- let server: Server | undefined;
271
-
272
- afterEach(async () => {
273
- await stop(server);
274
- await app?.close();
275
- app = undefined;
276
- server = undefined;
277
- });
278
-
279
- it("serverless app: two callers sharing a last hop are one caller; a different last hop is another", async () => {
280
- process.env["MCP_ABUSE_CAPTURE_LEAD_DAILY_CAP"] = "1";
281
- // Set explicitly so the write-origin check is never what refuses a call.
282
- process.env["MCP_CORS_WRITE_ALLOWED_ORIGINS"] = "*";
283
- app = await serverlessApp();
284
- const { server: served, port } = await serveHandler(app);
285
- server = served;
286
-
287
- const first = await mcpPost(port, captureLead(10, "First"), {
288
- "x-forwarded-for": "1.1.1.1, 9.9.9.9",
289
- });
290
- expect(first.status).toBe(200);
291
-
292
- const second = await mcpPost(port, captureLead(11, "Second"), {
293
- "x-forwarded-for": "2.2.2.2, 9.9.9.9",
294
- });
295
- expect(second.status).toBe(403);
296
- const refusal = (await second.json()) as { error?: string };
297
- expect(refusal.error).toBe("daily capture_lead cap reached for this IP");
298
-
299
- const third = await mcpPost(port, captureLead(12, "Third"), {
300
- "x-forwarded-for": "3.3.3.3, 8.8.8.8",
301
- });
302
- expect(third.status).toBe(200);
303
- });
304
-
305
- it("long-running app (no trustProxy): the header is ignored — every call is the socket's address", async () => {
306
- app = await buildHttpTransportApp({
307
- path: "/mcp",
308
- stateless: true,
309
- rateLimits: { readPerMin: 60, writePerMin: 10 },
310
- cors: { writeAllowedOrigins: ["*"] },
311
- abuse: { captureLeadDailyCapPerIp: 1, blockedUserAgents: "" },
312
- });
313
- const port = await listen(app);
314
-
315
- const first = await mcpPost(port, captureLead(20, "First"), {
316
- "x-forwarded-for": "3.3.3.3",
317
- });
318
- expect(first.status).toBe(200);
319
-
320
- const second = await mcpPost(port, captureLead(21, "Second"), {
321
- "x-forwarded-for": "4.4.4.4",
322
- });
323
- expect(second.status).toBe(403);
324
- });
325
- });
@@ -0,0 +1,92 @@
1
+ /**
2
+ * The boot set is a boot set (#9460 AC-1 (a)).
3
+ *
4
+ * Every file under `src/` may import only `@working-theory/mcp-server`, its
5
+ * `/hub` entry, `fastify`, the type-only `@working-theory/content-adapters`,
6
+ * the site's own `./site.js` and `./lib/*.generated.js` — and, inside
7
+ * `lib/paid-tools.generated.ts` alone, the paid MCP packs. A boot file that
8
+ * imported `@working-theory/validation`, `@working-theory/api-client` or a
9
+ * tool module would rebuild the coupling that broke 0.45.0; a deep import
10
+ * such as `@working-theory/mcp-server/dist/tools/get_faq.js` is one a bump
11
+ * would not keep stable. This suite ships to every scaffold, so a keyless
12
+ * site re-checks itself.
13
+ */
14
+
15
+ import { readdirSync, readFileSync, statSync } from "node:fs";
16
+ import { join, relative, resolve } from "node:path";
17
+
18
+ const SRC = resolve(__dirname, "../src");
19
+
20
+ const ALLOWED = new Set([
21
+ "@working-theory/mcp-server",
22
+ "@working-theory/mcp-server/hub",
23
+ "fastify",
24
+ "@working-theory/content-adapters",
25
+ ]);
26
+ const PAID_PACKS = new Set([
27
+ "@working-theory/mcp-scheduling",
28
+ "@working-theory/mcp-signal-collectors",
29
+ "@working-theory/mcp-workspace",
30
+ ]);
31
+ const REGISTRY = "lib/paid-tools.generated.ts";
32
+
33
+ function walk(dir: string, out: string[] = []): string[] {
34
+ for (const entry of readdirSync(dir)) {
35
+ const p = join(dir, entry);
36
+ if (statSync(p).isDirectory()) walk(p, out);
37
+ else if (p.endsWith(".ts")) out.push(p);
38
+ }
39
+ return out;
40
+ }
41
+
42
+ /** Every static and dynamic import specifier in `text`. */
43
+ function specifiers(text: string): string[] {
44
+ return [...text.matchAll(/(?:from|import)\s*\(?\s*"([^"]+)"/g)].map(
45
+ (m) => m[1]!,
46
+ );
47
+ }
48
+
49
+ function allowedFor(file: string, spec: string): boolean {
50
+ if (ALLOWED.has(spec)) return true;
51
+ if (spec === "./site.js" || /^\.\/lib\/[\w-]+\.generated\.js$/.test(spec))
52
+ return true;
53
+ return file === REGISTRY && PAID_PACKS.has(spec);
54
+ }
55
+
56
+ describe("apps/mcp/src is the boot set (#9460 AC-1)", () => {
57
+ const files = walk(SRC).map((p) => relative(SRC, p).split("\\").join("/"));
58
+
59
+ it("holds exactly the five boot files", () => {
60
+ expect(files.sort()).toEqual([
61
+ "app.ts",
62
+ "index.ts",
63
+ "lib/paid-tools.generated.ts",
64
+ "lib/topology.generated.ts",
65
+ "site.ts",
66
+ ]);
67
+ });
68
+
69
+ it.each(files)(
70
+ "%s imports only the package, fastify and the site's own files",
71
+ (file) => {
72
+ const text = readFileSync(join(SRC, file), "utf8");
73
+ const specs = specifiers(text);
74
+ expect(specs.filter((spec) => !allowedFor(file, spec))).toEqual([]);
75
+ },
76
+ );
77
+
78
+ it("no boot file imports a tool, a schema or the api client", () => {
79
+ for (const file of files) {
80
+ const specs = specifiers(readFileSync(join(SRC, file), "utf8"));
81
+ expect(
82
+ specs.filter(
83
+ (spec) =>
84
+ spec.includes("/dist/") ||
85
+ spec.includes("/tools/") ||
86
+ spec === "@working-theory/validation" ||
87
+ spec === "@working-theory/api-client",
88
+ ),
89
+ ).toEqual([]);
90
+ }
91
+ });
92
+ });
@@ -1,6 +1,11 @@
1
+ // Only so the handler suite's spawned create-ailk CLI scaffolds keyless (Free
2
+ // is held): the registration gate (`isFreeLevelReleased`) never reads it (#9534).
3
+ process.env.AILK_RELEASE_SCOPE = "ignore";
4
+
1
5
  module.exports = {
2
6
  preset: 'ts-jest',
3
7
  globalSetup: require.resolve('../../tools/jest/pin-timezone.cjs'),
8
+ reporters: require('../../tools/jest/reporters.cjs'),
4
9
  testEnvironment: 'node',
5
10
  // Workaround: @hono/node-server@1.19.14 (transitive via
6
11
  // @modelcontextprotocol/sdk's StreamableHTTPServerTransport) calls
@@ -21,7 +26,7 @@ module.exports = {
21
26
  // fresh checkout, and the published dist is ESM, which Jest's CJS preset
22
27
  // can't load. The CLIENT root (`@working-theory/database`) stays
23
28
  // deliberately UNMAPPED — see apps/mcp/src/lib/prisma.ts.
24
- '^@working-theory/database/tenancy$': '<rootDir>/../../database/tenancy.ts',
29
+ '^@working-theory/database/tenancy$': '<rootDir>/node_modules/@working-theory/database/dist/tenancy.js',
25
30
  '^(\\.{1,2}/.*)\\.js$': '$1',
26
31
  },
27
32
  collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts'],
@@ -16,25 +16,17 @@
16
16
  "test:coverage": "jest --coverage"
17
17
  },
18
18
  "dependencies": {
19
- "@fastify/cors": "^11.2.0",
20
- "@fastify/rate-limit": "^10.3.0",
21
- "@modelcontextprotocol/sdk": "^1.31.0",
22
19
  "@prisma/adapter-pg": "^7.8.0",
23
- "@working-theory/aeo": "workspace:*",
24
- "@working-theory/api-client": "workspace:*",
25
20
  "@working-theory/content-adapters": "workspace:*",
26
21
  "@working-theory/database": "workspace:*",
27
- "@working-theory/license": "workspace:*",
28
- "@working-theory/metadata": "workspace:*",
29
- "@working-theory/schema": "workspace:*",
30
- "@working-theory/site-config": "workspace:*",
31
- "@working-theory/validation": "workspace:*",
32
- "fastify": "^5.12.5",
33
- "yaml": "^2.9.0",
34
- "zod": "^4.2.1"
22
+ "@working-theory/mcp-server": "workspace:*",
23
+ "fastify": "^5.12.5"
35
24
  },
36
25
  "devDependencies": {
26
+ "@modelcontextprotocol/sdk": "^1.31.0",
37
27
  "@types/jest": "^30.0.0",
28
+ "@working-theory/api-client": "workspace:*",
29
+ "@working-theory/metadata": "workspace:*",
38
30
  "@types/node": "^22.20.0",
39
31
  "jest": "^30.4.2",
40
32
  "ts-jest": "^29.4.11",