create-ailk 0.1.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 (533) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +39 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +80 -0
  5. package/dist/copy.d.ts +8 -0
  6. package/dist/copy.js +109 -0
  7. package/dist/index.d.ts +10 -0
  8. package/dist/index.js +10 -0
  9. package/dist/lib/pro-callout.d.ts +12 -0
  10. package/dist/lib/pro-callout.js +20 -0
  11. package/dist/parse-args.d.ts +13 -0
  12. package/dist/parse-args.js +81 -0
  13. package/dist/programmatic.d.ts +49 -0
  14. package/dist/programmatic.js +89 -0
  15. package/dist/substitute.d.ts +31 -0
  16. package/dist/substitute.js +45 -0
  17. package/dist/validate.d.ts +8 -0
  18. package/dist/validate.js +70 -0
  19. package/package.json +47 -0
  20. package/templates/.claude/.gitkeep +0 -0
  21. package/templates/.claude/agents/web.md +80 -0
  22. package/templates/.claude/rules/architecture.md +62 -0
  23. package/templates/.claude/rules/preserve-existing-style.md +51 -0
  24. package/templates/.claude/skills/README.md +43 -0
  25. package/templates/.claude/skills/add-schema/SKILL.md +270 -0
  26. package/templates/.claude/skills/add-schema/references/conflict-handling.md +200 -0
  27. package/templates/.claude/skills/add-schema/references/file-finding.md +123 -0
  28. package/templates/.claude/skills/add-schema/references/schema-types.md +131 -0
  29. package/templates/.claude/skills/audit-site/SKILL.md +213 -0
  30. package/templates/.claude/skills/audit-site/references/common-errors.md +113 -0
  31. package/templates/.claude/skills/audit-site/references/findings-glossary.md +138 -0
  32. package/templates/.claude/skills/audit-site/references/severity-levels.md +114 -0
  33. package/templates/.claude/skills/provision-config/SKILL.md +243 -0
  34. package/templates/.claude/skills/provision-config/references/env-vars-template.md +184 -0
  35. package/templates/.claude/skills/provision-config/references/runbook-template.md +248 -0
  36. package/templates/.claude/skills/provision-config/references/vercel-json-template.md +98 -0
  37. package/templates/.claude/skills/scaffold-auth/SKILL.md +261 -0
  38. package/templates/.claude/skills/scaffold-auth/references/env-vars.md +91 -0
  39. package/templates/.claude/skills/scaffold-auth/references/oauth-app-setup.md +171 -0
  40. package/templates/.claude/skills/scaffold-commerce/SKILL.md +310 -0
  41. package/templates/.claude/skills/scaffold-commerce/references/lookup-keys-template.md +71 -0
  42. package/templates/.claude/skills/scaffold-commerce/references/marketplace-brand-pages.md +83 -0
  43. package/templates/.claude/skills/scaffold-commerce/templates/marketplace-cta-route.tsx.tmpl +72 -0
  44. package/templates/.claude/skills/scaffold-page/SKILL.md +243 -0
  45. package/templates/.claude/skills/scaffold-page/references/page-types.md +169 -0
  46. package/templates/.claude/skills/scaffold-page/templates/content.mdx.tmpl +28 -0
  47. package/templates/.claude/skills/scaffold-page/templates/route.tsx.tmpl +28 -0
  48. package/templates/.claude/skills/suggest-site-pages/SKILL.md +242 -0
  49. package/templates/.claude/skills/suggest-site-pages/references/categories.md +287 -0
  50. package/templates/.env.example +205 -0
  51. package/templates/.gitkeep +2 -0
  52. package/templates/CLAUDE.md +142 -0
  53. package/templates/CONVENTIONS.md +222 -0
  54. package/templates/README.md +110 -0
  55. package/templates/apps/api/.env.example +40 -0
  56. package/templates/apps/api/CLAUDE.md +63 -0
  57. package/templates/apps/api/api/index.ts +144 -0
  58. package/templates/apps/api/jest.config.cjs +74 -0
  59. package/templates/apps/api/package.json +54 -0
  60. package/templates/apps/api/src/__tests__/factories/content-fixture.ts +138 -0
  61. package/templates/apps/api/src/__tests__/factories/index.ts +70 -0
  62. package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +82 -0
  63. package/templates/apps/api/src/__tests__/index.test.ts +118 -0
  64. package/templates/apps/api/src/__tests__/server.test.ts +207 -0
  65. package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +126 -0
  66. package/templates/apps/api/src/__tests__/setup.ts +24 -0
  67. package/templates/apps/api/src/cli.ts +30 -0
  68. package/templates/apps/api/src/config/__tests__/index.test.ts +97 -0
  69. package/templates/apps/api/src/config/index.ts +56 -0
  70. package/templates/apps/api/src/index.ts +32 -0
  71. package/templates/apps/api/src/lib/__mocks__/prisma-client.js +15 -0
  72. package/templates/apps/api/src/lib/__mocks__/prisma.ts +45 -0
  73. package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +178 -0
  74. package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +100 -0
  75. package/templates/apps/api/src/lib/__tests__/errors.test.ts +94 -0
  76. package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +144 -0
  77. package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +8 -0
  78. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +227 -0
  79. package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +125 -0
  80. package/templates/apps/api/src/lib/__tests__/prisma.test.ts +165 -0
  81. package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +129 -0
  82. package/templates/apps/api/src/lib/__tests__/stripe.test.ts +74 -0
  83. package/templates/apps/api/src/lib/content-adapter.ts +86 -0
  84. package/templates/apps/api/src/lib/error-serializer.ts +77 -0
  85. package/templates/apps/api/src/lib/errors.ts +95 -0
  86. package/templates/apps/api/src/lib/file-fallback.ts +87 -0
  87. package/templates/apps/api/src/lib/lead-capture-store.ts +110 -0
  88. package/templates/apps/api/src/lib/locales.ts +201 -0
  89. package/templates/apps/api/src/lib/outbound-http.ts +122 -0
  90. package/templates/apps/api/src/lib/prisma.ts +21 -0
  91. package/templates/apps/api/src/lib/require-paid-tier.ts +53 -0
  92. package/templates/apps/api/src/lib/stripe.ts +30 -0
  93. package/templates/apps/api/src/lib/webhook-idempotency.ts +92 -0
  94. package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +111 -0
  95. package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +172 -0
  96. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +119 -0
  97. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +138 -0
  98. package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +149 -0
  99. package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +139 -0
  100. package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +175 -0
  101. package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +76 -0
  102. package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +153 -0
  103. package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +72 -0
  104. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +292 -0
  105. package/templates/apps/api/src/middleware/auth.ts +246 -0
  106. package/templates/apps/api/src/middleware/rate-limit.ts +132 -0
  107. package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +129 -0
  108. package/templates/apps/api/src/openapi/index.ts +12 -0
  109. package/templates/apps/api/src/openapi/spec.ts +408 -0
  110. package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +193 -0
  111. package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +201 -0
  112. package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +294 -0
  113. package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +486 -0
  114. package/templates/apps/api/src/routes/auth/tokens.ts +199 -0
  115. package/templates/apps/api/src/routes/auth/user.ts +244 -0
  116. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +588 -0
  117. package/templates/apps/api/src/routes/checkout/index.ts +13 -0
  118. package/templates/apps/api/src/routes/checkout/sessions.ts +185 -0
  119. package/templates/apps/api/src/routes/content/__tests__/create.test.ts +239 -0
  120. package/templates/apps/api/src/routes/content/__tests__/delete.test.ts +201 -0
  121. package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +141 -0
  122. package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +122 -0
  123. package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +44 -0
  124. package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +118 -0
  125. package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +51 -0
  126. package/templates/apps/api/src/routes/content/__tests__/update.test.ts +252 -0
  127. package/templates/apps/api/src/routes/content/create.ts +114 -0
  128. package/templates/apps/api/src/routes/content/delete.ts +81 -0
  129. package/templates/apps/api/src/routes/content/get-page.ts +98 -0
  130. package/templates/apps/api/src/routes/content/index.ts +32 -0
  131. package/templates/apps/api/src/routes/content/list-pages.ts +83 -0
  132. package/templates/apps/api/src/routes/content/list-types.ts +19 -0
  133. package/templates/apps/api/src/routes/content/rate-limit.ts +13 -0
  134. package/templates/apps/api/src/routes/content/slug.ts +9 -0
  135. package/templates/apps/api/src/routes/content/update.ts +111 -0
  136. package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +415 -0
  137. package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +165 -0
  138. package/templates/apps/api/src/routes/leads/index.ts +130 -0
  139. package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +296 -0
  140. package/templates/apps/api/src/routes/test/auth/session.ts +141 -0
  141. package/templates/apps/api/src/routes/webhooks/README.md +57 -0
  142. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +247 -0
  143. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +198 -0
  144. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +633 -0
  145. package/templates/apps/api/src/routes/webhooks/index.ts +41 -0
  146. package/templates/apps/api/src/routes/webhooks/stripe.ts +253 -0
  147. package/templates/apps/api/src/server.ts +157 -0
  148. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +395 -0
  149. package/templates/apps/api/src/services/enrichment-shim.ts +53 -0
  150. package/templates/apps/api/src/services/lead-routing.ts +338 -0
  151. package/templates/apps/api/tsconfig.json +34 -0
  152. package/templates/apps/api/vercel.json +17 -0
  153. package/templates/apps/mcp/.env.example +52 -0
  154. package/templates/apps/mcp/CLAUDE.md +84 -0
  155. package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +52 -0
  156. package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +46 -0
  157. package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +36 -0
  158. package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +54 -0
  159. package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +110 -0
  160. package/templates/apps/mcp/__tests__/audit-single-page.test.ts +213 -0
  161. package/templates/apps/mcp/__tests__/audit.test.ts +217 -0
  162. package/templates/apps/mcp/__tests__/catalog-drift.test.ts +52 -0
  163. package/templates/apps/mcp/__tests__/create_page.test.ts +201 -0
  164. package/templates/apps/mcp/__tests__/delete_page.test.ts +176 -0
  165. package/templates/apps/mcp/__tests__/get_business_hours.test.ts +82 -0
  166. package/templates/apps/mcp/__tests__/get_faq.test.ts +80 -0
  167. package/templates/apps/mcp/__tests__/get_locations.test.ts +65 -0
  168. package/templates/apps/mcp/__tests__/get_offerings.test.ts +90 -0
  169. package/templates/apps/mcp/__tests__/get_pricing.test.ts +80 -0
  170. package/templates/apps/mcp/__tests__/get_site_info.test.ts +81 -0
  171. package/templates/apps/mcp/__tests__/http-transport.test.ts +323 -0
  172. package/templates/apps/mcp/__tests__/lib/errors.test.ts +75 -0
  173. package/templates/apps/mcp/__tests__/lib/require-paid-tier.test.ts +75 -0
  174. package/templates/apps/mcp/__tests__/list_pages.test.ts +112 -0
  175. package/templates/apps/mcp/__tests__/locale.test.ts +135 -0
  176. package/templates/apps/mcp/__tests__/parity.test.ts +205 -0
  177. package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +34 -0
  178. package/templates/apps/mcp/__tests__/read_content.test.ts +153 -0
  179. package/templates/apps/mcp/__tests__/request_callback.test.ts +163 -0
  180. package/templates/apps/mcp/__tests__/search_content.test.ts +153 -0
  181. package/templates/apps/mcp/__tests__/server.test.ts +115 -0
  182. package/templates/apps/mcp/__tests__/submit_lead.test.ts +165 -0
  183. package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +161 -0
  184. package/templates/apps/mcp/__tests__/tools/purchase.test.ts +227 -0
  185. package/templates/apps/mcp/__tests__/tools/scaffold.test.ts +237 -0
  186. package/templates/apps/mcp/__tests__/update_page.test.ts +195 -0
  187. package/templates/apps/mcp/jest.config.cjs +82 -0
  188. package/templates/apps/mcp/package.json +37 -0
  189. package/templates/apps/mcp/src/abuse/daily-cap.ts +47 -0
  190. package/templates/apps/mcp/src/abuse/email-validator.ts +25 -0
  191. package/templates/apps/mcp/src/abuse/honeypot.ts +21 -0
  192. package/templates/apps/mcp/src/abuse/index.ts +111 -0
  193. package/templates/apps/mcp/src/abuse/user-agent-deny.ts +58 -0
  194. package/templates/apps/mcp/src/http-transport.ts +303 -0
  195. package/templates/apps/mcp/src/index.ts +67 -0
  196. package/templates/apps/mcp/src/lib/audit-single-page.ts +194 -0
  197. package/templates/apps/mcp/src/lib/errors.ts +61 -0
  198. package/templates/apps/mcp/src/lib/locales.ts +171 -0
  199. package/templates/apps/mcp/src/lib/require-paid-tier.ts +44 -0
  200. package/templates/apps/mcp/src/lib/resolve-locale.ts +30 -0
  201. package/templates/apps/mcp/src/server.ts +139 -0
  202. package/templates/apps/mcp/src/tools/audit.ts +103 -0
  203. package/templates/apps/mcp/src/tools/capture_lead.ts +52 -0
  204. package/templates/apps/mcp/src/tools/create_page.ts +95 -0
  205. package/templates/apps/mcp/src/tools/delete_page.ts +73 -0
  206. package/templates/apps/mcp/src/tools/get_business_hours.ts +66 -0
  207. package/templates/apps/mcp/src/tools/get_faq.ts +69 -0
  208. package/templates/apps/mcp/src/tools/get_locations.ts +85 -0
  209. package/templates/apps/mcp/src/tools/get_offerings.ts +66 -0
  210. package/templates/apps/mcp/src/tools/get_pricing.ts +74 -0
  211. package/templates/apps/mcp/src/tools/get_site_info.ts +84 -0
  212. package/templates/apps/mcp/src/tools/index.ts +125 -0
  213. package/templates/apps/mcp/src/tools/list_pages.ts +72 -0
  214. package/templates/apps/mcp/src/tools/purchase.ts +89 -0
  215. package/templates/apps/mcp/src/tools/read_content.ts +61 -0
  216. package/templates/apps/mcp/src/tools/request_callback.ts +51 -0
  217. package/templates/apps/mcp/src/tools/scaffold.ts +119 -0
  218. package/templates/apps/mcp/src/tools/search_content.ts +59 -0
  219. package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +47 -0
  220. package/templates/apps/mcp/src/tools/update_page.ts +91 -0
  221. package/templates/apps/mcp/tsconfig.json +19 -0
  222. package/templates/apps/web/.env.example +47 -0
  223. package/templates/apps/web/CLAUDE.md +81 -0
  224. package/templates/apps/web/__tests__/auth/adversarial/cookie-attributes.test.ts +94 -0
  225. package/templates/apps/web/__tests__/auth/adversarial/oauth-state-parameter.test.ts +75 -0
  226. package/templates/apps/web/__tests__/auth/adversarial/redirect-uri-allowlist.test.ts +82 -0
  227. package/templates/apps/web/__tests__/auth/env-helpers.test.ts +168 -0
  228. package/templates/apps/web/__tests__/authority-list-routes.test.tsx +208 -0
  229. package/templates/apps/web/__tests__/better-stack.test.ts +66 -0
  230. package/templates/apps/web/__tests__/blog-dir-resolution.test.ts +87 -0
  231. package/templates/apps/web/__tests__/blog-source-populated.test.ts +130 -0
  232. package/templates/apps/web/__tests__/data-testid-coverage.test.tsx +60 -0
  233. package/templates/apps/web/__tests__/google-analytics.test.tsx +104 -0
  234. package/templates/apps/web/__tests__/i18n/middleware.test.ts +119 -0
  235. package/templates/apps/web/__tests__/i18n/routing.test.ts +114 -0
  236. package/templates/apps/web/__tests__/i18n/translations.test.ts +191 -0
  237. package/templates/apps/web/__tests__/json-ld.test.ts +98 -0
  238. package/templates/apps/web/__tests__/knowledge-events-routes.test.tsx +580 -0
  239. package/templates/apps/web/__tests__/layout-stealth.test.ts +39 -0
  240. package/templates/apps/web/__tests__/lighthouse-fixtures/improvement-image-shrink.tsx +103 -0
  241. package/templates/apps/web/__tests__/lighthouse-fixtures/override-fixture.md +114 -0
  242. package/templates/apps/web/__tests__/lighthouse-fixtures/regression-bloat.tsx +94 -0
  243. package/templates/apps/web/__tests__/page.test.tsx +230 -0
  244. package/templates/apps/web/__tests__/products-services-phase1.test.tsx +321 -0
  245. package/templates/apps/web/__tests__/projects-routes.test.tsx +392 -0
  246. package/templates/apps/web/__tests__/resources-downloads-integrations-phase2.test.tsx +475 -0
  247. package/templates/apps/web/__tests__/routes/ai-plugin-json.test.ts +53 -0
  248. package/templates/apps/web/__tests__/routes/blog-route.test.tsx +191 -0
  249. package/templates/apps/web/__tests__/routes/llms-txt.test.ts +123 -0
  250. package/templates/apps/web/__tests__/routes/robots-txt.test.ts +52 -0
  251. package/templates/apps/web/__tests__/routes/sitemap-xml.test.ts +78 -0
  252. package/templates/apps/web/__tests__/routes/well-known-mcp.test.ts +203 -0
  253. package/templates/apps/web/__tests__/section-routes.test.tsx +693 -0
  254. package/templates/apps/web/__tests__/security-headers.test.ts +201 -0
  255. package/templates/apps/web/__tests__/sentry-config.test.ts +116 -0
  256. package/templates/apps/web/__tests__/setup.ts +82 -0
  257. package/templates/apps/web/__tests__/sitemap-locales.test.ts +415 -0
  258. package/templates/apps/web/__tests__/standalone-informational-routes.test.tsx +844 -0
  259. package/templates/apps/web/app/.well-known/ai-plugin.json/route.ts +81 -0
  260. package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +110 -0
  261. package/templates/apps/web/app/.well-known/mcp.json/route.ts +58 -0
  262. package/templates/apps/web/app/[locale]/__tests__/layout.test.tsx +120 -0
  263. package/templates/apps/web/app/[locale]/__tests__/page-renderer-migration.test.tsx +202 -0
  264. package/templates/apps/web/app/[locale]/about/page.tsx +31 -0
  265. package/templates/apps/web/app/[locale]/blog/[[...slug]]/page.tsx +173 -0
  266. package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +45 -0
  267. package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +117 -0
  268. package/templates/apps/web/app/[locale]/careers/page.tsx +25 -0
  269. package/templates/apps/web/app/[locale]/case-studies/[slug]/page.tsx +44 -0
  270. package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +113 -0
  271. package/templates/apps/web/app/[locale]/case-studies/page.tsx +25 -0
  272. package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +63 -0
  273. package/templates/apps/web/app/[locale]/clients/page.tsx +27 -0
  274. package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +130 -0
  275. package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +152 -0
  276. package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +92 -0
  277. package/templates/apps/web/app/[locale]/contact/contact.actions.ts +79 -0
  278. package/templates/apps/web/app/[locale]/contact/error.tsx +24 -0
  279. package/templates/apps/web/app/[locale]/contact/page.tsx +38 -0
  280. package/templates/apps/web/app/[locale]/courses/[slug]/page.tsx +34 -0
  281. package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +119 -0
  282. package/templates/apps/web/app/[locale]/courses/page.tsx +25 -0
  283. package/templates/apps/web/app/[locale]/dev/purchase/__tests__/actions.test.ts +160 -0
  284. package/templates/apps/web/app/[locale]/dev/purchase/error.tsx +25 -0
  285. package/templates/apps/web/app/[locale]/dev/purchase/page.tsx +117 -0
  286. package/templates/apps/web/app/[locale]/dev/purchase/purchase.actions.ts +58 -0
  287. package/templates/apps/web/app/[locale]/docs/[[...slug]]/page.tsx +118 -0
  288. package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +72 -0
  289. package/templates/apps/web/app/[locale]/downloads/page.tsx +25 -0
  290. package/templates/apps/web/app/[locale]/events/[slug]/page.tsx +47 -0
  291. package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +130 -0
  292. package/templates/apps/web/app/[locale]/events/page.tsx +25 -0
  293. package/templates/apps/web/app/[locale]/faq/page.tsx +36 -0
  294. package/templates/apps/web/app/[locale]/how-to/[slug]/page.tsx +34 -0
  295. package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +78 -0
  296. package/templates/apps/web/app/[locale]/how-to/page.tsx +40 -0
  297. package/templates/apps/web/app/[locale]/integrations/[slug]/page.tsx +43 -0
  298. package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +129 -0
  299. package/templates/apps/web/app/[locale]/integrations/page.tsx +25 -0
  300. package/templates/apps/web/app/[locale]/launch-service/page.tsx +31 -0
  301. package/templates/apps/web/app/[locale]/layout.tsx +241 -0
  302. package/templates/apps/web/app/[locale]/page.tsx +41 -0
  303. package/templates/apps/web/app/[locale]/partners/[slug]/page.tsx +44 -0
  304. package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +113 -0
  305. package/templates/apps/web/app/[locale]/partners/page.tsx +25 -0
  306. package/templates/apps/web/app/[locale]/products/[slug]/page.tsx +43 -0
  307. package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +129 -0
  308. package/templates/apps/web/app/[locale]/products/page.tsx +25 -0
  309. package/templates/apps/web/app/[locale]/projects/[slug]/page.tsx +39 -0
  310. package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +138 -0
  311. package/templates/apps/web/app/[locale]/projects/page.tsx +30 -0
  312. package/templates/apps/web/app/[locale]/resources/[slug]/page.tsx +51 -0
  313. package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +117 -0
  314. package/templates/apps/web/app/[locale]/resources/page.tsx +27 -0
  315. package/templates/apps/web/app/[locale]/services/[slug]/page.tsx +43 -0
  316. package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +129 -0
  317. package/templates/apps/web/app/[locale]/services/page.tsx +25 -0
  318. package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +34 -0
  319. package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +81 -0
  320. package/templates/apps/web/app/[locale]/software/page.tsx +39 -0
  321. package/templates/apps/web/app/[locale]/tech-articles/[slug]/page.tsx +34 -0
  322. package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +82 -0
  323. package/templates/apps/web/app/[locale]/tech-articles/page.tsx +39 -0
  324. package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +63 -0
  325. package/templates/apps/web/app/[locale]/testimonials/page.tsx +27 -0
  326. package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +63 -0
  327. package/templates/apps/web/app/[locale]/use-cases/page.tsx +27 -0
  328. package/templates/apps/web/app/[locale]/whitepapers/[slug]/page.tsx +34 -0
  329. package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +82 -0
  330. package/templates/apps/web/app/[locale]/whitepapers/page.tsx +39 -0
  331. package/templates/apps/web/app/__tests__/error-boundaries.test.tsx +152 -0
  332. package/templates/apps/web/app/api/auth/[...all]/route.ts +16 -0
  333. package/templates/apps/web/app/error-fallback.tsx +75 -0
  334. package/templates/apps/web/app/error.tsx +23 -0
  335. package/templates/apps/web/app/layout.tsx +18 -0
  336. package/templates/apps/web/app/llms.txt/route.ts +101 -0
  337. package/templates/apps/web/app/not-found.tsx +48 -0
  338. package/templates/apps/web/app/og/__tests__/route.test.ts +164 -0
  339. package/templates/apps/web/app/og/route.tsx +135 -0
  340. package/templates/apps/web/app/robots.txt/route.ts +36 -0
  341. package/templates/apps/web/app/sitemap.xml/route.ts +146 -0
  342. package/templates/apps/web/auth.ts +141 -0
  343. package/templates/apps/web/components/ThemeToggle.tsx +60 -0
  344. package/templates/apps/web/components/google-analytics.tsx +34 -0
  345. package/templates/apps/web/content/en/blog/index.mdx +15 -0
  346. package/templates/apps/web/content/en/blog/launching-ailk.mdx +20 -0
  347. package/templates/apps/web/content/en/docs/getting-started.mdx +30 -0
  348. package/templates/apps/web/i18n/request.ts +36 -0
  349. package/templates/apps/web/jest.config.cjs +100 -0
  350. package/templates/apps/web/lib/__mocks__/next-mdx-remote-rsc.js +12 -0
  351. package/templates/apps/web/lib/__mocks__/source-server.js +31 -0
  352. package/templates/apps/web/lib/__tests__/og.test.ts +65 -0
  353. package/templates/apps/web/lib/auth-env.ts +66 -0
  354. package/templates/apps/web/lib/blog-list-data.ts +95 -0
  355. package/templates/apps/web/lib/blog-post-data.ts +79 -0
  356. package/templates/apps/web/lib/nav-config.ts +13 -0
  357. package/templates/apps/web/lib/observability/better-stack.ts +27 -0
  358. package/templates/apps/web/lib/og.ts +23 -0
  359. package/templates/apps/web/lib/prisma-for-auth.ts +34 -0
  360. package/templates/apps/web/lib/source.ts +34 -0
  361. package/templates/apps/web/messages/en.json +131 -0
  362. package/templates/apps/web/middleware.ts +80 -0
  363. package/templates/apps/web/next.config.mjs +167 -0
  364. package/templates/apps/web/package.json +62 -0
  365. package/templates/apps/web/public/.well-known/security.txt +17 -0
  366. package/templates/apps/web/public/android-chrome-192x192.png +0 -0
  367. package/templates/apps/web/public/android-chrome-512x512.png +0 -0
  368. package/templates/apps/web/public/apple-touch-icon.png +0 -0
  369. package/templates/apps/web/public/favicon-16x16.png +0 -0
  370. package/templates/apps/web/public/favicon-32x32.png +0 -0
  371. package/templates/apps/web/public/favicon.ico +0 -0
  372. package/templates/apps/web/public/favicon.svg +4 -0
  373. package/templates/apps/web/public/logo-dark.svg +21 -0
  374. package/templates/apps/web/public/logo-light.svg +21 -0
  375. package/templates/apps/web/public/logomark-dark.svg +4 -0
  376. package/templates/apps/web/public/logomark-light.svg +4 -0
  377. package/templates/apps/web/public/og-default.png +0 -0
  378. package/templates/apps/web/public/site.webmanifest +19 -0
  379. package/templates/apps/web/scripts/assert-content-bundled.ts +55 -0
  380. package/templates/apps/web/security-headers.config.ts +132 -0
  381. package/templates/apps/web/sentry.client.config.ts +27 -0
  382. package/templates/apps/web/sentry.edge.config.ts +15 -0
  383. package/templates/apps/web/sentry.server.config.ts +20 -0
  384. package/templates/apps/web/source.config.ts +78 -0
  385. package/templates/apps/web/src/components/SiteNav.tsx +21 -0
  386. package/templates/apps/web/src/lib/routes.ts +37 -0
  387. package/templates/apps/web/tsconfig.json +35 -0
  388. package/templates/apps/web/types/messages.d.ts +19 -0
  389. package/templates/content/.gitkeep +0 -0
  390. package/templates/content/CLAUDE.md +85 -0
  391. package/templates/content/_site.mdx +38 -0
  392. package/templates/content/ar/HomePage/home.mdx +123 -0
  393. package/templates/content/ar/_site.mdx +35 -0
  394. package/templates/content/de/_site.mdx +29 -0
  395. package/templates/content/en/.gitkeep +0 -0
  396. package/templates/content/en/AboutPage/about.mdx +19 -0
  397. package/templates/content/en/AboutPage/about.schema.json +82 -0
  398. package/templates/content/en/BookCall/book-call.mdx +19 -0
  399. package/templates/content/en/BookCall/book-call.schema.json +121 -0
  400. package/templates/content/en/BreadcrumbList/site-breadcrumbs.mdx +20 -0
  401. package/templates/content/en/CareersList/careers.mdx +24 -0
  402. package/templates/content/en/CaseStudiesList/case-studies.mdx +22 -0
  403. package/templates/content/en/CaseStudiesList/showcase.mdx +8 -0
  404. package/templates/content/en/CaseStudy/ailk-aeo-rollout.mdx +32 -0
  405. package/templates/content/en/CaseStudy/schema-builder-migration.mdx +41 -0
  406. package/templates/content/en/ClientsList/clients.mdx +38 -0
  407. package/templates/content/en/ContactPage/contact.mdx +19 -0
  408. package/templates/content/en/ContactPage/contact.schema.json +100 -0
  409. package/templates/content/en/ContactPoint/primary.mdx +14 -0
  410. package/templates/content/en/Course/aeo-fundamentals.mdx +37 -0
  411. package/templates/content/en/Course/schema-builder-workshop.mdx +62 -0
  412. package/templates/content/en/CoursesList/courses.mdx +22 -0
  413. package/templates/content/en/DownloadsList/downloads.mdx +22 -0
  414. package/templates/content/en/Event/aeo-office-hours-may-2026.mdx +39 -0
  415. package/templates/content/en/Event/ailk-launch-day-2026.mdx +35 -0
  416. package/templates/content/en/EventsList/events.mdx +26 -0
  417. package/templates/content/en/FAQPage/faq.mdx +420 -0
  418. package/templates/content/en/FAQPage/faq.schema.json +231 -0
  419. package/templates/content/en/GlossaryList/glossary.mdx +19 -0
  420. package/templates/content/en/GlossaryList/glossary.schema.json +300 -0
  421. package/templates/content/en/HomePage/home.mdx +312 -0
  422. package/templates/content/en/HomePage/home.schema.json +88 -0
  423. package/templates/content/en/HomePage/launch-service.mdx +475 -0
  424. package/templates/content/en/HomePage/launch-service.schema.json +138 -0
  425. package/templates/content/en/HowTo/add-mdx-content.mdx +38 -0
  426. package/templates/content/en/HowTo/configure-aeo-scoring.mdx +35 -0
  427. package/templates/content/en/HowTo/set-up-json-ld.mdx +36 -0
  428. package/templates/content/en/Integration/github-actions.mdx +31 -0
  429. package/templates/content/en/Integration/openai-api.mdx +26 -0
  430. package/templates/content/en/Integration/vercel.mdx +32 -0
  431. package/templates/content/en/IntegrationsList/integrations.mdx +22 -0
  432. package/templates/content/en/JobPosting/content-strategist.mdx +46 -0
  433. package/templates/content/en/JobPosting/developer-advocate.mdx +47 -0
  434. package/templates/content/en/JobPosting/senior-fullstack-engineer.mdx +57 -0
  435. package/templates/content/en/LandingPage/aeo-audit.mdx +19 -0
  436. package/templates/content/en/LandingPage/aeo-audit.schema.json +92 -0
  437. package/templates/content/en/LandingPage/agency-waitlist.mdx +340 -0
  438. package/templates/content/en/LandingPage/agency-waitlist.schema.json +152 -0
  439. package/templates/content/en/LandingPage/developers.mdx +19 -0
  440. package/templates/content/en/LandingPage/developers.schema.json +109 -0
  441. package/templates/content/en/LandingPage/for-agencies.mdx +390 -0
  442. package/templates/content/en/LandingPage/for-agencies.schema.json +107 -0
  443. package/templates/content/en/LandingPage/for-ai-search-agencies.mdx +417 -0
  444. package/templates/content/en/LandingPage/for-ai-search-agencies.schema.json +105 -0
  445. package/templates/content/en/LandingPage/for-businesses.mdx +19 -0
  446. package/templates/content/en/LandingPage/for-businesses.schema.json +96 -0
  447. package/templates/content/en/LandingPage/platform.mdx +369 -0
  448. package/templates/content/en/LandingPage/platform.schema.json +166 -0
  449. package/templates/content/en/LandingPage/vs-ai-website-builders.mdx +19 -0
  450. package/templates/content/en/LandingPage/vs-ai-website-builders.schema.json +102 -0
  451. package/templates/content/en/LandingPage/vs-wordpress.mdx +19 -0
  452. package/templates/content/en/LandingPage/vs-wordpress.schema.json +53 -0
  453. package/templates/content/en/NewsletterSignup/newsletter.mdx +236 -0
  454. package/templates/content/en/NewsletterSignup/newsletter.schema.json +91 -0
  455. package/templates/content/en/Organization/site-owner.mdx +16 -0
  456. package/templates/content/en/Partner/prisma.mdx +31 -0
  457. package/templates/content/en/Partner/supabase.mdx +30 -0
  458. package/templates/content/en/Partner/vercel.mdx +28 -0
  459. package/templates/content/en/PartnersList/partners.mdx +22 -0
  460. package/templates/content/en/Person/founder.mdx +18 -0
  461. package/templates/content/en/Pricing/pricing.mdx +538 -0
  462. package/templates/content/en/Pricing/pricing.schema.json +209 -0
  463. package/templates/content/en/PrivacyPage/privacy.mdx +165 -0
  464. package/templates/content/en/PrivacyPage/privacy.schema.json +64 -0
  465. package/templates/content/en/Product/ailk.mdx +19 -0
  466. package/templates/content/en/Product/ailk.schema.json +94 -0
  467. package/templates/content/en/Product/api-launch-kit.mdx +26 -0
  468. package/templates/content/en/Product/launch-kit.mdx +28 -0
  469. package/templates/content/en/ProductsList/products.mdx +26 -0
  470. package/templates/content/en/Project/ailk-phase-2.mdx +54 -0
  471. package/templates/content/en/ProjectsList/projects.mdx +25 -0
  472. package/templates/content/en/ResourceDetail/aeo-scoring-guide.mdx +27 -0
  473. package/templates/content/en/ResourceDetail/content-model-whitepaper.mdx +28 -0
  474. package/templates/content/en/ResourceDetail/schema-org-quick-reference.mdx +39 -0
  475. package/templates/content/en/ResourcesHub/resources.mdx +22 -0
  476. package/templates/content/en/Service/consulting.mdx +22 -0
  477. package/templates/content/en/Service/implementation.mdx +30 -0
  478. package/templates/content/en/Service/launch-service.mdx +232 -0
  479. package/templates/content/en/Service/launch.mdx +228 -0
  480. package/templates/content/en/ServicesList/services.mdx +84 -0
  481. package/templates/content/en/SoftwareProduct/ailk-aeo.mdx +44 -0
  482. package/templates/content/en/SoftwareProduct/ailk-content-adapters.mdx +47 -0
  483. package/templates/content/en/SoftwareProduct/ailk-schema.mdx +49 -0
  484. package/templates/content/en/TeamList/team.mdx +63 -0
  485. package/templates/content/en/TeamMember/founder.mdx +72 -0
  486. package/templates/content/en/TermsPage/terms.mdx +19 -0
  487. package/templates/content/en/TermsPage/terms.schema.json +99 -0
  488. package/templates/content/en/TestimonialsList/testimonials.mdx +44 -0
  489. package/templates/content/en/UseCasesList/use-cases.mdx +30 -0
  490. package/templates/content/en/Whitepaper/ax-first-product-development.mdx +27 -0
  491. package/templates/content/en/Whitepaper/open-core-commercial-strategy.mdx +27 -0
  492. package/templates/content/en/Whitepaper/structured-data-for-answer-engines.mdx +31 -0
  493. package/templates/content/en-XA/AboutPage/about.mdx +8 -0
  494. package/templates/content/en-XA/FAQPage/faq.mdx +8 -0
  495. package/templates/content/en-XA/HomePage/home.mdx +8 -0
  496. package/templates/content/es/_site.mdx +30 -0
  497. package/templates/content/fr/_site.mdx +30 -0
  498. package/templates/content/ja/_site.mdx +30 -0
  499. package/templates/content/pt-BR/AboutPage/about.mdx +8 -0
  500. package/templates/content/pt-BR/FAQPage/faq.mdx +8 -0
  501. package/templates/content/pt-BR/HomePage/home.mdx +23 -0
  502. package/templates/database/CHANGELOG.md +5 -0
  503. package/templates/database/README.md +234 -0
  504. package/templates/database/__tests__/user-cascade.test.ts +125 -0
  505. package/templates/database/auth/.gitkeep +0 -0
  506. package/templates/database/config/.gitkeep +0 -0
  507. package/templates/database/content/.gitkeep +0 -0
  508. package/templates/database/inbox/.gitkeep +0 -0
  509. package/templates/database/inbox/README.md +3 -0
  510. package/templates/database/inbox/__tests__/schema.test.ts +40 -0
  511. package/templates/database/inbox/schema.prisma +52 -0
  512. package/templates/database/jest.config.cjs +29 -0
  513. package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +328 -0
  514. package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +100 -0
  515. package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +28 -0
  516. package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +25 -0
  517. package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +42 -0
  518. package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +67 -0
  519. package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +21 -0
  520. package/templates/database/migrations/migration_lock.toml +3 -0
  521. package/templates/database/ops/.gitkeep +0 -0
  522. package/templates/database/package.json +45 -0
  523. package/templates/database/prisma.config.ts +20 -0
  524. package/templates/database/schema.prisma +487 -0
  525. package/templates/database/scripts/db-generate-locked.sh +80 -0
  526. package/templates/database/seed-test.ts +85 -0
  527. package/templates/database/tsconfig.build.json +16 -0
  528. package/templates/database/tsconfig.json +9 -0
  529. package/templates/package.json +125 -0
  530. package/templates/pnpm-workspace.yaml +6 -0
  531. package/templates/project.yaml +59 -0
  532. package/templates/tsconfig.base.json +18 -0
  533. package/templates/tsconfig.json +45 -0
