create-ailk 0.5.0 → 0.6.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 (299) hide show
  1. package/README.md +55 -8
  2. package/component-catalog.json +336 -27
  3. package/component-catalog.md +25 -12
  4. package/dist/lib/api-boot-assertion.d.ts +46 -0
  5. package/dist/lib/api-boot-assertion.js +70 -0
  6. package/dist/lib/import-graph.d.ts +29 -0
  7. package/dist/lib/import-graph.js +140 -0
  8. package/dist/module-architecture.d.ts +1 -0
  9. package/dist/module-architecture.js +253 -127
  10. package/dist/surfaces.js +105 -7
  11. package/dist/template-manifest.d.ts +33 -0
  12. package/dist/template-manifest.js +99 -16
  13. package/dist/template-names.d.ts +1 -1
  14. package/dist/template-names.js +1 -0
  15. package/package.json +3 -2
  16. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +22 -2
  17. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +9 -2
  18. package/site-templates/marketing-site/ailk-template.json +1 -1
  19. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +2 -2
  20. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +1 -0
  21. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +10 -2
  22. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +47 -35
  23. package/site-templates/minimalism-site/ailk-template.json +2 -1
  24. package/site-templates/minimalism-site/assets/wordmark-placeholder.svg +28 -0
  25. package/site-templates/minimalism-site/content/en/HomePage/home.mdx +49 -19
  26. package/site-templates/simple-service/TEMPLATE-MANIFEST.json +240 -0
  27. package/site-templates/simple-service/TEMPLATE-MANIFEST.md +278 -0
  28. package/site-templates/simple-service/ailk-template.json +10 -0
  29. package/site-templates/simple-service/content/en/AboutPage/about.mdx +38 -0
  30. package/site-templates/simple-service/content/en/ContactPage/contact.mdx +67 -0
  31. package/site-templates/simple-service/content/en/FAQPage/faq.mdx +56 -0
  32. package/site-templates/simple-service/content/en/HomePage/home.mdx +85 -0
  33. package/site-templates/simple-service/content/en/Service/landscape-design.mdx +40 -0
  34. package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +40 -0
  35. package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +40 -0
  36. package/site-templates/simple-service/content/en/ServicesList/services.mdx +72 -0
  37. package/site-templates/simple-service/provenance.json +4 -0
  38. package/templates/.env.example +72 -7
  39. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +8 -0
  40. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +12 -0
  41. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +12 -0
  42. package/templates/apps/api/.env.example +13 -0
  43. package/templates/apps/api/CLAUDE.md +26 -2
  44. package/templates/apps/api/jest.config.cjs +3 -0
  45. package/templates/apps/api/package.json +1 -0
  46. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +407 -0
  47. package/templates/apps/api/src/__tests__/module-exclusion.test.ts +83 -7
  48. package/templates/apps/api/src/__tests__/server.test.ts +471 -0
  49. package/templates/apps/api/src/__tests__/vercel-handler.test.ts +45 -0
  50. package/templates/apps/api/src/__tests__/workspace-module-registration.test.ts +2 -0
  51. package/templates/apps/api/src/config/index.ts +62 -0
  52. package/templates/apps/api/src/config/modules.ts +7 -3
  53. package/templates/apps/api/src/lib/__mocks__/prisma.ts +238 -2
  54. package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +143 -0
  55. package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +23 -0
  56. package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +125 -0
  57. package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +20 -0
  58. package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +317 -0
  59. package/templates/apps/api/src/lib/__tests__/site.test.ts +238 -0
  60. package/templates/apps/api/src/lib/__tests__/stripe.test.ts +75 -0
  61. package/templates/apps/api/src/lib/auth-email-budget.ts +160 -0
  62. package/templates/apps/api/src/lib/content-adapter.ts +57 -31
  63. package/templates/apps/api/src/lib/deliverable-asset-store.ts +76 -0
  64. package/templates/apps/api/src/lib/error-serializer.ts +23 -3
  65. package/templates/apps/api/src/lib/outbound-http.ts +7 -2
  66. package/templates/apps/api/src/lib/require-commerce-claim.ts +250 -0
  67. package/templates/apps/api/src/lib/site.ts +208 -9
  68. package/templates/apps/api/src/lib/stripe.ts +66 -0
  69. package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +182 -0
  70. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +42 -0
  71. package/templates/apps/api/src/middleware/rate-limit.ts +7 -1
  72. package/templates/apps/api/src/openapi/spec.ts +543 -2
  73. package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +48 -0
  74. package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +309 -0
  75. package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +123 -0
  76. package/templates/apps/api/src/routes/auth/transactional-email.ts +273 -0
  77. package/templates/apps/api/src/routes/auth/user.ts +61 -0
  78. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +434 -0
  79. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +888 -0
  80. package/templates/apps/api/src/routes/checkout/index.ts +34 -0
  81. package/templates/apps/api/src/routes/checkout/session.ts +139 -0
  82. package/templates/apps/api/src/routes/checkout/sessions.ts +197 -0
  83. package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +554 -0
  84. package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +108 -0
  85. package/templates/apps/api/src/routes/content/__tests__/search.test.ts +450 -0
  86. package/templates/apps/api/src/routes/content/get-page.ts +94 -12
  87. package/templates/apps/api/src/routes/content/index.ts +13 -73
  88. package/templates/apps/api/src/routes/content/list-pages.ts +15 -3
  89. package/templates/apps/api/src/routes/content/rate-limit.ts +15 -6
  90. package/templates/apps/api/src/routes/content/search.ts +129 -0
  91. package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +447 -31
  92. package/templates/apps/api/src/routes/leads/index.ts +100 -13
  93. package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +51 -0
  94. package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +351 -0
  95. package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +51 -0
  96. package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +5 -2
  97. package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +4 -1
  98. package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +58 -0
  99. package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +107 -6
  100. package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +87 -2
  101. package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +51 -0
  102. package/templates/apps/api/src/routes/project-listings/start.ts +5 -1
  103. package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +686 -0
  104. package/templates/apps/api/src/routes/requests/confirm.ts +601 -0
  105. package/templates/apps/api/src/routes/requests/index.ts +54 -0
  106. package/templates/apps/api/src/routes/webhooks/README.md +265 -0
  107. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +749 -0
  108. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +330 -0
  109. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +262 -0
  110. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +285 -0
  111. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +213 -0
  112. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +301 -0
  113. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +648 -0
  114. package/templates/apps/api/src/routes/webhooks/index.ts +89 -0
  115. package/templates/apps/api/src/routes/webhooks/stripe.ts +1399 -0
  116. package/templates/apps/api/src/server.ts +439 -49
  117. package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +39 -0
  118. package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +217 -40
  119. package/templates/apps/api/src/services/__tests__/audit-log.test.ts +620 -0
  120. package/templates/apps/api/src/services/__tests__/consent.test.ts +2 -0
  121. package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +300 -5
  122. package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +20 -0
  123. package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +368 -0
  124. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +160 -0
  125. package/templates/apps/api/src/services/__tests__/listing-config.test.ts +166 -0
  126. package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +154 -0
  127. package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +137 -0
  128. package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +444 -0
  129. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +238 -0
  130. package/templates/apps/api/src/services/__tests__/verified-email.test.ts +78 -0
  131. package/templates/apps/api/src/services/abandon-email.ts +8 -2
  132. package/templates/apps/api/src/services/aeo-score.ts +49 -12
  133. package/templates/apps/api/src/services/audit-log.ts +668 -0
  134. package/templates/apps/api/src/services/consent.ts +18 -0
  135. package/templates/apps/api/src/services/default-tenant.ts +70 -31
  136. package/templates/apps/api/src/services/deliverable-fulfillment.ts +141 -13
  137. package/templates/apps/api/src/services/dunning-policy.ts +294 -0
  138. package/templates/apps/api/src/services/entitlements.ts +80 -0
  139. package/templates/apps/api/src/services/lead-promotion.ts +13 -14
  140. package/templates/apps/api/src/services/lead-routing.ts +161 -2
  141. package/templates/apps/api/src/services/leads-inbox.ts +23 -2
  142. package/templates/apps/api/src/services/listing-config.ts +27 -9
  143. package/templates/apps/api/src/services/project-listings.ts +201 -6
  144. package/templates/apps/api/src/services/public-site-resolver.ts +106 -0
  145. package/templates/apps/api/src/services/request-confirm.ts +646 -0
  146. package/templates/apps/api/src/services/revalidation.ts +173 -0
  147. package/templates/apps/api/src/services/verified-email.ts +71 -0
  148. package/templates/apps/api/src/vercel-handler.ts +75 -35
  149. package/templates/apps/mcp/.env.example +17 -0
  150. package/templates/apps/mcp/CLAUDE.md +57 -24
  151. package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +6 -0
  152. package/templates/apps/mcp/__tests__/audit.test.ts +137 -8
  153. package/templates/apps/mcp/__tests__/catalog-drift.test.ts +79 -36
  154. package/templates/apps/mcp/__tests__/get_offerings.test.ts +111 -2
  155. package/templates/apps/mcp/__tests__/get_pricing.test.ts +82 -2
  156. package/templates/apps/mcp/__tests__/http-transport.test.ts +541 -2
  157. package/templates/apps/mcp/__tests__/index.test.ts +39 -0
  158. package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +143 -0
  159. package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +111 -0
  160. package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +65 -0
  161. package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +188 -0
  162. package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +165 -0
  163. package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +124 -0
  164. package/templates/apps/mcp/__tests__/list_pages.test.ts +116 -0
  165. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +7 -1
  166. package/templates/apps/mcp/__tests__/parity.test.ts +10 -7
  167. package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +89 -22
  168. package/templates/apps/mcp/__tests__/read_content.test.ts +322 -1
  169. package/templates/apps/mcp/__tests__/search_content.test.ts +105 -2
  170. package/templates/apps/mcp/__tests__/server.test.ts +67 -14
  171. package/templates/apps/mcp/__tests__/start_purchase.test.ts +252 -0
  172. package/templates/apps/mcp/__tests__/tools/purchase.test.ts +300 -123
  173. package/templates/apps/mcp/jest.config.cjs +13 -0
  174. package/templates/apps/mcp/package.json +2 -0
  175. package/templates/apps/mcp/src/abuse/index.ts +159 -24
  176. package/templates/apps/mcp/src/config/modules.ts +10 -5
  177. package/templates/apps/mcp/src/http-transport.ts +102 -29
  178. package/templates/apps/mcp/src/index.ts +73 -11
  179. package/templates/apps/mcp/src/lib/audit-single-page.ts +90 -3
  180. package/templates/apps/mcp/src/lib/commerce-claim.ts +94 -0
  181. package/templates/apps/mcp/src/lib/content-adapter.ts +113 -0
  182. package/templates/apps/mcp/src/lib/empty-content-adapter.ts +139 -0
  183. package/templates/apps/mcp/src/lib/prisma.ts +39 -0
  184. package/templates/apps/mcp/src/lib/public-workspace.ts +133 -0
  185. package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +59 -0
  186. package/templates/apps/mcp/src/server.ts +59 -35
  187. package/templates/apps/mcp/src/tools/audit.ts +26 -2
  188. package/templates/apps/mcp/src/tools/get_business_hours.ts +4 -3
  189. package/templates/apps/mcp/src/tools/get_faq.ts +4 -3
  190. package/templates/apps/mcp/src/tools/get_locations.ts +5 -3
  191. package/templates/apps/mcp/src/tools/get_offerings.ts +16 -4
  192. package/templates/apps/mcp/src/tools/get_pricing.ts +25 -6
  193. package/templates/apps/mcp/src/tools/get_site_info.ts +4 -3
  194. package/templates/apps/mcp/src/tools/index.ts +6 -4
  195. package/templates/apps/mcp/src/tools/list_pages.ts +4 -3
  196. package/templates/apps/mcp/src/tools/purchase.ts +128 -45
  197. package/templates/apps/mcp/src/tools/read_content.ts +20 -6
  198. package/templates/apps/mcp/src/tools/search_content.ts +11 -4
  199. package/templates/apps/web/.env.example +71 -5
  200. package/templates/apps/web/CLAUDE.md +44 -0
  201. package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +18 -2
  202. package/templates/apps/web/app/.well-known/mcp.json/route.ts +11 -3
  203. package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +282 -0
  204. package/templates/apps/web/app/[locale]/(auth)/__tests__/password-reset.test.tsx +515 -0
  205. package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +89 -0
  206. package/templates/apps/web/app/[locale]/(auth)/forgot-password/page.tsx +109 -0
  207. package/templates/apps/web/app/[locale]/(auth)/layout.tsx +92 -0
  208. package/templates/apps/web/app/[locale]/(auth)/reset-password/page.tsx +135 -0
  209. package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +109 -0
  210. package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/page.test.tsx +48 -2
  211. package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/page.tsx +20 -6
  212. package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +125 -0
  213. package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +96 -0
  214. package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +101 -0
  215. package/templates/apps/web/app/[locale]/(auth)/use-auth-card-flow.ts +102 -0
  216. package/templates/apps/web/app/[locale]/(auth)/verify-email/page.tsx +87 -0
  217. package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +20 -10
  218. package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +84 -0
  219. package/templates/apps/web/app/[locale]/(authed)/account/actions.ts +58 -0
  220. package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +63 -8
  221. package/templates/apps/web/app/[locale]/(authed)/layout.tsx +18 -1
  222. package/templates/apps/web/app/[locale]/cancellation/page.tsx +44 -0
  223. package/templates/apps/web/app/[locale]/layout.tsx +133 -87
  224. package/templates/apps/web/app/[locale]/purchase/__tests__/cancel.test.tsx +162 -0
  225. package/templates/apps/web/app/[locale]/purchase/__tests__/module-scope.test.ts +68 -0
  226. package/templates/apps/web/app/[locale]/purchase/__tests__/success.test.tsx +361 -0
  227. package/templates/apps/web/app/[locale]/purchase/cancel/page.tsx +115 -0
  228. package/templates/apps/web/app/[locale]/purchase/success/page.tsx +307 -0
  229. package/templates/apps/web/app/[locale]/returns/page.tsx +44 -0
  230. package/templates/apps/web/app/[locale]/shipping/page.tsx +44 -0
  231. package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +670 -0
  232. package/templates/apps/web/app/api/revalidate/route.ts +194 -0
  233. package/templates/apps/web/auth.ts +407 -8
  234. package/templates/apps/web/jest.config.cjs +8 -4
  235. package/templates/apps/web/lib/__tests__/auth-email.test.ts +214 -0
  236. package/templates/apps/web/lib/__tests__/auth-routes.test.ts +74 -0
  237. package/templates/apps/web/lib/__tests__/meeting-slugs.test.ts +72 -0
  238. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +18 -1
  239. package/templates/apps/web/lib/auth-email.ts +318 -0
  240. package/templates/apps/web/lib/auth-env.ts +85 -0
  241. package/templates/apps/web/lib/auth-routes.ts +55 -0
  242. package/templates/apps/web/lib/meeting-slugs.ts +53 -0
  243. package/templates/apps/web/lib/telemetry-scrub.ts +5 -1
  244. package/templates/apps/web/messages/en.json +187 -0
  245. package/templates/apps/web/package.json +2 -1
  246. package/templates/apps/web/src/lib/commerce-claim.ts +33 -0
  247. package/templates/apps/web/src/lib/commerce-sections.ts +61 -0
  248. package/templates/content/en/CancellationPolicyPage/cancellation.mdx +108 -0
  249. package/templates/content/en/ReturnsPolicyPage/returns.mdx +108 -0
  250. package/templates/content/en/ShippingPolicyPage/shipping.mdx +108 -0
  251. package/templates/database/CHANGELOG.md +142 -0
  252. package/templates/database/README.md +10 -3
  253. package/templates/database/__tests__/appointment.db.test.ts +106 -0
  254. package/templates/database/__tests__/artifact-content-store.db.test.ts +316 -0
  255. package/templates/database/__tests__/composite-fence.db.test.ts +206 -0
  256. package/templates/database/__tests__/fence-fan-out.db.test.ts +711 -0
  257. package/templates/database/__tests__/fixtures/appointment-create-probe.ts +79 -0
  258. package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +100 -0
  259. package/templates/database/__tests__/flow-workspace-key.db.test.ts +263 -0
  260. package/templates/database/__tests__/prefixed-ids.db.test.ts +85 -9
  261. package/templates/database/__tests__/project-listing-consent-at.db.test.ts +111 -0
  262. package/templates/database/__tests__/tenancy.test.ts +141 -0
  263. package/templates/database/config/schema.prisma +79 -2
  264. package/templates/database/content/schema.prisma +87 -11
  265. package/templates/database/inbox/schema.prisma +452 -9
  266. package/templates/database/jest.config.cjs +5 -3
  267. package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +15 -0
  268. package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +158 -0
  269. package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +40 -0
  270. package/templates/database/migrations/20260918120000_add_appointment/migration.sql +67 -0
  271. package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +70 -0
  272. package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +181 -0
  273. package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +172 -0
  274. package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +41 -0
  275. package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +185 -0
  276. package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +70 -0
  277. package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +57 -0
  278. package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +68 -0
  279. package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +1067 -0
  280. package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +210 -0
  281. package/templates/database/package.json +1 -1
  282. package/templates/database/tenancy.ts +86 -1
  283. package/templates/database/tsconfig.json +1 -0
  284. package/versions.json +34 -34
  285. package/templates/apps/api/src/routes/content/__tests__/create.test.ts +0 -253
  286. package/templates/apps/api/src/routes/content/__tests__/delete.test.ts +0 -215
  287. package/templates/apps/api/src/routes/content/__tests__/update.test.ts +0 -266
  288. package/templates/apps/api/src/routes/content/create.ts +0 -115
  289. package/templates/apps/api/src/routes/content/delete.ts +0 -82
  290. package/templates/apps/api/src/routes/content/update.ts +0 -112
  291. package/templates/apps/mcp/__tests__/create_page.test.ts +0 -202
  292. package/templates/apps/mcp/__tests__/delete_page.test.ts +0 -177
  293. package/templates/apps/mcp/__tests__/update_page.test.ts +0 -196
  294. package/templates/apps/mcp/src/tools/create_page.ts +0 -96
  295. package/templates/apps/mcp/src/tools/delete_page.ts +0 -74
  296. package/templates/apps/mcp/src/tools/update_page.ts +0 -92
  297. package/templates/apps/web/app/[locale]/sign-in/sign-in-card.tsx +0 -123
  298. /package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/next-path.test.ts +0 -0
  299. /package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/next-path.ts +0 -0
