create-ailk 0.8.0 → 0.10.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 (238) hide show
  1. package/README.md +71 -3
  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 +104 -5
  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 +48 -32
  34. package/dist/lib/module-license-gate.js +117 -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 +67 -23
  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 +216 -19
  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 +16 -63
  52. package/dist/starter-grid.js +102 -84
  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 +53 -28
  57. package/package.json +6 -3
  58. package/release-scope.json +25 -0
  59. package/site-templates/_base/content/en/UseCase/persona-1.mdx +7 -6
  60. package/site-templates/_base/content/en/UseCase/persona-2.mdx +7 -6
  61. package/site-templates/_base/content/en/UseCase/persona-3.mdx +7 -6
  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/{minimalism-site → designs/minimalism/sample}/content/en/HomePage/home.mdx +1 -1
  65. package/site-templates/designs/standard/DESIGN.md +98 -6
  66. package/site-templates/marketing-site/DESIGN.md +98 -6
  67. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +60 -27
  68. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +50 -30
  69. package/site-templates/marketing-site-free/DESIGN.md +98 -6
  70. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +60 -24
  71. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +44 -27
  72. package/site-templates/marketing-site-free/ailk-template.json +1 -1
  73. package/site-templates/saas-product/DESIGN.md +98 -6
  74. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +127 -18
  75. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +74 -20
  76. package/site-templates/shapes/local-business-service/ailk-template.json +1 -1
  77. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +127 -18
  78. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +74 -20
  79. package/site-templates/shapes/organization-service/ailk-template.json +1 -1
  80. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +127 -18
  81. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +75 -21
  82. package/site-templates/shapes/person-service/ailk-template.json +1 -1
  83. package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +1 -1
  84. package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +2 -2
  85. package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +4 -2
  86. package/site-templates/shapes/person-service/content/en/ServicesList/services.mdx +1 -1
  87. package/templates/.claude/agents/web.md +10 -8
  88. package/templates/.claude/rules/architecture.md +17 -7
  89. package/templates/.claude/skills/README.md +3 -2
  90. package/templates/.claude/skills/add-auth/SKILL.md +142 -90
  91. package/templates/.claude/skills/add-auth/references/env-vars.md +32 -17
  92. package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +17 -8
  93. package/templates/.claude/skills/add-page/SKILL.md +241 -238
  94. package/templates/.claude/skills/add-page/references/page-types.md +94 -86
  95. package/templates/.claude/skills/add-page/scripts/site-pages.mjs +87 -0
  96. package/templates/.claude/skills/add-page/templates/comparison-page.mdx.tmpl +99 -0
  97. package/templates/.claude/skills/add-page/templates/content.mdx.tmpl +8 -18
  98. package/templates/.claude/skills/add-page/templates/flow-landing-page.mdx.tmpl +43 -0
  99. package/templates/.claude/skills/add-page/templates/report-page.mdx.tmpl +52 -0
  100. package/templates/.claude/skills/add-page/templates/reports-list.mdx.tmpl +38 -0
  101. package/templates/.claude/skills/check-site/SKILL.md +51 -18
  102. package/templates/.claude/skills/check-site/references/common-errors.md +12 -9
  103. package/templates/.claude/skills/check-site/references/findings-glossary.md +4 -4
  104. package/templates/.claude/skills/check-site/references/severity-levels.md +3 -3
  105. package/templates/.claude/skills/fill-page/SKILL.md +26 -7
  106. package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +1 -1
  107. package/templates/.claude/skills/setup-deploy/SKILL.md +75 -38
  108. package/templates/.claude/skills/update-page/SKILL.md +117 -0
  109. package/templates/.claude/skills/update-page/scripts/update-page.ts +640 -0
  110. package/templates/.claude/skills/update-page/templates/redirects.mjs.tmpl +31 -0
  111. package/templates/.claude/skills/upgrade-plan/SKILL.md +12 -8
  112. package/templates/.env.example +23 -2
  113. package/templates/.github/workflows/ci.yml +4 -0
  114. package/templates/.prettierignore +1 -0
  115. package/templates/CLAUDE.md +146 -103
  116. package/templates/DESIGN.md +98 -6
  117. package/templates/README.md +50 -38
  118. package/templates/apps/api/.env.example +2 -1
  119. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +2 -0
  120. package/templates/apps/api/src/__tests__/server.test.ts +116 -0
  121. package/templates/apps/api/src/lib/stripe.ts +9 -0
  122. package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +140 -0
  123. package/templates/apps/api/src/middleware/auth.ts +54 -0
  124. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +5 -2
  125. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +628 -0
  126. package/templates/apps/api/src/routes/checkout/sessions.ts +222 -24
  127. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +1 -1
  128. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +5 -1
  129. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +521 -20
  130. package/templates/apps/api/src/routes/webhooks/stripe.ts +124 -32
  131. package/templates/apps/api/src/server.ts +28 -0
  132. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +90 -15
  133. package/templates/apps/api/src/services/checkout-buyer.ts +72 -0
  134. package/templates/apps/api/src/services/revalidation.ts +60 -15
  135. package/templates/apps/mcp/__tests__/tools/create_project.test.ts +30 -24
  136. package/templates/apps/mcp/src/tools/purchase.ts +4 -2
  137. package/templates/apps/web/.env.example +13 -0
  138. package/templates/apps/web/CLAUDE.md +22 -28
  139. package/templates/apps/web/app/[locale]/(auth)/layout.tsx +1 -1
  140. package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +24 -0
  141. package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +17 -6
  142. package/templates/apps/web/app/[locale]/[slug]/[detail]/__tests__/page.test.tsx +110 -0
  143. package/templates/apps/web/app/[locale]/[slug]/[detail]/page.tsx +60 -0
  144. package/templates/apps/web/app/[locale]/[slug]/page.tsx +1 -1
  145. package/templates/apps/web/app/[locale]/alternatives/__tests__/page.test.tsx +161 -0
  146. package/templates/apps/web/app/[locale]/alternatives/page.tsx +104 -0
  147. package/templates/apps/web/app/[locale]/{use-cases → for}/[slug]/page.tsx +4 -3
  148. package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +73 -0
  149. package/templates/apps/web/app/[locale]/{use-cases → for}/page.tsx +8 -7
  150. package/templates/apps/web/app/[locale]/glossary/page.tsx +1 -1
  151. package/templates/apps/web/app/[locale]/layout.tsx +35 -19
  152. package/templates/apps/web/app/[locale]/newsletter/page.tsx +1 -1
  153. package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +1 -1
  154. package/templates/apps/web/app/[locale]/portfolio/page.tsx +1 -1
  155. package/templates/apps/web/app/[locale]/vs/[slug]/__tests__/page.test.tsx +112 -0
  156. package/templates/apps/web/app/[locale]/vs/[slug]/page.tsx +70 -0
  157. package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +236 -44
  158. package/templates/apps/web/app/api/revalidate/route.ts +78 -36
  159. package/templates/apps/web/lib/__tests__/site-brand.test.ts +79 -0
  160. package/templates/apps/web/lib/__tests__/site-theme.test.ts +104 -11
  161. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +21 -4
  162. package/templates/apps/web/lib/locale-guard.ts +18 -0
  163. package/templates/apps/web/lib/meet-placeholder.ts +5 -0
  164. package/templates/apps/web/lib/nav-config.ts +14 -13
  165. package/templates/apps/web/lib/site-brand.tsx +13 -9
  166. package/templates/apps/web/lib/site-logo.tsx +36 -0
  167. package/templates/apps/web/lib/site-theme.ts +46 -26
  168. package/templates/apps/web/messages/en.json +23 -9
  169. package/templates/apps/web/middleware.ts +28 -4
  170. package/templates/content/en/BookCall/book-a-call.mdx +80 -0
  171. package/templates/content/en/BookCall/onsite-estimate.mdx +56 -0
  172. package/templates/content/en/BookCall/onsite-service.mdx +56 -0
  173. package/templates/content/en/BookCall/start-project.mdx +56 -0
  174. package/templates/content/en/ContactPage/contact.mdx +40 -1
  175. package/templates/content/en/HomePage/home.mdx +2 -6
  176. package/templates/content/en/LandingPage/meet.mdx +59 -0
  177. package/templates/content/en/UseCasesList/{use-cases.mdx → for.mdx} +19 -18
  178. package/templates/database/CHANGELOG.md +7 -0
  179. package/templates/database/package.json +1 -1
  180. package/templates/package.json +4 -1
  181. package/templates/tools/check-claude-md.ts +128 -0
  182. package/versions.json +33 -33
  183. package/dist/modules/commerce/0.6.0.tar.gz +0 -0
  184. package/dist/modules/commerce/0.6.1.tar.gz +0 -0
  185. package/dist/modules/docs-blog/0.6.0.tar.gz +0 -0
  186. package/dist/modules/docs-blog/0.6.1.tar.gz +0 -0
  187. package/dist/modules/marketing-site/0.6.1.tar.gz +0 -0
  188. package/dist/modules/minimalism-site/0.6.1.tar.gz +0 -0
  189. package/dist/modules/multi-tenant/0.6.0.tar.gz +0 -0
  190. package/dist/modules/multi-tenant/0.6.1.tar.gz +0 -0
  191. package/dist/modules/saas-product/0.6.1.tar.gz +0 -0
  192. package/dist/modules/scheduling/0.6.0.tar.gz +0 -0
  193. package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
  194. package/dist/modules/signal-collectors/0.6.0.tar.gz +0 -0
  195. package/dist/modules/signal-collectors/0.6.1.tar.gz +0 -0
  196. package/dist/modules/simple-service/0.6.1.tar.gz +0 -0
  197. package/dist/modules/workspace/0.6.0.tar.gz +0 -0
  198. package/dist/modules/workspace/0.6.1.tar.gz +0 -0
  199. package/site-templates/_base/content/en/BookCall/book-call.mdx +0 -52
  200. package/site-templates/minimalism-site/DESIGN.md +0 -162
  201. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +0 -506
  202. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +0 -458
  203. package/site-templates/minimalism-site/ailk-template.json +0 -23
  204. package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +0 -110
  205. package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +0 -52
  206. package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +0 -34
  207. package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +0 -57
  208. package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +0 -77
  209. package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +0 -73
  210. package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -123
  211. package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +0 -52
  212. package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +0 -52
  213. package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +0 -52
  214. package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +0 -52
  215. package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +0 -38
  216. package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +0 -38
  217. package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +0 -38
  218. package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +0 -73
  219. package/site-templates/minimalism-site/flows/referral.flow.json +0 -71
  220. package/site-templates/minimalism-site/provenance.json +0 -4
  221. package/templates/.claude/skills/add-page/templates/route.tsx.tmpl +0 -28
  222. package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +0 -175
  223. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +0 -8
  224. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +0 -12
  225. package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +0 -12
  226. package/templates/apps/web/app/[locale]/book-a-call/page.tsx +0 -50
  227. package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +0 -72
  228. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-1.svg +0 -0
  229. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-2.svg +0 -0
  230. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-3.svg +0 -0
  231. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-4.svg +0 -0
  232. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-5.svg +0 -0
  233. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-6.svg +0 -0
  234. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/hero-backdrop.svg +0 -0
  235. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-1.svg +0 -0
  236. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-2.svg +0 -0
  237. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-3.svg +0 -0
  238. /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/wordmark-placeholder.svg +0 -0
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: check-site
3
- description: Run `ailk-audit --json` on the consumer's AILK site, parse the JSON report, and explain the score and findings in plain language. Use when the user asks "how is my site doing?", "audit my site", "what's my score?", "is my JSON-LD valid?", "do I have all the schema I need?", or otherwise wants a citation-readiness check on their AILK content. The skill never edits files — it reports and points at fix tools.
3
+ description: Run `ailk-audit --format json` on the consumer's AILK site, parse the JSON report, and explain the score and findings in plain language. Use when the user asks "how is my site doing?", "audit my site", "what's my score?", "is my JSON-LD valid?", "do I have all the schema I need?", or otherwise wants a citation-readiness check on their AILK content. The skill never edits files — it reports and points at fix tools.
4
4
  ---