@@ -0,0 +1,171 @@
1
+ # OAuth + Magic-Link Setup — RUNBOOK Template
2
+
3
+ The `scaffold-auth` skill writes (or merges into) `RUNBOOK.md` at the
4
+ consumer's repo root using the per-provider sections below. Only the
5
+ sections for providers actually activated this session are emitted.
6
+
7
+ The skill **substitutes nothing** in these blocks at runtime — they're
8
+ copy-paste ready as-is. The only per-session variation is which
9
+ sections appear in the final runbook.
10
+
11
+ ---
12
+
13
+ ## Provider section: magic-link (Resend)
14
+
15
+ ```markdown
16
+ ## Auth — magic-link (Resend)
17
+
18
+ Magic-link sign-in uses Resend as the email provider. Activation is
19
+ keyed off two env vars in `.env.local`:
20
+
21
+ - `AUTH_EMAIL_SERVER` — `smtp://resend:<API_KEY>@smtp.resend.com:465`
22
+ - `AUTH_EMAIL_FROM` — verified sender address on your Resend account
23
+
24
+ ### One-time setup
25
+
26
+ 1. Sign up at <https://resend.com> (free tier is fine for development).
27
+ 2. Create an API key: <https://resend.com/api-keys>. Save it
28
+ somewhere safe — you'll only see it once.
29
+ 3. Use a verified sender. For development, `onboarding@resend.dev` is
30
+ Resend's shared dev sender and works without verification. For
31
+ production, verify your own sending domain in the Resend dashboard.
32
+
33
+ ### `.env.local` entries
34
+
35
+ \`\`\`
36
+ AUTH_EMAIL_SERVER=smtp://resend:re_yourapikeyhere@smtp.resend.com:465
37
+ AUTH_EMAIL_FROM=onboarding@resend.dev
38
+ \`\`\`
39
+
40
+ ### Rotating the API key
41
+
42
+ If you rotate the Resend API key, update `AUTH_EMAIL_SERVER` in
43
+ `.env.local` and restart the dev server.
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Provider section: Google OAuth
49
+
50
+ ```markdown
51
+ ## Auth — Google OAuth
52
+
53
+ Google sign-in is activated when both env vars are present in
54
+ `.env.local`:
55
+
56
+ - `GOOGLE_CLIENT_ID`
57
+ - `GOOGLE_CLIENT_SECRET`
58
+
59
+ ### One-time setup
60
+
61
+ 1. Open <https://console.cloud.google.com/apis/credentials>.
62
+ 2. If you haven't yet, configure the OAuth consent screen:
63
+ - User type: **External** (unless you're inside a Workspace org).
64
+ - Fill in app name, support email, and developer contact email.
65
+ - Scopes are auto-populated by NextAuth at runtime — leave the
66
+ consent screen scope list empty.
67
+ 3. Click **Create Credentials → OAuth client ID**.
68
+ 4. Application type: **Web application**.
69
+ 5. Name: anything (e.g., "AILK dev").
70
+ 6. **Authorized redirect URIs** — add exactly:
71
+ `http://localhost:3000/api/auth/callback/google`
72
+ 7. Click **Create**. Copy the Client ID and Client secret from the
73
+ dialog (you can return to copy them later via the Credentials page).
74
+
75
+ ### `.env.local` entries
76
+
77
+ \`\`\`
78
+ GOOGLE_CLIENT_ID=...
79
+ GOOGLE_CLIENT_SECRET=...
80
+ \`\`\`
81
+
82
+ ### Production callback URL
83
+
84
+ The `localhost` callback above is dev-only. For production, you'll
85
+ need to add a second redirect URI to the same OAuth client (or
86
+ create a separate prod client) of the form
87
+ `https://<your-prod-domain>/api/auth/callback/google`. The
88
+ `provision-config` skill or your future deploy skill will help you
89
+ wire this when you're ready to ship.
90
+
91
+ ### Rotating the client secret
92
+
93
+ In the Google Console, find the OAuth client, generate a new secret,
94
+ update `GOOGLE_CLIENT_SECRET` in `.env.local`, and restart the dev
95
+ server. The Client ID stays the same.
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Provider section: GitHub OAuth
101
+
102
+ ```markdown
103
+ ## Auth — GitHub OAuth
104
+
105
+ GitHub sign-in is activated when both env vars are present in
106
+ `.env.local`:
107
+
108
+ - `GITHUB_CLIENT_ID`
109
+ - `GITHUB_CLIENT_SECRET`
110
+
111
+ ### One-time setup
112
+
113
+ 1. Open <https://github.com/settings/developers>.
114
+ 2. Click **New OAuth App**.
115
+ 3. Application name: anything (e.g., "AILK dev").
116
+ 4. Homepage URL: `http://localhost:3000`
117
+ 5. **Authorization callback URL** — add exactly:
118
+ `http://localhost:3000/api/auth/callback/github`
119
+ 6. Click **Register application**.
120
+ 7. On the resulting app page, click **Generate a new client secret**
121
+ and copy it immediately (GitHub shows it once).
122
+ 8. Copy the Client ID from the same page.
123
+
124
+ ### `.env.local` entries
125
+
126
+ \`\`\`
127
+ GITHUB_CLIENT_ID=...
128
+ GITHUB_CLIENT_SECRET=...
129
+ \`\`\`
130
+
131
+ ### Production callback URL
132
+
133
+ The `localhost` callback above is dev-only. For production, either
134
+ register a separate OAuth App with a `https://<your-prod-domain>/...`
135
+ callback, or update this app's callback (GitHub allows multiple).
136
+ The `provision-config` skill or your future deploy skill will help
137
+ you wire this when you're ready to ship.
138
+
139
+ ### Rotating the client secret
140
+
141
+ Generate a new client secret on the app's GitHub page, update
142
+ `GITHUB_CLIENT_SECRET` in `.env.local`, and restart the dev server.
143
+ The Client ID stays the same.
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Closing section (always emitted at the end of the runbook)
149
+
150
+ ```markdown
151
+ ## Activation summary
152
+
153
+ | Provider | Env vars | Active |
154
+ | ----------- | ------------------------------------------------- | ------ |
155
+ | magic-link | `AUTH_EMAIL_SERVER` + `AUTH_EMAIL_FROM` | <fill> |
156
+ | Google | `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` | <fill> |
157
+ | GitHub | `GITHUB_CLIENT_ID` + `GITHUB_CLIENT_SECRET` | <fill> |
158
+
159
+ A provider is **active** when both required env vars are set in
160
+ `.env.local`. The provider list is computed at server startup from env
161
+ vars only — there are no `auth.config.ts` edits to make.
162
+
163
+ To require sign-in for protected routes, set in `.env.local`:
164
+
165
+ \`\`\`
166
+ AILK_AUTH_REQUIRED=1
167
+ \`\`\`
168
+
169
+ Default (unset or `0`) is auth-disabled / public — useful while
170
+ building.
171
+ ```
@@ -0,0 +1,310 @@
1
+ ---
2
+ name: scaffold-commerce
3
+ description: Wire up commerce on an AILK consumer site — either an external link to an existing storefront (Amazon, Etsy, Shopify, eBay, Gumroad, custom) via a `<MarketplaceCTA>` button, or direct payments via Stripe (test-mode only at v1). Use when the user says "let me sell something", "add a buy button", "wire up Stripe", "set up payments", "I have an Amazon store", or otherwise wants commerce wiring on their AILK site. Two-path branching — picks link vs direct first, never assumes Stripe.
4
+ ---
5
+
6
+ # scaffold-commerce
7
+
8
+ Add commerce to an AILK site. The first question is always: **external
9
+ link to an existing storefront, or direct payments on this site?** Both
10
+ paths are conversational and emit minimal, consumer-owned source.
11
+
12
+ This skill is the canonical "sell stuff" entry point. Pricing UI itself
13
+ is `scaffold-page` (#362)'s lane (you scaffold a `/pricing` page with
14
+ that skill, then wire `lookup_key`s into it). Production webhook setup
15
+ is `provision-config` (#367)'s lane.
16
+
17
+ ## When to use
18
+
19
+ The user wants to sell something — physical goods, digital goods,
20
+ subscriptions, services, courses, anything with a price. Triggers:
21
+
22
+ - "let me sell something" / "I want to sell"
23
+ - "add a buy button" / "add a buy now"
24
+ - "wire up Stripe" / "set up payments"
25
+ - "I have an Amazon / Etsy / Shopify / eBay / Gumroad store, link it"
26
+ - "what's the simplest way to charge for this?"
27
+
28
+ Skip this skill when:
29
+
30
+ - The user wants to _design_ a pricing page (lay out tiers, copy,
31
+ comparison table) — that's `scaffold-page` (#362) emitting a Product
32
+ page. Wire `lookup_key`s afterwards from this skill's output.
33
+ - The user wants to set up production Stripe (live mode, real webhooks).
34
+ Hard-blocked at v1 — sandbox-only is hook-enforced globally. Defer
35
+ with the same answer regardless: "v1 is test-mode only; production
36
+ setup is `provision-config` (#367)'s lane."
37
+ - The user is on a non-Stripe payment processor (Lemon Squeezy, Paddle,
38
+ Gumroad-as-payment-processor). v1 only supports Stripe for direct
39
+ payments. Acknowledge and stop; future PRs will add `--provider`
40
+ branches.
41
+
42
+ ## The first question (always asked)
43
+
44
+ Greet the consumer with a clear two-path branch:
45
+
46
+ > "Two ways to sell on your AILK site:
47
+ >
48
+ > **Link to an existing store** — you already sell on Amazon, Etsy,
49
+ > Shopify, eBay, Gumroad, or your own storefront. We add a 'Buy on
50
+ > {marketplace}' button that links there.
51
+ >
52
+ > **Direct payments via Stripe** — you don't have a storefront yet, or
53
+ > you want checkout on your own site. We create products in your
54
+ > Stripe (test mode), wire env vars, and point you at the next steps.
55
+ >
56
+ > Which one?"
57
+
58
+ Wait for the consumer's choice. Then run the matching path.
59
+
60
+ ## Link path
61
+
62
+ The link path emits source the consumer owns — no env wiring, no API
63
+ calls, no `@working-theory/ui` import.
64
+
65
+ ### Step 1 — Collect the inputs
66
+
67
+ Ask conversationally for:
68
+
69
+ 1. **URL** — the storefront URL. Validate it parses as a URL. Don't
70
+ accept plain text; prompt again if input fails.
71
+ 2. **Button text** — defaults to "Buy on {marketplace}" where
72
+ `{marketplace}` is parsed from the URL hostname (e.g.,
73
+ `amazon.com` → "Amazon"). Consumer can override.
74
+ 3. **Optional `iconSrc`** — a path to an SVG/PNG of the marketplace
75
+ logo, e.g., `/logos/amazon.svg`. Optional — clean text-only buttons
76
+ are fine. If the consumer wants logos, point them at
77
+ `references/marketplace-brand-pages.md` for sourcing.
78
+
79
+ ### Step 2 — Emit the route template
80
+
81
+ Use `templates/marketplace-cta-route.tsx.tmpl` as the starting source.
82
+ The template defines `<MarketplaceCTA>` **inline** at the top of the
83
+ emitted route file (not bundled in `@working-theory/ui`, not imported from a
84
+ shared package). The consumer owns the component and can customize it.
85
+
86
+ The emitted file path is the consumer's call — typical placement is
87
+ `app/buy/page.tsx` for a dedicated landing, or inserted into an
88
+ existing page (e.g., `app/products/[slug]/page.tsx`) as a `<MarketplaceCTA>`
89
+ usage. Ask which.
90
+
91
+ ### Step 3 — Confirm and write
92
+
93
+ Show the consumer the emitted file diff (or new file if standalone)
94
+ in a single confirmation step. After approval, write.
95
+
96
+ ### Step 4 — No env wiring, no follow-up files
97
+
98
+ The link path is self-contained. Nothing to add to `.env.local`. No
99
+ references file write (the marketplace brand pages cheat-sheet ships
100
+ in the skill folder; the skill points at it but doesn't copy it into
101
+ the consumer's repo).
102
+
103
+ ## Direct payments path (Stripe, test-mode only at v1)
104
+
105
+ The Stripe path uses the **Stripe MCP** (configured in the AILK
106
+ consumer scaffold's `.claude/settings.json`) to create products with
107
+ consumer-derived `lookup_key`s, writes test-mode env vars, and
108
+ surfaces created keys for the consumer to grep when wiring pricing UI.
109
+
110
+ ### Step 1 — Defense-in-depth live-key check
111
+
112
+ Before any other action:
113
+
114
+ 1. **Env detection.** Scan the consumer's `.env.local`, `.env`,
115
+ `.env.development`, and any `.env.example` for `sk_live_` or
116
+ `pk_live_`. If any match, refuse with:
117
+
118
+ > "AILK is sandbox-only at v1. I see a `sk_live_*` or `pk_live_*`
119
+ > value in your env files — replace it with a test-mode key from
120
+ > <https://dashboard.stripe.com/test/apikeys> before continuing.
121
+ > Production setup is `provision-config` (#367)'s lane and is
122
+ > deferred at v1."
123
+
124
+ Stop. No Stripe API calls fire.
125
+
126
+ 2. **Paste detection.** If the consumer pastes a `sk_live_` or
127
+ `pk_live_` value during the flow, refuse with the same message
128
+ and stop.
129
+
130
+ This double-check is required by the brief and matches the global
131
+ hook-enforced sandbox-only constraint.
132
+
133
+ ### Step 2 — Collect product inputs
134
+
135
+ Ask the consumer to describe each product they want to sell. Per
136
+ product:
137
+
138
+ - **Name** — e.g., "Pro plan", "Pizza", "Online course".
139
+ - **Price + interval** — e.g., "$29/month", "$15 one-time", "$199/year".
140
+ - **Optional features bullet list** — surfaced in the dashboard, not
141
+ required for the API call.
142
+
143
+ Loop until the consumer says "that's all" or equivalent.
144
+
145
+ ### Step 3 — Derive `lookup_key`s
146
+
147
+ For each product, derive a stable, human-readable `lookup_key`:
148
+
149
+ - Lowercase the name, replace spaces with underscores.
150
+ - Append `_monthly` / `_yearly` / `_onetime` based on interval.
151
+ - Examples:
152
+ - "Pro plan, $29/month" → `pro_monthly`
153
+ - "Annual subscription, $199/year" → `annual_yearly`
154
+ - "Pizza, $15 one-time" → `pizza_onetime`
155
+
156
+ Show the derivations to the consumer and offer to override per-product
157
+ before any API call.
158
+
159
+ ### Step 4 — Conflict handling (per product)
160
+
161
+ For each product, before creating it, query the consumer's Stripe
162
+ account for an existing product with the same `lookup_key` (use the
163
+ Stripe MCP — `stripe.products.list({lookup_keys: [...]})` or equivalent).
164
+
165
+ If one exists, **show + ask** (do not silently skip, do not refuse):
166
+
167
+ ```
168
+ A product with lookup_key `pro_monthly` already exists:
169
+ Existing: "Pro plan" — $29/month — created 2026-04-15
170
+ Proposed: "Pro plan" — $29/month — new
171
+
172
+ What would you like to do?
173
+ - Keep existing (no change)
174
+ - Overwrite amounts (update price, keep lookup_key)
175
+ - Pick a different lookup_key (e.g., `pro_monthly_v2`)
176
+ ```
177
+
178
+ Wait for choice. Apply.
179
+
180
+ ### Step 5 — Create products + prices in Stripe
181
+
182
+ For each product (after conflict resolution), use the Stripe MCP:
183
+
184
+ 1. **Create product:** `stripe.products.create({ name, ... })`.
185
+ 2. **Create price:** `stripe.prices.create({ product: <id>, unit_amount, currency: 'usd', recurring: { interval } | undefined, lookup_key })`.
186
+
187
+ Surface created IDs in chat as you go so the consumer can verify in
188
+ their Stripe dashboard alongside the run.
189
+
190
+ ### Step 6 — Write `.env.local`
191
+
192
+ After all products are created, write to the consumer's `.env.local`:
193
+
194
+ ```
195
+ STRIPE_SECRET_KEY=sk_test_...
196
+ STRIPE_PUBLISHABLE_KEY=pk_test_...
197
+ STRIPE_WEBHOOK_SECRET=
198
+ ```
199
+
200
+ Use the test-mode keys from the consumer's Stripe account (the
201
+ consumer pastes these from
202
+ <https://dashboard.stripe.com/test/apikeys>). Leave
203
+ `STRIPE_WEBHOOK_SECRET` empty — Step 7 fills it.
204
+
205
+ ### Step 7 — Webhook setup (dev-only)
206
+
207
+ Tell the consumer to run, in a separate terminal:
208
+
209
+ ```bash
210
+ stripe listen --forward-to localhost:3000/api/webhooks/stripe
211
+ ```
212
+
213
+ The CLI prints a signing secret (`whsec_...`). Have the consumer paste
214
+ it into `.env.local` as `STRIPE_WEBHOOK_SECRET`.
215
+
216
+ Note: production webhook setup is **deferred to v2** — the consumer
217
+ will register a permanent webhook endpoint in Stripe's dashboard
218
+ during deploy. Point at `provision-config` (#367) or future deploy
219
+ skill for the production handoff. Do not attempt to register a
220
+ production webhook from this skill.
221
+
222
+ ### Step 8 — Write `references/lookup-keys.md`
223
+
224
+ Use `references/lookup-keys-template.md` as the source. Instantiate
225
+ with the products created this session:
226
+
227
+ ```markdown
228
+ # Lookup Keys — generated by scaffold-commerce
229
+
230
+ | Product | Lookup key | Amount | Interval |
231
+ | -------- | ------------- | ------ | -------- |
232
+ | Pro plan | `pro_monthly` | $29.00 | monthly |
233
+ | ... | ... | ... | ... |
234
+
235
+ When wiring a pricing page (`scaffold-page` (#362) on a `Product` slug),
236
+ import or reference these lookup keys. Stripe lookup keys are stable
237
+ across price recreates — safe to hard-code in your app.
238
+ ```
239
+
240
+ The consumer's filled-in `lookup-keys.md` lives in their repo (e.g.,
241
+ project root or a `docs/` folder) — point them at `scaffold-page`
242
+ (#362) for the pricing page that consumes these keys.
243
+
244
+ ### Step 9 — Closing summary
245
+
246
+ Print:
247
+
248
+ - Number of products created (with `lookup_key`s).
249
+ - Path to `references/lookup-keys.md`.
250
+ - Reminder: webhook setup is dev-only at v1; production webhook is
251
+ `provision-config` (#367)'s lane.
252
+ - Pointer at `scaffold-page` (#362) for wiring pricing UI.
253
+ - Reminder: sandbox-only at v1. Live keys are hook-blocked globally.
254
+
255
+ ## Output style
256
+
257
+ - **Two questions, two paths.** Don't lead with Stripe assumptions.
258
+ - **Live-key checks happen first** for the Stripe path. Always.
259
+ - **Show + ask on conflicts.** Never silently skip or auto-overwrite.
260
+ - **Source the consumer owns.** The link path emits inline source, not
261
+ an `@working-theory/ui` import. The consumer can edit any of it post-emit.
262
+ - **`lookup_key` derivations are visible.** Show the derivation; let
263
+ the consumer override before any API call.
264
+
265
+ ## What this skill does NOT do
266
+
267
+ - Live-mode Stripe anything. Hook-blocked globally; SKILL refuses.
268
+ - Bundle marketplace logos (Amazon, Etsy, Shopify, eBay, Gumroad).
269
+ AILK doesn't ship those SVGs (trademark-redistribution concern). The
270
+ consumer drops their own SVG into `public/logos/` and passes
271
+ `iconSrc` to `<MarketplaceCTA>`. See
272
+ `references/marketplace-brand-pages.md` for official brand-kit
273
+ sources.
274
+ - Build a pricing page. That's `scaffold-page` (#362).
275
+ - Register a production webhook endpoint. That's `provision-config`
276
+ (#367) or future deploy skill.
277
+ - Use `pricebook.ts` or env-var price mapping. AILK uses
278
+ `lookup_key`s as the source of truth — they're stable across price
279
+ recreates.
280
+ - Auto-invoke other skills. Always points at the next skill by name;
281
+ consumer drives.
282
+
283
+ ## References
284
+
285
+ - `references/marketplace-brand-pages.md` — links to official brand
286
+ kits (Amazon, Etsy, Shopify, eBay, Gumroad). Used by the link path
287
+ when the consumer wants logos. AILK does not bundle the SVGs.
288
+ - `references/lookup-keys-template.md` — template the skill instantiates
289
+ per session, lists every product the consumer created with its
290
+ `lookup_key` and price.
291
+ - `templates/marketplace-cta-route.tsx.tmpl` — emitted route source
292
+ the link path writes. Includes the inline `<MarketplaceCTA>`
293
+ component definition (not a separate package).
294
+
295
+ ## Coordination
296
+
297
+ - **`scaffold-page` (#362)** — pricing UI. After this skill creates
298
+ products and surfaces `lookup_key`s, the consumer scaffolds a
299
+ `/pricing` page that consumes them.
300
+ - **`provision-config` (#367)** — production webhook setup, deploy
301
+ config, persistent leads (related infra). v1 is dev-mode only;
302
+ prod webhook lives there.
303
+ - **Stripe MCP** — used for product/price/lookup_key creation. Should
304
+ already be configured in `.claude/settings.json` from the consumer
305
+ scaffold. If missing, surface a clear "Stripe MCP not configured"
306
+ error and stop; do not invent the configuration.
307
+ - **`@working-theory/stripe-client`** — wrapper for Stripe SDK. The skill does
308
+ not import this directly (the skill is a prompt/template, not
309
+ runtime code). The consumer's `apps/api/routes/checkout/sessions.ts`
310
+ uses it.
@@ -0,0 +1,71 @@
1
+ # Lookup Keys — generated by `scaffold-commerce`
2
+
3
+ This file lists every Stripe product the `scaffold-commerce` skill
4
+ created in your test-mode account. The skill writes one row per
5
+ product as it goes; re-running the skill appends new rows under
6
+ "## Added by re-run YYYY-MM-DD".
7
+
8
+ ## How to use this file
9
+
10
+ Stripe `lookup_key`s are stable identifiers — they survive price
11
+ recreates (e.g., when you change an amount, you can keep the same
12
+ `lookup_key`). They're the canonical reference for AILK pricing UI.
13
+
14
+ When wiring a pricing page (e.g., from `scaffold-page` (#362) on a
15
+ `Product` slug), refer to `lookup_key` in your code:
16
+
17
+ ```ts
18
+ // apps/web/app/pricing/page.tsx
19
+ const PRICING_LOOKUP_KEYS = ["pro_monthly", "team_monthly"];
20
+
21
+ // Server-side fetch (apps/api):
22
+ const prices = await stripe.prices.list({
23
+ lookup_keys: PRICING_LOOKUP_KEYS,
24
+ expand: ["data.product"],
25
+ });
26
+ ```
27
+
28
+ The pricing page renders from `prices`. If you change a price's
29
+ amount in the Stripe dashboard later, the `lookup_key` resolves to
30
+ the new price automatically — no app-code change needed.
31
+
32
+ ## Products created this session
33
+
34
+ (The skill fills this table during Step 8 of the Stripe path. Empty
35
+ on first emit; populated as products are created.)
36
+
37
+ | Product | Lookup key | Amount | Interval | Stripe ID |
38
+ | ---------- | ---------- | ------ | -------- | --------- |
39
+ | _none yet_ | _ -_ | _-_ | _-_ | _-_ |
40
+
41
+ Example after a session that created two products:
42
+
43
+ | Product | Lookup key | Amount | Interval | Stripe ID |
44
+ | --------- | -------------- | ---------- | -------- | ---------------- |
45
+ | Pro plan | `pro_monthly` | $29.00 USD | monthly | `price_1XXXX...` |
46
+ | Team plan | `team_monthly` | $99.00 USD | monthly | `price_1YYYY...` |
47
+
48
+ ## Re-running the skill
49
+
50
+ If you re-run `scaffold-commerce` and add more products:
51
+
52
+ - Existing rows are not modified.
53
+ - New products land under `## Added by re-run <DATE>` heading at the
54
+ end of the file.
55
+ - Conflict-handling (skill Step 4) means existing `lookup_key`s are
56
+ never silently changed — you'll be asked to keep / overwrite /
57
+ pick a different key.
58
+
59
+ ## Pointers
60
+
61
+ - **Pricing page UI:** `scaffold-page` (#362) on a `Product` slug.
62
+ Wire the `PRICING_LOOKUP_KEYS` array to point at the keys above.
63
+ - **Production webhook:** `provision-config` (#367). Dev-mode
64
+ webhook is set up via `stripe listen` per skill Step 7.
65
+ - **Sandbox-only at v1:** AILK rejects live keys (`sk_live_*`,
66
+ `pk_live_*`) at multiple layers. Production setup is a future
67
+ deploy lane.
68
+ - **Stripe dashboard:**
69
+ - Test products: <https://dashboard.stripe.com/test/products>
70
+ - Test prices: <https://dashboard.stripe.com/test/prices>
71
+ - Test API keys: <https://dashboard.stripe.com/test/apikeys>
@@ -0,0 +1,83 @@
1
+ # Marketplace Brand Pages
2
+
3
+ AILK does **not** bundle marketplace logo SVGs (Amazon, Etsy, Shopify,
4
+ eBay, Gumroad). Trademarks are not blanket-licensed for redistribution
5
+ through third-party templates, and shipping them in the AILK template
6
+ chain would put us in the redistribution chain.
7
+
8
+ Brand recognition value is preserved via the **brand name in the
9
+ button text** ("Buy on Amazon", "View on Etsy"). Consumers who want
10
+ the logo too can fetch it themselves from each marketplace's official
11
+ brand-kit page (links below) and drop it in their own `public/logos/`
12
+ directory, then pass `iconSrc="/logos/amazon.svg"` to
13
+ `<MarketplaceCTA>`.
14
+
15
+ Each link below points at the marketplace's first-party brand-asset
16
+ page. URLs may change; if a link breaks, search "<marketplace> brand
17
+ guidelines" or "<marketplace> press kit" — the canonical source is
18
+ always the marketplace's own brand site.
19
+
20
+ ## Amazon
21
+
22
+ - **Brand assets:** <https://brand.amazon.com> (US Brand Standards)
23
+ - **Press / logo:** <https://www.aboutamazon.com/news/company-news/press-room>
24
+ - Notes: Amazon's brand guidelines restrict use of the smile-arrow
25
+ logo. The "Available at Amazon" badge is the consumer-permitted
26
+ affiliate-style asset.
27
+
28
+ ## Etsy
29
+
30
+ - **Press kit:** <https://www.etsy.com/press>
31
+ - **Logo + brand guidelines:** linked from the press page.
32
+ - Notes: "Sell on Etsy" assets are for sellers; "Available on Etsy"
33
+ / "Buy on Etsy" buttons are appropriate for outbound links.
34
+
35
+ ## Shopify
36
+
37
+ - **Brand assets:** <https://www.shopify.com/news/brand-assets> (or
38
+ search "Shopify brand guidelines")
39
+ - Notes: Shopify provides logo files for partners; consumers using
40
+ Shopify as their backend can typically use the logo in
41
+ reasonable-context "Powered by Shopify" / "Buy on our Shopify
42
+ store" buttons.
43
+
44
+ ## eBay
45
+
46
+ - **Brand center:** <https://partnernetwork.ebay.com/marketing-center>
47
+ (eBay Partner Network — affiliate context)
48
+ - **Press / logo:** <https://www.ebayinc.com/company/press-room>
49
+ - Notes: eBay distinguishes affiliate-context use (covered by EPN
50
+ assets) from general use. For "View on eBay" buttons linking to a
51
+ specific seller's storefront, the EPN assets apply.
52
+
53
+ ## Gumroad
54
+
55
+ - **Brand assets:** <https://gumroad.com> (search the footer for
56
+ "press" or "brand"; Gumroad's logo policy is permissive for
57
+ outbound links to creator pages)
58
+ - Notes: simplest of the five; Gumroad's logo and "Available on
59
+ Gumroad" badge are typically copyable directly from their
60
+ about/press surface.
61
+
62
+ ## Custom storefronts
63
+
64
+ If the consumer has their own storefront (Webflow, Squarespace,
65
+ Bigcartel, custom-built), they don't need a marketplace logo — a
66
+ plain "Buy now" or "Shop" button works. The `iconSrc` prop is
67
+ optional.
68
+
69
+ ## Legal note (no legal advice)
70
+
71
+ - Trademarks are owned by the marketplaces. AILK does not grant
72
+ permission to use any marketplace logo; the consumer's use is
73
+ governed by each marketplace's brand guidelines.
74
+ - For affiliate context (consumer earns a referral fee), most
75
+ marketplaces have explicit affiliate-asset programs (Amazon
76
+ Associates, eBay Partner Network, etc.) with permitted logo use.
77
+ - For non-affiliate "I have a store there, send people to it"
78
+ context, the marketplace's general brand guidelines apply. When
79
+ in doubt, the brand name in text only — `Buy on {marketplace}`
80
+ — is always safe.
81
+
82
+ This file is informational. Consumers responsible for compliance
83
+ with each marketplace's brand guidelines for their specific use.