create-ailk 0.8.0 → 0.9.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 (211) hide show
  1. package/README.md +68 -0
  2. package/component-catalog.json +279 -45
  3. package/dist/add-module.d.ts +20 -0
  4. package/dist/add-module.js +43 -7
  5. package/dist/add-route.d.ts +56 -0
  6. package/dist/add-route.js +286 -0
  7. package/dist/apply-design-md.d.ts +7 -0
  8. package/dist/apply-design-md.js +50 -0
  9. package/dist/apply-design.d.ts +64 -0
  10. package/dist/apply-design.js +273 -0
  11. package/dist/claude-md.d.ts +111 -0
  12. package/dist/claude-md.js +334 -0
  13. package/dist/cli.js +92 -4
  14. package/dist/derive-architecture.js +41 -36
  15. package/dist/design-compile.d.ts +71 -0
  16. package/dist/design-compile.js +98 -0
  17. package/dist/design-package.d.ts +83 -0
  18. package/dist/design-package.js +468 -0
  19. package/dist/design-presets.d.ts +86 -0
  20. package/dist/design-presets.js +642 -0
  21. package/dist/design-scaffold.d.ts +76 -0
  22. package/dist/design-scaffold.js +220 -0
  23. package/dist/index.d.ts +2 -1
  24. package/dist/index.js +4 -1
  25. package/dist/legacy-nav-renderers.d.ts +45 -0
  26. package/dist/legacy-nav-renderers.js +545 -0
  27. package/dist/lib/auth-secret-file.d.ts +19 -0
  28. package/dist/lib/auth-secret-file.js +112 -0
  29. package/dist/lib/design-checks.d.ts +78 -0
  30. package/dist/lib/design-checks.js +174 -0
  31. package/dist/lib/license-key-files.d.ts +9 -0
  32. package/dist/lib/license-key-files.js +2 -2
  33. package/dist/lib/module-license-gate.d.ts +19 -9
  34. package/dist/lib/module-license-gate.js +19 -8
  35. package/dist/lib/render-verdict.d.ts +52 -0
  36. package/dist/lib/render-verdict.js +77 -0
  37. package/dist/lib/scaffold-render-sweep.d.ts +105 -0
  38. package/dist/lib/scaffold-render-sweep.js +236 -0
  39. package/dist/module-architecture.d.ts +19 -16
  40. package/dist/module-architecture.js +64 -21
  41. package/dist/parse-args.d.ts +12 -2
  42. package/dist/parse-args.js +74 -13
  43. package/dist/programmatic.d.ts +30 -6
  44. package/dist/programmatic.js +206 -17
  45. package/dist/site-chrome.d.ts +19 -9
  46. package/dist/site-chrome.js +23 -13
  47. package/dist/site-manifest.d.ts +25 -0
  48. package/dist/site-manifest.js +254 -0
  49. package/dist/site-roster.d.ts +41 -0
  50. package/dist/site-roster.js +141 -8
  51. package/dist/starter-grid.d.ts +32 -16
  52. package/dist/starter-grid.js +129 -33
  53. package/dist/surfaces.d.ts +41 -9
  54. package/dist/surfaces.js +200 -83
  55. package/dist/template-manifest.d.ts +30 -13
  56. package/dist/template-manifest.js +49 -24
  57. package/package.json +5 -4
  58. package/site-templates/_base/content/en/UseCase/persona-1.mdx +7 -6
  59. package/site-templates/_base/content/en/UseCase/persona-2.mdx +7 -6
  60. package/site-templates/_base/content/en/UseCase/persona-3.mdx +7 -6
  61. package/site-templates/{minimalism-site/TEMPLATE-MANIFEST.json → aliases/minimalism-site.TEMPLATE-MANIFEST.json} +72 -40
  62. package/site-templates/designs/minimalism/DESIGN.md +98 -6
  63. package/site-templates/designs/minimalism/sample/README.md +48 -0
  64. package/site-templates/designs/standard/DESIGN.md +98 -6
  65. package/site-templates/marketing-site/DESIGN.md +98 -6
  66. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +60 -27
  67. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +50 -30
  68. package/site-templates/marketing-site-free/DESIGN.md +98 -6
  69. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +60 -24
  70. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +44 -27
  71. package/site-templates/marketing-site-free/ailk-template.json +1 -1
  72. package/site-templates/saas-product/DESIGN.md +98 -6
  73. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +127 -18
  74. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +74 -20
  75. package/site-templates/shapes/local-business-service/ailk-template.json +1 -1
  76. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +127 -18
  77. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +74 -20
  78. package/site-templates/shapes/organization-service/ailk-template.json +1 -1
  79. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +127 -18
  80. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +75 -21
  81. package/site-templates/shapes/person-service/ailk-template.json +1 -1
  82. package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +1 -1
  83. package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +2 -2
  84. package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +4 -2
  85. package/site-templates/shapes/person-service/content/en/ServicesList/services.mdx +1 -1
  86. package/templates/.claude/rules/architecture.md +7 -0
  87. package/templates/.claude/skills/README.md +3 -2
  88. package/templates/.claude/skills/add-auth/references/env-vars.md +22 -15
  89. package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +3 -2
  90. package/templates/.claude/skills/add-page/SKILL.md +241 -238
  91. package/templates/.claude/skills/add-page/references/page-types.md +85 -76
  92. package/templates/.claude/skills/add-page/scripts/site-pages.mjs +87 -0
  93. package/templates/.claude/skills/add-page/templates/comparison-page.mdx.tmpl +99 -0
  94. package/templates/.claude/skills/add-page/templates/content.mdx.tmpl +8 -18
  95. package/templates/.claude/skills/add-page/templates/flow-landing-page.mdx.tmpl +43 -0
  96. package/templates/.claude/skills/add-page/templates/report-page.mdx.tmpl +52 -0
  97. package/templates/.claude/skills/add-page/templates/reports-list.mdx.tmpl +38 -0
  98. package/templates/.claude/skills/check-site/SKILL.md +23 -0
  99. package/templates/.claude/skills/fill-page/SKILL.md +26 -7
  100. package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +1 -1
  101. package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +28 -11
  102. package/templates/.claude/skills/update-page/SKILL.md +117 -0
  103. package/templates/.claude/skills/update-page/scripts/update-page.ts +640 -0
  104. package/templates/.claude/skills/update-page/templates/redirects.mjs.tmpl +31 -0
  105. package/templates/.claude/skills/upgrade-plan/SKILL.md +12 -8
  106. package/templates/.github/workflows/ci.yml +4 -0
  107. package/templates/.prettierignore +1 -0
  108. package/templates/CLAUDE.md +146 -103
  109. package/templates/DESIGN.md +98 -6
  110. package/templates/README.md +50 -38
  111. package/templates/apps/api/.env.example +2 -1
  112. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +2 -0
  113. package/templates/apps/api/src/__tests__/server.test.ts +116 -0
  114. package/templates/apps/api/src/lib/stripe.ts +9 -0
  115. package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +140 -0
  116. package/templates/apps/api/src/middleware/auth.ts +54 -0
  117. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +5 -2
  118. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +628 -0
  119. package/templates/apps/api/src/routes/checkout/sessions.ts +222 -24
  120. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +1 -1
  121. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +5 -1
  122. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +521 -20
  123. package/templates/apps/api/src/routes/webhooks/stripe.ts +124 -32
  124. package/templates/apps/api/src/server.ts +28 -0
  125. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +90 -15
  126. package/templates/apps/api/src/services/checkout-buyer.ts +72 -0
  127. package/templates/apps/api/src/services/revalidation.ts +60 -15
  128. package/templates/apps/mcp/__tests__/tools/create_project.test.ts +30 -24
  129. package/templates/apps/mcp/src/tools/purchase.ts +4 -2
  130. package/templates/apps/web/.env.example +13 -0
  131. package/templates/apps/web/CLAUDE.md +22 -28
  132. package/templates/apps/web/app/[locale]/(auth)/layout.tsx +1 -1
  133. package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +24 -0
  134. package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +17 -6
  135. package/templates/apps/web/app/[locale]/[slug]/[detail]/__tests__/page.test.tsx +110 -0
  136. package/templates/apps/web/app/[locale]/[slug]/[detail]/page.tsx +60 -0
  137. package/templates/apps/web/app/[locale]/[slug]/page.tsx +1 -1
  138. package/templates/apps/web/app/[locale]/alternatives/__tests__/page.test.tsx +161 -0
  139. package/templates/apps/web/app/[locale]/alternatives/page.tsx +104 -0
  140. package/templates/apps/web/app/[locale]/{use-cases → for}/[slug]/page.tsx +4 -3
  141. package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +73 -0
  142. package/templates/apps/web/app/[locale]/{use-cases → for}/page.tsx +8 -7
  143. package/templates/apps/web/app/[locale]/glossary/page.tsx +1 -1
  144. package/templates/apps/web/app/[locale]/layout.tsx +35 -19
  145. package/templates/apps/web/app/[locale]/newsletter/page.tsx +1 -1
  146. package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +1 -1
  147. package/templates/apps/web/app/[locale]/portfolio/page.tsx +1 -1
  148. package/templates/apps/web/app/[locale]/vs/[slug]/__tests__/page.test.tsx +112 -0
  149. package/templates/apps/web/app/[locale]/vs/[slug]/page.tsx +70 -0
  150. package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +236 -44
  151. package/templates/apps/web/app/api/revalidate/route.ts +78 -36
  152. package/templates/apps/web/lib/__tests__/site-brand.test.ts +79 -0
  153. package/templates/apps/web/lib/__tests__/site-theme.test.ts +104 -11
  154. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +21 -4
  155. package/templates/apps/web/lib/locale-guard.ts +18 -0
  156. package/templates/apps/web/lib/meet-placeholder.ts +5 -0
  157. package/templates/apps/web/lib/nav-config.ts +14 -13
  158. package/templates/apps/web/lib/site-brand.tsx +13 -9
  159. package/templates/apps/web/lib/site-logo.tsx +36 -0
  160. package/templates/apps/web/lib/site-theme.ts +46 -26
  161. package/templates/apps/web/messages/en.json +23 -9
  162. package/templates/apps/web/middleware.ts +28 -4
  163. package/templates/content/en/BookCall/book-a-call.mdx +80 -0
  164. package/templates/content/en/BookCall/onsite-estimate.mdx +56 -0
  165. package/templates/content/en/BookCall/onsite-service.mdx +56 -0
  166. package/templates/content/en/BookCall/start-project.mdx +56 -0
  167. package/templates/content/en/ContactPage/contact.mdx +40 -1
  168. package/templates/content/en/HomePage/home.mdx +2 -6
  169. package/templates/content/en/LandingPage/meet.mdx +59 -0
  170. package/templates/content/en/UseCasesList/{use-cases.mdx → for.mdx} +19 -18
  171. package/templates/database/CHANGELOG.md +7 -0
  172. package/templates/database/package.json +1 -1
  173. package/templates/package.json +2 -1
  174. package/templates/tools/check-claude-md.ts +128 -0
  175. package/versions.json +33 -33
  176. package/site-templates/_base/content/en/BookCall/book-call.mdx +0 -52
  177. package/site-templates/minimalism-site/DESIGN.md +0 -162
  178. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +0 -458
  179. package/site-templates/minimalism-site/ailk-template.json +0 -23
  180. package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +0 -110
  181. package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +0 -52
  182. package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +0 -34
  183. package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +0 -57
  184. package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +0 -77
  185. package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +0 -73
  186. package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -123
  187. package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +0 -52
  188. package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +0 -52
  189. package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +0 -52
  190. package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +0 -52
  191. package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +0 -38
  192. package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +0 -38
  193. package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +0 -38
  194. package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +0 -73
  195. package/site-templates/minimalism-site/flows/referral.flow.json +0 -71
  196. package/site-templates/minimalism-site/provenance.json +0 -4
  197. package/templates/.claude/skills/add-page/templates/route.tsx.tmpl +0 -28
  198. package/templates/apps/web/app/[locale]/book-a-call/page.tsx +0 -50
  199. package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +0 -72
  200. /package/site-templates/{minimalism-site → designs/minimalism/sample}/content/en/HomePage/home.mdx +0 -0
  201. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-1.svg +0 -0
  202. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-2.svg +0 -0
  203. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-3.svg +0 -0
  204. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-4.svg +0 -0
  205. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-5.svg +0 -0
  206. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-6.svg +0 -0
  207. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/hero-backdrop.svg +0 -0
  208. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-1.svg +0 -0
  209. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-2.svg +0 -0
  210. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-3.svg +0 -0
  211. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/wordmark-placeholder.svg +0 -0