5
5
 
6
6
  # check-site
7
7
 
8
- Shell out to `ailk-audit --json`, parse the JSON, and turn it into a
8
+ Shell out to `ailk-audit --format json`, parse the JSON, and turn it into a
9
9
  conversational summary the consumer can act on. Pure explain-only —
10
10
  the skill names fix tools (like the `schema:` frontmatter override)
11
11
  but does not invoke them.
@@ -27,22 +27,46 @@ Skip this skill when:
27
27
  tool (usually `add-page`'s `schema:` frontmatter override) and stop. This skill reports;
28
28
  fix tools fix.
29
29
  - The consumer is asking about deploy-time monitoring or continuous
30
- audits — those are Pro features (`ailk pro` for details). Mention
31
- briefly and stop.
32
- - The audit CLI isn't installed (`ailk-audit` not on PATH or as a
33
- workspace bin) — translate the error per "Common errors" below.
30
+ audits — those are Pro features (the `upgrade-plan` skill explains
31
+ the levels). Mention briefly and stop.
32
+ - The audit CLI isn't installed (`apps/api/node_modules/.bin/ailk-audit`
33
+ is missing) — translate the error per "Common errors" below.
34
34
 
35
35
  ## The mechanic
36
36
 
37
+ ### Step 0 — Read what this site can render
38
+
39
+ Read `.ailk-site-manifest.json` at the site root, the site's roster of
40
+ record:
41
+
42
+ - `modules` — the modules this site has. Add any module the
43
+ `# Modules:` line of `architecture.yaml` names that `modules` does not:
44
+ `create-ailk add-module` records a module it adds there. With no
45
+ manifest, or none carrying `modules`, that line is the set.
46
+ - `rows` — every route the site carries and the page type each renders.
47
+ - `level` — present only when the scaffold derived it from the licence
48
+ key. It never decides what to suggest; `modules` does.
49
+
50
+ A page type renders on this site only when its **Module** in
51
+ `.claude/skills/add-page/references/page-types.md` is in that set.
52
+ Step 7 suggests a page only of such a type.
53
+
37
54
  ### Step 1 — Invoke the CLI
