create-ailk 0.23.0 → 0.25.1

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 (604) hide show
  1. package/README.md +68 -33
  2. package/component-catalog.json +3 -3
  3. package/component-catalog.md +3 -3
  4. package/dist/add-module.js +10 -3
  5. package/dist/add-route.d.ts +12 -1
  6. package/dist/add-route.js +38 -4
  7. package/dist/cli.js +12 -7
  8. package/dist/derive-architecture.d.ts +3 -4
  9. package/dist/derive-architecture.js +75 -22
  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 +1 -1
  14. package/dist/lib/fetch-template-snapshot.js +7 -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 +34 -12
  19. package/dist/lib/scaffold-render-sweep.d.ts +33 -0
  20. package/dist/lib/scaffold-render-sweep.js +45 -0
  21. package/dist/module-architecture.d.ts +20 -3
  22. package/dist/module-architecture.js +122 -538
  23. package/dist/paid-sections.d.ts +25 -1
  24. package/dist/paid-sections.js +88 -3
  25. package/dist/surfaces.js +10 -2
  26. package/dist/sync-routes.d.ts +30 -4
  27. package/dist/sync-routes.js +271 -18
  28. package/dist/template-record.d.ts +14 -4
  29. package/dist/template-record.js +23 -5
  30. package/dist/topology.d.ts +16 -3
  31. package/dist/topology.js +31 -19
  32. package/dist/update.d.ts +10 -1
  33. package/dist/update.js +540 -16
  34. package/package.json +3 -3
  35. package/release-scope.json +1 -1
  36. package/templates/.claude/cloudparity-repo-hooks.json +5 -0
  37. package/templates/.claude/hooks/template-guard.sh +137 -0
  38. package/templates/.claude/rules/extending.md +106 -0
  39. package/templates/.claude/rules/loop-contract.md +2 -2
  40. package/templates/.claude/settings.json +11 -0
  41. package/templates/.env.example +9 -5
  42. package/templates/.github/workflows/ci.yml +7 -4
  43. package/templates/CLAUDE.md +15 -3
  44. package/templates/CONVENTIONS.md +8 -10
  45. package/templates/README.md +14 -13
  46. package/templates/apps/api/.env.example +9 -2
  47. package/templates/apps/api/CLAUDE.md +122 -82
  48. package/templates/apps/api/jest.config.cjs +15 -5
  49. package/templates/apps/api/package.json +16 -20
  50. package/templates/apps/api/src/__tests__/trusted-origins.server.test.ts +2 -2
  51. package/templates/apps/api/src/__tests__/vercel-handler.test.ts +4 -4
  52. package/templates/apps/api/src/index.ts +1 -1
  53. package/templates/apps/api/src/lib/__mocks__/prisma.ts +7 -4
  54. package/templates/apps/api/src/modules/commerce.ts +10 -0
  55. package/templates/apps/api/src/modules/content-write.ts +10 -0
  56. package/templates/apps/api/src/modules/multi-tenant.ts +10 -0
  57. package/templates/apps/api/src/modules/scheduling.ts +10 -0
  58. package/templates/apps/api/src/modules/signal-collectors.ts +10 -0
  59. package/templates/apps/api/src/modules/workspace.ts +10 -0
  60. package/templates/apps/api/src/server.ts +117 -1857
  61. package/templates/apps/api/vercel.json +2 -2
  62. package/templates/apps/mcp/CLAUDE.md +77 -24
  63. package/templates/apps/mcp/__tests__/app-entry.test.ts +4 -254
  64. package/templates/apps/mcp/__tests__/boot-file.test.ts +92 -0
  65. package/templates/apps/mcp/jest.config.cjs +6 -1
  66. package/templates/apps/mcp/package.json +5 -12
  67. package/templates/apps/mcp/src/app.ts +8 -7
  68. package/templates/apps/mcp/src/index.ts +6 -34
  69. package/templates/apps/mcp/src/lib/paid-tools.generated.ts +10 -0
  70. package/templates/apps/mcp/src/lib/topology.generated.ts +2 -2
  71. package/templates/apps/mcp/src/site.ts +12 -0
  72. package/templates/apps/web/.env.example +1 -1
  73. package/templates/apps/web/CLAUDE.md +21 -5
  74. package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
  75. package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +1 -1
  76. package/templates/apps/web/app/[locale]/contact/contact.actions.ts +14 -4
  77. package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
  78. package/templates/apps/web/app/[locale]/contact/intake-script.ts +1 -1
  79. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +22 -1
  80. package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +28 -7
  81. package/templates/apps/web/app/[locale]/pricing/__tests__/unconnected.test.tsx +43 -0
  82. package/templates/apps/web/app/[locale]/pricing/page.tsx +7 -3
  83. package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/__tests__/route.test.ts +222 -0
  84. package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +10 -3
  85. package/templates/apps/web/app/api/revalidate/route.ts +3 -3
  86. package/templates/apps/web/auth.ts +2 -2
  87. package/templates/apps/web/jest.config.cjs +1 -0
  88. package/templates/apps/web/lib/__tests__/magnet-routes.test.ts +7 -0
  89. package/templates/apps/web/lib/auth-email.ts +1 -1
  90. package/templates/apps/web/lib/magnet-routes.ts +3 -1
  91. package/templates/apps/web/lib/newsletter.actions.ts +9 -6
  92. package/templates/apps/web/lib/relay.ts +2 -2
  93. package/templates/apps/web/lib/release-scope.ts +47 -0
  94. package/templates/apps/web/lib/server-api.ts +1 -1
  95. package/templates/apps/web/src/lib/commerce-claim.ts +1 -1
  96. package/templates/customizations.yaml +37 -0
  97. package/templates/database/prisma.config.ts +10 -14
  98. package/templates/database/seed-test.ts +2 -2
  99. package/templates/database/seed.ts +32 -5
  100. package/templates/package.json +12 -6
  101. package/templates/pnpm-workspace.yaml +0 -1
  102. package/templates/project.yaml +16 -8
  103. package/templates/tools/jest/reporters.cjs +65 -0
  104. package/templates/tools/lint-architecture.ts +757 -7
  105. package/templates/tsconfig.json +1 -2
  106. package/versions.json +48 -35
  107. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +0 -409
  108. package/templates/apps/api/src/__tests__/factories/agent-caller.ts +0 -102
  109. package/templates/apps/api/src/__tests__/factories/content-fixture.ts +0 -138
  110. package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +0 -441
  111. package/templates/apps/api/src/__tests__/factories/index.ts +0 -70
  112. package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +0 -82
  113. package/templates/apps/api/src/__tests__/leads-forwarded-rate-limit.test.ts +0 -135
  114. package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +0 -126
  115. package/templates/apps/api/src/__tests__/stripe-boot.test.ts +0 -132
  116. package/templates/apps/api/src/__tests__/support/hub-sign-in-fake-db.ts +0 -362
  117. package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +0 -184
  118. package/templates/apps/api/src/bin/abandon-sweep.ts +0 -42
  119. package/templates/apps/api/src/bin/rate-limit-probe.ts +0 -53
  120. package/templates/apps/api/src/bin/spokes.ts +0 -198
  121. package/templates/apps/api/src/bin/stripe-connections-rekey.ts +0 -45
  122. package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +0 -196
  123. package/templates/apps/api/src/config/__tests__/index.test.ts +0 -233
  124. package/templates/apps/api/src/config/__tests__/modules.test.ts +0 -76
  125. package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +0 -185
  126. package/templates/apps/api/src/config/__tests__/trusted-origins.test.ts +0 -238
  127. package/templates/apps/api/src/config/index.ts +0 -596
  128. package/templates/apps/api/src/config/modules.ts +0 -83
  129. package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +0 -581
  130. package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +0 -143
  131. package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +0 -237
  132. package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +0 -353
  133. package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +0 -201
  134. package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +0 -224
  135. package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +0 -120
  136. package/templates/apps/api/src/lib/__tests__/errors.test.ts +0 -94
  137. package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +0 -144
  138. package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +0 -8
  139. package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +0 -149
  140. package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +0 -116
  141. package/templates/apps/api/src/lib/__tests__/hub-sign-in-store.test.ts +0 -209
  142. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +0 -257
  143. package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +0 -96
  144. package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +0 -125
  145. package/templates/apps/api/src/lib/__tests__/prisma.test.ts +0 -165
  146. package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +0 -317
  147. package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +0 -129
  148. package/templates/apps/api/src/lib/__tests__/site.test.ts +0 -292
  149. package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +0 -89
  150. package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +0 -202
  151. package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +0 -217
  152. package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -82
  153. package/templates/apps/api/src/lib/agent-store.ts +0 -613
  154. package/templates/apps/api/src/lib/auth-email-budget.ts +0 -161
  155. package/templates/apps/api/src/lib/consent-store.ts +0 -363
  156. package/templates/apps/api/src/lib/content-adapter.ts +0 -112
  157. package/templates/apps/api/src/lib/deliverable-asset-store.ts +0 -96
  158. package/templates/apps/api/src/lib/error-serializer.ts +0 -164
  159. package/templates/apps/api/src/lib/errors.ts +0 -95
  160. package/templates/apps/api/src/lib/file-fallback.ts +0 -87
  161. package/templates/apps/api/src/lib/flow-completion-store.ts +0 -136
  162. package/templates/apps/api/src/lib/hub-sign-in-store.ts +0 -455
  163. package/templates/apps/api/src/lib/lead-capture-store.ts +0 -122
  164. package/templates/apps/api/src/lib/lead-delivery.ts +0 -52
  165. package/templates/apps/api/src/lib/license-key-store.ts +0 -45
  166. package/templates/apps/api/src/lib/locales.ts +0 -201
  167. package/templates/apps/api/src/lib/outbound-http.ts +0 -127
  168. package/templates/apps/api/src/lib/prisma.ts +0 -21
  169. package/templates/apps/api/src/lib/proposal-paid-store.ts +0 -66
  170. package/templates/apps/api/src/lib/rate-limit-probe.ts +0 -165
  171. package/templates/apps/api/src/lib/rate-limit-store.ts +0 -142
  172. package/templates/apps/api/src/lib/require-commerce-claim.ts +0 -250
  173. package/templates/apps/api/src/lib/require-paid-tier.ts +0 -53
  174. package/templates/apps/api/src/lib/site.ts +0 -254
  175. package/templates/apps/api/src/lib/slice-load.ts +0 -90
  176. package/templates/apps/api/src/lib/spoke-store.ts +0 -180
  177. package/templates/apps/api/src/lib/stripe.ts +0 -318
  178. package/templates/apps/api/src/lib/webhook-idempotency.ts +0 -156
  179. package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +0 -111
  180. package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +0 -172
  181. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +0 -119
  182. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +0 -138
  183. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-trusted-origins.test.ts +0 -142
  184. package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +0 -155
  185. package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +0 -139
  186. package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +0 -562
  187. package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +0 -76
  188. package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +0 -220
  189. package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +0 -97
  190. package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +0 -557
  191. package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +0 -72
  192. package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +0 -140
  193. package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +0 -721
  194. package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +0 -220
  195. package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +0 -430
  196. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +0 -1409
  197. package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +0 -174
  198. package/templates/apps/api/src/middleware/auth.ts +0 -864
  199. package/templates/apps/api/src/middleware/default-tenant.ts +0 -166
  200. package/templates/apps/api/src/middleware/rate-limit.ts +0 -983
  201. package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +0 -264
  202. package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +0 -182
  203. package/templates/apps/api/src/openapi/index.ts +0 -18
  204. package/templates/apps/api/src/openapi/spec.ts +0 -1815
  205. package/templates/apps/api/src/openapi/surface-drift.ts +0 -195
  206. package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +0 -175
  207. package/templates/apps/api/src/routes/aeo/index.ts +0 -107
  208. package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +0 -196
  209. package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +0 -249
  210. package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +0 -532
  211. package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +0 -313
  212. package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +0 -413
  213. package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +0 -609
  214. package/templates/apps/api/src/routes/auth/hub-sign-in.ts +0 -242
  215. package/templates/apps/api/src/routes/auth/tokens.ts +0 -211
  216. package/templates/apps/api/src/routes/auth/transactional-email.ts +0 -301
  217. package/templates/apps/api/src/routes/auth/user.ts +0 -305
  218. package/templates/apps/api/src/routes/billing/plan-checkout.ts +0 -325
  219. package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +0 -178
  220. package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +0 -1300
  221. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +0 -448
  222. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -1742
  223. package/templates/apps/api/src/routes/checkout/index.ts +0 -34
  224. package/templates/apps/api/src/routes/checkout/session.ts +0 -171
  225. package/templates/apps/api/src/routes/checkout/sessions.ts +0 -540
  226. package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +0 -386
  227. package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +0 -160
  228. package/templates/apps/api/src/routes/consent/account.ts +0 -268
  229. package/templates/apps/api/src/routes/consent/cookie.ts +0 -90
  230. package/templates/apps/api/src/routes/consent/index.ts +0 -26
  231. package/templates/apps/api/src/routes/consent/unsubscribe.ts +0 -127
  232. package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +0 -853
  233. package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +0 -230
  234. package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +0 -44
  235. package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +0 -118
  236. package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +0 -731
  237. package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +0 -753
  238. package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +0 -51
  239. package/templates/apps/api/src/routes/content/__tests__/search.test.ts +0 -450
  240. package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +0 -762
  241. package/templates/apps/api/src/routes/content/get-page.ts +0 -268
  242. package/templates/apps/api/src/routes/content/index.ts +0 -49
  243. package/templates/apps/api/src/routes/content/list-pages.ts +0 -95
  244. package/templates/apps/api/src/routes/content/list-types.ts +0 -19
  245. package/templates/apps/api/src/routes/content/offerings.ts +0 -184
  246. package/templates/apps/api/src/routes/content/pricing.ts +0 -176
  247. package/templates/apps/api/src/routes/content/rate-limit.ts +0 -22
  248. package/templates/apps/api/src/routes/content/search.ts +0 -129
  249. package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
  250. package/templates/apps/api/src/routes/content/slug.ts +0 -9
  251. package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +0 -88
  252. package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +0 -171
  253. package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +0 -515
  254. package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +0 -392
  255. package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +0 -165
  256. package/templates/apps/api/src/routes/leads/index.ts +0 -573
  257. package/templates/apps/api/src/routes/leads/list.ts +0 -104
  258. package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +0 -626
  259. package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +0 -1268
  260. package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +0 -847
  261. package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +0 -480
  262. package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -465
  263. package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +0 -872
  264. package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +0 -1022
  265. package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +0 -484
  266. package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +0 -535
  267. package/templates/apps/api/src/routes/project-listings/index.ts +0 -164
  268. package/templates/apps/api/src/routes/project-listings/me.ts +0 -87
  269. package/templates/apps/api/src/routes/project-listings/patch-copy.ts +0 -224
  270. package/templates/apps/api/src/routes/project-listings/patch-draft.ts +0 -102
  271. package/templates/apps/api/src/routes/project-listings/public.ts +0 -98
  272. package/templates/apps/api/src/routes/project-listings/respond.ts +0 -48
  273. package/templates/apps/api/src/routes/project-listings/resume-token.ts +0 -27
  274. package/templates/apps/api/src/routes/project-listings/start.ts +0 -140
  275. package/templates/apps/api/src/routes/project-listings/submit.ts +0 -130
  276. package/templates/apps/api/src/routes/project-listings/verify-email.ts +0 -150
  277. package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +0 -686
  278. package/templates/apps/api/src/routes/requests/confirm.ts +0 -601
  279. package/templates/apps/api/src/routes/requests/index.ts +0 -54
  280. package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +0 -306
  281. package/templates/apps/api/src/routes/test/auth/session.ts +0 -143
  282. package/templates/apps/api/src/routes/webhooks/README.md +0 -398
  283. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +0 -649
  284. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +0 -749
  285. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -448
  286. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -264
  287. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +0 -159
  288. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +0 -158
  289. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +0 -814
  290. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -301
  291. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +0 -369
  292. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -215
  293. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +0 -301
  294. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +0 -808
  295. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -1155
  296. package/templates/apps/api/src/routes/webhooks/index.ts +0 -141
  297. package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +0 -384
  298. package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -2026
  299. package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -528
  300. package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +0 -132
  301. package/templates/apps/api/src/services/__tests__/audit-log.test.ts +0 -1028
  302. package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +0 -313
  303. package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +0 -503
  304. package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +0 -65
  305. package/templates/apps/api/src/services/__tests__/consent.test.ts +0 -299
  306. package/templates/apps/api/src/services/__tests__/default-tenant.test.ts +0 -147
  307. package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +0 -867
  308. package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +0 -379
  309. package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +0 -368
  310. package/templates/apps/api/src/services/__tests__/entitlements.test.ts +0 -142
  311. package/templates/apps/api/src/services/__tests__/hub-sign-in.test.ts +0 -854
  312. package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +0 -234
  313. package/templates/apps/api/src/services/__tests__/lead-accept-user.test.ts +0 -251
  314. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +0 -2660
  315. package/templates/apps/api/src/services/__tests__/listing-config.test.ts +0 -166
  316. package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +0 -389
  317. package/templates/apps/api/src/services/__tests__/person.test.ts +0 -1176
  318. package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -444
  319. package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -154
  320. package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +0 -137
  321. package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +0 -531
  322. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +0 -372
  323. package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +0 -348
  324. package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +0 -660
  325. package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +0 -941
  326. package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +0 -588
  327. package/templates/apps/api/src/services/__tests__/verified-email.test.ts +0 -78
  328. package/templates/apps/api/src/services/abandon-email.ts +0 -313
  329. package/templates/apps/api/src/services/aeo-score.ts +0 -325
  330. package/templates/apps/api/src/services/answer-distributions.ts +0 -138
  331. package/templates/apps/api/src/services/audit-log.ts +0 -961
  332. package/templates/apps/api/src/services/checkout-buyer.ts +0 -168
  333. package/templates/apps/api/src/services/consent.ts +0 -834
  334. package/templates/apps/api/src/services/default-tenant.ts +0 -416
  335. package/templates/apps/api/src/services/deliverable-fulfillment.ts +0 -755
  336. package/templates/apps/api/src/services/dunning-policy.ts +0 -294
  337. package/templates/apps/api/src/services/enrichment-shim.ts +0 -53
  338. package/templates/apps/api/src/services/entitlements.ts +0 -338
  339. package/templates/apps/api/src/services/hub-sign-in.ts +0 -472
  340. package/templates/apps/api/src/services/lead-accept-user.ts +0 -126
  341. package/templates/apps/api/src/services/lead-promotion.ts +0 -160
  342. package/templates/apps/api/src/services/lead-routing.ts +0 -1372
  343. package/templates/apps/api/src/services/leads-inbox.ts +0 -312
  344. package/templates/apps/api/src/services/listing-config.ts +0 -178
  345. package/templates/apps/api/src/services/magnet-completion.ts +0 -242
  346. package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +0 -295
  347. package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +0 -268
  348. package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +0 -868
  349. package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +0 -416
  350. package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +0 -396
  351. package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -681
  352. package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
  353. package/templates/apps/api/src/services/offerings/catalog.ts +0 -308
  354. package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -385
  355. package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
  356. package/templates/apps/api/src/services/offerings/connection.ts +0 -1003
  357. package/templates/apps/api/src/services/offerings/index.ts +0 -614
  358. package/templates/apps/api/src/services/offerings/source.ts +0 -140
  359. package/templates/apps/api/src/services/offerings/store.ts +0 -150
  360. package/templates/apps/api/src/services/owner-workspaces.ts +0 -132
  361. package/templates/apps/api/src/services/person.ts +0 -1188
  362. package/templates/apps/api/src/services/plan-offerings.ts +0 -125
  363. package/templates/apps/api/src/services/project-listing-resume-email.ts +0 -326
  364. package/templates/apps/api/src/services/project-listings.ts +0 -2073
  365. package/templates/apps/api/src/services/public-site-resolver.ts +0 -396
  366. package/templates/apps/api/src/services/request-confirm.ts +0 -698
  367. package/templates/apps/api/src/services/revalidation.ts +0 -235
  368. package/templates/apps/api/src/services/slack-notify.ts +0 -291
  369. package/templates/apps/api/src/services/usage-aggregation.ts +0 -516
  370. package/templates/apps/api/src/services/usage-credits.ts +0 -340
  371. package/templates/apps/api/src/services/verified-email.ts +0 -71
  372. package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +0 -52
  373. package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +0 -46
  374. package/templates/apps/mcp/__tests__/abuse/guard.test.ts +0 -198
  375. package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +0 -36
  376. package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +0 -54
  377. package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +0 -116
  378. package/templates/apps/mcp/__tests__/audit-single-page.test.ts +0 -299
  379. package/templates/apps/mcp/__tests__/boot.test.ts +0 -280
  380. package/templates/apps/mcp/__tests__/catalog-drift.test.ts +0 -359
  381. package/templates/apps/mcp/__tests__/config/modules.test.ts +0 -78
  382. package/templates/apps/mcp/__tests__/get_business_hours.test.ts +0 -82
  383. package/templates/apps/mcp/__tests__/get_faq.test.ts +0 -80
  384. package/templates/apps/mcp/__tests__/get_locations.test.ts +0 -65
  385. package/templates/apps/mcp/__tests__/get_offerings.test.ts +0 -557
  386. package/templates/apps/mcp/__tests__/get_pricing.test.ts +0 -524
  387. package/templates/apps/mcp/__tests__/get_site_info.test.ts +0 -81
  388. package/templates/apps/mcp/__tests__/http-transport.test.ts +0 -1151
  389. package/templates/apps/mcp/__tests__/index.test.ts +0 -195
  390. package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +0 -191
  391. package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +0 -531
  392. package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +0 -65
  393. package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -187
  394. package/templates/apps/mcp/__tests__/lib/content-root.test.ts +0 -93
  395. package/templates/apps/mcp/__tests__/lib/errors.test.ts +0 -75
  396. package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +0 -165
  397. package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
  398. package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -228
  399. package/templates/apps/mcp/__tests__/locale.test.ts +0 -135
  400. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +0 -175
  401. package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +0 -101
  402. package/templates/apps/mcp/__tests__/read_content.test.ts +0 -474
  403. package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -225
  404. package/templates/apps/mcp/__tests__/search_content.test.ts +0 -256
  405. package/templates/apps/mcp/__tests__/server.test.ts +0 -388
  406. package/templates/apps/mcp/__tests__/start_purchase.test.ts +0 -448
  407. package/templates/apps/mcp/__tests__/submit_lead.test.ts +0 -307
  408. package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -223
  409. package/templates/apps/mcp/__tests__/tools/create_project.test.ts +0 -243
  410. package/templates/apps/mcp/__tests__/tools/purchase.test.ts +0 -451
  411. package/templates/apps/mcp/src/abuse/daily-cap.ts +0 -47
  412. package/templates/apps/mcp/src/abuse/email-validator.ts +0 -25
  413. package/templates/apps/mcp/src/abuse/honeypot.ts +0 -21
  414. package/templates/apps/mcp/src/abuse/index.ts +0 -342
  415. package/templates/apps/mcp/src/abuse/user-agent-deny.ts +0 -58
  416. package/templates/apps/mcp/src/boot.ts +0 -167
  417. package/templates/apps/mcp/src/config/modules.ts +0 -43
  418. package/templates/apps/mcp/src/http-transport.ts +0 -526
  419. package/templates/apps/mcp/src/lib/audit-single-page.ts +0 -308
  420. package/templates/apps/mcp/src/lib/commerce-claim.ts +0 -263
  421. package/templates/apps/mcp/src/lib/content-adapter.ts +0 -142
  422. package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -139
  423. package/templates/apps/mcp/src/lib/errors.ts +0 -61
  424. package/templates/apps/mcp/src/lib/license-key-store.ts +0 -45
  425. package/templates/apps/mcp/src/lib/locales.ts +0 -171
  426. package/templates/apps/mcp/src/lib/prisma.ts +0 -39
  427. package/templates/apps/mcp/src/lib/public-workspace.ts +0 -133
  428. package/templates/apps/mcp/src/lib/resolve-locale.ts +0 -30
  429. package/templates/apps/mcp/src/lib/shown-offerings.ts +0 -105
  430. package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +0 -59
  431. package/templates/apps/mcp/src/request-context.ts +0 -52
  432. package/templates/apps/mcp/src/server.ts +0 -343
  433. package/templates/apps/mcp/src/serverless-app.ts +0 -88
  434. package/templates/apps/mcp/src/tools/audit.ts +0 -127
  435. package/templates/apps/mcp/src/tools/capture_lead.ts +0 -64
  436. package/templates/apps/mcp/src/tools/create_project.ts +0 -134
  437. package/templates/apps/mcp/src/tools/get_business_hours.ts +0 -68
  438. package/templates/apps/mcp/src/tools/get_faq.ts +0 -71
  439. package/templates/apps/mcp/src/tools/get_locations.ts +0 -88
  440. package/templates/apps/mcp/src/tools/get_offerings.ts +0 -96
  441. package/templates/apps/mcp/src/tools/get_pricing.ts +0 -94
  442. package/templates/apps/mcp/src/tools/get_site_info.ts +0 -86
  443. package/templates/apps/mcp/src/tools/index.ts +0 -137
  444. package/templates/apps/mcp/src/tools/list_pages.ts +0 -74
  445. package/templates/apps/mcp/src/tools/person_notes.ts +0 -25
  446. package/templates/apps/mcp/src/tools/proposals.ts +0 -27
  447. package/templates/apps/mcp/src/tools/purchase.ts +0 -205
  448. package/templates/apps/mcp/src/tools/read_content.ts +0 -75
  449. package/templates/apps/mcp/src/tools/request_callback.ts +0 -59
  450. package/templates/apps/mcp/src/tools/search_content.ts +0 -67
  451. package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -57
  452. package/templates/apps/mcp/src/workspace-server.ts +0 -224
  453. package/templates/database/CHANGELOG.md +0 -961
  454. package/templates/database/LICENSE +0 -202
  455. package/templates/database/NOTICE +0 -2
  456. package/templates/database/README.md +0 -243
  457. package/templates/database/__tests__/agents.db.test.ts +0 -320
  458. package/templates/database/__tests__/appointment.db.test.ts +0 -106
  459. package/templates/database/__tests__/artifact-content-store.db.test.ts +0 -316
  460. package/templates/database/__tests__/composite-fence.db.test.ts +0 -206
  461. package/templates/database/__tests__/consent-ledger.db.test.ts +0 -345
  462. package/templates/database/__tests__/consent-source-checkout-migration.test.ts +0 -79
  463. package/templates/database/__tests__/fence-fan-out.db.test.ts +0 -715
  464. package/templates/database/__tests__/fixtures/appointment-create-probe.ts +0 -79
  465. package/templates/database/__tests__/fixtures/person-backfill.json +0 -264
  466. package/templates/database/__tests__/fixtures/person-contact-backfill.json +0 -182
  467. package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +0 -100
  468. package/templates/database/__tests__/flow-completion-migration.test.ts +0 -115
  469. package/templates/database/__tests__/flow-completion.db.test.ts +0 -136
  470. package/templates/database/__tests__/flow-workspace-key.db.test.ts +0 -263
  471. package/templates/database/__tests__/flows-listing-diagnostic.test.ts +0 -392
  472. package/templates/database/__tests__/flows-presets.test.ts +0 -173
  473. package/templates/database/__tests__/in-page-magnets-migration.test.ts +0 -161
  474. package/templates/database/__tests__/lead-idempotency-key.db.test.ts +0 -92
  475. package/templates/database/__tests__/member-area.db.test.ts +0 -257
  476. package/templates/database/__tests__/member-contract-migration.test.ts +0 -85
  477. package/templates/database/__tests__/member-contract.db.test.ts +0 -413
  478. package/templates/database/__tests__/offerings-checkout-session.db.test.ts +0 -270
  479. package/templates/database/__tests__/offerings-migration.test.ts +0 -197
  480. package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +0 -86
  481. package/templates/database/__tests__/offerings.db.test.ts +0 -303
  482. package/templates/database/__tests__/outbound-message-action.db.test.ts +0 -80
  483. package/templates/database/__tests__/person-contact.db.test.ts +0 -563
  484. package/templates/database/__tests__/person-notes.db.test.ts +0 -249
  485. package/templates/database/__tests__/person.db.test.ts +0 -586
  486. package/templates/database/__tests__/piece-kind-migration.test.ts +0 -67
  487. package/templates/database/__tests__/piece-kind.db.test.ts +0 -208
  488. package/templates/database/__tests__/prefixed-ids.db.test.ts +0 -222
  489. package/templates/database/__tests__/project-listing-consent-at.db.test.ts +0 -111
  490. package/templates/database/__tests__/seed.test.ts +0 -240
  491. package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
  492. package/templates/database/__tests__/tenancy.test.ts +0 -141
  493. package/templates/database/__tests__/user-cascade.test.ts +0 -140
  494. package/templates/database/_gitignore +0 -8
  495. package/templates/database/auth/.gitkeep +0 -0
  496. package/templates/database/auth/schema.prisma +0 -641
  497. package/templates/database/config/.gitkeep +0 -0
  498. package/templates/database/config/schema.prisma +0 -441
  499. package/templates/database/content/.gitkeep +0 -0
  500. package/templates/database/content/schema.prisma +0 -339
  501. package/templates/database/eslint.config.mjs +0 -69
  502. package/templates/database/flows/listing-diagnostic.ts +0 -182
  503. package/templates/database/flows/presets.ts +0 -315
  504. package/templates/database/inbox/.gitkeep +0 -0
  505. package/templates/database/inbox/README.md +0 -3
  506. package/templates/database/inbox/__tests__/schema.test.ts +0 -44
  507. package/templates/database/inbox/schema.prisma +0 -1447
  508. package/templates/database/jest.config.cjs +0 -36
  509. package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +0 -328
  510. package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +0 -100
  511. package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +0 -28
  512. package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +0 -25
  513. package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +0 -42
  514. package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +0 -67
  515. package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +0 -21
  516. package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +0 -201
  517. package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +0 -67
  518. package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +0 -46
  519. package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +0 -25
  520. package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +0 -49
  521. package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +0 -197
  522. package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +0 -32
  523. package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +0 -22
  524. package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +0 -151
  525. package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +0 -223
  526. package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +0 -22
  527. package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +0 -32
  528. package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +0 -40
  529. package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +0 -4
  530. package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +0 -2
  531. package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +0 -2
  532. package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +0 -29
  533. package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +0 -6
  534. package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +0 -39
  535. package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +0 -24
  536. package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +0 -3
  537. package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +0 -33
  538. package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +0 -30
  539. package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +0 -47
  540. package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +0 -16
  541. package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +0 -47
  542. package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +0 -10
  543. package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +0 -26
  544. package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +0 -90
  545. package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +0 -174
  546. package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +0 -14
  547. package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +0 -25
  548. package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +0 -32
  549. package/templates/database/migrations/20260911180000_consent_grants/migration.sql +0 -71
  550. package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +0 -30
  551. package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +0 -49
  552. package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +0 -123
  553. package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +0 -15
  554. package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +0 -158
  555. package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +0 -40
  556. package/templates/database/migrations/20260918120000_add_appointment/migration.sql +0 -67
  557. package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +0 -70
  558. package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +0 -181
  559. package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +0 -172
  560. package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +0 -41
  561. package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +0 -185
  562. package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +0 -70
  563. package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +0 -57
  564. package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +0 -68
  565. package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +0 -1067
  566. package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +0 -210
  567. package/templates/database/migrations/20261003120000_spoke_registry/migration.sql +0 -80
  568. package/templates/database/migrations/20261003130000_scheduling_connection/migration.sql +0 -49
  569. package/templates/database/migrations/20261005120000_agents/migration.sql +0 -84
  570. package/templates/database/migrations/20261008120000_user_last_workspace/migration.sql +0 -35
  571. package/templates/database/migrations/20261008130000_lead_idempotency_key/migration.sql +0 -20
  572. package/templates/database/migrations/20261009120000_agent_grants/migration.sql +0 -33
  573. package/templates/database/migrations/20261010120000_person/migration.sql +0 -106
  574. package/templates/database/migrations/20261010121000_person_backfill/migration.sql +0 -132
  575. package/templates/database/migrations/20261010130000_agent_grants_people_read/migration.sql +0 -20
  576. package/templates/database/migrations/20261011120000_member_area/migration.sql +0 -158
  577. package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql +0 -21
  578. package/templates/database/migrations/20261012120000_member_contract/migration.sql +0 -192
  579. package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +0 -20
  580. package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +0 -122
  581. package/templates/database/migrations/20261014120000_person_contact/migration.sql +0 -231
  582. package/templates/database/migrations/20261015120000_person_notes/migration.sql +0 -77
  583. package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +0 -43
  584. package/templates/database/migrations/20261016120000_piece_kind/migration.sql +0 -95
  585. package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +0 -30
  586. package/templates/database/migrations/20261018120000_flow_completion/migration.sql +0 -52
  587. package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +0 -27
  588. package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +0 -146
  589. package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +0 -77
  590. package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +0 -45
  591. package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +0 -47
  592. package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +0 -16
  593. package/templates/database/migrations/migration_lock.toml +0 -3
  594. package/templates/database/ops/.gitkeep +0 -0
  595. package/templates/database/ops/schema.prisma +0 -43
  596. package/templates/database/package.json +0 -89
  597. package/templates/database/schema.prisma +0 -71
  598. package/templates/database/scripts/db-generate-locked.sh +0 -80
  599. package/templates/database/scripts/person-backfill.sql +0 -132
  600. package/templates/database/tenancy.ts +0 -183
  601. package/templates/database/tsconfig.build.json +0 -16
  602. package/templates/database/tsconfig.flows.json +0 -15
  603. package/templates/database/tsconfig.json +0 -16
  604. package/templates/database/tsconfig.tenancy.json +0 -14