@@ -88,12 +88,15 @@ Answer in this order, in plain words:
88
88
  second recommendation; you may say what would change it (for example "if
89
89
  you add multi-tenant later, that moves you to Pro Plus").
90
90
  4. **What happens next.** Link `recommendation.link`. After purchase the
91
- licence key arrives by email; set it as `AILK_LICENSE_KEY` in your
92
- environment. To install the module(s): run
93
- `pnpm dlx create-ailk@latest --help`, and name `add-module` only if that
94
- output lists it. Otherwise say: re-run `create-ailk` with
95
- `--modules <module>` and the key set, into a new directory, and move your
96
- content across.
91
+ licence key arrives by email. To install a paid module into this site
92
+ in place, run `AILK_LICENSE_KEY=<key> pnpm create ailk@latest
93
+ add-module <module>` in the site root, once per module; it leaves
94
+ every file the site already has as-is except `package.json`
95
+ dependency/script keys, `next.config.*` and `jest.config.*`, which it
96
+ patches. `pnpm create ailk@latest license set -` (key on stdin) keeps
97
+ the key with the site (and, on a site linked to Vercel, sets it there
98
+ and redeploys). A different design is
99
+ `pnpm create ailk@latest apply-design <name|path>`.
97
100
 
98
101
  ## Hard rules
99
102
 
@@ -108,8 +111,9 @@ Answer in this order, in plain words:
108
111
  - **Unpublished means no prices.** When `pricing.status` is `unpublished`,
109
112
  say the pricing page does not publish machine-readable prices yet and link
110
113
  https://ailaunchkit.ai/pricing.
111
- - **Read-only.** Write no file and install nothing. The only outside command
112
- besides the helper is the `--help` probe in step 3.
114
+ - **Read-only.** Write no file and install nothing. The helper is the only
115
+ command you run; `add-module`, `license set` and `apply-design` are named
116
+ for the owner to run, never run by you.
113
117
  - **Never print the licence key.** Report only whether it is set.
114
118
 
115
119
  ## References
@@ -48,6 +48,10 @@ jobs:
48
48
  # locally.
49
49
  - run: pnpm architecture
50
50
 
51
+ # A hand-edit inside a template-owned section of CLAUDE.md — the same
52
+ # check `pnpm preflight` runs locally.
53
+ - run: pnpm claude-md:check
54
+
51
55
  - run: pnpm test
52
56
 
53
57
  - run: pnpm build
@@ -0,0 +1 @@
1
+ CLAUDE.md
@@ -1,22 +1,35 @@
1
+ <!-- ailk:template id="intro" -->
2
+
1
3
  # {{PROJECT_NAME}} — Agent Operating Manual
2
4
 
3
5
  You are Claude, working in the `{{PROJECT_NAME}}` repo. Read this file at session start.
4
6
 
7
+ Sections between `ailk:template` markers come from AI Launch Kit: don't edit
8
+ them. `pnpm claude-md:check` fails on a hand-edit, and
9
+ `pnpm create ailk@latest --sync-claude-md` rewrites them to the current
10
+ template. Your own notes go in **Site notes** at the end; a pasted
11
+ CloudParity block goes just above it.
12
+ <!-- /ailk:template id="intro" -->
13
+
14
+ <!-- ailk:template id="repo-shape" -->
15
+
5
16
  ## Repo shape
6
17
 
7
18
  ```
8
- apps/web/ Next.js 16 app — visitor-facing UX
9
- apps/api/ Fastify HTTP API — checkout, lead capture, webhooks (optional)
10
- apps/mcp/ MCP server — agent-callable tools (optional)
11
- content/ MDX content for typed page surfaces (HomePage, BlogPosting, ...)
12
- .claude/ Rules, skills, and agent definitions for Claude Code
13
- docs/ Project notes (ADRs, architecture, planning)
19
+ apps/web/ Next.js app — visitor-facing UX
20
+ apps/api/ Fastify HTTP API — lead capture, checkout, webhooks
21
+ apps/mcp/ MCP server — agent-callable tools
22
+ database/ Prisma schema + migrations
23
+ content/ Site settings (_site.mdx) and MDX pages (en/<TypeName>/)
24
+ .claude/ Rules, skills and agent definitions for Claude Code
25
+ tools/ This repo's own checks (architecture, CLAUDE.md drift)
14
26
  ```
15
27
 
16
- You consume `@working-theory/*` packages from npm. Source for those packages is at
17
- <https://github.com/working-theory-labs/ai-launch-kit>; you don't have it locally.
18
- Treat each `@working-theory/*` package as a third-party dependency — read its README
19
- or its types, don't go looking for the source.
28
+ You consume `@working-theory/*` packages from npm. Treat each one as a
29
+ third-party dependency: read its README or its types, not its source.
30
+ <!-- /ailk:template id="repo-shape" -->
31
+
32
+ <!-- ailk:template id="architecture" -->
20
33
 
21
34
  ## Architecture invariants
22
35
 
@@ -26,44 +39,78 @@ The full rule lives at `.claude/rules/architecture.md`. Summary:
26
39
  - `apps/web` does not read the database — it goes through `apps/api` via
27
40
  the published HTTP client. The one exception is the Better Auth adapter
28
41
  (`apps/web/lib/prisma-for-auth.ts`, typed in `apps/web/auth.ts`).
29
- - Vendor SDKs (Stripe, Resend, NextAuth, Prisma) are wrapped in their
30
- respective `@working-theory/*` packages. Don't import them directly in your code.
31
- - New page types live under `content/<TypeName>/` and consume the schema
32
- builders from `@working-theory/schema`.
42
+ - Vendor SDKs (Stripe, Resend, Prisma) are wrapped in their
43
+ `@working-theory/*` packages. Don't import them directly.
44
+ - A page is an MDX file under `content/en/<TypeName>/`, typed against
45
+ `@working-theory/schema`.
33
46
 
34
- Crossing one of these is an architecture decision, not a workaround. If
35
- you think you need to, stop and write a short note in `docs/` explaining
36
- why before you change the boundary.
47
+ Crossing one of these is an architecture decision, not a workaround. Stop
48
+ and ask before you change a boundary. `architecture.yaml` records them for
49
+ your module set; `pnpm architecture` enforces it, and a hook in
50
+ `.claude/settings.json` runs it after every edit.
51
+ <!-- /ailk:template id="architecture" -->
37
52
 
38
- `architecture.yaml` records these boundaries for your module set, and
39
- `pnpm architecture` (`tools/lint-architecture.ts`) enforces it. A
40
- PostToolUse hook in `.claude/settings.json` runs it after every Edit or
41
- Write and reports a violation in-session; `pnpm preflight` and CI run it too.
53
+ <!-- ailk:template id="resource-map" -->
42
54
 
43
55
  ## Resource map
44
56
 
45
- Where to find the rule, surface, or fact you need.
46
-
47
- | For… | Look at |
48
- | ---------------------------------------------- | -------------------------------------------------------------- |
49
- | Per-issue workflow (pick → branch → TDD → PR) | § Workflow, below |
50
- | Architecture boundaries (the why + escalation) | `.claude/rules/architecture.md` |
51
- | Diff hygiene when editing existing files | `.claude/rules/preserve-existing-style.md` |
52
- | Skills available to invoke | `.claude/skills/README.md` |
53
- | Domain agents (sample web agent) | `.claude/agents/web.md` |
54
- | Code style, testing, security, content schema | `CONVENTIONS.md` |
55
- | Environment variables and what they unlock | `.env.example` |
56
- | Per-page-type content shape | `content/<TypeName>/*.mdx` frontmatter |
57
- | Deploy targets | `apps/web/vercel.json`, `apps/api/vercel.json` |
58
- | Verification before push | `pnpm preflight` (architecture + types + lint + build) |
59
-
60
- If a question doesn't fit any row above, add the answer to this table
61
- when you find it. Future-you will thank present-you.
57
+ | For… | Look at |
58
+ | ---------------------------------------------- | -------------------------------------------------------------------------------------------------- |
59
+ | Per-issue workflow (pick → branch → TDD → PR) | § Workflow, below |
60
+ | Architecture boundaries (the why + escalation) | `.claude/rules/architecture.md` |
61
+ | Module set + import boundaries | `architecture.yaml` — never hand-edit; regenerate with `create-ailk --sync-architecture <modules>` |
62
+ | What this site is (the roster of record) | `.ailk-site-manifest.json` |
63
+ | The locked look | `DESIGN.md` |
64
+ | Change the look | `create-ailk apply-design <name\|path>` (keeps `brand:`); at scaffold, `--design <folder>` |
65
+ | Logos, photos, brand reference | `brand_assets/` |
66
+ | Repo identity, labels, hard floors | `project.yaml` |
67
+ | Diff hygiene when editing existing files | `.claude/rules/preserve-existing-style.md` |
68
+ | Code style, testing, security | `CONVENTIONS.md` |
69
+ | Environment variables and what they unlock | `.env.example` |
70
+ | Deploy configuration | `apps/api/vercel.json`; the `setup-deploy` skill |
71
+ | Verification before push | `pnpm preflight` (see § Checks) |
72
+
73
+ <!-- /ailk:template id="resource-map" -->
74
+
75
+ <!-- ailk:template id="skills" -->
76
+
77
+ ## Skills
78
+
79
+ In `.claude/skills/`; Claude Code finds them at session start.
80
+
81
+ | Skill | Use when |
82
+ | ---------------- | ----------------------------------------------------------------- |
83
+ | `add-page` | You need a new page, or extra JSON-LD on an existing one |
84
+ | `update-page` | A page should live at a different URL, or needs a new title |
85
+ | `fill-page` | A page still carries `{placeholder}` copy |
86
+ | `check-site` | You want the site's citation-readiness score and findings |
87
+ | `setup-database` | Leads should land in a database inbox at `/leads` |
88
+ | `setup-deploy` | You are ready to deploy to Vercel |
89
+ | `add-auth` | Visitors need to sign in (magic link, Google, GitHub) |
90
+ | `upgrade-plan` | You are weighing Free against a paid level or the commerce add-on |
91
+
92
+ <!-- /ailk:template id="skills" -->
93
+
94
+ <!-- ailk:template id="checks" -->
95
+
96
+ ## Checks
97
+
98
+ | Command | Catches |
99
+ | ---------------------- | -------------------------------------------------------- |
100
+ | `pnpm preflight` | The next four and `build`, not `test`. Run before a push |
101
+ | `pnpm architecture` | An import that crosses a boundary in `architecture.yaml` |
102
+ | `pnpm claude-md:check` | A hand-edit inside a template-owned section of this file |
103
+ | `pnpm type-check` | Type errors in every workspace |
104
+ | `pnpm lint` | Lint errors in every workspace |
105
+ | `pnpm test` | Failing unit tests |
106
+ | `check-site` skill | Missing or invalid JSON-LD, weak citation-readiness |
107
+
108
+ <!-- /ailk:template id="checks" -->
109
+
110
+ <!-- ailk:template id="workflow" -->
62
111
 
63
112
  ## Workflow
64
113
 
65
- The single-developer flow, in full:
66
-
67
114
  1. Pick or open an issue with a `## Acceptance Criteria` section.
68
115
  2. Branch from your default branch (typically `main`).
69
116
  3. Write tests against the acceptance criteria first (RED).
@@ -71,83 +118,79 @@ The single-developer flow, in full:
71
118
  5. Run `pnpm preflight` — must be green before you push.
72
119
  6. Open a PR; reference the issue with `Closes #N`.
73
120
 
74
- Skip the test-first step only for: pure documentation, single-line typo
75
- fixes, or config-only changes already covered by an existing test.
76
-
77
- ## Project-specific MCP servers
121
+ Skip the test-first step only for documentation, typo fixes, or config
122
+ changes an existing test already covers.
123
+ <!-- /ailk:template id="workflow" -->
78
124
 
79
- Configured in `.claude/settings.json`. This project doesn't ship any MCP
80
- server connections by default — add the ones you actually use (your
81
- database, your deployment platform, etc.) and keep the tokens in
82
- `.env.local`, never in the repo.
125
+ <!-- ailk:template id="content" -->
83
126
 
84
- ```json
85
- // example shape — add only what you have credentials for
86
- {
87
- "mcpServers": {
88
- "your-database": { "command": "...", "args": ["..."] }
89
- }
90
- }
91
- ```
127
+ ## Content
92
128
 
93
- ## Content schema discipline
94
-
95
- This project's content is typed against schema.org via `@working-theory/schema`.
96
- Every MDX file under `content/` has frontmatter that the build validates:
129
+ `content/_site.mdx` holds the site's name, identity entity, `theme:` (the
130
+ design's) and `brand:` (the owner's colours and fonts). Each page is
131
+ `content/en/<TypeName>/<slug>.mdx`: frontmatter names the page type, and
132
+ the page body is a `sections:` list the build validates:
97
133
 