38
55
 
39
- Run `ailk-audit --json` from the consumer's project root. Use
40
- whichever of these is appropriate to the consumer's setup:
56
+ The `ailk-audit` CLI ships in `@working-theory/aeo`, which the scaffold
57
+ installs as a dependency of `apps/api` — not of the site root — so pnpm
58
+ links its bin at `apps/api/node_modules/.bin/ailk-audit`. Run it **from
59
+ the site root**:
41
60
 
42
- - `pnpm exec ailk-audit --json`
43
- - `npx ailk-audit --json`
44
- - A package.json script if the consumer has one (`pnpm audit:run`,
45
- etc.) — only if it's a thin wrapper over the same CLI.
61
+ ```bash
62
+ apps/api/node_modules/.bin/ailk-audit --format json
63
+ ```
64
+
65
+ The site root matters: the CLI reads `content/` (its `--content-root`
66
+ default) and `project.yaml` relative to the directory it runs in. Do not
67
+ run it through `pnpm --filter ./apps/api exec`, which runs it inside
68
+ `apps/api` where neither exists. `--format json` is the flag that
69
+ selects JSON; the CLI rejects any flag it does not know and exits 2.
46
70
 
47
71
  Capture both stdout (the JSON report) and stderr (errors). Do not
48
72
  cache. Each invocation runs the CLI fresh.
@@ -61,7 +85,9 @@ Stop here on errors. Do not continue to Step 3.
61
85
 
62
86
  ### Step 3 — Parse the JSON report
63
87
 
64
- The report shape (from `packages/aeo/src/types.ts`):
88
+ The report is the `AuditReport` type `@working-theory/aeo` exports
89
+ (its shipped `dist/types.d.ts`, under
90
+ `apps/api/node_modules/@working-theory/aeo/`):
65
91
 