@@ -1,43 +0,0 @@
1
- /**
2
- * Paid-module presence — the registration-grain signal used by `server.ts`
3
- * to decide whether a paid module's tools are wired into this build
4
- * (S1, #5088; defaulted off by D-44, #5368). Mirrors
5
- * `apps/api/src/config/modules.ts` — apps/* may not import apps/*, so this
6
- * tiny reader is duplicated rather than shared.
7
- *
8
- * `AILK_ENABLED_MODULES` is a comma-separated allowlist (e.g.
9
- * `"multi-tenant,scheduling"`). Unset means **no paid modules** — installed
10
- * modules enable themselves explicitly; an explicit empty string (`""`)
11
- * means the same (the OSS-strip build target); a list enables exactly the
12
- * modules it names.
13
- *
14
- * Recognized module keys: `docs`, `multi-tenant`, `scheduling`,
15
- * `signal-collectors` (the `ModuleName` vocabulary
16
- * `packages/create-ailk/src/module-architecture.ts` already models via
17
- * `MODULE_SLICES`) plus `content-write` — the Pro content-write surface,
18
- * which owns NO MCP tool since #5853: `create_page`/`update_page`/`delete_page`
19
- * were retired by deletion along with their untenanted HTTP twins, and their
20
- * replacement is identity-bound, which the identity-blind MCP surface cannot
21
- * carry (D7, D15; the authed MCP surface is #3591). The flag is read here only
22
- * because this reader is shared with `apps/api`, where it still gates the
23
- * tenant-guarded editor routes. `content-write` is intentionally NOT a
24
- * `MODULE_SLICES` entry: it is not (yet) a create-ailk `--modules` selector,
25
- * so it stays a local flag here rather than widening the create-ailk module
26
- * vocabulary.
27
- */
28
-
29
- function enabledModules(): Set<string> {
30
- const raw = process.env.AILK_ENABLED_MODULES;
31
- if (raw === undefined) return new Set(); // unset = no paid modules
32
- return new Set(
33
- raw
34
- .split(",")
35
- .map((m) => m.trim())
36
- .filter(Boolean),
37
- );
38
- }
39
-
40
- /** Whether the named paid module's tools should register on this build/boot. */
41
- export function isModuleEnabled(moduleName: string): boolean {
42
- return enabledModules().has(moduleName);
43
- }
@@ -1,526 +0,0 @@
1
- /**
2
- * MCP HTTP transport for @working-theory/mcp.
3
- *
4
- * Wraps the MCP SDK's StreamableHTTPServerTransport in a Fastify server with:
5
- * - @fastify/cors — open for reads, allowlist-by-config for writes
6
- * - @fastify/rate-limit — 60/min reads, 10/min writes (env-overridable)
7
- * - abuse heuristics — UA deny list, honeypot, email validation, daily cap
8
- *
9
- * Decision references:
10
- * Decision 1 — same binary, env-var transport selection (apps/mcp/src/index.ts;
11
- * the Vercel entry, apps/mcp/src/app.ts, serves HTTP only — #8070)
12
- * Decision 2 — configurable path, default /mcp, standalone root-mounted
13
- * Decision 3 — @fastify/rate-limit per-IP token bucket
14
- * Decision 4 — in-process abuse heuristics for write tools
15
- * Decision 5 — @fastify/cors open reads, allowlist writes
16
- *
17
- * Two modes, chosen by `config.stateless` (#8070 D1; the entries read it from
18
- * `MCP_HTTP_STATELESS` through `readStatelessEnv`, src/boot.ts):
19
- * - stateful (the long-running entry's default): an `initialize` creates a
20
- * StreamableHTTPServerTransport + McpServer pair kept in an in-memory map
21
- * keyed by its Mcp-Session-Id. Sessions live in ONE process's memory and
22
- * are not persisted across restarts, so this mode needs a single instance.
23
- * - stateless (the Vercel entry's default): every POST gets a fresh
24
- * transport + server and no session ID; GET and DELETE answer 400. Any
25
- * instance can answer any request.
26
- *
27
- * The anonymous `config.path` never reads `Authorization`. Beside it,
28
- * `${config.path}/workspace` serves the signed-in workspace tools (#3591 D15):
29
- * POST only and always stateless, each request carrying an agent key that is
30
- * handed to that request's tools and nothing else — see
31
- * {@link registerWorkspaceRoute}.
32
- */
33
-
34
- import { randomUUID } from "node:crypto";
35
- import type { IncomingMessage } from "node:http";
36
-
37
- import cors from "@fastify/cors";
38
- import rateLimit from "@fastify/rate-limit";
39
- import type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
40
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
41
- import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
42
- import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
43
- import Fastify, {
44
- type FastifyInstance,
45
- type FastifyReply,
46
- type FastifyRequest,
47
- } from "fastify";
48
-
49
- import {
50
- AbuseGuard,
51
- AbuseReasonCode,
52
- type AbuseConfig,
53
- } from "./abuse/index.js";
54
- import { trustedCallerAddress } from "./request-context.js";
55
- import { createMcpServer } from "./server.js";
56
- import { createWorkspaceMcpServer } from "./workspace-server.js";
57
-
58
- /**
59
- * HTTP status for each {@link AbuseReasonCode} an AbuseGuard refusal can
60
- * carry (#5994).
61
- *
62
- * A refusal of the CALLER — a denied User-Agent, an IP that has spent its
63
- * daily budget — is **403**: the input was fine, the caller is not allowed to
64
- * make the call right now. A refusal of the INPUT — a filled honeypot, a
65
- * malformed email — is **422**.
66
- *
67
- * Keying on the code rather than on the refusal prose is what this table is
68
- * for: the split used to be `reason.includes("daily cap")`, so a reworded
69
- * reason silently demoted a rate-limit refusal to 422 — and `capture_lead`'s
70
- * wording only matched by accident, because the tool's name begins with
71
- * "cap". Typing the record over the full union also means a new reason code
72
- * fails to compile here until it declares its status.
73
- */
74
- export const ABUSE_REFUSAL_STATUS: Record<AbuseReasonCode, 403 | 422> = {
75
- [AbuseReasonCode.BLOCKED_USER_AGENT]: 403,
76
- [AbuseReasonCode.DAILY_CAP_REACHED]: 403,
77
- [AbuseReasonCode.HONEYPOT_FILLED]: 422,
78
- [AbuseReasonCode.INVALID_EMAIL]: 422,
79
- };
80
-
81
- /**
82
- * MCP tool names that are write operations (subject to stricter CORS + rate
83
- * limits, and to the AbuseGuard).
84
- *
85
- * `start_purchase` joined in #5971: it has a side effect at Stripe and it is
86
- * worth money to abuse, so it takes the write branch — the origin allow-list,
87
- * the write CORS posture, and `abuseGuard.validate()` — rather than the read
88
- * branch's UA check alone.
89
- *
90
- * `create_booking` and `submit_flow_step` joined in #8071: each forwards
91
- * caller-chosen data to the hub — a real booking on the seller's calendar
92
- * that emails the attendee an invite, and a flow step whose completing call
93
- * can create a Lead — so they take the same branch, each on its own daily
94
- * cap. `__tests__/write-tool-guard.test.ts` fails when a catalog tool that
95
- * sends a non-GET request to the hub is missing from this set.
96
- */
97
- // Any name added here MUST be enforced through the batch-aware path in
98
- // writeToolCalls() below — a request body can be a JSON-RPC ARRAY, and a
99
- // per-request (rather than per-message) check lets N batched calls through on
100
- // one cap unit. See the #5971 security review and the batch regression tests
101
- // in __tests__/http-transport.test.ts.
102
- export const WRITE_TOOLS = new Set([
103
- "capture_lead",
104
- "subscribe_newsletter",
105
- "request_callback",
106
- "start_purchase",
107
- "create_booking",
108
- "submit_flow_step",
109
- ]);
110
-
111
- export interface HttpTransportCorsConfig {
112
- /**
113
- * Origins allowed to call write tools.
114
- * Empty array = no cross-origin writes (most restrictive; default).
115
- * ["*"] = allow all origins for writes (use only in dev/testing).
116
- */
117
- writeAllowedOrigins: string[];
118
- }
119
-
120
- export interface HttpTransportRateLimits {
121
- /** Max requests per minute per IP for read tools. Default 60. */
122
- readPerMin: number;
123
- /** Max requests per minute per IP for write tools. Default 10. */
124
- writePerMin: number;
125
- }
126
-
127
- export interface HttpTransportConfig {
128
- /** URL path to mount the MCP endpoint on. Default "/mcp". */
129
- path?: string;
130
- /** Rate limit configuration. */
131
- rateLimits: HttpTransportRateLimits;
132
- /** CORS configuration. */
133
- cors: HttpTransportCorsConfig;
134
- /** Abuse protection configuration. */
135
- abuse: AbuseConfig;
136
- /**
137
- * When true, use stateless transport mode: no session IDs, every request
138
- * creates a fresh McpServer + transport. Needed on a host that runs several
139
- * instances (the Vercel entry), and used by tests.
140
- * Default: false (stateful). The entries set it from `MCP_HTTP_STATELESS`
141
- * (`readStatelessEnv`, src/boot.ts — #8070 D1).
142
- */
143
- stateless?: boolean;
144
- }
145
-
146
- /** One write-tool invocation found in a request body. */
147
- interface WriteToolCall {
148
- toolName: string;
149
- args: unknown;
150
- }
151
-
152
- /**
153
- * Every write-tool invocation carried by a request body, in order.
154
- *
155
- * JSON-RPC 2.0 allows a BATCH: an array of messages in one POST. The MCP SDK
156
- * honours it — `webStandardStreamableHttp.js` maps an array body to N parsed
157
- * messages and dispatches every one. So a body must be normalised to a LIST of
158
- * messages before any of them is classified; inspecting `body.method` on what
159
- * may be an array silently answers "not a write" for the whole batch, and the
160
- * request then takes the read branch: no write-origin check, and no
161
- * `AbuseGuard` cap unit consumed by ANY of the N calls it goes on to execute.
162
- *
163
- * That is a real bypass of the per-IP daily cap, and for `start_purchase` each
164
- * bypassed call creates a genuine Stripe Checkout Session on the seller's
165
- * account. It predates `start_purchase` — `capture_lead`,
166
- * `subscribe_newsletter` and `request_callback` have carried it since this
167
- * transport was written — and normalising here closes it for all four at once
168
- * (#5971 security review, High).
169
- *
170
- * Returns one entry PER matching message, so the caller can charge the guard
171
- * once per call rather than once per request.
172
- */
173
- function writeToolCalls(body: unknown): WriteToolCall[] {
174
- const messages = Array.isArray(body) ? body : [body];
175
- const calls: WriteToolCall[] = [];
176
-
177
- for (const message of messages) {
178
- if (!message || typeof message !== "object") continue;
179
- const req = message as Record<string, unknown>;
180
- if (req["method"] !== "tools/call") continue;
181
- const params = req["params"] as Record<string, unknown> | undefined;
182
- if (!params) continue;
183
- const toolName = params["name"];
184
- if (typeof toolName !== "string" || !WRITE_TOOLS.has(toolName)) continue;
185
- calls.push({ toolName, args: params["arguments"] ?? {} });
186
- }
187
-
188
- return calls;
189
- }
190
-
191
- /**
192
- * Determine whether an Origin header is in the write allowlist.
193
- * ["*"] matches any origin. Empty list blocks all cross-origin writes.
194
- */
195
- function isOriginAllowedForWrite(
196
- origin: string | undefined,
197
- allowedOrigins: string[],
198
- ): boolean {
199
- if (!origin) return true; // Same-origin or non-browser clients have no Origin header
200
- if (allowedOrigins.includes("*")) return true;
201
- return allowedOrigins.includes(origin);
202
- }
203
-
204
- /**
205
- * An agent key's shape (#3591 D2): `ailk_agt_` plus 32 random bytes in
206
- * base64url. apps/mcp checks only this; apps/api is where the key is checked.
207
- */
208
- const AGENT_BEARER = /^Bearer (ailk_agt_[A-Za-z0-9_-]{43})$/;
209
-
210
- /** The agent key an `Authorization` header carries, or null. */
211
- function agentKeyOf(header: string | string[] | undefined): string | null {
212
- if (typeof header !== "string") return null;
213
- return AGENT_BEARER.exec(header)?.[1] ?? null;
214
- }
215
-
216
- /**
217
- * The signed-in workspace surface (#3591 D15) at `path`: POST only, always
218
- * stateless — a fresh transport and `createWorkspaceMcpServer()` per request,
219
- * closed when the response ends, and no session map, so GET and DELETE are
220
- * 405. In order, a POST must:
221
- *
222
- * 1. carry `Authorization: Bearer ailk_agt_<43 base64url>` — else 401 in
223
- * `onRequest`, before the body is read and before any tool runs. A
224
- * personal token (`tok_…`) is refused here like any other shape;
225
- * 2. be one JSON-RPC message — a batch (array) body is 400;
226
- * 3. pass the abuse guard's User-Agent check.
227
- *
228
- * Rate limiting is apps/api's per-agent limiter, which every forwarded call
229
- * meets after the key is verified (D4); the app-wide per-IP limit still
230
- * applies here. The key is attached as the SDK's `req.auth` for this request
231
- * only, which the SDK hands each tool as `extra.authInfo`.
232
- */
233
- function registerWorkspaceRoute(
234
- app: FastifyInstance,
235
- path: string,
236
- abuseGuard: AbuseGuard,
237
- ): void {
238
- const notAllowed = async (_request: FastifyRequest, reply: FastifyReply) =>
239
- reply
240
- .code(405)
241
- .header("allow", "POST")
242
- .send({ error: "method_not_allowed" });
243
- app.get(path, notAllowed);
244
- app.delete(path, notAllowed);
245
-
246
- app.post(path, {
247
- onRequest: async (request, reply) => {
248
- if (agentKeyOf(request.headers["authorization"]) === null) {
249
- return reply.code(401).send({ error: "unauthorized" });
250
- }
251
- },
252
- preHandler: async (request, reply) => {
253
- if (Array.isArray(request.body)) {
254
- return reply.code(400).send({ error: "batch_not_supported" });
255
- }
256
- const ua = abuseGuard.validate("__read__", {}, request);
257
- if (!ua.allowed) {
258
- return reply.code(403).send({ error: ua.reason });
259
- }
260
- },
261
- handler: async (request, reply) => {
262
- const raw = request.raw as IncomingMessage & { auth?: AuthInfo };
263
- raw.auth = {
264
- token: agentKeyOf(request.headers["authorization"])!,
265
- clientId: "ailk-agent",
266
- scopes: [],
267
- };
268
- const transport = new StreamableHTTPServerTransport({
269
- enableJsonResponse: true,
270
- });
271
- const server = createWorkspaceMcpServer();
272
- try {
273
- // The cast is the same exactOptionalPropertyTypes one the anonymous
274
- // route carries.
275
- await server.connect(transport as unknown as Transport);
276
- await transport.handleRequest(raw, reply.raw, request.body);
277
- } catch (err) {
278
- if (!reply.sent) {
279
- reply.code(500).send({
280
- jsonrpc: "2.0",
281
- error: { code: -32603, message: "Internal server error" },
282
- id: null,
283
- });
284
- }
285
- throw err;
286
- } finally {
287
- await transport.close().catch(() => undefined);
288
- await server.close().catch(() => undefined);
289
- }
290
- },
291
- });
292
- }
293
-
294
- /**
295
- * Register the MCP HTTP transport at `config.path` on an existing Fastify
296
- * instance: CORS, the per-IP rate limit, the abuse guard, the anonymous MCP
297
- * route and the signed-in workspace route (#8070 D2). The caller owns the
298
- * instance — and so its options, such as the Vercel entry's `trustProxy`
299
- * (src/serverless-app.ts).
300
- *
301
- * @param app - The Fastify instance to register on (not yet listening)
302
- * @param config - HTTP transport configuration
303
- */
304
- export async function registerHttpTransport(
305
- app: FastifyInstance,
306
- config: HttpTransportConfig,
307
- ): Promise<void> {
308
- const mcpPath = config.path ?? "/mcp";
309
- const abuseGuard = new AbuseGuard(config.abuse);
310
-
311
- // Active transports keyed by session ID (stateful mode only).
312
- const transports = new Map<string, StreamableHTTPServerTransport>();
313
-
314
- // ── CORS ──────────────────────────────────────────────────────────────────
315
- // Read tools: open (origin: true — reflect the caller's Origin).
316
- // Write tools: enforced per-request in the preHandler below.
317
- // We register a permissive global CORS so browser preflight succeeds for
318
- // reads; write-tool CORS is enforced by the preHandler, not this plugin.
319
- await app.register(cors, {
320
- origin: true,
321
- methods: ["GET", "POST", "DELETE", "OPTIONS"],
322
- });
323
-
324
- // ── Rate limiting ─────────────────────────────────────────────────────────
325
- // Global ceiling — the lower write limit is enforced per-request via the
326
- // preHandler by checking the tool name after body parse.
327
- await app.register(rateLimit, {
328
- max: config.rateLimits.readPerMin,
329
- timeWindow: "1 minute",
330
- keyGenerator: (request: FastifyRequest) => request.ip,
331
- });
332
-
333
- // ── MCP route ─────────────────────────────────────────────────────────────
334
-
335
- // GET — SSE stream for an existing session
336
- app.get(mcpPath, async (request, reply) => {
337
- const sessionId = request.headers["mcp-session-id"] as string | undefined;
338
- if (!sessionId || !transports.has(sessionId)) {
339
- reply.code(400).send("Invalid or missing session ID");
340
- return;
341
- }
342
- const transport = transports.get(sessionId)!;
343
- await transport.handleRequest(request.raw, reply.raw);
344
- });
345
-
346
- // POST — new session initialize or existing session message
347
- app.post(mcpPath, {
348
- preHandler: async (request, reply) => {
349
- const body = request.body as unknown;
350
- const origin = request.headers["origin"] as string | undefined;
351
-
352
- // A batch body counts as a write request when ANY of its messages names
353
- // a write tool — see writeToolCalls().
354
- const writeCalls = writeToolCalls(body);
355
-
356
- // Write-tool CORS enforcement
357
- if (writeCalls.length > 0) {
358
- if (!isOriginAllowedForWrite(origin, config.cors.writeAllowedOrigins)) {
359
- reply
360
- .code(403)
361
- .send({ error: "CORS: cross-origin write not allowed" });
362
- return;
363
- }
364
-
365
- // Write-tool rate limit (stricter than read ceiling)
366
- // We re-use the same in-memory store but apply a tighter key.
367
- // @fastify/rate-limit tracks by keyGenerator; we check manually here.
368
- // Simple approach: use a second rate-limit store baked into the guard.
369
- // For now, we rely on the global ceiling for writes (configurable).
370
- // TODO: per-tool write rate limit when @fastify/rate-limit v11 lands
371
- // a per-route override API compatible with our stateless route design.
372
-
373
- // Abuse heuristics — charged ONCE PER CALL, not once per request, so a
374
- // batch of N cannot spend one cap unit and execute N times. The whole
375
- // request is refused on the first message that fails, before the SDK
376
- // dispatches any of them.
377
- for (const { toolName, args } of writeCalls) {
378
- const abuseResult = abuseGuard.validate(toolName, args, request);
379
- if (!abuseResult.allowed) {
380
- reply
381
- .code(ABUSE_REFUSAL_STATUS[abuseResult.code])
382
- .send({ error: abuseResult.reason });
383
- return;
384
- }
385
- }
386
- } else {
387
- // Read-tool or protocol message: check UA deny list only
388
- const abuseGuardResult = abuseGuard.validate("__read__", {}, request);
389
- if (!abuseGuardResult.allowed) {
390
- reply.code(403).send({ error: abuseGuardResult.reason });
391
- return;
392
- }
393
- }
394
- },
395
- handler: async (request, reply) =>
396
- // The lead-write tools read this address (#8073) through
397
- // `visitorForwardHeadersForThisCall()` while the SDK dispatches their
398
- // call, somewhere inside `transport.handleRequest()` below — the whole
399
- // handler body runs inside the store so every path reaches it.
400
- trustedCallerAddress.run(request.ip, async () => {
401
- const body = request.body as unknown;
402
- const sessionId = request.headers["mcp-session-id"] as
403
- | string
404
- | undefined;
405
-
406
- try {
407
- let transport: StreamableHTTPServerTransport;
408
-
409
- if (config.stateless) {
410
- // Stateless mode: each request gets a fresh transport + server.
411
- // enableJsonResponse: true ensures plain JSON responses (no SSE).
412
- // sessionIdGenerator is intentionally omitted (stateless = no sessions).
413
- transport = new StreamableHTTPServerTransport({
414
- enableJsonResponse: true,
415
- });
416
- const server = createMcpServer();
417
- // Cast needed: SDK's StreamableHTTPServerTransport.onclose is typed
418
- // as `(() => void) | undefined`, which conflicts with Transport.onclose
419
- // under exactOptionalPropertyTypes: true. The runtime behaviour is
420
- // identical; the cast is safe.
421
- await server.connect(transport as unknown as Transport);
422
- try {
423
- await transport.handleRequest(request.raw, reply.raw, body);
424
- } finally {
425
- // Close the per-request transport + server to release internal
426
- // handles. Without this, the MCP SDK's transport leaves open
427
- // sockets that surface as `socket.destroySoon is not a function`
428
- // during Jest teardown on Node 20.x (@hono/node-server compat).
429
- await transport.close().catch(() => undefined);
430
- await server.close().catch(() => undefined);
431
- }
432
- return;
433
- }
434
-
435
- if (sessionId && transports.has(sessionId)) {
436
- // Existing session — reuse transport
437
- transport = transports.get(sessionId)!;
438
- } else if (!sessionId && isInitializeRequest(body)) {
439
- // New initialization — create a stateful transport + fresh server
440
- transport = new StreamableHTTPServerTransport({
441
- sessionIdGenerator: () => randomUUID(),
442
- onsessioninitialized: (sid) => {
443
- transports.set(sid, transport);
444
- },
445
- });
446
-
447
- transport.onclose = () => {
448
- const sid = transport.sessionId;
449
- if (sid) transports.delete(sid);
450
- };
451
-
452
- const server = createMcpServer();
453
- // Cast needed: SDK's StreamableHTTPServerTransport.onclose is typed
454
- // as `(() => void) | undefined`, which conflicts with Transport.onclose
455
- // under exactOptionalPropertyTypes: true. The runtime behaviour is
456
- // identical; the cast is safe.
457
- await server.connect(transport as unknown as Transport);
458
- } else {
459
- reply.code(400).send({
460
- jsonrpc: "2.0",
461
- error: {
462
- code: -32000,
463
- message: "Bad Request: no valid session",
464
- },
465
- id: null,
466
- });
467
- return;
468
- }
469
-
470
- await transport.handleRequest(request.raw, reply.raw, body);
471
- } catch (err) {
472
- if (!reply.sent) {
473
- reply.code(500).send({
474
- jsonrpc: "2.0",
475
- error: { code: -32603, message: "Internal server error" },
476
- id: null,
477
- });
478
- }
479
- throw err;
480
- }
481
- }),
482
- });
483
-
484
- // DELETE — session termination
485
- app.delete(mcpPath, async (request, reply) => {
486
- const sessionId = request.headers["mcp-session-id"] as string | undefined;
487
- if (!sessionId || !transports.has(sessionId)) {
488
- reply.code(400).send("Invalid or missing session ID");
489
- return;
490
- }
491
- const transport = transports.get(sessionId)!;
492
- await transport.handleRequest(request.raw, reply.raw);
493
- });
494
-
495
- // ── Signed-in workspace route (#3591 D15) ─────────────────────────────────
496
- registerWorkspaceRoute(app, `${mcpPath}/workspace`, abuseGuard);
497
- }
498
-
499
- /**
500
- * Build and return a configured Fastify instance that exposes the MCP HTTP
501
- * transport at `config.path`. The instance is not yet listening — callers
502
- * call `.listen()` or `.inject()` (tests). Sets no `trustProxy`, so
503
- * `request.ip` is the socket's address.
504
- *
505
- * @param config - HTTP transport configuration
506
- * @returns Configured Fastify instance (ready to listen or inject)
507
- */
508
- export async function buildHttpTransportApp(
509
- config: HttpTransportConfig,
510
- ): Promise<FastifyInstance> {
511
- const app = Fastify({ logger: false });
512
- await registerHttpTransport(app, config);
513
- return app;
514
- }
515
-
516
- /**
517
- * Start the HTTP transport bound to the configured port.
518
- * Returns the listening Fastify instance.
519
- */
520
- export async function startHttpTransport(
521
- config: HttpTransportConfig & { port: number },
522
- ): Promise<FastifyInstance> {
523
- const app = await buildHttpTransportApp(config);
524
- await app.listen({ port: config.port, host: "0.0.0.0" });
525
- return app;
526
- }