@@ -1,96 +0,0 @@
1
- // oss: false
2
- /**
3
- * create_page — Paid-tier MCP tool for authoring a new content page.
4
- *
5
- * D14a Stage 1 Unit C — wires the McpServer create_page handler to the
6
- * ContentAdapter.createPage method (Stage 1 Unit A implements the MDX
7
- * adapter; tests inject a fake adapter).
8
- *
9
- * Surface contract: validates input via FrontmatterSchema.extend({ body }),
10
- * runs the Paid-tier license guard, calls adapter.createPage, and maps adapter
11
- * errors to canonical MCP error bodies (see apps/mcp/src/lib/errors.ts).
12
- *
13
- * Input shape mirrors the Stage 0 catalog entry in
14
- * packages/metadata/src/mcp-tool-catalog.ts. Catalog parses a permissive
15
- * outer shape (`page: record`); this handler parses strictly via
16
- * FrontmatterSchema so bad frontmatter surfaces as a validation_failed body.
17
- */
18
-
19
- import { join } from "node:path";
20
-
21
- import {
22
- FrontmatterSchema,
23
- createMdxAdapter,
24
- mapAdapterError,
25
- type ContentAdapter,
26
- } from "@working-theory/content-adapters";
27
- import { z } from "zod";
28
-
29
- import { validationError, type ErrorBody } from "../lib/errors.js";
30
- import { requirePaidTier } from "../lib/require-paid-tier.js";
31
-
32
- const CreatePageInputSchema = FrontmatterSchema.extend({
33
- body: z.string().min(1),
34
- });
35
-
36
- interface CreatePageSuccess {
37
- page: Record<string, unknown>;
38
- version: string;
39
- }
40
-
41
- export type CreatePageResult = CreatePageSuccess | ErrorBody;
42
-
43
- export interface CreatePageInput {
44
- type: string;
45
- slug: string;
46
- page: Record<string, unknown>;
47
- body: string;
48
- }
49
-
50
- /**
51
- * ailkCreatePage handler.
52
- *
53
- * Optional `adapter` injection mirrors the Q3 resolution in the resource plan
54
- * (tests construct adapters directly with isolated content roots). When
55
- * omitted, falls back to the default MDX adapter rooted at process.cwd()/content.
56
- */
57
- export async function ailkCreatePage(
58
- input: CreatePageInput,
59
- adapter?: ContentAdapter,
60
- ): Promise<CreatePageResult> {
61
- const guard = await requirePaidTier();
62
- if (guard) return guard;
63
-
64
- const parsed = CreatePageInputSchema.safeParse({
65
- ...input.page,
66
- type: input.type,
67
- slug: input.slug,
68
- body: input.body,
69
- });
70
-
71
- if (!parsed.success) {
72
- return validationError("Invalid frontmatter or body for create_page.", {
73
- issues: parsed.error.issues,
74
- });
75
- }
76
-
77
- const resolved =
78
- adapter ??
79
- createMdxAdapter({ contentRoot: join(process.cwd(), "content") });
80
-
81
- try {
82
- const result = await resolved.createPage(
83
- parsed.data.type,
84
- parsed.data.slug,
85
- parsed.data,
86
- );
87
- return { page: result.page, version: result.version };
88
- } catch (err) {
89
- const mapped = mapAdapterError(err, {
90
- type: parsed.data.type,
91
- slug: parsed.data.slug,
92
- });
93
- if (mapped) return mapped;
94
- throw err;
95
- }
96
- }
@@ -1,74 +0,0 @@
1
- // oss: false
2
- /**
3
- * delete_page — Paid-tier MCP tool for removing a content page.
4
- *
5
- * D14a Stage 1 Unit C — wires McpServer delete_page to ContentAdapter.deletePage.
6
- * Mandatory optimistic locking: caller supplies `ifMatch`; stale or missing
7
- * tokens yield canonical conflict bodies.
8
- *
9
- * Success body is `{ ok: true }` per the Stage 0 catalog `deletePageOutputSchema`.
10
- */
11
-
12
- import { join } from "node:path";
13
-
14
- import {
15
- SCHEMA_ORG_TYPES,
16
- SLUG_PATTERN,
17
- createMdxAdapter,
18
- mapAdapterError,
19
- type ContentAdapter,
20
- } from "@working-theory/content-adapters";
21
- import { z } from "zod";
22
-
23
- import { validationError, type ErrorBody } from "../lib/errors.js";
24
- import { requirePaidTier } from "../lib/require-paid-tier.js";
25
-
26
- const DeletePageInputSchema = z.object({
27
- type: z.enum(SCHEMA_ORG_TYPES),
28
- // Defence-in-depth slug allowlist matches create_page / update_page;
29
- // the adapter also enforces the pattern, but a fail-fast validation_failed
30
- // here keeps the tool's surface contract consistent (issue #398).
31
- slug: z.string().regex(SLUG_PATTERN),
32
- ifMatch: z.string().min(1),
33
- });
34
-
35
- interface DeletePageSuccess {
36
- ok: true;
37
- }
38
-
39
- export type DeletePageResult = DeletePageSuccess | ErrorBody;
40
-
41
- export interface DeletePageInput {
42
- type: string;
43
- slug: string;
44
- ifMatch: string;
45
- }
46
-
47
- export async function ailkDeletePage(
48
- input: DeletePageInput,
49
- adapter?: ContentAdapter,
50
- ): Promise<DeletePageResult> {
51
- const guard = await requirePaidTier();
52
- if (guard) return guard;
53
-
54
- const parsed = DeletePageInputSchema.safeParse(input);
55
- if (!parsed.success) {
56
- return validationError("Invalid input for delete_page.", {
57
- issues: parsed.error.issues,
58
- });
59
- }
60
-
61
- const { type, slug, ifMatch } = parsed.data;
62
- const resolved =
63
- adapter ??
64
- createMdxAdapter({ contentRoot: join(process.cwd(), "content") });
65
-
66
- try {
67
- await resolved.deletePage(type, slug, { ifMatch });
68
- return { ok: true };
69
- } catch (err) {
70
- const mapped = mapAdapterError(err, { type, slug });
71
- if (mapped) return mapped;
72
- throw err;
73
- }
74
- }
@@ -1,92 +0,0 @@
1
- // oss: false
2
- /**
3
- * update_page — Paid-tier MCP tool for revising an existing content page.
4
- *
5
- * D14a Stage 1 Unit C — wires McpServer update_page to ContentAdapter.updatePage.
6
- * Mandatory optimistic locking: caller supplies `ifMatch` (version token from a
7
- * prior read or write); stale or missing tokens yield canonical conflict bodies.
8
- *
9
- * Validation strategy mirrors create_page — strict parse via
10
- * FrontmatterSchema.extend({ body, ifMatch }) inside the handler so bad
11
- * frontmatter surfaces as validation_failed (the Stage 0 catalog uses a
12
- * permissive outer shape because @working-theory/metadata cannot import
13
- * @working-theory/content-adapters).
14
- */
15
-
16
- import { join } from "node:path";
17
-
18
- import {
19
- FrontmatterSchema,
20
- createMdxAdapter,
21
- mapAdapterError,
22
- type ContentAdapter,
23
- } from "@working-theory/content-adapters";
24
- import { z } from "zod";
25
-
26
- import { validationError, type ErrorBody } from "../lib/errors.js";
27
- import { requirePaidTier } from "../lib/require-paid-tier.js";
28
-
29
- const UpdatePageInputSchema = FrontmatterSchema.extend({
30
- body: z.string().min(1),
31
- ifMatch: z.string().min(1),
32
- });
33
-
34
- interface UpdatePageSuccess {
35
- page: Record<string, unknown>;
36
- version: string;
37
- }
38
-
39
- export type UpdatePageResult = UpdatePageSuccess | ErrorBody;
40
-
41
- export interface UpdatePageInput {
42
- type: string;
43
- slug: string;
44
- page: Record<string, unknown>;
45
- body: string;
46
- ifMatch: string;
47
- }
48
-
49
- export async function ailkUpdatePage(
50
- input: UpdatePageInput,
51
- adapter?: ContentAdapter,
52
- ): Promise<UpdatePageResult> {
53
- const guard = await requirePaidTier();
54
- if (guard) return guard;
55
-
56
- const parsed = UpdatePageInputSchema.safeParse({
57
- ...input.page,
58
- type: input.type,
59
- slug: input.slug,
60
- body: input.body,
61
- ifMatch: input.ifMatch,
62
- });
63
-
64
- if (!parsed.success) {
65
- return validationError(
66
- "Invalid frontmatter, body, or ifMatch for update_page.",
67
- { issues: parsed.error.issues },
68
- );
69
- }
70
-
71
- const { ifMatch, ...pageWithBody } = parsed.data;
72
- const resolved =
73
- adapter ??
74
- createMdxAdapter({ contentRoot: join(process.cwd(), "content") });
75
-
76
- try {
77
- const result = await resolved.updatePage(
78
- pageWithBody.type,
79
- pageWithBody.slug,
80
- pageWithBody,
81
- { ifMatch },
82
- );
83
- return { page: result.page, version: result.version };
84
- } catch (err) {
85
- const mapped = mapAdapterError(err, {
86
- type: pageWithBody.type,
87
- slug: pageWithBody.slug,
88
- });
89
- if (mapped) return mapped;
90
- throw err;
91
- }
92
- }
@@ -1,123 +0,0 @@
1
- "use client"; // Better Auth's client calls (signIn.social / signIn.email) + error state
2
-
3
- /**
4
- * SignInCard — the /sign-in page's client island (#4984).
5
- *
6
- * Composes the shipped `AuthCard` block (`intent="sign-in"`, `footer="none"`)
7
- * and wires its provider buttons / password form to the Better Auth client,
8
- * using the SAME `createAuthClient()` idiom the `(authed)` group's
9
- * `SignInGate` uses. The page (RSC) decides providers + method from auth-env
10
- * and hands them in; this component never reads env itself.
11
- *
12
- * No sign-up affordance anywhere: `footer="none"` drops the "Not a member?
13
- * Create an account" cross-link (Better Auth `emailAndPassword.disableSignUp`
14
- * posture).
15
- *
16
- * Password path: `apps/web/auth.ts` does not enable `emailAndPassword` today,
17
- * so `signIn.email` is wired but inert (Better Auth answers with an error)
18
- * until an operator enables it server-side — the page only selects
19
- * `method="password"` when auth-env reports the "email" provider.
20
- *
21
- * Zero providers (method sso, providers []): the card renders in its inert
22
- * state — heading + `notConfiguredSubhead`, no buttons, no form. Never a
23
- * fabricated session.
24
- *
25
- * Error surface: AuthCard's `errors` prop is per-field. A failed provider
26
- * launch lands on `errors.email` — the social row sits inside the password
27
- * form beside the email field, so it renders there. The SSO body has no
28
- * fields at all, so for `method="sso"` the same message is rendered as an
29
- * `Alert` above the card instead.
30
- */
31
-
32
- import { AuthCard, type AuthCardLabels } from "@working-theory/ui/blocks";
33
- import { Alert, AlertDescription } from "@working-theory/ui/primitives";
34
- import { createAuthClient } from "better-auth/react";
35
- import type { ReactElement, ReactNode } from "react";
36
- import { useState } from "react";
37
-
38
- const authClient = createAuthClient();
39
-
40
- /** The OAuth providers this page can launch — a subset of AuthCard's. */
41
- export type SignInProvider = "google" | "github";
42
-
43
- export interface SignInCardProps {
44
- /** Active OAuth providers, exactly as auth-env reports them. */
45
- providers: SignInProvider[];
46
- /** "password" when the email provider is active; otherwise "sso". */
47
- method: "sso" | "password";
48
- /** Sanitised post-sign-in path (see `next-path.ts`). */
49
- next: string;
50
- /** Brand mark rendered top-center inside the card. */
51
- logo?: ReactNode;
52
- /** Translated AuthCard labels (resolved server-side by the page). */
53
- labels: AuthCardLabels;
54
- /** Subhead shown when no provider is configured. */
55
- notConfiguredSubhead: string;
56
- /** Translated error copy. */
57
- errorLabels: { signInFailed: string; providerFailed: string };
58
- }
59
-
60
- type FieldErrors = { email?: string; password?: string };
61
-
62
- export function SignInCard({
63
- providers,
64
- method,
65
- next,
66
- logo,
67
- labels,
68
- notConfiguredSubhead,
69
- errorLabels,
70
- }: SignInCardProps): ReactElement {
71
- const [errors, setErrors] = useState<FieldErrors>({});
72
- const [providerError, setProviderError] = useState<string | null>(null);
73
-
74
- const notConfigured = method === "sso" && providers.length === 0;
75
-
76
- const launchProvider = async (provider: SignInProvider): Promise<void> => {
77
- setProviderError(null);
78
- // Better Auth reports a failed launch as `{ error }`; a network/runtime
79
- // failure rejects. Both land on the same providerFailed message.
80
- const failed = await authClient.signIn
81
- .social({ provider, callbackURL: next })
82
- .then((res) => Boolean(res?.error), () => true);
83
- if (failed) {
84
- setProviderError(errorLabels.providerFailed);
85
- setErrors((prev) => ({ ...prev, email: errorLabels.providerFailed }));
86
- }
87
- };
88
-
89
- const submitPassword = async (email: string, password: string): Promise<void> => {
90
- setErrors({});
91
- const res = await authClient.signIn.email({ email, password, callbackURL: next });
92
- if (res?.error) setErrors({ password: errorLabels.signInFailed });
93
- };
94
-
95
- return (
96
- <div
97
- className="flex min-h-screen items-center justify-center py-section"
98
- data-testid="sign-in-page"
99
- >
100
- <div className="flex w-full max-w-md flex-col gap-4">
101
- {method === "sso" && providerError ? (
102
- <Alert variant="error" data-testid="sign-in-provider-error">
103
- <AlertDescription>{providerError}</AlertDescription>
104
- </Alert>
105
- ) : null}
106
- <AuthCard
107
- intent="sign-in"
108
- method={method}
109
- footer="none"
110
- {...(logo !== undefined ? { logo } : {})}
111
- {...(notConfigured ? { subhead: notConfiguredSubhead } : {})}
112
- providers={providers.map((provider) => ({
113
- provider,
114
- onClick: () => void launchProvider(provider),
115
- }))}
116
- onSubmit={(data) => void submitPassword(data.email, data.password ?? "")}
117
- errors={errors}
118
- labels={labels}
119
- />
120
- </div>
121
- </div>
122
- );
123
- }