66
92
  ```ts
67
93
  interface AuditReport {
@@ -136,6 +162,12 @@ themselves on a subsequent turn.
136
162
  | `entity-markup` | Manual edit — ensure `Organization` (or `Person`) JSON-LD is emitted somewhere site-wide |
137
163
  | `faq-howto-incentive` | `add-page`'s `schema:` frontmatter override — add an `FAQPage` or `HowTo` block to a relevant page |
138
164
 
165
+ When a fix means adding a page, name only a page type this site can
166
+ render (Step 0) — for `faq-howto-incentive`, a `FAQPage` or `HowTo`
167
+ page, never one the site's modules do not render. When only a type the
168
+ site cannot render would fix a finding, say which module renders it and
169
+ which level carries it, and point at the `upgrade-plan` skill.
170
+
139
171
  Phrase the pointer as a single sentence:
140
172
 
141
173
  > "Missing `Product` schema on `/pricing` — add it via `add-page`'s
@@ -152,12 +184,12 @@ single-line mention tied to that finding:
152
184
  mismatch or stale schema-type usage):
153
185
 
154
186
  > "Pro auto-applies schema-pack updates as schema.org evolves —
155
- > `ailk pro` for details."
187
+ > the `upgrade-plan` skill explains the levels."
156
188
 
157
189
  - **Continuous-deploy audit** (the consumer is asking how to keep
158
190
  the score from regressing, not about a specific finding):
159
191
  > "Pro can run this audit on every deploy and gate releases on
160
- > the score — `ailk pro` for details."
192
+ > the score — the `upgrade-plan` skill explains the levels."
161
193
 
162
194
  Never produce a multi-line Pro recommendation, feature
163
195
  comparison, or upgrade prompt. The mention is informational, not
@@ -205,8 +237,9 @@ Never recommend "weekly" / "monthly" / a date.
205
237
  mechanism the skill points at. Never auto-invoked.
206
238
  - **`add-page`** — new-page creation; not a fix-tool
207
239
  for audit findings (audit reports on existing pages).
208
- - **`packages/aeo`** — owner of the `ailk-audit` CLI and rule set.
209
- This skill depends only on the CLI's `--json` output schema, not
210
- the package's internal types. New rules added upstream surface
240
+ - **`@working-theory/aeo`** — owner of the `ailk-audit` CLI and rule
241
+ set, installed under `apps/api`. This skill depends only on the
242
+ CLI's `--format json` output schema, not the package's internal
243
+ types. New rules added upstream surface
211
244
  automatically as new findings; the glossary may lag and that's
212
245
  acceptable (unrecognized rule IDs render as the raw ID).
@@ -73,21 +73,24 @@ mis-translate an unfamiliar error into a familiar fix path.
73
73
 
74
74
  - `command not found: ailk-audit`
75
75
  - `ailk-audit: command not found`
76
- - The skill itself can't find the binary on PATH or in
77
- `node_modules/.bin`.
76
+ - `apps/api/node_modules/.bin/ailk-audit: No such file or directory`
77
+ - The skill itself can't find `apps/api/node_modules/.bin/ailk-audit`.
78
78
 
79
79
  **Translation:**
80
80
 
81
81
  > The `ailk-audit` CLI isn't installed in this project. It ships
82
- > with `@working-theory/aeo`, which is normally part of the AILK consumer
83
- > scaffold.
82
+ > with `@working-theory/aeo`, which the AILK scaffold installs as a
83
+ > dependency of `apps/api` — its bin lives at
84
+ > `apps/api/node_modules/.bin/ailk-audit`, not at the site root.
84
85
  >
85
- > Add it: `pnpm add -D @working-theory/aeo` (dev dep is fine — audits run
86
- > at content time, not at build time). Then `pnpm install` and
87
- > re-run.
86
+ > If `apps/api/package.json` lists `@working-theory/aeo`, run
87
+ > `pnpm install` once from the site root to refresh
88
+ > `apps/api/node_modules/.bin`, then re-run the audit from the site
89
+ > root.
88
90
  >
89
- > If `@working-theory/aeo` is in `package.json` but the binary still isn't
90
- > found, run `pnpm install` once to refresh `node_modules/.bin`.
91
+ > If it isn't listed, the scaffold's `apps/api` is incomplete — add
92
+ > it there with `pnpm --filter ./apps/api add @working-theory/aeo`,
93
+ > then re-run from the site root.
91
94
 
92
95
  ---
93
96
 
@@ -7,7 +7,7 @@ pointer).
7
7
 
8
8
  The structure deliberately matches `perRule[].id` from the audit
9
9
  JSON so the skill can grep this file for `## <rule-id>` to find the
10
- explanation. New rules added to `packages/aeo` will not appear here
10
+ explanation. New rules added to `@working-theory/aeo` will not appear here
11
11
  until this file is updated; render unrecognized rule IDs as the raw
12
12
  ID (no synthesis).
13
13
 
@@ -118,7 +118,7 @@ an _incentive_ in drill-down, not a finding to "fix."
118
118
  ## always-passes / always-fails
119
119
 
120
120
  These are **test rules** that exist for the audit's own test suite
121
- in `packages/aeo`. They should not appear on a real consumer site
121
+ in `@working-theory/aeo`. They should not appear on a real consumer site
122
122
  unless the rule list has been customized. If you see one of these
123
123
  IDs in your audit output, the consumer's `ailk-audit` CLI may have
124
124
  a non-standard rule list — that's a setup question, not a content
@@ -129,11 +129,11 @@ finding.
129
129
  ## Unrecognized rule IDs
130
130
 
131
131
  If the audit JSON includes a rule ID not listed above, the rule is
132
- new (added to `packages/aeo` after this glossary was last updated).
132
+ new (added to `@working-theory/aeo` after this glossary was last updated).
133
133
  Render it as:
134
134
 
135
135
  > Rule `<id>` — `<evidence text from the audit JSON>` — not in
136
- > the local glossary; consult `packages/aeo` upstream docs.
136
+ > the local glossary; consult the `@working-theory/aeo` package docs.
137
137
 
138
138
  Do not invent a plain-language explanation for an unrecognized
139
139
  rule. The consumer can read the rule's `description` field from
@@ -20,7 +20,7 @@ The skill applies these rules in `SKILL.md` Step 5.
20
20
 
21
21
  A rule with `pass: false` AND `weight: 0` is **not possible** today