98
134
  ```yaml
99
135
  ---
100
- type: BlogPosting # one of the supported page types
101
- slug: my-post # URL-safe identifier
102
- title: My Post
103
- description: "Short summary used for the page meta tag and JSON-LD."
136
+ type: HomePage
137
+ slug: home
138
+ title: Your Company
139
+ sections:
140
+ - id: hero
141
+ type: hero
142
+ data:
143
+ {
144
+ headline: "{Your headline}",
145
+ primaryCta: { label: "Contact us", href: "/contact" },
146
+ }
104
147
  ---
105
148
  ```
106
149
 
107
- When in doubt, copy an existing file in the same folder, then change the
108
- slug and the body. Don't invent a new `type` value without first
109
- checking what `@working-theory/schema` exports.
110
-
111
- ## Hard floors
112
-
113
- These are non-negotiable in this repo. Don't ask, don't try to route
114
- around them.
115
-
116
- - **No live Stripe keys in code.** The runtime guard is an ALLOW-LIST, not
117
- a list of banned prefixes: it accepts only recognized test-mode keys
118
- (`sk_test_`, `pk_test_`, `rk_test_`) and refuses everything else. Every
119
- live key is therefore refused — a restricted key (`rk_live_`) and any
120
- prefix Stripe introduces later included — because it is absent from the
121
- allow-list, not because someone remembered to ban it. Live keys belong
122
- in the deployment platform's secrets store, never in `.env`, source
123
- files, or commit messages. Use Stripe sandbox keys for everything in
124
- source.
125
- - **No secrets in commits.** API keys, license keys, database URLs — all
126
- go through `.env.local` (gitignored) for local dev and the deployment
127
- platform's secrets store for prod.
128
- - **Validate every webhook.** Stripe sends signed payloads; reject any
129
- request whose HMAC doesn't match before you do any work on it.
130
- - **No production database access from a dev session.** If you need to
131
- inspect prod, do it through your hosting platform's read-only console,
132
- not from your laptop with a copied connection string.
150
+ Copy an existing file in the same folder, then change it. Text in `{braces}`
151
+ is placeholder copy. Don't invent a `type` that `@working-theory/schema`
152
+ doesn't export.
153
+ <!-- /ailk:template id="content" -->
133
154
 