22
22
  (incentive rules are designed to never fail — see
23
- `faq-howto-incentive` in `packages/aeo`). If one ever appears,
23
+ `faq-howto-incentive` in `@working-theory/aeo`). If one ever appears,
24
24
  treat it as Info (the rule's own design says failures are neutral).
25
25
 
26
26
  ---
@@ -39,7 +39,7 @@ severity-based. Reasons:
39
39
  The skill turns "weight 10 fail" into "Critical" because that's
40
40
  the language consumers can act on.
41
41
  - **Rule authors don't have to think about severity.** A new rule
42
- added to `packages/aeo` gets a weight (its impact on the score)
42
+ added to `@working-theory/aeo` gets a weight (its impact on the score)
43
43
  and the skill maps that to a severity tier automatically. No
44
44
  coupling between rule authoring and consumer-facing UX.
45
45
 
@@ -105,7 +105,7 @@ for drill-down.
105
105
 
106
106
  ## Future rules
107
107
 
108
- When `packages/aeo` adds a new rule, this glossary may not name
108
+ When `@working-theory/aeo` adds a new rule, this glossary may not name
109
109
  it. The severity mapping still works because it keys off `weight`
110
110
  and `pass` only — both fields are guaranteed by the
111
111
  `PerRuleResult` type. New critical-tier rules will surface as
@@ -67,15 +67,30 @@ comes from `_site.mdx` `siteIdentity.name`.
67
67
 
68
68
  ## Step 0 — Read
69
69
 
70
- 1. Read the profile: `profiles/<slug>.yaml`.
71
- 2. Read `content/_site.mdx` for `siteIdentity.name`.
72
- 3. Read the page file. Note its stack (`sections[].type` in order).
73
- 4. For each section type in the stack, read its data schema: the
70
+ 1. Read `.ailk-site-manifest.json` at the site root, the site's roster
71
+ of record: `modules` (the modules this site has) and `rows` (every
72
+ route it carries). Add any module the `# Modules:` line of
73
+ `architecture.yaml` names that `modules` does not — `create-ailk
74
+ add-module` records a module it adds there; with no manifest, or none
75
+ carrying `modules`, that line is the set. `level`, when present, never
76
+ decides anything here.
77
+
78
+ The page's `type` must render on this site: its **Module** in
79
+ `../add-page/references/page-types.md` is in that set, or a row
80
+ already renders it (`rows[].pageType` — a Free starter's `/meet/<slug>`
81
+ `BookCall` placeholders). When it does not,
82
+ say which module renders the type and which level carries it, point at
83
+ the `upgrade-plan` skill, and stop. Never fill a page this site cannot
84
+ render.
85
+ 2. Read the profile: `profiles/<slug>.yaml`.
86
+ 3. Read `content/_site.mdx` for `siteIdentity.name`.
87
+ 4. Read the page file. Note its stack (`sections[].type` in order).
88
+ 5. For each section type in the stack, read its data schema: the
74
89
  `<Type>SectionDataSchema` (or `<Type>DataSchema`) export in the
75
90
  installed `@working-theory/validation`'s `schemas/page-sections`. Fill
76
91
  only fields the schema declares. Every field a section renders from
77
92
  copy gets content; a field the source page did not use stays unused.
78
- 5. Find the route that renders this page type under `apps/web/app/[locale]/`
93
+ 6. Find the route that renders this page type under `apps/web/app/[locale]/`
79
94
  and read its `bodyMode`. When it is `"mdx-body"`, the MDX body is
80
95
  rendered and must be filled too. Otherwise the body is a short note,
81
96
  and you rewrite it as one plain sentence that names no braces.
@@ -88,7 +103,9 @@ fields and intake answers that fill it.
88
103
  1. **Sections.** For each section, in place, write every copy field from
89
104
  the profile using `references/section-sources.md`:
90
105
  - offerings → `items` entries (`title` = the offering `name`,
91
- `description` = its `job`, `link.href` = `/services/<kebab name>`);
106
+ `description` = its `job`, `link.href` = `/services/<kebab name>`
107
+ only when the manifest's `rows` carry `/services/[slug]`; otherwise
108
+ no `link`, so no entry points at a page the site does not have);
92
109
  - vocabulary → headlines, eyebrows and FAQ questions (the buyer's own
93
110
  words: the `problem` list for what went wrong, `outcome` for what
94
111
  they get);
@@ -176,5 +193,7 @@ and run both again. Stop only when both are clean.
176
193
  - Tier 3 (the Messaging Canvas through the content pipeline).
177
194
  - Create a page — use `add-page`.
178
195
  - Edit `_site.mdx`, the nav or the page roster. A profile's `roster` and
179
- `nav` entries are declared for a later step and are not applied here.
196
+ `nav` entries are declared for a later step and are not applied here,
197
+ and a profile page type this site cannot render (Step 0) is never
198
+ suggested.
180
199
  - Write a price, a name or an address the owner did not give.
@@ -50,7 +50,7 @@ vocabulary:
50
50
  - tidy job, nothing left behind
51
51
  roster:
52
52
  - op: add
53
- route: /emergency
53
+ route: /meet/emergency
54
54
  pageType: BookCall
55
55
  reason: Emergency jobs book a call, not a form.
56
56
  - op: drop
@@ -1,12 +1,13 @@
1
1
  ---
2
2
  name: setup-deploy
3
- description: Emit deploy configuration for an AILK consumer site — `vercel.json`, `.env.example`, and `RUNBOOK.md`. Vercel-only at v1; other platforms reject with a clear "not yet supported" message. Use when the user asks "set up Vercel", "provision deploy config", "what env vars do I need for production?", "I'm ready to ship to Vercel", or otherwise asks about pre-deploy file setup. Asks where leads should go — the email key (`RESEND_API_KEY` + the two notification addresses) or a database (`setup-database`) — and warns when neither is set. The RUNBOOK documents the two lead destinations: Email (default) and Lead inbox (setup-database).
3
+ description: Emit deploy configuration for an AILK consumer site — `vercel.json` and `RUNBOOK.md`, plus an env checklist read from the scaffold's own `.env.example`. Vercel-only at v1; other platforms reject with a clear "not yet supported" message. Use when the user asks "set up Vercel", "provision deploy config", "what env vars do I need for production?", "I'm ready to ship to Vercel", or otherwise asks about pre-deploy file setup. Asks where leads should go — the email key (`RESEND_API_KEY` + the two notification addresses) or a database (`setup-database`) — and warns when neither is set. The RUNBOOK documents the two lead destinations: Email (default) and Lead inbox (setup-database).
4
4
  ---
5
5
 
6
6
  # setup-deploy
7
7
 
8
- Emit `vercel.json`, `.env.example`, and `RUNBOOK.md` at the consumer's
9
- project root, ready for a Vercel deploy. Vercel is the only valid
8
+ Emit `vercel.json` and `RUNBOOK.md` at the consumer's project root,
9
+ and bring the scaffold's own `.env.example` up to date with what the
10
+ site's code reads, ready for a Vercel deploy. Vercel is the only valid
10
11
  `platform` value at v1. Other platforms (Netlify, Cloudflare, Render,
11
12
  Fly, self-host) reject with an explicit "not yet supported" message
12
13
  and emit nothing.
@@ -40,13 +41,16 @@ Skip this skill when:
40
41
  the consumer's project root.
41
42
  - For each artifact, ask the consumer how to handle conflicts
42
43
  (merge / overwrite / skip) before writing.
43
- - Emit the three artifacts at the consumer's project root, derived
44
- from templates in `references/`.
44
+ - Emit `vercel.json` and `RUNBOOK.md` at the consumer's project root,
45
+ derived from templates in `references/`.
46
+ - Read the env contract from the scaffold's own `.env.example` — the
47
+ file every scaffold ships at its root — plus a `process.env` scan
48
+ of the site's code, and turn it into the env checklist (Step 5).
45
49
  - Ask where leads go (Step 5a) — the email key, or a database via
46
50
  `setup-database` — and warn, verbatim, when neither is set.
47
51
  - Validate the emitted output (parse `vercel.json` as JSON, check
48
- `.env.example` covers required vars, confirm `RUNBOOK.md` has the
49
- two lead-destination headings).
52
+ `.env.example` declares every variable the `process.env` scan
53
+ found, confirm `RUNBOOK.md` has the two lead-destination headings).
50
54
 
51
55
  **Does not:**
52
56
 
@@ -84,23 +88,31 @@ consumer's project root. For each one, note:
84
88
  - **Missing** — will emit fresh.
85
89
  - **Present** — ask how to handle (Step 3).
86
90
 
91
+ `.env.example` is the exception: every scaffold ships one, and it is
92
+ the source this skill reads, not a file it writes from scratch. If
93
+ it is missing, tell the consumer to restore it from git history and
94
+ re-run — never write one from memory.
95
+
87
96
  ### Step 3 — Conflict handling per file
88
97
 
89
98
  For each existing artifact, show the consumer:
90
99
 
91
100
  1. The first ~10 lines of the existing file (preview).
92
101
  2. A summary of what the skill would emit (template name + key
93
- fields).
102
+ fields; for `.env.example`, the variables Step 5 would add).
94
103
  3. Three options: **merge** (only for `RUNBOOK.md` and
95
104
  `.env.example` — see merge logic below), **overwrite**
96
- (replace contents), **skip** (leave existing file untouched).
105
+ (replace contents; not offered for `.env.example`, which has no
106
+ other source), **skip** (leave existing file untouched).
97
107
 
98
108
  Wait for the consumer's choice per file. Do not blindly overwrite.
99
109
 
100
- **Merge logic — `.env.example`:** if a var listed in
101
- `references/env-vars-template.md` is **missing** from the existing
102
- file, append it (with comment) at the bottom under a "## Added by
103
- setup-deploy" section. Vars already present are not modified.
110
+ **Merge logic — `.env.example`:** if a var the Step 5 `process.env`
111
+ scan found is **missing** from every `.env.example` Step 5 reads —
112
+ neither set (`NAME=`) nor listed commented (`# NAME=`) — append it
113
+ (with comment) at the bottom of the root file
114
+ under a `# ── Added by setup-deploy ──` heading. Lines already in
115
+ the file are never modified; the consumer's comments and values win.
104
116
 
105
117
  **Merge logic — `RUNBOOK.md`:** if the "Leads — where messages go"
106
118
  section (with its two headings, `Email (default)` and
@@ -130,22 +142,43 @@ emitted file has these fields:
130
142
  After write, parse the JSON. If parse fails, the skill has a bug —
131
143
  report it to the consumer with the literal error.
132
144
 
133
- ### Step 5 — Emit `.env.example`
134
-
135
- Use the template at `references/env-vars-template.md`. The emitted
136
- file lists every env var the consumer's site reads, grouped by
137
- concern (auth, content, payments, analytics, etc.) with placeholder
138
- values and inline comments.
145
+ ### Step 5 — Build the env checklist from `.env.example`
146
+
147
+ The env contract is the scaffold's own `.env.example` at the project
148
+ root, plus the per-app `apps/*/.env.example` files it points to. Read
149
+ them; keep no second copy of them anywhere, including in this skill.
150
+
151
+ 1. **Read the declared names.** In each of those files, every
152
+ uncommented `NAME=value` line is a variable the scaffold sets (for
153
+ example `CONTENT_ADAPTER=mdx`); every commented `# NAME=` line is
154
+ an opt-in variable. The `# ── <Section> ──` heading above a line
155
+ is its group, and the comment above an entry says what it does
156
+ and whether production needs it. A name counts as declared when
157
+ any of the files declares it.
158
+ 2. **Scan the code.** Grep the site's source (`apps/`, `database/`,
159
+ and `packages/` if the scaffold has one) for `process.env.NAME`
160
+ and `process.env["NAME"]`. Skip `NODE_ENV`, variables the platform
161
+ sets itself (`VERCEL_*`, `CI`), and any name the files' comments
162
+ call deprecated — the code reads those only as a fallback, and the
163
+ checklist uses the name that replaced them.
164
+ 3. **Add what is missing.** A name the scan found that `.env.example`
165
+ does not declare goes at the bottom under
166
+ `# ── Added by setup-deploy ──`, commented out with an empty
167
+ placeholder and a one-line comment naming the file that reads it.
168
+ Do this only when the consumer chose **merge** in Step 3; on
169
+ **skip**, list those names in the checklist instead. Either way,
170
+ never silently omit a var the consumer's site reads.
171
+ 4. **Show the checklist.** List each section heading with its
172
+ variables, marking the ones the file sets, and quote the entry's
173
+ own comment for what production needs. Call out every value the
174
+ file sets that the consumer must change for their own site — for
175
+ example `AILK_PUBLIC_DOMAIN`, and `STEALTH`, which stays `true`
176
+ until launch. Use the names exactly as `.env.example` spells
177
+ them — do not restate a variable from memory.
139
178
 