134
- ## When to stop and ask
155
+ <!-- ailk:template id="hard-floors" -->
135
156
 
136
- You have wide latitude on most things, but stop and surface the question
137
- when:
157
+ ## Hard floors (non-negotiable)
158
+
159
+ - **Stripe test keys only in source.** The guard is an allow-list: it
160
+ refuses every live key.
161
+ - **No secrets in commits.** Keys and database URLs go in `.env.local`
162
+ (gitignored) locally and the platform's secrets store in production.
163
+ - **Validate every webhook.** Reject any request whose signature doesn't
164
+ match before you do any work on it.
165
+ - **No production database access from a dev session.**
166
+
167
+ <!-- /ailk:template id="hard-floors" -->
168
+
169
+ <!-- ailk:template id="when-to-stop" -->
170
+
171
+ ## When to stop and ask
138
172
 
139
173
  - An architecture invariant would have to bend.
140
- - A change to a shared `@working-theory/*` package would be needed (file an issue
141
- upstream at <https://github.com/working-theory-labs/ai-launch-kit>; don't fork).
142
- - You're about to delete or move >5 files at once.
174
+ - A change to a `@working-theory/*` package would be needed.
175
+ - You're about to delete or move more than 5 files at once.
143
176
  - The acceptance criteria contradict each other or the existing code.
144
177
 
145
- A 30-second clarifying question beats two hours of work down the wrong
146
- branch.
178
+ A 30-second question beats two hours down the wrong branch. Global rules
179
+ in `~/.claude/rules/` still apply; this file wins only where it says so.
180
+ <!-- /ailk:template id="when-to-stop" -->
181
+
182
+ <!-- ailk:template id="help" -->
183
+
184
+ ## Help
185
+
186
+ - Documentation: <https://ailaunchkit.ai/docs>
187
+ - File an issue: <https://github.com/working-theory-labs/ai-launch-kit/issues>
188
+
189
+ <!-- /ailk:template id="help" -->
190
+
191
+ <!-- ailk:site -->
147
192
 
148
- ## Inherited rules
193
+ ## Site notes
149
194
 
150
- If you have global rules in `~/.claude/rules/` they still apply. This
151
- file describes only what's specific to `{{PROJECT_NAME}}`. Where the two
152
- disagree, the global rule wins unless you're explicitly editing this
153
- file to override it.
195
+ Yours. `--sync-claude-md` and `pnpm claude-md:check` never read or change
196
+ anything from the marker above to the end of the file.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: Standard
3
- description: The standard design — the black-on-white foundation any shape wears by default: full navigation, a multi-column footer, the document-scroll home.
3
+ description: "The standard design — the black-on-white foundation any shape wears by default: full navigation, a multi-column footer, the document-scroll home."
4
4
  colors:
5
5
  bg: "#ffffff"
6
6
  fg: "#000000"
@@ -15,6 +15,19 @@ colors:
15
15
  fg-dark: "#ffffff"
16
16
  border-dark: "#ffffff"
17
17
  brand-dark: "#ffffff"
18
+ text-muted-dark: "#cccccc"
19
+ treatments:
20
+ corners: square
21
+ eyebrowCase: sentence
22
+ placeholders: fill
23
+ checkmarks: plain
24
+ layout:
25
+ nav: full
26
+ footer: columns
27
+ announcementBanner: false
28
+ home: default
29
+ copy:
30
+ density: standard
18
31
  typography:
19
32
  display:
20
33
  fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, sans-serif"
@@ -69,9 +82,12 @@ spacing:
69
82
  stays on-system.
70
83
  Edit the canonical file, never a copy — a test holds every copy to it.
71
84
 
72
- The tokens above describe what the site RENDERS today. Colours come from
73
- content/_site.mdx (`theme.colors`); type, radius and spacing are platform
74
- defaults a site cannot override yet — see "Where this is heading" below.
85
+ The tokens above describe what the site RENDERS today. The design's own
86
+ colours and shape knobs live in content/_site.mdx `theme:`, which
87
+ `create-ailk apply-design` replaces wholesale; the owner's brand colours and
88
+ fonts live beside it in `brand.colors` and `brand.fonts`, which applying a
89
+ design never rewrites. Radius and spacing are platform defaults a site
90
+ cannot override yet — see "Where this is heading" below.
75
91
  -->
76
92
 
77
93
  # Standard
@@ -84,6 +100,27 @@ Every page is composed from the AI Launch Kit component library (`@working-theor
84
100
 
85
101
  ## Colors
86
102
 
103
+ <!-- generated:begin colors -->
104
+
105
+ | Key | Value | Compiles to |
106
+ | ------------------- | --------- | -------------------------------------------------------------------------------------------------------------- |
107
+ | `bg` | `#ffffff` | `light.bg` |
108
+ | `fg` | `#000000` | `light.text` |
109
+ | `surface` | `#ffffff` | `light.surface` |
110
+ | `surface-secondary` | `#ffffff` | `light.bgMuted` |
111
+ | `border` | `#000000` | `light.border` |
112
+ | `text-muted` | `#333333` | `light.textMuted` |
113
+ | `brand` | `#000000` | `light.primary` |
114
+ | `fg-on-brand` | `#ffffff` | `light.primaryFg` |
115
+ | `accent` | `#000000` | `light.accent` |
116
+ | `bg-dark` | `#000000` | `dark.bg`, `dark.bgMuted` (fallback of L1), `dark.surface` (fallback of L2), `dark.primaryFg` (fallback of L4) |
117
+ | `fg-dark` | `#ffffff` | `dark.text` |
118
+ | `border-dark` | `#ffffff` | `dark.border` |
119
+ | `brand-dark` | `#ffffff` | `dark.primary`, `dark.accent` (fallback of L5) |
120
+ | `text-muted-dark` | `#cccccc` | `dark.textMuted` |
121
+
122
+ <!-- generated:end -->
123
+
87
124
  ### Primary
88
125
 
89
126
  **Black** (`brand` `#000000`) fills the primary button; its label is white. The secondary button is white with a black hairline and black label.
@@ -100,6 +137,18 @@ Dark mode inverts: black ground, white ink, white rules, white primary button wi
100
137
 
101
138
  ## Typography
102
139
 
140
+ <!-- generated:begin typography -->
141
+
142
+ | Role | Family | Size | Weight | Line height | Tracking |
143
+ | ----------------- | ------------------------------------------------------------------------ | ---------- | ------ | ----------- | -------- |
144
+ | `display` | `system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, sans-serif` | `3.5rem` | 700 | 1.1 | `normal` |
145
+ | `heading-section` | `system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, sans-serif` | `3rem` | 700 | 1.1 | `normal` |
146
+ | `heading-item` | — | `2rem` | 700 | 1.375 | `normal` |
147
+ | `body` | `system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, sans-serif` | `1.125rem` | 400 | 1.5 | — |
148
+ | `eyebrow` | — | `0.875rem` | 600 | 1.4 | `0.05em` |
149
+
150
+ <!-- generated:end -->
151
+
103
152
  System sans throughout; no web font.
104
153
 
105
154
  ### Hierarchy
@@ -118,10 +167,53 @@ The small label above a section heading is **kept** as part of this foundation's
118
167
 
119
168
  ## Layout
120
169
 
170
+ <!-- generated:begin layout -->
171
+
172
+ | Knob | Value |
173
+ | -------------------- | --------- |
174
+ | `nav` | `full` |
175
+ | `footer` | `columns` |
176
+ | `announcementBanner` | `false` |
177
+ | `home` | `default` |
178
+
179
+ | Spacing | Value |
180
+ | ---------------- | -------- |
181
+ | `section` | `7rem` |
182
+ | `section-mobile` | `4rem` |
183
+ | `card` | `1.5rem` |
184
+ | `grid` | `1.5rem` |
185
+ | `container` | `1280px` |
186
+ | `measure` | `36rem` |
187
+
188
+ <!-- generated:end -->
189
+
121
190
  Full navigation; a multi-column footer; the default home. The home-only announcement banner is off by default (`layout.announcementBanner`). Every page this site carries is listed in its roster of record, `.ailk-site-manifest.json` at the site root. Shared foundation: a 1280px container, sections at 7rem (4rem below 1024px), card grids at 1.5rem, breakpoints 320 / 768 / 1024 / 1440.
122
191
 
192
+ ## Copy
193
+
194
+ <!-- generated:begin copy -->
195
+
196
+ Copy density: standard — pages carry the ordinary amount of body copy for their section.
197
+ <!-- generated:end -->
198
+
123
199
  ## Shapes
124
200
 
201
+ <!-- generated:begin shapes -->
202
+
203
+ | Rounded | Value |
204
+ | -------- | --------- |
205
+ | `button` | `0.5rem` |
206
+ | `card` | `0.75rem` |
207
+
208
+ | Treatment | Value |
209
+ | ------------------------- | ---------- |
210
+ | `treatments.corners` | `square` |
211
+ | `treatments.eyebrowCase` | `sentence` |
212
+ | `treatments.placeholders` | `fill` |
213
+ | `treatments.checkmarks` | `plain` |
214
+
215
+ <!-- generated:end -->
216
+
125
217
  Square corners everywhere (`theme.corners: square`) — buttons, cards, the auth card, image placeholders; the tokens above are the base foundation's defaults a site overrides.
126
218
 
127
219
  ## Components
@@ -156,8 +248,8 @@ The foundation's pinned direction is the pacing of a classic wireframe marketing
156
248
  ## Do's and Don'ts
157
249
 
158
250
  - **Do** keep every page built from registered sections. If a section you need does not exist, request it rather than writing one-off markup.
159
- - **Do** change colours in `content/_site.mdx` `theme.colors`; they reach every section.
160
- - **Don't** add a colour accent. The foundation's one idea is black on white; a brand pass adds colour deliberately, through the theme.
251
+ - **Do** set your brand colours (`primary`, `primaryFg`, `accent`, per mode) in `content/_site.mdx` `brand.colors` and your fonts (`display`, `body`) in `brand.fonts`; they reach every section and survive applying another design, which replaces `theme:`.
252
+ - **Don't** add a colour accent. The foundation's one idea is black on white; a brand pass adds colour deliberately, through `brand.colors`.
161
253
  - **Don't** replace a black rule with a shadow or a grey fill.
162
254
  - **Don't** hard-code the "heading toward" values above into a page. They arrive through the platform, or not at all.
163
255