140
179
  The skill **does not** read live `.env` files. Placeholder values
141
180
  only. No `sk_live_*`, no `pk_live_*`, no real Resend keys, no real
142
- NextAuth secrets.
143
-
144
- After write, count the declared vars and confirm the count matches
145
- the template's expected count. If a var the consumer's site uses
146
- (grep `process.env.X` from a quick scan) is missing from the
147
- template, add it under "## Added by setup-deploy" — never silently
148
- omit a var the consumer needs.
181
+ auth secrets.
149
182
 
150
183
  ### Step 5a — Lead delivery
151
184
 
@@ -160,10 +193,10 @@ two questions:
160
193
  2. **What email should messages go to?** Ask for
161
194
  `RESEND_API_KEY`, `AILK_LEAD_NOTIFICATION_TO` (their address) and
162
195
  `AILK_LEAD_NOTIFICATION_FROM` (a sender on their Resend-verified
163
- domain). All three are needed — a key alone sends nothing. Write
164
- **placeholders only** into `.env.example`; tell the consumer to set
165
- the real values in the **API** project's dashboard. Never write a
166
- key into a file.
196
+ domain). All three are needed — a key alone sends nothing.
197
+ `.env.example` already lists all three as commented entries; tell
198
+ the consumer to set the real values in the **API** project's
199
+ dashboard. Never write a key into a file.
167
200
 
168
201
  If the consumer provides neither a database nor all three email
169
202
  values, print this, verbatim:
@@ -229,7 +262,9 @@ message.
229
262
  Before reporting "done":
230
263
 
231
264
  - `vercel.json` parses as JSON ✓
232
- - `.env.example` declares >= the count of vars in the template ✓
265
+ - Every variable the `process.env` scan found is declared in an
266
+ `.env.example`, set or commented — or, when the consumer chose
267
+ **skip**, listed in the checklist ✓
233
268
  - `RUNBOOK.md` contains both lead-destination headings
234
269
  (`Email (default)`, `Lead inbox (setup-database)`) ✓
235
270
  - Step 5a ran: the consumer chose a lead destination, or saw the
@@ -250,8 +285,9 @@ If any check fails, surface the failure to the consumer (not silent).
250
285
  ## References
251
286
 
252
287
  - `references/vercel-json-template.md` — minimal viable `vercel.json`.
253
- - `references/env-vars-template.md` — `.env.example` structure with
254
- placeholder values per category.
288
+ - The scaffold's own `.env.example` at the project root, and the
289
+ per-app `apps/*/.env.example` files — the env contract Step 5
290
+ reads. This skill keeps no copy of it.
255
291
  - `references/runbook-template.md` — `RUNBOOK.md` with the two lead
256
292
  destinations (Email (default), Lead inbox (setup-database)).
257
293
 
@@ -265,11 +301,12 @@ If any check fails, surface the failure to the consumer (not silent).
265
301
  RUNBOOK adds production callback URLs and merges with any
266
302
  existing runbook content (not blindly overwrites).
267
303
  - **`@working-theory/env`** — at v1 a placeholder package, not yet a Zod
268
- schema. This skill derives `.env.example` from the template, not
269
- from a runtime schema. When `@working-theory/env` ships its schema, this
270
- skill should be revised to read from it.
271
- - **Stripe sandbox-only** — hard-floor enforced globally. Emitted
272
- `.env.example` uses `sk_test_*` placeholders, never `sk_live_*`.
304
+ schema. This skill reads the env contract from the scaffold's
305
+ `.env.example`, not from a runtime schema. When `@working-theory/env`
306
+ ships its schema, this skill should be revised to read from it.
307
+ - **Stripe sandbox-only** — hard-floor enforced globally. Nothing
308
+ this skill adds to `.env.example` carries a `sk_live_*` or
309
+ `pk_live_*` value.
273
310
  - **Cloudflare deferred** — neither CF Pages (deploy target) nor
274
311
  CF KV / D1 / R2 (data layer) is in v1. Will ship as a coherent
275
312
  follow-up PR.
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: update-page
3
+ description: Rename a page on this AI Launch Kit site — change its URL (/meet to /schedule, /team to /people) and/or its title — safely, in one plan-then-confirm pass. Use this whenever the user wants to move, rename, re-slug or re-title an existing page, even if they don't say "rename" — "make /meet be /schedule", "the booking page should live at /book", "call the team page People", "I don't like this URL". It moves the content file(s), the page's own route folder if it has one, every exact internal link, the site-manifest row, and adds a permanent redirect from the old URL. It refuses pages whose URL is fixed by their type or shipped by the scaffold. Not for adding a page (add-page) or rewriting its words (fill-page).
4
+ ---
5
+
6
+ # update-page
7
+
8
+ Move a page from `/old` to `/new` (and optionally give it a new title) without
9
+ leaving a dead link, a stale manifest row, or a broken inbound URL behind. A
10
+ bundled helper computes the whole change as a plan; you show the plan, the user
11
+ confirms once, and only then does anything get written.
12
+
13
+ ## The one rule
14
+
15
+ **Never run `apply` before the user has seen the plan and confirmed it.** The
16
+ helper enforces this mechanically — `apply` requires the hash the plan printed,
17
+ and refuses any other — but the order is yours to keep:
18
+ plan → show the file list → wait for confirmation → apply with the plan hash.
19
+
20
+ ## Step 1 — Plan
21
+
22
+ From the site root:
23
+
24
+ ```bash
25
+ pnpm exec tsx .claude/skills/update-page/scripts/update-page.ts plan --from /meet --to /schedule
26
+ ```
27
+
28
+ Add `--name "Book a time"` to also change the page's title (the `title:` in its
29
+ content file; it sets the English file only and reports other languages as
30
+ "title left as translated").
31
+
32
+ The helper prints:
33
+
34
+ - every file it would touch, tagged `move`, `modify`, `create` or `delete`;
35
+ - `note:` lines a reader should know about (see below);
36
+ - `hash: <sha256>` — the plan's fingerprint.
37
+
38
+ It writes nothing. If it prints `refused: …` and exits 3, stop there and tell
39
+ the user why (the reasons are below). Don't work around a refusal by hand.
40
+
41
+ ## Step 2 — Show the plan and wait
42
+
43
+ Show the user the file list and the notes as printed. If they want to see the
44
+ new contents, `plan --json` prints every change with its full new content.
45
+ Then wait for one confirmation. A "yes" to the summary is enough; you don't
46
+ need per-file approval.
47
+
48
+ ## Step 3 — Apply
49
+
50
+ ```bash
51
+ pnpm exec tsx .claude/skills/update-page/scripts/update-page.ts apply --from /meet --to /schedule --confirm <hash>
52
+ ```
53
+
54
+ Pass the same `--from`, `--to` and `--name` as the plan. The helper re-plans
55
+ and compares hashes: if anything changed in between (a file was edited, a
56
+ different rename was planned), it exits 1 and writes nothing — run `plan` again
57
+ and confirm the new hash.
58
+
59
+ ## Step 4 — Check and report
60
+
61
+ Run `pnpm build` from the site root. Then tell the user:
62
+
63
+ - the new URL (with the locale, e.g. `/en/schedule`), and that `/meet` now
64
+ answers with a permanent redirect (HTTP 308) to it;
65
+ - any `note:` lines that need their attention (below);
66
+ - that the nav label text lives in `apps/web/messages/<locale>.json` if they
67
+ also want the menu wording changed — this skill only re-points the link.
68
+
69
+ ## What the plan changes
70
+
71
+ | Surface | What happens |
72
+ |---|---|
73
+ | `content/<locale>/<Type>/old.mdx` (every locale) | Renamed to `new.mdx`; its `slug:` updated; `title:` updated when `--name` is given |
74
+ | The page's own route folder, when a folder under `apps/web/app` serves `/old` and is not a route the scaffold ships (a page the catch-all route serves has none) | Moved to the sibling folder `new/`; the `getPage("old")` literal inside becomes `getPage("new")` |
75
+ | Exact links to `/old` in `content/**` and `apps/web/lib/nav-config.ts` | Rewritten to `/new`. Exact means the whole path: `/meet` is rewritten, `/meet/book-a-call` and `/meeting` are not |
76
+ | `.ailk-site-manifest.json` | The one row whose `route` is `/old` now reads `/new`; no other byte changes |
77
+ | `apps/web/next.config.mjs` `redirects()` | Gains a managed block (`ailk:page-renames`) with `{ from: "/old", to: "/new" }`. Locale-prefixed forms are added for every non-default locale. A second rename collapses chains: renaming `/schedule` to `/book` later re-points the `/meet` row straight to `/book` |
78
+
79
+ Links to `/old` in code files (`apps/web/app`, `lib`, `components`) are
80
+ reported, not rewritten — the redirect covers them, and code edits are the
81
+ owner's call.
82
+
83
+ ## The notes, and what to say about them
84
+
85
+ - **"…belongs to the `<module>` module's routes…"** — the old or new URL is a
86
+ route a paid module (scheduling, docs-blog, …) would install if the site
87
+ adds it later. Tell the user: if they add that module, the redirect (for the
88
+ old URL) or the module's folder (for the new URL) will take over, and the
89
+ note says what to remove or rename first.
90
+ - **"add-module `<module>` will keep these edited placeholder files…"** — the
91
+ rename edited seed pages that a module would normally replace; the module
92
+ will now list them for review instead. Nothing is lost.
93
+ - **"add-module will no longer regenerate the nav…"** — the nav is now a
94
+ hand-edited file; later module installs report the nav change they wanted
95
+ rather than applying it.
96
+ - **"the pages under /old … keep their URLs"** — detail pages like
97
+ `/meet/book-a-call` are fixed by their type and stay where they are.
98
+
99
+ ## When the helper refuses (exit 3)
100
+
101
+ | Reason | What it means | What to offer instead |
102
+ |---|---|---|
103
+ | `routes must be one lowercase segment` | Only a top-level page moves (`/meet`, not `/meet/book-a-call`) | Detail pages are fixed by their type |
104
+ | `no page at /old` | Nothing on the site is served there | Check the URL; `add-page` adds a page |
105
+ | `/old is a code route with no page content to move` | A route folder exists but no content page backs it | A code change, not a rename |
106
+ | `a <Type> page's URL is fixed by its type` | About, Contact, a Service, a booking page — their URL comes from the page type | Explain that these can't move; the title can still change in the content file |
107
+ | `/old is served by a route the scaffold ships` | The route folder came with the scaffold (e.g. `/pricing`) | Same as above |
108
+ | `/new already exists: …` | A route folder, another page, or a content locale directory owns `/new` | Pick another route |
109
+ | `redirects() has been edited` | Someone hand-edited `redirects()` in `next.config.mjs`, so the helper won't touch it | Add the redirect line the message gives, by hand, or restore the generated method |
110
+
111
+ ## What this skill does not do
112
+
113
+ - Add a page (`add-page`) or rewrite its words (`fill-page`).
114
+ - Change the menu label text in `apps/web/messages/*.json` (it re-points the
115
+ link and reports the label key).
116
+ - Edit route literals in code, or anything in `apps/api` / `apps/mcp`.
117
+ - Move detail pages, hubs, or any page whose URL is fixed by its type.